| @@ -5,8 +5,7 @@ set -e | |||||
| JUCE_MODULES_DIR="/home/falktx/Personal/FOSS/GIT/DISTRHO/libs/juce/source/modules/" | JUCE_MODULES_DIR="/home/falktx/Personal/FOSS/GIT/DISTRHO/libs/juce/source/modules/" | ||||
| CARLA_MODULES_DIR="/home/falktx/Personal/FOSS/GIT/Carla/source/modules" | CARLA_MODULES_DIR="/home/falktx/Personal/FOSS/GIT/Carla/source/modules" | ||||
| # MODULES=("juce_audio_basics juce_audio_devices juce_audio_formats juce_audio_processors juce_core juce_data_structures juce_events juce_graphics juce_gui_basics") | |||||
| MODULES=("juce_audio_devices") | |||||
| MODULES=("juce_audio_basics juce_audio_devices juce_audio_formats juce_audio_processors juce_core juce_data_structures juce_events juce_graphics juce_gui_basics") | |||||
| for M in $MODULES; do | for M in $MODULES; do | ||||
| echo $M; | echo $M; | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -42,38 +43,6 @@ | |||||
| #include "stream_decoder.h" | #include "stream_decoder.h" | ||||
| #include "stream_encoder.h" | #include "stream_encoder.h" | ||||
| #ifdef _MSC_VER | |||||
| /* OPT: an MSVC built-in would be better */ | |||||
| static _inline FLAC__uint32 local_swap32_(FLAC__uint32 x) | |||||
| { | |||||
| x = ((x<<8)&0xFF00FF00) | ((x>>8)&0x00FF00FF); | |||||
| return (x>>16) | (x<<16); | |||||
| } | |||||
| #endif | |||||
| #if defined(_MSC_VER) && defined(_X86_) | |||||
| /* OPT: an MSVC built-in would be better */ | |||||
| static void local_swap32_block_(FLAC__uint32 *start, FLAC__uint32 len) | |||||
| { | |||||
| __asm { | |||||
| mov edx, start | |||||
| mov ecx, len | |||||
| test ecx, ecx | |||||
| loop1: | |||||
| jz done1 | |||||
| mov eax, [edx] | |||||
| bswap eax | |||||
| mov [edx], eax | |||||
| add edx, 4 | |||||
| dec ecx | |||||
| jmp short loop1 | |||||
| done1: | |||||
| } | |||||
| } | |||||
| #endif | |||||
| /** \mainpage | /** \mainpage | ||||
| * | * | ||||
| * \section intro Introduction | * \section intro Introduction | ||||
| @@ -193,7 +162,7 @@ done1: | |||||
| * in FLAC 1.1.3 is a set of \c #defines in \c export.h of each | * in FLAC 1.1.3 is a set of \c #defines in \c export.h of each | ||||
| * library's includes (e.g. \c include/FLAC/export.h). The | * library's includes (e.g. \c include/FLAC/export.h). The | ||||
| * \c #defines mirror the libraries' | * \c #defines mirror the libraries' | ||||
| * <A HREF="http://www.gnu.org/software/libtool/manual.html#Libtool-versioning">libtool version numbers</A>, | |||||
| * <A HREF="http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning">libtool version numbers</A>, | |||||
| * e.g. in libFLAC there are \c FLAC_API_VERSION_CURRENT, | * e.g. in libFLAC there are \c FLAC_API_VERSION_CURRENT, | ||||
| * \c FLAC_API_VERSION_REVISION, and \c FLAC_API_VERSION_AGE. | * \c FLAC_API_VERSION_REVISION, and \c FLAC_API_VERSION_AGE. | ||||
| * These can be used to support multiple versions of an API during the | * These can be used to support multiple versions of an API during the | ||||
| @@ -1,19 +1,33 @@ | |||||
| /* alloc - Convenience routines for safely allocating memory | /* alloc - Convenience routines for safely allocating memory | ||||
| * Copyright (C) 2007 Josh Coalson | |||||
| * Copyright (C) 2007-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * This library is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the GNU Lesser General Public | |||||
| * License as published by the Free Software Foundation; either | |||||
| * version 2.1 of the License, or (at your option) any later version. | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * | * | ||||
| * 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. | |||||
| * - Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * | * | ||||
| * 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 | |||||
| * - Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in the | |||||
| * documentation and/or other materials provided with the distribution. | |||||
| * | |||||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||||
| * contributors may be used to endorse or promote products derived from | |||||
| * this software without specific prior written permission. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||||
| */ | */ | ||||
| #ifndef FLAC__SHARE__ALLOC_H | #ifndef FLAC__SHARE__ALLOC_H | ||||
| @@ -28,15 +42,20 @@ | |||||
| */ | */ | ||||
| #include <limits.h> /* for SIZE_MAX */ | #include <limits.h> /* for SIZE_MAX */ | ||||
| #if !defined _MSC_VER && !defined __MINGW32__ && !defined __EMX__ | |||||
| #if HAVE_STDINT_H | |||||
| #include <stdint.h> /* for SIZE_MAX in case limits.h didn't get it */ | #include <stdint.h> /* for SIZE_MAX in case limits.h didn't get it */ | ||||
| #endif | #endif | ||||
| #include <stdlib.h> /* for size_t, malloc(), etc */ | #include <stdlib.h> /* for size_t, malloc(), etc */ | ||||
| #include "compat.h" | |||||
| #ifndef SIZE_MAX | #ifndef SIZE_MAX | ||||
| # ifndef SIZE_T_MAX | # ifndef SIZE_T_MAX | ||||
| # ifdef _MSC_VER | # ifdef _MSC_VER | ||||
| # define SIZE_T_MAX UINT_MAX | |||||
| # ifdef _WIN64 | |||||
| # define SIZE_T_MAX 0xffffffffffffffffui64 | |||||
| # else | |||||
| # define SIZE_T_MAX 0xffffffff | |||||
| # endif | |||||
| # else | # else | ||||
| # error | # error | ||||
| # endif | # endif | ||||
| @@ -44,14 +63,10 @@ | |||||
| # define SIZE_MAX SIZE_T_MAX | # define SIZE_MAX SIZE_T_MAX | ||||
| #endif | #endif | ||||
| #ifndef FLaC__INLINE | |||||
| #define FLaC__INLINE | |||||
| #endif | |||||
| /* avoid malloc()ing 0 bytes, see: | /* 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 | * 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) | |||||
| static inline void *safe_malloc_(size_t size) | |||||
| { | { | ||||
| /* malloc(0) is undefined; FLAC src convention is to always allocate */ | /* malloc(0) is undefined; FLAC src convention is to always allocate */ | ||||
| if(!size) | if(!size) | ||||
| @@ -59,7 +74,7 @@ static FLaC__INLINE void *safe_malloc_(size_t size) | |||||
| return malloc(size); | return malloc(size); | ||||
| } | } | ||||
| static FLaC__INLINE void *safe_calloc_(size_t nmemb, size_t size) | |||||
| static inline void *safe_calloc_(size_t nmemb, size_t size) | |||||
| { | { | ||||
| if(!nmemb || !size) | if(!nmemb || !size) | ||||
| return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ | return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ | ||||
| @@ -68,7 +83,7 @@ static FLaC__INLINE void *safe_calloc_(size_t nmemb, size_t size) | |||||
| /*@@@@ there's probably a better way to prevent overflows when allocating untrusted sums but this works for now */ | /*@@@@ 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) | |||||
| static inline void *safe_malloc_add_2op_(size_t size1, size_t size2) | |||||
| { | { | ||||
| size2 += size1; | size2 += size1; | ||||
| if(size2 < size1) | if(size2 < size1) | ||||
| @@ -76,7 +91,7 @@ static FLaC__INLINE void *safe_malloc_add_2op_(size_t size1, size_t size2) | |||||
| return safe_malloc_(size2); | return safe_malloc_(size2); | ||||
| } | } | ||||
| static FLaC__INLINE void *safe_malloc_add_3op_(size_t size1, size_t size2, size_t size3) | |||||
| static inline void *safe_malloc_add_3op_(size_t size1, size_t size2, size_t size3) | |||||
| { | { | ||||
| size2 += size1; | size2 += size1; | ||||
| if(size2 < size1) | if(size2 < size1) | ||||
| @@ -87,7 +102,7 @@ static FLaC__INLINE void *safe_malloc_add_3op_(size_t size1, size_t size2, size_ | |||||
| return safe_malloc_(size3); | return safe_malloc_(size3); | ||||
| } | } | ||||
| static FLaC__INLINE void *safe_malloc_add_4op_(size_t size1, size_t size2, size_t size3, size_t size4) | |||||
| static inline void *safe_malloc_add_4op_(size_t size1, size_t size2, size_t size3, size_t size4) | |||||
| { | { | ||||
| size2 += size1; | size2 += size1; | ||||
| if(size2 < size1) | if(size2 < size1) | ||||
| @@ -101,29 +116,9 @@ static FLaC__INLINE void *safe_malloc_add_4op_(size_t size1, size_t size2, size_ | |||||
| return safe_malloc_(size4); | 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 | |||||
| void *safe_malloc_mul_2op_(size_t size1, size_t size2) ; | |||||
| static FLaC__INLINE void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_t size3) | |||||
| static inline void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_t size3) | |||||
| { | { | ||||
| if(!size1 || !size2 || !size3) | if(!size1 || !size2 || !size3) | ||||
| return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ | return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ | ||||
| @@ -136,7 +131,7 @@ static FLaC__INLINE void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_ | |||||
| } | } | ||||
| /* size1*size2 + size3 */ | /* size1*size2 + size3 */ | ||||
| static FLaC__INLINE void *safe_malloc_mul2add_(size_t size1, size_t size2, size_t size3) | |||||
| static inline void *safe_malloc_mul2add_(size_t size1, size_t size2, size_t size3) | |||||
| { | { | ||||
| if(!size1 || !size2) | if(!size1 || !size2) | ||||
| return safe_malloc_(size3); | return safe_malloc_(size3); | ||||
| @@ -146,17 +141,19 @@ static FLaC__INLINE void *safe_malloc_mul2add_(size_t size1, size_t size2, size_ | |||||
| } | } | ||||
| /* size1 * (size2 + size3) */ | /* size1 * (size2 + size3) */ | ||||
| static FLaC__INLINE void *safe_malloc_muladd2_(size_t size1, size_t size2, size_t size3) | |||||
| static inline void *safe_malloc_muladd2_(size_t size1, size_t size2, size_t size3) | |||||
| { | { | ||||
| if(!size1 || (!size2 && !size3)) | if(!size1 || (!size2 && !size3)) | ||||
| return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ | return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ | ||||
| size2 += size3; | size2 += size3; | ||||
| if(size2 < size3) | if(size2 < size3) | ||||
| return 0; | return 0; | ||||
| return safe_malloc_mul_2op_(size1, size2); | |||||
| if(size1 > SIZE_MAX / size2) | |||||
| return 0; | |||||
| return malloc(size1*size2); | |||||
| } | } | ||||
| static FLaC__INLINE void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2) | |||||
| static inline void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2) | |||||
| { | { | ||||
| size2 += size1; | size2 += size1; | ||||
| if(size2 < size1) | if(size2 < size1) | ||||
| @@ -164,7 +161,7 @@ static FLaC__INLINE void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t | |||||
| return realloc(ptr, size2); | return realloc(ptr, size2); | ||||
| } | } | ||||
| static FLaC__INLINE void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) | |||||
| static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) | |||||
| { | { | ||||
| size2 += size1; | size2 += size1; | ||||
| if(size2 < size1) | if(size2 < size1) | ||||
| @@ -175,7 +172,7 @@ static FLaC__INLINE void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t | |||||
| return realloc(ptr, size3); | 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) | |||||
| static inline void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4) | |||||
| { | { | ||||
| size2 += size1; | size2 += size1; | ||||
| if(size2 < size1) | if(size2 < size1) | ||||
| @@ -189,7 +186,7 @@ static FLaC__INLINE void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t | |||||
| return realloc(ptr, size4); | return realloc(ptr, size4); | ||||
| } | } | ||||
| static FLaC__INLINE void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2) | |||||
| static inline void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2) | |||||
| { | { | ||||
| if(!size1 || !size2) | if(!size1 || !size2) | ||||
| return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ | return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ | ||||
| @@ -199,7 +196,7 @@ static FLaC__INLINE void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t | |||||
| } | } | ||||
| /* size1 * (size2 + size3) */ | /* size1 * (size2 + size3) */ | ||||
| static FLaC__INLINE void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3) | |||||
| static inline void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3) | |||||
| { | { | ||||
| if(!size1 || (!size2 && !size3)) | if(!size1 || (!size2 && !size3)) | ||||
| return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ | return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2001-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2004-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -0,0 +1,195 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | |||||
| * Copyright (C) 2012 Xiph.org Foundation | |||||
| * | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * | |||||
| * - Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * | |||||
| * - Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in the | |||||
| * documentation and/or other materials provided with the distribution. | |||||
| * | |||||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||||
| * contributors may be used to endorse or promote products derived from | |||||
| * this software without specific prior written permission. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||||
| */ | |||||
| /* This is the prefered location of all CPP hackery to make $random_compiler | |||||
| * work like something approaching a C99 (or maybe more accurately GNU99) | |||||
| * compiler. | |||||
| * | |||||
| * It is assumed that this header will be included after "config.h". | |||||
| */ | |||||
| #ifndef FLAC__SHARE__COMPAT_H | |||||
| #define FLAC__SHARE__COMPAT_H | |||||
| #if defined _WIN32 && !defined __CYGWIN__ | |||||
| /* where MSVC puts unlink() */ | |||||
| # include <io.h> | |||||
| #else | |||||
| # include <unistd.h> | |||||
| #endif | |||||
| #if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ | |||||
| #include <sys/types.h> /* for off_t */ | |||||
| #define FLAC__off_t __int64 /* use this instead of off_t to fix the 2 GB limit */ | |||||
| #if !defined __MINGW32__ | |||||
| #define fseeko _fseeki64 | |||||
| #define ftello _ftelli64 | |||||
| #else /* MinGW */ | |||||
| #if !defined(HAVE_FSEEKO) | |||||
| #define fseeko fseeko64 | |||||
| #define ftello ftello64 | |||||
| #endif | |||||
| #endif | |||||
| #else | |||||
| #define FLAC__off_t off_t | |||||
| #endif | |||||
| #if HAVE_INTTYPES_H | |||||
| #define __STDC_FORMAT_MACROS | |||||
| #include <inttypes.h> | |||||
| #endif | |||||
| #if defined(_MSC_VER) | |||||
| #define strtoll _strtoi64 | |||||
| #define strtoull _strtoui64 | |||||
| #endif | |||||
| #if defined(_MSC_VER) | |||||
| #if _MSC_VER < 1500 | |||||
| /* Visual Studio 2008 has restrict. */ | |||||
| #define restrict __restrict | |||||
| #endif | |||||
| #define inline __inline | |||||
| #endif | |||||
| /* adjust for compilers that can't understand using LLU suffix for uint64_t literals */ | |||||
| #ifdef _MSC_VER | |||||
| #define FLAC__U64L(x) x | |||||
| #else | |||||
| #define FLAC__U64L(x) x##LLU | |||||
| #endif | |||||
| #if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ | |||||
| #define FLAC__STRNCASECMP strnicmp | |||||
| #else | |||||
| #define FLAC__STRNCASECMP strncasecmp | |||||
| #endif | |||||
| #if defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__ || defined __EMX__ | |||||
| #include <io.h> /* for _setmode(), chmod() */ | |||||
| #include <fcntl.h> /* for _O_BINARY */ | |||||
| #else | |||||
| #include <unistd.h> /* for chown(), unlink() */ | |||||
| #endif | |||||
| #if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ | |||||
| #if defined __BORLANDC__ | |||||
| #include <utime.h> /* for utime() */ | |||||
| #else | |||||
| #include <sys/utime.h> /* for utime() */ | |||||
| #endif | |||||
| #else | |||||
| #include <sys/types.h> /* some flavors of BSD (like OS X) require this to get time_t */ | |||||
| #include <utime.h> /* for utime() */ | |||||
| #endif | |||||
| #if defined _MSC_VER | |||||
| # if _MSC_VER >= 1600 | |||||
| /* Visual Studio 2010 has decent C99 support */ | |||||
| # include <stdint.h> | |||||
| # define PRIu64 "llu" | |||||
| # define PRId64 "lld" | |||||
| # define PRIx64 "llx" | |||||
| # else | |||||
| # include <limits.h> | |||||
| # ifndef UINT32_MAX | |||||
| # define UINT32_MAX _UI32_MAX | |||||
| # endif | |||||
| typedef unsigned __int64 uint64_t; | |||||
| typedef unsigned __int32 uint32_t; | |||||
| typedef unsigned __int16 uint16_t; | |||||
| typedef unsigned __int8 uint8_t; | |||||
| typedef __int64 int64_t; | |||||
| typedef __int32 int32_t; | |||||
| typedef __int16 int16_t; | |||||
| typedef __int8 int8_t; | |||||
| # define PRIu64 "I64u" | |||||
| # define PRId64 "I64d" | |||||
| # define PRIx64 "I64x" | |||||
| # endif | |||||
| #endif /* defined _MSC_VER */ | |||||
| #ifdef _WIN32 | |||||
| /* All char* strings are in UTF-8 format. Added to support Unicode files on Windows */ | |||||
| #define flac_printf printf_utf8 | |||||
| #define flac_fprintf fprintf_utf8 | |||||
| #define flac_vfprintf vfprintf_utf8 | |||||
| #define flac_fopen fopen_utf8 | |||||
| #define flac_chmod chmod_utf8 | |||||
| #define flac_utime utime_utf8 | |||||
| #define flac_unlink unlink_utf8 | |||||
| #define flac_rename rename_utf8 | |||||
| #define flac_stat _stat64_utf8 | |||||
| #else | |||||
| #define flac_printf printf | |||||
| #define flac_fprintf fprintf | |||||
| #define flac_vfprintf vfprintf | |||||
| #define flac_fopen fopen | |||||
| #define flac_chmod chmod | |||||
| #define flac_utime utime | |||||
| #define flac_unlink unlink | |||||
| #define flac_rename rename | |||||
| #ifdef _WIN32 | |||||
| #define flac_stat _stat64 | |||||
| #else | |||||
| #define flac_stat stat | |||||
| #endif | |||||
| #endif | |||||
| #ifdef _WIN32 | |||||
| #define flac_stat_s __stat64 /* stat struct */ | |||||
| #define flac_fstat _fstat64 | |||||
| #else | |||||
| #define flac_stat_s stat /* stat struct */ | |||||
| #define flac_fstat fstat | |||||
| #endif | |||||
| /* FLAC needs to compile and work correctly on systems with a norrmal ISO C99 | |||||
| * snprintf as well as Microsoft Visual Studio which has an non-standards | |||||
| * conformant snprint_s function. | |||||
| * | |||||
| * This function wraps the MS version to behave more like the the ISO version. | |||||
| */ | |||||
| #ifdef __cplusplus | |||||
| extern "C" { | |||||
| #endif | |||||
| int flac_snprintf(char *str, size_t size, const char *fmt, ...); | |||||
| #ifdef __cplusplus | |||||
| }; | |||||
| #endif | |||||
| #endif /* FLAC__SHARE__COMPAT_H */ | |||||
| @@ -0,0 +1,52 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | |||||
| * Copyright (C) 2012 Xiph.org Foundation | |||||
| * | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * | |||||
| * - Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * | |||||
| * - Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in the | |||||
| * documentation and/or other materials provided with the distribution. | |||||
| * | |||||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||||
| * contributors may be used to endorse or promote products derived from | |||||
| * this software without specific prior written permission. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||||
| */ | |||||
| /* It is assumed that this header will be included after "config.h". */ | |||||
| #if HAVE_BSWAP32 /* GCC and Clang */ | |||||
| #define ENDSWAP_32(x) (__builtin_bswap32 (x)) | |||||
| #elif defined _MSC_VER /* Windows. Apparently in <stdlib.h>. */ | |||||
| #define ENDSWAP_32(x) (_byteswap_ulong (x)) | |||||
| #elif defined HAVE_BYTESWAP_H /* Linux */ | |||||
| #include <byteswap.h> | |||||
| #define ENDSWAP_32(x) (bswap_32 (x)) | |||||
| #else | |||||
| #define ENDSWAP_32(x) ((((x) >> 24) & 0xFF) + (((x) >> 8) & 0xFF00) + (((x) & 0xFF00) << 8) + (((x) & 0xFF) << 24)) | |||||
| #endif | |||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -55,25 +56,30 @@ | |||||
| * \{ | * \{ | ||||
| */ | */ | ||||
| #if defined(FLAC__NO_DLL) || !defined(_MSC_VER) | |||||
| #if defined(FLAC__NO_DLL) | |||||
| #define FLAC_API | #define FLAC_API | ||||
| #else | |||||
| #elif defined(_MSC_VER) | |||||
| #ifdef FLAC_API_EXPORTS | #ifdef FLAC_API_EXPORTS | ||||
| #define FLAC_API _declspec(dllexport) | #define FLAC_API _declspec(dllexport) | ||||
| #else | #else | ||||
| #define FLAC_API _declspec(dllimport) | #define FLAC_API _declspec(dllimport) | ||||
| #endif | #endif | ||||
| #elif defined(FLAC__USE_VISIBILITY_ATTR) | |||||
| #define FLAC_API __attribute__ ((visibility ("default"))) | |||||
| #else | |||||
| #define FLAC_API | |||||
| #endif | #endif | ||||
| /** These #defines will mirror the libtool-based library version number, see | /** These #defines will mirror the libtool-based library version number, see | ||||
| * http://www.gnu.org/software/libtool/manual.html#Libtool-versioning | |||||
| * http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning | |||||
| */ | */ | ||||
| #define FLAC_API_VERSION_CURRENT 10 | |||||
| #define FLAC_API_VERSION_CURRENT 11 | |||||
| #define FLAC_API_VERSION_REVISION 0 /**< see above */ | #define FLAC_API_VERSION_REVISION 0 /**< see above */ | ||||
| #define FLAC_API_VERSION_AGE 2 /**< see above */ | |||||
| #define FLAC_API_VERSION_AGE 3 /**< see above */ | |||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||
| extern "C" { | extern "C" { | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -879,6 +880,18 @@ extern FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN; /**< == 24 (bit | |||||
| */ | */ | ||||
| FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate); | FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate); | ||||
| /** Tests that a blocksize at the given sample rate is valid for the FLAC | |||||
| * subset. | |||||
| * | |||||
| * \param blocksize The blocksize to test for compliance. | |||||
| * \param sample_rate The sample rate is needed, since the valid subset | |||||
| * blocksize depends on the sample rate. | |||||
| * \retval FLAC__bool | |||||
| * \c true if the given blocksize conforms to the specification for the | |||||
| * subset at the given sample rate, else \c false. | |||||
| */ | |||||
| FLAC_API FLAC__bool FLAC__format_blocksize_is_subset(unsigned blocksize, unsigned sample_rate); | |||||
| /** Tests that a sample rate is valid for the FLAC subset. The subset rules | /** Tests that a sample rate is valid for the FLAC subset. The subset rules | ||||
| * for valid sample rates are slightly more complex since the rate has to | * for valid sample rates are slightly more complex since the rate has to | ||||
| * be expressible completely in the frame header. | * be expressible completely in the frame header. | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2001-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -36,46 +37,6 @@ | |||||
| #include "include/private/bitmath.h" | #include "include/private/bitmath.h" | ||||
| #include "../assert.h" | #include "../assert.h" | ||||
| /* An example of what FLAC__bitmath_ilog2() computes: | |||||
| * | |||||
| * ilog2( 0) = assertion failure | |||||
| * ilog2( 1) = 0 | |||||
| * ilog2( 2) = 1 | |||||
| * ilog2( 3) = 1 | |||||
| * ilog2( 4) = 2 | |||||
| * ilog2( 5) = 2 | |||||
| * ilog2( 6) = 2 | |||||
| * ilog2( 7) = 2 | |||||
| * ilog2( 8) = 3 | |||||
| * ilog2( 9) = 3 | |||||
| * ilog2(10) = 3 | |||||
| * ilog2(11) = 3 | |||||
| * ilog2(12) = 3 | |||||
| * ilog2(13) = 3 | |||||
| * ilog2(14) = 3 | |||||
| * ilog2(15) = 3 | |||||
| * ilog2(16) = 4 | |||||
| * ilog2(17) = 4 | |||||
| * ilog2(18) = 4 | |||||
| */ | |||||
| unsigned FLAC__bitmath_ilog2(FLAC__uint32 v) | |||||
| { | |||||
| unsigned l = 0; | |||||
| FLAC__ASSERT(v > 0); | |||||
| while(v >>= 1) | |||||
| l++; | |||||
| return l; | |||||
| } | |||||
| unsigned FLAC__bitmath_ilog2_wide(FLAC__uint64 v) | |||||
| { | |||||
| unsigned l = 0; | |||||
| FLAC__ASSERT(v > 0); | |||||
| while(v >>= 1) | |||||
| l++; | |||||
| return l; | |||||
| } | |||||
| /* An example of what FLAC__bitmath_silog2() computes: | /* An example of what FLAC__bitmath_silog2() computes: | ||||
| * | * | ||||
| * silog2(-10) = 5 | * silog2(-10) = 5 | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -33,49 +34,28 @@ | |||||
| # include <config.h> | # include <config.h> | ||||
| #endif | #endif | ||||
| #include <stdlib.h> /* for malloc() */ | |||||
| #include <string.h> /* for memcpy(), memset() */ | |||||
| #ifdef _MSC_VER | |||||
| #include <winsock.h> /* for ntohl() */ | |||||
| #elif defined FLAC__SYS_DARWIN | |||||
| #include <machine/endian.h> /* for ntohl() */ | |||||
| #elif defined __MINGW32__ | |||||
| #include <winsock.h> /* for ntohl() */ | |||||
| #else | |||||
| #include <netinet/in.h> /* for ntohl() */ | |||||
| #endif | |||||
| #include <stdlib.h> | |||||
| #include <string.h> | |||||
| #include "include/private/bitmath.h" | #include "include/private/bitmath.h" | ||||
| #include "include/private/bitreader.h" | #include "include/private/bitreader.h" | ||||
| #include "include/private/crc.h" | #include "include/private/crc.h" | ||||
| #include "../assert.h" | #include "../assert.h" | ||||
| #include "../compat.h" | |||||
| #include "../endswap.h" | |||||
| /* Things should be fastest when this matches the machine word size */ | /* 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 COUNT_ZERO_MSBS below to match */ | |||||
| /* WATCHOUT: there are a few places where the code will not work unless brword is >= 32 bits wide */ | |||||
| /* WATCHOUT: if you change this you must also change the following #defines down to FLAC__clz_uint32 below to match */ | |||||
| /* WATCHOUT: there are a few places where the code will not work unless uint32_t is >= 32 bits wide */ | |||||
| /* also, some sections currently only have fast versions for 4 or 8 bytes per word */ | /* also, some sections currently only have fast versions for 4 or 8 bytes per word */ | ||||
| typedef FLAC__uint32 brword; | |||||
| #define FLAC__BYTES_PER_WORD 4 | |||||
| #define FLAC__BITS_PER_WORD 32 | |||||
| #define FLAC__BYTES_PER_WORD 4 /* sizeof uint32_t */ | |||||
| #define FLAC__BITS_PER_WORD (8 * FLAC__BYTES_PER_WORD) | |||||
| #define FLAC__WORD_ALL_ONES ((FLAC__uint32)0xffffffff) | #define FLAC__WORD_ALL_ONES ((FLAC__uint32)0xffffffff) | ||||
| /* SWAP_BE_WORD_TO_HOST swaps bytes in a brword (which is always big-endian) if necessary to match host byte order */ | |||||
| /* SWAP_BE_WORD_TO_HOST swaps bytes in a uint32_t (which is always big-endian) if necessary to match host byte order */ | |||||
| #if WORDS_BIGENDIAN | #if WORDS_BIGENDIAN | ||||
| #define SWAP_BE_WORD_TO_HOST(x) (x) | #define SWAP_BE_WORD_TO_HOST(x) (x) | ||||
| #else | #else | ||||
| #if defined (_MSC_VER) && defined (_X86_) | |||||
| #define SWAP_BE_WORD_TO_HOST(x) local_swap32_(x) | |||||
| #else | |||||
| #define SWAP_BE_WORD_TO_HOST(x) ntohl(x) | |||||
| #endif | |||||
| #define SWAP_BE_WORD_TO_HOST(x) ENDSWAP_32(x) | |||||
| #endif | #endif | ||||
| /* counts the # of zero MSBs in a word */ | |||||
| #define COUNT_ZERO_MSBS(word) ( \ | |||||
| (word) <= 0xffff ? \ | |||||
| ( (word) <= 0xff? byte_to_unary_table[word] + 24 : byte_to_unary_table[(word) >> 8] + 16 ) : \ | |||||
| ( (word) <= 0xffffff? byte_to_unary_table[word >> 16] + 8 : byte_to_unary_table[(word) >> 24] ) \ | |||||
| ) | |||||
| /* this alternate might be slightly faster on some systems/compilers: */ | |||||
| #define COUNT_ZERO_MSBS2(word) ( (word) <= 0xff ? byte_to_unary_table[word] + 24 : ((word) <= 0xffff ? byte_to_unary_table[(word) >> 8] + 16 : ((word) <= 0xffffff ? byte_to_unary_table[(word) >> 16] + 8 : byte_to_unary_table[(word) >> 24])) ) | |||||
| /* | /* | ||||
| * This should be at least twice as large as the largest number of words | * This should be at least twice as large as the largest number of words | ||||
| @@ -93,50 +73,11 @@ typedef FLAC__uint32 brword; | |||||
| */ | */ | ||||
| static const unsigned FLAC__BITREADER_DEFAULT_CAPACITY = 65536u / FLAC__BITS_PER_WORD; /* in words */ | static const unsigned FLAC__BITREADER_DEFAULT_CAPACITY = 65536u / FLAC__BITS_PER_WORD; /* in words */ | ||||
| static const unsigned char byte_to_unary_table[] = { | |||||
| 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, | |||||
| 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |||||
| 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |||||
| 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |||||
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |||||
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |||||
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |||||
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |||||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | |||||
| }; | |||||
| #ifdef min | |||||
| #undef min | |||||
| #endif | |||||
| #define min(x,y) ((x)<(y)?(x):(y)) | |||||
| #ifdef max | |||||
| #undef max | |||||
| #endif | |||||
| #define max(x,y) ((x)>(y)?(x):(y)) | |||||
| /* adjust for compilers that can't understand using LLU suffix for uint64_t literals */ | |||||
| #ifdef _MSC_VER | |||||
| #define FLAC__U64L(x) x | |||||
| #else | |||||
| #define FLAC__U64L(x) x##LLU | |||||
| #endif | |||||
| #ifndef FLaC__INLINE | |||||
| #define FLaC__INLINE inline | |||||
| #endif | |||||
| /* WATCHOUT: assembly routines rely on the order in which these fields are declared */ | /* WATCHOUT: assembly routines rely on the order in which these fields are declared */ | ||||
| struct FLAC__BitReader { | struct FLAC__BitReader { | ||||
| /* any partially-consumed word at the head will stay right-justified as bits are consumed from the left */ | /* any partially-consumed word at the head will stay right-justified as bits are consumed from the left */ | ||||
| /* any incomplete word at the tail will be left-justified, and bytes from the read callback are added on the right */ | /* any incomplete word at the tail will be left-justified, and bytes from the read callback are added on the right */ | ||||
| brword *buffer; | |||||
| uint32_t *buffer; | |||||
| unsigned capacity; /* in words */ | unsigned capacity; /* in words */ | ||||
| unsigned words; /* # of completed words in buffer */ | unsigned words; /* # of completed words in buffer */ | ||||
| unsigned bytes; /* # of bytes in incomplete word at buffer[words] */ | unsigned bytes; /* # of bytes in incomplete word at buffer[words] */ | ||||
| @@ -149,7 +90,7 @@ struct FLAC__BitReader { | |||||
| FLAC__CPUInfo cpu_info; | FLAC__CPUInfo cpu_info; | ||||
| }; | }; | ||||
| static FLaC__INLINE void crc16_update_word_(FLAC__BitReader *br, brword word) | |||||
| static inline void crc16_update_word_(FLAC__BitReader *br, uint32_t word) | |||||
| { | { | ||||
| register unsigned crc = br->read_crc16; | register unsigned crc = br->read_crc16; | ||||
| #if FLAC__BYTES_PER_WORD == 4 | #if FLAC__BYTES_PER_WORD == 4 | ||||
| @@ -203,7 +144,7 @@ FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br) | |||||
| return false; /* no space left, buffer is too small; see note for FLAC__BITREADER_DEFAULT_CAPACITY */ | return false; /* no space left, buffer is too small; see note for FLAC__BITREADER_DEFAULT_CAPACITY */ | ||||
| target = ((FLAC__byte*)(br->buffer+br->words)) + br->bytes; | target = ((FLAC__byte*)(br->buffer+br->words)) + br->bytes; | ||||
| /* before reading, if the existing reader looks like this (say brword is 32 bits wide) | |||||
| /* before reading, if the existing reader looks like this (say uint32_t is 32 bits wide) | |||||
| * bitstream : 11 22 33 44 55 br->words=1 br->bytes=1 (partial tail word is left-justified) | * bitstream : 11 22 33 44 55 br->words=1 br->bytes=1 (partial tail word is left-justified) | ||||
| * buffer[BE]: 11 22 33 44 55 ?? ?? ?? (shown layed out as bytes sequentially in memory) | * buffer[BE]: 11 22 33 44 55 ?? ?? ?? (shown layed out as bytes sequentially in memory) | ||||
| * buffer[LE]: 44 33 22 11 ?? ?? ?? 55 (?? being don't-care) | * buffer[LE]: 44 33 22 11 ?? ?? ?? 55 (?? being don't-care) | ||||
| @@ -237,13 +178,6 @@ FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br) | |||||
| #if WORDS_BIGENDIAN | #if WORDS_BIGENDIAN | ||||
| #else | #else | ||||
| end = (br->words*FLAC__BYTES_PER_WORD + br->bytes + bytes + (FLAC__BYTES_PER_WORD-1)) / FLAC__BYTES_PER_WORD; | end = (br->words*FLAC__BYTES_PER_WORD + br->bytes + bytes + (FLAC__BYTES_PER_WORD-1)) / FLAC__BYTES_PER_WORD; | ||||
| # if defined(_MSC_VER) && defined (_X86_) && (FLAC__BYTES_PER_WORD == 4) | |||||
| if(br->cpu_info.type == FLAC__CPUINFO_TYPE_IA32 && br->cpu_info.data.ia32.bswap) { | |||||
| start = br->words; | |||||
| local_swap32_block_(br->buffer + start, end - start); | |||||
| } | |||||
| else | |||||
| # endif | |||||
| for(start = br->words; start < end; start++) | for(start = br->words; start < end; start++) | ||||
| br->buffer[start] = SWAP_BE_WORD_TO_HOST(br->buffer[start]); | br->buffer[start] = SWAP_BE_WORD_TO_HOST(br->buffer[start]); | ||||
| #endif | #endif | ||||
| @@ -269,7 +203,7 @@ FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br) | |||||
| FLAC__BitReader *FLAC__bitreader_new(void) | FLAC__BitReader *FLAC__bitreader_new(void) | ||||
| { | { | ||||
| FLAC__BitReader *br = (FLAC__BitReader*)calloc(1, sizeof(FLAC__BitReader)); | |||||
| FLAC__BitReader *br = (FLAC__BitReader*) calloc(1, sizeof(FLAC__BitReader)); | |||||
| /* calloc() implies: | /* calloc() implies: | ||||
| memset(br, 0, sizeof(FLAC__BitReader)); | memset(br, 0, sizeof(FLAC__BitReader)); | ||||
| @@ -304,7 +238,7 @@ FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__CPUInfo cpu, FLAC__Bi | |||||
| br->words = br->bytes = 0; | br->words = br->bytes = 0; | ||||
| br->consumed_words = br->consumed_bits = 0; | br->consumed_words = br->consumed_bits = 0; | ||||
| br->capacity = FLAC__BITREADER_DEFAULT_CAPACITY; | br->capacity = FLAC__BITREADER_DEFAULT_CAPACITY; | ||||
| br->buffer = (brword*)malloc(sizeof(brword) * br->capacity); | |||||
| br->buffer = (uint32_t*) malloc(sizeof(uint32_t) * br->capacity); | |||||
| if(br->buffer == 0) | if(br->buffer == 0) | ||||
| return false; | return false; | ||||
| br->read_callback = rcb; | br->read_callback = rcb; | ||||
| @@ -384,29 +318,29 @@ FLAC__uint16 FLAC__bitreader_get_read_crc16(FLAC__BitReader *br) | |||||
| /* CRC any tail bytes in a partially-consumed word */ | /* CRC any tail bytes in a partially-consumed word */ | ||||
| if(br->consumed_bits) { | if(br->consumed_bits) { | ||||
| const brword tail = br->buffer[br->consumed_words]; | |||||
| const uint32_t tail = br->buffer[br->consumed_words]; | |||||
| for( ; br->crc16_align < br->consumed_bits; br->crc16_align += 8) | for( ; br->crc16_align < br->consumed_bits; br->crc16_align += 8) | ||||
| br->read_crc16 = FLAC__CRC16_UPDATE((unsigned)((tail >> (FLAC__BITS_PER_WORD-8-br->crc16_align)) & 0xff), br->read_crc16); | br->read_crc16 = FLAC__CRC16_UPDATE((unsigned)((tail >> (FLAC__BITS_PER_WORD-8-br->crc16_align)) & 0xff), br->read_crc16); | ||||
| } | } | ||||
| return (FLAC__uint16) br->read_crc16; | |||||
| return br->read_crc16; | |||||
| } | } | ||||
| FLaC__INLINE FLAC__bool FLAC__bitreader_is_consumed_byte_aligned(const FLAC__BitReader *br) | |||||
| inline FLAC__bool FLAC__bitreader_is_consumed_byte_aligned(const FLAC__BitReader *br) | |||||
| { | { | ||||
| return ((br->consumed_bits & 7) == 0); | return ((br->consumed_bits & 7) == 0); | ||||
| } | } | ||||
| FLaC__INLINE unsigned FLAC__bitreader_bits_left_for_byte_alignment(const FLAC__BitReader *br) | |||||
| inline unsigned FLAC__bitreader_bits_left_for_byte_alignment(const FLAC__BitReader *br) | |||||
| { | { | ||||
| return 8 - (br->consumed_bits & 7); | return 8 - (br->consumed_bits & 7); | ||||
| } | } | ||||
| FLaC__INLINE unsigned FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader *br) | |||||
| inline unsigned FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader *br) | |||||
| { | { | ||||
| return (br->words-br->consumed_words)*FLAC__BITS_PER_WORD + br->bytes*8 - br->consumed_bits; | return (br->words-br->consumed_words)*FLAC__BITS_PER_WORD + br->bytes*8 - br->consumed_bits; | ||||
| } | } | ||||
| FLaC__INLINE FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *val, unsigned bits) | |||||
| FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *val, unsigned bits) | |||||
| { | { | ||||
| FLAC__ASSERT(0 != br); | FLAC__ASSERT(0 != br); | ||||
| FLAC__ASSERT(0 != br->buffer); | FLAC__ASSERT(0 != br->buffer); | ||||
| @@ -432,7 +366,7 @@ FLaC__INLINE FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLA | |||||
| if(br->consumed_bits) { | if(br->consumed_bits) { | ||||
| /* this also works when consumed_bits==0, it's just a little slower than necessary for that case */ | /* this also works when consumed_bits==0, it's just a little slower than necessary for that case */ | ||||
| const unsigned n = FLAC__BITS_PER_WORD - br->consumed_bits; | const unsigned n = FLAC__BITS_PER_WORD - br->consumed_bits; | ||||
| const brword word = br->buffer[br->consumed_words]; | |||||
| const uint32_t word = br->buffer[br->consumed_words]; | |||||
| if(bits < n) { | if(bits < n) { | ||||
| *val = (word & (FLAC__WORD_ALL_ONES >> br->consumed_bits)) >> (n-bits); | *val = (word & (FLAC__WORD_ALL_ONES >> br->consumed_bits)) >> (n-bits); | ||||
| br->consumed_bits += bits; | br->consumed_bits += bits; | ||||
| @@ -451,7 +385,7 @@ FLaC__INLINE FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLA | |||||
| return true; | return true; | ||||
| } | } | ||||
| else { | else { | ||||
| const brword word = br->buffer[br->consumed_words]; | |||||
| const uint32_t word = br->buffer[br->consumed_words]; | |||||
| if(bits < FLAC__BITS_PER_WORD) { | if(bits < FLAC__BITS_PER_WORD) { | ||||
| *val = word >> (FLAC__BITS_PER_WORD-bits); | *val = word >> (FLAC__BITS_PER_WORD-bits); | ||||
| br->consumed_bits = bits; | br->consumed_bits = bits; | ||||
| @@ -517,7 +451,7 @@ FLAC__bool FLAC__bitreader_read_raw_uint64(FLAC__BitReader *br, FLAC__uint64 *va | |||||
| return true; | return true; | ||||
| } | } | ||||
| FLaC__INLINE FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val) | |||||
| inline FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val) | |||||
| { | { | ||||
| FLAC__uint32 x8, x32 = 0; | FLAC__uint32 x8, x32 = 0; | ||||
| @@ -557,7 +491,7 @@ FLAC__bool FLAC__bitreader_skip_bits_no_crc(FLAC__BitReader *br, unsigned bits) | |||||
| FLAC__uint32 x; | FLAC__uint32 x; | ||||
| if(n != 0) { | if(n != 0) { | ||||
| m = min(8-n, bits); | |||||
| m = flac_min(8-n, bits); | |||||
| if(!FLAC__bitreader_read_raw_uint32(br, &x, m)) | if(!FLAC__bitreader_read_raw_uint32(br, &x, m)) | ||||
| return false; | return false; | ||||
| bits -= m; | bits -= m; | ||||
| @@ -632,7 +566,7 @@ FLAC__bool FLAC__bitreader_read_byte_block_aligned_no_crc(FLAC__BitReader *br, F | |||||
| /* step 2: read whole words in chunks */ | /* step 2: read whole words in chunks */ | ||||
| while(nvals >= FLAC__BYTES_PER_WORD) { | while(nvals >= FLAC__BYTES_PER_WORD) { | ||||
| if(br->consumed_words < br->words) { | if(br->consumed_words < br->words) { | ||||
| const brword word = br->buffer[br->consumed_words++]; | |||||
| const uint32_t word = br->buffer[br->consumed_words++]; | |||||
| #if FLAC__BYTES_PER_WORD == 4 | #if FLAC__BYTES_PER_WORD == 4 | ||||
| val[0] = (FLAC__byte)(word >> 24); | val[0] = (FLAC__byte)(word >> 24); | ||||
| val[1] = (FLAC__byte)(word >> 16); | val[1] = (FLAC__byte)(word >> 16); | ||||
| @@ -668,7 +602,7 @@ FLAC__bool FLAC__bitreader_read_byte_block_aligned_no_crc(FLAC__BitReader *br, F | |||||
| return true; | return true; | ||||
| } | } | ||||
| FLaC__INLINE FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, unsigned *val) | |||||
| FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, unsigned *val) | |||||
| #if 0 /* slow but readable version */ | #if 0 /* slow but readable version */ | ||||
| { | { | ||||
| unsigned bit; | unsigned bit; | ||||
| @@ -697,9 +631,9 @@ FLaC__INLINE FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, | |||||
| *val = 0; | *val = 0; | ||||
| while(1) { | while(1) { | ||||
| while(br->consumed_words < br->words) { /* if we've not consumed up to a partial tail word... */ | while(br->consumed_words < br->words) { /* if we've not consumed up to a partial tail word... */ | ||||
| brword b = br->buffer[br->consumed_words] << br->consumed_bits; | |||||
| uint32_t b = br->buffer[br->consumed_words] << br->consumed_bits; | |||||
| if(b) { | if(b) { | ||||
| i = COUNT_ZERO_MSBS(b); | |||||
| i = FLAC__clz_uint32(b); | |||||
| *val += i; | *val += i; | ||||
| i++; | i++; | ||||
| br->consumed_bits += i; | br->consumed_bits += i; | ||||
| @@ -725,11 +659,11 @@ FLaC__INLINE FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, | |||||
| * us data a byte at a time (unlikely), br->consumed_bits may not | * us data a byte at a time (unlikely), br->consumed_bits may not | ||||
| * be zero. | * be zero. | ||||
| */ | */ | ||||
| if(br->bytes) { | |||||
| if(br->bytes*8 > br->consumed_bits) { | |||||
| const unsigned end = br->bytes * 8; | const unsigned end = br->bytes * 8; | ||||
| brword b = (br->buffer[br->consumed_words] & (FLAC__WORD_ALL_ONES << (FLAC__BITS_PER_WORD-end))) << br->consumed_bits; | |||||
| uint32_t b = (br->buffer[br->consumed_words] & (FLAC__WORD_ALL_ONES << (FLAC__BITS_PER_WORD-end))) << br->consumed_bits; | |||||
| if(b) { | if(b) { | ||||
| i = COUNT_ZERO_MSBS(b); | |||||
| i = FLAC__clz_uint32(b); | |||||
| *val += i; | *val += i; | ||||
| i++; | i++; | ||||
| br->consumed_bits += i; | br->consumed_bits += i; | ||||
| @@ -738,7 +672,7 @@ FLaC__INLINE FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, | |||||
| } | } | ||||
| else { | else { | ||||
| *val += end - br->consumed_bits; | *val += end - br->consumed_bits; | ||||
| br->consumed_bits += end; | |||||
| br->consumed_bits = end; | |||||
| FLAC__ASSERT(br->consumed_bits < FLAC__BITS_PER_WORD); | FLAC__ASSERT(br->consumed_bits < FLAC__BITS_PER_WORD); | ||||
| /* didn't find stop bit yet, have to keep going... */ | /* didn't find stop bit yet, have to keep going... */ | ||||
| } | } | ||||
| @@ -759,7 +693,7 @@ FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, unsig | |||||
| FLAC__ASSERT(parameter <= 31); | FLAC__ASSERT(parameter <= 31); | ||||
| /* read the unary MSBs and end bit */ | /* read the unary MSBs and end bit */ | ||||
| if(!FLAC__bitreader_read_unary_unsigned(br, (unsigned int*) &msbs)) | |||||
| if(!FLAC__bitreader_read_unary_unsigned(br, &msbs)) | |||||
| return false; | return false; | ||||
| /* read the binary LSBs */ | /* read the binary LSBs */ | ||||
| @@ -777,379 +711,144 @@ FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, unsig | |||||
| } | } | ||||
| /* this is by far the most heavily used reader call. it ain't pretty but it's fast */ | /* this is by far the most heavily used reader call. it ain't pretty but it's fast */ | ||||
| /* a lot of the logic is copied, then adapted, from FLAC__bitreader_read_unary_unsigned() and FLAC__bitreader_read_raw_uint32() */ | |||||
| FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter) | FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter) | ||||
| /* OPT: possibly faster version for use with MSVC */ | |||||
| #ifdef _MSC_VER | |||||
| { | { | ||||
| unsigned i; | |||||
| unsigned uval = 0; | |||||
| unsigned bits; /* the # of binary LSBs left to read to finish a rice codeword */ | |||||
| /* try and get br->consumed_words and br->consumed_bits into register; | /* try and get br->consumed_words and br->consumed_bits into register; | ||||
| * must remember to flush them back to *br before calling other | * must remember to flush them back to *br before calling other | ||||
| * bitwriter functions that use them, and before returning */ | |||||
| register unsigned cwords; | |||||
| register unsigned cbits; | |||||
| * bitreader functions that use them, and before returning */ | |||||
| unsigned cwords, words, lsbs, msbs, x, y; | |||||
| unsigned ucbits; /* keep track of the number of unconsumed bits in word */ | |||||
| uint32_t b; | |||||
| int *val, *end; | |||||
| FLAC__ASSERT(0 != br); | FLAC__ASSERT(0 != br); | ||||
| FLAC__ASSERT(0 != br->buffer); | FLAC__ASSERT(0 != br->buffer); | ||||
| /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */ | /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */ | ||||
| FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32); | FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32); | ||||
| FLAC__ASSERT(parameter < 32); | FLAC__ASSERT(parameter < 32); | ||||
| /* the above two asserts also guarantee that the binary part never straddles more that 2 words, so we don't have to loop to read it */ | |||||
| if(nvals == 0) | |||||
| return true; | |||||
| cbits = br->consumed_bits; | |||||
| cwords = br->consumed_words; | |||||
| /* the above two asserts also guarantee that the binary part never straddles more than 2 words, so we don't have to loop to read it */ | |||||
| while(1) { | |||||
| val = vals; | |||||
| end = vals + nvals; | |||||
| /* read unary part */ | |||||
| while(1) { | |||||
| while(cwords < br->words) { /* if we've not consumed up to a partial tail word... */ | |||||
| brword b = br->buffer[cwords] << cbits; | |||||
| if(b) { | |||||
| #if 0 /* slower, probably due to bad register allocation... */ && defined FLAC__CPU_IA32 && !defined FLAC__NO_ASM && FLAC__BITS_PER_WORD == 32 | |||||
| __asm { | |||||
| bsr eax, b | |||||
| not eax | |||||
| and eax, 31 | |||||
| mov i, eax | |||||
| } | |||||
| #else | |||||
| i = COUNT_ZERO_MSBS(b); | |||||
| #endif | |||||
| uval += i; | |||||
| bits = parameter; | |||||
| i++; | |||||
| cbits += i; | |||||
| if(cbits == FLAC__BITS_PER_WORD) { | |||||
| crc16_update_word_(br, br->buffer[cwords]); | |||||
| cwords++; | |||||
| cbits = 0; | |||||
| } | |||||
| goto break1; | |||||
| } | |||||
| else { | |||||
| uval += FLAC__BITS_PER_WORD - cbits; | |||||
| crc16_update_word_(br, br->buffer[cwords]); | |||||
| cwords++; | |||||
| cbits = 0; | |||||
| /* didn't find stop bit yet, have to keep going... */ | |||||
| } | |||||
| } | |||||
| /* at this point we've eaten up all the whole words; have to try | |||||
| * reading through any tail bytes before calling the read callback. | |||||
| * this is a repeat of the above logic adjusted for the fact we | |||||
| * don't have a whole word. note though if the client is feeding | |||||
| * us data a byte at a time (unlikely), br->consumed_bits may not | |||||
| * be zero. | |||||
| */ | |||||
| if(br->bytes) { | |||||
| const unsigned end = br->bytes * 8; | |||||
| brword b = (br->buffer[cwords] & (FLAC__WORD_ALL_ONES << (FLAC__BITS_PER_WORD-end))) << cbits; | |||||
| if(b) { | |||||
| i = COUNT_ZERO_MSBS(b); | |||||
| uval += i; | |||||
| bits = parameter; | |||||
| i++; | |||||
| cbits += i; | |||||
| FLAC__ASSERT(cbits < FLAC__BITS_PER_WORD); | |||||
| goto break1; | |||||
| } | |||||
| else { | |||||
| uval += end - cbits; | |||||
| cbits += end; | |||||
| FLAC__ASSERT(cbits < FLAC__BITS_PER_WORD); | |||||
| /* didn't find stop bit yet, have to keep going... */ | |||||
| } | |||||
| } | |||||
| /* flush registers and read; bitreader_read_from_client_() does | |||||
| * not touch br->consumed_bits at all but we still need to set | |||||
| * it in case it fails and we have to return false. | |||||
| */ | |||||
| br->consumed_bits = cbits; | |||||
| br->consumed_words = cwords; | |||||
| if(!bitreader_read_from_client_(br)) | |||||
| if(parameter == 0) { | |||||
| while(val < end) { | |||||
| /* read the unary MSBs and end bit */ | |||||
| if(!FLAC__bitreader_read_unary_unsigned(br, &msbs)) | |||||
| return false; | return false; | ||||
| cwords = br->consumed_words; | |||||
| } | |||||
| break1: | |||||
| /* read binary part */ | |||||
| FLAC__ASSERT(cwords <= br->words); | |||||
| if(bits) { | |||||
| while((br->words-cwords)*FLAC__BITS_PER_WORD + br->bytes*8 - cbits < bits) { | |||||
| /* flush registers and read; bitreader_read_from_client_() does | |||||
| * not touch br->consumed_bits at all but we still need to set | |||||
| * it in case it fails and we have to return false. | |||||
| */ | |||||
| br->consumed_bits = cbits; | |||||
| br->consumed_words = cwords; | |||||
| if(!bitreader_read_from_client_(br)) | |||||
| return false; | |||||
| cwords = br->consumed_words; | |||||
| } | |||||
| if(cwords < br->words) { /* if we've not consumed up to a partial tail word... */ | |||||
| if(cbits) { | |||||
| /* this also works when consumed_bits==0, it's just a little slower than necessary for that case */ | |||||
| const unsigned n = FLAC__BITS_PER_WORD - cbits; | |||||
| const brword word = br->buffer[cwords]; | |||||
| if(bits < n) { | |||||
| uval <<= bits; | |||||
| uval |= (word & (FLAC__WORD_ALL_ONES >> cbits)) >> (n-bits); | |||||
| cbits += bits; | |||||
| goto break2; | |||||
| } | |||||
| uval <<= n; | |||||
| uval |= word & (FLAC__WORD_ALL_ONES >> cbits); | |||||
| bits -= n; | |||||
| crc16_update_word_(br, word); | |||||
| cwords++; | |||||
| cbits = 0; | |||||
| if(bits) { /* if there are still bits left to read, there have to be less than 32 so they will all be in the next word */ | |||||
| uval <<= bits; | |||||
| uval |= (br->buffer[cwords] >> (FLAC__BITS_PER_WORD-bits)); | |||||
| cbits = bits; | |||||
| } | |||||
| goto break2; | |||||
| } | |||||
| else { | |||||
| FLAC__ASSERT(bits < FLAC__BITS_PER_WORD); | |||||
| uval <<= bits; | |||||
| uval |= br->buffer[cwords] >> (FLAC__BITS_PER_WORD-bits); | |||||
| cbits = bits; | |||||
| goto break2; | |||||
| } | |||||
| } | |||||
| else { | |||||
| /* in this case we're starting our read at a partial tail word; | |||||
| * the reader has guaranteed that we have at least 'bits' bits | |||||
| * available to read, which makes this case simpler. | |||||
| */ | |||||
| uval <<= bits; | |||||
| if(cbits) { | |||||
| /* this also works when consumed_bits==0, it's just a little slower than necessary for that case */ | |||||
| FLAC__ASSERT(cbits + bits <= br->bytes*8); | |||||
| uval |= (br->buffer[cwords] & (FLAC__WORD_ALL_ONES >> cbits)) >> (FLAC__BITS_PER_WORD-cbits-bits); | |||||
| cbits += bits; | |||||
| goto break2; | |||||
| } | |||||
| else { | |||||
| uval |= br->buffer[cwords] >> (FLAC__BITS_PER_WORD-bits); | |||||
| cbits += bits; | |||||
| goto break2; | |||||
| } | |||||
| } | |||||
| } | |||||
| break2: | |||||
| /* compose the value */ | |||||
| *vals = (int)(uval >> 1 ^ -(int)(uval & 1)); | |||||
| /* are we done? */ | |||||
| --nvals; | |||||
| if(nvals == 0) { | |||||
| br->consumed_bits = cbits; | |||||
| br->consumed_words = cwords; | |||||
| return true; | |||||
| *val++ = (int)(msbs >> 1) ^ -(int)(msbs & 1); | |||||
| } | } | ||||
| uval = 0; | |||||
| ++vals; | |||||
| return true; | |||||
| } | } | ||||
| } | |||||
| #else | |||||
| { | |||||
| unsigned i; | |||||
| unsigned uval = 0; | |||||
| /* try and get br->consumed_words and br->consumed_bits into register; | |||||
| * must remember to flush them back to *br before calling other | |||||
| * bitwriter functions that use them, and before returning */ | |||||
| register unsigned cwords; | |||||
| register unsigned cbits; | |||||
| unsigned ucbits; /* keep track of the number of unconsumed bits in the buffer */ | |||||
| FLAC__ASSERT(parameter > 0); | |||||
| FLAC__ASSERT(0 != br); | |||||
| FLAC__ASSERT(0 != br->buffer); | |||||
| /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */ | |||||
| FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32); | |||||
| FLAC__ASSERT(parameter < 32); | |||||
| /* the above two asserts also guarantee that the binary part never straddles more than 2 words, so we don't have to loop to read it */ | |||||
| cwords = br->consumed_words; | |||||
| words = br->words; | |||||
| if(nvals == 0) | |||||
| return true; | |||||
| /* if we've not consumed up to a partial tail word... */ | |||||
| if(cwords >= words) { | |||||
| x = 0; | |||||
| goto process_tail; | |||||
| } | |||||
| cbits = br->consumed_bits; | |||||
| cwords = br->consumed_words; | |||||
| ucbits = (br->words-cwords)*FLAC__BITS_PER_WORD + br->bytes*8 - cbits; | |||||
| ucbits = FLAC__BITS_PER_WORD - br->consumed_bits; | |||||
| b = br->buffer[cwords] << br->consumed_bits; /* keep unconsumed bits aligned to left */ | |||||
| while(1) { | |||||
| while(val < end) { | |||||
| /* read the unary MSBs and end bit */ | |||||
| x = y = FLAC__clz2_uint32(b); | |||||
| if(x == FLAC__BITS_PER_WORD) { | |||||
| x = ucbits; | |||||
| do { | |||||
| /* didn't find stop bit yet, have to keep going... */ | |||||
| crc16_update_word_(br, br->buffer[cwords++]); | |||||
| if (cwords >= words) | |||||
| goto incomplete_msbs; | |||||
| b = br->buffer[cwords]; | |||||
| y = FLAC__clz2_uint32(b); | |||||
| x += y; | |||||
| } while(y == FLAC__BITS_PER_WORD); | |||||
| } | |||||
| b <<= y; | |||||
| b <<= 1; /* account for stop bit */ | |||||
| ucbits = (ucbits - x - 1) % FLAC__BITS_PER_WORD; | |||||
| msbs = x; | |||||
| /* read the binary LSBs */ | |||||
| x = b >> (FLAC__BITS_PER_WORD - parameter); | |||||
| if(parameter <= ucbits) { | |||||
| ucbits -= parameter; | |||||
| b <<= parameter; | |||||
| } else { | |||||
| /* there are still bits left to read, they will all be in the next word */ | |||||
| crc16_update_word_(br, br->buffer[cwords++]); | |||||
| if (cwords >= words) | |||||
| goto incomplete_lsbs; | |||||
| b = br->buffer[cwords]; | |||||
| ucbits += FLAC__BITS_PER_WORD - parameter; | |||||
| x |= b >> ucbits; | |||||
| b <<= FLAC__BITS_PER_WORD - ucbits; | |||||
| } | |||||
| lsbs = x; | |||||
| /* read unary part */ | |||||
| while(1) { | |||||
| while(cwords < br->words) { /* if we've not consumed up to a partial tail word... */ | |||||
| brword b = br->buffer[cwords] << cbits; | |||||
| if(b) { | |||||
| #if 0 /* is not discernably faster... */ && defined FLAC__CPU_IA32 && !defined FLAC__NO_ASM && FLAC__BITS_PER_WORD == 32 && defined __GNUC__ | |||||
| asm volatile ( | |||||
| "bsrl %1, %0;" | |||||
| "notl %0;" | |||||
| "andl $31, %0;" | |||||
| : "=r"(i) | |||||
| : "r"(b) | |||||
| ); | |||||
| #else | |||||
| i = COUNT_ZERO_MSBS(b); | |||||
| #endif | |||||
| uval += i; | |||||
| cbits += i; | |||||
| cbits++; /* skip over stop bit */ | |||||
| if(cbits >= FLAC__BITS_PER_WORD) { /* faster way of testing if(cbits == FLAC__BITS_PER_WORD) */ | |||||
| crc16_update_word_(br, br->buffer[cwords]); | |||||
| cwords++; | |||||
| cbits = 0; | |||||
| } | |||||
| goto break1; | |||||
| } | |||||
| else { | |||||
| uval += FLAC__BITS_PER_WORD - cbits; | |||||
| crc16_update_word_(br, br->buffer[cwords]); | |||||
| cwords++; | |||||
| cbits = 0; | |||||
| /* didn't find stop bit yet, have to keep going... */ | |||||
| } | |||||
| } | |||||
| /* at this point we've eaten up all the whole words; have to try | |||||
| * reading through any tail bytes before calling the read callback. | |||||
| * this is a repeat of the above logic adjusted for the fact we | |||||
| * don't have a whole word. note though if the client is feeding | |||||
| * us data a byte at a time (unlikely), br->consumed_bits may not | |||||
| * be zero. | |||||
| */ | |||||
| if(br->bytes) { | |||||
| const unsigned end = br->bytes * 8; | |||||
| brword b = (br->buffer[cwords] & ~(FLAC__WORD_ALL_ONES >> end)) << cbits; | |||||
| if(b) { | |||||
| i = COUNT_ZERO_MSBS(b); | |||||
| uval += i; | |||||
| cbits += i; | |||||
| cbits++; /* skip over stop bit */ | |||||
| FLAC__ASSERT(cbits < FLAC__BITS_PER_WORD); | |||||
| goto break1; | |||||
| } | |||||
| else { | |||||
| uval += end - cbits; | |||||
| cbits += end; | |||||
| FLAC__ASSERT(cbits < FLAC__BITS_PER_WORD); | |||||
| /* didn't find stop bit yet, have to keep going... */ | |||||
| } | |||||
| /* compose the value */ | |||||
| x = (msbs << parameter) | lsbs; | |||||
| *val++ = (int)(x >> 1) ^ -(int)(x & 1); | |||||
| continue; | |||||
| /* at this point we've eaten up all the whole words */ | |||||
| process_tail: | |||||
| do { | |||||
| if(0) { | |||||
| incomplete_msbs: | |||||
| br->consumed_bits = 0; | |||||
| br->consumed_words = cwords; | |||||
| } | } | ||||
| /* flush registers and read; bitreader_read_from_client_() does | |||||
| * not touch br->consumed_bits at all but we still need to set | |||||
| * it in case it fails and we have to return false. | |||||
| */ | |||||
| br->consumed_bits = cbits; | |||||
| br->consumed_words = cwords; | |||||
| if(!bitreader_read_from_client_(br)) | |||||
| /* read the unary MSBs and end bit */ | |||||
| if(!FLAC__bitreader_read_unary_unsigned(br, &msbs)) | |||||
| return false; | return false; | ||||
| cwords = br->consumed_words; | |||||
| ucbits = (br->words-cwords)*FLAC__BITS_PER_WORD + br->bytes*8 - cbits + uval; | |||||
| /* + uval to offset our count by the # of unary bits already | |||||
| * consumed before the read, because we will add these back | |||||
| * in all at once at break1 | |||||
| */ | |||||
| } | |||||
| break1: | |||||
| ucbits -= uval; | |||||
| ucbits--; /* account for stop bit */ | |||||
| /* read binary part */ | |||||
| FLAC__ASSERT(cwords <= br->words); | |||||
| if(parameter) { | |||||
| while(ucbits < parameter) { | |||||
| /* flush registers and read; bitreader_read_from_client_() does | |||||
| * not touch br->consumed_bits at all but we still need to set | |||||
| * it in case it fails and we have to return false. | |||||
| */ | |||||
| br->consumed_bits = cbits; | |||||
| msbs += x; | |||||
| x = ucbits = 0; | |||||
| if(0) { | |||||
| incomplete_lsbs: | |||||
| br->consumed_bits = 0; | |||||
| br->consumed_words = cwords; | br->consumed_words = cwords; | ||||
| if(!bitreader_read_from_client_(br)) | |||||
| return false; | |||||
| cwords = br->consumed_words; | |||||
| ucbits = (br->words-cwords)*FLAC__BITS_PER_WORD + br->bytes*8 - cbits; | |||||
| } | |||||
| if(cwords < br->words) { /* if we've not consumed up to a partial tail word... */ | |||||
| if(cbits) { | |||||
| /* this also works when consumed_bits==0, it's just slower than necessary for that case */ | |||||
| const unsigned n = FLAC__BITS_PER_WORD - cbits; | |||||
| const brword word = br->buffer[cwords]; | |||||
| if(parameter < n) { | |||||
| uval <<= parameter; | |||||
| uval |= (word & (FLAC__WORD_ALL_ONES >> cbits)) >> (n-parameter); | |||||
| cbits += parameter; | |||||
| } | |||||
| else { | |||||
| uval <<= n; | |||||
| uval |= word & (FLAC__WORD_ALL_ONES >> cbits); | |||||
| crc16_update_word_(br, word); | |||||
| cwords++; | |||||
| cbits = parameter - n; | |||||
| if(cbits) { /* parameter > n, i.e. if there are still bits left to read, there have to be less than 32 so they will all be in the next word */ | |||||
| uval <<= cbits; | |||||
| uval |= (br->buffer[cwords] >> (FLAC__BITS_PER_WORD-cbits)); | |||||
| } | |||||
| } | |||||
| } | |||||
| else { | |||||
| cbits = parameter; | |||||
| uval <<= parameter; | |||||
| uval |= br->buffer[cwords] >> (FLAC__BITS_PER_WORD-cbits); | |||||
| } | |||||
| } | } | ||||
| else { | |||||
| /* in this case we're starting our read at a partial tail word; | |||||
| * the reader has guaranteed that we have at least 'parameter' | |||||
| * bits available to read, which makes this case simpler. | |||||
| */ | |||||
| uval <<= parameter; | |||||
| if(cbits) { | |||||
| /* this also works when consumed_bits==0, it's just a little slower than necessary for that case */ | |||||
| FLAC__ASSERT(cbits + parameter <= br->bytes*8); | |||||
| uval |= (br->buffer[cwords] & (FLAC__WORD_ALL_ONES >> cbits)) >> (FLAC__BITS_PER_WORD-cbits-parameter); | |||||
| cbits += parameter; | |||||
| } | |||||
| else { | |||||
| cbits = parameter; | |||||
| uval |= br->buffer[cwords] >> (FLAC__BITS_PER_WORD-cbits); | |||||
| } | |||||
| } | |||||
| } | |||||
| ucbits -= parameter; | |||||
| /* read the binary LSBs */ | |||||
| if(!FLAC__bitreader_read_raw_uint32(br, &lsbs, parameter - ucbits)) | |||||
| return false; | |||||
| lsbs = x | lsbs; | |||||
| /* compose the value */ | |||||
| *vals = (int)(uval >> 1 ^ -(int)(uval & 1)); | |||||
| /* compose the value */ | |||||
| x = (msbs << parameter) | lsbs; | |||||
| *val++ = (int)(x >> 1) ^ -(int)(x & 1); | |||||
| x = 0; | |||||
| /* are we done? */ | |||||
| --nvals; | |||||
| if(nvals == 0) { | |||||
| br->consumed_bits = cbits; | |||||
| br->consumed_words = cwords; | |||||
| return true; | |||||
| } | |||||
| uval = 0; | |||||
| ++vals; | |||||
| cwords = br->consumed_words; | |||||
| words = br->words; | |||||
| ucbits = FLAC__BITS_PER_WORD - br->consumed_bits; | |||||
| b = br->buffer[cwords] << br->consumed_bits; | |||||
| } while(cwords >= words && val < end); | |||||
| } | |||||
| if(ucbits == 0 && cwords < words) { | |||||
| /* don't leave the head word with no unconsumed bits */ | |||||
| crc16_update_word_(br, br->buffer[cwords++]); | |||||
| ucbits = FLAC__BITS_PER_WORD; | |||||
| } | } | ||||
| br->consumed_bits = FLAC__BITS_PER_WORD - ucbits; | |||||
| br->consumed_words = cwords; | |||||
| return true; | |||||
| } | } | ||||
| #endif | |||||
| #if 0 /* UNUSED */ | #if 0 /* UNUSED */ | ||||
| FLAC__bool FLAC__bitreader_read_golomb_signed(FLAC__BitReader *br, int *val, unsigned parameter) | FLAC__bool FLAC__bitreader_read_golomb_signed(FLAC__BitReader *br, int *val, unsigned parameter) | ||||
| @@ -1348,3 +1047,16 @@ FLAC__bool FLAC__bitreader_read_utf8_uint64(FLAC__BitReader *br, FLAC__uint64 *v | |||||
| *val = v; | *val = v; | ||||
| return true; | return true; | ||||
| } | } | ||||
| /* These functions a declared inline in this file but are also callable as | |||||
| * externs from elsewhere. | |||||
| * According to the C99 sepc, section 6.7.4, simply providing a function | |||||
| * prototype in a header file without 'inline' and making the function inline | |||||
| * in this file should be sufficient. | |||||
| * Unfortunately, the Microsoft VS compiler doesn't pick them up externally. To | |||||
| * fix that we add extern declarations here. | |||||
| */ | |||||
| extern FLAC__bool FLAC__bitreader_is_consumed_byte_aligned(const FLAC__BitReader *br); | |||||
| extern unsigned FLAC__bitreader_bits_left_for_byte_alignment(const FLAC__BitReader *br); | |||||
| extern unsigned FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader *br); | |||||
| extern FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val); | |||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -33,41 +34,27 @@ | |||||
| # include <config.h> | # include <config.h> | ||||
| #endif | #endif | ||||
| #include <stdlib.h> /* for malloc() */ | |||||
| #include <string.h> /* for memcpy(), memset() */ | |||||
| #ifdef _MSC_VER | |||||
| #include <winsock.h> /* for ntohl() */ | |||||
| #elif defined FLAC__SYS_DARWIN | |||||
| #include <machine/endian.h> /* for ntohl() */ | |||||
| #elif defined __MINGW32__ | |||||
| #include <winsock.h> /* for ntohl() */ | |||||
| #else | |||||
| #include <netinet/in.h> /* for ntohl() */ | |||||
| #endif | |||||
| #if 0 /* UNUSED */ | |||||
| #include "include/private/bitmath.h" | |||||
| #endif | |||||
| #include <stdlib.h> | |||||
| #include <string.h> | |||||
| #include "include/private/bitwriter.h" | #include "include/private/bitwriter.h" | ||||
| #include "include/private/crc.h" | #include "include/private/crc.h" | ||||
| #include "../assert.h" | #include "../assert.h" | ||||
| #include "../alloc.h" | #include "../alloc.h" | ||||
| #include "../compat.h" | |||||
| #include "../endswap.h" | |||||
| /* Things should be fastest when this matches the machine word size */ | /* 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 */ | /* WATCHOUT: if you change this you must also change the following #defines down to SWAP_BE_WORD_TO_HOST below to match */ | ||||
| /* WATCHOUT: there are a few places where the code will not work unless bwword is >= 32 bits wide */ | |||||
| typedef FLAC__uint32 bwword; | |||||
| /* WATCHOUT: there are a few places where the code will not work unless uint32_t is >= 32 bits wide */ | |||||
| #define FLAC__BYTES_PER_WORD 4 | #define FLAC__BYTES_PER_WORD 4 | ||||
| #undef FLAC__BITS_PER_WORD | |||||
| #define FLAC__BITS_PER_WORD 32 | #define FLAC__BITS_PER_WORD 32 | ||||
| #define FLAC__WORD_ALL_ONES ((FLAC__uint32)0xffffffff) | #define FLAC__WORD_ALL_ONES ((FLAC__uint32)0xffffffff) | ||||
| /* SWAP_BE_WORD_TO_HOST swaps bytes in a bwword (which is always big-endian) if necessary to match host byte order */ | |||||
| /* SWAP_BE_WORD_TO_HOST swaps bytes in a uint32_t (which is always big-endian) if necessary to match host byte order */ | |||||
| #if WORDS_BIGENDIAN | #if WORDS_BIGENDIAN | ||||
| #define SWAP_BE_WORD_TO_HOST(x) (x) | #define SWAP_BE_WORD_TO_HOST(x) (x) | ||||
| #else | #else | ||||
| #ifdef _MSC_VER | |||||
| #define SWAP_BE_WORD_TO_HOST(x) local_swap32_(x) | |||||
| #else | |||||
| #define SWAP_BE_WORD_TO_HOST(x) ntohl(x) | |||||
| #endif | |||||
| #define SWAP_BE_WORD_TO_HOST(x) ENDSWAP_32(x) | |||||
| #endif | #endif | ||||
| /* | /* | ||||
| @@ -76,42 +63,29 @@ typedef FLAC__uint32 bwword; | |||||
| * a frame or metadata block, then write that out and clear the buffer for the | * a frame or metadata block, then write that out and clear the buffer for the | ||||
| * next one. | * next one. | ||||
| */ | */ | ||||
| static const unsigned FLAC__BITWRITER_DEFAULT_CAPACITY = 32768u / sizeof(bwword); /* size in words */ | |||||
| static const unsigned FLAC__BITWRITER_DEFAULT_CAPACITY = 32768u / sizeof(uint32_t); /* size in words */ | |||||
| /* When growing, increment 4K at a time */ | /* When growing, increment 4K at a time */ | ||||
| static const unsigned FLAC__BITWRITER_DEFAULT_INCREMENT = 4096u / sizeof(bwword); /* size in words */ | |||||
| static const unsigned FLAC__BITWRITER_DEFAULT_INCREMENT = 4096u / sizeof(uint32_t); /* size in words */ | |||||
| #define FLAC__WORDS_TO_BITS(words) ((words) * FLAC__BITS_PER_WORD) | #define FLAC__WORDS_TO_BITS(words) ((words) * FLAC__BITS_PER_WORD) | ||||
| #define FLAC__TOTAL_BITS(bw) (FLAC__WORDS_TO_BITS((bw)->words) + (bw)->bits) | #define FLAC__TOTAL_BITS(bw) (FLAC__WORDS_TO_BITS((bw)->words) + (bw)->bits) | ||||
| #ifdef min | |||||
| #undef min | |||||
| #endif | |||||
| #define min(x,y) ((x)<(y)?(x):(y)) | |||||
| /* adjust for compilers that can't understand using LLU suffix for uint64_t literals */ | |||||
| #ifdef _MSC_VER | |||||
| #define FLAC__U64L(x) x | |||||
| #else | |||||
| #define FLAC__U64L(x) x##LLU | |||||
| #endif | |||||
| #ifndef FLaC__INLINE | |||||
| #define FLaC__INLINE | |||||
| #endif | |||||
| struct FLAC__BitWriter { | struct FLAC__BitWriter { | ||||
| bwword *buffer; | |||||
| bwword accum; /* accumulator; bits are right-justified; when full, accum is appended to buffer */ | |||||
| uint32_t *buffer; | |||||
| uint32_t accum; /* accumulator; bits are right-justified; when full, accum is appended to buffer */ | |||||
| unsigned capacity; /* capacity of buffer in words */ | unsigned capacity; /* capacity of buffer in words */ | ||||
| unsigned words; /* # of complete words in buffer */ | unsigned words; /* # of complete words in buffer */ | ||||
| unsigned bits; /* # of used bits in accum */ | unsigned bits; /* # of used bits in accum */ | ||||
| }; | }; | ||||
| /* * WATCHOUT: The current implementation only grows the buffer. */ | /* * WATCHOUT: The current implementation only grows the buffer. */ | ||||
| static FLAC__bool bitwriter_grow_(FLAC__BitWriter *bw, unsigned bits_to_add) | |||||
| #ifndef __SUNPRO_C | |||||
| static | |||||
| #endif | |||||
| FLAC__bool bitwriter_grow_(FLAC__BitWriter *bw, unsigned bits_to_add) | |||||
| { | { | ||||
| unsigned new_capacity; | unsigned new_capacity; | ||||
| bwword *new_buffer; | |||||
| uint32_t *new_buffer; | |||||
| FLAC__ASSERT(0 != bw); | FLAC__ASSERT(0 != bw); | ||||
| FLAC__ASSERT(0 != bw->buffer); | FLAC__ASSERT(0 != bw->buffer); | ||||
| @@ -133,7 +107,7 @@ static FLAC__bool bitwriter_grow_(FLAC__BitWriter *bw, unsigned bits_to_add) | |||||
| FLAC__ASSERT(new_capacity > bw->capacity); | 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)); | FLAC__ASSERT(new_capacity >= bw->words + ((bw->bits + bits_to_add + FLAC__BITS_PER_WORD - 1) / FLAC__BITS_PER_WORD)); | ||||
| new_buffer = (bwword*)safe_realloc_mul_2op_(bw->buffer, sizeof(bwword), /*times*/new_capacity); | |||||
| new_buffer = (uint32_t*) safe_realloc_mul_2op_(bw->buffer, sizeof(uint32_t), /*times*/new_capacity); | |||||
| if(new_buffer == 0) | if(new_buffer == 0) | ||||
| return false; | return false; | ||||
| bw->buffer = new_buffer; | bw->buffer = new_buffer; | ||||
| @@ -150,7 +124,7 @@ static FLAC__bool bitwriter_grow_(FLAC__BitWriter *bw, unsigned bits_to_add) | |||||
| FLAC__BitWriter *FLAC__bitwriter_new(void) | FLAC__BitWriter *FLAC__bitwriter_new(void) | ||||
| { | { | ||||
| FLAC__BitWriter *bw = (FLAC__BitWriter*)calloc(1, sizeof(FLAC__BitWriter)); | |||||
| FLAC__BitWriter *bw = (FLAC__BitWriter*) calloc(1, sizeof(FLAC__BitWriter)); | |||||
| /* note that calloc() sets all members to 0 for us */ | /* note that calloc() sets all members to 0 for us */ | ||||
| return bw; | return bw; | ||||
| } | } | ||||
| @@ -175,7 +149,7 @@ FLAC__bool FLAC__bitwriter_init(FLAC__BitWriter *bw) | |||||
| bw->words = bw->bits = 0; | bw->words = bw->bits = 0; | ||||
| bw->capacity = FLAC__BITWRITER_DEFAULT_CAPACITY; | bw->capacity = FLAC__BITWRITER_DEFAULT_CAPACITY; | ||||
| bw->buffer = (bwword*)malloc(sizeof(bwword) * bw->capacity); | |||||
| bw->buffer = (uint32_t*) malloc(sizeof(uint32_t) * bw->capacity); | |||||
| if(bw->buffer == 0) | if(bw->buffer == 0) | ||||
| return false; | return false; | ||||
| @@ -290,7 +264,7 @@ void FLAC__bitwriter_release_buffer(FLAC__BitWriter *bw) | |||||
| (void)bw; | (void)bw; | ||||
| } | } | ||||
| FLaC__INLINE FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, unsigned bits) | |||||
| inline FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, unsigned bits) | |||||
| { | { | ||||
| unsigned n; | unsigned n; | ||||
| @@ -304,7 +278,7 @@ FLaC__INLINE FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, unsign | |||||
| return false; | return false; | ||||
| /* first part gets to word alignment */ | /* first part gets to word alignment */ | ||||
| if(bw->bits) { | if(bw->bits) { | ||||
| n = min(FLAC__BITS_PER_WORD - bw->bits, bits); | |||||
| n = flac_min(FLAC__BITS_PER_WORD - bw->bits, bits); | |||||
| bw->accum <<= n; | bw->accum <<= n; | ||||
| bits -= n; | bits -= n; | ||||
| bw->bits += n; | bw->bits += n; | ||||
| @@ -328,7 +302,7 @@ FLaC__INLINE FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, unsign | |||||
| return true; | return true; | ||||
| } | } | ||||
| FLaC__INLINE FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FLAC__uint32 val, unsigned bits) | |||||
| inline FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FLAC__uint32 val, unsigned bits) | |||||
| { | { | ||||
| register unsigned left; | register unsigned left; | ||||
| @@ -367,7 +341,7 @@ FLaC__INLINE FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FL | |||||
| return true; | return true; | ||||
| } | } | ||||
| FLaC__INLINE FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, unsigned bits) | |||||
| inline FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, unsigned bits) | |||||
| { | { | ||||
| /* zero-out unused bits */ | /* zero-out unused bits */ | ||||
| if(bits < 32) | if(bits < 32) | ||||
| @@ -376,7 +350,7 @@ FLaC__INLINE FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLA | |||||
| return FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)val, bits); | return FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)val, bits); | ||||
| } | } | ||||
| FLaC__INLINE FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, unsigned bits) | |||||
| inline FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, unsigned bits) | |||||
| { | { | ||||
| /* this could be a little faster but it's not used for much */ | /* this could be a little faster but it's not used for much */ | ||||
| if(bits > 32) { | if(bits > 32) { | ||||
| @@ -388,7 +362,7 @@ FLaC__INLINE FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FL | |||||
| return FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)val, bits); | return FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)val, bits); | ||||
| } | } | ||||
| FLaC__INLINE FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val) | |||||
| inline FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val) | |||||
| { | { | ||||
| /* this doesn't need to be that fast as currently it is only used for vorbis comments */ | /* this doesn't need to be that fast as currently it is only used for vorbis comments */ | ||||
| @@ -404,7 +378,7 @@ FLaC__INLINE FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__Bit | |||||
| return true; | return true; | ||||
| } | } | ||||
| FLaC__INLINE FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], unsigned nvals) | |||||
| inline FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], unsigned nvals) | |||||
| { | { | ||||
| unsigned i; | unsigned i; | ||||
| @@ -540,7 +514,7 @@ FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FL | |||||
| FLAC__ASSERT(0 != bw); | FLAC__ASSERT(0 != bw); | ||||
| FLAC__ASSERT(0 != bw->buffer); | FLAC__ASSERT(0 != bw->buffer); | ||||
| FLAC__ASSERT(parameter < 8*sizeof(bwword)-1); | |||||
| FLAC__ASSERT(parameter < 8*sizeof(uint32_t)-1); | |||||
| /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */ | /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */ | ||||
| FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32); | FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32); | ||||
| @@ -551,8 +525,8 @@ FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FL | |||||
| msbits = uval >> parameter; | msbits = uval >> parameter; | ||||
| #if 0 /* OPT: can remove this special case if it doesn't make up for the extra compare (doesn't make a statistically significant difference with msvc or gcc/x86) */ | #if 0 /* OPT: can remove this special case if it doesn't make up for the extra compare (doesn't make a statistically significant difference with msvc or gcc/x86) */ | ||||
| if(bw->bits && bw->bits + msbits + lsbits <= FLAC__BITS_PER_WORD) { /* i.e. if the whole thing fits in the current bwword */ | |||||
| /* ^^^ if bw->bits is 0 then we may have filled the buffer and have no free bwword to work in */ | |||||
| if(bw->bits && bw->bits + msbits + lsbits <= FLAC__BITS_PER_WORD) { /* i.e. if the whole thing fits in the current uint32_t */ | |||||
| /* ^^^ if bw->bits is 0 then we may have filled the buffer and have no free uint32_t to work in */ | |||||
| bw->bits = bw->bits + msbits + lsbits; | bw->bits = bw->bits + msbits + lsbits; | ||||
| uval |= mask1; /* set stop bit */ | uval |= mask1; /* set stop bit */ | ||||
| uval &= mask2; /* mask off unused top bits */ | uval &= mask2; /* mask off unused top bits */ | ||||
| @@ -572,8 +546,8 @@ FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FL | |||||
| } | } | ||||
| else { | else { | ||||
| #elif 1 /*@@@@@@ OPT: try this version with MSVC6 to see if better, not much difference for gcc-4 */ | #elif 1 /*@@@@@@ OPT: try this version with MSVC6 to see if better, not much difference for gcc-4 */ | ||||
| if(bw->bits && bw->bits + msbits + lsbits < FLAC__BITS_PER_WORD) { /* i.e. if the whole thing fits in the current bwword */ | |||||
| /* ^^^ if bw->bits is 0 then we may have filled the buffer and have no free bwword to work in */ | |||||
| if(bw->bits && bw->bits + msbits + lsbits < FLAC__BITS_PER_WORD) { /* i.e. if the whole thing fits in the current uint32_t */ | |||||
| /* ^^^ if bw->bits is 0 then we may have filled the buffer and have no free uint32_t to work in */ | |||||
| bw->bits = bw->bits + msbits + lsbits; | bw->bits = bw->bits + msbits + lsbits; | ||||
| uval |= mask1; /* set stop bit */ | uval |= mask1; /* set stop bit */ | ||||
| uval &= mask2; /* mask off unused top bits */ | uval &= mask2; /* mask off unused top bits */ | ||||
| @@ -584,7 +558,7 @@ FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FL | |||||
| #endif | #endif | ||||
| /* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+msbits+lsbits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */ | /* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+msbits+lsbits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */ | ||||
| /* OPT: pessimism may cause flurry of false calls to grow_ which eat up all savings before it */ | /* OPT: pessimism may cause flurry of false calls to grow_ which eat up all savings before it */ | ||||
| if(bw->capacity <= bw->words + bw->bits + msbits + 1/*lsbits always fit in 1 bwword*/ && !bitwriter_grow_(bw, msbits+lsbits)) | |||||
| if(bw->capacity <= bw->words + bw->bits + msbits + 1/*lsbits always fit in 1 uint32_t*/ && !bitwriter_grow_(bw, msbits+lsbits)) | |||||
| return false; | return false; | ||||
| if(msbits) { | if(msbits) { | ||||
| @@ -878,3 +852,17 @@ FLAC__bool FLAC__bitwriter_zero_pad_to_byte_boundary(FLAC__BitWriter *bw) | |||||
| else | else | ||||
| return true; | return true; | ||||
| } | } | ||||
| /* These functions a declared inline in this file but are also callable as | |||||
| * externs from elsewhere. | |||||
| * According to the C99 sepc, section 6.7.4, simply providing a function | |||||
| * prototype in a header file without 'inline' and making the function inline | |||||
| * in this file should be sufficient. | |||||
| * Unfortunately, the Microsoft VS compiler doesn't pick them up externally. To | |||||
| * fix that we add extern declarations here. | |||||
| */ | |||||
| extern FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, unsigned bits); | |||||
| extern FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, unsigned bits); | |||||
| extern FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, unsigned bits); | |||||
| extern FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val); | |||||
| extern FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], unsigned nvals); | |||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2001-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -136,7 +137,7 @@ static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX = 0x00400000; | |||||
| # endif | # endif | ||||
| # elif defined(_MSC_VER) | # elif defined(_MSC_VER) | ||||
| # include <windows.h> | # include <windows.h> | ||||
| # undef USE_TRY_CATCH_FLAVOR /* #define this to use the try/catch method for catching illegal opcode exception */ | |||||
| # define USE_TRY_CATCH_FLAVOR /* sigill_handler flavor resulted in several crash reports on win32 */ | |||||
| # ifdef USE_TRY_CATCH_FLAVOR | # ifdef USE_TRY_CATCH_FLAVOR | ||||
| # else | # else | ||||
| LONG CALLBACK sigill_handler_sse_os(EXCEPTION_POINTERS *ep) | LONG CALLBACK sigill_handler_sse_os(EXCEPTION_POINTERS *ep) | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -74,7 +75,7 @@ FLAC__byte const FLAC__crc8_table[256] = { | |||||
| /* CRC-16, poly = x^16 + x^15 + x^2 + x^0, init = 0 */ | /* CRC-16, poly = x^16 + x^15 + x^2 + x^0, init = 0 */ | ||||
| unsigned FLAC__crc16_table[256] = { | |||||
| unsigned const FLAC__crc16_table[256] = { | |||||
| 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011, | 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011, | ||||
| 0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022, | 0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022, | ||||
| 0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072, | 0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072, | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -44,11 +45,6 @@ | |||||
| #define M_LN2 0.69314718055994530942 | #define M_LN2 0.69314718055994530942 | ||||
| #endif | #endif | ||||
| #ifdef min | |||||
| #undef min | |||||
| #endif | |||||
| #define min(x,y) ((x) < (y)? (x) : (y)) | |||||
| #ifdef local_abs | #ifdef local_abs | ||||
| #undef local_abs | #undef local_abs | ||||
| #endif | #endif | ||||
| @@ -242,11 +238,11 @@ unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned d | |||||
| error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save; | error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save; | ||||
| } | } | ||||
| if(total_error_0 < min(min(min(total_error_1, total_error_2), total_error_3), total_error_4)) | |||||
| if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) | |||||
| order = 0; | order = 0; | ||||
| else if(total_error_1 < min(min(total_error_2, total_error_3), total_error_4)) | |||||
| else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) | |||||
| order = 1; | order = 1; | ||||
| else if(total_error_2 < min(total_error_3, total_error_4)) | |||||
| else if(total_error_2 < flac_min(total_error_3, total_error_4)) | |||||
| order = 2; | order = 2; | ||||
| else if(total_error_3 < total_error_4) | else if(total_error_3 < total_error_4) | ||||
| order = 3; | order = 3; | ||||
| @@ -304,11 +300,11 @@ unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsig | |||||
| error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save; | error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save; | ||||
| } | } | ||||
| if(total_error_0 < min(min(min(total_error_1, total_error_2), total_error_3), total_error_4)) | |||||
| if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) | |||||
| order = 0; | order = 0; | ||||
| else if(total_error_1 < min(min(total_error_2, total_error_3), total_error_4)) | |||||
| else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) | |||||
| order = 1; | order = 1; | ||||
| else if(total_error_2 < min(total_error_3, total_error_4)) | |||||
| else if(total_error_2 < flac_min(total_error_3, total_error_4)) | |||||
| order = 2; | order = 2; | ||||
| else if(total_error_3 < total_error_4) | else if(total_error_3 < total_error_4) | ||||
| order = 3; | order = 3; | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2004-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -34,18 +35,11 @@ | |||||
| #endif | #endif | ||||
| #include "../assert.h" | #include "../assert.h" | ||||
| #include "../compat.h" | |||||
| #include "include/private/float.h" | #include "include/private/float.h" | ||||
| #ifdef FLAC__INTEGER_ONLY_LIBRARY | #ifdef FLAC__INTEGER_ONLY_LIBRARY | ||||
| /* adjust for compilers that can't understand using LLU suffix for uint64_t literals */ | |||||
| #ifdef _MSC_VER | |||||
| #define FLAC__U64L(x) x | |||||
| #else | |||||
| #define FLAC__U64L(x) x##LLU | |||||
| #endif | |||||
| const FLAC__fixedpoint FLAC__FP_ZERO = 0; | const FLAC__fixedpoint FLAC__FP_ZERO = 0; | ||||
| const FLAC__fixedpoint FLAC__FP_ONE_HALF = 0x00008000; | const FLAC__fixedpoint FLAC__FP_ONE_HALF = 0x00008000; | ||||
| const FLAC__fixedpoint FLAC__FP_ONE = 0x00010000; | const FLAC__fixedpoint FLAC__FP_ONE = 0x00010000; | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -38,37 +39,17 @@ | |||||
| #include <string.h> /* for memset() */ | #include <string.h> /* for memset() */ | ||||
| #include "../assert.h" | #include "../assert.h" | ||||
| #include "../format.h" | #include "../format.h" | ||||
| #include "../compat.h" | |||||
| #include "include/private/format.h" | #include "include/private/format.h" | ||||
| #ifndef FLaC__INLINE | |||||
| #define FLaC__INLINE | |||||
| #endif | |||||
| #ifdef min | |||||
| #undef min | |||||
| #endif | |||||
| #define min(a,b) ((a)<(b)?(a):(b)) | |||||
| /* adjust for compilers that can't understand using LLU suffix for uint64_t literals */ | |||||
| #ifdef _MSC_VER | |||||
| #define FLAC__U64L(x) x | |||||
| #else | |||||
| #define FLAC__U64L(x) x##LLU | |||||
| #endif | |||||
| /* VERSION should come from configure */ | /* VERSION should come from configure */ | ||||
| FLAC_API const char *FLAC__VERSION_STRING = VERSION | |||||
| ; | |||||
| FLAC_API const char *FLAC__VERSION_STRING = VERSION; | |||||
| #if defined _MSC_VER || defined __BORLANDC__ || defined __MINW32__ | #if defined _MSC_VER || defined __BORLANDC__ || defined __MINW32__ | ||||
| /* yet one more hack because of MSVC6: */ | /* yet one more hack because of MSVC6: */ | ||||
| FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC 1.2.1 20070917"; | |||||
| FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC 1.3.0 20130526"; | |||||
| #else | #else | ||||
| FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " VERSION " 20070917"; | |||||
| FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " VERSION " 20130526"; | |||||
| #endif | #endif | ||||
| FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' }; | FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' }; | ||||
| @@ -228,6 +209,16 @@ FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate) | |||||
| return true; | return true; | ||||
| } | } | ||||
| FLAC_API FLAC__bool FLAC__format_blocksize_is_subset(unsigned blocksize, unsigned sample_rate) | |||||
| { | |||||
| if(blocksize > 16384) | |||||
| return false; | |||||
| else if(sample_rate <= 48000 && blocksize > 4608) | |||||
| return false; | |||||
| else | |||||
| return true; | |||||
| } | |||||
| FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(unsigned sample_rate) | FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(unsigned sample_rate) | ||||
| { | { | ||||
| if( | if( | ||||
| @@ -268,7 +259,7 @@ FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_S | |||||
| } | } | ||||
| /* used as the sort predicate for qsort() */ | /* used as the sort predicate for qsort() */ | ||||
| static int JUCE_CDECL seekpoint_compare_(const FLAC__StreamMetadata_SeekPoint *l, const FLAC__StreamMetadata_SeekPoint *r) | |||||
| static int seekpoint_compare_(const FLAC__StreamMetadata_SeekPoint *l, const FLAC__StreamMetadata_SeekPoint *r) | |||||
| { | { | ||||
| /* we don't just 'return l->sample_number - r->sample_number' since the result (FLAC__int64) might overflow an 'int' */ | /* we don't just 'return l->sample_number - r->sample_number' since the result (FLAC__int64) might overflow an 'int' */ | ||||
| if(l->sample_number == r->sample_number) | if(l->sample_number == r->sample_number) | ||||
| @@ -288,7 +279,7 @@ FLAC_API unsigned FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *se | |||||
| FLAC__ASSERT(0 != seek_table); | FLAC__ASSERT(0 != seek_table); | ||||
| /* sort the seekpoints */ | /* sort the seekpoints */ | ||||
| qsort(seek_table->points, seek_table->num_points, sizeof(FLAC__StreamMetadata_SeekPoint), (int (JUCE_CDECL *)(const void *, const void *))seekpoint_compare_); | |||||
| qsort(seek_table->points, seek_table->num_points, sizeof(FLAC__StreamMetadata_SeekPoint), (int (*)(const void *, const void *))seekpoint_compare_); | |||||
| /* uniquify the seekpoints */ | /* uniquify the seekpoints */ | ||||
| first = true; | first = true; | ||||
| @@ -318,7 +309,7 @@ FLAC_API unsigned FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *se | |||||
| * and a more clear explanation at the end of this section: | * and a more clear explanation at the end of this section: | ||||
| * http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 | * http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 | ||||
| */ | */ | ||||
| static FLaC__INLINE unsigned utf8len_(const FLAC__byte *utf8) | |||||
| static unsigned utf8len_(const FLAC__byte *utf8) | |||||
| { | { | ||||
| FLAC__ASSERT(0 != utf8); | FLAC__ASSERT(0 != utf8); | ||||
| if ((utf8[0] & 0x80) == 0) { | if ((utf8[0] & 0x80) == 0) { | ||||
| @@ -541,7 +532,7 @@ unsigned FLAC__format_get_max_rice_partition_order_from_blocksize(unsigned block | |||||
| max_rice_partition_order++; | max_rice_partition_order++; | ||||
| blocksize >>= 1; | blocksize >>= 1; | ||||
| } | } | ||||
| return min(FLAC__MAX_RICE_PARTITION_ORDER, max_rice_partition_order); | |||||
| return flac_min(FLAC__MAX_RICE_PARTITION_ORDER, max_rice_partition_order); | |||||
| } | } | ||||
| unsigned FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(unsigned limit, unsigned blocksize, unsigned predictor_order) | unsigned FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(unsigned limit, unsigned blocksize, unsigned predictor_order) | ||||
| @@ -586,9 +577,9 @@ FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_s | |||||
| FLAC__ASSERT(object->capacity_by_order > 0 || (0 == object->parameters && 0 == object->raw_bits)); | FLAC__ASSERT(object->capacity_by_order > 0 || (0 == object->parameters && 0 == object->raw_bits)); | ||||
| if(object->capacity_by_order < max_partition_order) { | if(object->capacity_by_order < max_partition_order) { | ||||
| if(0 == (object->parameters = (unsigned*)realloc(object->parameters, sizeof(unsigned)*(1 << max_partition_order)))) | |||||
| if(0 == (object->parameters = (unsigned int*) realloc(object->parameters, sizeof(unsigned)*(1 << max_partition_order)))) | |||||
| return false; | return false; | ||||
| if(0 == (object->raw_bits = (unsigned*)realloc(object->raw_bits, sizeof(unsigned)*(1 << max_partition_order)))) | |||||
| if(0 == (object->raw_bits = (unsigned int*) realloc(object->raw_bits, sizeof(unsigned)*(1 << max_partition_order)))) | |||||
| return false; | return false; | ||||
| memset(object->raw_bits, 0, sizeof(unsigned)*(1 << max_partition_order)); | memset(object->raw_bits, 0, sizeof(unsigned)*(1 << max_partition_order)); | ||||
| object->capacity_by_order = max_partition_order; | object->capacity_by_order = max_partition_order; | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2001-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -34,8 +35,136 @@ | |||||
| #include "../../../ordinals.h" | #include "../../../ordinals.h" | ||||
| unsigned FLAC__bitmath_ilog2(FLAC__uint32 v); | |||||
| unsigned FLAC__bitmath_ilog2_wide(FLAC__uint64 v); | |||||
| /* for CHAR_BIT */ | |||||
| #include <limits.h> | |||||
| #include "../../../compat.h" | |||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1400) | |||||
| #include <intrin.h> /* for _BitScanReverse* */ | |||||
| #endif | |||||
| /* Will never be emitted for MSVC, GCC, Intel compilers */ | |||||
| static inline unsigned int FLAC__clz_soft_uint32(unsigned int word) | |||||
| { | |||||
| static const unsigned char byte_to_unary_table[] = { | |||||
| 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, | |||||
| 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |||||
| 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |||||
| 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |||||
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |||||
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |||||
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |||||
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |||||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||||
| }; | |||||
| return (word) > 0xffffff ? byte_to_unary_table[(word) >> 24] : | |||||
| (word) > 0xffff ? byte_to_unary_table[(word) >> 16] + 8 : | |||||
| (word) > 0xff ? byte_to_unary_table[(word) >> 8] + 16 : | |||||
| byte_to_unary_table[(word)] + 24; | |||||
| } | |||||
| static inline unsigned int FLAC__clz_uint32(FLAC__uint32 v) | |||||
| { | |||||
| /* Never used with input 0 */ | |||||
| #if defined(__INTEL_COMPILER) | |||||
| return _bit_scan_reverse(v) ^ 31U; | |||||
| #elif defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) | |||||
| /* This will translate either to (bsr ^ 31U), clz , ctlz, cntlz, lzcnt depending on | |||||
| * -march= setting or to a software rutine in exotic machines. */ | |||||
| return __builtin_clz(v); | |||||
| #elif defined(_MSC_VER) && (_MSC_VER >= 1400) | |||||
| FLAC__uint32 idx; | |||||
| _BitScanReverse((DWORD*) &idx, v); | |||||
| return idx ^ 31U; | |||||
| #else | |||||
| return FLAC__clz_soft_uint32(v); | |||||
| #endif | |||||
| } | |||||
| /* This one works with input 0 */ | |||||
| static inline unsigned int FLAC__clz2_uint32(FLAC__uint32 v) | |||||
| { | |||||
| if (!v) | |||||
| return 32; | |||||
| return FLAC__clz_uint32(v); | |||||
| } | |||||
| /* An example of what FLAC__bitmath_ilog2() computes: | |||||
| * | |||||
| * ilog2( 0) = undefined | |||||
| * ilog2( 1) = 0 | |||||
| * ilog2( 2) = 1 | |||||
| * ilog2( 3) = 1 | |||||
| * ilog2( 4) = 2 | |||||
| * ilog2( 5) = 2 | |||||
| * ilog2( 6) = 2 | |||||
| * ilog2( 7) = 2 | |||||
| * ilog2( 8) = 3 | |||||
| * ilog2( 9) = 3 | |||||
| * ilog2(10) = 3 | |||||
| * ilog2(11) = 3 | |||||
| * ilog2(12) = 3 | |||||
| * ilog2(13) = 3 | |||||
| * ilog2(14) = 3 | |||||
| * ilog2(15) = 3 | |||||
| * ilog2(16) = 4 | |||||
| * ilog2(17) = 4 | |||||
| * ilog2(18) = 4 | |||||
| */ | |||||
| static inline unsigned FLAC__bitmath_ilog2(FLAC__uint32 v) | |||||
| { | |||||
| return sizeof(FLAC__uint32) * CHAR_BIT - 1 - FLAC__clz_uint32(v); | |||||
| } | |||||
| #ifdef FLAC__INTEGER_ONLY_LIBRARY /*Unused otherwise */ | |||||
| static inline unsigned FLAC__bitmath_ilog2_wide(FLAC__uint64 v) | |||||
| { | |||||
| if (v == 0) | |||||
| return 0; | |||||
| #if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) | |||||
| return sizeof(FLAC__uint64) * CHAR_BIT - 1 - __builtin_clzll(v); | |||||
| /* Sorry, only supported in win64/Itanium.. */ | |||||
| #elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && (defined(_M_IA64) || defined(_WIN64)) | |||||
| FLAC__uint64 idx; | |||||
| _BitScanReverse64(&idx, v); | |||||
| return idx ^ 63U; | |||||
| #else | |||||
| /* Brain-damaged compilers will use the fastest possible way that is, | |||||
| de Bruijn sequences (http://supertech.csail.mit.edu/papers/debruijn.pdf) | |||||
| (C) Timothy B. Terriberry (tterribe@xiph.org) 2001-2009 LGPL (v2 or later). | |||||
| */ | |||||
| static const unsigned char DEBRUIJN_IDX64[64]={ | |||||
| 0, 1, 2, 7, 3,13, 8,19, 4,25,14,28, 9,34,20,40, | |||||
| 5,17,26,38,15,46,29,48,10,31,35,54,21,50,41,57, | |||||
| 63, 6,12,18,24,27,33,39,16,37,45,47,30,53,49,56, | |||||
| 62,11,23,32,36,44,52,55,61,22,43,51,60,42,59,58 | |||||
| }; | |||||
| int ret; | |||||
| ret= v>0; | |||||
| v|= v>>1; | |||||
| v|= v>>2; | |||||
| v|= v>>4; | |||||
| v|= v>>8; | |||||
| v|= v>>16; | |||||
| v|= v>>32; | |||||
| v= (v>>1)+1; | |||||
| ret+=DEBRUIJN_IDX64[v*0x218A392CD3D5DBF>>58&0x3F]; | |||||
| return ret; | |||||
| #endif | |||||
| } | |||||
| #endif | |||||
| unsigned FLAC__bitmath_silog2(int v); | unsigned FLAC__bitmath_silog2(int v); | ||||
| unsigned FLAC__bitmath_silog2_wide(FLAC__int64 v); | unsigned FLAC__bitmath_silog2_wide(FLAC__int64 v); | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2001-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -48,7 +49,7 @@ FLAC__uint8 FLAC__crc8(const FLAC__byte *data, unsigned len); | |||||
| ** polynomial = x^16 + x^15 + x^2 + x^0 | ** polynomial = x^16 + x^15 + x^2 + x^0 | ||||
| ** init = 0 | ** init = 0 | ||||
| */ | */ | ||||
| extern unsigned FLAC__crc16_table[256]; | |||||
| extern unsigned const FLAC__crc16_table[256]; | |||||
| #define FLAC__CRC16_UPDATE(data, crc) (((((crc)<<8) & 0xffff) ^ FLAC__crc16_table[((crc)>>8) ^ (data)])) | #define FLAC__CRC16_UPDATE(data, crc) (((((crc)<<8) & 0xffff) ^ FLAC__crc16_table[((crc)>>8) ^ (data)])) | ||||
| /* this alternate may be faster on some systems/compilers */ | /* this alternate may be faster on some systems/compilers */ | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -37,7 +38,7 @@ | |||||
| #endif | #endif | ||||
| #include "float.h" | #include "float.h" | ||||
| #include "format.h" | |||||
| #include "../../../format.h" | |||||
| /* | /* | ||||
| * FLAC__fixed_compute_best_predictor() | * FLAC__fixed_compute_best_predictor() | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2004-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2001-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -45,12 +46,13 @@ | |||||
| * Use free() on this address to deallocate. | * Use free() on this address to deallocate. | ||||
| */ | */ | ||||
| void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address); | void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address); | ||||
| FLAC__bool FLAC__memory_alloc_aligned_int32_array(unsigned elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer); | |||||
| FLAC__bool FLAC__memory_alloc_aligned_uint32_array(unsigned elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer); | |||||
| FLAC__bool FLAC__memory_alloc_aligned_uint64_array(unsigned elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer); | |||||
| FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(unsigned elements, unsigned **unaligned_pointer, unsigned **aligned_pointer); | |||||
| FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer); | |||||
| FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer); | |||||
| FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer); | |||||
| FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, unsigned **unaligned_pointer, unsigned **aligned_pointer); | |||||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||||
| FLAC__bool FLAC__memory_alloc_aligned_real_array(unsigned elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer); | |||||
| FLAC__bool FLAC__memory_alloc_aligned_real_array(size_t elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer); | |||||
| #endif | #endif | ||||
| void *safe_malloc_mul_2op_p(size_t size1, size_t size2); | |||||
| #endif | #endif | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2002-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -32,7 +33,7 @@ | |||||
| #ifndef FLAC__PRIVATE__METADATA_H | #ifndef FLAC__PRIVATE__METADATA_H | ||||
| #define FLAC__PRIVATE__METADATA_H | #define FLAC__PRIVATE__METADATA_H | ||||
| #include "metadata.h" | |||||
| #include "FLAC/metadata.h" | |||||
| /* WATCHOUT: all malloc()ed data in the block is free()ed; this may not | /* WATCHOUT: all malloc()ed data in the block is free()ed; this may not | ||||
| * be a consistent state (e.g. PICTURE) or equivalent to the initial | * be a consistent state (e.g. PICTURE) or equivalent to the initial | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2006,2007 Josh Coalson | |||||
| * Copyright (C) 2006-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2001-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -34,7 +35,7 @@ | |||||
| #include "../../../stream_decoder.h" | #include "../../../stream_decoder.h" | ||||
| #if FLAC__HAS_OGG | #if FLAC__HAS_OGG | ||||
| #include "include/private/ogg_decoder_aspect.h" | |||||
| #include "../private/ogg_decoder_aspect.h" | |||||
| #endif | #endif | ||||
| typedef struct FLAC__StreamDecoderProtected { | typedef struct FLAC__StreamDecoderProtected { | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2001-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -34,7 +35,7 @@ | |||||
| #include "../../../stream_encoder.h" | #include "../../../stream_encoder.h" | ||||
| #if FLAC__HAS_OGG | #if FLAC__HAS_OGG | ||||
| #include "private/ogg_encoder_aspect.h" | |||||
| #include "../private/ogg_encoder_aspect.h" | |||||
| #endif | #endif | ||||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -34,14 +35,19 @@ | |||||
| #endif | #endif | ||||
| #include <math.h> | #include <math.h> | ||||
| #include "../assert.h" | #include "../assert.h" | ||||
| #include "../format.h" | #include "../format.h" | ||||
| #include "../compat.h" | |||||
| #include "include/private/bitmath.h" | #include "include/private/bitmath.h" | ||||
| #include "include/private/lpc.h" | #include "include/private/lpc.h" | ||||
| #if defined DEBUG || defined FLAC__OVERFLOW_DETECT || defined FLAC__OVERFLOW_DETECT_VERBOSE | #if defined DEBUG || defined FLAC__OVERFLOW_DETECT || defined FLAC__OVERFLOW_DETECT_VERBOSE | ||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #endif | #endif | ||||
| /* OPT: #undef'ing this may improve the speed on some architectures */ | |||||
| #define FLAC__LPC_UNROLLED_FILTER_LOOPS | |||||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||||
| #ifndef M_LN2 | #ifndef M_LN2 | ||||
| @@ -49,9 +55,18 @@ | |||||
| #define M_LN2 0.69314718055994530942 | #define M_LN2 0.69314718055994530942 | ||||
| #endif | #endif | ||||
| /* OPT: #undef'ing this may improve the speed on some architectures */ | |||||
| #define FLAC__LPC_UNROLLED_FILTER_LOOPS | |||||
| #if !defined(HAVE_LROUND) | |||||
| #if defined(_MSC_VER) | |||||
| #include <float.h> | |||||
| #define copysign _copysign | |||||
| #elif defined(__GNUC__) | |||||
| #define copysign __builtin_copysign | |||||
| #endif | |||||
| static inline long int lround(double x) { | |||||
| return (long)(x + copysign (0.5, x)); | |||||
| } | |||||
| //If this fails, we are in the precence of a mid 90's compiler..move along... | |||||
| #endif | |||||
| void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], unsigned data_len) | void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], unsigned data_len) | ||||
| { | { | ||||
| @@ -126,6 +141,7 @@ void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], unsigned *max_o | |||||
| r = -autoc[i+1]; | r = -autoc[i+1]; | ||||
| for(j = 0; j < i; j++) | for(j = 0; j < i; j++) | ||||
| r -= lpc[j] * autoc[i-j]; | r -= lpc[j] * autoc[i-j]; | ||||
| r /= err; | |||||
| /* Update LPC coefficients and total error. */ | /* Update LPC coefficients and total error. */ | ||||
| lpc[i]=r; | lpc[i]=r; | ||||
| @@ -199,14 +215,8 @@ int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], unsigned order, | |||||
| FLAC__int32 q; | FLAC__int32 q; | ||||
| for(i = 0; i < order; i++) { | for(i = 0; i < order; i++) { | ||||
| error += lp_coeff[i] * (1 << *shift); | error += lp_coeff[i] * (1 << *shift); | ||||
| #if 1 /* unfortunately lround() is C99 */ | |||||
| if(error >= 0.0) | |||||
| q = (FLAC__int32)(error + 0.5); | |||||
| else | |||||
| q = (FLAC__int32)(error - 0.5); | |||||
| #else | |||||
| q = lround(error); | q = lround(error); | ||||
| #endif | |||||
| #ifdef FLAC__OVERFLOW_DETECT | #ifdef FLAC__OVERFLOW_DETECT | ||||
| if(q > qmax+1) /* we expect q==qmax+1 occasionally due to rounding */ | if(q > qmax+1) /* we expect q==qmax+1 occasionally due to rounding */ | ||||
| fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q>qmax %d>%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n",q,qmax,*shift,cmax,precision+1,i,lp_coeff[i]); | fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q>qmax %d>%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n",q,qmax,*shift,cmax,precision+1,i,lp_coeff[i]); | ||||
| @@ -234,14 +244,7 @@ int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], unsigned order, | |||||
| #endif | #endif | ||||
| for(i = 0; i < order; i++) { | for(i = 0; i < order; i++) { | ||||
| error += lp_coeff[i] / (1 << nshift); | error += lp_coeff[i] / (1 << nshift); | ||||
| #if 1 /* unfortunately lround() is C99 */ | |||||
| if(error >= 0.0) | |||||
| q = (FLAC__int32)(error + 0.5); | |||||
| else | |||||
| q = (FLAC__int32)(error - 0.5); | |||||
| #else | |||||
| q = lround(error); | q = lround(error); | ||||
| #endif | |||||
| #ifdef FLAC__OVERFLOW_DETECT | #ifdef FLAC__OVERFLOW_DETECT | ||||
| if(q > qmax+1) /* we expect q==qmax+1 occasionally due to rounding */ | if(q > qmax+1) /* we expect q==qmax+1 occasionally due to rounding */ | ||||
| fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q>qmax %d>%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n",q,qmax,*shift,cmax,precision+1,i,lp_coeff[i]); | fprintf(stderr,"FLAC__lpc_quantize_coefficients: quantizer overflow: q>qmax %d>%d shift=%d cmax=%f precision=%u lpc[%u]=%f\n",q,qmax,*shift,cmax,precision+1,i,lp_coeff[i]); | ||||
| @@ -284,13 +287,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, u | |||||
| for(j = 0; j < order; j++) { | for(j = 0; j < order; j++) { | ||||
| sum += qlp_coeff[j] * (*(--history)); | sum += qlp_coeff[j] * (*(--history)); | ||||
| sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history); | sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history); | ||||
| #if defined _MSC_VER | |||||
| if(sumo > 2147483647I64 || sumo < -2147483648I64) | |||||
| fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%I64d\n",i,j,qlp_coeff[j],*history,sumo); | |||||
| #else | |||||
| if(sumo > 2147483647ll || sumo < -2147483648ll) | |||||
| fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%lld\n",i,j,qlp_coeff[j],*history,(long long)sumo); | |||||
| #endif | |||||
| fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%" PRId64 "\n",i,j,qlp_coeff[j],*history,sumo); | |||||
| } | } | ||||
| *(residual++) = *(data++) - (sum >> lp_quantization); | *(residual++) = *(data++) - (sum >> lp_quantization); | ||||
| } | } | ||||
| @@ -548,19 +545,11 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da | |||||
| for(j = 0; j < order; j++) | for(j = 0; j < order; j++) | ||||
| sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history)); | sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history)); | ||||
| if(FLAC__bitmath_silog2_wide(sum >> lp_quantization) > 32) { | if(FLAC__bitmath_silog2_wide(sum >> lp_quantization) > 32) { | ||||
| #if defined _MSC_VER | |||||
| fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, sum=%I64d\n", i, sum >> lp_quantization); | |||||
| #else | |||||
| fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, sum=%lld\n", i, (long long)(sum >> lp_quantization)); | |||||
| #endif | |||||
| fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, sum=%" PRId64 "\n", i, (sum >> lp_quantization)); | |||||
| break; | break; | ||||
| } | } | ||||
| if(FLAC__bitmath_silog2_wide((FLAC__int64)(*data) - (sum >> lp_quantization)) > 32) { | if(FLAC__bitmath_silog2_wide((FLAC__int64)(*data) - (sum >> lp_quantization)) > 32) { | ||||
| #if defined _MSC_VER | |||||
| fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, data=%d, sum=%I64d, residual=%I64d\n", i, *data, sum >> lp_quantization, (FLAC__int64)(*data) - (sum >> lp_quantization)); | |||||
| #else | |||||
| fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, data=%d, sum=%lld, residual=%lld\n", i, *data, (long long)(sum >> lp_quantization), (long long)((FLAC__int64)(*data) - (sum >> lp_quantization))); | |||||
| #endif | |||||
| fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, data=%d, sum=%" PRId64 ", residual=%" PRId64 "\n", i, *data, (long long)(sum >> lp_quantization), ((FLAC__int64)(*data) - (sum >> lp_quantization))); | |||||
| break; | break; | ||||
| } | } | ||||
| *(residual++) = *(data++) - (FLAC__int32)(sum >> lp_quantization); | *(residual++) = *(data++) - (FLAC__int32)(sum >> lp_quantization); | ||||
| @@ -814,13 +803,8 @@ void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, c | |||||
| for(j = 0; j < order; j++) { | for(j = 0; j < order; j++) { | ||||
| sum += qlp_coeff[j] * (*(--history)); | sum += qlp_coeff[j] * (*(--history)); | ||||
| sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history); | sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history); | ||||
| #if defined _MSC_VER | |||||
| if(sumo > 2147483647I64 || sumo < -2147483648I64) | |||||
| fprintf(stderr,"FLAC__lpc_restore_signal: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%I64d\n",i,j,qlp_coeff[j],*history,sumo); | |||||
| #else | |||||
| if(sumo > 2147483647ll || sumo < -2147483648ll) | if(sumo > 2147483647ll || sumo < -2147483648ll) | ||||
| fprintf(stderr,"FLAC__lpc_restore_signal: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%lld\n",i,j,qlp_coeff[j],*history,(long long)sumo); | |||||
| #endif | |||||
| fprintf(stderr,"FLAC__lpc_restore_signal: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%" PRId64 "\n",i,j,qlp_coeff[j],*history,sumo); | |||||
| } | } | ||||
| *(data++) = *(r++) + (sum >> lp_quantization); | *(data++) = *(r++) + (sum >> lp_quantization); | ||||
| } | } | ||||
| @@ -1078,19 +1062,11 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l | |||||
| for(j = 0; j < order; j++) | for(j = 0; j < order; j++) | ||||
| sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history)); | sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history)); | ||||
| if(FLAC__bitmath_silog2_wide(sum >> lp_quantization) > 32) { | if(FLAC__bitmath_silog2_wide(sum >> lp_quantization) > 32) { | ||||
| #ifdef _MSC_VER | |||||
| fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, sum=%I64d\n", i, sum >> lp_quantization); | |||||
| #else | |||||
| fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, sum=%lld\n", i, (long long)(sum >> lp_quantization)); | |||||
| #endif | |||||
| fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, sum=%" PRId64 "\n", i, (sum >> lp_quantization)); | |||||
| break; | break; | ||||
| } | } | ||||
| if(FLAC__bitmath_silog2_wide((FLAC__int64)(*r) + (sum >> lp_quantization)) > 32) { | if(FLAC__bitmath_silog2_wide((FLAC__int64)(*r) + (sum >> lp_quantization)) > 32) { | ||||
| #ifdef _MSC_VER | |||||
| fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, residual=%d, sum=%I64d, data=%I64d\n", i, *r, sum >> lp_quantization, (FLAC__int64)(*r) + (sum >> lp_quantization)); | |||||
| #else | |||||
| fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, residual=%d, sum=%lld, data=%lld\n", i, *r, (long long)(sum >> lp_quantization), (long long)((FLAC__int64)(*r) + (sum >> lp_quantization))); | |||||
| #endif | |||||
| fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, residual=%d, sum=%" PRId64 ", data=%" PRId64 "\n", i, *r, (sum >> lp_quantization), ((FLAC__int64)(*r) + (sum >> lp_quantization))); | |||||
| break; | break; | ||||
| } | } | ||||
| *(data++) = *(r++) + (FLAC__int32)(sum >> lp_quantization); | *(data++) = *(r++) + (FLAC__int32)(sum >> lp_quantization); | ||||
| @@ -1351,7 +1327,7 @@ FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scal | |||||
| unsigned FLAC__lpc_compute_best_order(const FLAC__double lpc_error[], unsigned max_order, unsigned total_samples, unsigned overhead_bits_per_order) | unsigned FLAC__lpc_compute_best_order(const FLAC__double lpc_error[], unsigned max_order, unsigned total_samples, unsigned overhead_bits_per_order) | ||||
| { | { | ||||
| unsigned order, index, best_index; /* 'index' the index into lpc_error; index==order-1 since lpc_error[0] is for order==1, lpc_error[1] is for order==2, etc */ | |||||
| unsigned order, indx, best_index; /* 'index' the index into lpc_error; index==order-1 since lpc_error[0] is for order==1, lpc_error[1] is for order==2, etc */ | |||||
| FLAC__double bits, best_bits, error_scale; | FLAC__double bits, best_bits, error_scale; | ||||
| FLAC__ASSERT(max_order > 0); | FLAC__ASSERT(max_order > 0); | ||||
| @@ -1362,15 +1338,15 @@ unsigned FLAC__lpc_compute_best_order(const FLAC__double lpc_error[], unsigned m | |||||
| best_index = 0; | best_index = 0; | ||||
| best_bits = (unsigned)(-1); | best_bits = (unsigned)(-1); | ||||
| for(index = 0, order = 1; index < max_order; index++, order++) { | |||||
| bits = FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error[index], error_scale) * (FLAC__double)(total_samples - order) + (FLAC__double)(order * overhead_bits_per_order); | |||||
| for(indx = 0, order = 1; indx < max_order; indx++, order++) { | |||||
| bits = FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error[indx], error_scale) * (FLAC__double)(total_samples - order) + (FLAC__double)(order * overhead_bits_per_order); | |||||
| if(bits < best_bits) { | if(bits < best_bits) { | ||||
| best_index = index; | |||||
| best_index = indx; | |||||
| best_bits = bits; | best_bits = bits; | ||||
| } | } | ||||
| } | } | ||||
| return best_index+1; /* +1 since index of lpc_error[] is order-1 */ | |||||
| return best_index+1; /* +1 since indx of lpc_error[] is order-1 */ | |||||
| } | } | ||||
| #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ | #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ | ||||
| @@ -1,4 +1,3 @@ | |||||
| #if HAVE_CONFIG_H | #if HAVE_CONFIG_H | ||||
| # include <config.h> | # include <config.h> | ||||
| #endif | #endif | ||||
| @@ -9,10 +8,6 @@ | |||||
| #include "include/private/md5.h" | #include "include/private/md5.h" | ||||
| #include "../alloc.h" | #include "../alloc.h" | ||||
| #ifndef FLaC__INLINE | |||||
| #define FLaC__INLINE | |||||
| #endif | |||||
| /* | /* | ||||
| * This code implements the MD5 message-digest algorithm. | * This code implements the MD5 message-digest algorithm. | ||||
| * The algorithm is due to Ron Rivest. This code was | * The algorithm is due to Ron Rivest. This code was | ||||
| @@ -264,12 +259,12 @@ void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *ctx) | |||||
| byteSwap(ctx->buf, 4); | byteSwap(ctx->buf, 4); | ||||
| memcpy(digest, ctx->buf, 16); | memcpy(digest, ctx->buf, 16); | ||||
| //memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ | |||||
| if(0 != ctx->internal_buf) { | if(0 != ctx->internal_buf) { | ||||
| free(ctx->internal_buf); | free(ctx->internal_buf); | ||||
| ctx->internal_buf = 0; | ctx->internal_buf = 0; | ||||
| ctx->capacity = 0; | ctx->capacity = 0; | ||||
| } | } | ||||
| memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ | |||||
| } | } | ||||
| /* | /* | ||||
| @@ -407,13 +402,14 @@ FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const | |||||
| return false; | return false; | ||||
| if(ctx->capacity < bytes_needed) { | if(ctx->capacity < bytes_needed) { | ||||
| FLAC__byte *tmp = (FLAC__byte*)realloc(ctx->internal_buf, bytes_needed); | |||||
| FLAC__byte *tmp = (FLAC__byte*) realloc(ctx->internal_buf, bytes_needed); | |||||
| if(0 == tmp) { | if(0 == tmp) { | ||||
| free(ctx->internal_buf); | free(ctx->internal_buf); | ||||
| if(0 == (ctx->internal_buf = (FLAC__byte*)safe_malloc_(bytes_needed))) | |||||
| if(0 == (ctx->internal_buf = (FLAC__byte*) safe_malloc_(bytes_needed))) | |||||
| return false; | return false; | ||||
| } | } | ||||
| ctx->internal_buf = tmp; | |||||
| else | |||||
| ctx->internal_buf = tmp; | |||||
| ctx->capacity = bytes_needed; | ctx->capacity = bytes_needed; | ||||
| } | } | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2001-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -71,7 +72,7 @@ void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address) | |||||
| return x; | return x; | ||||
| } | } | ||||
| FLAC__bool FLAC__memory_alloc_aligned_int32_array(unsigned elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer) | |||||
| FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer) | |||||
| { | { | ||||
| FLAC__int32 *pu; /* unaligned pointer */ | FLAC__int32 *pu; /* unaligned pointer */ | ||||
| union { /* union needed to comply with C99 pointer aliasing rules */ | union { /* union needed to comply with C99 pointer aliasing rules */ | ||||
| @@ -84,7 +85,10 @@ FLAC__bool FLAC__memory_alloc_aligned_int32_array(unsigned elements, FLAC__int32 | |||||
| FLAC__ASSERT(0 != aligned_pointer); | FLAC__ASSERT(0 != aligned_pointer); | ||||
| FLAC__ASSERT(unaligned_pointer != aligned_pointer); | FLAC__ASSERT(unaligned_pointer != aligned_pointer); | ||||
| pu = (FLAC__int32*)FLAC__memory_alloc_aligned(sizeof(*pu) * (size_t)elements, &u.pv); | |||||
| if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ | |||||
| return false; | |||||
| pu = (FLAC__int32*) FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); | |||||
| if(0 == pu) { | if(0 == pu) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -97,7 +101,7 @@ FLAC__bool FLAC__memory_alloc_aligned_int32_array(unsigned elements, FLAC__int32 | |||||
| } | } | ||||
| } | } | ||||
| FLAC__bool FLAC__memory_alloc_aligned_uint32_array(unsigned elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer) | |||||
| FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer) | |||||
| { | { | ||||
| FLAC__uint32 *pu; /* unaligned pointer */ | FLAC__uint32 *pu; /* unaligned pointer */ | ||||
| union { /* union needed to comply with C99 pointer aliasing rules */ | union { /* union needed to comply with C99 pointer aliasing rules */ | ||||
| @@ -110,7 +114,10 @@ FLAC__bool FLAC__memory_alloc_aligned_uint32_array(unsigned elements, FLAC__uint | |||||
| FLAC__ASSERT(0 != aligned_pointer); | FLAC__ASSERT(0 != aligned_pointer); | ||||
| FLAC__ASSERT(unaligned_pointer != aligned_pointer); | FLAC__ASSERT(unaligned_pointer != aligned_pointer); | ||||
| pu = (FLAC__uint32*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); | |||||
| if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ | |||||
| return false; | |||||
| pu = (FLAC__uint32*) FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); | |||||
| if(0 == pu) { | if(0 == pu) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -123,7 +130,7 @@ FLAC__bool FLAC__memory_alloc_aligned_uint32_array(unsigned elements, FLAC__uint | |||||
| } | } | ||||
| } | } | ||||
| FLAC__bool FLAC__memory_alloc_aligned_uint64_array(unsigned elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer) | |||||
| FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer) | |||||
| { | { | ||||
| FLAC__uint64 *pu; /* unaligned pointer */ | FLAC__uint64 *pu; /* unaligned pointer */ | ||||
| union { /* union needed to comply with C99 pointer aliasing rules */ | union { /* union needed to comply with C99 pointer aliasing rules */ | ||||
| @@ -136,7 +143,10 @@ FLAC__bool FLAC__memory_alloc_aligned_uint64_array(unsigned elements, FLAC__uint | |||||
| FLAC__ASSERT(0 != aligned_pointer); | FLAC__ASSERT(0 != aligned_pointer); | ||||
| FLAC__ASSERT(unaligned_pointer != aligned_pointer); | FLAC__ASSERT(unaligned_pointer != aligned_pointer); | ||||
| pu = (FLAC__uint64*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); | |||||
| if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ | |||||
| return false; | |||||
| pu = (FLAC__uint64*) FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); | |||||
| if(0 == pu) { | if(0 == pu) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -149,7 +159,7 @@ FLAC__bool FLAC__memory_alloc_aligned_uint64_array(unsigned elements, FLAC__uint | |||||
| } | } | ||||
| } | } | ||||
| FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(unsigned elements, unsigned **unaligned_pointer, unsigned **aligned_pointer) | |||||
| FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, unsigned **unaligned_pointer, unsigned **aligned_pointer) | |||||
| { | { | ||||
| unsigned *pu; /* unaligned pointer */ | unsigned *pu; /* unaligned pointer */ | ||||
| union { /* union needed to comply with C99 pointer aliasing rules */ | union { /* union needed to comply with C99 pointer aliasing rules */ | ||||
| @@ -162,7 +172,10 @@ FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(unsigned elements, unsigned | |||||
| FLAC__ASSERT(0 != aligned_pointer); | FLAC__ASSERT(0 != aligned_pointer); | ||||
| FLAC__ASSERT(unaligned_pointer != aligned_pointer); | FLAC__ASSERT(unaligned_pointer != aligned_pointer); | ||||
| pu = (unsigned*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); | |||||
| if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ | |||||
| return false; | |||||
| pu = (unsigned int*) FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); | |||||
| if(0 == pu) { | if(0 == pu) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -177,7 +190,7 @@ FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(unsigned elements, unsigned | |||||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||||
| FLAC__bool FLAC__memory_alloc_aligned_real_array(unsigned elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer) | |||||
| FLAC__bool FLAC__memory_alloc_aligned_real_array(size_t elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer) | |||||
| { | { | ||||
| FLAC__real *pu; /* unaligned pointer */ | FLAC__real *pu; /* unaligned pointer */ | ||||
| union { /* union needed to comply with C99 pointer aliasing rules */ | union { /* union needed to comply with C99 pointer aliasing rules */ | ||||
| @@ -190,7 +203,10 @@ FLAC__bool FLAC__memory_alloc_aligned_real_array(unsigned elements, FLAC__real * | |||||
| FLAC__ASSERT(0 != aligned_pointer); | FLAC__ASSERT(0 != aligned_pointer); | ||||
| FLAC__ASSERT(unaligned_pointer != aligned_pointer); | FLAC__ASSERT(unaligned_pointer != aligned_pointer); | ||||
| pu = (FLAC__real*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); | |||||
| if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ | |||||
| return false; | |||||
| pu = (FLAC__real*) FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); | |||||
| if(0 == pu) { | if(0 == pu) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -204,3 +220,12 @@ FLAC__bool FLAC__memory_alloc_aligned_real_array(unsigned elements, FLAC__real * | |||||
| } | } | ||||
| #endif | #endif | ||||
| void *safe_malloc_mul_2op_p(size_t size1, size_t size2) | |||||
| { | |||||
| if(!size1 || !size2) | |||||
| return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ | |||||
| if(size1 > SIZE_MAX / size2) | |||||
| return 0; | |||||
| return malloc(size1*size2); | |||||
| } | |||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -33,23 +34,12 @@ | |||||
| # include <config.h> | # include <config.h> | ||||
| #endif | #endif | ||||
| #if defined _MSC_VER || defined __MINGW32__ | |||||
| #include <io.h> /* for _setmode() */ | |||||
| #include <fcntl.h> /* for _O_BINARY */ | |||||
| #endif | |||||
| #if defined __CYGWIN__ || defined __EMX__ | |||||
| #include <io.h> /* for setmode(), O_BINARY */ | |||||
| #include <fcntl.h> /* for _O_BINARY */ | |||||
| #endif | |||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #include <stdlib.h> /* for malloc() */ | #include <stdlib.h> /* for malloc() */ | ||||
| #include <string.h> /* for memset/memcpy() */ | #include <string.h> /* for memset/memcpy() */ | ||||
| #include <sys/stat.h> /* for stat() */ | #include <sys/stat.h> /* for stat() */ | ||||
| #include <sys/types.h> /* for off_t */ | #include <sys/types.h> /* for off_t */ | ||||
| #if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ | |||||
| #define fseeko fseek | |||||
| #define ftello ftell | |||||
| #endif | |||||
| #include "../compat.h" | |||||
| #include "../assert.h" | #include "../assert.h" | ||||
| #include "../alloc.h" | #include "../alloc.h" | ||||
| #include "include/protected/stream_decoder.h" | #include "include/protected/stream_decoder.h" | ||||
| @@ -63,18 +53,6 @@ | |||||
| #include "include/private/md5.h" | #include "include/private/md5.h" | ||||
| #include "include/private/memory.h" | #include "include/private/memory.h" | ||||
| #ifdef max | |||||
| #undef max | |||||
| #endif | |||||
| #define max(a,b) ((a)>(b)?(a):(b)) | |||||
| /* adjust for compilers that can't understand using LLU suffix for uint64_t literals */ | |||||
| #ifdef _MSC_VER | |||||
| #define FLAC__U64L(x) x | |||||
| #else | |||||
| #define FLAC__U64L(x) x##LLU | |||||
| #endif | |||||
| /* technically this should be in an "export.c" but this is convenient enough */ | /* technically this should be in an "export.c" but this is convenient enough */ | ||||
| FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC = | FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC = | ||||
| @@ -100,8 +78,8 @@ static FLAC__byte ID3V2_TAG_[3] = { 'I', 'D', '3' }; | |||||
| * | * | ||||
| ***********************************************************************/ | ***********************************************************************/ | ||||
| static void set_defaults_dec(FLAC__StreamDecoder *decoder); | |||||
| static FILE *get_binary_stdin_(void); | |||||
| static void set_defaults_(FLAC__StreamDecoder *decoder); | |||||
| //static FILE *get_binary_stdin_(void); | |||||
| static FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigned channels); | static FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigned channels); | ||||
| static FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id); | static FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id); | ||||
| static FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder); | static FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder); | ||||
| @@ -133,11 +111,11 @@ static FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__u | |||||
| #if FLAC__HAS_OGG | #if FLAC__HAS_OGG | ||||
| static FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample); | static FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample); | ||||
| #endif | #endif | ||||
| static FLAC__StreamDecoderReadStatus file_read_callback_dec (const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data); | |||||
| static FLAC__StreamDecoderSeekStatus file_seek_callback_dec (const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data); | |||||
| static FLAC__StreamDecoderTellStatus file_tell_callback_dec (const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data); | |||||
| static FLAC__StreamDecoderLengthStatus file_length_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data); | |||||
| static FLAC__bool file_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_data); | |||||
| //static FLAC__StreamDecoderReadStatus file_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data); | |||||
| //static FLAC__StreamDecoderSeekStatus file_seek_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data); | |||||
| //static FLAC__StreamDecoderTellStatus file_tell_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data); | |||||
| //static FLAC__StreamDecoderLengthStatus file_length_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data); | |||||
| //static FLAC__bool file_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_data); | |||||
| /*********************************************************************** | /*********************************************************************** | ||||
| * | * | ||||
| @@ -165,7 +143,7 @@ typedef struct FLAC__StreamDecoderPrivate { | |||||
| void (*local_lpc_restore_signal_16bit)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); | void (*local_lpc_restore_signal_16bit)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); | ||||
| /* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit), AND order <= 8: */ | /* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit), AND order <= 8: */ | ||||
| void (*local_lpc_restore_signal_16bit_order8)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); | void (*local_lpc_restore_signal_16bit_order8)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); | ||||
| FLAC__bool (*local_bitreader_read_rice_signed_block)(FLAC__BitReader *br, int* vals, unsigned nvals, unsigned parameter); | |||||
| FLAC__bool (*local_bitreader_read_rice_signed_block)(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter); | |||||
| void *client_data; | void *client_data; | ||||
| FILE *file; /* only used if FLAC__stream_decoder_init_file()/FLAC__stream_decoder_init_file() called, else NULL */ | FILE *file; /* only used if FLAC__stream_decoder_init_file()/FLAC__stream_decoder_init_file() called, else NULL */ | ||||
| FLAC__BitReader *input; | FLAC__BitReader *input; | ||||
| @@ -279,18 +257,18 @@ FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(void) | |||||
| FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ | FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ | ||||
| decoder = (FLAC__StreamDecoder*)calloc(1, sizeof(FLAC__StreamDecoder)); | |||||
| decoder = (FLAC__StreamDecoder*) calloc(1, sizeof(FLAC__StreamDecoder)); | |||||
| if(decoder == 0) { | if(decoder == 0) { | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| decoder->protected_ = (FLAC__StreamDecoderProtected*)calloc(1, sizeof(FLAC__StreamDecoderProtected)); | |||||
| decoder->protected_ = (FLAC__StreamDecoderProtected*) calloc(1, sizeof(FLAC__StreamDecoderProtected)); | |||||
| if(decoder->protected_ == 0) { | if(decoder->protected_ == 0) { | ||||
| free(decoder); | free(decoder); | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| decoder->private_ = (FLAC__StreamDecoderPrivate*)calloc(1, sizeof(FLAC__StreamDecoderPrivate)); | |||||
| decoder->private_ = (FLAC__StreamDecoderPrivate*) calloc(1, sizeof(FLAC__StreamDecoderPrivate)); | |||||
| if(decoder->private_ == 0) { | if(decoder->private_ == 0) { | ||||
| free(decoder->protected_); | free(decoder->protected_); | ||||
| free(decoder); | free(decoder); | ||||
| @@ -306,7 +284,7 @@ FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(void) | |||||
| } | } | ||||
| decoder->private_->metadata_filter_ids_capacity = 16; | decoder->private_->metadata_filter_ids_capacity = 16; | ||||
| if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)malloc((FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) * decoder->private_->metadata_filter_ids_capacity))) { | |||||
| if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*) malloc((FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) * decoder->private_->metadata_filter_ids_capacity))) { | |||||
| FLAC__bitreader_delete(decoder->private_->input); | FLAC__bitreader_delete(decoder->private_->input); | ||||
| free(decoder->private_); | free(decoder->private_); | ||||
| free(decoder->protected_); | free(decoder->protected_); | ||||
| @@ -328,7 +306,7 @@ FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(void) | |||||
| decoder->private_->file = 0; | decoder->private_->file = 0; | ||||
| set_defaults_dec(decoder); | |||||
| set_defaults_(decoder); | |||||
| decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED; | decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED; | ||||
| @@ -339,7 +317,9 @@ FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder) | |||||
| { | { | ||||
| unsigned i; | unsigned i; | ||||
| FLAC__ASSERT(0 != decoder); | |||||
| if (decoder == NULL) | |||||
| return ; | |||||
| FLAC__ASSERT(0 != decoder->protected_); | FLAC__ASSERT(0 != decoder->protected_); | ||||
| FLAC__ASSERT(0 != decoder->private_); | FLAC__ASSERT(0 != decoder->private_); | ||||
| FLAC__ASSERT(0 != decoder->private_->input); | FLAC__ASSERT(0 != decoder->private_->input); | ||||
| @@ -365,7 +345,7 @@ FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder) | |||||
| * | * | ||||
| ***********************************************************************/ | ***********************************************************************/ | ||||
| static FLAC__StreamDecoderInitStatus init_stream_internal_dec( | |||||
| static FLAC__StreamDecoderInitStatus init_stream_internal_( | |||||
| FLAC__StreamDecoder *decoder, | FLAC__StreamDecoder *decoder, | ||||
| FLAC__StreamDecoderReadCallback read_callback, | FLAC__StreamDecoderReadCallback read_callback, | ||||
| FLAC__StreamDecoderSeekCallback seek_callback, | FLAC__StreamDecoderSeekCallback seek_callback, | ||||
| @@ -490,7 +470,7 @@ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_stream( | |||||
| void *client_data | void *client_data | ||||
| ) | ) | ||||
| { | { | ||||
| return init_stream_internal_dec( | |||||
| return init_stream_internal_( | |||||
| decoder, | decoder, | ||||
| read_callback, | read_callback, | ||||
| seek_callback, | seek_callback, | ||||
| @@ -518,7 +498,7 @@ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_stream( | |||||
| void *client_data | void *client_data | ||||
| ) | ) | ||||
| { | { | ||||
| return init_stream_internal_dec( | |||||
| return init_stream_internal_( | |||||
| decoder, | decoder, | ||||
| read_callback, | read_callback, | ||||
| seek_callback, | seek_callback, | ||||
| @@ -533,6 +513,7 @@ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_stream( | |||||
| ); | ); | ||||
| } | } | ||||
| #if 0 | |||||
| static FLAC__StreamDecoderInitStatus init_FILE_internal_( | static FLAC__StreamDecoderInitStatus init_FILE_internal_( | ||||
| FLAC__StreamDecoder *decoder, | FLAC__StreamDecoder *decoder, | ||||
| FILE *file, | FILE *file, | ||||
| @@ -562,11 +543,11 @@ static FLAC__StreamDecoderInitStatus init_FILE_internal_( | |||||
| decoder->private_->file = file; | decoder->private_->file = file; | ||||
| return init_stream_internal_dec( | |||||
| return init_stream_internal_( | |||||
| decoder, | decoder, | ||||
| file_read_callback_dec, | |||||
| decoder->private_->file == stdin? 0: file_seek_callback_dec, | |||||
| decoder->private_->file == stdin? 0: file_tell_callback_dec, | |||||
| file_read_callback_, | |||||
| decoder->private_->file == stdin? 0: file_seek_callback_, | |||||
| decoder->private_->file == stdin? 0: file_tell_callback_, | |||||
| decoder->private_->file == stdin? 0: file_length_callback_, | decoder->private_->file == stdin? 0: file_length_callback_, | ||||
| file_eof_callback_, | file_eof_callback_, | ||||
| write_callback, | write_callback, | ||||
| @@ -626,7 +607,7 @@ static FLAC__StreamDecoderInitStatus init_file_internal_( | |||||
| if(0 == write_callback || 0 == error_callback) | if(0 == write_callback || 0 == error_callback) | ||||
| return (FLAC__StreamDecoderInitStatus) (decoder->protected_->state = (FLAC__StreamDecoderState) FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS); | return (FLAC__StreamDecoderInitStatus) (decoder->protected_->state = (FLAC__StreamDecoderState) FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS); | ||||
| file = filename? fopen(filename, "rb") : stdin; | |||||
| file = filename? flac_fopen(filename, "rb") : stdin; | |||||
| if(0 == file) | if(0 == file) | ||||
| return FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE; | return FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE; | ||||
| @@ -657,6 +638,7 @@ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_file( | |||||
| { | { | ||||
| return init_file_internal_(decoder, filename, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/true); | return init_file_internal_(decoder, filename, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/true); | ||||
| } | } | ||||
| #endif | |||||
| FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder) | FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder) | ||||
| { | { | ||||
| @@ -717,7 +699,7 @@ FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder) | |||||
| } | } | ||||
| decoder->private_->is_seeking = false; | decoder->private_->is_seeking = false; | ||||
| set_defaults_dec(decoder); | |||||
| set_defaults_(decoder); | |||||
| decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED; | decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED; | ||||
| @@ -783,7 +765,7 @@ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__ | |||||
| FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids); | FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids); | ||||
| if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) { | if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) { | ||||
| 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))) { | |||||
| 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; | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -842,7 +824,7 @@ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__S | |||||
| FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids); | FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids); | ||||
| if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) { | if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) { | ||||
| 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))) { | |||||
| 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; | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -1249,7 +1231,7 @@ unsigned FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecod | |||||
| * | * | ||||
| ***********************************************************************/ | ***********************************************************************/ | ||||
| void set_defaults_dec(FLAC__StreamDecoder *decoder) | |||||
| void set_defaults_(FLAC__StreamDecoder *decoder) | |||||
| { | { | ||||
| #if FLAC__HAS_OGG | #if FLAC__HAS_OGG | ||||
| decoder->private_->is_ogg = false; | decoder->private_->is_ogg = false; | ||||
| @@ -1275,6 +1257,7 @@ void set_defaults_dec(FLAC__StreamDecoder *decoder) | |||||
| #endif | #endif | ||||
| } | } | ||||
| #if 0 | |||||
| /* | /* | ||||
| * This will forcibly set stdin to binary mode (for OSes that require it) | * This will forcibly set stdin to binary mode (for OSes that require it) | ||||
| */ | */ | ||||
| @@ -1295,6 +1278,7 @@ FILE *get_binary_stdin_(void) | |||||
| return stdin; | return stdin; | ||||
| } | } | ||||
| #endif | |||||
| FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigned channels) | FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigned channels) | ||||
| { | { | ||||
| @@ -1324,7 +1308,7 @@ FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigne | |||||
| * (at negative indices) for alignment purposes; we use 4 | * (at negative indices) for alignment purposes; we use 4 | ||||
| * to keep the data well-aligned. | * to keep the data well-aligned. | ||||
| */ | */ | ||||
| tmp = (FLAC__int32*)safe_malloc_muladd2_(sizeof(FLAC__int32), /*times (*/size, /*+*/4/*)*/); | |||||
| tmp = (FLAC__int32*) safe_malloc_muladd2_(sizeof(FLAC__int32), /*times (*/size, /*+*/4/*)*/); | |||||
| if(tmp == 0) { | if(tmp == 0) { | ||||
| decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||||
| return false; | return false; | ||||
| @@ -1405,7 +1389,7 @@ FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder) | |||||
| decoder->private_->lookahead = (FLAC__byte)x; | decoder->private_->lookahead = (FLAC__byte)x; | ||||
| decoder->private_->cached = true; | decoder->private_->cached = true; | ||||
| } | } | ||||
| else if(x >> 2 == 0x3e) { /* MAGIC NUMBER for the last 6 sync bits */ | |||||
| else if(x >> 1 == 0x7c) { /* MAGIC NUMBER for the last 6 sync bits and reserved 7th bit */ | |||||
| decoder->private_->header_warmup[1] = (FLAC__byte)x; | decoder->private_->header_warmup[1] = (FLAC__byte)x; | ||||
| decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME; | decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME; | ||||
| return true; | return true; | ||||
| @@ -1495,7 +1479,7 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) | |||||
| case FLAC__METADATA_TYPE_APPLICATION: | case FLAC__METADATA_TYPE_APPLICATION: | ||||
| /* remember, we read the ID already */ | /* remember, we read the ID already */ | ||||
| if(real_length > 0) { | if(real_length > 0) { | ||||
| if(0 == (block.data.application.data = (FLAC__byte*)malloc(real_length))) { | |||||
| if(0 == (block.data.application.data = (FLAC__byte*) malloc(real_length))) { | |||||
| decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -1523,7 +1507,7 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) | |||||
| break; | break; | ||||
| default: | default: | ||||
| if(real_length > 0) { | if(real_length > 0) { | ||||
| if(0 == (block.data.unknown.data = (FLAC__byte*)malloc(real_length))) { | |||||
| if(0 == (block.data.unknown.data = (FLAC__byte*) malloc(real_length))) { | |||||
| decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -1677,7 +1661,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; | 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) */ | /* 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*)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)))) { | |||||
| 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; | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -1716,7 +1700,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)) | if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length)) | ||||
| return false; /* read_callback_ sets the state for us */ | return false; /* read_callback_ sets the state for us */ | ||||
| if(obj->vendor_string.length > 0) { | if(obj->vendor_string.length > 0) { | ||||
| if(0 == (obj->vendor_string.entry = (FLAC__byte*)safe_malloc_add_2op_(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; | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -1734,7 +1718,7 @@ FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__Stre | |||||
| /* read comments */ | /* read comments */ | ||||
| if(obj->num_comments > 0) { | if(obj->num_comments > 0) { | ||||
| if(0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)safe_malloc_mul_2op_(obj->num_comments, /*times*/sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) { | |||||
| if(0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*) safe_malloc_mul_2op_p(obj->num_comments, /*times*/sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) { | |||||
| decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -1743,7 +1727,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)) | if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->comments[i].length)) | ||||
| return false; /* read_callback_ sets the state for us */ | return false; /* read_callback_ sets the state for us */ | ||||
| if(obj->comments[i].length > 0) { | if(obj->comments[i].length > 0) { | ||||
| if(0 == (obj->comments[i].entry = (FLAC__byte*)safe_malloc_add_2op_(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; | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -1789,7 +1773,7 @@ FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMet | |||||
| obj->num_tracks = x; | obj->num_tracks = x; | ||||
| if(obj->num_tracks > 0) { | if(obj->num_tracks > 0) { | ||||
| if(0 == (obj->tracks = (FLAC__StreamMetadata_CueSheet_Track*)safe_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; | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -1822,18 +1806,18 @@ FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMet | |||||
| track->num_indices = (FLAC__byte)x; | track->num_indices = (FLAC__byte)x; | ||||
| if(track->num_indices > 0) { | if(track->num_indices > 0) { | ||||
| if(0 == (track->indices = (FLAC__StreamMetadata_CueSheet_Index*)safe_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; | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||||
| return false; | return false; | ||||
| } | } | ||||
| for(j = 0; j < track->num_indices; j++) { | for(j = 0; j < track->num_indices; j++) { | ||||
| FLAC__StreamMetadata_CueSheet_Index *index = &track->indices[j]; | |||||
| if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &index->offset, FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN)) | |||||
| FLAC__StreamMetadata_CueSheet_Index *indx = &track->indices[j]; | |||||
| if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &indx->offset, FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN)) | |||||
| return false; /* read_callback_ sets the state for us */ | return false; /* read_callback_ sets the state for us */ | ||||
| if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN)) | if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN)) | ||||
| return false; /* read_callback_ sets the state for us */ | return false; /* read_callback_ sets the state for us */ | ||||
| index->number = (FLAC__byte)x; | |||||
| indx->number = (FLAC__byte)x; | |||||
| if(!FLAC__bitreader_skip_bits_no_crc(decoder->private_->input, FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN)) | if(!FLAC__bitreader_skip_bits_no_crc(decoder->private_->input, FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN)) | ||||
| return false; /* read_callback_ sets the state for us */ | return false; /* read_callback_ sets the state for us */ | ||||
| @@ -1859,7 +1843,7 @@ FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMeta | |||||
| /* read MIME type */ | /* read MIME type */ | ||||
| if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN)) | 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 */ | return false; /* read_callback_ sets the state for us */ | ||||
| if(0 == (obj->mime_type = (char*)safe_malloc_add_2op_(x, /*+*/1))) { | |||||
| if(0 == (obj->mime_type = (char*) safe_malloc_add_2op_(x, /*+*/1))) { | |||||
| decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -1872,7 +1856,7 @@ FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMeta | |||||
| /* read description */ | /* read description */ | ||||
| if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN)) | 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 */ | return false; /* read_callback_ sets the state for us */ | ||||
| if(0 == (obj->description = (FLAC__byte*)safe_malloc_add_2op_(x, /*+*/1))) { | |||||
| if(0 == (obj->description = (FLAC__byte*) safe_malloc_add_2op_(x, /*+*/1))) { | |||||
| decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -1901,7 +1885,7 @@ FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMeta | |||||
| /* read data */ | /* read data */ | ||||
| if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &(obj->data_length), FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN)) | 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 */ | return false; /* read_callback_ sets the state for us */ | ||||
| if(0 == (obj->data = (FLAC__byte*)safe_malloc_(obj->data_length))) { | |||||
| if(0 == (obj->data = (FLAC__byte*) safe_malloc_(obj->data_length))) { | |||||
| decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -1975,7 +1959,7 @@ FLAC__bool frame_sync_(FLAC__StreamDecoder *decoder) | |||||
| decoder->private_->lookahead = (FLAC__byte)x; | decoder->private_->lookahead = (FLAC__byte)x; | ||||
| decoder->private_->cached = true; | decoder->private_->cached = true; | ||||
| } | } | ||||
| else if(x >> 2 == 0x3e) { /* MAGIC NUMBER for the last 6 sync bits */ | |||||
| else if(x >> 1 == 0x7c) { /* MAGIC NUMBER for the last 6 sync bits and reserved 7th bit */ | |||||
| decoder->private_->header_warmup[1] = (FLAC__byte)x; | decoder->private_->header_warmup[1] = (FLAC__byte)x; | ||||
| decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME; | decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME; | ||||
| return true; | return true; | ||||
| @@ -2735,7 +2719,7 @@ FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigne | |||||
| } | } | ||||
| } | } | ||||
| if(!FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, max(6, partition_order))) { | |||||
| if(!FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, flac_max(6u, partition_order))) { | |||||
| decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -2748,7 +2732,7 @@ FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigne | |||||
| if(rice_parameter < pesc) { | if(rice_parameter < pesc) { | ||||
| partitioned_rice_contents->raw_bits[partition] = 0; | partitioned_rice_contents->raw_bits[partition] = 0; | ||||
| u = (partition_order == 0 || partition > 0)? partition_samples : partition_samples - predictor_order; | u = (partition_order == 0 || partition > 0)? partition_samples : partition_samples - predictor_order; | ||||
| if(!decoder->private_->local_bitreader_read_rice_signed_block(decoder->private_->input, (int*) residual + sample, u, rice_parameter)) | |||||
| if(!decoder->private_->local_bitreader_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter)) | |||||
| return false; /* read_callback_ sets the state for us */ | return false; /* read_callback_ sets the state for us */ | ||||
| sample += u; | sample += u; | ||||
| } | } | ||||
| @@ -2757,7 +2741,7 @@ FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigne | |||||
| return false; /* read_callback_ sets the state for us */ | return false; /* read_callback_ sets the state for us */ | ||||
| partitioned_rice_contents->raw_bits[partition] = rice_parameter; | partitioned_rice_contents->raw_bits[partition] = rice_parameter; | ||||
| for(u = (partition_order == 0 || partition > 0)? 0 : predictor_order; u < partition_samples; u++, sample++) { | for(u = (partition_order == 0 || partition > 0)? 0 : predictor_order; u < partition_samples; u++, sample++) { | ||||
| if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, (FLAC__int32*) &i, rice_parameter)) | |||||
| if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i, rice_parameter)) | |||||
| return false; /* read_callback_ sets the state for us */ | return false; /* read_callback_ sets the state for us */ | ||||
| residual[sample] = i; | residual[sample] = i; | ||||
| } | } | ||||
| @@ -2940,22 +2924,23 @@ FLAC__StreamDecoderWriteStatus write_audio_frame_to_client_(FLAC__StreamDecoder | |||||
| return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data); | return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data); | ||||
| } | } | ||||
| } | } | ||||
| return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; | |||||
| else { | |||||
| return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; | |||||
| } | |||||
| } | |||||
| else { | |||||
| /* | |||||
| * If we never got STREAMINFO, turn off MD5 checking to save | |||||
| * cycles since we don't have a sum to compare to anyway | |||||
| */ | |||||
| if(!decoder->private_->has_stream_info) | |||||
| decoder->private_->do_md5_checking = false; | |||||
| if(decoder->private_->do_md5_checking) { | |||||
| if(!FLAC__MD5Accumulate(&decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8)) | |||||
| return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; | |||||
| } | |||||
| return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data); | |||||
| } | } | ||||
| /* | |||||
| * If we never got STREAMINFO, turn off MD5 checking to save | |||||
| * cycles since we don't have a sum to compare to anyway | |||||
| */ | |||||
| if(!decoder->private_->has_stream_info) | |||||
| decoder->private_->do_md5_checking = false; | |||||
| if(decoder->private_->do_md5_checking) { | |||||
| if(!FLAC__MD5Accumulate(&decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8)) | |||||
| return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; | |||||
| } | |||||
| return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data); | |||||
| } | } | ||||
| void send_error_to_client_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status) | void send_error_to_client_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status) | ||||
| @@ -3317,7 +3302,8 @@ FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint | |||||
| } | } | ||||
| #endif | #endif | ||||
| FLAC__StreamDecoderReadStatus file_read_callback_dec(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) | |||||
| #if 0 | |||||
| FLAC__StreamDecoderReadStatus file_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) | |||||
| { | { | ||||
| (void)client_data; | (void)client_data; | ||||
| @@ -3334,21 +3320,21 @@ FLAC__StreamDecoderReadStatus file_read_callback_dec(const FLAC__StreamDecoder * | |||||
| return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */ | return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */ | ||||
| } | } | ||||
| FLAC__StreamDecoderSeekStatus file_seek_callback_dec(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) | |||||
| FLAC__StreamDecoderSeekStatus file_seek_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) | |||||
| { | { | ||||
| (void)client_data; | (void)client_data; | ||||
| if(decoder->private_->file == stdin) | if(decoder->private_->file == stdin) | ||||
| return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED; | return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED; | ||||
| else if(fseeko(decoder->private_->file, (off_t)absolute_byte_offset, SEEK_SET) < 0) | |||||
| else if(fseeko(decoder->private_->file, (FLAC__off_t)absolute_byte_offset, SEEK_SET) < 0) | |||||
| return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; | return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; | ||||
| else | else | ||||
| return FLAC__STREAM_DECODER_SEEK_STATUS_OK; | return FLAC__STREAM_DECODER_SEEK_STATUS_OK; | ||||
| } | } | ||||
| FLAC__StreamDecoderTellStatus file_tell_callback_dec(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) | |||||
| FLAC__StreamDecoderTellStatus file_tell_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) | |||||
| { | { | ||||
| off_t pos; | |||||
| FLAC__off_t pos; | |||||
| (void)client_data; | (void)client_data; | ||||
| if(decoder->private_->file == stdin) | if(decoder->private_->file == stdin) | ||||
| @@ -3363,12 +3349,12 @@ FLAC__StreamDecoderTellStatus file_tell_callback_dec(const FLAC__StreamDecoder * | |||||
| FLAC__StreamDecoderLengthStatus file_length_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) | FLAC__StreamDecoderLengthStatus file_length_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) | ||||
| { | { | ||||
| struct stat filestats; | |||||
| struct flac_stat_s filestats; | |||||
| (void)client_data; | (void)client_data; | ||||
| if(decoder->private_->file == stdin) | if(decoder->private_->file == stdin) | ||||
| return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED; | return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED; | ||||
| else if(fstat(fileno(decoder->private_->file), &filestats) != 0) | |||||
| else if(flac_fstat(fileno(decoder->private_->file), &filestats) != 0) | |||||
| return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR; | return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR; | ||||
| else { | else { | ||||
| *stream_length = (FLAC__uint64)filestats.st_size; | *stream_length = (FLAC__uint64)filestats.st_size; | ||||
| @@ -3382,3 +3368,5 @@ FLAC__bool file_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_d | |||||
| return feof(decoder->private_->file)? true : false; | return feof(decoder->private_->file)? true : false; | ||||
| } | } | ||||
| #endif | |||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -33,25 +34,12 @@ | |||||
| # include <config.h> | # include <config.h> | ||||
| #endif | #endif | ||||
| #if defined _MSC_VER || defined __MINGW32__ | |||||
| #include <io.h> /* for _setmode() */ | |||||
| #include <fcntl.h> /* for _O_BINARY */ | |||||
| #endif | |||||
| #if defined __CYGWIN__ || defined __EMX__ | |||||
| #include <io.h> /* for setmode(), O_BINARY */ | |||||
| #include <fcntl.h> /* for _O_BINARY */ | |||||
| #endif | |||||
| #include <limits.h> | #include <limits.h> | ||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #include <stdlib.h> /* for malloc() */ | #include <stdlib.h> /* for malloc() */ | ||||
| #include <string.h> /* for memcpy() */ | #include <string.h> /* for memcpy() */ | ||||
| #include <sys/types.h> /* for off_t */ | #include <sys/types.h> /* for off_t */ | ||||
| #if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ | |||||
| #define fseeko fseek | |||||
| #define ftello ftell | |||||
| #endif | |||||
| #include "../assert.h" | #include "../assert.h" | ||||
| #include "../alloc.h" | |||||
| #include "../stream_decoder.h" | #include "../stream_decoder.h" | ||||
| #include "include/protected/stream_encoder.h" | #include "include/protected/stream_encoder.h" | ||||
| #include "include/private/bitwriter.h" | #include "include/private/bitwriter.h" | ||||
| @@ -69,20 +57,9 @@ | |||||
| #endif | #endif | ||||
| #include "include/private/stream_encoder_framing.h" | #include "include/private/stream_encoder_framing.h" | ||||
| #include "include/private/window.h" | #include "include/private/window.h" | ||||
| #include "../alloc.h" | |||||
| #include "../compat.h" | |||||
| #ifndef FLaC__INLINE | |||||
| #define FLaC__INLINE | |||||
| #endif | |||||
| #ifdef min | |||||
| #undef min | |||||
| #endif | |||||
| #define min(x,y) ((x)<(y)?(x):(y)) | |||||
| #ifdef max | |||||
| #undef max | |||||
| #endif | |||||
| #define max(x,y) ((x)>(y)?(x):(y)) | |||||
| /* Exact Rice codeword length calculation is off by default. The simple | /* Exact Rice codeword length calculation is off by default. The simple | ||||
| * (and fast) estimation (of how many bits a residual value will be | * (and fast) estimation (of how many bits a residual value will be | ||||
| @@ -145,7 +122,7 @@ static struct CompressionLevels { | |||||
| * | * | ||||
| ***********************************************************************/ | ***********************************************************************/ | ||||
| static void set_defaults_enc(FLAC__StreamEncoder *encoder); | |||||
| static void set_defaults_(FLAC__StreamEncoder *encoder); | |||||
| static void free_(FLAC__StreamEncoder *encoder); | static void free_(FLAC__StreamEncoder *encoder); | ||||
| static FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_blocksize); | static FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_blocksize); | ||||
| static FLAC__bool write_bitbuffer_(FLAC__StreamEncoder *encoder, unsigned samples, FLAC__bool is_last_block); | static FLAC__bool write_bitbuffer_(FLAC__StreamEncoder *encoder, unsigned samples, FLAC__bool is_last_block); | ||||
| @@ -314,11 +291,11 @@ static FLAC__StreamDecoderWriteStatus verify_write_callback_(const FLAC__StreamD | |||||
| static void verify_metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); | static void verify_metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); | ||||
| static void verify_error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); | static void verify_error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); | ||||
| static FLAC__StreamEncoderReadStatus file_read_callback_enc(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data); | |||||
| static FLAC__StreamEncoderSeekStatus file_seek_callback_enc(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data); | |||||
| static FLAC__StreamEncoderTellStatus file_tell_callback_enc(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data); | |||||
| static FLAC__StreamEncoderWriteStatus file_write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data); | |||||
| static FILE *get_binary_stdout_(void); | |||||
| //static FLAC__StreamEncoderReadStatus file_read_callback_(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data); | |||||
| //static FLAC__StreamEncoderSeekStatus file_seek_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data); | |||||
| //static FLAC__StreamEncoderTellStatus file_tell_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data); | |||||
| //static FLAC__StreamEncoderWriteStatus file_write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data); | |||||
| //static FILE *get_binary_stdout_(void); | |||||
| /*********************************************************************** | /*********************************************************************** | ||||
| @@ -475,7 +452,7 @@ FLAC_API const char * const FLAC__StreamEncoderInitStatusString[] = { | |||||
| "FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED" | "FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED" | ||||
| }; | }; | ||||
| FLAC_API const char * const FLAC__treamEncoderReadStatusString[] = { | |||||
| FLAC_API const char * const FLAC__StreamEncoderReadStatusString[] = { | |||||
| "FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE", | "FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE", | ||||
| "FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM", | "FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM", | ||||
| "FLAC__STREAM_ENCODER_READ_STATUS_ABORT", | "FLAC__STREAM_ENCODER_READ_STATUS_ABORT", | ||||
| @@ -524,18 +501,18 @@ FLAC_API FLAC__StreamEncoder *FLAC__stream_encoder_new(void) | |||||
| FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ | FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ | ||||
| encoder = (FLAC__StreamEncoder*)calloc(1, sizeof(FLAC__StreamEncoder)); | |||||
| encoder = (FLAC__StreamEncoder*) calloc(1, sizeof(FLAC__StreamEncoder)); | |||||
| if(encoder == 0) { | if(encoder == 0) { | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| encoder->protected_ = (FLAC__StreamEncoderProtected*)calloc(1, sizeof(FLAC__StreamEncoderProtected)); | |||||
| encoder->protected_ = (FLAC__StreamEncoderProtected*) calloc(1, sizeof(FLAC__StreamEncoderProtected)); | |||||
| if(encoder->protected_ == 0) { | if(encoder->protected_ == 0) { | ||||
| free(encoder); | free(encoder); | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| encoder->private_ = (FLAC__StreamEncoderPrivate*)calloc(1, sizeof(FLAC__StreamEncoderPrivate)); | |||||
| encoder->private_ = (FLAC__StreamEncoderPrivate*) calloc(1, sizeof(FLAC__StreamEncoderPrivate)); | |||||
| if(encoder->private_ == 0) { | if(encoder->private_ == 0) { | ||||
| free(encoder->protected_); | free(encoder->protected_); | ||||
| free(encoder); | free(encoder); | ||||
| @@ -552,7 +529,7 @@ FLAC_API FLAC__StreamEncoder *FLAC__stream_encoder_new(void) | |||||
| encoder->private_->file = 0; | encoder->private_->file = 0; | ||||
| set_defaults_enc(encoder); | |||||
| set_defaults_(encoder); | |||||
| encoder->private_->is_being_deleted = false; | encoder->private_->is_being_deleted = false; | ||||
| @@ -593,7 +570,9 @@ FLAC_API void FLAC__stream_encoder_delete(FLAC__StreamEncoder *encoder) | |||||
| { | { | ||||
| unsigned i; | unsigned i; | ||||
| FLAC__ASSERT(0 != encoder); | |||||
| if (encoder == NULL) | |||||
| return ; | |||||
| FLAC__ASSERT(0 != encoder->protected_); | FLAC__ASSERT(0 != encoder->protected_); | ||||
| FLAC__ASSERT(0 != encoder->private_); | FLAC__ASSERT(0 != encoder->private_); | ||||
| FLAC__ASSERT(0 != encoder->private_->frame); | FLAC__ASSERT(0 != encoder->private_->frame); | ||||
| @@ -628,7 +607,7 @@ FLAC_API void FLAC__stream_encoder_delete(FLAC__StreamEncoder *encoder) | |||||
| * | * | ||||
| ***********************************************************************/ | ***********************************************************************/ | ||||
| static FLAC__StreamEncoderInitStatus init_stream_internal_enc( | |||||
| static FLAC__StreamEncoderInitStatus init_stream_internal_( | |||||
| FLAC__StreamEncoder *encoder, | FLAC__StreamEncoder *encoder, | ||||
| FLAC__StreamEncoderReadCallback read_callback, | FLAC__StreamEncoderReadCallback read_callback, | ||||
| FLAC__StreamEncoderWriteCallback write_callback, | FLAC__StreamEncoderWriteCallback write_callback, | ||||
| @@ -694,7 +673,7 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_enc( | |||||
| if(encoder->protected_->bits_per_sample < 16) { | if(encoder->protected_->bits_per_sample < 16) { | ||||
| /* @@@ need some data about how to set this here w.r.t. blocksize and sample rate */ | /* @@@ need some data about how to set this here w.r.t. blocksize and sample rate */ | ||||
| /* @@@ until then we'll make a guess */ | /* @@@ until then we'll make a guess */ | ||||
| encoder->protected_->qlp_coeff_precision = max(FLAC__MIN_QLP_COEFF_PRECISION, 2 + encoder->protected_->bits_per_sample / 2); | |||||
| encoder->protected_->qlp_coeff_precision = flac_max(FLAC__MIN_QLP_COEFF_PRECISION, 2 + encoder->protected_->bits_per_sample / 2); | |||||
| } | } | ||||
| else if(encoder->protected_->bits_per_sample == 16) { | else if(encoder->protected_->bits_per_sample == 16) { | ||||
| if(encoder->protected_->blocksize <= 192) | if(encoder->protected_->blocksize <= 192) | ||||
| @@ -726,20 +705,7 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_enc( | |||||
| return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_QLP_COEFF_PRECISION; | return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_QLP_COEFF_PRECISION; | ||||
| if(encoder->protected_->streamable_subset) { | if(encoder->protected_->streamable_subset) { | ||||
| if( | |||||
| encoder->protected_->blocksize != 192 && | |||||
| encoder->protected_->blocksize != 576 && | |||||
| encoder->protected_->blocksize != 1152 && | |||||
| encoder->protected_->blocksize != 2304 && | |||||
| encoder->protected_->blocksize != 4608 && | |||||
| encoder->protected_->blocksize != 256 && | |||||
| encoder->protected_->blocksize != 512 && | |||||
| encoder->protected_->blocksize != 1024 && | |||||
| encoder->protected_->blocksize != 2048 && | |||||
| encoder->protected_->blocksize != 4096 && | |||||
| encoder->protected_->blocksize != 8192 && | |||||
| encoder->protected_->blocksize != 16384 | |||||
| ) | |||||
| if(!FLAC__format_blocksize_is_subset(encoder->protected_->blocksize, encoder->protected_->sample_rate)) | |||||
| return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE; | return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE; | ||||
| if(!FLAC__format_sample_rate_is_subset(encoder->protected_->sample_rate)) | if(!FLAC__format_sample_rate_is_subset(encoder->protected_->sample_rate)) | ||||
| return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE; | return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE; | ||||
| @@ -772,12 +738,12 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_enc( | |||||
| #if FLAC__HAS_OGG | #if FLAC__HAS_OGG | ||||
| /* reorder metadata if necessary to ensure that any VORBIS_COMMENT is the first, according to the mapping spec */ | /* reorder metadata if necessary to ensure that any VORBIS_COMMENT is the first, according to the mapping spec */ | ||||
| if(is_ogg && 0 != encoder->protected_->metadata && encoder->protected_->num_metadata_blocks > 1) { | if(is_ogg && 0 != encoder->protected_->metadata && encoder->protected_->num_metadata_blocks > 1) { | ||||
| unsigned i; | |||||
| for(i = 1; i < encoder->protected_->num_metadata_blocks; i++) { | |||||
| if(0 != encoder->protected_->metadata[i] && encoder->protected_->metadata[i]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { | |||||
| FLAC__StreamMetadata *vc = encoder->protected_->metadata[i]; | |||||
| for( ; i > 0; i--) | |||||
| encoder->protected_->metadata[i] = encoder->protected_->metadata[i-1]; | |||||
| unsigned i1; | |||||
| for(i1 = 1; i1 < encoder->protected_->num_metadata_blocks; i1++) { | |||||
| if(0 != encoder->protected_->metadata[i1] && encoder->protected_->metadata[i1]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { | |||||
| FLAC__StreamMetadata *vc = encoder->protected_->metadata[i1]; | |||||
| for( ; i1 > 0; i1--) | |||||
| encoder->protected_->metadata[i1] = encoder->protected_->metadata[i1-1]; | |||||
| encoder->protected_->metadata[0] = vc; | encoder->protected_->metadata[0] = vc; | ||||
| break; | break; | ||||
| } | } | ||||
| @@ -786,10 +752,10 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_enc( | |||||
| #endif | #endif | ||||
| /* keep track of any SEEKTABLE block */ | /* keep track of any SEEKTABLE block */ | ||||
| if(0 != encoder->protected_->metadata && encoder->protected_->num_metadata_blocks > 0) { | if(0 != encoder->protected_->metadata && encoder->protected_->num_metadata_blocks > 0) { | ||||
| unsigned i; | |||||
| for(i = 0; i < encoder->protected_->num_metadata_blocks; i++) { | |||||
| if(0 != encoder->protected_->metadata[i] && encoder->protected_->metadata[i]->type == FLAC__METADATA_TYPE_SEEKTABLE) { | |||||
| encoder->private_->seek_table = &encoder->protected_->metadata[i]->data.seek_table; | |||||
| unsigned i2; | |||||
| for(i2 = 0; i2 < encoder->protected_->num_metadata_blocks; i2++) { | |||||
| if(0 != encoder->protected_->metadata[i2] && encoder->protected_->metadata[i2]->type == FLAC__METADATA_TYPE_SEEKTABLE) { | |||||
| encoder->private_->seek_table = &encoder->protected_->metadata[i2]->data.seek_table; | |||||
| break; /* take only the first one */ | break; /* take only the first one */ | ||||
| } | } | ||||
| } | } | ||||
| @@ -896,7 +862,7 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_enc( | |||||
| encoder->private_->current_frame_number = 0; | encoder->private_->current_frame_number = 0; | ||||
| encoder->private_->use_wide_by_block = (encoder->protected_->bits_per_sample + FLAC__bitmath_ilog2(encoder->protected_->blocksize)+1 > 30); | encoder->private_->use_wide_by_block = (encoder->protected_->bits_per_sample + FLAC__bitmath_ilog2(encoder->protected_->blocksize)+1 > 30); | ||||
| encoder->private_->use_wide_by_order = (encoder->protected_->bits_per_sample + FLAC__bitmath_ilog2(max(encoder->protected_->max_lpc_order, FLAC__MAX_FIXED_ORDER))+1 > 30); /*@@@ need to use this? */ | |||||
| encoder->private_->use_wide_by_order = (encoder->protected_->bits_per_sample + FLAC__bitmath_ilog2(flac_max(encoder->protected_->max_lpc_order, FLAC__MAX_FIXED_ORDER))+1 > 30); /*@@@ need to use this? */ | |||||
| encoder->private_->use_wide_by_partition = (false); /*@@@ need to set this */ | encoder->private_->use_wide_by_partition = (false); /*@@@ need to set this */ | ||||
| /* | /* | ||||
| @@ -992,7 +958,7 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_enc( | |||||
| */ | */ | ||||
| encoder->private_->verify.input_fifo.size = encoder->protected_->blocksize+OVERREAD_; | encoder->private_->verify.input_fifo.size = encoder->protected_->blocksize+OVERREAD_; | ||||
| for(i = 0; i < encoder->protected_->channels; i++) { | for(i = 0; i < encoder->protected_->channels; i++) { | ||||
| 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))) { | |||||
| if(0 == (encoder->private_->verify.input_fifo.data[i] = (FLAC__int32*) safe_malloc_mul_2op_p(sizeof(FLAC__int32), /*times*/encoder->private_->verify.input_fifo.size))) { | |||||
| encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; | ||||
| return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; | ||||
| } | } | ||||
| @@ -1002,10 +968,12 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_enc( | |||||
| /* | /* | ||||
| * Now set up a stream decoder for verification | * Now set up a stream decoder for verification | ||||
| */ | */ | ||||
| encoder->private_->verify.decoder = FLAC__stream_decoder_new(); | |||||
| if(0 == encoder->private_->verify.decoder) { | if(0 == encoder->private_->verify.decoder) { | ||||
| encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR; | |||||
| return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; | |||||
| encoder->private_->verify.decoder = FLAC__stream_decoder_new(); | |||||
| if(0 == encoder->private_->verify.decoder) { | |||||
| encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR; | |||||
| return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; | |||||
| } | |||||
| } | } | ||||
| if(FLAC__stream_decoder_init_stream(encoder->private_->verify.decoder, verify_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, verify_write_callback_, verify_metadata_callback_, verify_error_callback_, /*client_data=*/encoder) != FLAC__STREAM_DECODER_INIT_STATUS_OK) { | if(FLAC__stream_decoder_init_stream(encoder->private_->verify.decoder, verify_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, verify_write_callback_, verify_metadata_callback_, verify_error_callback_, /*client_data=*/encoder) != FLAC__STREAM_DECODER_INIT_STATUS_OK) { | ||||
| @@ -1145,7 +1113,7 @@ FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_stream( | |||||
| void *client_data | void *client_data | ||||
| ) | ) | ||||
| { | { | ||||
| return init_stream_internal_enc( | |||||
| return init_stream_internal_( | |||||
| encoder, | encoder, | ||||
| /*read_callback=*/0, | /*read_callback=*/0, | ||||
| write_callback, | write_callback, | ||||
| @@ -1167,7 +1135,7 @@ FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_stream( | |||||
| void *client_data | void *client_data | ||||
| ) | ) | ||||
| { | { | ||||
| return init_stream_internal_enc( | |||||
| return init_stream_internal_( | |||||
| encoder, | encoder, | ||||
| read_callback, | read_callback, | ||||
| write_callback, | write_callback, | ||||
| @@ -1179,11 +1147,12 @@ FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_stream( | |||||
| ); | ); | ||||
| } | } | ||||
| static FLAC__StreamEncoderInitStatus init_FILE_internal_enc( | |||||
| #if 0 | |||||
| static FLAC__StreamEncoderInitStatus init_FILE_internal_( | |||||
| FLAC__StreamEncoder *encoder, | FLAC__StreamEncoder *encoder, | ||||
| FILE *file, | FILE *file, | ||||
| FLAC__StreamEncoderProgressCallback progress_callback, | FLAC__StreamEncoderProgressCallback progress_callback, | ||||
| void *client_data, | |||||
| void * /*client_data*/, | |||||
| FLAC__bool is_ogg | FLAC__bool is_ogg | ||||
| ) | ) | ||||
| { | { | ||||
| @@ -1216,12 +1185,12 @@ static FLAC__StreamEncoderInitStatus init_FILE_internal_enc( | |||||
| encoder->private_->samples_written = 0; | encoder->private_->samples_written = 0; | ||||
| encoder->private_->frames_written = 0; | encoder->private_->frames_written = 0; | ||||
| init_status = init_stream_internal_enc( | |||||
| init_status = init_stream_internal_( | |||||
| encoder, | encoder, | ||||
| encoder->private_->file == stdout? 0 : is_ogg? file_read_callback_enc : 0, | |||||
| encoder->private_->file == stdout? 0 : is_ogg? file_read_callback_ : 0, | |||||
| file_write_callback_, | file_write_callback_, | ||||
| encoder->private_->file == stdout? 0 : file_seek_callback_enc, | |||||
| encoder->private_->file == stdout? 0 : file_tell_callback_enc, | |||||
| encoder->private_->file == stdout? 0 : file_seek_callback_, | |||||
| encoder->private_->file == stdout? 0 : file_tell_callback_, | |||||
| /*metadata_callback=*/0, | /*metadata_callback=*/0, | ||||
| client_data, | client_data, | ||||
| is_ogg | is_ogg | ||||
| @@ -1248,7 +1217,7 @@ FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_FILE( | |||||
| void *client_data | void *client_data | ||||
| ) | ) | ||||
| { | { | ||||
| return init_FILE_internal_enc(encoder, file, progress_callback, client_data, /*is_ogg=*/false); | |||||
| return init_FILE_internal_(encoder, file, progress_callback, client_data, /*is_ogg=*/false); | |||||
| } | } | ||||
| FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_FILE( | FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_FILE( | ||||
| @@ -1258,10 +1227,10 @@ FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_FILE( | |||||
| void *client_data | void *client_data | ||||
| ) | ) | ||||
| { | { | ||||
| return init_FILE_internal_enc(encoder, file, progress_callback, client_data, /*is_ogg=*/true); | |||||
| return init_FILE_internal_(encoder, file, progress_callback, client_data, /*is_ogg=*/true); | |||||
| } | } | ||||
| static FLAC__StreamEncoderInitStatus init_file_internal_enc( | |||||
| static FLAC__StreamEncoderInitStatus init_file_internal_( | |||||
| FLAC__StreamEncoder *encoder, | FLAC__StreamEncoder *encoder, | ||||
| const char *filename, | const char *filename, | ||||
| FLAC__StreamEncoderProgressCallback progress_callback, | FLAC__StreamEncoderProgressCallback progress_callback, | ||||
| @@ -1281,14 +1250,14 @@ static FLAC__StreamEncoderInitStatus init_file_internal_enc( | |||||
| if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||||
| return FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED; | return FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED; | ||||
| file = filename? fopen(filename, "w+b") : stdout; | |||||
| file = filename? flac_fopen(filename, "w+b") : stdout; | |||||
| if(file == 0) { | if(file == 0) { | ||||
| encoder->protected_->state = FLAC__STREAM_ENCODER_IO_ERROR; | encoder->protected_->state = FLAC__STREAM_ENCODER_IO_ERROR; | ||||
| return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; | ||||
| } | } | ||||
| return init_FILE_internal_enc(encoder, file, progress_callback, client_data, is_ogg); | |||||
| return init_FILE_internal_(encoder, file, progress_callback, client_data, is_ogg); | |||||
| } | } | ||||
| FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_file( | FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_file( | ||||
| @@ -1298,7 +1267,7 @@ FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_file( | |||||
| void *client_data | void *client_data | ||||
| ) | ) | ||||
| { | { | ||||
| return init_file_internal_enc(encoder, filename, progress_callback, client_data, /*is_ogg=*/false); | |||||
| return init_file_internal_(encoder, filename, progress_callback, client_data, /*is_ogg=*/false); | |||||
| } | } | ||||
| FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_file( | FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_file( | ||||
| @@ -1308,8 +1277,9 @@ FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_file( | |||||
| void *client_data | void *client_data | ||||
| ) | ) | ||||
| { | { | ||||
| return init_file_internal_enc(encoder, filename, progress_callback, client_data, /*is_ogg=*/true); | |||||
| return init_file_internal_(encoder, filename, progress_callback, client_data, /*is_ogg=*/true); | |||||
| } | } | ||||
| #endif | |||||
| FLAC_API FLAC__bool FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder) | FLAC_API FLAC__bool FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder) | ||||
| { | { | ||||
| @@ -1371,7 +1341,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder) | |||||
| #endif | #endif | ||||
| free_(encoder); | free_(encoder); | ||||
| set_defaults_enc(encoder); | |||||
| set_defaults_(encoder); | |||||
| if(!error) | if(!error) | ||||
| encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED; | encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED; | ||||
| @@ -1420,7 +1390,6 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_streamable_subset(FLAC__StreamEncod | |||||
| return true; | return true; | ||||
| } | } | ||||
| FLAC_API FLAC__bool FLAC__stream_encoder_set_do_md5(FLAC__StreamEncoder *encoder, FLAC__bool value); | |||||
| FLAC_API FLAC__bool FLAC__stream_encoder_set_do_md5(FLAC__StreamEncoder *encoder, FLAC__bool value) | FLAC_API FLAC__bool FLAC__stream_encoder_set_do_md5(FLAC__StreamEncoder *encoder, FLAC__bool value) | ||||
| { | { | ||||
| FLAC__ASSERT(0 != encoder); | FLAC__ASSERT(0 != encoder); | ||||
| @@ -1732,7 +1701,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_metadata(FLAC__StreamEncoder *encod | |||||
| } | } | ||||
| if(num_blocks) { | if(num_blocks) { | ||||
| FLAC__StreamMetadata **m; | FLAC__StreamMetadata **m; | ||||
| if(0 == (m = (FLAC__StreamMetadata**)safe_malloc_mul_2op_(sizeof(m[0]), /*times*/num_blocks))) | |||||
| if(0 == (m = (FLAC__StreamMetadata**) safe_malloc_mul_2op_p(sizeof(m[0]), /*times*/num_blocks))) | |||||
| return false; | return false; | ||||
| memcpy(m, metadata, sizeof(m[0]) * num_blocks); | memcpy(m, metadata, sizeof(m[0]) * num_blocks); | ||||
| encoder->protected_->metadata = m; | encoder->protected_->metadata = m; | ||||
| @@ -1749,7 +1718,6 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_metadata(FLAC__StreamEncoder *encod | |||||
| * These three functions are not static, but not publically exposed in | * These three functions are not static, but not publically exposed in | ||||
| * include/FLAC/ either. They are used by the test suite. | * include/FLAC/ either. They are used by the test suite. | ||||
| */ | */ | ||||
| FLAC_API FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value); | |||||
| FLAC_API FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value) | FLAC_API FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value) | ||||
| { | { | ||||
| FLAC__ASSERT(0 != encoder); | FLAC__ASSERT(0 != encoder); | ||||
| @@ -1761,7 +1729,6 @@ FLAC_API FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__Stream | |||||
| return true; | return true; | ||||
| } | } | ||||
| FLAC_API FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value); | |||||
| FLAC_API FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value) | FLAC_API FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value) | ||||
| { | { | ||||
| FLAC__ASSERT(0 != encoder); | FLAC__ASSERT(0 != encoder); | ||||
| @@ -1773,7 +1740,6 @@ FLAC_API FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEnc | |||||
| return true; | return true; | ||||
| } | } | ||||
| FLAC_API FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value); | |||||
| FLAC_API FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value) | FLAC_API FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value) | ||||
| { | { | ||||
| FLAC__ASSERT(0 != encoder); | FLAC__ASSERT(0 != encoder); | ||||
| @@ -1850,7 +1816,6 @@ FLAC_API FLAC__bool FLAC__stream_encoder_get_streamable_subset(const FLAC__Strea | |||||
| return encoder->protected_->streamable_subset; | return encoder->protected_->streamable_subset; | ||||
| } | } | ||||
| FLAC_API FLAC__bool FLAC__stream_encoder_get_do_md5(const FLAC__StreamEncoder *encoder); | |||||
| FLAC_API FLAC__bool FLAC__stream_encoder_get_do_md5(const FLAC__StreamEncoder *encoder) | FLAC_API FLAC__bool FLAC__stream_encoder_get_do_md5(const FLAC__StreamEncoder *encoder) | ||||
| { | { | ||||
| FLAC__ASSERT(0 != encoder); | FLAC__ASSERT(0 != encoder); | ||||
| @@ -1990,7 +1955,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, c | |||||
| FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK); | FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK); | ||||
| do { | do { | ||||
| const unsigned n = min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j); | |||||
| const unsigned n = flac_min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j); | |||||
| if(encoder->protected_->verify) | if(encoder->protected_->verify) | ||||
| append_to_verify_fifo_(&encoder->private_->verify.input_fifo, buffer, j, channels, n); | append_to_verify_fifo_(&encoder->private_->verify.input_fifo, buffer, j, channels, n); | ||||
| @@ -2053,7 +2018,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder | |||||
| */ | */ | ||||
| do { | do { | ||||
| if(encoder->protected_->verify) | if(encoder->protected_->verify) | ||||
| append_to_verify_fifo_interleaved_(&encoder->private_->verify.input_fifo, buffer, j, channels, min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j)); | |||||
| append_to_verify_fifo_interleaved_(&encoder->private_->verify.input_fifo, buffer, j, channels, flac_min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j)); | |||||
| /* "i <= blocksize" to overread 1 sample; see comment in OVERREAD_ decl */ | /* "i <= blocksize" to overread 1 sample; see comment in OVERREAD_ decl */ | ||||
| for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) { | for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) { | ||||
| @@ -2088,7 +2053,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder | |||||
| */ | */ | ||||
| do { | do { | ||||
| if(encoder->protected_->verify) | if(encoder->protected_->verify) | ||||
| append_to_verify_fifo_interleaved_(&encoder->private_->verify.input_fifo, buffer, j, channels, min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j)); | |||||
| append_to_verify_fifo_interleaved_(&encoder->private_->verify.input_fifo, buffer, j, channels, flac_min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j)); | |||||
| /* "i <= blocksize" to overread 1 sample; see comment in OVERREAD_ decl */ | /* "i <= blocksize" to overread 1 sample; see comment in OVERREAD_ decl */ | ||||
| for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) { | for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) { | ||||
| @@ -2119,7 +2084,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder | |||||
| * | * | ||||
| ***********************************************************************/ | ***********************************************************************/ | ||||
| void set_defaults_enc(FLAC__StreamEncoder *encoder) | |||||
| void set_defaults_(FLAC__StreamEncoder *encoder) | |||||
| { | { | ||||
| FLAC__ASSERT(0 != encoder); | FLAC__ASSERT(0 != encoder); | ||||
| @@ -2171,6 +2136,8 @@ void set_defaults_enc(FLAC__StreamEncoder *encoder) | |||||
| #if FLAC__HAS_OGG | #if FLAC__HAS_OGG | ||||
| FLAC__ogg_encoder_aspect_set_defaults(&encoder->protected_->ogg_encoder_aspect); | FLAC__ogg_encoder_aspect_set_defaults(&encoder->protected_->ogg_encoder_aspect); | ||||
| #endif | #endif | ||||
| FLAC__stream_encoder_set_compression_level(encoder, 5); | |||||
| } | } | ||||
| void free_(FLAC__StreamEncoder *encoder) | void free_(FLAC__StreamEncoder *encoder) | ||||
| @@ -2428,18 +2395,22 @@ FLAC__bool write_bitbuffer_(FLAC__StreamEncoder *encoder, unsigned samples, FLAC | |||||
| FLAC__bitwriter_clear(encoder->private_->frame); | FLAC__bitwriter_clear(encoder->private_->frame); | ||||
| if(samples > 0) { | if(samples > 0) { | ||||
| encoder->private_->streaminfo.data.stream_info.min_framesize = min(bytes, encoder->private_->streaminfo.data.stream_info.min_framesize); | |||||
| encoder->private_->streaminfo.data.stream_info.max_framesize = max(bytes, encoder->private_->streaminfo.data.stream_info.max_framesize); | |||||
| encoder->private_->streaminfo.data.stream_info.min_framesize = flac_min(bytes, (size_t) encoder->private_->streaminfo.data.stream_info.min_framesize); | |||||
| encoder->private_->streaminfo.data.stream_info.max_framesize = flac_max(bytes, (size_t) encoder->private_->streaminfo.data.stream_info.max_framesize); | |||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| FLAC__StreamEncoderWriteStatus write_frame_(FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, FLAC__bool /* is_last_block */) | |||||
| FLAC__StreamEncoderWriteStatus write_frame_(FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, FLAC__bool is_last_block) | |||||
| { | { | ||||
| FLAC__StreamEncoderWriteStatus status; | FLAC__StreamEncoderWriteStatus status; | ||||
| FLAC__uint64 output_position = 0; | FLAC__uint64 output_position = 0; | ||||
| #if FLAC__HAS_OGG == 0 | |||||
| (void)is_last_block; | |||||
| #endif | |||||
| /* FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED just means we didn't get the offset; no error */ | /* FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED just means we didn't get the offset; no error */ | ||||
| if(encoder->private_->tell_callback && encoder->private_->tell_callback(encoder, &output_position, encoder->private_->client_data) == FLAC__STREAM_ENCODER_TELL_STATUS_ERROR) { | if(encoder->private_->tell_callback && encoder->private_->tell_callback(encoder, &output_position, encoder->private_->client_data) == FLAC__STREAM_ENCODER_TELL_STATUS_ERROR) { | ||||
| encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; | encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; | ||||
| @@ -2516,7 +2487,7 @@ FLAC__StreamEncoderWriteStatus write_frame_(FLAC__StreamEncoder *encoder, const | |||||
| * when the encoder goes back to write metadata, 'current_frame' | * when the encoder goes back to write metadata, 'current_frame' | ||||
| * will drop back to 0. | * will drop back to 0. | ||||
| */ | */ | ||||
| encoder->private_->frames_written = max(encoder->private_->frames_written, encoder->private_->current_frame_number+1); | |||||
| encoder->private_->frames_written = flac_max(encoder->private_->frames_written, encoder->private_->current_frame_number+1); | |||||
| } | } | ||||
| else | else | ||||
| encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; | encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; | ||||
| @@ -2527,7 +2498,7 @@ FLAC__StreamEncoderWriteStatus write_frame_(FLAC__StreamEncoder *encoder, const | |||||
| /* Gets called when the encoding process has finished so that we can update the STREAMINFO and SEEKTABLE blocks. */ | /* Gets called when the encoding process has finished so that we can update the STREAMINFO and SEEKTABLE blocks. */ | ||||
| void update_metadata_(const FLAC__StreamEncoder *encoder) | void update_metadata_(const FLAC__StreamEncoder *encoder) | ||||
| { | { | ||||
| FLAC__byte b[max(6, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)]; | |||||
| FLAC__byte b[FLAC__STREAM_METADATA_SEEKPOINT_LENGTH]; | |||||
| const FLAC__StreamMetadata *metadata = &encoder->private_->streaminfo; | const FLAC__StreamMetadata *metadata = &encoder->private_->streaminfo; | ||||
| const FLAC__uint64 samples = metadata->data.stream_info.total_samples; | const FLAC__uint64 samples = metadata->data.stream_info.total_samples; | ||||
| const unsigned min_framesize = metadata->data.stream_info.min_framesize; | const unsigned min_framesize = metadata->data.stream_info.min_framesize; | ||||
| @@ -2692,7 +2663,7 @@ void update_ogg_metadata_(FLAC__StreamEncoder *encoder) | |||||
| FLAC__OGG_MAPPING_NUM_HEADERS_LENGTH + | FLAC__OGG_MAPPING_NUM_HEADERS_LENGTH + | ||||
| FLAC__STREAM_SYNC_LENGTH | FLAC__STREAM_SYNC_LENGTH | ||||
| ; | ; | ||||
| FLAC__byte b[max(6, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)]; | |||||
| FLAC__byte b[flac_max(6u, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)]; | |||||
| const FLAC__StreamMetadata *metadata = &encoder->private_->streaminfo; | const FLAC__StreamMetadata *metadata = &encoder->private_->streaminfo; | ||||
| const FLAC__uint64 samples = metadata->data.stream_info.total_samples; | const FLAC__uint64 samples = metadata->data.stream_info.total_samples; | ||||
| const unsigned min_framesize = metadata->data.stream_info.min_framesize; | const unsigned min_framesize = metadata->data.stream_info.min_framesize; | ||||
| @@ -2943,9 +2914,9 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_fracti | |||||
| } | } | ||||
| else { | else { | ||||
| max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize(encoder->protected_->blocksize); | max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize(encoder->protected_->blocksize); | ||||
| max_partition_order = min(max_partition_order, encoder->protected_->max_residual_partition_order); | |||||
| max_partition_order = flac_min(max_partition_order, encoder->protected_->max_residual_partition_order); | |||||
| } | } | ||||
| min_partition_order = min(min_partition_order, max_partition_order); | |||||
| min_partition_order = flac_min(min_partition_order, max_partition_order); | |||||
| /* | /* | ||||
| * Setup the frame | * Setup the frame | ||||
| @@ -3349,8 +3320,8 @@ FLAC__bool process_subframe_( | |||||
| min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION; | min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION; | ||||
| /* try to ensure a 32-bit datapath throughout for 16bps(+1bps for side channel) or less */ | /* try to ensure a 32-bit datapath throughout for 16bps(+1bps for side channel) or less */ | ||||
| if(subframe_bps <= 17) { | if(subframe_bps <= 17) { | ||||
| max_qlp_coeff_precision = min(32 - subframe_bps - lpc_order, FLAC__MAX_QLP_COEFF_PRECISION); | |||||
| max_qlp_coeff_precision = max(max_qlp_coeff_precision, min_qlp_coeff_precision); | |||||
| max_qlp_coeff_precision = flac_min(32 - subframe_bps - lpc_order, FLAC__MAX_QLP_COEFF_PRECISION); | |||||
| max_qlp_coeff_precision = flac_max(max_qlp_coeff_precision, min_qlp_coeff_precision); | |||||
| } | } | ||||
| else | else | ||||
| max_qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION; | max_qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION; | ||||
| @@ -3594,7 +3565,7 @@ unsigned evaluate_lpc_subframe_( | |||||
| if(subframe_bps <= 16) { | if(subframe_bps <= 16) { | ||||
| FLAC__ASSERT(order > 0); | FLAC__ASSERT(order > 0); | ||||
| FLAC__ASSERT(order <= FLAC__MAX_LPC_ORDER); | FLAC__ASSERT(order <= FLAC__MAX_LPC_ORDER); | ||||
| qlp_coeff_precision = min(qlp_coeff_precision, 32 - subframe_bps - FLAC__bitmath_ilog2(order)); | |||||
| qlp_coeff_precision = flac_min(qlp_coeff_precision, 32 - subframe_bps - FLAC__bitmath_ilog2(order)); | |||||
| } | } | ||||
| ret = FLAC__lpc_quantize_coefficients(lp_coeff, order, qlp_coeff_precision, qlp_coeff, &quantization); | ret = FLAC__lpc_quantize_coefficients(lp_coeff, order, qlp_coeff_precision, qlp_coeff, &quantization); | ||||
| @@ -3698,7 +3669,7 @@ unsigned find_best_partition_order_( | |||||
| const unsigned blocksize = residual_samples + predictor_order; | 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); | max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(max_partition_order, blocksize, predictor_order); | ||||
| min_partition_order = min(min_partition_order, max_partition_order); | |||||
| min_partition_order = flac_min(min_partition_order, max_partition_order); | |||||
| precompute_partition_info_sums_(residual, abs_residual_partition_sums, residual_samples, predictor_order, min_partition_order, max_partition_order, bps); | precompute_partition_info_sums_(residual, abs_residual_partition_sums, residual_samples, predictor_order, min_partition_order, max_partition_order, bps); | ||||
| @@ -3752,7 +3723,7 @@ unsigned find_best_partition_order_( | |||||
| unsigned partition; | unsigned partition; | ||||
| /* save best parameters and raw_bits */ | /* save best parameters and raw_bits */ | ||||
| FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(prc, max(6, best_partition_order)); | |||||
| FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(prc, flac_max(6u, best_partition_order)); | |||||
| memcpy(prc->parameters, private_->partitioned_rice_contents_extra[best_parameters_index].parameters, sizeof(unsigned)*(1<<(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) | if(do_escape_coding) | ||||
| memcpy(prc->raw_bits, private_->partitioned_rice_contents_extra[best_parameters_index].raw_bits, sizeof(unsigned)*(1<<(best_partition_order))); | memcpy(prc->raw_bits, private_->partitioned_rice_contents_extra[best_parameters_index].raw_bits, sizeof(unsigned)*(1<<(best_partition_order))); | ||||
| @@ -3904,7 +3875,7 @@ void precompute_partition_info_escapes_( | |||||
| for(i = 0; i < partitions; i++) { | for(i = 0; i < partitions; i++) { | ||||
| m = raw_bits_per_partition[from_partition]; | m = raw_bits_per_partition[from_partition]; | ||||
| from_partition++; | from_partition++; | ||||
| raw_bits_per_partition[to_partition] = max(m, raw_bits_per_partition[from_partition]); | |||||
| raw_bits_per_partition[to_partition] = flac_max(m, raw_bits_per_partition[from_partition]); | |||||
| from_partition++; | from_partition++; | ||||
| to_partition++; | to_partition++; | ||||
| } | } | ||||
| @@ -3912,7 +3883,7 @@ void precompute_partition_info_escapes_( | |||||
| } | } | ||||
| #ifdef EXACT_RICE_BITS_CALCULATION | #ifdef EXACT_RICE_BITS_CALCULATION | ||||
| static FLaC__INLINE unsigned count_rice_bits_in_partition_( | |||||
| static inline unsigned count_rice_bits_in_partition_( | |||||
| const unsigned rice_parameter, | const unsigned rice_parameter, | ||||
| const unsigned partition_samples, | const unsigned partition_samples, | ||||
| const FLAC__int32 *residual | const FLAC__int32 *residual | ||||
| @@ -3927,7 +3898,7 @@ static FLaC__INLINE unsigned count_rice_bits_in_partition_( | |||||
| return partition_bits; | return partition_bits; | ||||
| } | } | ||||
| #else | #else | ||||
| static FLaC__INLINE unsigned count_rice_bits_in_partition_( | |||||
| static inline unsigned count_rice_bits_in_partition_( | |||||
| const unsigned rice_parameter, | const unsigned rice_parameter, | ||||
| const unsigned partition_samples, | const unsigned partition_samples, | ||||
| const FLAC__uint64 abs_residual_partition_sum | const FLAC__uint64 abs_residual_partition_sum | ||||
| @@ -3982,7 +3953,7 @@ FLAC__bool set_partitioned_rice_( | |||||
| FLAC__ASSERT(suggested_rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_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__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)); | |||||
| FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, flac_max(6u, partition_order)); | |||||
| parameters = partitioned_rice_contents->parameters; | parameters = partitioned_rice_contents->parameters; | ||||
| raw_bits = partitioned_rice_contents->raw_bits; | raw_bits = partitioned_rice_contents->raw_bits; | ||||
| @@ -4256,7 +4227,8 @@ void verify_error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDeco | |||||
| encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR; | encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR; | ||||
| } | } | ||||
| FLAC__StreamEncoderReadStatus file_read_callback_enc(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data) | |||||
| #if 0 | |||||
| FLAC__StreamEncoderReadStatus file_read_callback_(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data) | |||||
| { | { | ||||
| (void)client_data; | (void)client_data; | ||||
| @@ -4270,19 +4242,19 @@ FLAC__StreamEncoderReadStatus file_read_callback_enc(const FLAC__StreamEncoder * | |||||
| return FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE; | return FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE; | ||||
| } | } | ||||
| FLAC__StreamEncoderSeekStatus file_seek_callback_enc(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data) | |||||
| FLAC__StreamEncoderSeekStatus file_seek_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data) | |||||
| { | { | ||||
| (void)client_data; | (void)client_data; | ||||
| if(fseeko(encoder->private_->file, (off_t)absolute_byte_offset, SEEK_SET) < 0) | |||||
| if(fseeko(encoder->private_->file, (FLAC__off_t)absolute_byte_offset, SEEK_SET) < 0) | |||||
| return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR; | return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR; | ||||
| else | else | ||||
| return FLAC__STREAM_ENCODER_SEEK_STATUS_OK; | return FLAC__STREAM_ENCODER_SEEK_STATUS_OK; | ||||
| } | } | ||||
| FLAC__StreamEncoderTellStatus file_tell_callback_enc(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data) | |||||
| FLAC__StreamEncoderTellStatus file_tell_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data) | |||||
| { | { | ||||
| off_t offset; | |||||
| FLAC__off_t offset; | |||||
| (void)client_data; | (void)client_data; | ||||
| @@ -4360,3 +4332,5 @@ FILE *get_binary_stdout_(void) | |||||
| return stdout; | return stdout; | ||||
| } | } | ||||
| #endif | |||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -39,11 +40,6 @@ | |||||
| #include "include/private/crc.h" | #include "include/private/crc.h" | ||||
| #include "../assert.h" | #include "../assert.h" | ||||
| #ifdef max | |||||
| #undef max | |||||
| #endif | |||||
| #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_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, const FLAC__bool is_extended); | 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); | ||||
| @@ -166,11 +162,11 @@ FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__ | |||||
| if(!FLAC__bitwriter_write_raw_uint32(bw, track->num_indices, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN)) | if(!FLAC__bitwriter_write_raw_uint32(bw, track->num_indices, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN)) | ||||
| return false; | return false; | ||||
| for(j = 0; j < track->num_indices; j++) { | for(j = 0; j < track->num_indices; j++) { | ||||
| const FLAC__StreamMetadata_CueSheet_Index *index = track->indices + j; | |||||
| const FLAC__StreamMetadata_CueSheet_Index *indx = track->indices + j; | |||||
| if(!FLAC__bitwriter_write_raw_uint64(bw, index->offset, FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN)) | |||||
| if(!FLAC__bitwriter_write_raw_uint64(bw, indx->offset, FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN)) | |||||
| return false; | return false; | ||||
| if(!FLAC__bitwriter_write_raw_uint32(bw, index->number, FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN)) | |||||
| if(!FLAC__bitwriter_write_raw_uint32(bw, indx->number, FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN)) | |||||
| return false; | return false; | ||||
| if(!FLAC__bitwriter_write_zeroes(bw, FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN)) | if(!FLAC__bitwriter_write_zeroes(bw, FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN)) | ||||
| return false; | return false; | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2006,2007 Josh Coalson | |||||
| * Copyright (C) 2006-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2001-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -1986,7 +1987,7 @@ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_resize_tracks(FLAC__StreamMet | |||||
| * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode | * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode | ||||
| * \code track_num < object->data.cue_sheet.num_tracks \endcode | * \code track_num < object->data.cue_sheet.num_tracks \endcode | ||||
| * \code (track->indices != NULL && track->num_indices > 0) || | * \code (track->indices != NULL && track->num_indices > 0) || | ||||
| * (track->indices == NULL && track->num_indices == 0) | |||||
| * (track->indices == NULL && track->num_indices == 0) \endcode | |||||
| * \retval FLAC__bool | * \retval FLAC__bool | ||||
| * \c false if \a copy is \c true and malloc() fails, else \c true. | * \c false if \a copy is \c true and malloc() fails, else \c true. | ||||
| */ | */ | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -32,40 +33,45 @@ | |||||
| #ifndef FLAC__ORDINALS_H | #ifndef FLAC__ORDINALS_H | ||||
| #define FLAC__ORDINALS_H | #define FLAC__ORDINALS_H | ||||
| #if !(defined(_MSC_VER) || defined(__BORLANDC__) || defined(__EMX__)) | |||||
| #include <inttypes.h> | |||||
| #endif | |||||
| #if defined(_MSC_VER) && _MSC_VER < 1600 | |||||
| /* Microsoft Visual Studio earlier than the 2010 version did not provide | |||||
| * the 1999 ISO C Standard header file <stdint.h>. | |||||
| */ | |||||
| typedef signed char FLAC__int8; | |||||
| typedef unsigned char FLAC__uint8; | |||||
| typedef __int8 FLAC__int8; | |||||
| typedef unsigned __int8 FLAC__uint8; | |||||
| #if defined(_MSC_VER) || defined(__BORLANDC__) | |||||
| typedef __int16 FLAC__int16; | typedef __int16 FLAC__int16; | ||||
| typedef __int32 FLAC__int32; | typedef __int32 FLAC__int32; | ||||
| typedef __int64 FLAC__int64; | typedef __int64 FLAC__int64; | ||||
| typedef unsigned __int16 FLAC__uint16; | typedef unsigned __int16 FLAC__uint16; | ||||
| typedef unsigned __int32 FLAC__uint32; | typedef unsigned __int32 FLAC__uint32; | ||||
| typedef unsigned __int64 FLAC__uint64; | typedef unsigned __int64 FLAC__uint64; | ||||
| #elif defined(__EMX__) | |||||
| typedef short FLAC__int16; | |||||
| typedef long FLAC__int32; | |||||
| typedef long long FLAC__int64; | |||||
| typedef unsigned short FLAC__uint16; | |||||
| typedef unsigned long FLAC__uint32; | |||||
| typedef unsigned long long FLAC__uint64; | |||||
| #else | #else | ||||
| /* For MSVC 2010 and everything else which provides <stdint.h>. */ | |||||
| #include <stdint.h> | |||||
| typedef int8_t FLAC__int8; | |||||
| typedef uint8_t FLAC__uint8; | |||||
| typedef int16_t FLAC__int16; | typedef int16_t FLAC__int16; | ||||
| typedef int32_t FLAC__int32; | typedef int32_t FLAC__int32; | ||||
| typedef int64_t FLAC__int64; | typedef int64_t FLAC__int64; | ||||
| typedef uint16_t FLAC__uint16; | typedef uint16_t FLAC__uint16; | ||||
| typedef uint32_t FLAC__uint32; | typedef uint32_t FLAC__uint32; | ||||
| typedef uint64_t FLAC__uint64; | typedef uint64_t FLAC__uint64; | ||||
| #endif | #endif | ||||
| typedef int FLAC__bool; | typedef int FLAC__bool; | ||||
| typedef FLAC__uint8 FLAC__byte; | typedef FLAC__uint8 FLAC__byte; | ||||
| #ifdef true | #ifdef true | ||||
| #undef true | #undef true | ||||
| #endif | #endif | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -1,5 +1,6 @@ | |||||
| /* libFLAC - Free Lossless Audio Codec library | /* libFLAC - Free Lossless Audio Codec library | ||||
| * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson | |||||
| * Copyright (C) 2000-2009 Josh Coalson | |||||
| * Copyright (C) 2011-2013 Xiph.Org Foundation | |||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| @@ -128,7 +129,7 @@ extern "C" { | |||||
| * Unlike the decoders, the stream encoder has many options that can | * Unlike the decoders, the stream encoder has many options that can | ||||
| * affect the speed and compression ratio. When setting these parameters | * affect the speed and compression ratio. When setting these parameters | ||||
| * you should have some basic knowledge of the format (see the | * you should have some basic knowledge of the format (see the | ||||
| * <A HREF="../documentation.html#format">user-level documentation</A> | |||||
| * <A HREF="../documentation_format_overview.html">user-level documentation</A> | |||||
| * or the <A HREF="../format.html">formal description</A>). The | * or the <A HREF="../format.html">formal description</A>). The | ||||
| * FLAC__stream_encoder_set_*() functions themselves do not validate the | * FLAC__stream_encoder_set_*() functions themselves do not validate the | ||||
| * values as many are interdependent. The FLAC__stream_encoder_init_*() | * values as many are interdependent. The FLAC__stream_encoder_init_*() | ||||
| @@ -343,7 +343,7 @@ namespace AiffFileHelpers | |||||
| out.writeIntBigEndian (values.getValue (prefix + "TimeStamp", "0").getIntValue()); | out.writeIntBigEndian (values.getValue (prefix + "TimeStamp", "0").getIntValue()); | ||||
| out.writeShortBigEndian ((short) values.getValue (prefix + "Identifier", "0").getIntValue()); | out.writeShortBigEndian ((short) values.getValue (prefix + "Identifier", "0").getIntValue()); | ||||
| const String comment (values.getValue (prefix + "Text", String::empty)); | |||||
| const String comment (values.getValue (prefix + "Text", String())); | |||||
| const size_t commentLength = jmin (comment.getNumBytesAsUTF8(), (size_t) 65534); | const size_t commentLength = jmin (comment.getNumBytesAsUTF8(), (size_t) 65534); | ||||
| out.writeShortBigEndian ((short) commentLength + 1); | out.writeShortBigEndian ((short) commentLength + 1); | ||||
| @@ -51,7 +51,19 @@ namespace FlacNamespace | |||||
| #pragma clang diagnostic ignored "-Wshadow" | #pragma clang diagnostic ignored "-Wshadow" | ||||
| #endif | #endif | ||||
| #if JUCE_INTEL | |||||
| #if JUCE_32BIT | |||||
| #define FLAC__CPU_IA32 1 | |||||
| #endif | |||||
| #if JUCE_64BIT | |||||
| #define FLAC__CPU_X86_64 1 | |||||
| #endif | |||||
| #define FLAC__HAS_X86INTRIN 1 | |||||
| #endif | |||||
| #define __STDC_LIMIT_MACROS 1 | #define __STDC_LIMIT_MACROS 1 | ||||
| #define flac_max jmax | |||||
| #define flac_min jmin | |||||
| #include "flac/all.h" | #include "flac/all.h" | ||||
| #include "flac/libFLAC/bitmath.c" | #include "flac/libFLAC/bitmath.c" | ||||
| #include "flac/libFLAC/bitreader.c" | #include "flac/libFLAC/bitreader.c" | ||||
| @@ -28,7 +28,7 @@ class LAMEEncoderAudioFormat::Writer : public AudioFormatWriter | |||||
| { | { | ||||
| public: | public: | ||||
| Writer (OutputStream* destStream, const String& formatName, | Writer (OutputStream* destStream, const String& formatName, | ||||
| const File& lameApp, int vbr, int cbr, | |||||
| const File& appFile, int vbr, int cbr, | |||||
| double sampleRate, unsigned int numberOfChannels, | double sampleRate, unsigned int numberOfChannels, | ||||
| unsigned int bitsPerSample, const StringPairArray& metadata) | unsigned int bitsPerSample, const StringPairArray& metadata) | ||||
| : AudioFormatWriter (destStream, formatName, sampleRate, | : AudioFormatWriter (destStream, formatName, sampleRate, | ||||
| @@ -43,7 +43,7 @@ public: | |||||
| writer = wavFormat.createWriterFor (out, sampleRate, numChannels, | writer = wavFormat.createWriterFor (out, sampleRate, numChannels, | ||||
| bitsPerSample, metadata, 0); | bitsPerSample, metadata, 0); | ||||
| args.add (lameApp.getFullPathName()); | |||||
| args.add (appFile.getFullPathName()); | |||||
| args.add ("--quiet"); | args.add ("--quiet"); | ||||
| @@ -72,7 +72,7 @@ public: | |||||
| void addMetadataArg (const StringPairArray& metadata, const char* key, const char* lameFlag) | void addMetadataArg (const StringPairArray& metadata, const char* key, const char* lameFlag) | ||||
| { | { | ||||
| const String value (metadata.getValue (key, String::empty)); | |||||
| const String value (metadata.getValue (key, String())); | |||||
| if (value.isNotEmpty()) | if (value.isNotEmpty()) | ||||
| { | { | ||||
| @@ -103,11 +103,11 @@ private: | |||||
| ScopedPointer<AudioFormatWriter> writer; | ScopedPointer<AudioFormatWriter> writer; | ||||
| StringArray args; | StringArray args; | ||||
| bool runLameChildProcess (const TemporaryFile& tempMP3, const StringArray& args) const | |||||
| bool runLameChildProcess (const TemporaryFile& tempMP3, const StringArray& processArgs) const | |||||
| { | { | ||||
| ChildProcess cp; | ChildProcess cp; | ||||
| if (cp.start (args)) | |||||
| if (cp.start (processArgs)) | |||||
| { | { | ||||
| const String childOutput (cp.readAllProcessOutput()); | const String childOutput (cp.readAllProcessOutput()); | ||||
| DBG (childOutput); (void) childOutput; | DBG (childOutput); (void) childOutput; | ||||
| @@ -3095,7 +3095,14 @@ private: | |||||
| const int64 streamSize = stream.stream.getTotalLength(); | const int64 streamSize = stream.stream.getTotalLength(); | ||||
| if (streamSize > 0) | if (streamSize > 0) | ||||
| numFrames = (streamSize - streamStartPos) / (stream.frame.frameSize); | |||||
| { | |||||
| const int bytesPerFrame = stream.frame.frameSize + 4; | |||||
| if (bytesPerFrame == 417 || bytesPerFrame == 418) | |||||
| numFrames = roundToInt ((streamSize - streamStartPos) / 417.95918); // more accurate for 128k | |||||
| else | |||||
| numFrames = (streamSize - streamStartPos) / bytesPerFrame; | |||||
| } | |||||
| } | } | ||||
| return numFrames * 1152; | return numFrames * 1152; | ||||
| @@ -124,6 +124,17 @@ public: | |||||
| if (err == 0) | if (err == 0) | ||||
| { | { | ||||
| vorbis_info* info = ov_info (&ovFile, -1); | vorbis_info* info = ov_info (&ovFile, -1); | ||||
| vorbis_comment* const comment = ov_comment (&ovFile, -1); | |||||
| addMetadataItem (comment, "ENCODER", OggVorbisAudioFormat::encoderName); | |||||
| addMetadataItem (comment, "TITLE", OggVorbisAudioFormat::id3title); | |||||
| addMetadataItem (comment, "ARTIST", OggVorbisAudioFormat::id3artist); | |||||
| addMetadataItem (comment, "ALBUM", OggVorbisAudioFormat::id3album); | |||||
| addMetadataItem (comment, "COMMENT", OggVorbisAudioFormat::id3comment); | |||||
| addMetadataItem (comment, "DATE", OggVorbisAudioFormat::id3date); | |||||
| addMetadataItem (comment, "GENRE", OggVorbisAudioFormat::id3genre); | |||||
| addMetadataItem (comment, "TRACKNUMBER", OggVorbisAudioFormat::id3trackNumber); | |||||
| lengthInSamples = (uint32) ov_pcm_total (&ovFile, -1); | lengthInSamples = (uint32) ov_pcm_total (&ovFile, -1); | ||||
| numChannels = (unsigned int) info->channels; | numChannels = (unsigned int) info->channels; | ||||
| bitsPerSample = 16; | bitsPerSample = 16; | ||||
| @@ -139,6 +150,12 @@ public: | |||||
| OggVorbisNamespace::ov_clear (&ovFile); | OggVorbisNamespace::ov_clear (&ovFile); | ||||
| } | } | ||||
| void addMetadataItem (OggVorbisNamespace::vorbis_comment* comment, const char* name, const char* metadataName) | |||||
| { | |||||
| if (const char* value = vorbis_comment_query (comment, name, 0)) | |||||
| metadataValues.set (metadataName, value); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, | bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, | ||||
| int64 startSampleInFile, int numSamples) override | int64 startSampleInFile, int numSamples) override | ||||
| @@ -39,16 +39,16 @@ void vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bm){ | |||||
| bm->short_per_long=ci->blocksizes[1]/ci->blocksizes[0]; | bm->short_per_long=ci->blocksizes[1]/ci->blocksizes[0]; | ||||
| bm->managed=1; | bm->managed=1; | ||||
| bm->avg_bitsper= rint(1.*bi->avg_rate*halfsamples/ratesamples); | |||||
| bm->min_bitsper= rint(1.*bi->min_rate*halfsamples/ratesamples); | |||||
| bm->max_bitsper= rint(1.*bi->max_rate*halfsamples/ratesamples); | |||||
| bm->avg_bitsper= (int) rint(1.*bi->avg_rate*halfsamples/ratesamples); | |||||
| bm->min_bitsper= (int) rint(1.*bi->min_rate*halfsamples/ratesamples); | |||||
| bm->max_bitsper= (int) rint(1.*bi->max_rate*halfsamples/ratesamples); | |||||
| bm->avgfloat=PACKETBLOBS/2; | bm->avgfloat=PACKETBLOBS/2; | ||||
| /* not a necessary fix, but one that leads to a more balanced | /* not a necessary fix, but one that leads to a more balanced | ||||
| typical initialization */ | typical initialization */ | ||||
| { | { | ||||
| long desired_fill=bi->reservoir_bits*bi->reservoir_bias; | |||||
| long desired_fill = (long) (bi->reservoir_bits*bi->reservoir_bias); | |||||
| bm->minmax_reservoir=desired_fill; | bm->minmax_reservoir=desired_fill; | ||||
| bm->avg_reservoir=desired_fill; | bm->avg_reservoir=desired_fill; | ||||
| } | } | ||||
| @@ -80,12 +80,12 @@ int vorbis_bitrate_addblock(vorbis_block *vb){ | |||||
| codec_setup_info *ci=(codec_setup_info*)vi->codec_setup; | codec_setup_info *ci=(codec_setup_info*)vi->codec_setup; | ||||
| bitrate_manager_info *bi=&ci->bi; | bitrate_manager_info *bi=&ci->bi; | ||||
| int choice=rint(bm->avgfloat); | |||||
| int choice = (int) rint(bm->avgfloat); | |||||
| long this_bits=oggpack_bytes(vbi->packetblob[choice])*8; | long this_bits=oggpack_bytes(vbi->packetblob[choice])*8; | ||||
| long min_target_bits=(vb->W?bm->min_bitsper*bm->short_per_long:bm->min_bitsper); | long min_target_bits=(vb->W?bm->min_bitsper*bm->short_per_long:bm->min_bitsper); | ||||
| long max_target_bits=(vb->W?bm->max_bitsper*bm->short_per_long:bm->max_bitsper); | long max_target_bits=(vb->W?bm->max_bitsper*bm->short_per_long:bm->max_bitsper); | ||||
| int samples=ci->blocksizes[vb->W]>>1; | int samples=ci->blocksizes[vb->W]>>1; | ||||
| long desired_fill=bi->reservoir_bits*bi->reservoir_bias; | |||||
| long desired_fill = (long) (bi->reservoir_bits*bi->reservoir_bias); | |||||
| if(!bm->managed){ | if(!bm->managed){ | ||||
| /* not a bitrate managed stream, but for API simplicity, we'll | /* not a bitrate managed stream, but for API simplicity, we'll | ||||
| buffer the packet to keep the code path clean */ | buffer the packet to keep the code path clean */ | ||||
| @@ -132,7 +132,7 @@ int vorbis_bitrate_addblock(vorbis_block *vb){ | |||||
| slew=rint(choice-bm->avgfloat)/samples*vi->rate; | slew=rint(choice-bm->avgfloat)/samples*vi->rate; | ||||
| if(slew<-slewlimit)slew=-slewlimit; | if(slew<-slewlimit)slew=-slewlimit; | ||||
| if(slew>slewlimit)slew=slewlimit; | if(slew>slewlimit)slew=slewlimit; | ||||
| choice=rint(bm->avgfloat+= slew/vi->rate*samples); | |||||
| choice = (int) rint(bm->avgfloat+= slew/vi->rate*samples); | |||||
| this_bits=oggpack_bytes(vbi->packetblob[choice])*8; | this_bits=oggpack_bytes(vbi->packetblob[choice])*8; | ||||
| } | } | ||||
| @@ -169,7 +169,6 @@ int vorbis_block_clear(vorbis_block *vb){ | |||||
| The init is here because some of it is shared */ | The init is here because some of it is shared */ | ||||
| static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){ | static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){ | ||||
| int i; | |||||
| codec_setup_info *ci=(codec_setup_info*)vi->codec_setup; | codec_setup_info *ci=(codec_setup_info*)vi->codec_setup; | ||||
| private_state *b=NULL; | private_state *b=NULL; | ||||
| int hs; | int hs; | ||||
| @@ -206,12 +205,12 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){ | |||||
| /* finish the codebooks */ | /* finish the codebooks */ | ||||
| if(!ci->fullbooks){ | if(!ci->fullbooks){ | ||||
| ci->fullbooks=(codebook*) _ogg_calloc(ci->books,sizeof(*ci->fullbooks)); | ci->fullbooks=(codebook*) _ogg_calloc(ci->books,sizeof(*ci->fullbooks)); | ||||
| for(i=0;i<ci->books;i++) | |||||
| for(int i=0;i<ci->books;i++) | |||||
| vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]); | vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]); | ||||
| } | } | ||||
| b->psy=(vorbis_look_psy*)_ogg_calloc(ci->psys,sizeof(*b->psy)); | b->psy=(vorbis_look_psy*)_ogg_calloc(ci->psys,sizeof(*b->psy)); | ||||
| for(i=0;i<ci->psys;i++){ | |||||
| for(int i=0;i<ci->psys;i++){ | |||||
| _vp_psy_init(b->psy+i, | _vp_psy_init(b->psy+i, | ||||
| ci->psy_param[i], | ci->psy_param[i], | ||||
| &ci->psy_g_param, | &ci->psy_g_param, | ||||
| @@ -224,7 +223,7 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){ | |||||
| /* finish the codebooks */ | /* finish the codebooks */ | ||||
| if(!ci->fullbooks){ | if(!ci->fullbooks){ | ||||
| ci->fullbooks=(codebook*) _ogg_calloc(ci->books,sizeof(*ci->fullbooks)); | ci->fullbooks=(codebook*) _ogg_calloc(ci->books,sizeof(*ci->fullbooks)); | ||||
| for(i=0;i<ci->books;i++){ | |||||
| for(int i=0;i<ci->books;i++){ | |||||
| if(ci->book_param[i]==NULL) | if(ci->book_param[i]==NULL) | ||||
| goto abort_books; | goto abort_books; | ||||
| if(vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i])) | if(vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i])) | ||||
| @@ -261,17 +260,17 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){ | |||||
| b->flr=(vorbis_look_floor**)_ogg_calloc(ci->floors,sizeof(*b->flr)); | b->flr=(vorbis_look_floor**)_ogg_calloc(ci->floors,sizeof(*b->flr)); | ||||
| b->residue=(vorbis_look_residue**)_ogg_calloc(ci->residues,sizeof(*b->residue)); | b->residue=(vorbis_look_residue**)_ogg_calloc(ci->residues,sizeof(*b->residue)); | ||||
| for(i=0;i<ci->floors;i++) | |||||
| for(int i=0;i<ci->floors;i++) | |||||
| b->flr[i]=_floor_P[ci->floor_type[i]]-> | b->flr[i]=_floor_P[ci->floor_type[i]]-> | ||||
| look(v,ci->floor_param[i]); | look(v,ci->floor_param[i]); | ||||
| for(i=0;i<ci->residues;i++) | |||||
| for(int i=0;i<ci->residues;i++) | |||||
| b->residue[i]=_residue_P[ci->residue_type[i]]-> | b->residue[i]=_residue_P[ci->residue_type[i]]-> | ||||
| look(v,ci->residue_param[i]); | look(v,ci->residue_param[i]); | ||||
| return 0; | return 0; | ||||
| abort_books: | abort_books: | ||||
| for(i=0;i<ci->books;i++){ | |||||
| for(int i=0;i<ci->books;i++){ | |||||
| if(ci->book_param[i]!=NULL){ | if(ci->book_param[i]!=NULL){ | ||||
| vorbis_staticbook_destroy(ci->book_param[i]); | vorbis_staticbook_destroy(ci->book_param[i]); | ||||
| ci->book_param[i]=NULL; | ci->book_param[i]=NULL; | ||||
| @@ -850,7 +849,7 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){ | |||||
| if(b->sample_count>v->granulepos){ | if(b->sample_count>v->granulepos){ | ||||
| /* corner case; if this is both the first and last audio page, | /* corner case; if this is both the first and last audio page, | ||||
| then spec says the end is cut, not beginning */ | then spec says the end is cut, not beginning */ | ||||
| long extra=b->sample_count-vb->granulepos; | |||||
| long extra = (long) (b->sample_count-vb->granulepos); | |||||
| /* we use ogg_int64_t for granule positions because a | /* we use ogg_int64_t for granule positions because a | ||||
| uint64 isn't universally available. Unfortunately, | uint64 isn't universally available. Unfortunately, | ||||
| @@ -958,7 +957,6 @@ int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){ | |||||
| int n=ci->blocksizes[v->W]>>(hs+1); | int n=ci->blocksizes[v->W]>>(hs+1); | ||||
| int n0=ci->blocksizes[0]>>(hs+1); | int n0=ci->blocksizes[0]>>(hs+1); | ||||
| int n1=ci->blocksizes[1]>>(hs+1); | int n1=ci->blocksizes[1]>>(hs+1); | ||||
| int i,j; | |||||
| if(v->pcm_returned<0)return 0; | if(v->pcm_returned<0)return 0; | ||||
| @@ -975,9 +973,9 @@ int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){ | |||||
| if(v->centerW==n1){ | if(v->centerW==n1){ | ||||
| /* the data buffer wraps; swap the halves */ | /* the data buffer wraps; swap the halves */ | ||||
| /* slow, sure, small */ | /* slow, sure, small */ | ||||
| for(j=0;j<vi->channels;j++){ | |||||
| for(int j=0;j<vi->channels;j++){ | |||||
| float *p=v->pcm[j]; | float *p=v->pcm[j]; | ||||
| for(i=0;i<n1;i++){ | |||||
| for(int i=0;i<n1;i++){ | |||||
| float temp=p[i]; | float temp=p[i]; | ||||
| p[i]=p[i+n1]; | p[i]=p[i+n1]; | ||||
| p[i+n1]=temp; | p[i+n1]=temp; | ||||
| @@ -992,10 +990,10 @@ int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){ | |||||
| /* solidify buffer into contiguous space */ | /* solidify buffer into contiguous space */ | ||||
| if((v->lW^v->W)==1){ | if((v->lW^v->W)==1){ | ||||
| /* long/short or short/long */ | /* long/short or short/long */ | ||||
| for(j=0;j<vi->channels;j++){ | |||||
| for(int j=0;j<vi->channels;j++){ | |||||
| float *s=v->pcm[j]; | float *s=v->pcm[j]; | ||||
| float *d=v->pcm[j]+(n1-n0)/2; | float *d=v->pcm[j]+(n1-n0)/2; | ||||
| for(i=(n1+n0)/2-1;i>=0;--i) | |||||
| for(int i=(n1+n0)/2-1;i>=0;--i) | |||||
| d[i]=s[i]; | d[i]=s[i]; | ||||
| } | } | ||||
| v->pcm_returned+=(n1-n0)/2; | v->pcm_returned+=(n1-n0)/2; | ||||
| @@ -1003,10 +1001,10 @@ int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){ | |||||
| }else{ | }else{ | ||||
| if(v->lW==0){ | if(v->lW==0){ | ||||
| /* short/short */ | /* short/short */ | ||||
| for(j=0;j<vi->channels;j++){ | |||||
| for(int j=0;j<vi->channels;j++){ | |||||
| float *s=v->pcm[j]; | float *s=v->pcm[j]; | ||||
| float *d=v->pcm[j]+n1-n0; | float *d=v->pcm[j]+n1-n0; | ||||
| for(i=n0-1;i>=0;--i) | |||||
| for(int i=n0-1;i>=0;--i) | |||||
| d[i]=s[i]; | d[i]=s[i]; | ||||
| } | } | ||||
| v->pcm_returned+=n1-n0; | v->pcm_returned+=n1-n0; | ||||
| @@ -1015,8 +1013,7 @@ int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){ | |||||
| } | } | ||||
| if(pcm){ | if(pcm){ | ||||
| int i; | |||||
| for(i=0;i<vi->channels;i++) | |||||
| for(int i=0;i<vi->channels;i++) | |||||
| v->pcmret[i]=v->pcm[i]+v->pcm_returned; | v->pcmret[i]=v->pcm[i]+v->pcm_returned; | ||||
| *pcm=v->pcmret; | *pcm=v->pcmret; | ||||
| } | } | ||||
| @@ -426,7 +426,7 @@ static long **_01class(vorbis_block *vb,vorbis_look_residue *vl, | |||||
| int partvals=n/samples_per_partition; | int partvals=n/samples_per_partition; | ||||
| long **partword=(long**)_vorbis_block_alloc(vb,ch*sizeof(*partword)); | long **partword=(long**)_vorbis_block_alloc(vb,ch*sizeof(*partword)); | ||||
| float scale=100./samples_per_partition; | |||||
| float scale=100.0f/samples_per_partition; | |||||
| /* we find the partition type for each partition of each | /* we find the partition type for each partition of each | ||||
| channel. We'll go back and do the interleaved encoding in a | channel. We'll go back and do the interleaved encoding in a | ||||
| @@ -36,6 +36,10 @@ void AudioPluginFormatManager::addDefaultFormats() | |||||
| jassert (dynamic_cast <VSTPluginFormat*> (formats[i]) == nullptr); | jassert (dynamic_cast <VSTPluginFormat*> (formats[i]) == nullptr); | ||||
| #endif | #endif | ||||
| #if JUCE_PLUGINHOST_VST3 | |||||
| jassert (dynamic_cast <VST3PluginFormat*> (formats[i]) == nullptr); | |||||
| #endif | |||||
| #if JUCE_PLUGINHOST_AU && JUCE_MAC | #if JUCE_PLUGINHOST_AU && JUCE_MAC | ||||
| jassert (dynamic_cast <AudioUnitPluginFormat*> (formats[i]) == nullptr); | jassert (dynamic_cast <AudioUnitPluginFormat*> (formats[i]) == nullptr); | ||||
| #endif | #endif | ||||
| @@ -54,6 +58,10 @@ void AudioPluginFormatManager::addDefaultFormats() | |||||
| formats.add (new VSTPluginFormat()); | formats.add (new VSTPluginFormat()); | ||||
| #endif | #endif | ||||
| #if JUCE_PLUGINHOST_VST3 | |||||
| formats.add (new VST3PluginFormat()); | |||||
| #endif | |||||
| #if JUCE_PLUGINHOST_LADSPA && JUCE_LINUX | #if JUCE_PLUGINHOST_LADSPA && JUCE_LINUX | ||||
| formats.add (new LADSPAPluginFormat()); | formats.add (new LADSPAPluginFormat()); | ||||
| #endif | #endif | ||||
| @@ -58,7 +58,9 @@ namespace juce | |||||
| namespace AudioUnitFormatHelpers | namespace AudioUnitFormatHelpers | ||||
| { | { | ||||
| static int insideCallback = 0; | |||||
| #if JUCE_DEBUG | |||||
| static ThreadLocalValue<int> insideCallback; | |||||
| #endif | |||||
| String osTypeToString (OSType type) | String osTypeToString (OSType type) | ||||
| { | { | ||||
| @@ -136,7 +138,7 @@ namespace AudioUnitFormatHelpers | |||||
| fileOrIdentifier.lastIndexOfChar ('/')) + 1)); | fileOrIdentifier.lastIndexOfChar ('/')) + 1)); | ||||
| StringArray tokens; | StringArray tokens; | ||||
| tokens.addTokens (s, ",", String::empty); | |||||
| tokens.addTokens (s, ",", String()); | |||||
| tokens.removeEmptyStrings(); | tokens.removeEmptyStrings(); | ||||
| if (tokens.size() == 3) | if (tokens.size() == 3) | ||||
| @@ -290,7 +292,9 @@ public: | |||||
| { | { | ||||
| using namespace AudioUnitFormatHelpers; | using namespace AudioUnitFormatHelpers; | ||||
| ++insideCallback; | |||||
| #if JUCE_DEBUG | |||||
| ++*insideCallback; | |||||
| #endif | |||||
| JUCE_AU_LOG ("Opening AU: " + fileOrIdentifier); | JUCE_AU_LOG ("Opening AU: " + fileOrIdentifier); | ||||
| @@ -306,14 +310,20 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| --insideCallback; | |||||
| #if JUCE_DEBUG | |||||
| --*insideCallback; | |||||
| #endif | |||||
| } | } | ||||
| ~AudioUnitPluginInstance() | ~AudioUnitPluginInstance() | ||||
| { | { | ||||
| const ScopedLock sl (lock); | const ScopedLock sl (lock); | ||||
| jassert (AudioUnitFormatHelpers::insideCallback == 0); | |||||
| #if JUCE_DEBUG | |||||
| // this indicates that some kind of recursive call is getting triggered that's | |||||
| // deleting this plugin while it's still under construction. | |||||
| jassert (AudioUnitFormatHelpers::insideCallback.get() == 0); | |||||
| #endif | |||||
| if (eventListenerRef != 0) | if (eventListenerRef != 0) | ||||
| { | { | ||||
| @@ -468,8 +478,8 @@ public: | |||||
| resetBusses(); | resetBusses(); | ||||
| prepared = (AudioUnitInitialize (audioUnit) == noErr); | |||||
| jassert (prepared); | |||||
| jassert (! prepared); | |||||
| initialiseAudioUnit(); | |||||
| } | } | ||||
| } | } | ||||
| @@ -489,6 +499,14 @@ public: | |||||
| incomingMidi.clear(); | incomingMidi.clear(); | ||||
| } | } | ||||
| bool initialiseAudioUnit() | |||||
| { | |||||
| if (! prepared) | |||||
| prepared = (AudioUnitInitialize (audioUnit) == noErr); | |||||
| return prepared; | |||||
| } | |||||
| void resetBusses() | void resetBusses() | ||||
| { | { | ||||
| for (int i = 0; i < numInputBusses; ++i) AudioUnitReset (audioUnit, kAudioUnitScope_Input, i); | for (int i = 0; i < numInputBusses; ++i) AudioUnitReset (audioUnit, kAudioUnitScope_Input, i); | ||||
| @@ -570,7 +588,7 @@ public: | |||||
| if (isPositiveAndBelow (index, getNumInputChannels())) | if (isPositiveAndBelow (index, getNumInputChannels())) | ||||
| return "Input " + String (index + 1); | return "Input " + String (index + 1); | ||||
| return String::empty; | |||||
| return String(); | |||||
| } | } | ||||
| const String getOutputChannelName (int index) const override | const String getOutputChannelName (int index) const override | ||||
| @@ -578,7 +596,7 @@ public: | |||||
| if (isPositiveAndBelow (index, getNumOutputChannels())) | if (isPositiveAndBelow (index, getNumOutputChannels())) | ||||
| return "Output " + String (index + 1); | return "Output " + String (index + 1); | ||||
| return String::empty; | |||||
| return String(); | |||||
| } | } | ||||
| bool isInputChannelStereoPair (int index) const override { return isPositiveAndBelow (index, getNumInputChannels()); } | bool isInputChannelStereoPair (int index) const override { return isPositiveAndBelow (index, getNumInputChannels()); } | ||||
| @@ -643,8 +661,13 @@ public: | |||||
| void sendAllParametersChangedEvents() | void sendAllParametersChangedEvents() | ||||
| { | { | ||||
| for (int i = 0; i < parameters.size(); ++i) | |||||
| sendParameterChangeEvent (i); | |||||
| jassert (audioUnit != nullptr); | |||||
| AudioUnitParameter param; | |||||
| param.mAudioUnit = audioUnit; | |||||
| param.mParameterID = kAUParameterListener_AnyParameter; | |||||
| AUParameterListenerNotify (nullptr, nullptr, ¶m); | |||||
| } | } | ||||
| const String getParameterName (int index) override | const String getParameterName (int index) override | ||||
| @@ -652,7 +675,7 @@ public: | |||||
| if (const ParamInfo* p = parameters[index]) | if (const ParamInfo* p = parameters[index]) | ||||
| return p->name; | return p->name; | ||||
| return String::empty; | |||||
| return String(); | |||||
| } | } | ||||
| const String getParameterText (int index) override { return String (getParameter (index)); } | const String getParameterText (int index) override { return String (getParameter (index)); } | ||||
| @@ -789,10 +812,14 @@ public: | |||||
| if (propertyList != 0) | if (propertyList != 0) | ||||
| { | { | ||||
| initialiseAudioUnit(); | |||||
| AudioUnitSetProperty (audioUnit, kAudioUnitProperty_ClassInfo, kAudioUnitScope_Global, | AudioUnitSetProperty (audioUnit, kAudioUnitProperty_ClassInfo, kAudioUnitScope_Global, | ||||
| 0, &propertyList, sizeof (propertyList)); | 0, &propertyList, sizeof (propertyList)); | ||||
| sendAllParametersChangedEvents(); | sendAllParametersChangedEvents(); | ||||
| CFRelease (propertyList); | |||||
| } | } | ||||
| } | } | ||||
| @@ -1285,15 +1312,14 @@ private: | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| class AudioUnitPluginWindowCocoa : public AudioProcessorEditor, | |||||
| public Timer | |||||
| class AudioUnitPluginWindowCocoa : public AudioProcessorEditor | |||||
| { | { | ||||
| public: | public: | ||||
| AudioUnitPluginWindowCocoa (AudioUnitPluginInstance& p, bool createGenericViewIfNeeded) | AudioUnitPluginWindowCocoa (AudioUnitPluginInstance& p, bool createGenericViewIfNeeded) | ||||
| : AudioProcessorEditor (&p), | : AudioProcessorEditor (&p), | ||||
| plugin (p) | plugin (p) | ||||
| { | { | ||||
| addAndMakeVisible (&wrapper); | |||||
| addAndMakeVisible (wrapper); | |||||
| setOpaque (true); | setOpaque (true); | ||||
| setVisible (true); | setVisible (true); | ||||
| @@ -1325,30 +1351,25 @@ public: | |||||
| wrapper.setSize (getWidth(), getHeight()); | wrapper.setSize (getWidth(), getHeight()); | ||||
| } | } | ||||
| void timerCallback() override | |||||
| { | |||||
| wrapper.resizeToFitView(); | |||||
| startTimer (jmin (713, getTimerInterval() + 51)); | |||||
| } | |||||
| void childBoundsChanged (Component*) override | void childBoundsChanged (Component*) override | ||||
| { | { | ||||
| setSize (wrapper.getWidth(), wrapper.getHeight()); | setSize (wrapper.getWidth(), wrapper.getHeight()); | ||||
| startTimer (70); | |||||
| } | } | ||||
| private: | private: | ||||
| AudioUnitPluginInstance& plugin; | AudioUnitPluginInstance& plugin; | ||||
| NSViewComponent wrapper; | |||||
| AutoResizingNSViewComponent wrapper; | |||||
| bool createView (const bool createGenericViewIfNeeded) | bool createView (const bool createGenericViewIfNeeded) | ||||
| { | { | ||||
| if (! plugin.initialiseAudioUnit()) | |||||
| return false; | |||||
| NSView* pluginView = nil; | NSView* pluginView = nil; | ||||
| UInt32 dataSize = 0; | UInt32 dataSize = 0; | ||||
| Boolean isWritable = false; | Boolean isWritable = false; | ||||
| AudioUnitInitialize (plugin.audioUnit); | |||||
| if (AudioUnitGetPropertyInfo (plugin.audioUnit, kAudioUnitProperty_CocoaUI, kAudioUnitScope_Global, | if (AudioUnitGetPropertyInfo (plugin.audioUnit, kAudioUnitProperty_CocoaUI, kAudioUnitScope_Global, | ||||
| 0, &dataSize, &isWritable) == noErr | 0, &dataSize, &isWritable) == noErr | ||||
| && dataSize != 0 | && dataSize != 0 | ||||
| @@ -1400,10 +1421,7 @@ private: | |||||
| wrapper.setView (pluginView); | wrapper.setView (pluginView); | ||||
| if (pluginView != nil) | if (pluginView != nil) | ||||
| { | |||||
| timerCallback(); | |||||
| startTimer (70); | |||||
| } | |||||
| wrapper.resizeToFitView(); | |||||
| return pluginView != nil; | return pluginView != nil; | ||||
| } | } | ||||
| @@ -1518,16 +1536,10 @@ private: | |||||
| Float32Point pos = { 0, 0 }; | Float32Point pos = { 0, 0 }; | ||||
| Float32Point size = { 250, 200 }; | Float32Point size = { 250, 200 }; | ||||
| HIViewRef pluginView = 0; | HIViewRef pluginView = 0; | ||||
| AudioUnitCarbonViewCreate (carbonView, | |||||
| owner.getAudioUnit(), | |||||
| windowRef, | |||||
| rootView, | |||||
| &pos, | |||||
| &size, | |||||
| (ControlRef*) &pluginView); | |||||
| AudioUnitCarbonViewCreate (carbonView, owner.getAudioUnit(), windowRef, rootView, | |||||
| &pos, &size, (ControlRef*) &pluginView); | |||||
| return pluginView; | return pluginView; | ||||
| } | } | ||||
| @@ -222,7 +222,7 @@ public: | |||||
| desc.lastFileModTime = module->file.getLastModificationTime(); | desc.lastFileModTime = module->file.getLastModificationTime(); | ||||
| desc.pluginFormatName = "LADSPA"; | desc.pluginFormatName = "LADSPA"; | ||||
| desc.category = getCategory(); | desc.category = getCategory(); | ||||
| desc.manufacturerName = plugin != nullptr ? String (plugin->Maker) : String::empty; | |||||
| desc.manufacturerName = plugin != nullptr ? String (plugin->Maker) : String(); | |||||
| desc.version = getVersion(); | desc.version = getVersion(); | ||||
| desc.numInputChannels = getNumInputChannels(); | desc.numInputChannels = getNumInputChannels(); | ||||
| desc.numOutputChannels = getNumOutputChannels(); | desc.numOutputChannels = getNumOutputChannels(); | ||||
| @@ -338,7 +338,7 @@ public: | |||||
| if (isPositiveAndBelow (index, getNumInputChannels())) | if (isPositiveAndBelow (index, getNumInputChannels())) | ||||
| return String (plugin->PortNames [inputs [index]]).trim(); | return String (plugin->PortNames [inputs [index]]).trim(); | ||||
| return String::empty; | |||||
| return String(); | |||||
| } | } | ||||
| const String getOutputChannelName (const int index) const | const String getOutputChannelName (const int index) const | ||||
| @@ -346,7 +346,7 @@ public: | |||||
| if (isPositiveAndBelow (index, getNumInputChannels())) | if (isPositiveAndBelow (index, getNumInputChannels())) | ||||
| return String (plugin->PortNames [outputs [index]]).trim(); | return String (plugin->PortNames [outputs [index]]).trim(); | ||||
| return String::empty; | |||||
| return String(); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -390,7 +390,7 @@ public: | |||||
| return String (plugin->PortNames [parameters [index]]).trim(); | return String (plugin->PortNames [parameters [index]]).trim(); | ||||
| } | } | ||||
| return String::empty; | |||||
| return String(); | |||||
| } | } | ||||
| const String getParameterText (int index) | const String getParameterText (int index) | ||||
| @@ -407,7 +407,7 @@ public: | |||||
| return String (parameterValues[index].scaled, 4); | return String (parameterValues[index].scaled, 4); | ||||
| } | } | ||||
| return String::empty; | |||||
| return String(); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -424,7 +424,7 @@ public: | |||||
| const String getProgramName (int index) | const String getProgramName (int index) | ||||
| { | { | ||||
| // XXX | // XXX | ||||
| return String::empty; | |||||
| return String(); | |||||
| } | } | ||||
| void changeProgramName (int index, const String& newName) | void changeProgramName (int index, const String& newName) | ||||
| @@ -0,0 +1,410 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCE library. | |||||
| Copyright (c) 2013 - Raw Material Software Ltd. | |||||
| Permission is granted to use this software under the terms of either: | |||||
| a) the GPL v2 (or any later version) | |||||
| b) the Affero GPL v3 | |||||
| Details of these licenses can be found at: www.gnu.org/licenses | |||||
| JUCE 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. | |||||
| ------------------------------------------------------------------------------ | |||||
| To release a closed-source product which uses JUCE, commercial licenses are | |||||
| available: visit www.juce.com for more information. | |||||
| ============================================================================== | |||||
| */ | |||||
| #ifndef JUCE_VST3COMMON_H_INCLUDED | |||||
| #define JUCE_VST3COMMON_H_INCLUDED | |||||
| //============================================================================== | |||||
| #define JUCE_DECLARE_VST3_COM_REF_METHODS \ | |||||
| Steinberg::uint32 JUCE_CALLTYPE addRef() override { return (Steinberg::uint32) ++refCount; } \ | |||||
| Steinberg::uint32 JUCE_CALLTYPE release() override { const int r = --refCount; if (r == 0) delete this; return (Steinberg::uint32) r; } | |||||
| #define JUCE_DECLARE_VST3_COM_QUERY_METHODS \ | |||||
| Steinberg::tresult PLUGIN_API JUCE_CALLTYPE queryInterface (const Steinberg::TUID, void** obj) override \ | |||||
| { \ | |||||
| jassertfalse; \ | |||||
| *obj = nullptr; \ | |||||
| return Steinberg::kNotImplemented; \ | |||||
| } | |||||
| static bool doUIDsMatch (const Steinberg::TUID a, const Steinberg::TUID b) noexcept | |||||
| { | |||||
| return std::memcmp (a, b, sizeof (Steinberg::TUID)) == 0; | |||||
| } | |||||
| #define TEST_FOR_AND_RETURN_IF_VALID(ClassType) \ | |||||
| if (doUIDsMatch (iid, ClassType::iid)) \ | |||||
| { \ | |||||
| addRef(); \ | |||||
| *obj = dynamic_cast<ClassType*> (this); \ | |||||
| return Steinberg::kResultOk; \ | |||||
| } | |||||
| //============================================================================== | |||||
| static juce::String toString (const Steinberg::char8* string) noexcept { return juce::String (string); } | |||||
| static juce::String toString (const Steinberg::char16* string) noexcept { return juce::String (juce::CharPointer_UTF16 ((juce::CharPointer_UTF16::CharType*) string)); } | |||||
| // NB: The casts are handled by a Steinberg::UString operator | |||||
| static juce::String toString (const Steinberg::UString128& string) noexcept { return toString (static_cast<const Steinberg::char16*> (string)); } | |||||
| static juce::String toString (const Steinberg::UString256& string) noexcept { return toString (static_cast<const Steinberg::char16*> (string)); } | |||||
| static void toString (Steinberg::Vst::String128 result, const juce::String& source) | |||||
| { | |||||
| Steinberg::UString (result, 128).fromAscii (source.toUTF8()); | |||||
| } | |||||
| static Steinberg::Vst::TChar* toString (const juce::String& source) noexcept | |||||
| { | |||||
| return reinterpret_cast<Steinberg::Vst::TChar*> (source.toUTF16().getAddress()); | |||||
| } | |||||
| //============================================================================== | |||||
| /** The equivalent numChannels and speaker arrangements should always | |||||
| match between this function and fillWithCorrespondingSpeakerArrangements(). | |||||
| There can only be 1 arrangement per channel count. (i.e.: 4 channels == k31Cine OR k40Cine) | |||||
| @see fillWithCorrespondingSpeakerArrangements | |||||
| */ | |||||
| static Steinberg::Vst::SpeakerArrangement getArrangementForNumChannels (int numChannels) noexcept | |||||
| { | |||||
| using namespace Steinberg::Vst::SpeakerArr; | |||||
| if (numChannels >= 14) return k131; | |||||
| if (numChannels >= 13) return k130; | |||||
| if (numChannels >= 12) return k111; | |||||
| if (numChannels >= 11) return k101; | |||||
| if (numChannels >= 10) return k91; | |||||
| if (numChannels >= 9) return k90; | |||||
| if (numChannels >= 8) return k71CineFullFront; | |||||
| if (numChannels >= 7) return k61Cine; | |||||
| if (numChannels >= 6) return k51; | |||||
| if (numChannels >= 5) return k50; | |||||
| if (numChannels >= 4) return k31Cine; | |||||
| if (numChannels >= 3) return k30Cine; | |||||
| if (numChannels >= 2) return kStereo; | |||||
| if (numChannels >= 1) return kMono; | |||||
| return kEmpty; | |||||
| } | |||||
| /** The equivalent numChannels and speaker arrangements should always | |||||
| match between this function and getArrangementForNumChannels(). | |||||
| There can only be 1 arrangement per channel count. (i.e.: 4 channels == k31Cine OR k40Cine) | |||||
| @see getArrangementForNumChannels | |||||
| */ | |||||
| static void fillWithCorrespondingSpeakerArrangements (Array<Steinberg::Vst::SpeakerArrangement>& destination, | |||||
| int numChannels) | |||||
| { | |||||
| using namespace Steinberg::Vst::SpeakerArr; | |||||
| destination.clearQuick(); | |||||
| if (numChannels <= 0) | |||||
| { | |||||
| destination.add (kEmpty); | |||||
| return; | |||||
| } | |||||
| /* | |||||
| The order of the arrangement checks must be descending, since most plugins test for | |||||
| the first arrangement to match their number of specified channels. | |||||
| */ | |||||
| if (numChannels >= 14) destination.add (k131); | |||||
| if (numChannels >= 13) destination.add (k130); | |||||
| if (numChannels >= 12) destination.add (k111); | |||||
| if (numChannels >= 11) destination.add (k101); | |||||
| if (numChannels >= 10) destination.add (k91); | |||||
| if (numChannels >= 9) destination.add (k90); | |||||
| if (numChannels >= 8) destination.add (k71CineFullFront); | |||||
| if (numChannels >= 7) destination.add (k61Cine); | |||||
| if (numChannels >= 6) destination.add (k51); | |||||
| if (numChannels >= 5) destination.add (k50); | |||||
| if (numChannels >= 4) destination.add (k31Cine); | |||||
| if (numChannels >= 3) destination.add (k30Cine); | |||||
| if (numChannels >= 2) destination.add (kStereo); | |||||
| if (numChannels >= 1) destination.add (kMono); | |||||
| } | |||||
| //============================================================================== | |||||
| template <class ObjectType> | |||||
| class ComSmartPtr | |||||
| { | |||||
| public: | |||||
| ComSmartPtr() noexcept : source (nullptr) {} | |||||
| ComSmartPtr (ObjectType* object) noexcept : source (object) { if (source != nullptr) source->addRef(); } | |||||
| ComSmartPtr (const ComSmartPtr& other) noexcept : source (other.source) { if (source != nullptr) source->addRef(); } | |||||
| ~ComSmartPtr() { if (source != nullptr) source->release(); } | |||||
| operator ObjectType*() const noexcept { return source; } | |||||
| ObjectType* get() const noexcept { return source; } | |||||
| ObjectType& operator*() const noexcept { return *source; } | |||||
| ObjectType* operator->() const noexcept { return source; } | |||||
| ComSmartPtr& operator= (const ComSmartPtr& other) { return operator= (other.source); } | |||||
| ComSmartPtr& operator= (ObjectType* const newObjectToTakePossessionOf) | |||||
| { | |||||
| ComSmartPtr p (newObjectToTakePossessionOf); | |||||
| std::swap (p.source, source); | |||||
| return *this; | |||||
| } | |||||
| bool operator== (ObjectType* const other) noexcept { return source == other; } | |||||
| bool operator!= (ObjectType* const other) noexcept { return source != other; } | |||||
| bool loadFrom (Steinberg::FUnknown* o) | |||||
| { | |||||
| *this = nullptr; | |||||
| return o != nullptr && o->queryInterface (ObjectType::iid, (void**) &source) == Steinberg::kResultOk; | |||||
| } | |||||
| bool loadFrom (Steinberg::IPluginFactory* factory, const Steinberg::TUID& uuid) | |||||
| { | |||||
| jassert (factory != nullptr); | |||||
| *this = nullptr; | |||||
| return factory->createInstance (uuid, ObjectType::iid, (void**) &source) == Steinberg::kResultOk; | |||||
| } | |||||
| private: | |||||
| ObjectType* source; | |||||
| }; | |||||
| //============================================================================== | |||||
| class MidiEventList : public Steinberg::Vst::IEventList | |||||
| { | |||||
| public: | |||||
| MidiEventList() {} | |||||
| virtual ~MidiEventList() {} | |||||
| JUCE_DECLARE_VST3_COM_REF_METHODS | |||||
| JUCE_DECLARE_VST3_COM_QUERY_METHODS | |||||
| //============================================================================== | |||||
| void clear() | |||||
| { | |||||
| events.clearQuick(); | |||||
| } | |||||
| Steinberg::int32 PLUGIN_API getEventCount() override | |||||
| { | |||||
| return (Steinberg::int32) events.size(); | |||||
| } | |||||
| // NB: This has to cope with out-of-range indexes from some plugins. | |||||
| Steinberg::tresult PLUGIN_API getEvent (Steinberg::int32 index, Steinberg::Vst::Event& e) override | |||||
| { | |||||
| if (isPositiveAndBelow ((int) index, events.size())) | |||||
| { | |||||
| e = events.getReference ((int) index); | |||||
| return Steinberg::kResultTrue; | |||||
| } | |||||
| return Steinberg::kResultFalse; | |||||
| } | |||||
| Steinberg::tresult PLUGIN_API addEvent (Steinberg::Vst::Event& e) override | |||||
| { | |||||
| events.add (e); | |||||
| return Steinberg::kResultTrue; | |||||
| } | |||||
| //============================================================================== | |||||
| static void toMidiBuffer (MidiBuffer& result, Steinberg::Vst::IEventList& eventList) | |||||
| { | |||||
| for (Steinberg::int32 i = 0; i < eventList.getEventCount(); ++i) | |||||
| { | |||||
| Steinberg::Vst::Event e; | |||||
| if (eventList.getEvent (i, e) == Steinberg::kResultOk) | |||||
| { | |||||
| switch (e.type) | |||||
| { | |||||
| case Steinberg::Vst::Event::kNoteOnEvent: | |||||
| result.addEvent (MidiMessage::noteOn (createSafeChannel (e.noteOn.channel), | |||||
| createSafeNote (e.noteOn.pitch), | |||||
| (Steinberg::uint8) denormaliseToMidiValue (e.noteOn.velocity)), | |||||
| e.sampleOffset); | |||||
| break; | |||||
| case Steinberg::Vst::Event::kNoteOffEvent: | |||||
| result.addEvent (MidiMessage::noteOff (createSafeChannel (e.noteOff.channel), | |||||
| createSafeNote (e.noteOff.pitch), | |||||
| (Steinberg::uint8) denormaliseToMidiValue (e.noteOff.velocity)), | |||||
| e.sampleOffset); | |||||
| break; | |||||
| case Steinberg::Vst::Event::kPolyPressureEvent: | |||||
| result.addEvent (MidiMessage::aftertouchChange (createSafeChannel (e.polyPressure.channel), | |||||
| createSafeNote (e.polyPressure.pitch), | |||||
| denormaliseToMidiValue (e.polyPressure.pressure)), | |||||
| e.sampleOffset); | |||||
| break; | |||||
| case Steinberg::Vst::Event::kDataEvent: | |||||
| result.addEvent (MidiMessage::createSysExMessage (e.data.bytes, e.data.size), | |||||
| e.sampleOffset); | |||||
| break; | |||||
| default: | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| static void toEventList (Steinberg::Vst::IEventList& result, MidiBuffer& midiBuffer) | |||||
| { | |||||
| MidiBuffer::Iterator iterator (midiBuffer); | |||||
| MidiMessage msg; | |||||
| int midiEventPosition = 0; | |||||
| enum { maxNumEvents = 2048 }; // Steinberg's Host Checker states that no more than 2048 events are allowed at once | |||||
| int numEvents = 0; | |||||
| while (iterator.getNextEvent (msg, midiEventPosition)) | |||||
| { | |||||
| if (++numEvents > maxNumEvents) | |||||
| break; | |||||
| Steinberg::Vst::Event e = { 0 }; | |||||
| if (msg.isNoteOn()) | |||||
| { | |||||
| e.type = Steinberg::Vst::Event::kNoteOnEvent; | |||||
| e.noteOn.channel = createSafeChannel (msg.getChannel()); | |||||
| e.noteOn.pitch = createSafeNote (msg.getNoteNumber()); | |||||
| e.noteOn.velocity = normaliseMidiValue (msg.getVelocity()); | |||||
| e.noteOn.length = 0; | |||||
| e.noteOn.tuning = 0.0f; | |||||
| e.noteOn.noteId = -1; | |||||
| } | |||||
| else if (msg.isNoteOff()) | |||||
| { | |||||
| e.type = Steinberg::Vst::Event::kNoteOffEvent; | |||||
| e.noteOff.channel = createSafeChannel (msg.getChannel()); | |||||
| e.noteOff.pitch = createSafeNote (msg.getNoteNumber()); | |||||
| e.noteOff.velocity = normaliseMidiValue (msg.getVelocity()); | |||||
| e.noteOff.tuning = 0.0f; | |||||
| e.noteOff.noteId = -1; | |||||
| } | |||||
| else if (msg.isSysEx()) | |||||
| { | |||||
| e.type = Steinberg::Vst::Event::kDataEvent; | |||||
| e.data.bytes = msg.getSysExData(); | |||||
| e.data.size = msg.getSysExDataSize(); | |||||
| e.data.type = Steinberg::Vst::DataEvent::kMidiSysEx; | |||||
| } | |||||
| else if (msg.isAftertouch()) | |||||
| { | |||||
| e.type = Steinberg::Vst::Event::kPolyPressureEvent; | |||||
| e.polyPressure.channel = createSafeChannel (msg.getChannel()); | |||||
| e.polyPressure.pitch = createSafeNote (msg.getNoteNumber()); | |||||
| e.polyPressure.pressure = normaliseMidiValue (msg.getAfterTouchValue()); | |||||
| } | |||||
| else | |||||
| { | |||||
| continue; | |||||
| } | |||||
| e.busIndex = 0; | |||||
| e.sampleOffset = midiEventPosition; | |||||
| result.addEvent (e); | |||||
| } | |||||
| } | |||||
| private: | |||||
| Array<Steinberg::Vst::Event, CriticalSection> events; | |||||
| Atomic<int> refCount; | |||||
| static Steinberg::int16 createSafeChannel (int channel) noexcept { return (Steinberg::int16) jlimit (0, 15, channel - 1); } | |||||
| static int createSafeChannel (Steinberg::int16 channel) noexcept { return (int) jlimit (1, 16, channel + 1); } | |||||
| static Steinberg::int16 createSafeNote (int note) noexcept { return (Steinberg::int16) jlimit (0, 127, note); } | |||||
| static int createSafeNote (Steinberg::int16 note) noexcept { return jlimit (0, 127, (int) note); } | |||||
| static float normaliseMidiValue (int value) noexcept { return jlimit (0.0f, 1.0f, (float) value / 127.0f); } | |||||
| static int denormaliseToMidiValue (float value) noexcept { return roundToInt (jlimit (0.0f, 127.0f, value * 127.0f)); } | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiEventList) | |||||
| }; | |||||
| //============================================================================== | |||||
| namespace VST3BufferExchange | |||||
| { | |||||
| typedef Array<float*> Bus; | |||||
| typedef Array<Bus> BusMap; | |||||
| /** Assigns a series of AudioSampleBuffer's channels to an AudioBusBuffers' | |||||
| @warning For speed, does not check the channel count and offsets | |||||
| according to the AudioSampleBuffer | |||||
| */ | |||||
| void associateBufferTo (Steinberg::Vst::AudioBusBuffers& vstBuffers, | |||||
| Bus& bus, | |||||
| const AudioSampleBuffer& buffer, | |||||
| int numChannels, int channelStartOffset, | |||||
| int sampleOffset = 0) noexcept | |||||
| { | |||||
| const int channelEnd = numChannels + channelStartOffset; | |||||
| jassert (channelEnd >= 0 && channelEnd <= buffer.getNumChannels()); | |||||
| bus.clearQuick(); | |||||
| for (int i = channelStartOffset; i < channelEnd; ++i) | |||||
| bus.add (buffer.getSampleData (i, sampleOffset)); | |||||
| vstBuffers.channelBuffers32 = bus.getRawDataPointer(); | |||||
| vstBuffers.numChannels = numChannels; | |||||
| vstBuffers.silenceFlags = 0; | |||||
| } | |||||
| static void mapBufferToBusses (Array<Steinberg::Vst::AudioBusBuffers>& result, | |||||
| Steinberg::Vst::IAudioProcessor& processor, | |||||
| BusMap& busMapToUse, | |||||
| bool isInput, int numBusses, | |||||
| AudioSampleBuffer& source) | |||||
| { | |||||
| int channelIndexOffset = 0; | |||||
| for (int i = 0; i < numBusses; ++i) | |||||
| { | |||||
| Steinberg::Vst::SpeakerArrangement arrangement = 0; | |||||
| processor.getBusArrangement (isInput ? Steinberg::Vst::kInput : Steinberg::Vst::kOutput, | |||||
| (Steinberg::int32) i, arrangement); | |||||
| const int numChansForBus = BigInteger ((juce::int64) arrangement).countNumberOfSetBits(); | |||||
| if (i >= result.size()) | |||||
| result.add (Steinberg::Vst::AudioBusBuffers()); | |||||
| if (i >= busMapToUse.size()) | |||||
| busMapToUse.add (Bus()); | |||||
| if (numChansForBus > 0) | |||||
| { | |||||
| associateBufferTo (result.getReference (i), | |||||
| busMapToUse.getReference (i), | |||||
| source, numChansForBus, channelIndexOffset); | |||||
| } | |||||
| channelIndexOffset += numChansForBus; | |||||
| } | |||||
| } | |||||
| } | |||||
| #endif //JUCE_VST3COMMON_H_INCLUDED | |||||
| @@ -0,0 +1,172 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCE library. | |||||
| Copyright (c) 2013 - Raw Material Software Ltd. | |||||
| Permission is granted to use this software under the terms of either: | |||||
| a) the GPL v2 (or any later version) | |||||
| b) the Affero GPL v3 | |||||
| Details of these licenses can be found at: www.gnu.org/licenses | |||||
| JUCE 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. | |||||
| ------------------------------------------------------------------------------ | |||||
| To release a closed-source product which uses JUCE, commercial licenses are | |||||
| available: visit www.juce.com for more information. | |||||
| ============================================================================== | |||||
| */ | |||||
| #ifndef JUCE_VST3HEADER_H_INCLUDED | |||||
| #define JUCE_VST3HEADER_H_INCLUDED | |||||
| #undef Point | |||||
| #undef Component | |||||
| // Wow, those Steinberg guys really don't worry too much about compiler warnings. | |||||
| #if _MSC_VER | |||||
| #pragma warning (disable: 4505) | |||||
| #pragma warning (push, 0) | |||||
| #pragma warning (disable: 4702) | |||||
| #elif __clang__ | |||||
| #pragma clang diagnostic push | |||||
| #pragma clang diagnostic ignored "-Wnon-virtual-dtor" | |||||
| #pragma clang diagnostic ignored "-Wreorder" | |||||
| #pragma clang diagnostic ignored "-Wunsequenced" | |||||
| #pragma clang diagnostic ignored "-Wint-to-pointer-cast" | |||||
| #pragma clang diagnostic ignored "-Wunused-parameter" | |||||
| #pragma clang diagnostic ignored "-Wconversion" | |||||
| #pragma clang diagnostic ignored "-Woverloaded-virtual" | |||||
| #pragma clang diagnostic ignored "-Wshadow" | |||||
| #endif | |||||
| /* These files come with the Steinberg VST3 SDK - to get them, you'll need to | |||||
| visit the Steinberg website and agree to whatever is currently required to | |||||
| get them. | |||||
| Then, you'll need to make sure your include path contains your "VST3 SDK" | |||||
| directory (or whatever you've named it on your machine). The Introjucer has | |||||
| a special box for setting this path. | |||||
| */ | |||||
| #if JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY | |||||
| #include <base/source/fstring.h> | |||||
| #include <pluginterfaces/base/conststringtable.h> | |||||
| #include <pluginterfaces/base/funknown.h> | |||||
| #include <pluginterfaces/base/ipluginbase.h> | |||||
| #include <pluginterfaces/base/ustring.h> | |||||
| #include <pluginterfaces/gui/iplugview.h> | |||||
| #include <pluginterfaces/vst/ivstattributes.h> | |||||
| #include <pluginterfaces/vst/ivstaudioprocessor.h> | |||||
| #include <pluginterfaces/vst/ivstcomponent.h> | |||||
| #include <pluginterfaces/vst/ivstcontextmenu.h> | |||||
| #include <pluginterfaces/vst/ivsteditcontroller.h> | |||||
| #include <pluginterfaces/vst/ivstevents.h> | |||||
| #include <pluginterfaces/vst/ivsthostapplication.h> | |||||
| #include <pluginterfaces/vst/ivstmessage.h> | |||||
| #include <pluginterfaces/vst/ivstmidicontrollers.h> | |||||
| #include <pluginterfaces/vst/ivstparameterchanges.h> | |||||
| #include <pluginterfaces/vst/ivstplugview.h> | |||||
| #include <pluginterfaces/vst/ivstprocesscontext.h> | |||||
| #include <pluginterfaces/vst/vsttypes.h> | |||||
| #include <pluginterfaces/vst/ivstunits.h> | |||||
| #include <public.sdk/source/common/memorystream.h> | |||||
| #else | |||||
| #include <base/source/baseiids.cpp> | |||||
| #include <base/source/fatomic.cpp> | |||||
| #include <base/source/fbuffer.cpp> | |||||
| #include <base/source/fdebug.cpp> | |||||
| #include <base/source/fobject.cpp> | |||||
| #include <base/source/frect.cpp> | |||||
| #include <base/source/fstreamer.cpp> | |||||
| #include <base/source/fstring.cpp> | |||||
| #include <base/source/fthread.cpp> | |||||
| #include <base/source/updatehandler.cpp> | |||||
| #include <pluginterfaces/base/conststringtable.cpp> | |||||
| #include <pluginterfaces/base/funknown.cpp> | |||||
| #include <pluginterfaces/base/ipluginbase.h> | |||||
| #include <pluginterfaces/base/ustring.cpp> | |||||
| #include <pluginterfaces/gui/iplugview.h> | |||||
| #include <public.sdk/source/common/memorystream.cpp> | |||||
| #include <public.sdk/source/common/pluginview.cpp> | |||||
| #include <public.sdk/source/vst/vsteditcontroller.cpp> | |||||
| #include <public.sdk/source/vst/vstbus.cpp> | |||||
| #include <public.sdk/source/vst/vstinitiids.cpp> | |||||
| #include <public.sdk/source/vst/vstcomponent.cpp> | |||||
| #include <public.sdk/source/vst/vstcomponentbase.cpp> | |||||
| #include <public.sdk/source/vst/vstparameters.cpp> | |||||
| #include <public.sdk/source/vst/hosting/hostclasses.cpp> | |||||
| //============================================================================== | |||||
| namespace Steinberg | |||||
| { | |||||
| /** Missing IIDs */ | |||||
| DEF_CLASS_IID (IPluginBase) | |||||
| DEF_CLASS_IID (IPlugView) | |||||
| DEF_CLASS_IID (IPlugFrame) | |||||
| DEF_CLASS_IID (IBStream) | |||||
| DEF_CLASS_IID (ISizeableStream) | |||||
| DEF_CLASS_IID (IPluginFactory) | |||||
| DEF_CLASS_IID (IPluginFactory2) | |||||
| DEF_CLASS_IID (IPluginFactory3) | |||||
| } | |||||
| #endif //JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY | |||||
| #if _MSC_VER | |||||
| #pragma warning (pop) | |||||
| #elif __clang__ | |||||
| #pragma clang diagnostic pop | |||||
| #endif | |||||
| //============================================================================== | |||||
| #undef ASSERT | |||||
| #undef WARNING | |||||
| #undef PRINTSYSERROR | |||||
| #undef DEBUGSTR | |||||
| #undef DBPRT0 | |||||
| #undef DBPRT1 | |||||
| #undef DBPRT2 | |||||
| #undef DBPRT3 | |||||
| #undef DBPRT4 | |||||
| #undef DBPRT5 | |||||
| #undef min | |||||
| #undef max | |||||
| #undef MIN | |||||
| #undef MAX | |||||
| #undef calloc | |||||
| #undef free | |||||
| #undef malloc | |||||
| #undef realloc | |||||
| #undef NEW | |||||
| #undef NEWVEC | |||||
| #undef VERIFY | |||||
| #undef VERIFY_IS | |||||
| #undef VERIFY_NOT | |||||
| #undef META_CREATE_FUNC | |||||
| #undef CLASS_CREATE_FUNC | |||||
| #undef SINGLE_CREATE_FUNC | |||||
| #undef _META_CLASS | |||||
| #undef _META_CLASS_IFACE | |||||
| #undef _META_CLASS_SINGLE | |||||
| #undef META_CLASS | |||||
| #undef META_CLASS_IFACE | |||||
| #undef META_CLASS_SINGLE | |||||
| #undef SINGLETON | |||||
| #undef OBJ_METHODS | |||||
| #undef QUERY_INTERFACE | |||||
| #undef LICENCE_UID | |||||
| #undef DEF_CLASS_IID | |||||
| #undef BEGIN_FACTORY | |||||
| #undef DEF_CLASS | |||||
| #undef DEF_CLASS1 | |||||
| #undef DEF_CLASS2 | |||||
| #undef DEF_CLASS_W | |||||
| #undef END_FACTORY | |||||
| #undef Point | |||||
| #undef Component | |||||
| #endif //JUCE_VST3HEADER_H_INCLUDED | |||||
| @@ -0,0 +1,72 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCE library. | |||||
| Copyright (c) 2013 - Raw Material Software Ltd. | |||||
| Permission is granted to use this software under the terms of either: | |||||
| a) the GPL v2 (or any later version) | |||||
| b) the Affero GPL v3 | |||||
| Details of these licenses can be found at: www.gnu.org/licenses | |||||
| JUCE 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. | |||||
| ------------------------------------------------------------------------------ | |||||
| To release a closed-source product which uses JUCE, commercial licenses are | |||||
| available: visit www.juce.com for more information. | |||||
| ============================================================================== | |||||
| */ | |||||
| #ifndef JUCE_VST3PLUGINFORMAT_H_INCLUDED | |||||
| #define JUCE_VST3PLUGINFORMAT_H_INCLUDED | |||||
| #if JUCE_PLUGINHOST_VST3 | |||||
| /** | |||||
| Implements a plugin format for VST3s. | |||||
| */ | |||||
| class JUCE_API VST3PluginFormat : public AudioPluginFormat | |||||
| { | |||||
| public: | |||||
| /** Constructor */ | |||||
| VST3PluginFormat(); | |||||
| /** Destructor */ | |||||
| ~VST3PluginFormat(); | |||||
| //============================================================================== | |||||
| /** @internal */ | |||||
| String getName() const override { return "VST3"; } | |||||
| /** @internal */ | |||||
| void findAllTypesForFile (OwnedArray<PluginDescription>& results, const String& fileOrIdentifier) override; | |||||
| /** @internal */ | |||||
| AudioPluginInstance* createInstanceFromDescription (const PluginDescription& description, double, int) override; | |||||
| /** @internal */ | |||||
| bool fileMightContainThisPluginType (const String& fileOrIdentifier) override; | |||||
| /** @internal */ | |||||
| String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) override; | |||||
| /** @internal */ | |||||
| bool pluginNeedsRescanning (const PluginDescription& description) override; | |||||
| /** @internal */ | |||||
| StringArray searchPathsForPlugins (const FileSearchPath& searchPath, bool recursive) override; | |||||
| /** @internal */ | |||||
| bool doesPluginStillExist (const PluginDescription& description) override; | |||||
| /** @internal */ | |||||
| FileSearchPath getDefaultLocationsToSearch() override; | |||||
| /** @internal */ | |||||
| bool canScanForPlugins() const override { return true; } | |||||
| private: | |||||
| //============================================================================== | |||||
| void recursiveFileSearch (StringArray&, const File&, bool recursive); | |||||
| //============================================================================== | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VST3PluginFormat) | |||||
| }; | |||||
| #endif // JUCE_PLUGINHOST_VST3 | |||||
| #endif // JUCE_VST3PLUGINFORMAT_H_INCLUDED | |||||
| @@ -22,12 +22,11 @@ | |||||
| ============================================================================== | ============================================================================== | ||||
| */ | */ | ||||
| #ifdef __aeffect__ | |||||
| #ifdef __aeffect__ // NB: this must come first, *before* the header-guard. | |||||
| #ifndef JUCE_VSTMIDIEVENTLIST_H_INCLUDED | #ifndef JUCE_VSTMIDIEVENTLIST_H_INCLUDED | ||||
| #define JUCE_VSTMIDIEVENTLIST_H_INCLUDED | #define JUCE_VSTMIDIEVENTLIST_H_INCLUDED | ||||
| //============================================================================== | //============================================================================== | ||||
| /** Holds a set of VSTMidiEvent objects and makes it easy to add | /** Holds a set of VSTMidiEvent objects and makes it easy to add | ||||
| events to the list. | events to the list. | ||||
| @@ -184,6 +183,5 @@ private: | |||||
| } | } | ||||
| }; | }; | ||||
| #endif // JUCE_VSTMIDIEVENTLIST_H_INCLUDED | #endif // JUCE_VSTMIDIEVENTLIST_H_INCLUDED | ||||
| #endif | #endif | ||||
| @@ -191,11 +191,7 @@ class IdleCallRecursionPreventer | |||||
| { | { | ||||
| public: | public: | ||||
| IdleCallRecursionPreventer() | IdleCallRecursionPreventer() | ||||
| #ifndef JUCE_PLUGIN_HOST_NO_UI | |||||
| : isMessageThread (MessageManager::getInstance()->isThisTheMessageThread()) | : isMessageThread (MessageManager::getInstance()->isThisTheMessageThread()) | ||||
| #else | |||||
| : isMessageThread (false) | |||||
| #endif | |||||
| { | { | ||||
| if (isMessageThread) | if (isMessageThread) | ||||
| ++insideVSTCallback; | ++insideVSTCallback; | ||||
| @@ -241,7 +237,7 @@ static void* NewCFMFromMachO (void* const machofp) noexcept | |||||
| #endif | #endif | ||||
| //============================================================================== | //============================================================================== | ||||
| #if JUCE_LINUX && ! defined(JUCE_PLUGIN_HOST_NO_UI) | |||||
| #if JUCE_LINUX | |||||
| extern Display* display; | extern Display* display; | ||||
| extern XContext windowHandleXContext; | extern XContext windowHandleXContext; | ||||
| @@ -470,7 +466,7 @@ public: | |||||
| if (dllModule != INVALID_HANDLE_VALUE) | if (dllModule != INVALID_HANDLE_VALUE) | ||||
| { | { | ||||
| if (HRSRC res = FindResource (dllModule, MAKEINTRESOURCE (resID), (LPCWSTR)type.toRawUTF8())) | |||||
| if (HRSRC res = FindResource (dllModule, MAKEINTRESOURCE (resID), type.toWideCharPointer())) | |||||
| { | { | ||||
| if (HGLOBAL hGlob = LoadResource (dllModule, res)) | if (HGLOBAL hGlob = LoadResource (dllModule, res)) | ||||
| { | { | ||||
| @@ -714,18 +710,15 @@ static const int defaultVSTBlockSizeValue = 512; | |||||
| //============================================================================== | //============================================================================== | ||||
| //============================================================================== | //============================================================================== | ||||
| #ifndef JUCE_PLUGIN_HOST_NO_UI | |||||
| class VSTPluginInstance : public AudioPluginInstance, | class VSTPluginInstance : public AudioPluginInstance, | ||||
| private Timer, | private Timer, | ||||
| private AsyncUpdater | private AsyncUpdater | ||||
| #else | |||||
| class VSTPluginInstance : public AudioPluginInstance | |||||
| #endif | |||||
| { | { | ||||
| public: | public: | ||||
| VSTPluginInstance (const ModuleHandle::Ptr& module_) | VSTPluginInstance (const ModuleHandle::Ptr& module_) | ||||
| : effect (nullptr), | : effect (nullptr), | ||||
| module (module_), | module (module_), | ||||
| usesCocoaNSView (false), | |||||
| name (module_->pluginName), | name (module_->pluginName), | ||||
| wantsMidiMessages (false), | wantsMidiMessages (false), | ||||
| initialised (false), | initialised (false), | ||||
| @@ -790,10 +783,8 @@ public: | |||||
| UseResFile (module->resFileId); | UseResFile (module->resFileId); | ||||
| #endif | #endif | ||||
| #ifndef JUCE_PLUGIN_HOST_NO_UI | |||||
| // Must delete any editors before deleting the plugin instance! | // Must delete any editors before deleting the plugin instance! | ||||
| jassert (getActiveEditor() == 0); | jassert (getActiveEditor() == 0); | ||||
| #endif | |||||
| _fpreset(); // some dodgy plugs fuck around with this | _fpreset(); // some dodgy plugs fuck around with this | ||||
| @@ -841,7 +832,7 @@ public: | |||||
| if (initialised || effect == nullptr) | if (initialised || effect == nullptr) | ||||
| return; | return; | ||||
| #if JUCE_WINDOWS && ! defined(JUCE_PLUGIN_HOST_NO_UI) | |||||
| #if JUCE_WINDOWS | |||||
| // On Windows it's highly advisable to create your plugins using the message thread, | // On Windows it's highly advisable to create your plugins using the message thread, | ||||
| // because many plugins need a chance to create HWNDs that will get their | // because many plugins need a chance to create HWNDs that will get their | ||||
| // messages delivered by the main message thread, and that's not possible from | // messages delivered by the main message thread, and that's not possible from | ||||
| @@ -849,7 +840,7 @@ public: | |||||
| jassert (MessageManager::getInstance()->isThisTheMessageThread()); | jassert (MessageManager::getInstance()->isThisTheMessageThread()); | ||||
| #endif | #endif | ||||
| JUCE_VST_LOG ("Initialising VST: " + module->pluginName); | |||||
| JUCE_VST_LOG ("Initialising VST: " + module->pluginName + " (" + getVersion() + ")"); | |||||
| initialised = true; | initialised = true; | ||||
| setPlayConfigDetails (effect->numInputs, effect->numOutputs, | setPlayConfigDetails (effect->numInputs, effect->numOutputs, | ||||
| @@ -881,6 +872,10 @@ public: | |||||
| wantsMidiMessages = dispatch (effCanDo, 0, 0, (void*) "receiveVstMidiEvent", 0) > 0; | wantsMidiMessages = dispatch (effCanDo, 0, 0, (void*) "receiveVstMidiEvent", 0) > 0; | ||||
| #if JUCE_MAC && JUCE_SUPPORT_CARBON | |||||
| usesCocoaNSView = (dispatch (effCanDo, 0, 0, (void*) "hasCockosViewAsConfig", 0) & 0xffff0000) == 0xbeef0000; | |||||
| #endif | |||||
| setLatencySamples (effect->initialDelay); | setLatencySamples (effect->initialDelay); | ||||
| } | } | ||||
| @@ -1098,9 +1093,7 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| bool hasEditor() const override { return effect != nullptr && (effect->flags & effFlagsHasEditor) != 0; } | bool hasEditor() const override { return effect != nullptr && (effect->flags & effFlagsHasEditor) != 0; } | ||||
| #ifndef JUCE_PLUGIN_HOST_NO_UI | |||||
| AudioProcessorEditor* createEditor() override; | AudioProcessorEditor* createEditor() override; | ||||
| #endif | |||||
| //============================================================================== | //============================================================================== | ||||
| const String getInputChannelName (int index) const override | const String getInputChannelName (int index) const override | ||||
| @@ -1249,7 +1242,6 @@ public: | |||||
| void setCurrentProgramStateInformation (const void* data, int size) override { loadFromFXBFile (data, size); } | void setCurrentProgramStateInformation (const void* data, int size) override { loadFromFXBFile (data, size); } | ||||
| //============================================================================== | //============================================================================== | ||||
| #ifndef JUCE_PLUGIN_HOST_NO_UI | |||||
| void timerCallback() override | void timerCallback() override | ||||
| { | { | ||||
| if (dispatch (effIdle, 0, 0, 0, 0) == 0) | if (dispatch (effIdle, 0, 0, 0, 0) == 0) | ||||
| @@ -1261,7 +1253,6 @@ public: | |||||
| // indicates that something about the plugin has changed.. | // indicates that something about the plugin has changed.. | ||||
| updateHostDisplay(); | updateHostDisplay(); | ||||
| } | } | ||||
| #endif | |||||
| VstIntPtr handleCallback (VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt) | VstIntPtr handleCallback (VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt) | ||||
| { | { | ||||
| @@ -1279,7 +1270,6 @@ public: | |||||
| #pragma warning (pop) | #pragma warning (pop) | ||||
| #endif | #endif | ||||
| #ifndef JUCE_PLUGIN_HOST_NO_UI | |||||
| case audioMasterIdle: | case audioMasterIdle: | ||||
| if (insideVSTCallback == 0 && MessageManager::getInstance()->isThisTheMessageThread()) | if (insideVSTCallback == 0 && MessageManager::getInstance()->isThisTheMessageThread()) | ||||
| { | { | ||||
| @@ -1308,7 +1298,6 @@ public: | |||||
| case audioMasterUpdateDisplay: triggerAsyncUpdate(); break; | case audioMasterUpdateDisplay: triggerAsyncUpdate(); break; | ||||
| case audioMasterIOChanged: setLatencySamples (effect->initialDelay); break; | case audioMasterIOChanged: setLatencySamples (effect->initialDelay); break; | ||||
| case audioMasterNeedIdle: startTimer (50); break; | case audioMasterNeedIdle: startTimer (50); break; | ||||
| #endif | |||||
| case audioMasterGetSampleRate: return (VstIntPtr) (getSampleRate() > 0 ? getSampleRate() : defaultVSTSampleRateValue); | case audioMasterGetSampleRate: return (VstIntPtr) (getSampleRate() > 0 ? getSampleRate() : defaultVSTSampleRateValue); | ||||
| case audioMasterGetBlockSize: return (VstIntPtr) (getBlockSize() > 0 ? getBlockSize() : defaultVSTBlockSizeValue); | case audioMasterGetBlockSize: return (VstIntPtr) (getBlockSize() > 0 ? getBlockSize() : defaultVSTBlockSizeValue); | ||||
| @@ -1394,12 +1383,10 @@ public: | |||||
| case audioMasterGetVendorString: | case audioMasterGetVendorString: | ||||
| case audioMasterGetProductString: | case audioMasterGetProductString: | ||||
| { | { | ||||
| String hostName ("Carla"); | |||||
| String hostName ("Juce VST Host"); | |||||
| #ifndef JUCE_PLUGIN_HOST_NO_UI | |||||
| if (JUCEApplicationBase* app = JUCEApplicationBase::getInstance()) | if (JUCEApplicationBase* app = JUCEApplicationBase::getInstance()) | ||||
| hostName = app->getApplicationName(); | hostName = app->getApplicationName(); | ||||
| #endif | |||||
| hostName.copyToUTF8 ((char*) ptr, (size_t) jmin (kVstMaxVendorStrLen, kVstMaxProductStrLen) - 1); | hostName.copyToUTF8 ((char*) ptr, (size_t) jmin (kVstMaxVendorStrLen, kVstMaxProductStrLen) - 1); | ||||
| break; | break; | ||||
| @@ -1677,6 +1664,7 @@ public: | |||||
| ModuleHandle::Ptr module; | ModuleHandle::Ptr module; | ||||
| ScopedPointer<VSTPluginFormat::ExtraFunctions> extraFunctions; | ScopedPointer<VSTPluginFormat::ExtraFunctions> extraFunctions; | ||||
| bool usesCocoaNSView; | |||||
| private: | private: | ||||
| String name; | String name; | ||||
| @@ -1849,17 +1837,22 @@ private: | |||||
| int versionBits[32]; | int versionBits[32]; | ||||
| int n = 0; | int n = 0; | ||||
| while (v != 0) | |||||
| for (int vv = v; vv != 0; vv /= 10) | |||||
| versionBits [n++] = vv % 10; | |||||
| if (n > 4) // if the number ends up silly, it's probably encoded as hex instead of decimal.. | |||||
| { | { | ||||
| versionBits [n++] = v % 10; | |||||
| v /= 10; | |||||
| } | |||||
| n = 0; | |||||
| s << 'V'; | |||||
| for (int vv = v; vv != 0; vv >>= 8) | |||||
| versionBits [n++] = vv & 255; | |||||
| } | |||||
| while (n > 1 && versionBits [n - 1] == 0) | while (n > 1 && versionBits [n - 1] == 0) | ||||
| --n; | --n; | ||||
| s << 'V'; | |||||
| while (n > 0) | while (n > 0) | ||||
| { | { | ||||
| s << versionBits [--n]; | s << versionBits [--n]; | ||||
| @@ -1900,7 +1893,6 @@ private: | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VSTPluginInstance) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VSTPluginInstance) | ||||
| }; | }; | ||||
| #ifndef JUCE_PLUGIN_HOST_NO_UI | |||||
| //============================================================================== | //============================================================================== | ||||
| static Array <VSTPluginWindow*> activeVSTWindows; | static Array <VSTPluginWindow*> activeVSTWindows; | ||||
| @@ -1912,7 +1904,6 @@ class VSTPluginWindow : public AudioProcessorEditor, | |||||
| public Timer | public Timer | ||||
| { | { | ||||
| public: | public: | ||||
| //============================================================================== | |||||
| VSTPluginWindow (VSTPluginInstance& plug) | VSTPluginWindow (VSTPluginInstance& plug) | ||||
| : AudioProcessorEditor (&plug), | : AudioProcessorEditor (&plug), | ||||
| #if ! JUCE_MAC | #if ! JUCE_MAC | ||||
| @@ -1926,18 +1917,27 @@ public: | |||||
| alreadyInside (false) | alreadyInside (false) | ||||
| { | { | ||||
| #if JUCE_WINDOWS | #if JUCE_WINDOWS | ||||
| sizeCheckCount = 0; | |||||
| pluginHWND = 0; | pluginHWND = 0; | ||||
| sizeCheckCount = 0; | |||||
| #elif JUCE_LINUX | #elif JUCE_LINUX | ||||
| pluginWindow = None; | pluginWindow = None; | ||||
| pluginProc = None; | pluginProc = None; | ||||
| #elif JUCE_MAC && JUCE_SUPPORT_CARBON | |||||
| addAndMakeVisible (innerWrapper = new InnerWrapperComponent (*this)); | |||||
| #elif JUCE_MAC | #elif JUCE_MAC | ||||
| addAndMakeVisible (innerWrapper = new NSViewComponent()); | |||||
| NSView* innerView = [[NSView alloc] init]; | |||||
| innerWrapper->setView (innerView); | |||||
| [innerView release]; | |||||
| #if JUCE_SUPPORT_CARBON | |||||
| if (! plug.usesCocoaNSView) | |||||
| { | |||||
| addAndMakeVisible (carbonWrapper = new CarbonWrapperComponent (*this)); | |||||
| } | |||||
| else | |||||
| #endif | |||||
| { | |||||
| addAndMakeVisible (cocoaWrapper = new AutoResizingNSViewComponent()); | |||||
| NSView* innerView = [[NSView alloc] init]; | |||||
| cocoaWrapper->setView (innerView); | |||||
| [innerView release]; | |||||
| } | |||||
| #endif | #endif | ||||
| activeVSTWindows.add (this); | activeVSTWindows.add (this); | ||||
| @@ -1952,7 +1952,10 @@ public: | |||||
| closePluginWindow(); | closePluginWindow(); | ||||
| #if JUCE_MAC | #if JUCE_MAC | ||||
| innerWrapper = nullptr; | |||||
| #if JUCE_SUPPORT_CARBON | |||||
| carbonWrapper = nullptr; | |||||
| #endif | |||||
| cocoaWrapper = nullptr; | |||||
| #endif | #endif | ||||
| activeVSTWindows.removeFirstMatchingValue (this); | activeVSTWindows.removeFirstMatchingValue (this); | ||||
| @@ -2007,20 +2010,28 @@ public: | |||||
| } | } | ||||
| #endif | #endif | ||||
| #if JUCE_MAC && ! JUCE_SUPPORT_CARBON | |||||
| #if JUCE_MAC | |||||
| void visibilityChanged() override | void visibilityChanged() override | ||||
| { | { | ||||
| if (isVisible()) | |||||
| openPluginWindow(); | |||||
| else | |||||
| closePluginWindow(); | |||||
| if (cocoaWrapper != nullptr) | |||||
| { | |||||
| if (isVisible()) | |||||
| openPluginWindow ((NSView*) cocoaWrapper->getView()); | |||||
| else | |||||
| closePluginWindow(); | |||||
| } | |||||
| } | } | ||||
| void childBoundsChanged (Component*) override | void childBoundsChanged (Component*) override | ||||
| { | { | ||||
| if (innerWrapper != nullptr) | |||||
| setSize (innerWrapper->getWidth(), | |||||
| innerWrapper->getHeight()); | |||||
| if (cocoaWrapper != nullptr) | |||||
| { | |||||
| int w = cocoaWrapper->getWidth(); | |||||
| int h = cocoaWrapper->getHeight(); | |||||
| if (w != getWidth() || h != getHeight()) | |||||
| setSize (w, h); | |||||
| } | |||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -2152,15 +2163,8 @@ private: | |||||
| //============================================================================== | //============================================================================== | ||||
| #if JUCE_MAC | #if JUCE_MAC | ||||
| #if JUCE_SUPPORT_CARBON | |||||
| void openPluginWindow (WindowRef parentWindow) | |||||
| { | |||||
| #else | |||||
| void openPluginWindow() | |||||
| void openPluginWindow (void* parentWindow) | |||||
| { | { | ||||
| NSView* parentWindow = (NSView*) innerWrapper->getView(); | |||||
| #endif | |||||
| if (isOpen || parentWindow == 0) | if (isOpen || parentWindow == 0) | ||||
| return; | return; | ||||
| @@ -2372,9 +2376,9 @@ private: | |||||
| { | { | ||||
| for (int i = activeVSTWindows.size(); --i >= 0;) | for (int i = activeVSTWindows.size(); --i >= 0;) | ||||
| { | { | ||||
| const VSTPluginWindow* const w = activeVSTWindows.getUnchecked (i); | |||||
| Component::SafePointer<VSTPluginWindow> w (activeVSTWindows[i]); | |||||
| if (w->pluginHWND == hW) | |||||
| if (w != nullptr && w->pluginHWND == hW) | |||||
| { | { | ||||
| if (message == WM_CHAR | if (message == WM_CHAR | ||||
| || message == WM_KEYDOWN | || message == WM_KEYDOWN | ||||
| @@ -2387,9 +2391,10 @@ private: | |||||
| message, wParam, lParam); | message, wParam, lParam); | ||||
| } | } | ||||
| return CallWindowProc ((WNDPROC) w->originalWndProc, | |||||
| (HWND) w->pluginHWND, | |||||
| message, wParam, lParam); | |||||
| if (w != nullptr) // (may have been deleted in SendMessage callback) | |||||
| return CallWindowProc ((WNDPROC) w->originalWndProc, | |||||
| (HWND) w->pluginHWND, | |||||
| message, wParam, lParam); | |||||
| } | } | ||||
| } | } | ||||
| @@ -2514,17 +2519,17 @@ private: | |||||
| //============================================================================== | //============================================================================== | ||||
| #if JUCE_MAC | #if JUCE_MAC | ||||
| #if JUCE_SUPPORT_CARBON | #if JUCE_SUPPORT_CARBON | ||||
| class InnerWrapperComponent : public CarbonViewWrapperComponent | |||||
| class CarbonWrapperComponent : public CarbonViewWrapperComponent | |||||
| { | { | ||||
| public: | public: | ||||
| InnerWrapperComponent (VSTPluginWindow& w) | |||||
| CarbonWrapperComponent (VSTPluginWindow& w) | |||||
| : owner (w), alreadyInside (false) | : owner (w), alreadyInside (false) | ||||
| { | { | ||||
| keepPluginWindowWhenHidden = w.shouldAvoidDeletingWindow(); | keepPluginWindowWhenHidden = w.shouldAvoidDeletingWindow(); | ||||
| setRepaintsChildHIViewWhenCreated (w.shouldRepaintCarbonWindowWhenCreated()); | setRepaintsChildHIViewWhenCreated (w.shouldRepaintCarbonWindowWhenCreated()); | ||||
| } | } | ||||
| ~InnerWrapperComponent() | |||||
| ~CarbonWrapperComponent() | |||||
| { | { | ||||
| deleteWindow(); | deleteWindow(); | ||||
| } | } | ||||
| @@ -2588,35 +2593,36 @@ private: | |||||
| VSTPluginWindow& owner; | VSTPluginWindow& owner; | ||||
| bool alreadyInside; | bool alreadyInside; | ||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InnerWrapperComponent) | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CarbonWrapperComponent) | |||||
| }; | }; | ||||
| friend class InnerWrapperComponent; | |||||
| ScopedPointer<InnerWrapperComponent> innerWrapper; | |||||
| #else | |||||
| ScopedPointer<NSViewComponent> innerWrapper; | |||||
| friend class CarbonWrapperComponent; | |||||
| ScopedPointer<CarbonWrapperComponent> carbonWrapper; | |||||
| #endif | #endif | ||||
| ScopedPointer<NSViewComponent> cocoaWrapper; | |||||
| void resized() override | void resized() override | ||||
| { | { | ||||
| if (innerWrapper != nullptr) | |||||
| innerWrapper->setSize (getWidth(), getHeight()); | |||||
| #if JUCE_SUPPORT_CARBON | |||||
| if (carbonWrapper != nullptr) | |||||
| carbonWrapper->setSize (getWidth(), getHeight()); | |||||
| #endif | |||||
| if (cocoaWrapper != nullptr) | |||||
| cocoaWrapper->setSize (getWidth(), getHeight()); | |||||
| } | } | ||||
| #endif | #endif | ||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VSTPluginWindow) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VSTPluginWindow) | ||||
| }; | }; | ||||
| #endif | |||||
| #ifndef JUCE_PLUGIN_HOST_NO_UI | |||||
| //============================================================================== | //============================================================================== | ||||
| AudioProcessorEditor* VSTPluginInstance::createEditor() | AudioProcessorEditor* VSTPluginInstance::createEditor() | ||||
| { | { | ||||
| return hasEditor() ? new VSTPluginWindow (*this) | return hasEditor() ? new VSTPluginWindow (*this) | ||||
| : nullptr; | : nullptr; | ||||
| } | } | ||||
| #endif | |||||
| //============================================================================== | //============================================================================== | ||||
| // entry point for all callbacks from the plugin | // entry point for all callbacks from the plugin | ||||
| @@ -2654,7 +2660,7 @@ static VSTPluginInstance* createAndUpdateDesc (VSTPluginFormat& format, PluginDe | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| void VSTPluginFormat::findAllTypesForFile (OwnedArray <PluginDescription>& results, | |||||
| void VSTPluginFormat::findAllTypesForFile (OwnedArray<PluginDescription>& results, | |||||
| const String& fileOrIdentifier) | const String& fileOrIdentifier) | ||||
| { | { | ||||
| if (! fileMightContainThisPluginType (fileOrIdentifier)) | if (! fileMightContainThisPluginType (fileOrIdentifier)) | ||||
| @@ -2688,14 +2694,17 @@ void VSTPluginFormat::findAllTypesForFile (OwnedArray <PluginDescription>& resul | |||||
| break; | break; | ||||
| desc.uid = uid; | desc.uid = uid; | ||||
| desc.name = shellEffectName; | |||||
| aboutToScanVSTShellPlugin (desc); | |||||
| ScopedPointer<VSTPluginInstance> shellInstance (createAndUpdateDesc (*this, desc)); | ScopedPointer<VSTPluginInstance> shellInstance (createAndUpdateDesc (*this, desc)); | ||||
| if (shellInstance != nullptr) | if (shellInstance != nullptr) | ||||
| { | { | ||||
| jassert (desc.uid == uid); | jassert (desc.uid == uid); | ||||
| desc.name = shellEffectName; | |||||
| desc.hasSharedContainer = true; | desc.hasSharedContainer = true; | ||||
| desc.name = shellEffectName; | |||||
| if (! arrayContainsPlugin (results, desc)) | if (! arrayContainsPlugin (results, desc)) | ||||
| results.add (new PluginDescription (desc)); | results.add (new PluginDescription (desc)); | ||||
| @@ -2741,7 +2750,7 @@ AudioPluginInstance* VSTPluginFormat::createInstanceFromDescription (const Plugi | |||||
| bool VSTPluginFormat::fileMightContainThisPluginType (const String& fileOrIdentifier) | bool VSTPluginFormat::fileMightContainThisPluginType (const String& fileOrIdentifier) | ||||
| { | { | ||||
| const File f (fileOrIdentifier); | |||||
| const File f (File::createFileWithoutCheckingPath (fileOrIdentifier)); | |||||
| #if JUCE_MAC | #if JUCE_MAC | ||||
| if (f.isDirectory() && f.hasFileExtension (".vst")) | if (f.isDirectory() && f.hasFileExtension (".vst")) | ||||
| @@ -2898,4 +2907,6 @@ VSTPluginFormat::VstIntPtr JUCE_CALLTYPE VSTPluginFormat::dispatcher (AudioPlugi | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| void VSTPluginFormat::aboutToScanVSTShellPlugin (const PluginDescription&) {} | |||||
| #endif | #endif | ||||
| @@ -96,6 +96,13 @@ public: | |||||
| FileSearchPath getDefaultLocationsToSearch() override; | FileSearchPath getDefaultLocationsToSearch() override; | ||||
| bool canScanForPlugins() const override { return true; } | bool canScanForPlugins() const override { return true; } | ||||
| /** Can be overridden to receive a callback when each member of a shell plugin is about to be | |||||
| tested during a call to findAllTypesForFile(). | |||||
| Only the name and uid members of the PluginDescription are guaranteed to be valid when | |||||
| this is called. | |||||
| */ | |||||
| virtual void aboutToScanVSTShellPlugin (const PluginDescription&); | |||||
| private: | private: | ||||
| void recursiveFileSearch (StringArray&, const File&, bool recursive); | void recursiveFileSearch (StringArray&, const File&, bool recursive); | ||||
| @@ -37,7 +37,7 @@ | |||||
| #include "../juce_core/native/juce_BasicNativeHeaders.h" | #include "../juce_core/native/juce_BasicNativeHeaders.h" | ||||
| #include "juce_audio_processors.h" | #include "juce_audio_processors.h" | ||||
| //#include "../juce_gui_extra/juce_gui_extra.h" | |||||
| #include "../juce_gui_extra/juce_gui_extra.h" | |||||
| //============================================================================== | //============================================================================== | ||||
| #if JUCE_MAC | #if JUCE_MAC | ||||
| @@ -71,6 +71,36 @@ static inline bool arrayContainsPlugin (const OwnedArray<PluginDescription>& lis | |||||
| return false; | return false; | ||||
| } | } | ||||
| #if JUCE_MAC | |||||
| struct AutoResizingNSViewComponent : public NSViewComponent, | |||||
| private AsyncUpdater | |||||
| { | |||||
| AutoResizingNSViewComponent() : recursive (false) {} | |||||
| void childBoundsChanged (Component*) override | |||||
| { | |||||
| if (recursive) | |||||
| { | |||||
| triggerAsyncUpdate(); | |||||
| } | |||||
| else | |||||
| { | |||||
| recursive = true; | |||||
| resizeToFitView(); | |||||
| recursive = true; | |||||
| } | |||||
| } | |||||
| void handleAsyncUpdate() override { resizeToFitView(); } | |||||
| bool recursive; | |||||
| }; | |||||
| #endif | |||||
| #if JUCE_CLANG | |||||
| #pragma clang diagnostic ignored "-Wdeprecated-declarations" | |||||
| #endif | |||||
| #include "format/juce_AudioPluginFormat.cpp" | #include "format/juce_AudioPluginFormat.cpp" | ||||
| #include "format/juce_AudioPluginFormatManager.cpp" | #include "format/juce_AudioPluginFormatManager.cpp" | ||||
| #include "processors/juce_AudioProcessor.cpp" | #include "processors/juce_AudioProcessor.cpp" | ||||
| @@ -80,6 +110,7 @@ static inline bool arrayContainsPlugin (const OwnedArray<PluginDescription>& lis | |||||
| #include "processors/juce_PluginDescription.cpp" | #include "processors/juce_PluginDescription.cpp" | ||||
| #include "format_types/juce_LADSPAPluginFormat.cpp" | #include "format_types/juce_LADSPAPluginFormat.cpp" | ||||
| #include "format_types/juce_VSTPluginFormat.cpp" | #include "format_types/juce_VSTPluginFormat.cpp" | ||||
| #include "format_types/juce_VST3PluginFormat.cpp" | |||||
| #include "format_types/juce_AudioUnitPluginFormat.mm" | #include "format_types/juce_AudioUnitPluginFormat.mm" | ||||
| #include "scanning/juce_KnownPluginList.cpp" | #include "scanning/juce_KnownPluginList.cpp" | ||||
| #include "scanning/juce_PluginDirectoryScanner.cpp" | #include "scanning/juce_PluginDirectoryScanner.cpp" | ||||
| @@ -34,22 +34,32 @@ | |||||
| Enables the VST audio plugin hosting classes. This requires the Steinberg VST SDK to be | Enables the VST audio plugin hosting classes. This requires the Steinberg VST SDK to be | ||||
| installed on your machine. | installed on your machine. | ||||
| @see VSTPluginFormat, AudioPluginFormat, AudioPluginFormatManager, JUCE_PLUGINHOST_AU | |||||
| @see VSTPluginFormat, VST3PluginFormat, AudioPluginFormat, AudioPluginFormatManager, JUCE_PLUGINHOST_AU, JUCE_PLUGINHOST_VST3 | |||||
| */ | */ | ||||
| #ifndef JUCE_PLUGINHOST_VST | #ifndef JUCE_PLUGINHOST_VST | ||||
| #define JUCE_PLUGINHOST_VST 0 | #define JUCE_PLUGINHOST_VST 0 | ||||
| #endif | #endif | ||||
| /** Config: JUCE_PLUGINHOST_VST3 | |||||
| Enables the VST3 audio plugin hosting classes. This requires the Steinberg VST3 SDK to be | |||||
| installed on your machine. | |||||
| @see VSTPluginFormat, VVST3PluginFormat, AudioPluginFormat, AudioPluginFormatManager, JUCE_PLUGINHOST_VST, JUCE_PLUGINHOST_AU | |||||
| */ | |||||
| #ifndef JUCE_PLUGINHOST_VST3 | |||||
| #define JUCE_PLUGINHOST_VST3 0 | |||||
| #endif | |||||
| /** Config: JUCE_PLUGINHOST_AU | /** Config: JUCE_PLUGINHOST_AU | ||||
| Enables the AudioUnit plugin hosting classes. This is Mac-only, of course. | Enables the AudioUnit plugin hosting classes. This is Mac-only, of course. | ||||
| @see AudioUnitPluginFormat, AudioPluginFormat, AudioPluginFormatManager, JUCE_PLUGINHOST_VST | |||||
| @see AudioUnitPluginFormat, AudioPluginFormat, AudioPluginFormatManager, JUCE_PLUGINHOST_VST, JUCE_PLUGINHOST_VST3 | |||||
| */ | */ | ||||
| #ifndef JUCE_PLUGINHOST_AU | #ifndef JUCE_PLUGINHOST_AU | ||||
| #define JUCE_PLUGINHOST_AU 0 | #define JUCE_PLUGINHOST_AU 0 | ||||
| #endif | #endif | ||||
| #if ! (JUCE_PLUGINHOST_AU || JUCE_PLUGINHOST_VST) | |||||
| #if ! (JUCE_PLUGINHOST_AU || JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_VST3) | |||||
| // #error "You need to set either the JUCE_PLUGINHOST_AU anr/or JUCE_PLUGINHOST_VST flags if you're using this module!" | // #error "You need to set either the JUCE_PLUGINHOST_AU anr/or JUCE_PLUGINHOST_VST flags if you're using this module!" | ||||
| #endif | #endif | ||||
| @@ -78,6 +88,7 @@ class AudioProcessor; | |||||
| #include "format_types/juce_LADSPAPluginFormat.h" | #include "format_types/juce_LADSPAPluginFormat.h" | ||||
| #include "format_types/juce_VSTMidiEventList.h" | #include "format_types/juce_VSTMidiEventList.h" | ||||
| #include "format_types/juce_VSTPluginFormat.h" | #include "format_types/juce_VSTPluginFormat.h" | ||||
| #include "format_types/juce_VST3PluginFormat.h" | |||||
| #include "scanning/juce_PluginDirectoryScanner.h" | #include "scanning/juce_PluginDirectoryScanner.h" | ||||
| #include "scanning/juce_PluginListComponent.h" | #include "scanning/juce_PluginListComponent.h" | ||||
| @@ -44,11 +44,9 @@ AudioProcessor::AudioProcessor() | |||||
| AudioProcessor::~AudioProcessor() | AudioProcessor::~AudioProcessor() | ||||
| { | { | ||||
| #ifndef JUCE_PLUGIN_HOST_NO_UI | |||||
| // ooh, nasty - the editor should have been deleted before the filter | // ooh, nasty - the editor should have been deleted before the filter | ||||
| // that it refers to is deleted.. | // that it refers to is deleted.. | ||||
| jassert (activeEditor == nullptr); | jassert (activeEditor == nullptr); | ||||
| #endif | |||||
| #if JUCE_DEBUG | #if JUCE_DEBUG | ||||
| // This will fail if you've called beginParameterChangeGesture() for one | // This will fail if you've called beginParameterChangeGesture() for one | ||||
| @@ -203,7 +201,7 @@ void AudioProcessor::updateHostDisplay() | |||||
| l->audioProcessorChanged (this); | l->audioProcessorChanged (this); | ||||
| } | } | ||||
| String AudioProcessor::getParameterLabel (int) const { return String::empty; } | |||||
| String AudioProcessor::getParameterLabel (int) const { return String(); } | |||||
| bool AudioProcessor::isParameterAutomatable (int) const { return true; } | bool AudioProcessor::isParameterAutomatable (int) const { return true; } | ||||
| bool AudioProcessor::isMetaParameter (int) const { return false; } | bool AudioProcessor::isMetaParameter (int) const { return false; } | ||||
| @@ -216,7 +214,6 @@ void AudioProcessor::suspendProcessing (const bool shouldBeSuspended) | |||||
| void AudioProcessor::reset() {} | void AudioProcessor::reset() {} | ||||
| void AudioProcessor::processBlockBypassed (AudioSampleBuffer&, MidiBuffer&) {} | void AudioProcessor::processBlockBypassed (AudioSampleBuffer&, MidiBuffer&) {} | ||||
| #ifndef JUCE_PLUGIN_HOST_NO_UI | |||||
| //============================================================================== | //============================================================================== | ||||
| void AudioProcessor::editorBeingDeleted (AudioProcessorEditor* const editor) noexcept | void AudioProcessor::editorBeingDeleted (AudioProcessorEditor* const editor) noexcept | ||||
| { | { | ||||
| @@ -247,7 +244,6 @@ AudioProcessorEditor* AudioProcessor::createEditorIfNeeded() | |||||
| return ed; | return ed; | ||||
| } | } | ||||
| #endif | |||||
| //============================================================================== | //============================================================================== | ||||
| void AudioProcessor::getCurrentProgramStateInformation (juce::MemoryBlock& destData) | void AudioProcessor::getCurrentProgramStateInformation (juce::MemoryBlock& destData) | ||||
| @@ -270,7 +266,7 @@ void AudioProcessor::copyXmlToBinary (const XmlElement& xml, juce::MemoryBlock& | |||||
| MemoryOutputStream out (destData, false); | MemoryOutputStream out (destData, false); | ||||
| out.writeInt (magicXmlNumber); | out.writeInt (magicXmlNumber); | ||||
| out.writeInt (0); | out.writeInt (0); | ||||
| xml.writeToStream (out, String::empty, true, false); | |||||
| xml.writeToStream (out, String(), true, false); | |||||
| out.writeByte (0); | out.writeByte (0); | ||||
| } | } | ||||
| @@ -331,7 +331,6 @@ public: | |||||
| */ | */ | ||||
| void setNonRealtime (bool isNonRealtime) noexcept; | void setNonRealtime (bool isNonRealtime) noexcept; | ||||
| #ifndef JUCE_PLUGIN_HOST_NO_UI | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Creates the filter's UI. | /** Creates the filter's UI. | ||||
| @@ -361,14 +360,12 @@ public: | |||||
| @see hasEditor | @see hasEditor | ||||
| */ | */ | ||||
| virtual AudioProcessorEditor* createEditor() = 0; | virtual AudioProcessorEditor* createEditor() = 0; | ||||
| #endif | |||||
| /** Your filter must override this and return true if it can create an editor component. | /** Your filter must override this and return true if it can create an editor component. | ||||
| @see createEditor | @see createEditor | ||||
| */ | */ | ||||
| virtual bool hasEditor() const = 0; | virtual bool hasEditor() const = 0; | ||||
| #ifndef JUCE_PLUGIN_HOST_NO_UI | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns the active editor, if there is one. | /** Returns the active editor, if there is one. | ||||
| Bear in mind this can return nullptr, even if an editor has previously been opened. | Bear in mind this can return nullptr, even if an editor has previously been opened. | ||||
| @@ -379,7 +376,6 @@ public: | |||||
| This may call createEditor() internally to create the component. | This may call createEditor() internally to create the component. | ||||
| */ | */ | ||||
| AudioProcessorEditor* createEditorIfNeeded(); | AudioProcessorEditor* createEditorIfNeeded(); | ||||
| #endif | |||||
| //============================================================================== | //============================================================================== | ||||
| /** This must return the correct value immediately after the object has been | /** This must return the correct value immediately after the object has been | ||||
| @@ -586,7 +582,7 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| /** LV2 specific calls, saving/restore as string. */ | /** LV2 specific calls, saving/restore as string. */ | ||||
| virtual String getStateInformationString () { return String::empty; } | virtual String getStateInformationString () { return String::empty; } | ||||
| virtual void setStateInformationString (const String&) {} | |||||
| virtual void setStateInformationString (const String& data) {} | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Adds a listener that will be called when an aspect of this processor changes. */ | /** Adds a listener that will be called when an aspect of this processor changes. */ | ||||
| @@ -606,11 +602,9 @@ public: | |||||
| /** This is called by the processor to specify its details before being played. */ | /** This is called by the processor to specify its details before being played. */ | ||||
| void setPlayConfigDetails (int numIns, int numOuts, double sampleRate, int blockSize) noexcept; | void setPlayConfigDetails (int numIns, int numOuts, double sampleRate, int blockSize) noexcept; | ||||
| #ifndef JUCE_PLUGIN_HOST_NO_UI | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Not for public use - this is called before deleting an editor component. */ | /** Not for public use - this is called before deleting an editor component. */ | ||||
| void editorBeingDeleted (AudioProcessorEditor*) noexcept; | void editorBeingDeleted (AudioProcessorEditor*) noexcept; | ||||
| #endif | |||||
| /** Not for public use - this is called to initialise the processor before playing. */ | /** Not for public use - this is called to initialise the processor before playing. */ | ||||
| void setSpeakerArrangement (const String& inputs, const String& outputs); | void setSpeakerArrangement (const String& inputs, const String& outputs); | ||||
| @@ -662,9 +656,7 @@ protected: | |||||
| private: | private: | ||||
| Array<AudioProcessorListener*> listeners; | Array<AudioProcessorListener*> listeners; | ||||
| #ifndef JUCE_PLUGIN_HOST_NO_UI | |||||
| Component::SafePointer<AudioProcessorEditor> activeEditor; | Component::SafePointer<AudioProcessorEditor> activeEditor; | ||||
| #endif | |||||
| double sampleRate; | double sampleRate; | ||||
| int blockSize, numInputChannels, numOutputChannels, latencySamples; | int blockSize, numInputChannels, numOutputChannels, latencySamples; | ||||
| bool suspended, nonRealtime; | bool suspended, nonRealtime; | ||||
| @@ -1367,7 +1367,7 @@ const String AudioProcessorGraph::AudioGraphIOProcessor::getName() const | |||||
| default: break; | default: break; | ||||
| } | } | ||||
| return String::empty; | |||||
| return String(); | |||||
| } | } | ||||
| void AudioProcessorGraph::AudioGraphIOProcessor::fillInPluginDescription (PluginDescription& d) const | void AudioProcessorGraph::AudioGraphIOProcessor::fillInPluginDescription (PluginDescription& d) const | ||||
| @@ -1469,7 +1469,7 @@ const String AudioProcessorGraph::AudioGraphIOProcessor::getInputChannelName (in | |||||
| default: break; | default: break; | ||||
| } | } | ||||
| return String::empty; | |||||
| return String(); | |||||
| } | } | ||||
| const String AudioProcessorGraph::AudioGraphIOProcessor::getOutputChannelName (int channelIndex) const | const String AudioProcessorGraph::AudioGraphIOProcessor::getOutputChannelName (int channelIndex) const | ||||
| @@ -1481,7 +1481,7 @@ const String AudioProcessorGraph::AudioGraphIOProcessor::getOutputChannelName (i | |||||
| default: break; | default: break; | ||||
| } | } | ||||
| return String::empty; | |||||
| return String(); | |||||
| } | } | ||||
| bool AudioProcessorGraph::AudioGraphIOProcessor::isInputChannelStereoPair (int /*index*/) const | bool AudioProcessorGraph::AudioGraphIOProcessor::isInputChannelStereoPair (int /*index*/) const | ||||
| @@ -1501,17 +1501,17 @@ bool AudioProcessorGraph::AudioGraphIOProcessor::hasEditor() const | |||||
| AudioProcessorEditor* AudioProcessorGraph::AudioGraphIOProcessor::createEditor() { return nullptr; } | AudioProcessorEditor* AudioProcessorGraph::AudioGraphIOProcessor::createEditor() { return nullptr; } | ||||
| int AudioProcessorGraph::AudioGraphIOProcessor::getNumParameters() { return 0; } | int AudioProcessorGraph::AudioGraphIOProcessor::getNumParameters() { return 0; } | ||||
| const String AudioProcessorGraph::AudioGraphIOProcessor::getParameterName (int) { return String::empty; } | |||||
| const String AudioProcessorGraph::AudioGraphIOProcessor::getParameterName (int) { return String(); } | |||||
| float AudioProcessorGraph::AudioGraphIOProcessor::getParameter (int) { return 0.0f; } | float AudioProcessorGraph::AudioGraphIOProcessor::getParameter (int) { return 0.0f; } | ||||
| const String AudioProcessorGraph::AudioGraphIOProcessor::getParameterText (int) { return String::empty; } | |||||
| const String AudioProcessorGraph::AudioGraphIOProcessor::getParameterText (int) { return String(); } | |||||
| void AudioProcessorGraph::AudioGraphIOProcessor::setParameter (int, float) { } | void AudioProcessorGraph::AudioGraphIOProcessor::setParameter (int, float) { } | ||||
| int AudioProcessorGraph::AudioGraphIOProcessor::getNumPrograms() { return 0; } | int AudioProcessorGraph::AudioGraphIOProcessor::getNumPrograms() { return 0; } | ||||
| int AudioProcessorGraph::AudioGraphIOProcessor::getCurrentProgram() { return 0; } | int AudioProcessorGraph::AudioGraphIOProcessor::getCurrentProgram() { return 0; } | ||||
| void AudioProcessorGraph::AudioGraphIOProcessor::setCurrentProgram (int) { } | void AudioProcessorGraph::AudioGraphIOProcessor::setCurrentProgram (int) { } | ||||
| const String AudioProcessorGraph::AudioGraphIOProcessor::getProgramName (int) { return String::empty; } | |||||
| const String AudioProcessorGraph::AudioGraphIOProcessor::getProgramName (int) { return String(); } | |||||
| void AudioProcessorGraph::AudioGraphIOProcessor::changeProgramName (int, const String&) {} | void AudioProcessorGraph::AudioGraphIOProcessor::changeProgramName (int, const String&) {} | ||||
| void AudioProcessorGraph::AudioGraphIOProcessor::getStateInformation (juce::MemoryBlock&) {} | void AudioProcessorGraph::AudioGraphIOProcessor::getStateInformation (juce::MemoryBlock&) {} | ||||
| @@ -372,15 +372,15 @@ public: | |||||
| AudioProcessorEditor* createEditor() { return nullptr; } | AudioProcessorEditor* createEditor() { return nullptr; } | ||||
| int getNumParameters() { return 0; } | int getNumParameters() { return 0; } | ||||
| const String getParameterName (int) { return String::empty; } | |||||
| const String getParameterName (int) { return String(); } | |||||
| float getParameter (int) { return 0; } | float getParameter (int) { return 0; } | ||||
| const String getParameterText (int) { return String::empty; } | |||||
| const String getParameterText (int) { return String(); } | |||||
| void setParameter (int, float) { } | void setParameter (int, float) { } | ||||
| int getNumPrograms() { return 0; } | int getNumPrograms() { return 0; } | ||||
| int getCurrentProgram() { return 0; } | int getCurrentProgram() { return 0; } | ||||
| void setCurrentProgram (int) { } | void setCurrentProgram (int) { } | ||||
| const String getProgramName (int) { return String::empty; } | |||||
| const String getProgramName (int) { return String(); } | |||||
| void changeProgramName (int, const String&) { } | void changeProgramName (int, const String&) { } | ||||
| void getStateInformation (juce::MemoryBlock&); | void getStateInformation (juce::MemoryBlock&); | ||||
| @@ -35,7 +35,7 @@ public: | |||||
| slider (p, index_) | slider (p, index_) | ||||
| { | { | ||||
| startTimer (100); | startTimer (100); | ||||
| addAndMakeVisible (&slider); | |||||
| addAndMakeVisible (slider); | |||||
| owner.addListener (this); | owner.addListener (this); | ||||
| } | } | ||||
| @@ -123,7 +123,7 @@ GenericAudioProcessorEditor::GenericAudioProcessorEditor (AudioProcessor* const | |||||
| jassert (p != nullptr); | jassert (p != nullptr); | ||||
| setOpaque (true); | setOpaque (true); | ||||
| addAndMakeVisible (&panel); | |||||
| addAndMakeVisible (panel); | |||||
| Array <PropertyComponent*> params; | Array <PropertyComponent*> params; | ||||
| @@ -241,7 +241,8 @@ void KnownPluginList::clearBlacklistedFiles() | |||||
| //============================================================================== | //============================================================================== | ||||
| struct PluginSorter | struct PluginSorter | ||||
| { | { | ||||
| PluginSorter (KnownPluginList::SortMethod sortMethod) noexcept : method (sortMethod) {} | |||||
| PluginSorter (KnownPluginList::SortMethod sortMethod, bool forwards) noexcept | |||||
| : method (sortMethod), direction (forwards ? 1 : -1) {} | |||||
| int compareElements (const PluginDescription* const first, | int compareElements (const PluginDescription* const first, | ||||
| const PluginDescription* const second) const | const PluginDescription* const second) const | ||||
| @@ -252,6 +253,7 @@ struct PluginSorter | |||||
| { | { | ||||
| case KnownPluginList::sortByCategory: diff = first->category.compareLexicographically (second->category); break; | case KnownPluginList::sortByCategory: diff = first->category.compareLexicographically (second->category); break; | ||||
| case KnownPluginList::sortByManufacturer: diff = first->manufacturerName.compareLexicographically (second->manufacturerName); break; | case KnownPluginList::sortByManufacturer: diff = first->manufacturerName.compareLexicographically (second->manufacturerName); break; | ||||
| case KnownPluginList::sortByFormat: diff = first->pluginFormatName.compare (second->pluginFormatName); break; | |||||
| case KnownPluginList::sortByFileSystemLocation: diff = lastPathPart (first->fileOrIdentifier).compare (lastPathPart (second->fileOrIdentifier)); break; | case KnownPluginList::sortByFileSystemLocation: diff = lastPathPart (first->fileOrIdentifier).compare (lastPathPart (second->fileOrIdentifier)); break; | ||||
| default: break; | default: break; | ||||
| } | } | ||||
| @@ -259,7 +261,7 @@ struct PluginSorter | |||||
| if (diff == 0) | if (diff == 0) | ||||
| diff = first->name.compareLexicographically (second->name); | diff = first->name.compareLexicographically (second->name); | ||||
| return diff; | |||||
| return diff * direction; | |||||
| } | } | ||||
| private: | private: | ||||
| @@ -268,14 +270,17 @@ private: | |||||
| return path.replaceCharacter ('\\', '/').upToLastOccurrenceOf ("/", false, false); | return path.replaceCharacter ('\\', '/').upToLastOccurrenceOf ("/", false, false); | ||||
| } | } | ||||
| KnownPluginList::SortMethod method; | |||||
| const KnownPluginList::SortMethod method; | |||||
| const int direction; | |||||
| JUCE_DECLARE_NON_COPYABLE (PluginSorter) | |||||
| }; | }; | ||||
| void KnownPluginList::sort (const SortMethod method) | |||||
| void KnownPluginList::sort (const SortMethod method, bool forwards) | |||||
| { | { | ||||
| if (method != defaultOrder) | if (method != defaultOrder) | ||||
| { | { | ||||
| PluginSorter sorter (method); | |||||
| PluginSorter sorter (method, forwards); | |||||
| types.sort (sorter, true); | types.sort (sorter, true); | ||||
| sendChangeMessage(); | sendChangeMessage(); | ||||
| @@ -435,6 +440,18 @@ struct PluginTreeUtils | |||||
| } | } | ||||
| } | } | ||||
| static bool containsDuplicateNames (const Array<const PluginDescription*>& plugins, const String& name) | |||||
| { | |||||
| int matches = 0; | |||||
| for (int i = 0; i < plugins.size(); ++i) | |||||
| if (plugins.getUnchecked(i)->name == name) | |||||
| if (++matches > 1) | |||||
| return true; | |||||
| return false; | |||||
| } | |||||
| static void addToMenu (const KnownPluginList::PluginTree& tree, PopupMenu& m, const OwnedArray <PluginDescription>& allPlugins) | static void addToMenu (const KnownPluginList::PluginTree& tree, PopupMenu& m, const OwnedArray <PluginDescription>& allPlugins) | ||||
| { | { | ||||
| for (int i = 0; i < tree.subFolders.size(); ++i) | for (int i = 0; i < tree.subFolders.size(); ++i) | ||||
| @@ -450,7 +467,12 @@ struct PluginTreeUtils | |||||
| { | { | ||||
| const PluginDescription* const plugin = tree.plugins.getUnchecked(i); | const PluginDescription* const plugin = tree.plugins.getUnchecked(i); | ||||
| m.addItem (allPlugins.indexOf (plugin) + menuIdBase, plugin->name, true, false); | |||||
| String name (plugin->name); | |||||
| if (containsDuplicateNames (tree.plugins, name)) | |||||
| name << " (" << plugin->pluginFormatName << ')'; | |||||
| m.addItem (allPlugins.indexOf (plugin) + menuIdBase, name, true, false); | |||||
| } | } | ||||
| } | } | ||||
| }; | }; | ||||
| @@ -460,7 +482,7 @@ KnownPluginList::PluginTree* KnownPluginList::createTree (const SortMethod sortM | |||||
| Array <PluginDescription*> sorted; | Array <PluginDescription*> sorted; | ||||
| { | { | ||||
| PluginSorter sorter (sortMethod); | |||||
| PluginSorter sorter (sortMethod, true); | |||||
| for (int i = 0; i < types.size(); ++i) | for (int i = 0; i < types.size(); ++i) | ||||
| sorted.addSorted (sorter, types.getUnchecked(i)); | sorted.addSorted (sorter, types.getUnchecked(i)); | ||||
| @@ -468,7 +490,7 @@ KnownPluginList::PluginTree* KnownPluginList::createTree (const SortMethod sortM | |||||
| PluginTree* tree = new PluginTree(); | PluginTree* tree = new PluginTree(); | ||||
| if (sortMethod == sortByCategory || sortMethod == sortByManufacturer) | |||||
| if (sortMethod == sortByCategory || sortMethod == sortByManufacturer || sortMethod == sortByFormat) | |||||
| { | { | ||||
| PluginTreeUtils::buildTreeByCategory (*tree, sorted, sortMethod); | PluginTreeUtils::buildTreeByCategory (*tree, sorted, sortMethod); | ||||
| } | } | ||||
| @@ -132,6 +132,7 @@ public: | |||||
| sortAlphabetically, | sortAlphabetically, | ||||
| sortByCategory, | sortByCategory, | ||||
| sortByManufacturer, | sortByManufacturer, | ||||
| sortByFormat, | |||||
| sortByFileSystemLocation | sortByFileSystemLocation | ||||
| }; | }; | ||||
| @@ -143,7 +144,7 @@ public: | |||||
| Use getIndexChosenByMenu() to find out the type that was chosen. | Use getIndexChosenByMenu() to find out the type that was chosen. | ||||
| */ | */ | ||||
| void addToMenu (PopupMenu& menu, const SortMethod sortMethod) const; | |||||
| void addToMenu (PopupMenu& menu, SortMethod sortMethod) const; | |||||
| /** Converts a menu item index that has been chosen into its index in this list. | /** Converts a menu item index that has been chosen into its index in this list. | ||||
| Returns -1 if it's not an ID that was used. | Returns -1 if it's not an ID that was used. | ||||
| @@ -153,7 +154,7 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Sorts the list. */ | /** Sorts the list. */ | ||||
| void sort (const SortMethod method); | |||||
| void sort (SortMethod method, bool forwards); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Creates some XML that can be used to store the state of this list. */ | /** Creates some XML that can be used to store the state of this list. */ | ||||
| @@ -195,7 +196,7 @@ public: | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| OwnedArray <PluginDescription> types; | |||||
| OwnedArray<PluginDescription> types; | |||||
| StringArray blacklist; | StringArray blacklist; | ||||
| ScopedPointer<CustomScanner> scanner; | ScopedPointer<CustomScanner> scanner; | ||||
| CriticalSection scanLock; | CriticalSection scanLock; | ||||
| @@ -120,7 +120,7 @@ bool PluginDirectoryScanner::skipNextFile() | |||||
| void PluginDirectoryScanner::setDeadMansPedalFile (const StringArray& newContents) | void PluginDirectoryScanner::setDeadMansPedalFile (const StringArray& newContents) | ||||
| { | { | ||||
| if (deadMansPedalFile != File::nonexistent) | |||||
| if (deadMansPedalFile.getFullPathName().isNotEmpty()) | |||||
| deadMansPedalFile.replaceWithText (newContents.joinIntoString ("\n"), true, true); | deadMansPedalFile.replaceWithText (newContents.joinIntoString ("\n"), true, true); | ||||
| } | } | ||||
| @@ -22,10 +22,116 @@ | |||||
| ============================================================================== | ============================================================================== | ||||
| */ | */ | ||||
| PluginListComponent::PluginListComponent (AudioPluginFormatManager& manager, | |||||
| KnownPluginList& listToEdit, | |||||
| const File& deadMansPedal, | |||||
| PropertiesFile* const props) | |||||
| class PluginListComponent::TableModel : public TableListBoxModel | |||||
| { | |||||
| public: | |||||
| TableModel (PluginListComponent& c, KnownPluginList& l) : owner (c), list (l) {} | |||||
| int getNumRows() override | |||||
| { | |||||
| return list.getNumTypes() + list.getBlacklistedFiles().size(); | |||||
| } | |||||
| void paintRowBackground (Graphics& g, int /*rowNumber*/, int /*width*/, int /*height*/, bool rowIsSelected) override | |||||
| { | |||||
| if (rowIsSelected) | |||||
| g.fillAll (owner.findColour (TextEditor::highlightColourId)); | |||||
| } | |||||
| enum | |||||
| { | |||||
| nameCol = 1, | |||||
| typeCol = 2, | |||||
| categoryCol = 3, | |||||
| manufacturerCol = 4, | |||||
| descCol = 5 | |||||
| }; | |||||
| void paintCell (Graphics& g, int row, int columnId, int width, int height, bool /*rowIsSelected*/) override | |||||
| { | |||||
| String text; | |||||
| bool isBlacklisted = row >= list.getNumTypes(); | |||||
| if (isBlacklisted) | |||||
| { | |||||
| if (columnId == nameCol) | |||||
| text = list.getBlacklistedFiles() [row - list.getNumTypes()]; | |||||
| else if (columnId == descCol) | |||||
| text = TRANS("Deactivated after failing to initialise correctly"); | |||||
| } | |||||
| else if (const PluginDescription* const desc = list.getType (row)) | |||||
| { | |||||
| switch (columnId) | |||||
| { | |||||
| case nameCol: text = desc->name; break; | |||||
| case typeCol: text = desc->pluginFormatName; break; | |||||
| case categoryCol: text = desc->category.isNotEmpty() ? desc->category : "-"; break; | |||||
| case manufacturerCol: text = desc->manufacturerName; break; | |||||
| case descCol: text = getPluginDescription (*desc); break; | |||||
| default: jassertfalse; break; | |||||
| } | |||||
| } | |||||
| if (text.isNotEmpty()) | |||||
| { | |||||
| g.setColour (isBlacklisted ? Colours::red | |||||
| : columnId == nameCol ? Colours::black | |||||
| : Colours::grey); | |||||
| g.setFont (Font (height * 0.7f, Font::bold)); | |||||
| g.drawFittedText (text, 4, 0, width - 6, height, Justification::centredLeft, 1, 0.9f); | |||||
| } | |||||
| } | |||||
| void deleteKeyPressed (int) override | |||||
| { | |||||
| owner.removeSelected(); | |||||
| } | |||||
| void sortOrderChanged (int newSortColumnId, bool isForwards) override | |||||
| { | |||||
| switch (newSortColumnId) | |||||
| { | |||||
| case nameCol: list.sort (KnownPluginList::sortAlphabetically, isForwards); break; | |||||
| case typeCol: list.sort (KnownPluginList::sortByFormat, isForwards); break; | |||||
| case categoryCol: list.sort (KnownPluginList::sortByCategory, isForwards); break; | |||||
| case manufacturerCol: list.sort (KnownPluginList::sortByManufacturer, isForwards); break; | |||||
| case descCol: break; | |||||
| default: jassertfalse; break; | |||||
| } | |||||
| } | |||||
| static void removePluginItem (KnownPluginList& list, int index) | |||||
| { | |||||
| if (index < list.getNumTypes()) | |||||
| list.removeType (index); | |||||
| else | |||||
| list.removeFromBlacklist (list.getBlacklistedFiles() [index - list.getNumTypes()]); | |||||
| } | |||||
| static String getPluginDescription (const PluginDescription& desc) | |||||
| { | |||||
| StringArray items; | |||||
| if (desc.descriptiveName != desc.name) | |||||
| items.add (desc.descriptiveName); | |||||
| items.add (desc.version); | |||||
| items.removeEmptyStrings(); | |||||
| return items.joinIntoString (" - "); | |||||
| } | |||||
| PluginListComponent& owner; | |||||
| KnownPluginList& list; | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TableModel) | |||||
| }; | |||||
| //============================================================================== | |||||
| PluginListComponent::PluginListComponent (AudioPluginFormatManager& manager, KnownPluginList& listToEdit, | |||||
| const File& deadMansPedal, PropertiesFile* const props) | |||||
| : formatManager (manager), | : formatManager (manager), | ||||
| list (listToEdit), | list (listToEdit), | ||||
| deadMansPedalFile (deadMansPedal), | deadMansPedalFile (deadMansPedal), | ||||
| @@ -33,10 +139,23 @@ PluginListComponent::PluginListComponent (AudioPluginFormatManager& manager, | |||||
| propertiesToUse (props), | propertiesToUse (props), | ||||
| numThreads (0) | numThreads (0) | ||||
| { | { | ||||
| listBox.setModel (this); | |||||
| addAndMakeVisible (&listBox); | |||||
| tableModel = new TableModel (*this, listToEdit); | |||||
| TableHeaderComponent& header = table.getHeader(); | |||||
| header.addColumn (TRANS("Name"), TableModel::nameCol, 200, 100, 700, TableHeaderComponent::defaultFlags | TableHeaderComponent::sortedForwards); | |||||
| header.addColumn (TRANS("Format"), TableModel::typeCol, 80, 80, 80, TableHeaderComponent::notResizable); | |||||
| header.addColumn (TRANS("Category"), TableModel::categoryCol, 100, 100, 200); | |||||
| header.addColumn (TRANS("Manufacturer"), TableModel::manufacturerCol, 200, 100, 300); | |||||
| header.addColumn (TRANS("Description"), TableModel::descCol, 300, 100, 500, TableHeaderComponent::notSortable); | |||||
| table.setHeaderHeight (22); | |||||
| table.setRowHeight (20); | |||||
| table.setModel (tableModel); | |||||
| table.setMultipleSelectionEnabled (true); | |||||
| addAndMakeVisible (table); | |||||
| addAndMakeVisible (&optionsButton); | |||||
| addAndMakeVisible (optionsButton); | |||||
| optionsButton.addListener (this); | optionsButton.addListener (this); | ||||
| optionsButton.setTriggeredOnMouseDown (true); | optionsButton.setTriggeredOnMouseDown (true); | ||||
| @@ -66,9 +185,13 @@ void PluginListComponent::setNumberOfThreadsForScanning (int num) | |||||
| void PluginListComponent::resized() | void PluginListComponent::resized() | ||||
| { | { | ||||
| listBox.setBounds (0, 0, getWidth(), getHeight() - 30); | |||||
| Rectangle<int> r (getLocalBounds().reduced (2)); | |||||
| optionsButton.setBounds (r.removeFromBottom (24)); | |||||
| optionsButton.changeWidthToFitText (24); | optionsButton.changeWidthToFitText (24); | ||||
| optionsButton.setTopLeftPosition (0, getHeight() - 28); | |||||
| r.removeFromBottom (3); | |||||
| table.setBounds (r); | |||||
| } | } | ||||
| void PluginListComponent::changeListenerCallback (ChangeBroadcaster*) | void PluginListComponent::changeListenerCallback (ChangeBroadcaster*) | ||||
| @@ -78,89 +201,22 @@ void PluginListComponent::changeListenerCallback (ChangeBroadcaster*) | |||||
| void PluginListComponent::updateList() | void PluginListComponent::updateList() | ||||
| { | { | ||||
| listBox.updateContent(); | |||||
| listBox.repaint(); | |||||
| } | |||||
| int PluginListComponent::getNumRows() | |||||
| { | |||||
| return list.getNumTypes() + list.getBlacklistedFiles().size(); | |||||
| } | |||||
| void PluginListComponent::paintListBoxItem (int row, Graphics& g, int width, int height, bool rowIsSelected) | |||||
| { | |||||
| if (rowIsSelected) | |||||
| g.fillAll (findColour (TextEditor::highlightColourId)); | |||||
| String name, desc; | |||||
| bool isBlacklisted = false; | |||||
| if (row >= list.getNumTypes()) | |||||
| { | |||||
| isBlacklisted = true; | |||||
| name = list.getBlacklistedFiles() [row - list.getNumTypes()]; | |||||
| desc = TRANS("Deactivated after failing to initialise correctly"); | |||||
| } | |||||
| else if (const PluginDescription* const pd = list.getType (row)) | |||||
| { | |||||
| name = pd->name; | |||||
| desc << pd->pluginFormatName | |||||
| << (pd->isInstrument ? " instrument" : " effect") | |||||
| << " - " << pd->numInputChannels << (pd->numInputChannels == 1 ? " in" : " ins") | |||||
| << " / " << pd->numOutputChannels << (pd->numOutputChannels == 1 ? " out" : " outs"); | |||||
| if (pd->manufacturerName.isNotEmpty()) desc << " - " << pd->manufacturerName; | |||||
| if (pd->version.isNotEmpty()) desc << " - " << pd->version; | |||||
| if (pd->category.isNotEmpty()) desc << " - category: '" << pd->category << '\''; | |||||
| } | |||||
| if (name.isNotEmpty()) | |||||
| { | |||||
| GlyphArrangement ga; | |||||
| ga.addCurtailedLineOfText (Font (height * 0.7f, Font::bold), | |||||
| name, 8.0f, height * 0.8f, width - 10.0f, true); | |||||
| g.setColour (isBlacklisted ? Colours::red : Colours::black); | |||||
| ga.draw (g); | |||||
| const Rectangle<float> bb (ga.getBoundingBox (0, -1, false)); | |||||
| ga.clear(); | |||||
| ga.addCurtailedLineOfText (Font (height * 0.6f), desc, | |||||
| jmax (bb.getRight() + 10.0f, width / 3.0f), height * 0.8f, | |||||
| width - bb.getRight() - 12.0f, true); | |||||
| g.setColour (isBlacklisted ? Colours::red : Colours::grey); | |||||
| ga.draw (g); | |||||
| } | |||||
| } | |||||
| static void removePluginItem (KnownPluginList& list, int index) | |||||
| { | |||||
| if (index < list.getNumTypes()) | |||||
| list.removeType (index); | |||||
| else | |||||
| list.removeFromBlacklist (list.getBlacklistedFiles() [index - list.getNumTypes()]); | |||||
| } | |||||
| void PluginListComponent::deleteKeyPressed (int lastRowSelected) | |||||
| { | |||||
| removePluginItem (list, lastRowSelected); | |||||
| table.updateContent(); | |||||
| table.repaint(); | |||||
| } | } | ||||
| void PluginListComponent::removeSelected() | void PluginListComponent::removeSelected() | ||||
| { | { | ||||
| const SparseSet <int> selected (listBox.getSelectedRows()); | |||||
| const SparseSet<int> selected (table.getSelectedRows()); | |||||
| for (int i = list.getNumTypes(); --i >= 0;) | |||||
| for (int i = table.getNumRows(); --i >= 0;) | |||||
| if (selected.contains (i)) | if (selected.contains (i)) | ||||
| removePluginItem (list, i); | |||||
| TableModel::removePluginItem (list, i); | |||||
| } | } | ||||
| bool PluginListComponent::canShowSelectedFolder() const | bool PluginListComponent::canShowSelectedFolder() const | ||||
| { | { | ||||
| if (const PluginDescription* const desc = list.getType (listBox.getSelectedRow())) | |||||
| if (const PluginDescription* const desc = list.getType (table.getSelectedRow())) | |||||
| return File::createFileWithoutCheckingPath (desc->fileOrIdentifier).exists(); | return File::createFileWithoutCheckingPath (desc->fileOrIdentifier).exists(); | ||||
| return false; | return false; | ||||
| @@ -169,7 +225,7 @@ bool PluginListComponent::canShowSelectedFolder() const | |||||
| void PluginListComponent::showSelectedFolder() | void PluginListComponent::showSelectedFolder() | ||||
| { | { | ||||
| if (canShowSelectedFolder()) | if (canShowSelectedFolder()) | ||||
| if (const PluginDescription* const desc = list.getType (listBox.getSelectedRow())) | |||||
| if (const PluginDescription* const desc = list.getType (table.getSelectedRow())) | |||||
| File (desc->fileOrIdentifier).getParentDirectory().startAsProcess(); | File (desc->fileOrIdentifier).getParentDirectory().startAsProcess(); | ||||
| } | } | ||||
| @@ -192,12 +248,9 @@ void PluginListComponent::optionsMenuCallback (int result) | |||||
| { | { | ||||
| case 0: break; | case 0: break; | ||||
| case 1: list.clear(); break; | case 1: list.clear(); break; | ||||
| case 2: list.sort (KnownPluginList::sortAlphabetically); break; | |||||
| case 3: list.sort (KnownPluginList::sortByCategory); break; | |||||
| case 4: list.sort (KnownPluginList::sortByManufacturer); break; | |||||
| case 5: removeSelected(); break; | |||||
| case 6: showSelectedFolder(); break; | |||||
| case 7: removeMissingPlugins(); break; | |||||
| case 2: removeSelected(); break; | |||||
| case 3: showSelectedFolder(); break; | |||||
| case 4: removeMissingPlugins(); break; | |||||
| default: | default: | ||||
| if (AudioPluginFormat* format = formatManager.getFormat (result - 10)) | if (AudioPluginFormat* format = formatManager.getFormat (result - 10)) | ||||
| @@ -213,13 +266,9 @@ void PluginListComponent::buttonClicked (Button* button) | |||||
| { | { | ||||
| PopupMenu menu; | PopupMenu menu; | ||||
| menu.addItem (1, TRANS("Clear list")); | menu.addItem (1, TRANS("Clear list")); | ||||
| menu.addItem (5, TRANS("Remove selected plug-in from list"), listBox.getNumSelectedRows() > 0); | |||||
| menu.addItem (6, TRANS("Show folder containing selected plug-in"), canShowSelectedFolder()); | |||||
| menu.addItem (7, TRANS("Remove any plug-ins whose files no longer exist")); | |||||
| menu.addSeparator(); | |||||
| menu.addItem (2, TRANS("Sort alphabetically")); | |||||
| menu.addItem (3, TRANS("Sort by category")); | |||||
| menu.addItem (4, TRANS("Sort by manufacturer")); | |||||
| menu.addItem (2, TRANS("Remove selected plug-in from list"), table.getNumSelectedRows() > 0); | |||||
| menu.addItem (3, TRANS("Show folder containing selected plug-in"), canShowSelectedFolder()); | |||||
| menu.addItem (4, TRANS("Remove any plug-ins whose files no longer exist")); | |||||
| menu.addSeparator(); | menu.addSeparator(); | ||||
| for (int i = 0; i < formatManager.getNumFormats(); ++i) | for (int i = 0; i < formatManager.getNumFormats(); ++i) | ||||
| @@ -262,10 +311,7 @@ void PluginListComponent::setLastSearchPath (PropertiesFile& properties, AudioPl | |||||
| class PluginListComponent::Scanner : private Timer | class PluginListComponent::Scanner : private Timer | ||||
| { | { | ||||
| public: | public: | ||||
| Scanner (PluginListComponent& plc, | |||||
| AudioPluginFormat& format, | |||||
| PropertiesFile* properties, | |||||
| int threads) | |||||
| Scanner (PluginListComponent& plc, AudioPluginFormat& format, PropertiesFile* properties, int threads) | |||||
| : owner (plc), formatToScan (format), propertiesToUse (properties), | : owner (plc), formatToScan (format), propertiesToUse (properties), | ||||
| pathChooserWindow (TRANS("Select folders to scan..."), String::empty, AlertWindow::NoIcon), | pathChooserWindow (TRANS("Select folders to scan..."), String::empty, AlertWindow::NoIcon), | ||||
| progressWindow (TRANS("Scanning for plug-ins..."), | progressWindow (TRANS("Scanning for plug-ins..."), | ||||
| @@ -33,7 +33,6 @@ | |||||
| */ | */ | ||||
| class JUCE_API PluginListComponent : public Component, | class JUCE_API PluginListComponent : public Component, | ||||
| public FileDragAndDropTarget, | public FileDragAndDropTarget, | ||||
| private ListBoxModel, | |||||
| private ChangeListener, | private ChangeListener, | ||||
| private ButtonListener // (can't use Button::Listener due to idiotic VC2005 bug) | private ButtonListener // (can't use Button::Listener due to idiotic VC2005 bug) | ||||
| { | { | ||||
| @@ -53,7 +52,7 @@ public: | |||||
| /** Destructor. */ | /** Destructor. */ | ||||
| ~PluginListComponent(); | ~PluginListComponent(); | ||||
| /** Changes the text in the panel's button. */ | |||||
| /** Changes the text in the panel's options button. */ | |||||
| void setOptionsButtonText (const String& newText); | void setOptionsButtonText (const String& newText); | ||||
| /** Sets how many threads to simultaneously scan for plugins. | /** Sets how many threads to simultaneously scan for plugins. | ||||
| @@ -62,42 +61,32 @@ public: | |||||
| void setNumberOfThreadsForScanning (int numThreads); | void setNumberOfThreadsForScanning (int numThreads); | ||||
| /** Returns the last search path stored in a given properties file for the specified format. */ | /** Returns the last search path stored in a given properties file for the specified format. */ | ||||
| static FileSearchPath getLastSearchPath (PropertiesFile& properties, AudioPluginFormat& format); | |||||
| static FileSearchPath getLastSearchPath (PropertiesFile&, AudioPluginFormat&); | |||||
| /** Stores a search path in a properties file for the given format. */ | /** Stores a search path in a properties file for the given format. */ | ||||
| static void setLastSearchPath (PropertiesFile& properties, AudioPluginFormat& format, | |||||
| const FileSearchPath& newPath); | |||||
| static void setLastSearchPath (PropertiesFile&, AudioPluginFormat&, const FileSearchPath&); | |||||
| /** Triggers an asynchronous scan for the given format. */ | /** Triggers an asynchronous scan for the given format. */ | ||||
| void scanFor (AudioPluginFormat& format); | |||||
| void scanFor (AudioPluginFormat&); | |||||
| /** Returns true if there's currently a scan in progress. */ | /** Returns true if there's currently a scan in progress. */ | ||||
| bool isScanning() const noexcept; | bool isScanning() const noexcept; | ||||
| //============================================================================== | |||||
| /** @internal */ | |||||
| void resized() override; | |||||
| /** @internal */ | |||||
| bool isInterestedInFileDrag (const StringArray&) override; | |||||
| /** @internal */ | |||||
| void filesDropped (const StringArray&, int, int) override; | |||||
| /** @internal */ | |||||
| int getNumRows() override; | |||||
| /** @internal */ | |||||
| void paintListBoxItem (int row, Graphics&, int width, int height, bool rowIsSelected) override; | |||||
| /** @internal */ | |||||
| void deleteKeyPressed (int lastRowSelected) override; | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| AudioPluginFormatManager& formatManager; | AudioPluginFormatManager& formatManager; | ||||
| KnownPluginList& list; | KnownPluginList& list; | ||||
| File deadMansPedalFile; | File deadMansPedalFile; | ||||
| ListBox listBox; | |||||
| TableListBox table; | |||||
| TextButton optionsButton; | TextButton optionsButton; | ||||
| PropertiesFile* propertiesToUse; | PropertiesFile* propertiesToUse; | ||||
| int numThreads; | int numThreads; | ||||
| class TableModel; | |||||
| friend class TableModel; | |||||
| friend struct ContainerDeletePolicy<TableModel>; | |||||
| ScopedPointer<TableModel> tableModel; | |||||
| class Scanner; | class Scanner; | ||||
| friend class Scanner; | friend class Scanner; | ||||
| friend struct ContainerDeletePolicy<Scanner>; | friend struct ContainerDeletePolicy<Scanner>; | ||||
| @@ -107,11 +96,14 @@ private: | |||||
| static void optionsMenuStaticCallback (int, PluginListComponent*); | static void optionsMenuStaticCallback (int, PluginListComponent*); | ||||
| void optionsMenuCallback (int); | void optionsMenuCallback (int); | ||||
| void updateList(); | void updateList(); | ||||
| void removeSelected(); | |||||
| void showSelectedFolder(); | void showSelectedFolder(); | ||||
| bool canShowSelectedFolder() const; | bool canShowSelectedFolder() const; | ||||
| void removeSelected(); | |||||
| void removeMissingPlugins(); | void removeMissingPlugins(); | ||||
| void resized() override; | |||||
| bool isInterestedInFileDrag (const StringArray&) override; | |||||
| void filesDropped (const StringArray&, int, int) override; | |||||
| void buttonClicked (Button*) override; | void buttonClicked (Button*) override; | ||||
| void changeListenerCallback (ChangeBroadcaster*) override; | void changeListenerCallback (ChangeBroadcaster*) override; | ||||
| @@ -90,8 +90,8 @@ File PropertiesFile::Options::getDefaultFile() const | |||||
| File dir (File::getSpecialLocation (commonToAllUsers ? File::commonApplicationDataDirectory | File dir (File::getSpecialLocation (commonToAllUsers ? File::commonApplicationDataDirectory | ||||
| : File::userApplicationDataDirectory)); | : File::userApplicationDataDirectory)); | ||||
| if (dir == File::nonexistent) | |||||
| return File::nonexistent; | |||||
| if (dir == File()) | |||||
| return File(); | |||||
| dir = dir.getChildFile (folderName.isNotEmpty() ? folderName | dir = dir.getChildFile (folderName.isNotEmpty() ? folderName | ||||
| : applicationName); | : applicationName); | ||||
| @@ -165,7 +165,7 @@ bool PropertiesFile::save() | |||||
| stopTimer(); | stopTimer(); | ||||
| if (options.doNotSave | if (options.doNotSave | ||||
| || file == File::nonexistent | |||||
| || file == File() | |||||
| || file.isDirectory() | || file.isDirectory() | ||||
| || ! file.getParentDirectory().createDirectory()) | || ! file.getParentDirectory().createDirectory()) | ||||
| return false; | return false; | ||||
| @@ -195,7 +195,7 @@ bool PropertiesFile::loadAsXml() | |||||
| { | { | ||||
| getAllProperties().set (name, | getAllProperties().set (name, | ||||
| e->getFirstChildElement() != nullptr | e->getFirstChildElement() != nullptr | ||||
| ? e->getFirstChildElement()->createDocument (String::empty, true) | |||||
| ? e->getFirstChildElement()->createDocument ("", true) | |||||
| : e->getStringAttribute (PropertyFileConstants::valueAttribute)); | : e->getStringAttribute (PropertyFileConstants::valueAttribute)); | ||||
| } | } | ||||
| } | } | ||||
| @@ -234,7 +234,7 @@ bool PropertiesFile::saveAsXml() | |||||
| if (pl != nullptr && ! pl->isLocked()) | if (pl != nullptr && ! pl->isLocked()) | ||||
| return false; // locking failure.. | return false; // locking failure.. | ||||
| if (doc.writeToFile (file, String::empty)) | |||||
| if (doc.writeToFile (file, String())) | |||||
| { | { | ||||
| needsWriting = false; | needsWriting = false; | ||||
| return true; | return true; | ||||
| @@ -144,7 +144,7 @@ public: | |||||
| C:\\Documents and Settings\\username\\Application Data\\[folderName]\\[applicationName].[filenameSuffix] | C:\\Documents and Settings\\username\\Application Data\\[folderName]\\[applicationName].[filenameSuffix] | ||||
| On Linux it'll return | On Linux it'll return | ||||
| ~/.[folderName]/[applicationName].[filenameSuffix] | |||||
| ~/[folderName]/[applicationName].[filenameSuffix] | |||||
| If the folderName variable is empty, it'll use the app name for this (or omit the | If the folderName variable is empty, it'll use the app name for this (or omit the | ||||
| folder name on the Mac). | folder name on the Mac). | ||||
| @@ -235,7 +235,7 @@ String UndoManager::getUndoDescription() const | |||||
| if (const ActionSet* const s = getCurrentSet()) | if (const ActionSet* const s = getCurrentSet()) | ||||
| return s->name; | return s->name; | ||||
| return String::empty; | |||||
| return String(); | |||||
| } | } | ||||
| String UndoManager::getRedoDescription() const | String UndoManager::getRedoDescription() const | ||||
| @@ -243,7 +243,7 @@ String UndoManager::getRedoDescription() const | |||||
| if (const ActionSet* const s = getNextSet()) | if (const ActionSet* const s = getNextSet()) | ||||
| return s->name; | return s->name; | ||||
| return String::empty; | |||||
| return String(); | |||||
| } | } | ||||
| Time UndoManager::getTimeOfUndoTransaction() const | Time UndoManager::getTimeOfUndoTransaction() const | ||||
| @@ -107,7 +107,7 @@ public: | |||||
| @see beginNewTransaction | @see beginNewTransaction | ||||
| */ | */ | ||||
| bool perform (UndoableAction* action, | bool perform (UndoableAction* action, | ||||
| const String& actionName = String::empty); | |||||
| const String& actionName = String()); | |||||
| /** Starts a new group of actions that together will be treated as a single transaction. | /** Starts a new group of actions that together will be treated as a single transaction. | ||||
| @@ -118,7 +118,7 @@ public: | |||||
| @param actionName a description of the transaction that is about to be | @param actionName a description of the transaction that is about to be | ||||
| performed | performed | ||||
| */ | */ | ||||
| void beginNewTransaction (const String& actionName = String::empty); | |||||
| void beginNewTransaction (const String& actionName = String()); | |||||
| /** Changes the name stored for the current transaction. | /** Changes the name stored for the current transaction. | ||||
| @@ -168,7 +168,7 @@ public: | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| undoManager->perform (new SetPropertyAction (this, name, newValue, var::null, true, false)); | |||||
| undoManager->perform (new SetPropertyAction (this, name, newValue, var(), true, false)); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -188,7 +188,7 @@ public: | |||||
| else | else | ||||
| { | { | ||||
| if (properties.contains (name)) | if (properties.contains (name)) | ||||
| undoManager->perform (new SetPropertyAction (this, name, var::null, properties [name], false, true)); | |||||
| undoManager->perform (new SetPropertyAction (this, name, var(), properties [name], false, true)); | |||||
| } | } | ||||
| } | } | ||||
| @@ -206,7 +206,7 @@ public: | |||||
| else | else | ||||
| { | { | ||||
| for (int i = properties.size(); --i >= 0;) | for (int i = properties.size(); --i >= 0;) | ||||
| undoManager->perform (new SetPropertyAction (this, properties.getName(i), var::null, | |||||
| undoManager->perform (new SetPropertyAction (this, properties.getName(i), var(), | |||||
| properties.getValueAt(i), false, true)); | properties.getValueAt(i), false, true)); | ||||
| } | } | ||||
| } | } | ||||
| @@ -230,7 +230,7 @@ public: | |||||
| return ValueTree (s); | return ValueTree (s); | ||||
| } | } | ||||
| return ValueTree::invalid; | |||||
| return ValueTree(); | |||||
| } | } | ||||
| ValueTree getOrCreateChildWithName (const Identifier typeToMatch, UndoManager* undoManager) | ValueTree getOrCreateChildWithName (const Identifier typeToMatch, UndoManager* undoManager) | ||||
| @@ -257,7 +257,7 @@ public: | |||||
| return ValueTree (s); | return ValueTree (s); | ||||
| } | } | ||||
| return ValueTree::invalid; | |||||
| return ValueTree(); | |||||
| } | } | ||||
| bool isAChildOf (const SharedObject* const possibleParent) const noexcept | bool isAChildOf (const SharedObject* const possibleParent) const noexcept | ||||
| @@ -444,7 +444,7 @@ public: | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| output.writeString (String::empty); | |||||
| output.writeString (String()); | |||||
| output.writeCompressedInt (0); | output.writeCompressedInt (0); | ||||
| output.writeCompressedInt (0); | output.writeCompressedInt (0); | ||||
| } | } | ||||
| @@ -846,17 +846,17 @@ ValueTree ValueTree::getChild (int index) const | |||||
| ValueTree ValueTree::getChildWithName (const Identifier type) const | ValueTree ValueTree::getChildWithName (const Identifier type) const | ||||
| { | { | ||||
| return object != nullptr ? object->getChildWithName (type) : ValueTree::invalid; | |||||
| return object != nullptr ? object->getChildWithName (type) : ValueTree(); | |||||
| } | } | ||||
| ValueTree ValueTree::getOrCreateChildWithName (const Identifier type, UndoManager* undoManager) | ValueTree ValueTree::getOrCreateChildWithName (const Identifier type, UndoManager* undoManager) | ||||
| { | { | ||||
| return object != nullptr ? object->getOrCreateChildWithName (type, undoManager) : ValueTree::invalid; | |||||
| return object != nullptr ? object->getOrCreateChildWithName (type, undoManager) : ValueTree(); | |||||
| } | } | ||||
| ValueTree ValueTree::getChildWithProperty (const Identifier propertyName, const var& propertyValue) const | ValueTree ValueTree::getChildWithProperty (const Identifier propertyName, const var& propertyValue) const | ||||
| { | { | ||||
| return object != nullptr ? object->getChildWithProperty (propertyName, propertyValue) : ValueTree::invalid; | |||||
| return object != nullptr ? object->getChildWithProperty (propertyName, propertyValue) : ValueTree(); | |||||
| } | } | ||||
| bool ValueTree::isAChildOf (const ValueTree& possibleParent) const | bool ValueTree::isAChildOf (const ValueTree& possibleParent) const | ||||
| @@ -962,7 +962,7 @@ ValueTree ValueTree::fromXml (const XmlElement& xml) | |||||
| String ValueTree::toXmlString() const | String ValueTree::toXmlString() const | ||||
| { | { | ||||
| const ScopedPointer<XmlElement> xml (createXml()); | const ScopedPointer<XmlElement> xml (createXml()); | ||||
| return xml != nullptr ? xml->createDocument (String::empty) : String::empty; | |||||
| return xml != nullptr ? xml->createDocument ("") : String(); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -976,7 +976,7 @@ ValueTree ValueTree::readFromStream (InputStream& input) | |||||
| const String type (input.readString()); | const String type (input.readString()); | ||||
| if (type.isEmpty()) | if (type.isEmpty()) | ||||
| return ValueTree::invalid; | |||||
| return ValueTree(); | |||||
| ValueTree v (type); | ValueTree v (type); | ||||
| @@ -317,7 +317,7 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Creates an XmlElement that holds a complete image of this node and all its children. | /** Creates an XmlElement that holds a complete image of this node and all its children. | ||||
| If this node is invalid, this may return 0. Otherwise, the XML that is produced can | |||||
| If this node is invalid, this may return nullptr. Otherwise, the XML that is produced can | |||||
| be used to recreate a similar node by calling fromXml() | be used to recreate a similar node by calling fromXml() | ||||
| @see fromXml | @see fromXml | ||||
| */ | */ | ||||
| @@ -44,7 +44,7 @@ private: | |||||
| //============================================================================== | //============================================================================== | ||||
| AsyncUpdater::AsyncUpdater() | AsyncUpdater::AsyncUpdater() | ||||
| { | { | ||||
| message = new AsyncUpdaterMessage (*this); | |||||
| activeMessage = new AsyncUpdaterMessage (*this); | |||||
| } | } | ||||
| AsyncUpdater::~AsyncUpdater() | AsyncUpdater::~AsyncUpdater() | ||||
| @@ -55,18 +55,18 @@ AsyncUpdater::~AsyncUpdater() | |||||
| // deleting this object, or find some other way to avoid such a race condition. | // deleting this object, or find some other way to avoid such a race condition. | ||||
| jassert ((! isUpdatePending()) || MessageManager::getInstance()->currentThreadHasLockedMessageManager()); | jassert ((! isUpdatePending()) || MessageManager::getInstance()->currentThreadHasLockedMessageManager()); | ||||
| message->shouldDeliver.set (0); | |||||
| activeMessage->shouldDeliver.set (0); | |||||
| } | } | ||||
| void AsyncUpdater::triggerAsyncUpdate() | void AsyncUpdater::triggerAsyncUpdate() | ||||
| { | { | ||||
| if (message->shouldDeliver.compareAndSetBool (1, 0)) | |||||
| message->post(); | |||||
| if (activeMessage->shouldDeliver.compareAndSetBool (1, 0)) | |||||
| activeMessage->post(); | |||||
| } | } | ||||
| void AsyncUpdater::cancelPendingUpdate() noexcept | void AsyncUpdater::cancelPendingUpdate() noexcept | ||||
| { | { | ||||
| message->shouldDeliver.set (0); | |||||
| activeMessage->shouldDeliver.set (0); | |||||
| } | } | ||||
| void AsyncUpdater::handleUpdateNowIfNeeded() | void AsyncUpdater::handleUpdateNowIfNeeded() | ||||
| @@ -74,11 +74,11 @@ void AsyncUpdater::handleUpdateNowIfNeeded() | |||||
| // This can only be called by the event thread. | // This can only be called by the event thread. | ||||
| jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); | jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); | ||||
| if (message->shouldDeliver.exchange (0) != 0) | |||||
| if (activeMessage->shouldDeliver.exchange (0) != 0) | |||||
| handleAsyncUpdate(); | handleAsyncUpdate(); | ||||
| } | } | ||||
| bool AsyncUpdater::isUpdatePending() const noexcept | bool AsyncUpdater::isUpdatePending() const noexcept | ||||
| { | { | ||||
| return message->shouldDeliver.value != 0; | |||||
| return activeMessage->shouldDeliver.value != 0; | |||||
| } | } | ||||
| @@ -100,7 +100,7 @@ private: | |||||
| //============================================================================== | //============================================================================== | ||||
| class AsyncUpdaterMessage; | class AsyncUpdaterMessage; | ||||
| friend class ReferenceCountedObjectPtr<AsyncUpdaterMessage>; | friend class ReferenceCountedObjectPtr<AsyncUpdaterMessage>; | ||||
| ReferenceCountedObjectPtr<AsyncUpdaterMessage> message; | |||||
| ReferenceCountedObjectPtr<AsyncUpdaterMessage> activeMessage; | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AsyncUpdater) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AsyncUpdater) | ||||
| }; | }; | ||||
| @@ -141,7 +141,7 @@ String InterprocessConnection::getConnectedHostName() const | |||||
| return "localhost"; | return "localhost"; | ||||
| } | } | ||||
| return String::empty; | |||||
| return String(); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -134,7 +134,7 @@ struct JUCEApplicationBase::MultipleInstanceHandler {}; | |||||
| #if JUCE_ANDROID | #if JUCE_ANDROID | ||||
| StringArray JUCEApplicationBase::getCommandLineParameterArray() { return StringArray(); } | StringArray JUCEApplicationBase::getCommandLineParameterArray() { return StringArray(); } | ||||
| String JUCEApplicationBase::getCommandLineParameters() { return String::empty; } | |||||
| String JUCEApplicationBase::getCommandLineParameters() { return String(); } | |||||
| #else | #else | ||||
| @@ -22,21 +22,6 @@ | |||||
| ============================================================================== | ============================================================================== | ||||
| */ | */ | ||||
| class MessageManager::QuitMessage : public MessageManager::MessageBase | |||||
| { | |||||
| public: | |||||
| QuitMessage() {} | |||||
| void messageCallback() override | |||||
| { | |||||
| if (MessageManager* const mm = MessageManager::instance) | |||||
| mm->quitMessageReceived = true; | |||||
| } | |||||
| JUCE_DECLARE_NON_COPYABLE (QuitMessage) | |||||
| }; | |||||
| //============================================================================== | |||||
| MessageManager::MessageManager() noexcept | MessageManager::MessageManager() noexcept | ||||
| : quitMessagePosted (false), | : quitMessagePosted (false), | ||||
| quitMessageReceived (false), | quitMessageReceived (false), | ||||
| @@ -96,12 +81,6 @@ void MessageManager::runDispatchLoop() | |||||
| runDispatchLoopUntil (-1); | runDispatchLoopUntil (-1); | ||||
| } | } | ||||
| void MessageManager::stopDispatchLoop() | |||||
| { | |||||
| (new QuitMessage())->post(); | |||||
| quitMessagePosted = true; | |||||
| } | |||||
| bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor) | bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor) | ||||
| { | { | ||||
| jassert (isThisTheMessageThread()); // must only be called by the message thread | jassert (isThisTheMessageThread()); // must only be called by the message thread | ||||
| @@ -124,6 +103,26 @@ bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor) | |||||
| return ! quitMessageReceived; | return ! quitMessageReceived; | ||||
| } | } | ||||
| class MessageManager::QuitMessage : public MessageManager::MessageBase | |||||
| { | |||||
| public: | |||||
| QuitMessage() {} | |||||
| void messageCallback() override | |||||
| { | |||||
| if (MessageManager* const mm = MessageManager::instance) | |||||
| mm->quitMessageReceived = true; | |||||
| } | |||||
| JUCE_DECLARE_NON_COPYABLE (QuitMessage) | |||||
| }; | |||||
| void MessageManager::stopDispatchLoop() | |||||
| { | |||||
| (new QuitMessage())->post(); | |||||
| quitMessagePosted = true; | |||||
| } | |||||
| #endif | #endif | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -237,15 +237,32 @@ void MessageManager::runDispatchLoop() | |||||
| } | } | ||||
| } | } | ||||
| void MessageManager::stopDispatchLoop() | |||||
| static void shutdownNSApp() | |||||
| { | { | ||||
| jassert (isThisTheMessageThread()); // must only be called by the message thread | |||||
| [NSApp stop: nil]; | |||||
| [NSApp activateIgnoringOtherApps: YES]; // (if the app is inactive, it sits there and ignores the quit request until the next time it gets activated) | |||||
| [NSEvent startPeriodicEventsAfterDelay: 0 withPeriod: 0.1]; | |||||
| } | |||||
| void MessageManager::stopDispatchLoop() | |||||
| { | |||||
| quitMessagePosted = true; | quitMessagePosted = true; | ||||
| #if ! JUCE_PROJUCER_LIVE_BUILD | #if ! JUCE_PROJUCER_LIVE_BUILD | ||||
| [NSApp stop: nil]; | |||||
| [NSApp activateIgnoringOtherApps: YES]; // (if the app is inactive, it sits there and ignores the quit request until the next time it gets activated) | |||||
| [NSEvent startPeriodicEventsAfterDelay: 0 withPeriod: 0.1]; | |||||
| if (isThisTheMessageThread()) | |||||
| { | |||||
| shutdownNSApp(); | |||||
| } | |||||
| else | |||||
| { | |||||
| struct QuitCallback : public CallbackMessage | |||||
| { | |||||
| QuitCallback() {} | |||||
| void messageCallback() override { shutdownNSApp(); } | |||||
| }; | |||||
| (new QuitCallback())->post(); | |||||
| } | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -26,7 +26,7 @@ namespace ColourHelpers | |||||
| { | { | ||||
| static uint8 floatToUInt8 (const float n) noexcept | static uint8 floatToUInt8 (const float n) noexcept | ||||
| { | { | ||||
| return n <= 0.0f ? 0 : (n >= 1.0f ? 255 : (uint8) (n * 255.0f)); | |||||
| return n <= 0.0f ? 0 : (n >= 1.0f ? 255 : static_cast<uint8> (n * 255.996f)); | |||||
| } | } | ||||
| // This is an adjusted brightness value, based on the way the human | // This is an adjusted brightness value, based on the way the human | ||||
| @@ -151,8 +151,8 @@ public: | |||||
| */ | */ | ||||
| bool isRadial; | bool isRadial; | ||||
| bool operator== (const ColourGradient& other) const noexcept; | |||||
| bool operator!= (const ColourGradient& other) const noexcept; | |||||
| bool operator== (const ColourGradient&) const noexcept; | |||||
| bool operator!= (const ColourGradient&) const noexcept; | |||||
| private: | private: | ||||
| @@ -165,14 +165,14 @@ private: | |||||
| : position (pos), colour (col) | : position (pos), colour (col) | ||||
| {} | {} | ||||
| bool operator== (const ColourPoint& other) const noexcept; | |||||
| bool operator!= (const ColourPoint& other) const noexcept; | |||||
| bool operator== (const ColourPoint&) const noexcept; | |||||
| bool operator!= (const ColourPoint&) const noexcept; | |||||
| double position; | double position; | ||||
| Colour colour; | Colour colour; | ||||
| }; | }; | ||||
| Array <ColourPoint> colours; | |||||
| Array<ColourPoint> colours; | |||||
| JUCE_LEAK_DETECTOR (ColourGradient) | JUCE_LEAK_DETECTOR (ColourGradient) | ||||
| }; | }; | ||||
| @@ -59,14 +59,14 @@ public: | |||||
| FillType (const Image& image, const AffineTransform& transform) noexcept; | FillType (const Image& image, const AffineTransform& transform) noexcept; | ||||
| /** Creates a copy of another FillType. */ | /** Creates a copy of another FillType. */ | ||||
| FillType (const FillType& other); | |||||
| FillType (const FillType&); | |||||
| /** Makes a copy of another FillType. */ | /** Makes a copy of another FillType. */ | ||||
| FillType& operator= (const FillType& other); | |||||
| FillType& operator= (const FillType&); | |||||
| #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS | #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS | ||||
| FillType (FillType&& other) noexcept; | |||||
| FillType& operator= (FillType&& other) noexcept; | |||||
| FillType (FillType&&) noexcept; | |||||
| FillType& operator= (FillType&&) noexcept; | |||||
| #endif | #endif | ||||
| /** Destructor. */ | /** Destructor. */ | ||||
| @@ -138,8 +138,8 @@ public: | |||||
| AffineTransform transform; | AffineTransform transform; | ||||
| //============================================================================== | //============================================================================== | ||||
| bool operator== (const FillType& other) const; | |||||
| bool operator!= (const FillType& other) const; | |||||
| bool operator== (const FillType&) const; | |||||
| bool operator!= (const FillType&) const; | |||||
| private: | private: | ||||
| JUCE_LEAK_DETECTOR (FillType) | JUCE_LEAK_DETECTOR (FillType) | ||||
| @@ -232,17 +232,25 @@ Font Graphics::getCurrentFont() const | |||||
| void Graphics::drawSingleLineText (const String& text, const int startX, const int baselineY, | void Graphics::drawSingleLineText (const String& text, const int startX, const int baselineY, | ||||
| Justification justification) const | Justification justification) const | ||||
| { | { | ||||
| if (text.isNotEmpty() | |||||
| && startX < context.getClipBounds().getRight()) | |||||
| if (text.isNotEmpty()) | |||||
| { | { | ||||
| GlyphArrangement arr; | |||||
| arr.addLineOfText (context.getFont(), text, (float) startX, (float) baselineY); | |||||
| // Don't pass any vertical placement flags to this method - they'll be ignored. | // Don't pass any vertical placement flags to this method - they'll be ignored. | ||||
| jassert (justification.getOnlyVerticalFlags() == 0); | jassert (justification.getOnlyVerticalFlags() == 0); | ||||
| const int flags = justification.getOnlyHorizontalFlags(); | const int flags = justification.getOnlyHorizontalFlags(); | ||||
| if (flags == Justification::right) | |||||
| { | |||||
| if (startX < context.getClipBounds().getX()) | |||||
| return; | |||||
| } | |||||
| else if (flags == Justification::left) | |||||
| if (startX > context.getClipBounds().getRight()) | |||||
| return; | |||||
| GlyphArrangement arr; | |||||
| arr.addLineOfText (context.getFont(), text, (float) startX, (float) baselineY); | |||||
| if (flags != Justification::left) | if (flags != Justification::left) | ||||
| { | { | ||||
| float w = arr.getBoundingBox (0, -1, true).getWidth(); | float w = arr.getBoundingBox (0, -1, true).getWidth(); | ||||
| @@ -259,16 +267,6 @@ void Graphics::drawSingleLineText (const String& text, const int startX, const i | |||||
| } | } | ||||
| } | } | ||||
| void Graphics::drawTextAsPath (const String& text, const AffineTransform& transform) const | |||||
| { | |||||
| if (text.isNotEmpty()) | |||||
| { | |||||
| GlyphArrangement arr; | |||||
| arr.addLineOfText (context.getFont(), text, 0.0f, 0.0f); | |||||
| arr.draw (*this, transform); | |||||
| } | |||||
| } | |||||
| void Graphics::drawMultiLineText (const String& text, const int startX, | void Graphics::drawMultiLineText (const String& text, const int startX, | ||||
| const int baselineY, const int maximumLineWidth) const | const int baselineY, const int maximumLineWidth) const | ||||
| { | { | ||||
| @@ -455,6 +453,11 @@ void Graphics::drawEllipse (float x, float y, float width, float height, float l | |||||
| strokePath (p, PathStrokeType (lineThickness)); | strokePath (p, PathStrokeType (lineThickness)); | ||||
| } | } | ||||
| void Graphics::drawEllipse (const Rectangle<float>& area, float lineThickness) const | |||||
| { | |||||
| drawEllipse (area.getX(), area.getY(), area.getWidth(), area.getHeight(), lineThickness); | |||||
| } | |||||
| void Graphics::fillRoundedRectangle (float x, float y, float width, float height, float cornerSize) const | void Graphics::fillRoundedRectangle (float x, float y, float width, float height, float cornerSize) const | ||||
| { | { | ||||
| fillRoundedRectangle (coordsToRectangle (x, y, width, height), cornerSize); | fillRoundedRectangle (coordsToRectangle (x, y, width, height), cornerSize); | ||||
| @@ -104,7 +104,7 @@ public: | |||||
| Note there's also a setFont (float, int) method to quickly change the size and | Note there's also a setFont (float, int) method to quickly change the size and | ||||
| style of the current font. | style of the current font. | ||||
| @see drawSingleLineText, drawMultiLineText, drawTextAsPath, drawText, drawFittedText | |||||
| @see drawSingleLineText, drawMultiLineText, drawText, drawFittedText | |||||
| */ | */ | ||||
| void setFont (const Font& newFont); | void setFont (const Font& newFont); | ||||
| @@ -146,17 +146,6 @@ public: | |||||
| int startX, int baselineY, | int startX, int baselineY, | ||||
| int maximumLineWidth) const; | int maximumLineWidth) const; | ||||
| /** Renders a string of text as a vector path. | |||||
| This allows a string to be transformed with an arbitrary AffineTransform and | |||||
| rendered using the current colour/brush. It's much slower than the normal text methods | |||||
| but more accurate. | |||||
| @see setFont | |||||
| */ | |||||
| void drawTextAsPath (const String& text, | |||||
| const AffineTransform& transform) const; | |||||
| /** Draws a line of text within a specified rectangle. | /** Draws a line of text within a specified rectangle. | ||||
| The text will be positioned within the rectangle based on the justification | The text will be positioned within the rectangle based on the justification | ||||
| @@ -363,6 +352,11 @@ public: | |||||
| void drawEllipse (float x, float y, float width, float height, | void drawEllipse (float x, float y, float width, float height, | ||||
| float lineThickness) const; | float lineThickness) const; | ||||
| /** Draws an elliptical stroke using the current colour or brush. | |||||
| @see fillEllipse, Path::addEllipse | |||||
| */ | |||||
| void drawEllipse (const Rectangle<float>& area, float lineThickness) const; | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Draws a line between two points. | /** Draws a line between two points. | ||||
| The line is 1 pixel wide and drawn with the current colour or brush. | The line is 1 pixel wide and drawn with the current colour or brush. | ||||
| @@ -166,7 +166,7 @@ void AttributedString::append (const AttributedString& other) | |||||
| void AttributedString::clear() | void AttributedString::clear() | ||||
| { | { | ||||
| text = String::empty; | |||||
| text.clear(); | |||||
| attributes.clear(); | attributes.clear(); | ||||
| } | } | ||||
| @@ -99,13 +99,13 @@ namespace CustomTypefaceHelpers | |||||
| //============================================================================== | //============================================================================== | ||||
| CustomTypeface::CustomTypeface() | CustomTypeface::CustomTypeface() | ||||
| : Typeface (String::empty, String::empty) | |||||
| : Typeface (String(), String()) | |||||
| { | { | ||||
| clear(); | clear(); | ||||
| } | } | ||||
| CustomTypeface::CustomTypeface (InputStream& serialisedTypefaceStream) | CustomTypeface::CustomTypeface (InputStream& serialisedTypefaceStream) | ||||
| : Typeface (String::empty, String::empty) | |||||
| : Typeface (String(), String()) | |||||
| { | { | ||||
| clear(); | clear(); | ||||
| @@ -385,7 +385,7 @@ bool CustomTypeface::getOutlineForGlyph (int glyphNumber, Path& path) | |||||
| return false; | return false; | ||||
| } | } | ||||
| EdgeTable* CustomTypeface::getEdgeTableForGlyph (int glyphNumber, const AffineTransform& transform) | |||||
| EdgeTable* CustomTypeface::getEdgeTableForGlyph (int glyphNumber, const AffineTransform& transform, float fontHeight) | |||||
| { | { | ||||
| if (const GlyphInfo* const glyph = findGlyph ((juce_wchar) glyphNumber, true)) | if (const GlyphInfo* const glyph = findGlyph ((juce_wchar) glyphNumber, true)) | ||||
| { | { | ||||
| @@ -399,7 +399,7 @@ EdgeTable* CustomTypeface::getEdgeTableForGlyph (int glyphNumber, const AffineTr | |||||
| const Typeface::Ptr fallbackTypeface (getFallbackTypeface()); | const Typeface::Ptr fallbackTypeface (getFallbackTypeface()); | ||||
| if (fallbackTypeface != nullptr && fallbackTypeface != this) | if (fallbackTypeface != nullptr && fallbackTypeface != this) | ||||
| return fallbackTypeface->getEdgeTableForGlyph (glyphNumber, transform); | |||||
| return fallbackTypeface->getEdgeTableForGlyph (glyphNumber, transform, fontHeight); | |||||
| } | } | ||||
| return nullptr; | return nullptr; | ||||
| @@ -119,7 +119,7 @@ public: | |||||
| float getStringWidth (const String&) override; | float getStringWidth (const String&) override; | ||||
| void getGlyphPositions (const String&, Array <int>& glyphs, Array<float>& xOffsets) override; | void getGlyphPositions (const String&, Array <int>& glyphs, Array<float>& xOffsets) override; | ||||
| bool getOutlineForGlyph (int glyphNumber, Path&) override; | bool getOutlineForGlyph (int glyphNumber, Path&) override; | ||||
| EdgeTable* getEdgeTableForGlyph (int glyphNumber, const AffineTransform&) override; | |||||
| EdgeTable* getEdgeTableForGlyph (int glyphNumber, const AffineTransform&, float fontHeight) override; | |||||
| protected: | protected: | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -44,8 +44,8 @@ public: | |||||
| PositionedGlyph (const Font& font, juce_wchar character, int glyphNumber, | PositionedGlyph (const Font& font, juce_wchar character, int glyphNumber, | ||||
| float anchorX, float baselineY, float width, bool isWhitespace); | float anchorX, float baselineY, float width, bool isWhitespace); | ||||
| PositionedGlyph (const PositionedGlyph& other); | |||||
| PositionedGlyph& operator= (const PositionedGlyph& other); | |||||
| PositionedGlyph (const PositionedGlyph&); | |||||
| PositionedGlyph& operator= (const PositionedGlyph&); | |||||
| ~PositionedGlyph(); | ~PositionedGlyph(); | ||||
| /** Returns the character the glyph represents. */ | /** Returns the character the glyph represents. */ | ||||
| @@ -209,10 +209,10 @@ public: | |||||
| float minimumHorizontalScale = 0.7f); | float minimumHorizontalScale = 0.7f); | ||||
| /** Appends another glyph arrangement to this one. */ | /** Appends another glyph arrangement to this one. */ | ||||
| void addGlyphArrangement (const GlyphArrangement& other); | |||||
| void addGlyphArrangement (const GlyphArrangement&); | |||||
| /** Appends a custom glyph to the arrangement. */ | /** Appends a custom glyph to the arrangement. */ | ||||
| void addGlyph (const PositionedGlyph& glyph); | |||||
| void addGlyph (const PositionedGlyph&); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Draws this glyph arrangement to a graphics context. | /** Draws this glyph arrangement to a graphics context. | ||||
| @@ -101,8 +101,8 @@ struct FontStyleHelpers | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| Typeface::Typeface (const String& name_, const String& style_) noexcept | |||||
| : name (name_), style (style_) | |||||
| Typeface::Typeface (const String& faceName, const String& styleName) noexcept | |||||
| : name (faceName), style (styleName) | |||||
| { | { | ||||
| } | } | ||||
| @@ -116,13 +116,145 @@ Typeface::Ptr Typeface::getFallbackTypeface() | |||||
| return fallbackFont.getTypeface(); | return fallbackFont.getTypeface(); | ||||
| } | } | ||||
| EdgeTable* Typeface::getEdgeTableForGlyph (int glyphNumber, const AffineTransform& transform) | |||||
| EdgeTable* Typeface::getEdgeTableForGlyph (int glyphNumber, const AffineTransform& transform, float fontHeight) | |||||
| { | { | ||||
| Path path; | Path path; | ||||
| if (getOutlineForGlyph (glyphNumber, path) && ! path.isEmpty()) | if (getOutlineForGlyph (glyphNumber, path) && ! path.isEmpty()) | ||||
| { | |||||
| applyVerticalHintingTransform (fontHeight, path); | |||||
| return new EdgeTable (path.getBoundsTransformed (transform).getSmallestIntegerContainer().expanded (1, 0), | return new EdgeTable (path.getBoundsTransformed (transform).getSmallestIntegerContainer().expanded (1, 0), | ||||
| path, transform); | path, transform); | ||||
| } | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| //============================================================================== | |||||
| struct Typeface::HintingParams | |||||
| { | |||||
| HintingParams (Typeface& t) | |||||
| : cachedSize (0), top (0), middle (0), bottom (0) | |||||
| { | |||||
| Font font (&t); | |||||
| font = font.withHeight ((float) standardHeight); | |||||
| top = getAverageY (font, "BDEFPRTZOQ", true); | |||||
| middle = getAverageY (font, "acegmnopqrsuvwxy", true); | |||||
| bottom = getAverageY (font, "BDELZOC", false); | |||||
| } | |||||
| void applyVerticalHintingTransform (float fontSize, Path& path) | |||||
| { | |||||
| if (cachedSize != fontSize) | |||||
| { | |||||
| cachedSize = fontSize; | |||||
| cachedScale = Scaling (top, middle, bottom, fontSize); | |||||
| } | |||||
| if (bottom < top + 3.0f / fontSize) | |||||
| return; | |||||
| Path result; | |||||
| for (Path::Iterator i (path); i.next();) | |||||
| { | |||||
| switch (i.elementType) | |||||
| { | |||||
| case Path::Iterator::startNewSubPath: result.startNewSubPath (i.x1, cachedScale.apply (i.y1)); break; | |||||
| case Path::Iterator::lineTo: result.lineTo (i.x1, cachedScale.apply (i.y1)); break; | |||||
| case Path::Iterator::quadraticTo: result.quadraticTo (i.x1, cachedScale.apply (i.y1), | |||||
| i.x2, cachedScale.apply (i.y2)); break; | |||||
| case Path::Iterator::cubicTo: result.cubicTo (i.x1, cachedScale.apply (i.y1), | |||||
| i.x2, cachedScale.apply (i.y2), | |||||
| i.x3, cachedScale.apply (i.y3)); break; | |||||
| case Path::Iterator::closePath: result.closeSubPath(); break; | |||||
| default: jassertfalse; break; | |||||
| } | |||||
| } | |||||
| result.swapWithPath (path); | |||||
| } | |||||
| private: | |||||
| struct Scaling | |||||
| { | |||||
| Scaling() noexcept : middle(), upperScale(), upperOffset(), lowerScale(), lowerOffset() {} | |||||
| Scaling (float t, float m, float b, float fontSize) noexcept : middle (m) | |||||
| { | |||||
| const float newT = std::floor (fontSize * t + 0.5f) / fontSize; | |||||
| const float newB = std::floor (fontSize * b + 0.5f) / fontSize; | |||||
| const float newM = std::floor (fontSize * m + 0.3f) / fontSize; // this is slightly biased so that lower-case letters | |||||
| // are more likely to become taller than shorter. | |||||
| upperScale = jlimit (0.9f, 1.1f, (newM - newT) / (m - t)); | |||||
| lowerScale = jlimit (0.9f, 1.1f, (newB - newM) / (b - m)); | |||||
| upperOffset = newM - m * upperScale; | |||||
| lowerOffset = newB - b * lowerScale; | |||||
| } | |||||
| float apply (float y) const noexcept | |||||
| { | |||||
| return y < middle ? (y * upperScale + upperOffset) | |||||
| : (y * lowerScale + lowerOffset); | |||||
| } | |||||
| float middle, upperScale, upperOffset, lowerScale, lowerOffset; | |||||
| }; | |||||
| float cachedSize; | |||||
| Scaling cachedScale; | |||||
| static float getAverageY (const Font& font, const char* chars, bool getTop) | |||||
| { | |||||
| GlyphArrangement ga; | |||||
| ga.addLineOfText (font, chars, 0, 0); | |||||
| Array<float> y; | |||||
| DefaultElementComparator<float> sorter; | |||||
| for (int i = 0; i < ga.getNumGlyphs(); ++i) | |||||
| { | |||||
| Path p; | |||||
| ga.getGlyph (i).createPath (p); | |||||
| Rectangle<float> bounds (p.getBounds()); | |||||
| if (! p.isEmpty()) | |||||
| y.addSorted (sorter, getTop ? bounds.getY() : bounds.getBottom()); | |||||
| } | |||||
| float median = y[y.size() / 2]; | |||||
| float total = 0; | |||||
| int num = 0; | |||||
| for (int i = 0; i < y.size(); ++i) | |||||
| { | |||||
| if (std::abs (median - y.getUnchecked(i)) < 0.05f * (float) standardHeight) | |||||
| { | |||||
| total += y.getUnchecked(i); | |||||
| ++num; | |||||
| } | |||||
| } | |||||
| return num < 4 ? 0.0f : total / (num * (float) standardHeight); | |||||
| } | |||||
| enum { standardHeight = 100 }; | |||||
| float top, middle, bottom; | |||||
| }; | |||||
| void Typeface::applyVerticalHintingTransform (float fontSize, Path& path) | |||||
| { | |||||
| if (fontSize > 3.0f && fontSize < 25.0f) | |||||
| { | |||||
| ScopedLock sl (hintingLock); | |||||
| if (hintingParams == nullptr) | |||||
| hintingParams = new HintingParams (*this); | |||||
| return hintingParams->applyVerticalHintingTransform (fontSize, path); | |||||
| } | |||||
| } | |||||
| @@ -64,6 +64,12 @@ public: | |||||
| /** Creates a new system typeface. */ | /** Creates a new system typeface. */ | ||||
| static Ptr createSystemTypefaceFor (const Font& font); | static Ptr createSystemTypefaceFor (const Font& font); | ||||
| /** Attempts to create a font from some raw font file data (e.g. a TTF or OTF file image). | |||||
| The system will take its own internal copy of the data, so you can free the block once | |||||
| this method has returned. | |||||
| */ | |||||
| static Ptr createSystemTypefaceFor (const void* fontFileData, size_t fontFileDataSize); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Destructor. */ | /** Destructor. */ | ||||
| virtual ~Typeface(); | virtual ~Typeface(); | ||||
| @@ -111,7 +117,7 @@ public: | |||||
| virtual bool getOutlineForGlyph (int glyphNumber, Path& path) = 0; | virtual bool getOutlineForGlyph (int glyphNumber, Path& path) = 0; | ||||
| /** Returns a new EdgeTable that contains the path for the givem glyph, with the specified transform applied. */ | /** Returns a new EdgeTable that contains the path for the givem glyph, with the specified transform applied. */ | ||||
| virtual EdgeTable* getEdgeTableForGlyph (int glyphNumber, const AffineTransform& transform); | |||||
| virtual EdgeTable* getEdgeTableForGlyph (int glyphNumber, const AffineTransform& transform, float fontHeight); | |||||
| /** Returns true if the typeface uses hinting. */ | /** Returns true if the typeface uses hinting. */ | ||||
| virtual bool isHinted() const { return false; } | virtual bool isHinted() const { return false; } | ||||
| @@ -128,6 +134,12 @@ public: | |||||
| */ | */ | ||||
| static void scanFolderForFonts (const File& folder); | static void scanFolderForFonts (const File& folder); | ||||
| /** Makes an attempt at performing a good overall distortion that will scale a font of | |||||
| the given size to align vertically with the pixel grid. The path should be an unscaled | |||||
| (i.e. normalised to height of 1.0) path for a glyph. | |||||
| */ | |||||
| void applyVerticalHintingTransform (float fontHeight, Path& path); | |||||
| protected: | protected: | ||||
| //============================================================================== | //============================================================================== | ||||
| String name, style; | String name, style; | ||||
| @@ -137,6 +149,11 @@ protected: | |||||
| static Ptr getFallbackTypeface(); | static Ptr getFallbackTypeface(); | ||||
| private: | private: | ||||
| struct HintingParams; | |||||
| friend struct ContainerDeletePolicy<HintingParams>; | |||||
| ScopedPointer<HintingParams> hintingParams; | |||||
| CriticalSection hintingLock; | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Typeface) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Typeface) | ||||
| }; | }; | ||||
| @@ -332,57 +332,51 @@ void EdgeTable::sanitiseLevels (const bool useNonZeroWinding) noexcept | |||||
| if (num > 0) | if (num > 0) | ||||
| { | { | ||||
| LineItem* items = reinterpret_cast<LineItem*> (lineStart + 1); | LineItem* items = reinterpret_cast<LineItem*> (lineStart + 1); | ||||
| LineItem* const itemsEnd = items + num; | |||||
| // sort the X coords | // sort the X coords | ||||
| std::sort (items, items + num); | |||||
| std::sort (items, itemsEnd); | |||||
| // merge duplicate X coords | |||||
| for (int i = 0; i < num - 1; ++i) | |||||
| const LineItem* src = items; | |||||
| int correctedNum = num; | |||||
| int level = 0; | |||||
| while (src < itemsEnd) | |||||
| { | { | ||||
| if (items[i].x == items[i + 1].x) | |||||
| level += src->level; | |||||
| const int x = src->x; | |||||
| ++src; | |||||
| while (src < itemsEnd && src->x == x) | |||||
| { | { | ||||
| items[i].level += items[i + 1].level; | |||||
| memmove (items + i + 1, items + i + 2, (size_t) (num - i - 2) * sizeof (LineItem)); | |||||
| --num; | |||||
| --lineStart[0]; | |||||
| --i; | |||||
| level += src->level; | |||||
| ++src; | |||||
| --correctedNum; | |||||
| } | } | ||||
| } | |||||
| int level = 0; | |||||
| int corrected = std::abs (level); | |||||
| if (useNonZeroWinding) | |||||
| { | |||||
| while (--num > 0) | |||||
| if (corrected >> 8) | |||||
| { | { | ||||
| level += items->level; | |||||
| int corrected = std::abs (level); | |||||
| if (corrected >> 8) | |||||
| if (useNonZeroWinding) | |||||
| { | |||||
| corrected = 255; | corrected = 255; | ||||
| items->level = corrected; | |||||
| ++items; | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| while (--num > 0) | |||||
| { | |||||
| level += items->level; | |||||
| int corrected = std::abs (level); | |||||
| if (corrected >> 8) | |||||
| } | |||||
| else | |||||
| { | { | ||||
| corrected &= 511; | corrected &= 511; | ||||
| if (corrected >> 8) | if (corrected >> 8) | ||||
| corrected = 511 - corrected; | corrected = 511 - corrected; | ||||
| } | } | ||||
| items->level = corrected; | |||||
| ++items; | |||||
| } | } | ||||
| items->x = x; | |||||
| items->level = corrected; | |||||
| ++items; | |||||
| } | } | ||||
| items->level = 0; // force the last level to 0, just in case something went wrong in creating the table | |||||
| lineStart[0] = correctedNum; | |||||
| (items - 1)->level = 0; // force the last level to 0, just in case something went wrong in creating the table | |||||
| } | } | ||||
| lineStart += lineStrideElements; | lineStart += lineStrideElements; | ||||
| @@ -451,12 +445,12 @@ void EdgeTable::addEdgePointPair (int x1, int x2, int y, int winding) | |||||
| line = table + lineStrideElements * y; | line = table + lineStrideElements * y; | ||||
| } | } | ||||
| line[0] += 2; | |||||
| int n = numPoints << 1; | |||||
| line [n + 1] = x1; | |||||
| line [n + 2] = winding; | |||||
| line [n + 3] = x2; | |||||
| line [n + 4] = -winding; | |||||
| line[0] = numPoints + 2; | |||||
| line += numPoints << 1; | |||||
| line[1] = x1; | |||||
| line[2] = winding; | |||||
| line[3] = x2; | |||||
| line[4] = -winding; | |||||
| } | } | ||||
| void EdgeTable::translate (float dx, const int dy) noexcept | void EdgeTable::translate (float dx, const int dy) noexcept | ||||
| @@ -480,6 +474,25 @@ void EdgeTable::translate (float dx, const int dy) noexcept | |||||
| } | } | ||||
| } | } | ||||
| void EdgeTable::multiplyLevels (float amount) | |||||
| { | |||||
| int* lineStart = table; | |||||
| const int multiplier = (int) (amount * 256.0f); | |||||
| for (int y = 0; y < bounds.getHeight(); ++y) | |||||
| { | |||||
| int numPoints = lineStart[0]; | |||||
| LineItem* item = reinterpret_cast<LineItem*> (lineStart + 1); | |||||
| lineStart += lineStrideElements; | |||||
| while (--numPoints > 0) | |||||
| { | |||||
| item->level = jmin (255, (item->level * multiplier) >> 8); | |||||
| ++item; | |||||
| } | |||||
| } | |||||
| } | |||||
| void EdgeTable::intersectWithEdgeTableLine (const int y, const int* const otherLine) | void EdgeTable::intersectWithEdgeTableLine (const int y, const int* const otherLine) | ||||
| { | { | ||||
| jassert (y >= 0 && y < bounds.getHeight()); | jassert (y >= 0 && y < bounds.getHeight()); | ||||
| @@ -62,10 +62,10 @@ public: | |||||
| explicit EdgeTable (const Rectangle<float>& rectangleToAdd); | explicit EdgeTable (const Rectangle<float>& rectangleToAdd); | ||||
| /** Creates a copy of another edge table. */ | /** Creates a copy of another edge table. */ | ||||
| EdgeTable (const EdgeTable& other); | |||||
| EdgeTable (const EdgeTable&); | |||||
| /** Copies from another edge table. */ | /** Copies from another edge table. */ | ||||
| EdgeTable& operator= (const EdgeTable& other); | |||||
| EdgeTable& operator= (const EdgeTable&); | |||||
| /** Destructor. */ | /** Destructor. */ | ||||
| ~EdgeTable(); | ~EdgeTable(); | ||||
| @@ -73,12 +73,15 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| void clipToRectangle (const Rectangle<int>& r); | void clipToRectangle (const Rectangle<int>& r); | ||||
| void excludeRectangle (const Rectangle<int>& r); | void excludeRectangle (const Rectangle<int>& r); | ||||
| void clipToEdgeTable (const EdgeTable& other); | |||||
| void clipToEdgeTable (const EdgeTable&); | |||||
| void clipLineToMask (int x, int y, const uint8* mask, int maskStride, int numPixels); | void clipLineToMask (int x, int y, const uint8* mask, int maskStride, int numPixels); | ||||
| bool isEmpty() noexcept; | bool isEmpty() noexcept; | ||||
| const Rectangle<int>& getMaximumBounds() const noexcept { return bounds; } | const Rectangle<int>& getMaximumBounds() const noexcept { return bounds; } | ||||
| void translate (float dx, int dy) noexcept; | void translate (float dx, int dy) noexcept; | ||||
| /** Scales all the alpha-levels in the table by the given multiplier. */ | |||||
| void multiplyLevels (float factor); | |||||
| /** Reduces the amount of space the table has allocated. | /** Reduces the amount of space the table has allocated. | ||||
| This will shrink the table down to use as little memory as possible - useful for | This will shrink the table down to use as little memory as possible - useful for | ||||