| @@ -0,0 +1,371 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__ALL_H | |||
| #define FLAC__ALL_H | |||
| #include "export.h" | |||
| #include "assert.h" | |||
| #include "callback.h" | |||
| #include "format.h" | |||
| #include "metadata.h" | |||
| #include "ordinals.h" | |||
| #include "stream_decoder.h" | |||
| #include "stream_encoder.h" | |||
| /** \mainpage | |||
| * | |||
| * \section intro Introduction | |||
| * | |||
| * This is the documentation for the FLAC C and C++ APIs. It is | |||
| * highly interconnected; this introduction should give you a top | |||
| * level idea of the structure and how to find the information you | |||
| * need. As a prerequisite you should have at least a basic | |||
| * knowledge of the FLAC format, documented | |||
| * <A HREF="../format.html">here</A>. | |||
| * | |||
| * \section c_api FLAC C API | |||
| * | |||
| * The FLAC C API is the interface to libFLAC, a set of structures | |||
| * describing the components of FLAC streams, and functions for | |||
| * encoding and decoding streams, as well as manipulating FLAC | |||
| * metadata in files. The public include files will be installed | |||
| * in your include area (for example /usr/include/FLAC/...). | |||
| * | |||
| * By writing a little code and linking against libFLAC, it is | |||
| * relatively easy to add FLAC support to another program. The | |||
| * library is licensed under <A HREF="../license.html">Xiph's BSD license</A>. | |||
| * Complete source code of libFLAC as well as the command-line | |||
| * encoder and plugins is available and is a useful source of | |||
| * examples. | |||
| * | |||
| * Aside from encoders and decoders, libFLAC provides a powerful | |||
| * metadata interface for manipulating metadata in FLAC files. It | |||
| * allows the user to add, delete, and modify FLAC metadata blocks | |||
| * and it can automatically take advantage of PADDING blocks to avoid | |||
| * rewriting the entire FLAC file when changing the size of the | |||
| * metadata. | |||
| * | |||
| * libFLAC usually only requires the standard C library and C math | |||
| * library. In particular, threading is not used so there is no | |||
| * dependency on a thread library. However, libFLAC does not use | |||
| * global variables and should be thread-safe. | |||
| * | |||
| * libFLAC also supports encoding to and decoding from Ogg FLAC. | |||
| * However the metadata editing interfaces currently have limited | |||
| * read-only support for Ogg FLAC files. | |||
| * | |||
| * \section cpp_api FLAC C++ API | |||
| * | |||
| * The FLAC C++ API is a set of classes that encapsulate the | |||
| * structures and functions in libFLAC. They provide slightly more | |||
| * functionality with respect to metadata but are otherwise | |||
| * equivalent. For the most part, they share the same usage as | |||
| * their counterparts in libFLAC, and the FLAC C API documentation | |||
| * can be used as a supplement. The public include files | |||
| * for the C++ API will be installed in your include area (for | |||
| * example /usr/include/FLAC++/...). | |||
| * | |||
| * libFLAC++ is also licensed under | |||
| * <A HREF="../license.html">Xiph's BSD license</A>. | |||
| * | |||
| * \section getting_started Getting Started | |||
| * | |||
| * A good starting point for learning the API is to browse through | |||
| * the <A HREF="modules.html">modules</A>. Modules are logical | |||
| * groupings of related functions or classes, which correspond roughly | |||
| * to header files or sections of header files. Each module includes a | |||
| * detailed description of the general usage of its functions or | |||
| * classes. | |||
| * | |||
| * From there you can go on to look at the documentation of | |||
| * individual functions. You can see different views of the individual | |||
| * functions through the links in top bar across this page. | |||
| * | |||
| * If you prefer a more hands-on approach, you can jump right to some | |||
| * <A HREF="../documentation_example_code.html">example code</A>. | |||
| * | |||
| * \section porting_guide Porting Guide | |||
| * | |||
| * Starting with FLAC 1.1.3 a \link porting Porting Guide \endlink | |||
| * has been introduced which gives detailed instructions on how to | |||
| * port your code to newer versions of FLAC. | |||
| * | |||
| * \section embedded_developers Embedded Developers | |||
| * | |||
| * libFLAC has grown larger over time as more functionality has been | |||
| * included, but much of it may be unnecessary for a particular embedded | |||
| * implementation. Unused parts may be pruned by some simple editing of | |||
| * src/libFLAC/Makefile.am. In general, the decoders, encoders, and | |||
| * metadata interface are all independent from each other. | |||
| * | |||
| * It is easiest to just describe the dependencies: | |||
| * | |||
| * - All modules depend on the \link flac_format Format \endlink module. | |||
| * - The decoders and encoders depend on the bitbuffer. | |||
| * - The decoder is independent of the encoder. The encoder uses the | |||
| * decoder because of the verify feature, but this can be removed if | |||
| * not needed. | |||
| * - Parts of the metadata interface require the stream decoder (but not | |||
| * the encoder). | |||
| * - Ogg support is selectable through the compile time macro | |||
| * \c FLAC__HAS_OGG. | |||
| * | |||
| * For example, if your application only requires the stream decoder, no | |||
| * encoder, and no metadata interface, you can remove the stream encoder | |||
| * and the metadata interface, which will greatly reduce the size of the | |||
| * library. | |||
| * | |||
| * Also, there are several places in the libFLAC code with comments marked | |||
| * with "OPT:" where a \#define can be changed to enable code that might be | |||
| * faster on a specific platform. Experimenting with these can yield faster | |||
| * binaries. | |||
| */ | |||
| /** \defgroup porting Porting Guide for New Versions | |||
| * | |||
| * This module describes differences in the library interfaces from | |||
| * version to version. It assists in the porting of code that uses | |||
| * the libraries to newer versions of FLAC. | |||
| * | |||
| * One simple facility for making porting easier that has been added | |||
| * in FLAC 1.1.3 is a set of \#defines in \c export.h of each | |||
| * library's includes (e.g. \c include/FLAC/export.h). The | |||
| * \#defines mirror the libraries' | |||
| * <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, | |||
| * \c FLAC_API_VERSION_REVISION, and \c FLAC_API_VERSION_AGE. | |||
| * These can be used to support multiple versions of an API during the | |||
| * transition phase, e.g. | |||
| * | |||
| * \code | |||
| * #if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7 | |||
| * legacy code | |||
| * #else | |||
| * new code | |||
| * #endif | |||
| * \endcode | |||
| * | |||
| * The source will work for multiple versions and the legacy code can | |||
| * easily be removed when the transition is complete. | |||
| * | |||
| * Another available symbol is FLAC_API_SUPPORTS_OGG_FLAC (defined in | |||
| * include/FLAC/export.h), which can be used to determine whether or not | |||
| * the library has been compiled with support for Ogg FLAC. This is | |||
| * simpler than trying to call an Ogg init function and catching the | |||
| * error. | |||
| */ | |||
| /** \defgroup porting_1_1_2_to_1_1_3 Porting from FLAC 1.1.2 to 1.1.3 | |||
| * \ingroup porting | |||
| * | |||
| * \brief | |||
| * This module describes porting from FLAC 1.1.2 to FLAC 1.1.3. | |||
| * | |||
| * The main change between the APIs in 1.1.2 and 1.1.3 is that they have | |||
| * been simplified. First, libOggFLAC has been merged into libFLAC and | |||
| * libOggFLAC++ has been merged into libFLAC++. Second, both the three | |||
| * decoding layers and three encoding layers have been merged into a | |||
| * single stream decoder and stream encoder. That is, the functionality | |||
| * of FLAC__SeekableStreamDecoder and FLAC__FileDecoder has been merged | |||
| * into FLAC__StreamDecoder, and FLAC__SeekableStreamEncoder and | |||
| * FLAC__FileEncoder into FLAC__StreamEncoder. Only the | |||
| * FLAC__StreamDecoder and FLAC__StreamEncoder remain. What this means | |||
| * is there is now a single API that can be used to encode or decode | |||
| * streams to/from native FLAC or Ogg FLAC and the single API can work | |||
| * on both seekable and non-seekable streams. | |||
| * | |||
| * Instead of creating an encoder or decoder of a certain layer, now the | |||
| * client will always create a FLAC__StreamEncoder or | |||
| * FLAC__StreamDecoder. The old layers are now differentiated by the | |||
| * initialization function. For example, for the decoder, | |||
| * FLAC__stream_decoder_init() has been replaced by | |||
| * FLAC__stream_decoder_init_stream(). This init function takes | |||
| * callbacks for the I/O, and the seeking callbacks are optional. This | |||
| * allows the client to use the same object for seekable and | |||
| * non-seekable streams. For decoding a FLAC file directly, the client | |||
| * can use FLAC__stream_decoder_init_file() and pass just a filename | |||
| * and fewer callbacks; most of the other callbacks are supplied | |||
| * internally. For situations where fopen()ing by filename is not | |||
| * possible (e.g. Unicode filenames on Windows) the client can instead | |||
| * open the file itself and supply the FILE* to | |||
| * FLAC__stream_decoder_init_FILE(). The init functions now returns a | |||
| * FLAC__StreamDecoderInitStatus instead of FLAC__StreamDecoderState. | |||
| * Since the callbacks and client data are now passed to the init | |||
| * function, the FLAC__stream_decoder_set_*_callback() functions and | |||
| * FLAC__stream_decoder_set_client_data() are no longer needed. The | |||
| * rest of the calls to the decoder are the same as before. | |||
| * | |||
| * There are counterpart init functions for Ogg FLAC, e.g. | |||
| * FLAC__stream_decoder_init_ogg_stream(). All the rest of the calls | |||
| * and callbacks are the same as for native FLAC. | |||
| * | |||
| * As an example, in FLAC 1.1.2 a seekable stream decoder would have | |||
| * been set up like so: | |||
| * | |||
| * \code | |||
| * FLAC__SeekableStreamDecoder *decoder = FLAC__seekable_stream_decoder_new(); | |||
| * if(decoder == NULL) do_something; | |||
| * FLAC__seekable_stream_decoder_set_md5_checking(decoder, true); | |||
| * [... other settings ...] | |||
| * FLAC__seekable_stream_decoder_set_read_callback(decoder, my_read_callback); | |||
| * FLAC__seekable_stream_decoder_set_seek_callback(decoder, my_seek_callback); | |||
| * FLAC__seekable_stream_decoder_set_tell_callback(decoder, my_tell_callback); | |||
| * FLAC__seekable_stream_decoder_set_length_callback(decoder, my_length_callback); | |||
| * FLAC__seekable_stream_decoder_set_eof_callback(decoder, my_eof_callback); | |||
| * FLAC__seekable_stream_decoder_set_write_callback(decoder, my_write_callback); | |||
| * FLAC__seekable_stream_decoder_set_metadata_callback(decoder, my_metadata_callback); | |||
| * FLAC__seekable_stream_decoder_set_error_callback(decoder, my_error_callback); | |||
| * FLAC__seekable_stream_decoder_set_client_data(decoder, my_client_data); | |||
| * if(FLAC__seekable_stream_decoder_init(decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK) do_something; | |||
| * \endcode | |||
| * | |||
| * In FLAC 1.1.3 it is like this: | |||
| * | |||
| * \code | |||
| * FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new(); | |||
| * if(decoder == NULL) do_something; | |||
| * FLAC__stream_decoder_set_md5_checking(decoder, true); | |||
| * [... other settings ...] | |||
| * if(FLAC__stream_decoder_init_stream( | |||
| * decoder, | |||
| * my_read_callback, | |||
| * my_seek_callback, // or NULL | |||
| * my_tell_callback, // or NULL | |||
| * my_length_callback, // or NULL | |||
| * my_eof_callback, // or NULL | |||
| * my_write_callback, | |||
| * my_metadata_callback, // or NULL | |||
| * my_error_callback, | |||
| * my_client_data | |||
| * ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something; | |||
| * \endcode | |||
| * | |||
| * or you could do; | |||
| * | |||
| * \code | |||
| * [...] | |||
| * FILE *file = fopen("somefile.flac","rb"); | |||
| * if(file == NULL) do_somthing; | |||
| * if(FLAC__stream_decoder_init_FILE( | |||
| * decoder, | |||
| * file, | |||
| * my_write_callback, | |||
| * my_metadata_callback, // or NULL | |||
| * my_error_callback, | |||
| * my_client_data | |||
| * ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something; | |||
| * \endcode | |||
| * | |||
| * or just: | |||
| * | |||
| * \code | |||
| * [...] | |||
| * if(FLAC__stream_decoder_init_file( | |||
| * decoder, | |||
| * "somefile.flac", | |||
| * my_write_callback, | |||
| * my_metadata_callback, // or NULL | |||
| * my_error_callback, | |||
| * my_client_data | |||
| * ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something; | |||
| * \endcode | |||
| * | |||
| * Another small change to the decoder is in how it handles unparseable | |||
| * streams. Before, when the decoder found an unparseable stream | |||
| * (reserved for when the decoder encounters a stream from a future | |||
| * encoder that it can't parse), it changed the state to | |||
| * \c FLAC__STREAM_DECODER_UNPARSEABLE_STREAM. Now the decoder instead | |||
| * drops sync and calls the error callback with a new error code | |||
| * \c FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM. This is | |||
| * more robust. If your error callback does not discriminate on the the | |||
| * error state, your code does not need to be changed. | |||
| * | |||
| * The encoder now has a new setting: | |||
| * FLAC__stream_encoder_set_apodization(). This is for setting the | |||
| * method used to window the data before LPC analysis. You only need to | |||
| * add a call to this function if the default is not suitable. There | |||
| * are also two new convenience functions that may be useful: | |||
| * FLAC__metadata_object_cuesheet_calculate_cddb_id() and | |||
| * FLAC__metadata_get_cuesheet(). | |||
| * | |||
| * The \a bytes parameter to FLAC__StreamDecoderReadCallback, | |||
| * FLAC__StreamEncoderReadCallback, and FLAC__StreamEncoderWriteCallback | |||
| * is now \c size_t instead of \c uint32_t. | |||
| */ | |||
| /** \defgroup porting_1_1_3_to_1_1_4 Porting from FLAC 1.1.3 to 1.1.4 | |||
| * \ingroup porting | |||
| * | |||
| * \brief | |||
| * This module describes porting from FLAC 1.1.3 to FLAC 1.1.4. | |||
| * | |||
| * There were no changes to any of the interfaces from 1.1.3 to 1.1.4. | |||
| * There was a slight change in the implementation of | |||
| * FLAC__stream_encoder_set_metadata(); the function now makes a copy | |||
| * of the \a metadata array of pointers so the client no longer needs | |||
| * to maintain it after the call. The objects themselves that are | |||
| * pointed to by the array are still not copied though and must be | |||
| * maintained until the call to FLAC__stream_encoder_finish(). | |||
| */ | |||
| /** \defgroup porting_1_1_4_to_1_2_0 Porting from FLAC 1.1.4 to 1.2.0 | |||
| * \ingroup porting | |||
| * | |||
| * \brief | |||
| * This module describes porting from FLAC 1.1.4 to FLAC 1.2.0. | |||
| * | |||
| * There were only very minor changes to the interfaces from 1.1.4 to 1.2.0. | |||
| * In libFLAC, \c FLAC__format_sample_rate_is_subset() was added. | |||
| * In libFLAC++, \c FLAC::Decoder::Stream::get_decode_position() was added. | |||
| * | |||
| * Finally, value of the constant \c FLAC__FRAME_HEADER_RESERVED_LEN | |||
| * has changed to reflect the conversion of one of the reserved bits | |||
| * into active use. It used to be \c 2 and now is \c 1. However the | |||
| * FLAC frame header length has not changed, so to skip the proper | |||
| * number of bits, use \c FLAC__FRAME_HEADER_RESERVED_LEN + | |||
| * \c FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN | |||
| */ | |||
| /** \defgroup flac FLAC C API | |||
| * | |||
| * The FLAC C API is the interface to libFLAC, a set of structures | |||
| * describing the components of FLAC streams, and functions for | |||
| * encoding and decoding streams, as well as manipulating FLAC | |||
| * metadata in files. | |||
| * | |||
| * You should start with the format components as all other modules | |||
| * are dependent on it. | |||
| */ | |||
| #endif | |||
| @@ -0,0 +1,219 @@ | |||
| /* alloc - Convenience routines for safely allocating memory | |||
| * Copyright (C) 2007-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__SHARE__ALLOC_H | |||
| #define FLAC__SHARE__ALLOC_H | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| /* WATCHOUT: for c++ you may have to #define __STDC_LIMIT_MACROS 1 real early | |||
| * before #including this file, otherwise SIZE_MAX might not be defined | |||
| */ | |||
| #include <limits.h> /* for SIZE_MAX */ | |||
| #if HAVE_STDINT_H | |||
| #include <stdint.h> /* for SIZE_MAX in case limits.h didn't get it */ | |||
| #endif | |||
| #include <stdlib.h> /* for size_t, malloc(), etc */ | |||
| #include "compat.h" | |||
| #ifndef SIZE_MAX | |||
| # ifndef SIZE_T_MAX | |||
| # ifdef _MSC_VER | |||
| # ifdef _WIN64 | |||
| # define SIZE_T_MAX FLAC__U64L(0xffffffffffffffff) | |||
| # else | |||
| # define SIZE_T_MAX 0xffffffff | |||
| # endif | |||
| # else | |||
| # error | |||
| # endif | |||
| # endif | |||
| # define SIZE_MAX SIZE_T_MAX | |||
| #endif | |||
| /* avoid malloc()ing 0 bytes, see: | |||
| * https://www.securecoding.cert.org/confluence/display/seccode/MEM04-A.+Do+not+make+assumptions+about+the+result+of+allocating+0+bytes?focusedCommentId=5407003 | |||
| */ | |||
| static inline void *safe_malloc_(size_t size) | |||
| { | |||
| /* malloc(0) is undefined; FLAC src convention is to always allocate */ | |||
| if(!size) | |||
| size++; | |||
| return malloc(size); | |||
| } | |||
| static inline void *safe_calloc_(size_t nmemb, size_t size) | |||
| { | |||
| if(!nmemb || !size) | |||
| return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ | |||
| return calloc(nmemb, size); | |||
| } | |||
| /*@@@@ there's probably a better way to prevent overflows when allocating untrusted sums but this works for now */ | |||
| static inline void *safe_malloc_add_2op_(size_t size1, size_t size2) | |||
| { | |||
| size2 += size1; | |||
| if(size2 < size1) | |||
| return 0; | |||
| return safe_malloc_(size2); | |||
| } | |||
| static inline void *safe_malloc_add_3op_(size_t size1, size_t size2, size_t size3) | |||
| { | |||
| size2 += size1; | |||
| if(size2 < size1) | |||
| return 0; | |||
| size3 += size2; | |||
| if(size3 < size2) | |||
| return 0; | |||
| return safe_malloc_(size3); | |||
| } | |||
| static inline void *safe_malloc_add_4op_(size_t size1, size_t size2, size_t size3, size_t size4) | |||
| { | |||
| size2 += size1; | |||
| if(size2 < size1) | |||
| return 0; | |||
| size3 += size2; | |||
| if(size3 < size2) | |||
| return 0; | |||
| size4 += size3; | |||
| if(size4 < size3) | |||
| return 0; | |||
| return safe_malloc_(size4); | |||
| } | |||
| void *safe_malloc_mul_2op_(size_t size1, size_t size2) ; | |||
| static inline void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_t size3) | |||
| { | |||
| if(!size1 || !size2 || !size3) | |||
| return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ | |||
| if(size1 > SIZE_MAX / size2) | |||
| return 0; | |||
| size1 *= size2; | |||
| if(size1 > SIZE_MAX / size3) | |||
| return 0; | |||
| return malloc(size1*size3); | |||
| } | |||
| /* size1*size2 + size3 */ | |||
| static inline void *safe_malloc_mul2add_(size_t size1, size_t size2, size_t size3) | |||
| { | |||
| if(!size1 || !size2) | |||
| return safe_malloc_(size3); | |||
| if(size1 > SIZE_MAX / size2) | |||
| return 0; | |||
| return safe_malloc_add_2op_(size1*size2, size3); | |||
| } | |||
| /* size1 * (size2 + size3) */ | |||
| static inline void *safe_malloc_muladd2_(size_t size1, size_t size2, size_t size3) | |||
| { | |||
| if(!size1 || (!size2 && !size3)) | |||
| return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ | |||
| size2 += size3; | |||
| if(size2 < size3) | |||
| return 0; | |||
| if(size1 > SIZE_MAX / size2) | |||
| return 0; | |||
| return malloc(size1*size2); | |||
| } | |||
| static inline void *safe_realloc_(void *ptr, size_t size) | |||
| { | |||
| void *oldptr = ptr; | |||
| void *newptr = realloc(ptr, size); | |||
| if(size > 0 && newptr == 0) | |||
| free(oldptr); | |||
| return newptr; | |||
| } | |||
| static inline void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2) | |||
| { | |||
| size2 += size1; | |||
| if(size2 < size1) { | |||
| free(ptr); | |||
| return 0; | |||
| } | |||
| return realloc(ptr, size2); | |||
| } | |||
| static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) | |||
| { | |||
| size2 += size1; | |||
| if(size2 < size1) | |||
| return 0; | |||
| size3 += size2; | |||
| if(size3 < size2) | |||
| return 0; | |||
| return realloc(ptr, size3); | |||
| } | |||
| static inline void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4) | |||
| { | |||
| size2 += size1; | |||
| if(size2 < size1) | |||
| return 0; | |||
| size3 += size2; | |||
| if(size3 < size2) | |||
| return 0; | |||
| size4 += size3; | |||
| if(size4 < size3) | |||
| return 0; | |||
| return realloc(ptr, size4); | |||
| } | |||
| static inline void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2) | |||
| { | |||
| if(!size1 || !size2) | |||
| return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ | |||
| if(size1 > SIZE_MAX / size2) | |||
| return 0; | |||
| return safe_realloc_(ptr, size1*size2); | |||
| } | |||
| /* size1 * (size2 + size3) */ | |||
| static inline void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3) | |||
| { | |||
| if(!size1 || (!size2 && !size3)) | |||
| return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ | |||
| size2 += size3; | |||
| if(size2 < size3) | |||
| return 0; | |||
| return safe_realloc_mul_2op_(ptr, size1, size2); | |||
| } | |||
| #endif | |||
| @@ -0,0 +1,46 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2001-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__ASSERT_H | |||
| #define FLAC__ASSERT_H | |||
| /* we need this since some compilers (like MSVC) leave assert()s on release code (and we don't want to use their ASSERT) */ | |||
| #ifndef NDEBUG | |||
| #include <assert.h> | |||
| #define FLAC__ASSERT(x) assert(x) | |||
| #define FLAC__ASSERT_DECLARATION(x) x | |||
| #else | |||
| #define FLAC__ASSERT(x) | |||
| #define FLAC__ASSERT_DECLARATION(x) | |||
| #endif | |||
| #endif | |||
| @@ -0,0 +1,185 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2004-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__CALLBACK_H | |||
| #define FLAC__CALLBACK_H | |||
| #include "ordinals.h" | |||
| #include <stdlib.h> /* for size_t */ | |||
| /** \file include/FLAC/callback.h | |||
| * | |||
| * \brief | |||
| * This module defines the structures for describing I/O callbacks | |||
| * to the other FLAC interfaces. | |||
| * | |||
| * See the detailed documentation for callbacks in the | |||
| * \link flac_callbacks callbacks \endlink module. | |||
| */ | |||
| /** \defgroup flac_callbacks FLAC/callback.h: I/O callback structures | |||
| * \ingroup flac | |||
| * | |||
| * \brief | |||
| * This module defines the structures for describing I/O callbacks | |||
| * to the other FLAC interfaces. | |||
| * | |||
| * The purpose of the I/O callback functions is to create a common way | |||
| * for the metadata interfaces to handle I/O. | |||
| * | |||
| * Originally the metadata interfaces required filenames as the way of | |||
| * specifying FLAC files to operate on. This is problematic in some | |||
| * environments so there is an additional option to specify a set of | |||
| * callbacks for doing I/O on the FLAC file, instead of the filename. | |||
| * | |||
| * In addition to the callbacks, a FLAC__IOHandle type is defined as an | |||
| * opaque structure for a data source. | |||
| * | |||
| * The callback function prototypes are similar (but not identical) to the | |||
| * stdio functions fread, fwrite, fseek, ftell, feof, and fclose. If you use | |||
| * stdio streams to implement the callbacks, you can pass fread, fwrite, and | |||
| * fclose anywhere a FLAC__IOCallback_Read, FLAC__IOCallback_Write, or | |||
| * FLAC__IOCallback_Close is required, and a FILE* anywhere a FLAC__IOHandle | |||
| * is required. \warning You generally CANNOT directly use fseek or ftell | |||
| * for FLAC__IOCallback_Seek or FLAC__IOCallback_Tell since on most systems | |||
| * these use 32-bit offsets and FLAC requires 64-bit offsets to deal with | |||
| * large files. You will have to find an equivalent function (e.g. ftello), | |||
| * or write a wrapper. The same is true for feof() since this is usually | |||
| * implemented as a macro, not as a function whose address can be taken. | |||
| * | |||
| * \{ | |||
| */ | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| /** This is the opaque handle type used by the callbacks. Typically | |||
| * this is a \c FILE* or address of a file descriptor. | |||
| */ | |||
| typedef void* FLAC__IOHandle; | |||
| /** Signature for the read callback. | |||
| * The signature and semantics match POSIX fread() implementations | |||
| * and can generally be used interchangeably. | |||
| * | |||
| * \param ptr The address of the read buffer. | |||
| * \param size The size of the records to be read. | |||
| * \param nmemb The number of records to be read. | |||
| * \param handle The handle to the data source. | |||
| * \retval size_t | |||
| * The number of records read. | |||
| */ | |||
| typedef size_t (*FLAC__IOCallback_Read) (void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle); | |||
| /** Signature for the write callback. | |||
| * The signature and semantics match POSIX fwrite() implementations | |||
| * and can generally be used interchangeably. | |||
| * | |||
| * \param ptr The address of the write buffer. | |||
| * \param size The size of the records to be written. | |||
| * \param nmemb The number of records to be written. | |||
| * \param handle The handle to the data source. | |||
| * \retval size_t | |||
| * The number of records written. | |||
| */ | |||
| typedef size_t (*FLAC__IOCallback_Write) (const void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle); | |||
| /** Signature for the seek callback. | |||
| * The signature and semantics mostly match POSIX fseek() WITH ONE IMPORTANT | |||
| * EXCEPTION: the offset is a 64-bit type whereas fseek() is generally 'long' | |||
| * and 32-bits wide. | |||
| * | |||
| * \param handle The handle to the data source. | |||
| * \param offset The new position, relative to \a whence | |||
| * \param whence \c SEEK_SET, \c SEEK_CUR, or \c SEEK_END | |||
| * \retval int | |||
| * \c 0 on success, \c -1 on error. | |||
| */ | |||
| typedef int (*FLAC__IOCallback_Seek) (FLAC__IOHandle handle, FLAC__int64 offset, int whence); | |||
| /** Signature for the tell callback. | |||
| * The signature and semantics mostly match POSIX ftell() WITH ONE IMPORTANT | |||
| * EXCEPTION: the offset is a 64-bit type whereas ftell() is generally 'long' | |||
| * and 32-bits wide. | |||
| * | |||
| * \param handle The handle to the data source. | |||
| * \retval FLAC__int64 | |||
| * The current position on success, \c -1 on error. | |||
| */ | |||
| typedef FLAC__int64 (*FLAC__IOCallback_Tell) (FLAC__IOHandle handle); | |||
| /** Signature for the EOF callback. | |||
| * The signature and semantics mostly match POSIX feof() but WATCHOUT: | |||
| * on many systems, feof() is a macro, so in this case a wrapper function | |||
| * must be provided instead. | |||
| * | |||
| * \param handle The handle to the data source. | |||
| * \retval int | |||
| * \c 0 if not at end of file, nonzero if at end of file. | |||
| */ | |||
| typedef int (*FLAC__IOCallback_Eof) (FLAC__IOHandle handle); | |||
| /** Signature for the close callback. | |||
| * The signature and semantics match POSIX fclose() implementations | |||
| * and can generally be used interchangeably. | |||
| * | |||
| * \param handle The handle to the data source. | |||
| * \retval int | |||
| * \c 0 on success, \c EOF on error. | |||
| */ | |||
| typedef int (*FLAC__IOCallback_Close) (FLAC__IOHandle handle); | |||
| /** A structure for holding a set of callbacks. | |||
| * Each FLAC interface that requires a FLAC__IOCallbacks structure will | |||
| * describe which of the callbacks are required. The ones that are not | |||
| * required may be set to NULL. | |||
| * | |||
| * If the seek requirement for an interface is optional, you can signify that | |||
| * a data source is not seekable by setting the \a seek field to \c NULL. | |||
| */ | |||
| typedef struct { | |||
| FLAC__IOCallback_Read read; | |||
| FLAC__IOCallback_Write write; | |||
| FLAC__IOCallback_Seek seek; | |||
| FLAC__IOCallback_Tell tell; | |||
| FLAC__IOCallback_Eof eof; | |||
| FLAC__IOCallback_Close close; | |||
| } FLAC__IOCallbacks; | |||
| /* \} */ | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif | |||
| @@ -0,0 +1,213 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2012-2016 Xiph.org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| /* This is the preferred 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) && !defined(__cplusplus) | |||
| #define inline __inline | |||
| #endif | |||
| #if defined __INTEL_COMPILER || (defined _MSC_VER && defined _WIN64) | |||
| /* MSVS generates VERY slow 32-bit code with __restrict */ | |||
| #define flac_restrict __restrict | |||
| #elif defined __GNUC__ | |||
| #define flac_restrict __restrict__ | |||
| #else | |||
| #define flac_restrict | |||
| #endif | |||
| #define FLAC__U64L(x) x##ULL | |||
| #if defined _MSC_VER || defined __MINGW32__ | |||
| #define FLAC__STRCASECMP _stricmp | |||
| #define FLAC__STRNCASECMP _strnicmp | |||
| #elif defined __BORLANDC__ | |||
| #define FLAC__STRCASECMP stricmp | |||
| #define FLAC__STRNCASECMP strnicmp | |||
| #else | |||
| #define FLAC__STRCASECMP strcasecmp | |||
| #define FLAC__STRNCASECMP strncasecmp | |||
| #endif | |||
| #if defined _MSC_VER || defined __MINGW32__ || 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 | |||
| #if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200809L) | |||
| #include <fcntl.h> | |||
| #else | |||
| #include <sys/types.h> /* some flavors of BSD (like OS X) require this to get time_t */ | |||
| #include <utime.h> /* for utime() */ | |||
| #endif | |||
| #endif | |||
| #if defined _MSC_VER | |||
| # if _MSC_VER >= 1800 | |||
| # include <inttypes.h> | |||
| # elif _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 | |||
| # 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 */ | |||
| #include "win_utf8_io.h" | |||
| #define flac_printf printf_utf8 | |||
| #define flac_fprintf fprintf_utf8 | |||
| #define flac_vfprintf vfprintf_utf8 | |||
| #include "windows_unicode_filenames.h" | |||
| #define flac_fopen flac_internal_fopen_utf8 | |||
| #define flac_chmod flac_internal_chmod_utf8 | |||
| #define flac_utime flac_internal_utime_utf8 | |||
| #define flac_unlink flac_internal_unlink_utf8 | |||
| #define flac_rename flac_internal_rename_utf8 | |||
| #define flac_stat flac_internal_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_unlink unlink | |||
| #define flac_rename rename | |||
| #define flac_stat stat | |||
| #if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200809L) | |||
| #define flac_utime(a, b) utimensat (AT_FDCWD, a, *b, 0) | |||
| #else | |||
| #define flac_utime utime | |||
| #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 | |||
| #ifdef ANDROID | |||
| #include <limits.h> | |||
| #endif | |||
| #ifndef M_LN2 | |||
| #define M_LN2 0.69314718055994530942 | |||
| #endif | |||
| #ifndef M_PI | |||
| #define M_PI 3.14159265358979323846 | |||
| #endif | |||
| /* FLAC needs to compile and work correctly on systems with a normal ISO C99 | |||
| * snprintf as well as Microsoft Visual Studio which has an non-standards | |||
| * conformant snprint_s function. | |||
| * | |||
| * This function wraps the MS version to behave more like the ISO version. | |||
| */ | |||
| #include <stdarg.h> | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| int flac_snprintf(char *str, size_t size, const char *fmt, ...); | |||
| int flac_vsnprintf(char *str, size_t size, const char *fmt, va_list va); | |||
| #ifdef __cplusplus | |||
| }; | |||
| #endif | |||
| #endif /* FLAC__SHARE__COMPAT_H */ | |||
| @@ -0,0 +1,84 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2012-2016 Xiph.org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| /* It is assumed that this header will be included after "config.h". */ | |||
| #if HAVE_BSWAP32 /* GCC and Clang */ | |||
| /* GCC prior to 4.8 didn't provide bswap16 on x86_64 */ | |||
| #if ! HAVE_BSWAP16 | |||
| static inline unsigned short __builtin_bswap16(unsigned short a) | |||
| { | |||
| return (a<<8)|(a>>8); | |||
| } | |||
| #endif | |||
| #define ENDSWAP_16(x) (__builtin_bswap16 (x)) | |||
| #define ENDSWAP_32(x) (__builtin_bswap32 (x)) | |||
| #define ENDSWAP_64(x) (__builtin_bswap64 (x)) | |||
| #elif defined _MSC_VER /* Windows */ | |||
| #include <stdlib.h> | |||
| #define ENDSWAP_16(x) (_byteswap_ushort (x)) | |||
| #define ENDSWAP_32(x) (_byteswap_ulong (x)) | |||
| #define ENDSWAP_64(x) (_byteswap_uint64 (x)) | |||
| #elif defined HAVE_BYTESWAP_H /* Linux */ | |||
| #include <byteswap.h> | |||
| #define ENDSWAP_16(x) (bswap_16 (x)) | |||
| #define ENDSWAP_32(x) (bswap_32 (x)) | |||
| #define ENDSWAP_64(x) (bswap_64 (x)) | |||
| #else | |||
| #define ENDSWAP_16(x) ((((x) >> 8) & 0xFF) | (((x) & 0xFF) << 8)) | |||
| #define ENDSWAP_32(x) ((((x) >> 24) & 0xFF) | (((x) >> 8) & 0xFF00) | (((x) & 0xFF00) << 8) | (((x) & 0xFF) << 24)) | |||
| #define ENDSWAP_64(x) ((ENDSWAP_32(((x) >> 32) & 0xFFFFFFFF)) | (ENDSWAP_32((x) & 0xFFFFFFFF) << 32)) | |||
| #endif | |||
| /* Host to little-endian byte swapping (for MD5 calculation) */ | |||
| #if CPU_IS_BIG_ENDIAN | |||
| #define H2LE_16(x) ENDSWAP_16 (x) | |||
| #define H2LE_32(x) ENDSWAP_32 (x) | |||
| #else | |||
| #define H2LE_16(x) (x) | |||
| #define H2LE_32(x) (x) | |||
| #endif | |||
| @@ -0,0 +1,97 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__EXPORT_H | |||
| #define FLAC__EXPORT_H | |||
| /** \file include/FLAC/export.h | |||
| * | |||
| * \brief | |||
| * This module contains \#defines and symbols for exporting function | |||
| * calls, and providing version information and compiled-in features. | |||
| * | |||
| * See the \link flac_export export \endlink module. | |||
| */ | |||
| /** \defgroup flac_export FLAC/export.h: export symbols | |||
| * \ingroup flac | |||
| * | |||
| * \brief | |||
| * This module contains \#defines and symbols for exporting function | |||
| * calls, and providing version information and compiled-in features. | |||
| * | |||
| * If you are compiling with MSVC and will link to the static library | |||
| * (libFLAC.lib) you should define FLAC__NO_DLL in your project to | |||
| * make sure the symbols are exported properly. | |||
| * | |||
| * \{ | |||
| */ | |||
| #if defined(FLAC__NO_DLL) | |||
| #define FLAC_API | |||
| #elif defined(_WIN32) | |||
| #ifdef FLAC_API_EXPORTS | |||
| #define FLAC_API __declspec(dllexport) | |||
| #else | |||
| #define FLAC_API __declspec(dllimport) | |||
| #endif | |||
| #elif defined(FLAC__USE_VISIBILITY_ATTR) | |||
| #define FLAC_API __attribute__ ((visibility ("default"))) | |||
| #else | |||
| #define FLAC_API | |||
| #endif | |||
| /** These \#defines will mirror the libtool-based library version number, see | |||
| * http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning | |||
| */ | |||
| #define FLAC_API_VERSION_CURRENT 11 | |||
| #define FLAC_API_VERSION_REVISION 0 /**< see above */ | |||
| #define FLAC_API_VERSION_AGE 3 /**< see above */ | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| /** \c 1 if the library has been compiled with support for Ogg FLAC, else \c 0. */ | |||
| extern FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC; | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| /* \} */ | |||
| #endif | |||
| @@ -0,0 +1,184 @@ | |||
| /* | |||
| NOTE: | |||
| I cannot get the vanilla getopt code to work (i.e. compile only what | |||
| is needed and not duplicate symbols found in the standard library) | |||
| on all the platforms that FLAC supports. In particular the gating | |||
| of code with the ELIDE_CODE #define is not accurate enough on systems | |||
| that are POSIX but not glibc. If someone has a patch that works on | |||
| GNU/Linux, Darwin, AND Solaris please submit it on the project page: | |||
| https://sourceforge.net/p/flac/patches/ | |||
| In the meantime I have munged the global symbols and removed gates | |||
| around code, while at the same time trying to touch the original as | |||
| little as possible. | |||
| */ | |||
| /* Declarations for getopt. | |||
| Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc. | |||
| This file is part of the GNU C Library. | |||
| The GNU C Library is free software; you can redistribute it and/or | |||
| modify it under the terms of the GNU Library General Public License as | |||
| published by the Free Software Foundation; either version 2 of the | |||
| License, or (at your option) any later version. | |||
| The GNU C Library is distributed in the hope that it will be useful, | |||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| Library General Public License for more details. | |||
| You should have received a copy of the GNU Library General Public | |||
| License along with the GNU C Library; see the file COPYING.LIB. If not, | |||
| write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |||
| Boston, MA 02110-1301, USA. */ | |||
| #ifndef SHARE__GETOPT_H | |||
| #define SHARE__GETOPT_H | |||
| /*[JEC] was:#ifndef __need_getopt*/ | |||
| /*[JEC] was:# define _GETOPT_H 1*/ | |||
| /*[JEC] was:#endif*/ | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| /* For communication from `share__getopt' to the caller. | |||
| When `share__getopt' finds an option that takes an argument, | |||
| the argument value is returned here. | |||
| Also, when `ordering' is RETURN_IN_ORDER, | |||
| each non-option ARGV-element is returned here. */ | |||
| extern char *share__optarg; | |||
| /* Index in ARGV of the next element to be scanned. | |||
| This is used for communication to and from the caller | |||
| and for communication between successive calls to `share__getopt'. | |||
| On entry to `share__getopt', zero means this is the first call; initialize. | |||
| When `share__getopt' returns -1, this is the index of the first of the | |||
| non-option elements that the caller should itself scan. | |||
| Otherwise, `share__optind' communicates from one call to the next | |||
| how much of ARGV has been scanned so far. */ | |||
| extern int share__optind; | |||
| /* Callers store zero here to inhibit the error message `share__getopt' prints | |||
| for unrecognized options. */ | |||
| extern int share__opterr; | |||
| /* Set to an option character which was unrecognized. */ | |||
| extern int share__optopt; | |||
| /*[JEC] was:#ifndef __need_getopt */ | |||
| /* Describe the long-named options requested by the application. | |||
| The LONG_OPTIONS argument to share__getopt_long or share__getopt_long_only is a vector | |||
| of `struct share__option' terminated by an element containing a name which is | |||
| zero. | |||
| The field `has_arg' is: | |||
| share__no_argument (or 0) if the option does not take an argument, | |||
| share__required_argument (or 1) if the option requires an argument, | |||
| share__optional_argument (or 2) if the option takes an optional argument. | |||
| If the field `flag' is not NULL, it points to a variable that is set | |||
| to the value given in the field `val' when the option is found, but | |||
| left unchanged if the option is not found. | |||
| To have a long-named option do something other than set an `int' to | |||
| a compiled-in constant, such as set a value from `share__optarg', set the | |||
| option's `flag' field to zero and its `val' field to a nonzero | |||
| value (the equivalent single-letter option character, if there is | |||
| one). For long options that have a zero `flag' field, `share__getopt' | |||
| returns the contents of the `val' field. */ | |||
| struct share__option | |||
| { | |||
| # if defined __STDC__ && __STDC__ | |||
| const char *name; | |||
| # else | |||
| char *name; | |||
| # endif | |||
| /* has_arg can't be an enum because some compilers complain about | |||
| type mismatches in all the code that assumes it is an int. */ | |||
| int has_arg; | |||
| int *flag; | |||
| int val; | |||
| }; | |||
| /* Names for the values of the `has_arg' field of `struct share__option'. */ | |||
| # define share__no_argument 0 | |||
| # define share__required_argument 1 | |||
| # define share__optional_argument 2 | |||
| /*[JEC] was:#endif*/ /* need getopt */ | |||
| /* Get definitions and prototypes for functions to process the | |||
| arguments in ARGV (ARGC of them, minus the program name) for | |||
| options given in OPTS. | |||
| Return the option character from OPTS just read. Return -1 when | |||
| there are no more options. For unrecognized options, or options | |||
| missing arguments, `share__optopt' is set to the option letter, and '?' is | |||
| returned. | |||
| The OPTS string is a list of characters which are recognized option | |||
| letters, optionally followed by colons, specifying that that letter | |||
| takes an argument, to be placed in `share__optarg'. | |||
| If a letter in OPTS is followed by two colons, its argument is | |||
| optional. This behavior is specific to the GNU `share__getopt'. | |||
| The argument `--' causes premature termination of argument | |||
| scanning, explicitly telling `share__getopt' that there are no more | |||
| options. | |||
| If OPTS begins with `--', then non-option arguments are treated as | |||
| arguments to the option '\0'. This behavior is specific to the GNU | |||
| `share__getopt'. */ | |||
| /*[JEC] was:#if defined __STDC__ && __STDC__*/ | |||
| /*[JEC] was:# ifdef __GNU_LIBRARY__*/ | |||
| /* Many other libraries have conflicting prototypes for getopt, with | |||
| differences in the consts, in stdlib.h. To avoid compilation | |||
| errors, only prototype getopt for the GNU C library. */ | |||
| extern int share__getopt (int argc, char *const *argv, const char *shortopts); | |||
| /*[JEC] was:# else*/ /* not __GNU_LIBRARY__ */ | |||
| /*[JEC] was:extern int getopt ();*/ | |||
| /*[JEC] was:# endif*/ /* __GNU_LIBRARY__ */ | |||
| /*[JEC] was:# ifndef __need_getopt*/ | |||
| extern int share__getopt_long (int argc, char *const *argv, const char *shortopts, | |||
| const struct share__option *longopts, int *longind); | |||
| extern int share__getopt_long_only (int argc, char *const *argv, | |||
| const char *shortopts, | |||
| const struct share__option *longopts, int *longind); | |||
| /* Internal only. Users should not call this directly. */ | |||
| extern int share___getopt_internal (int argc, char *const *argv, | |||
| const char *shortopts, | |||
| const struct share__option *longopts, int *longind, | |||
| int long_only); | |||
| /*[JEC] was:# endif*/ | |||
| /*[JEC] was:#else*/ /* not __STDC__ */ | |||
| /*[JEC] was:extern int getopt ();*/ | |||
| /*[JEC] was:# ifndef __need_getopt*/ | |||
| /*[JEC] was:extern int getopt_long ();*/ | |||
| /*[JEC] was:extern int getopt_long_only ();*/ | |||
| /*[JEC] was:extern int _getopt_internal ();*/ | |||
| /*[JEC] was:# endif*/ | |||
| /*[JEC] was:#endif*/ /* __STDC__ */ | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| /* Make sure we later can get all the definitions and declarations. */ | |||
| /*[JEC] was:#undef __need_getopt*/ | |||
| #endif /* getopt.h */ | |||
| @@ -0,0 +1,30 @@ | |||
| /* grabbag - Convenience lib for various routines common to several tools | |||
| * Copyright (C) 2002-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * This library is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation; either | |||
| * version 2.1 of the License, or (at your option) any later version. | |||
| * | |||
| * This library is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| * Lesser General Public License for more details. | |||
| * | |||
| * You should have received a copy of the GNU Lesser General Public | |||
| * License along with this library; if not, write to the Free Software | |||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
| */ | |||
| #ifndef SHARE__GRABBAG_H | |||
| #define SHARE__GRABBAG_H | |||
| /* These can't be included by themselves, only from within grabbag.h */ | |||
| #include "grabbag/cuesheet.h" | |||
| #include "grabbag/file.h" | |||
| #include "grabbag/picture.h" | |||
| #include "grabbag/replaygain.h" | |||
| #include "grabbag/seektable.h" | |||
| #endif | |||
| @@ -0,0 +1,73 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2001-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include "include/private/bitmath.h" | |||
| /* An example of what FLAC__bitmath_silog2() computes: | |||
| * | |||
| * silog2(-10) = 5 | |||
| * silog2(- 9) = 5 | |||
| * silog2(- 8) = 4 | |||
| * silog2(- 7) = 4 | |||
| * silog2(- 6) = 4 | |||
| * silog2(- 5) = 4 | |||
| * silog2(- 4) = 3 | |||
| * silog2(- 3) = 3 | |||
| * silog2(- 2) = 2 | |||
| * silog2(- 1) = 2 | |||
| * silog2( 0) = 0 | |||
| * silog2( 1) = 2 | |||
| * silog2( 2) = 3 | |||
| * silog2( 3) = 3 | |||
| * silog2( 4) = 4 | |||
| * silog2( 5) = 4 | |||
| * silog2( 6) = 4 | |||
| * silog2( 7) = 4 | |||
| * silog2( 8) = 5 | |||
| * silog2( 9) = 5 | |||
| * silog2( 10) = 5 | |||
| */ | |||
| uint32_t FLAC__bitmath_silog2(FLAC__int64 v) | |||
| { | |||
| if(v == 0) | |||
| return 0; | |||
| if(v == -1) | |||
| return 2; | |||
| v = (v < 0) ? (-(v+1)) : v; | |||
| return FLAC__bitmath_ilog2_wide(v)+2; | |||
| } | |||
| @@ -0,0 +1,885 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #include "include/private/bitwriter.h" | |||
| #include "include/private/crc.h" | |||
| #include "include/private/macros.h" | |||
| #include "../assert.h" | |||
| #include "../alloc.h" | |||
| #include "../compat.h" | |||
| #include "../endswap.h" | |||
| /* Things should be fastest when this matches the machine word size */ | |||
| /* WATCHOUT: if you change this you must also change the following #defines down to SWAP_BE_WORD_TO_HOST below to match */ | |||
| /* WATCHOUT: there are a few places where the code will not work unless bwword is >= 32 bits wide */ | |||
| #if (ENABLE_64_BIT_WORDS == 0) | |||
| typedef FLAC__uint32 bwword; | |||
| #define FLAC__BYTES_PER_WORD 4 /* sizeof bwword */ | |||
| #define FLAC__BITS_PER_WORD 32 | |||
| /* SWAP_BE_WORD_TO_HOST swaps bytes in a bwword (which is always big-endian) if necessary to match host byte order */ | |||
| #if WORDS_BIGENDIAN | |||
| #define SWAP_BE_WORD_TO_HOST(x) (x) | |||
| #else | |||
| #define SWAP_BE_WORD_TO_HOST(x) ENDSWAP_32(x) | |||
| #endif | |||
| #else | |||
| typedef FLAC__uint64 bwword; | |||
| #define FLAC__BYTES_PER_WORD 8 /* sizeof bwword */ | |||
| #define FLAC__BITS_PER_WORD 64 | |||
| /* SWAP_BE_WORD_TO_HOST swaps bytes in a bwword (which is always big-endian) if necessary to match host byte order */ | |||
| #if WORDS_BIGENDIAN | |||
| #define SWAP_BE_WORD_TO_HOST(x) (x) | |||
| #else | |||
| #define SWAP_BE_WORD_TO_HOST(x) ENDSWAP_64(x) | |||
| #endif | |||
| #endif | |||
| /* | |||
| * The default capacity here doesn't matter too much. The buffer always grows | |||
| * to hold whatever is written to it. Usually the encoder will stop adding at | |||
| * a frame or metadata block, then write that out and clear the buffer for the | |||
| * next one. | |||
| */ | |||
| static const uint32_t FLAC__BITWRITER_DEFAULT_CAPACITY = 32768u / sizeof(bwword); /* size in words */ | |||
| /* When growing, increment 4K at a time */ | |||
| static const uint32_t FLAC__BITWRITER_DEFAULT_INCREMENT = 4096u / sizeof(bwword); /* size in words */ | |||
| #define FLAC__WORDS_TO_BITS(words) ((words) * FLAC__BITS_PER_WORD) | |||
| #define FLAC__TOTAL_BITS(bw) (FLAC__WORDS_TO_BITS((bw)->words) + (bw)->bits) | |||
| struct FLAC__BitWriter { | |||
| bwword *buffer; | |||
| bwword accum; /* accumulator; bits are right-justified; when full, accum is appended to buffer */ | |||
| uint32_t capacity; /* capacity of buffer in words */ | |||
| uint32_t words; /* # of complete words in buffer */ | |||
| uint32_t bits; /* # of used bits in accum */ | |||
| }; | |||
| /* * WATCHOUT: The current implementation only grows the buffer. */ | |||
| #ifndef __SUNPRO_C | |||
| static | |||
| #endif | |||
| FLAC__bool bitwriter_grow_(FLAC__BitWriter *bw, uint32_t bits_to_add) | |||
| { | |||
| uint32_t new_capacity; | |||
| bwword *new_buffer; | |||
| FLAC__ASSERT(0 != bw); | |||
| FLAC__ASSERT(0 != bw->buffer); | |||
| /* calculate total words needed to store 'bits_to_add' additional bits */ | |||
| new_capacity = bw->words + ((bw->bits + bits_to_add + FLAC__BITS_PER_WORD - 1) / FLAC__BITS_PER_WORD); | |||
| /* it's possible (due to pessimism in the growth estimation that | |||
| * leads to this call) that we don't actually need to grow | |||
| */ | |||
| if(bw->capacity >= new_capacity) | |||
| return true; | |||
| /* round up capacity increase to the nearest FLAC__BITWRITER_DEFAULT_INCREMENT */ | |||
| if((new_capacity - bw->capacity) % FLAC__BITWRITER_DEFAULT_INCREMENT) | |||
| new_capacity += FLAC__BITWRITER_DEFAULT_INCREMENT - ((new_capacity - bw->capacity) % FLAC__BITWRITER_DEFAULT_INCREMENT); | |||
| /* make sure we got everything right */ | |||
| FLAC__ASSERT(0 == (new_capacity - bw->capacity) % FLAC__BITWRITER_DEFAULT_INCREMENT); | |||
| FLAC__ASSERT(new_capacity > bw->capacity); | |||
| FLAC__ASSERT(new_capacity >= bw->words + ((bw->bits + bits_to_add + FLAC__BITS_PER_WORD - 1) / FLAC__BITS_PER_WORD)); | |||
| new_buffer = safe_realloc_mul_2op_(bw->buffer, sizeof(bwword), /*times*/new_capacity); | |||
| if(new_buffer == 0) | |||
| return false; | |||
| bw->buffer = new_buffer; | |||
| bw->capacity = new_capacity; | |||
| return true; | |||
| } | |||
| /*********************************************************************** | |||
| * | |||
| * Class constructor/destructor | |||
| * | |||
| ***********************************************************************/ | |||
| FLAC__BitWriter *FLAC__bitwriter_new(void) | |||
| { | |||
| FLAC__BitWriter *bw = calloc(1, sizeof(FLAC__BitWriter)); | |||
| /* note that calloc() sets all members to 0 for us */ | |||
| return bw; | |||
| } | |||
| void FLAC__bitwriter_delete(FLAC__BitWriter *bw) | |||
| { | |||
| FLAC__ASSERT(0 != bw); | |||
| FLAC__bitwriter_free(bw); | |||
| free(bw); | |||
| } | |||
| /*********************************************************************** | |||
| * | |||
| * Public class methods | |||
| * | |||
| ***********************************************************************/ | |||
| FLAC__bool FLAC__bitwriter_init(FLAC__BitWriter *bw) | |||
| { | |||
| FLAC__ASSERT(0 != bw); | |||
| bw->words = bw->bits = 0; | |||
| bw->capacity = FLAC__BITWRITER_DEFAULT_CAPACITY; | |||
| bw->buffer = malloc(sizeof(bwword) * bw->capacity); | |||
| if(bw->buffer == 0) | |||
| return false; | |||
| return true; | |||
| } | |||
| void FLAC__bitwriter_free(FLAC__BitWriter *bw) | |||
| { | |||
| FLAC__ASSERT(0 != bw); | |||
| if(0 != bw->buffer) | |||
| free(bw->buffer); | |||
| bw->buffer = 0; | |||
| bw->capacity = 0; | |||
| bw->words = bw->bits = 0; | |||
| } | |||
| void FLAC__bitwriter_clear(FLAC__BitWriter *bw) | |||
| { | |||
| bw->words = bw->bits = 0; | |||
| } | |||
| void FLAC__bitwriter_dump(const FLAC__BitWriter *bw, FILE *out) | |||
| { | |||
| uint32_t i, j; | |||
| if(bw == 0) { | |||
| fprintf(out, "bitwriter is NULL\n"); | |||
| } | |||
| else { | |||
| fprintf(out, "bitwriter: capacity=%u words=%u bits=%u total_bits=%u\n", bw->capacity, bw->words, bw->bits, FLAC__TOTAL_BITS(bw)); | |||
| for(i = 0; i < bw->words; i++) { | |||
| fprintf(out, "%08X: ", i); | |||
| for(j = 0; j < FLAC__BITS_PER_WORD; j++) | |||
| fprintf(out, "%01d", bw->buffer[i] & ((bwword)1 << (FLAC__BITS_PER_WORD-j-1)) ? 1:0); | |||
| fprintf(out, "\n"); | |||
| } | |||
| if(bw->bits > 0) { | |||
| fprintf(out, "%08X: ", i); | |||
| for(j = 0; j < bw->bits; j++) | |||
| fprintf(out, "%01d", bw->accum & ((bwword)1 << (bw->bits-j-1)) ? 1:0); | |||
| fprintf(out, "\n"); | |||
| } | |||
| } | |||
| } | |||
| FLAC__bool FLAC__bitwriter_get_write_crc16(FLAC__BitWriter *bw, FLAC__uint16 *crc) | |||
| { | |||
| const FLAC__byte *buffer; | |||
| size_t bytes; | |||
| FLAC__ASSERT((bw->bits & 7) == 0); /* assert that we're byte-aligned */ | |||
| if(!FLAC__bitwriter_get_buffer(bw, &buffer, &bytes)) | |||
| return false; | |||
| *crc = (FLAC__uint16)FLAC__crc16(buffer, bytes); | |||
| FLAC__bitwriter_release_buffer(bw); | |||
| return true; | |||
| } | |||
| FLAC__bool FLAC__bitwriter_get_write_crc8(FLAC__BitWriter *bw, FLAC__byte *crc) | |||
| { | |||
| const FLAC__byte *buffer; | |||
| size_t bytes; | |||
| FLAC__ASSERT((bw->bits & 7) == 0); /* assert that we're byte-aligned */ | |||
| if(!FLAC__bitwriter_get_buffer(bw, &buffer, &bytes)) | |||
| return false; | |||
| *crc = FLAC__crc8(buffer, bytes); | |||
| FLAC__bitwriter_release_buffer(bw); | |||
| return true; | |||
| } | |||
| FLAC__bool FLAC__bitwriter_is_byte_aligned(const FLAC__BitWriter *bw) | |||
| { | |||
| return ((bw->bits & 7) == 0); | |||
| } | |||
| uint32_t FLAC__bitwriter_get_input_bits_unconsumed(const FLAC__BitWriter *bw) | |||
| { | |||
| return FLAC__TOTAL_BITS(bw); | |||
| } | |||
| FLAC__bool FLAC__bitwriter_get_buffer(FLAC__BitWriter *bw, const FLAC__byte **buffer, size_t *bytes) | |||
| { | |||
| FLAC__ASSERT((bw->bits & 7) == 0); | |||
| /* double protection */ | |||
| if(bw->bits & 7) | |||
| return false; | |||
| /* if we have bits in the accumulator we have to flush those to the buffer first */ | |||
| if(bw->bits) { | |||
| FLAC__ASSERT(bw->words <= bw->capacity); | |||
| if(bw->words == bw->capacity && !bitwriter_grow_(bw, FLAC__BITS_PER_WORD)) | |||
| return false; | |||
| /* append bits as complete word to buffer, but don't change bw->accum or bw->bits */ | |||
| bw->buffer[bw->words] = SWAP_BE_WORD_TO_HOST(bw->accum << (FLAC__BITS_PER_WORD-bw->bits)); | |||
| } | |||
| /* now we can just return what we have */ | |||
| *buffer = (FLAC__byte*)bw->buffer; | |||
| *bytes = (FLAC__BYTES_PER_WORD * bw->words) + (bw->bits >> 3); | |||
| return true; | |||
| } | |||
| void FLAC__bitwriter_release_buffer(FLAC__BitWriter *bw) | |||
| { | |||
| /* nothing to do. in the future, strict checking of a 'writer-is-in- | |||
| * get-mode' flag could be added everywhere and then cleared here | |||
| */ | |||
| (void)bw; | |||
| } | |||
| inline FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, uint32_t bits) | |||
| { | |||
| uint32_t n; | |||
| FLAC__ASSERT(0 != bw); | |||
| FLAC__ASSERT(0 != bw->buffer); | |||
| if(bits == 0) | |||
| return true; | |||
| /* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+bits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */ | |||
| if(bw->capacity <= bw->words + bits && !bitwriter_grow_(bw, bits)) | |||
| return false; | |||
| /* first part gets to word alignment */ | |||
| if(bw->bits) { | |||
| n = flac_min(FLAC__BITS_PER_WORD - bw->bits, bits); | |||
| bw->accum <<= n; | |||
| bits -= n; | |||
| bw->bits += n; | |||
| if(bw->bits == FLAC__BITS_PER_WORD) { | |||
| bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum); | |||
| bw->bits = 0; | |||
| } | |||
| else | |||
| return true; | |||
| } | |||
| /* do whole words */ | |||
| while(bits >= FLAC__BITS_PER_WORD) { | |||
| bw->buffer[bw->words++] = 0; | |||
| bits -= FLAC__BITS_PER_WORD; | |||
| } | |||
| /* do any leftovers */ | |||
| if(bits > 0) { | |||
| bw->accum = 0; | |||
| bw->bits = bits; | |||
| } | |||
| return true; | |||
| } | |||
| static inline FLAC__bool FLAC__bitwriter_write_raw_uint32_nocheck(FLAC__BitWriter *bw, FLAC__uint32 val, uint32_t bits) | |||
| { | |||
| register uint32_t left; | |||
| /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */ | |||
| FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32); | |||
| if(bw == 0 || bw->buffer == 0) | |||
| return false; | |||
| if (bits > 32) | |||
| return false; | |||
| if(bits == 0) | |||
| return true; | |||
| FLAC__ASSERT((bits == 32) || (val>>bits == 0)); | |||
| /* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+bits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */ | |||
| if(bw->capacity <= bw->words + bits && !bitwriter_grow_(bw, bits)) | |||
| return false; | |||
| left = FLAC__BITS_PER_WORD - bw->bits; | |||
| if(bits < left) { | |||
| bw->accum <<= bits; | |||
| bw->accum |= val; | |||
| bw->bits += bits; | |||
| } | |||
| else if(bw->bits) { /* WATCHOUT: if bw->bits == 0, left==FLAC__BITS_PER_WORD and bw->accum<<=left is a NOP instead of setting to 0 */ | |||
| bw->accum <<= left; | |||
| bw->accum |= val >> (bw->bits = bits - left); | |||
| bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum); | |||
| bw->accum = val; /* unused top bits can contain garbage */ | |||
| } | |||
| else { /* at this point bits == FLAC__BITS_PER_WORD == 32 and bw->bits == 0 */ | |||
| bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST((bwword)val); | |||
| } | |||
| return true; | |||
| } | |||
| inline FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FLAC__uint32 val, uint32_t bits) | |||
| { | |||
| /* check that unused bits are unset */ | |||
| if((bits < 32) && (val>>bits != 0)) | |||
| return false; | |||
| return FLAC__bitwriter_write_raw_uint32_nocheck(bw, val, bits); | |||
| } | |||
| inline FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, uint32_t bits) | |||
| { | |||
| /* zero-out unused bits */ | |||
| if(bits < 32) | |||
| val &= (~(0xffffffff << bits)); | |||
| return FLAC__bitwriter_write_raw_uint32_nocheck(bw, (FLAC__uint32)val, bits); | |||
| } | |||
| inline FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, uint32_t bits) | |||
| { | |||
| /* this could be a little faster but it's not used for much */ | |||
| if(bits > 32) { | |||
| return | |||
| FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)(val>>32), bits-32) && | |||
| FLAC__bitwriter_write_raw_uint32_nocheck(bw, (FLAC__uint32)val, 32); | |||
| } | |||
| else | |||
| return FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)val, bits); | |||
| } | |||
| 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 */ | |||
| if(!FLAC__bitwriter_write_raw_uint32_nocheck(bw, val & 0xff, 8)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32_nocheck(bw, (val>>8) & 0xff, 8)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32_nocheck(bw, (val>>16) & 0xff, 8)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32_nocheck(bw, val>>24, 8)) | |||
| return false; | |||
| return true; | |||
| } | |||
| inline FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], uint32_t nvals) | |||
| { | |||
| uint32_t i; | |||
| /* grow capacity upfront to prevent constant reallocation during writes */ | |||
| if(bw->capacity <= bw->words + nvals / (FLAC__BITS_PER_WORD / 8) + 1 && !bitwriter_grow_(bw, nvals * 8)) | |||
| return false; | |||
| /* this could be faster but currently we don't need it to be since it's only used for writing metadata */ | |||
| for(i = 0; i < nvals; i++) { | |||
| if(!FLAC__bitwriter_write_raw_uint32_nocheck(bw, (FLAC__uint32)(vals[i]), 8)) | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| FLAC__bool FLAC__bitwriter_write_unary_unsigned(FLAC__BitWriter *bw, uint32_t val) | |||
| { | |||
| if(val < 32) | |||
| return FLAC__bitwriter_write_raw_uint32_nocheck(bw, 1, ++val); | |||
| else | |||
| return | |||
| FLAC__bitwriter_write_zeroes(bw, val) && | |||
| FLAC__bitwriter_write_raw_uint32_nocheck(bw, 1, 1); | |||
| } | |||
| uint32_t FLAC__bitwriter_rice_bits(FLAC__int32 val, uint32_t parameter) | |||
| { | |||
| FLAC__uint32 uval; | |||
| FLAC__ASSERT(parameter < 32); | |||
| /* fold signed to uint32_t; actual formula is: negative(v)? -2v-1 : 2v */ | |||
| uval = val; | |||
| uval <<= 1; | |||
| uval ^= (val>>31); | |||
| return 1 + parameter + (uval >> parameter); | |||
| } | |||
| #if 0 /* UNUSED */ | |||
| uint32_t FLAC__bitwriter_golomb_bits_signed(int val, uint32_t parameter) | |||
| { | |||
| uint32_t bits, msbs, uval; | |||
| uint32_t k; | |||
| FLAC__ASSERT(parameter > 0); | |||
| /* fold signed to uint32_t */ | |||
| if(val < 0) | |||
| uval = (uint32_t)(((-(++val)) << 1) + 1); | |||
| else | |||
| uval = (uint32_t)(val << 1); | |||
| k = FLAC__bitmath_ilog2(parameter); | |||
| if(parameter == 1u<<k) { | |||
| FLAC__ASSERT(k <= 30); | |||
| msbs = uval >> k; | |||
| bits = 1 + k + msbs; | |||
| } | |||
| else { | |||
| uint32_t q, r, d; | |||
| d = (1 << (k+1)) - parameter; | |||
| q = uval / parameter; | |||
| r = uval - (q * parameter); | |||
| bits = 1 + q + k; | |||
| if(r >= d) | |||
| bits++; | |||
| } | |||
| return bits; | |||
| } | |||
| uint32_t FLAC__bitwriter_golomb_bits_unsigned(uint32_t uval, uint32_t parameter) | |||
| { | |||
| uint32_t bits, msbs; | |||
| uint32_t k; | |||
| FLAC__ASSERT(parameter > 0); | |||
| k = FLAC__bitmath_ilog2(parameter); | |||
| if(parameter == 1u<<k) { | |||
| FLAC__ASSERT(k <= 30); | |||
| msbs = uval >> k; | |||
| bits = 1 + k + msbs; | |||
| } | |||
| else { | |||
| uint32_t q, r, d; | |||
| d = (1 << (k+1)) - parameter; | |||
| q = uval / parameter; | |||
| r = uval - (q * parameter); | |||
| bits = 1 + q + k; | |||
| if(r >= d) | |||
| bits++; | |||
| } | |||
| return bits; | |||
| } | |||
| #endif /* UNUSED */ | |||
| FLAC__bool FLAC__bitwriter_write_rice_signed(FLAC__BitWriter *bw, FLAC__int32 val, uint32_t parameter) | |||
| { | |||
| uint32_t total_bits, interesting_bits, msbs; | |||
| FLAC__uint32 uval, pattern; | |||
| FLAC__ASSERT(0 != bw); | |||
| FLAC__ASSERT(0 != bw->buffer); | |||
| FLAC__ASSERT(parameter < 32); | |||
| /* fold signed to uint32_t; actual formula is: negative(v)? -2v-1 : 2v */ | |||
| uval = val; | |||
| uval <<= 1; | |||
| uval ^= (val>>31); | |||
| msbs = uval >> parameter; | |||
| interesting_bits = 1 + parameter; | |||
| total_bits = interesting_bits + msbs; | |||
| pattern = 1 << parameter; /* the unary end bit */ | |||
| pattern |= (uval & ((1<<parameter)-1)); /* the binary LSBs */ | |||
| if(total_bits <= 32) | |||
| return FLAC__bitwriter_write_raw_uint32(bw, pattern, total_bits); | |||
| else | |||
| return | |||
| FLAC__bitwriter_write_zeroes(bw, msbs) && /* write the unary MSBs */ | |||
| FLAC__bitwriter_write_raw_uint32(bw, pattern, interesting_bits); /* write the unary end bit and binary LSBs */ | |||
| } | |||
| FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FLAC__int32 *vals, uint32_t nvals, uint32_t parameter) | |||
| { | |||
| const FLAC__uint32 mask1 = (FLAC__uint32)0xffffffff << parameter; /* we val|=mask1 to set the stop bit above it... */ | |||
| const FLAC__uint32 mask2 = (FLAC__uint32)0xffffffff >> (31-parameter); /* ...then mask off the bits above the stop bit with val&=mask2 */ | |||
| FLAC__uint32 uval; | |||
| uint32_t left; | |||
| const uint32_t lsbits = 1 + parameter; | |||
| uint32_t msbits, total_bits; | |||
| FLAC__ASSERT(0 != bw); | |||
| FLAC__ASSERT(0 != bw->buffer); | |||
| FLAC__ASSERT(parameter < 31); | |||
| /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */ | |||
| FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32); | |||
| while(nvals) { | |||
| /* fold signed to uint32_t; actual formula is: negative(v)? -2v-1 : 2v */ | |||
| uval = *vals; | |||
| uval <<= 1; | |||
| uval ^= (*vals>>31); | |||
| msbits = uval >> parameter; | |||
| total_bits = lsbits + msbits; | |||
| if(bw->bits && bw->bits + total_bits < 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 */ | |||
| bw->bits += total_bits; | |||
| uval |= mask1; /* set stop bit */ | |||
| uval &= mask2; /* mask off unused top bits */ | |||
| bw->accum <<= total_bits; | |||
| bw->accum |= uval; | |||
| } | |||
| else { | |||
| /* 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 */ | |||
| if(bw->capacity <= bw->words + bw->bits + msbits + 1 /* lsbits always fit in 1 bwword */ && !bitwriter_grow_(bw, total_bits)) | |||
| return false; | |||
| if(msbits) { | |||
| /* first part gets to word alignment */ | |||
| if(bw->bits) { | |||
| left = FLAC__BITS_PER_WORD - bw->bits; | |||
| if(msbits < left) { | |||
| bw->accum <<= msbits; | |||
| bw->bits += msbits; | |||
| goto break1; | |||
| } | |||
| else { | |||
| bw->accum <<= left; | |||
| msbits -= left; | |||
| bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum); | |||
| bw->bits = 0; | |||
| } | |||
| } | |||
| /* do whole words */ | |||
| while(msbits >= FLAC__BITS_PER_WORD) { | |||
| bw->buffer[bw->words++] = 0; | |||
| msbits -= FLAC__BITS_PER_WORD; | |||
| } | |||
| /* do any leftovers */ | |||
| if(msbits > 0) { | |||
| bw->accum = 0; | |||
| bw->bits = msbits; | |||
| } | |||
| } | |||
| break1: | |||
| uval |= mask1; /* set stop bit */ | |||
| uval &= mask2; /* mask off unused top bits */ | |||
| left = FLAC__BITS_PER_WORD - bw->bits; | |||
| if(lsbits < left) { | |||
| bw->accum <<= lsbits; | |||
| bw->accum |= uval; | |||
| bw->bits += lsbits; | |||
| } | |||
| else { | |||
| /* if bw->bits == 0, left==FLAC__BITS_PER_WORD which will always | |||
| * be > lsbits (because of previous assertions) so it would have | |||
| * triggered the (lsbits<left) case above. | |||
| */ | |||
| FLAC__ASSERT(bw->bits); | |||
| FLAC__ASSERT(left < FLAC__BITS_PER_WORD); | |||
| bw->accum <<= left; | |||
| bw->accum |= uval >> (bw->bits = lsbits - left); | |||
| bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum); | |||
| bw->accum = uval; /* unused top bits can contain garbage */ | |||
| } | |||
| } | |||
| vals++; | |||
| nvals--; | |||
| } | |||
| return true; | |||
| } | |||
| #if 0 /* UNUSED */ | |||
| FLAC__bool FLAC__bitwriter_write_golomb_signed(FLAC__BitWriter *bw, int val, uint32_t parameter) | |||
| { | |||
| uint32_t total_bits, msbs, uval; | |||
| uint32_t k; | |||
| FLAC__ASSERT(0 != bw); | |||
| FLAC__ASSERT(0 != bw->buffer); | |||
| FLAC__ASSERT(parameter > 0); | |||
| /* fold signed to uint32_t */ | |||
| if(val < 0) | |||
| uval = (uint32_t)(((-(++val)) << 1) + 1); | |||
| else | |||
| uval = (uint32_t)(val << 1); | |||
| k = FLAC__bitmath_ilog2(parameter); | |||
| if(parameter == 1u<<k) { | |||
| uint32_t pattern; | |||
| FLAC__ASSERT(k <= 30); | |||
| msbs = uval >> k; | |||
| total_bits = 1 + k + msbs; | |||
| pattern = 1 << k; /* the unary end bit */ | |||
| pattern |= (uval & ((1u<<k)-1)); /* the binary LSBs */ | |||
| if(total_bits <= 32) { | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, pattern, total_bits)) | |||
| return false; | |||
| } | |||
| else { | |||
| /* write the unary MSBs */ | |||
| if(!FLAC__bitwriter_write_zeroes(bw, msbs)) | |||
| return false; | |||
| /* write the unary end bit and binary LSBs */ | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, pattern, k+1)) | |||
| return false; | |||
| } | |||
| } | |||
| else { | |||
| uint32_t q, r, d; | |||
| d = (1 << (k+1)) - parameter; | |||
| q = uval / parameter; | |||
| r = uval - (q * parameter); | |||
| /* write the unary MSBs */ | |||
| if(!FLAC__bitwriter_write_zeroes(bw, q)) | |||
| return false; | |||
| /* write the unary end bit */ | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, 1, 1)) | |||
| return false; | |||
| /* write the binary LSBs */ | |||
| if(r >= d) { | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, r+d, k+1)) | |||
| return false; | |||
| } | |||
| else { | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, r, k)) | |||
| return false; | |||
| } | |||
| } | |||
| return true; | |||
| } | |||
| FLAC__bool FLAC__bitwriter_write_golomb_unsigned(FLAC__BitWriter *bw, uint32_t uval, uint32_t parameter) | |||
| { | |||
| uint32_t total_bits, msbs; | |||
| uint32_t k; | |||
| FLAC__ASSERT(0 != bw); | |||
| FLAC__ASSERT(0 != bw->buffer); | |||
| FLAC__ASSERT(parameter > 0); | |||
| k = FLAC__bitmath_ilog2(parameter); | |||
| if(parameter == 1u<<k) { | |||
| uint32_t pattern; | |||
| FLAC__ASSERT(k <= 30); | |||
| msbs = uval >> k; | |||
| total_bits = 1 + k + msbs; | |||
| pattern = 1 << k; /* the unary end bit */ | |||
| pattern |= (uval & ((1u<<k)-1)); /* the binary LSBs */ | |||
| if(total_bits <= 32) { | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, pattern, total_bits)) | |||
| return false; | |||
| } | |||
| else { | |||
| /* write the unary MSBs */ | |||
| if(!FLAC__bitwriter_write_zeroes(bw, msbs)) | |||
| return false; | |||
| /* write the unary end bit and binary LSBs */ | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, pattern, k+1)) | |||
| return false; | |||
| } | |||
| } | |||
| else { | |||
| uint32_t q, r, d; | |||
| d = (1 << (k+1)) - parameter; | |||
| q = uval / parameter; | |||
| r = uval - (q * parameter); | |||
| /* write the unary MSBs */ | |||
| if(!FLAC__bitwriter_write_zeroes(bw, q)) | |||
| return false; | |||
| /* write the unary end bit */ | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, 1, 1)) | |||
| return false; | |||
| /* write the binary LSBs */ | |||
| if(r >= d) { | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, r+d, k+1)) | |||
| return false; | |||
| } | |||
| else { | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, r, k)) | |||
| return false; | |||
| } | |||
| } | |||
| return true; | |||
| } | |||
| #endif /* UNUSED */ | |||
| FLAC__bool FLAC__bitwriter_write_utf8_uint32(FLAC__BitWriter *bw, FLAC__uint32 val) | |||
| { | |||
| FLAC__bool ok = 1; | |||
| FLAC__ASSERT(0 != bw); | |||
| FLAC__ASSERT(0 != bw->buffer); | |||
| if((val & 0x80000000) != 0) /* this version only handles 31 bits */ | |||
| return false; | |||
| if(val < 0x80) { | |||
| return FLAC__bitwriter_write_raw_uint32_nocheck(bw, val, 8); | |||
| } | |||
| else if(val < 0x800) { | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xC0 | (val>>6), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (val&0x3F), 8); | |||
| } | |||
| else if(val < 0x10000) { | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xE0 | (val>>12), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | ((val>>6)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (val&0x3F), 8); | |||
| } | |||
| else if(val < 0x200000) { | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xF0 | (val>>18), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | ((val>>12)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | ((val>>6)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (val&0x3F), 8); | |||
| } | |||
| else if(val < 0x4000000) { | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xF8 | (val>>24), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | ((val>>18)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | ((val>>12)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | ((val>>6)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (val&0x3F), 8); | |||
| } | |||
| else { | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xFC | (val>>30), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | ((val>>24)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | ((val>>18)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | ((val>>12)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | ((val>>6)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (val&0x3F), 8); | |||
| } | |||
| return ok; | |||
| } | |||
| FLAC__bool FLAC__bitwriter_write_utf8_uint64(FLAC__BitWriter *bw, FLAC__uint64 val) | |||
| { | |||
| FLAC__bool ok = 1; | |||
| FLAC__ASSERT(0 != bw); | |||
| FLAC__ASSERT(0 != bw->buffer); | |||
| if((val & FLAC__U64L(0xFFFFFFF000000000)) != 0) /* this version only handles 36 bits */ | |||
| return false; | |||
| if(val < 0x80) { | |||
| return FLAC__bitwriter_write_raw_uint32_nocheck(bw, (FLAC__uint32)val, 8); | |||
| } | |||
| else if(val < 0x800) { | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xC0 | (FLAC__uint32)(val>>6), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8); | |||
| } | |||
| else if(val < 0x10000) { | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xE0 | (FLAC__uint32)(val>>12), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8); | |||
| } | |||
| else if(val < 0x200000) { | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xF0 | (FLAC__uint32)(val>>18), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8); | |||
| } | |||
| else if(val < 0x4000000) { | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xF8 | (FLAC__uint32)(val>>24), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>18)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8); | |||
| } | |||
| else if(val < 0x80000000) { | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xFC | (FLAC__uint32)(val>>30), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>24)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>18)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8); | |||
| } | |||
| else { | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0xFE, 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>30)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>24)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>18)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32_nocheck(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8); | |||
| } | |||
| return ok; | |||
| } | |||
| FLAC__bool FLAC__bitwriter_zero_pad_to_byte_boundary(FLAC__BitWriter *bw) | |||
| { | |||
| /* 0-pad to byte boundary */ | |||
| if(bw->bits & 7u) | |||
| return FLAC__bitwriter_write_zeroes(bw, 8 - (bw->bits & 7u)); | |||
| else | |||
| return true; | |||
| } | |||
| /* These functions are declared inline in this file but are also callable as | |||
| * externs from elsewhere. | |||
| * According to the C99 spec, 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, uint32_t bits); | |||
| extern FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FLAC__uint32 val, uint32_t bits); | |||
| extern FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, uint32_t bits); | |||
| extern FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, uint32_t 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[], uint32_t nvals); | |||
| @@ -0,0 +1,305 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2001-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include "include/private/cpu.h" | |||
| #include "../compat.h" | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #if defined _MSC_VER | |||
| #include <intrin.h> /* for __cpuid() and _xgetbv() */ | |||
| #elif defined __GNUC__ && defined HAVE_CPUID_H | |||
| #include <cpuid.h> /* for __get_cpuid() and __get_cpuid_max() */ | |||
| #endif | |||
| #ifndef NDEBUG | |||
| #include <stdio.h> | |||
| #define dfprintf fprintf | |||
| #else | |||
| /* This is bad practice, it should be a static void empty function */ | |||
| #define dfprintf(file, format, ...) | |||
| #endif | |||
| #if defined FLAC__CPU_PPC | |||
| #if defined(__linux__) || (defined(__FreeBSD__) && (__FreeBSD__ >= 12)) | |||
| #include <sys/auxv.h> | |||
| #endif | |||
| #endif | |||
| #if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && (defined FLAC__HAS_NASM || FLAC__HAS_X86INTRIN) && !defined FLAC__NO_ASM | |||
| /* these are flags in EDX of CPUID AX=00000001 */ | |||
| static const uint32_t FLAC__CPUINFO_X86_CPUID_CMOV = 0x00008000; | |||
| static const uint32_t FLAC__CPUINFO_X86_CPUID_MMX = 0x00800000; | |||
| static const uint32_t FLAC__CPUINFO_X86_CPUID_SSE = 0x02000000; | |||
| static const uint32_t FLAC__CPUINFO_X86_CPUID_SSE2 = 0x04000000; | |||
| /* these are flags in ECX of CPUID AX=00000001 */ | |||
| static const uint32_t FLAC__CPUINFO_X86_CPUID_SSE3 = 0x00000001; | |||
| static const uint32_t FLAC__CPUINFO_X86_CPUID_SSSE3 = 0x00000200; | |||
| static const uint32_t FLAC__CPUINFO_X86_CPUID_SSE41 = 0x00080000; | |||
| static const uint32_t FLAC__CPUINFO_X86_CPUID_SSE42 = 0x00100000; | |||
| static const uint32_t FLAC__CPUINFO_X86_CPUID_OSXSAVE = 0x08000000; | |||
| static const uint32_t FLAC__CPUINFO_X86_CPUID_AVX = 0x10000000; | |||
| static const uint32_t FLAC__CPUINFO_X86_CPUID_FMA = 0x00001000; | |||
| /* these are flags in EBX of CPUID AX=00000007 */ | |||
| static const uint32_t FLAC__CPUINFO_X86_CPUID_AVX2 = 0x00000020; | |||
| static uint32_t | |||
| cpu_xgetbv_x86(void) | |||
| { | |||
| #if (defined _MSC_VER || defined __INTEL_COMPILER) && FLAC__AVX_SUPPORTED | |||
| return (uint32_t)_xgetbv(0); | |||
| #elif defined __GNUC__ | |||
| uint32_t lo, hi; | |||
| __asm__ volatile (".byte 0x0f, 0x01, 0xd0" : "=a"(lo), "=d"(hi) : "c" (0)); | |||
| return lo; | |||
| #else | |||
| return 0; | |||
| #endif | |||
| } | |||
| static uint32_t | |||
| cpu_have_cpuid(void) | |||
| { | |||
| #if defined FLAC__CPU_X86_64 || defined __i686__ || defined __SSE__ || (defined _M_IX86_FP && _M_IX86_FP > 0) | |||
| /* target CPU does have CPUID instruction */ | |||
| return 1; | |||
| #elif defined FLAC__HAS_NASM | |||
| return FLAC__cpu_have_cpuid_asm_ia32(); | |||
| #elif defined __GNUC__ && defined HAVE_CPUID_H | |||
| if (__get_cpuid_max(0, 0) != 0) | |||
| return 1; | |||
| else | |||
| return 0; | |||
| #elif defined _MSC_VER | |||
| FLAC__uint32 flags1, flags2; | |||
| __asm { | |||
| pushfd | |||
| pushfd | |||
| pop eax | |||
| mov flags1, eax | |||
| xor eax, 0x200000 | |||
| push eax | |||
| popfd | |||
| pushfd | |||
| pop eax | |||
| mov flags2, eax | |||
| popfd | |||
| } | |||
| if (((flags1^flags2) & 0x200000) != 0) | |||
| return 1; | |||
| else | |||
| return 0; | |||
| #else | |||
| return 0; | |||
| #endif | |||
| } | |||
| static void | |||
| cpuinfo_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx) | |||
| { | |||
| #if defined _MSC_VER | |||
| int cpuinfo[4]; | |||
| int ext = level & 0x80000000; | |||
| __cpuid(cpuinfo, ext); | |||
| if ((uint32_t)cpuinfo[0] >= level) { | |||
| #if FLAC__AVX_SUPPORTED | |||
| __cpuidex(cpuinfo, level, 0); /* for AVX2 detection */ | |||
| #else | |||
| __cpuid(cpuinfo, level); /* some old compilers don't support __cpuidex */ | |||
| #endif | |||
| *eax = cpuinfo[0]; *ebx = cpuinfo[1]; *ecx = cpuinfo[2]; *edx = cpuinfo[3]; | |||
| return; | |||
| } | |||
| #elif defined __GNUC__ && defined HAVE_CPUID_H | |||
| FLAC__uint32 ext = level & 0x80000000; | |||
| __cpuid(ext, *eax, *ebx, *ecx, *edx); | |||
| if (*eax >= level) { | |||
| __cpuid_count(level, 0, *eax, *ebx, *ecx, *edx); | |||
| return; | |||
| } | |||
| #elif defined FLAC__HAS_NASM && defined FLAC__CPU_IA32 | |||
| FLAC__cpu_info_asm_ia32(level, eax, ebx, ecx, edx); | |||
| return; | |||
| #endif | |||
| *eax = *ebx = *ecx = *edx = 0; | |||
| } | |||
| #endif | |||
| static void | |||
| x86_cpu_info (FLAC__CPUInfo *info) | |||
| { | |||
| #if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && (defined FLAC__HAS_NASM || FLAC__HAS_X86INTRIN) && !defined FLAC__NO_ASM | |||
| FLAC__bool x86_osxsave = false; | |||
| FLAC__bool os_avx = false; | |||
| FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx; | |||
| info->use_asm = true; /* we assume a minimum of 80386 */ | |||
| if (!cpu_have_cpuid()) | |||
| return; | |||
| cpuinfo_x86(0, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); | |||
| info->x86.intel = (flags_ebx == 0x756E6547 && flags_edx == 0x49656E69 && flags_ecx == 0x6C65746E) ? true : false; /* GenuineIntel */ | |||
| cpuinfo_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); | |||
| info->x86.cmov = (flags_edx & FLAC__CPUINFO_X86_CPUID_CMOV ) ? true : false; | |||
| info->x86.mmx = (flags_edx & FLAC__CPUINFO_X86_CPUID_MMX ) ? true : false; | |||
| info->x86.sse = (flags_edx & FLAC__CPUINFO_X86_CPUID_SSE ) ? true : false; | |||
| info->x86.sse2 = (flags_edx & FLAC__CPUINFO_X86_CPUID_SSE2 ) ? true : false; | |||
| info->x86.sse3 = (flags_ecx & FLAC__CPUINFO_X86_CPUID_SSE3 ) ? true : false; | |||
| info->x86.ssse3 = (flags_ecx & FLAC__CPUINFO_X86_CPUID_SSSE3) ? true : false; | |||
| info->x86.sse41 = (flags_ecx & FLAC__CPUINFO_X86_CPUID_SSE41) ? true : false; | |||
| info->x86.sse42 = (flags_ecx & FLAC__CPUINFO_X86_CPUID_SSE42) ? true : false; | |||
| if (FLAC__AVX_SUPPORTED) { | |||
| x86_osxsave = (flags_ecx & FLAC__CPUINFO_X86_CPUID_OSXSAVE) ? true : false; | |||
| info->x86.avx = (flags_ecx & FLAC__CPUINFO_X86_CPUID_AVX ) ? true : false; | |||
| info->x86.fma = (flags_ecx & FLAC__CPUINFO_X86_CPUID_FMA ) ? true : false; | |||
| cpuinfo_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); | |||
| info->x86.avx2 = (flags_ebx & FLAC__CPUINFO_X86_CPUID_AVX2 ) ? true : false; | |||
| } | |||
| #if defined FLAC__CPU_IA32 | |||
| dfprintf(stderr, "CPU info (IA-32):\n"); | |||
| #else | |||
| dfprintf(stderr, "CPU info (x86-64):\n"); | |||
| #endif | |||
| dfprintf(stderr, " CMOV ....... %c\n", info->x86.cmov ? 'Y' : 'n'); | |||
| dfprintf(stderr, " MMX ........ %c\n", info->x86.mmx ? 'Y' : 'n'); | |||
| dfprintf(stderr, " SSE ........ %c\n", info->x86.sse ? 'Y' : 'n'); | |||
| dfprintf(stderr, " SSE2 ....... %c\n", info->x86.sse2 ? 'Y' : 'n'); | |||
| dfprintf(stderr, " SSE3 ....... %c\n", info->x86.sse3 ? 'Y' : 'n'); | |||
| dfprintf(stderr, " SSSE3 ...... %c\n", info->x86.ssse3 ? 'Y' : 'n'); | |||
| dfprintf(stderr, " SSE41 ...... %c\n", info->x86.sse41 ? 'Y' : 'n'); | |||
| dfprintf(stderr, " SSE42 ...... %c\n", info->x86.sse42 ? 'Y' : 'n'); | |||
| if (FLAC__AVX_SUPPORTED) { | |||
| dfprintf(stderr, " AVX ........ %c\n", info->x86.avx ? 'Y' : 'n'); | |||
| dfprintf(stderr, " FMA ........ %c\n", info->x86.fma ? 'Y' : 'n'); | |||
| dfprintf(stderr, " AVX2 ....... %c\n", info->x86.avx2 ? 'Y' : 'n'); | |||
| } | |||
| /* | |||
| * now have to check for OS support of AVX instructions | |||
| */ | |||
| if (FLAC__AVX_SUPPORTED && info->x86.avx && x86_osxsave && (cpu_xgetbv_x86() & 0x6) == 0x6) { | |||
| os_avx = true; | |||
| } | |||
| if (os_avx) { | |||
| dfprintf(stderr, " AVX OS sup . %c\n", info->x86.avx ? 'Y' : 'n'); | |||
| } | |||
| if (!os_avx) { | |||
| /* no OS AVX support */ | |||
| info->x86.avx = false; | |||
| info->x86.avx2 = false; | |||
| info->x86.fma = false; | |||
| } | |||
| #else | |||
| info->use_asm = false; | |||
| #endif | |||
| } | |||
| static void | |||
| ppc_cpu_info (FLAC__CPUInfo *info) | |||
| { | |||
| #if defined FLAC__CPU_PPC | |||
| #ifndef PPC_FEATURE2_ARCH_3_00 | |||
| #define PPC_FEATURE2_ARCH_3_00 0x00800000 | |||
| #endif | |||
| #ifndef PPC_FEATURE2_ARCH_2_07 | |||
| #define PPC_FEATURE2_ARCH_2_07 0x80000000 | |||
| #endif | |||
| #ifdef __linux__ | |||
| if (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_00) { | |||
| info->ppc.arch_3_00 = true; | |||
| } else if (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07) { | |||
| info->ppc.arch_2_07 = true; | |||
| } | |||
| #elif defined(__FreeBSD__) && (__FreeBSD__ >= 12) | |||
| long hwcaps; | |||
| /* elf_aux_info() appeared in FreeBSD 12.0 */ | |||
| elf_aux_info(AT_HWCAP2, &hwcaps, sizeof(hwcaps)); | |||
| if (hwcaps & PPC_FEATURE2_ARCH_3_00) { | |||
| info->ppc.arch_3_00 = true; | |||
| } else if (hwcaps & PPC_FEATURE2_ARCH_2_07) { | |||
| info->ppc.arch_2_07 = true; | |||
| } | |||
| #elif defined(__APPLE__) | |||
| /* no Mac OS X version supports CPU with Power AVI v2.07 or better */ | |||
| info->ppc.arch_2_07 = false; | |||
| info->ppc.arch_3_00 = false; | |||
| #else | |||
| #error Unsupported platform! Please add support for reading ppc hwcaps. | |||
| #endif | |||
| #else | |||
| info->ppc.arch_2_07 = false; | |||
| info->ppc.arch_3_00 = false; | |||
| #endif | |||
| } | |||
| void FLAC__cpu_info (FLAC__CPUInfo *info) | |||
| { | |||
| memset(info, 0, sizeof(*info)); | |||
| #ifdef FLAC__CPU_IA32 | |||
| info->type = FLAC__CPUINFO_TYPE_IA32; | |||
| #elif defined FLAC__CPU_X86_64 | |||
| info->type = FLAC__CPUINFO_TYPE_X86_64; | |||
| #elif defined FLAC__CPU_PPC | |||
| info->type = FLAC__CPUINFO_TYPE_PPC; | |||
| #else | |||
| info->type = FLAC__CPUINFO_TYPE_UNKNOWN; | |||
| #endif | |||
| switch (info->type) { | |||
| case FLAC__CPUINFO_TYPE_IA32: /* fallthrough */ | |||
| case FLAC__CPUINFO_TYPE_X86_64: | |||
| x86_cpu_info (info); | |||
| break; | |||
| case FLAC__CPUINFO_TYPE_PPC: | |||
| ppc_cpu_info (info); | |||
| break; | |||
| default: | |||
| info->use_asm = false; | |||
| break; | |||
| } | |||
| } | |||
| @@ -0,0 +1,436 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2018 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include "include/private/crc.h" | |||
| /* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */ | |||
| FLAC__uint8 const FLAC__crc8_table[256] = { | |||
| 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, | |||
| 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D, | |||
| 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, | |||
| 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, | |||
| 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, | |||
| 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, | |||
| 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, | |||
| 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD, | |||
| 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, | |||
| 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, | |||
| 0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2, | |||
| 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A, | |||
| 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, | |||
| 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A, | |||
| 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, | |||
| 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, | |||
| 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C, | |||
| 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4, | |||
| 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, | |||
| 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4, | |||
| 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, | |||
| 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, | |||
| 0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C, | |||
| 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34, | |||
| 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, | |||
| 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63, | |||
| 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, | |||
| 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, | |||
| 0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, | |||
| 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83, | |||
| 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, | |||
| 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3 | |||
| }; | |||
| /* CRC-16, poly = x^16 + x^15 + x^2 + x^0, init = 0 */ | |||
| FLAC__uint16 const FLAC__crc16_table[8][256] = { | |||
| { 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011, | |||
| 0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022, | |||
| 0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072, | |||
| 0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041, | |||
| 0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2, | |||
| 0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1, | |||
| 0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1, | |||
| 0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082, | |||
| 0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192, | |||
| 0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1, | |||
| 0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1, | |||
| 0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2, | |||
| 0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151, | |||
| 0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162, | |||
| 0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132, | |||
| 0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101, | |||
| 0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312, | |||
| 0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321, | |||
| 0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371, | |||
| 0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342, | |||
| 0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1, | |||
| 0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2, | |||
| 0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2, | |||
| 0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381, | |||
| 0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291, | |||
| 0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2, | |||
| 0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2, | |||
| 0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1, | |||
| 0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252, | |||
| 0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261, | |||
| 0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231, | |||
| 0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202 }, | |||
| { 0x0000, 0x8603, 0x8c03, 0x0a00, 0x9803, 0x1e00, 0x1400, 0x9203, | |||
| 0xb003, 0x3600, 0x3c00, 0xba03, 0x2800, 0xae03, 0xa403, 0x2200, | |||
| 0xe003, 0x6600, 0x6c00, 0xea03, 0x7800, 0xfe03, 0xf403, 0x7200, | |||
| 0x5000, 0xd603, 0xdc03, 0x5a00, 0xc803, 0x4e00, 0x4400, 0xc203, | |||
| 0x4003, 0xc600, 0xcc00, 0x4a03, 0xd800, 0x5e03, 0x5403, 0xd200, | |||
| 0xf000, 0x7603, 0x7c03, 0xfa00, 0x6803, 0xee00, 0xe400, 0x6203, | |||
| 0xa000, 0x2603, 0x2c03, 0xaa00, 0x3803, 0xbe00, 0xb400, 0x3203, | |||
| 0x1003, 0x9600, 0x9c00, 0x1a03, 0x8800, 0x0e03, 0x0403, 0x8200, | |||
| 0x8006, 0x0605, 0x0c05, 0x8a06, 0x1805, 0x9e06, 0x9406, 0x1205, | |||
| 0x3005, 0xb606, 0xbc06, 0x3a05, 0xa806, 0x2e05, 0x2405, 0xa206, | |||
| 0x6005, 0xe606, 0xec06, 0x6a05, 0xf806, 0x7e05, 0x7405, 0xf206, | |||
| 0xd006, 0x5605, 0x5c05, 0xda06, 0x4805, 0xce06, 0xc406, 0x4205, | |||
| 0xc005, 0x4606, 0x4c06, 0xca05, 0x5806, 0xde05, 0xd405, 0x5206, | |||
| 0x7006, 0xf605, 0xfc05, 0x7a06, 0xe805, 0x6e06, 0x6406, 0xe205, | |||
| 0x2006, 0xa605, 0xac05, 0x2a06, 0xb805, 0x3e06, 0x3406, 0xb205, | |||
| 0x9005, 0x1606, 0x1c06, 0x9a05, 0x0806, 0x8e05, 0x8405, 0x0206, | |||
| 0x8009, 0x060a, 0x0c0a, 0x8a09, 0x180a, 0x9e09, 0x9409, 0x120a, | |||
| 0x300a, 0xb609, 0xbc09, 0x3a0a, 0xa809, 0x2e0a, 0x240a, 0xa209, | |||
| 0x600a, 0xe609, 0xec09, 0x6a0a, 0xf809, 0x7e0a, 0x740a, 0xf209, | |||
| 0xd009, 0x560a, 0x5c0a, 0xda09, 0x480a, 0xce09, 0xc409, 0x420a, | |||
| 0xc00a, 0x4609, 0x4c09, 0xca0a, 0x5809, 0xde0a, 0xd40a, 0x5209, | |||
| 0x7009, 0xf60a, 0xfc0a, 0x7a09, 0xe80a, 0x6e09, 0x6409, 0xe20a, | |||
| 0x2009, 0xa60a, 0xac0a, 0x2a09, 0xb80a, 0x3e09, 0x3409, 0xb20a, | |||
| 0x900a, 0x1609, 0x1c09, 0x9a0a, 0x0809, 0x8e0a, 0x840a, 0x0209, | |||
| 0x000f, 0x860c, 0x8c0c, 0x0a0f, 0x980c, 0x1e0f, 0x140f, 0x920c, | |||
| 0xb00c, 0x360f, 0x3c0f, 0xba0c, 0x280f, 0xae0c, 0xa40c, 0x220f, | |||
| 0xe00c, 0x660f, 0x6c0f, 0xea0c, 0x780f, 0xfe0c, 0xf40c, 0x720f, | |||
| 0x500f, 0xd60c, 0xdc0c, 0x5a0f, 0xc80c, 0x4e0f, 0x440f, 0xc20c, | |||
| 0x400c, 0xc60f, 0xcc0f, 0x4a0c, 0xd80f, 0x5e0c, 0x540c, 0xd20f, | |||
| 0xf00f, 0x760c, 0x7c0c, 0xfa0f, 0x680c, 0xee0f, 0xe40f, 0x620c, | |||
| 0xa00f, 0x260c, 0x2c0c, 0xaa0f, 0x380c, 0xbe0f, 0xb40f, 0x320c, | |||
| 0x100c, 0x960f, 0x9c0f, 0x1a0c, 0x880f, 0x0e0c, 0x040c, 0x820f }, | |||
| { 0x0000, 0x8017, 0x802b, 0x003c, 0x8053, 0x0044, 0x0078, 0x806f, | |||
| 0x80a3, 0x00b4, 0x0088, 0x809f, 0x00f0, 0x80e7, 0x80db, 0x00cc, | |||
| 0x8143, 0x0154, 0x0168, 0x817f, 0x0110, 0x8107, 0x813b, 0x012c, | |||
| 0x01e0, 0x81f7, 0x81cb, 0x01dc, 0x81b3, 0x01a4, 0x0198, 0x818f, | |||
| 0x8283, 0x0294, 0x02a8, 0x82bf, 0x02d0, 0x82c7, 0x82fb, 0x02ec, | |||
| 0x0220, 0x8237, 0x820b, 0x021c, 0x8273, 0x0264, 0x0258, 0x824f, | |||
| 0x03c0, 0x83d7, 0x83eb, 0x03fc, 0x8393, 0x0384, 0x03b8, 0x83af, | |||
| 0x8363, 0x0374, 0x0348, 0x835f, 0x0330, 0x8327, 0x831b, 0x030c, | |||
| 0x8503, 0x0514, 0x0528, 0x853f, 0x0550, 0x8547, 0x857b, 0x056c, | |||
| 0x05a0, 0x85b7, 0x858b, 0x059c, 0x85f3, 0x05e4, 0x05d8, 0x85cf, | |||
| 0x0440, 0x8457, 0x846b, 0x047c, 0x8413, 0x0404, 0x0438, 0x842f, | |||
| 0x84e3, 0x04f4, 0x04c8, 0x84df, 0x04b0, 0x84a7, 0x849b, 0x048c, | |||
| 0x0780, 0x8797, 0x87ab, 0x07bc, 0x87d3, 0x07c4, 0x07f8, 0x87ef, | |||
| 0x8723, 0x0734, 0x0708, 0x871f, 0x0770, 0x8767, 0x875b, 0x074c, | |||
| 0x86c3, 0x06d4, 0x06e8, 0x86ff, 0x0690, 0x8687, 0x86bb, 0x06ac, | |||
| 0x0660, 0x8677, 0x864b, 0x065c, 0x8633, 0x0624, 0x0618, 0x860f, | |||
| 0x8a03, 0x0a14, 0x0a28, 0x8a3f, 0x0a50, 0x8a47, 0x8a7b, 0x0a6c, | |||
| 0x0aa0, 0x8ab7, 0x8a8b, 0x0a9c, 0x8af3, 0x0ae4, 0x0ad8, 0x8acf, | |||
| 0x0b40, 0x8b57, 0x8b6b, 0x0b7c, 0x8b13, 0x0b04, 0x0b38, 0x8b2f, | |||
| 0x8be3, 0x0bf4, 0x0bc8, 0x8bdf, 0x0bb0, 0x8ba7, 0x8b9b, 0x0b8c, | |||
| 0x0880, 0x8897, 0x88ab, 0x08bc, 0x88d3, 0x08c4, 0x08f8, 0x88ef, | |||
| 0x8823, 0x0834, 0x0808, 0x881f, 0x0870, 0x8867, 0x885b, 0x084c, | |||
| 0x89c3, 0x09d4, 0x09e8, 0x89ff, 0x0990, 0x8987, 0x89bb, 0x09ac, | |||
| 0x0960, 0x8977, 0x894b, 0x095c, 0x8933, 0x0924, 0x0918, 0x890f, | |||
| 0x0f00, 0x8f17, 0x8f2b, 0x0f3c, 0x8f53, 0x0f44, 0x0f78, 0x8f6f, | |||
| 0x8fa3, 0x0fb4, 0x0f88, 0x8f9f, 0x0ff0, 0x8fe7, 0x8fdb, 0x0fcc, | |||
| 0x8e43, 0x0e54, 0x0e68, 0x8e7f, 0x0e10, 0x8e07, 0x8e3b, 0x0e2c, | |||
| 0x0ee0, 0x8ef7, 0x8ecb, 0x0edc, 0x8eb3, 0x0ea4, 0x0e98, 0x8e8f, | |||
| 0x8d83, 0x0d94, 0x0da8, 0x8dbf, 0x0dd0, 0x8dc7, 0x8dfb, 0x0dec, | |||
| 0x0d20, 0x8d37, 0x8d0b, 0x0d1c, 0x8d73, 0x0d64, 0x0d58, 0x8d4f, | |||
| 0x0cc0, 0x8cd7, 0x8ceb, 0x0cfc, 0x8c93, 0x0c84, 0x0cb8, 0x8caf, | |||
| 0x8c63, 0x0c74, 0x0c48, 0x8c5f, 0x0c30, 0x8c27, 0x8c1b, 0x0c0c }, | |||
| { 0x0000, 0x9403, 0xa803, 0x3c00, 0xd003, 0x4400, 0x7800, 0xec03, | |||
| 0x2003, 0xb400, 0x8800, 0x1c03, 0xf000, 0x6403, 0x5803, 0xcc00, | |||
| 0x4006, 0xd405, 0xe805, 0x7c06, 0x9005, 0x0406, 0x3806, 0xac05, | |||
| 0x6005, 0xf406, 0xc806, 0x5c05, 0xb006, 0x2405, 0x1805, 0x8c06, | |||
| 0x800c, 0x140f, 0x280f, 0xbc0c, 0x500f, 0xc40c, 0xf80c, 0x6c0f, | |||
| 0xa00f, 0x340c, 0x080c, 0x9c0f, 0x700c, 0xe40f, 0xd80f, 0x4c0c, | |||
| 0xc00a, 0x5409, 0x6809, 0xfc0a, 0x1009, 0x840a, 0xb80a, 0x2c09, | |||
| 0xe009, 0x740a, 0x480a, 0xdc09, 0x300a, 0xa409, 0x9809, 0x0c0a, | |||
| 0x801d, 0x141e, 0x281e, 0xbc1d, 0x501e, 0xc41d, 0xf81d, 0x6c1e, | |||
| 0xa01e, 0x341d, 0x081d, 0x9c1e, 0x701d, 0xe41e, 0xd81e, 0x4c1d, | |||
| 0xc01b, 0x5418, 0x6818, 0xfc1b, 0x1018, 0x841b, 0xb81b, 0x2c18, | |||
| 0xe018, 0x741b, 0x481b, 0xdc18, 0x301b, 0xa418, 0x9818, 0x0c1b, | |||
| 0x0011, 0x9412, 0xa812, 0x3c11, 0xd012, 0x4411, 0x7811, 0xec12, | |||
| 0x2012, 0xb411, 0x8811, 0x1c12, 0xf011, 0x6412, 0x5812, 0xcc11, | |||
| 0x4017, 0xd414, 0xe814, 0x7c17, 0x9014, 0x0417, 0x3817, 0xac14, | |||
| 0x6014, 0xf417, 0xc817, 0x5c14, 0xb017, 0x2414, 0x1814, 0x8c17, | |||
| 0x803f, 0x143c, 0x283c, 0xbc3f, 0x503c, 0xc43f, 0xf83f, 0x6c3c, | |||
| 0xa03c, 0x343f, 0x083f, 0x9c3c, 0x703f, 0xe43c, 0xd83c, 0x4c3f, | |||
| 0xc039, 0x543a, 0x683a, 0xfc39, 0x103a, 0x8439, 0xb839, 0x2c3a, | |||
| 0xe03a, 0x7439, 0x4839, 0xdc3a, 0x3039, 0xa43a, 0x983a, 0x0c39, | |||
| 0x0033, 0x9430, 0xa830, 0x3c33, 0xd030, 0x4433, 0x7833, 0xec30, | |||
| 0x2030, 0xb433, 0x8833, 0x1c30, 0xf033, 0x6430, 0x5830, 0xcc33, | |||
| 0x4035, 0xd436, 0xe836, 0x7c35, 0x9036, 0x0435, 0x3835, 0xac36, | |||
| 0x6036, 0xf435, 0xc835, 0x5c36, 0xb035, 0x2436, 0x1836, 0x8c35, | |||
| 0x0022, 0x9421, 0xa821, 0x3c22, 0xd021, 0x4422, 0x7822, 0xec21, | |||
| 0x2021, 0xb422, 0x8822, 0x1c21, 0xf022, 0x6421, 0x5821, 0xcc22, | |||
| 0x4024, 0xd427, 0xe827, 0x7c24, 0x9027, 0x0424, 0x3824, 0xac27, | |||
| 0x6027, 0xf424, 0xc824, 0x5c27, 0xb024, 0x2427, 0x1827, 0x8c24, | |||
| 0x802e, 0x142d, 0x282d, 0xbc2e, 0x502d, 0xc42e, 0xf82e, 0x6c2d, | |||
| 0xa02d, 0x342e, 0x082e, 0x9c2d, 0x702e, 0xe42d, 0xd82d, 0x4c2e, | |||
| 0xc028, 0x542b, 0x682b, 0xfc28, 0x102b, 0x8428, 0xb828, 0x2c2b, | |||
| 0xe02b, 0x7428, 0x4828, 0xdc2b, 0x3028, 0xa42b, 0x982b, 0x0c28 }, | |||
| { 0x0000, 0x807b, 0x80f3, 0x0088, 0x81e3, 0x0198, 0x0110, 0x816b, | |||
| 0x83c3, 0x03b8, 0x0330, 0x834b, 0x0220, 0x825b, 0x82d3, 0x02a8, | |||
| 0x8783, 0x07f8, 0x0770, 0x870b, 0x0660, 0x861b, 0x8693, 0x06e8, | |||
| 0x0440, 0x843b, 0x84b3, 0x04c8, 0x85a3, 0x05d8, 0x0550, 0x852b, | |||
| 0x8f03, 0x0f78, 0x0ff0, 0x8f8b, 0x0ee0, 0x8e9b, 0x8e13, 0x0e68, | |||
| 0x0cc0, 0x8cbb, 0x8c33, 0x0c48, 0x8d23, 0x0d58, 0x0dd0, 0x8dab, | |||
| 0x0880, 0x88fb, 0x8873, 0x0808, 0x8963, 0x0918, 0x0990, 0x89eb, | |||
| 0x8b43, 0x0b38, 0x0bb0, 0x8bcb, 0x0aa0, 0x8adb, 0x8a53, 0x0a28, | |||
| 0x9e03, 0x1e78, 0x1ef0, 0x9e8b, 0x1fe0, 0x9f9b, 0x9f13, 0x1f68, | |||
| 0x1dc0, 0x9dbb, 0x9d33, 0x1d48, 0x9c23, 0x1c58, 0x1cd0, 0x9cab, | |||
| 0x1980, 0x99fb, 0x9973, 0x1908, 0x9863, 0x1818, 0x1890, 0x98eb, | |||
| 0x9a43, 0x1a38, 0x1ab0, 0x9acb, 0x1ba0, 0x9bdb, 0x9b53, 0x1b28, | |||
| 0x1100, 0x917b, 0x91f3, 0x1188, 0x90e3, 0x1098, 0x1010, 0x906b, | |||
| 0x92c3, 0x12b8, 0x1230, 0x924b, 0x1320, 0x935b, 0x93d3, 0x13a8, | |||
| 0x9683, 0x16f8, 0x1670, 0x960b, 0x1760, 0x971b, 0x9793, 0x17e8, | |||
| 0x1540, 0x953b, 0x95b3, 0x15c8, 0x94a3, 0x14d8, 0x1450, 0x942b, | |||
| 0xbc03, 0x3c78, 0x3cf0, 0xbc8b, 0x3de0, 0xbd9b, 0xbd13, 0x3d68, | |||
| 0x3fc0, 0xbfbb, 0xbf33, 0x3f48, 0xbe23, 0x3e58, 0x3ed0, 0xbeab, | |||
| 0x3b80, 0xbbfb, 0xbb73, 0x3b08, 0xba63, 0x3a18, 0x3a90, 0xbaeb, | |||
| 0xb843, 0x3838, 0x38b0, 0xb8cb, 0x39a0, 0xb9db, 0xb953, 0x3928, | |||
| 0x3300, 0xb37b, 0xb3f3, 0x3388, 0xb2e3, 0x3298, 0x3210, 0xb26b, | |||
| 0xb0c3, 0x30b8, 0x3030, 0xb04b, 0x3120, 0xb15b, 0xb1d3, 0x31a8, | |||
| 0xb483, 0x34f8, 0x3470, 0xb40b, 0x3560, 0xb51b, 0xb593, 0x35e8, | |||
| 0x3740, 0xb73b, 0xb7b3, 0x37c8, 0xb6a3, 0x36d8, 0x3650, 0xb62b, | |||
| 0x2200, 0xa27b, 0xa2f3, 0x2288, 0xa3e3, 0x2398, 0x2310, 0xa36b, | |||
| 0xa1c3, 0x21b8, 0x2130, 0xa14b, 0x2020, 0xa05b, 0xa0d3, 0x20a8, | |||
| 0xa583, 0x25f8, 0x2570, 0xa50b, 0x2460, 0xa41b, 0xa493, 0x24e8, | |||
| 0x2640, 0xa63b, 0xa6b3, 0x26c8, 0xa7a3, 0x27d8, 0x2750, 0xa72b, | |||
| 0xad03, 0x2d78, 0x2df0, 0xad8b, 0x2ce0, 0xac9b, 0xac13, 0x2c68, | |||
| 0x2ec0, 0xaebb, 0xae33, 0x2e48, 0xaf23, 0x2f58, 0x2fd0, 0xafab, | |||
| 0x2a80, 0xaafb, 0xaa73, 0x2a08, 0xab63, 0x2b18, 0x2b90, 0xabeb, | |||
| 0xa943, 0x2938, 0x29b0, 0xa9cb, 0x28a0, 0xa8db, 0xa853, 0x2828 }, | |||
| { 0x0000, 0xf803, 0x7003, 0x8800, 0xe006, 0x1805, 0x9005, 0x6806, | |||
| 0x4009, 0xb80a, 0x300a, 0xc809, 0xa00f, 0x580c, 0xd00c, 0x280f, | |||
| 0x8012, 0x7811, 0xf011, 0x0812, 0x6014, 0x9817, 0x1017, 0xe814, | |||
| 0xc01b, 0x3818, 0xb018, 0x481b, 0x201d, 0xd81e, 0x501e, 0xa81d, | |||
| 0x8021, 0x7822, 0xf022, 0x0821, 0x6027, 0x9824, 0x1024, 0xe827, | |||
| 0xc028, 0x382b, 0xb02b, 0x4828, 0x202e, 0xd82d, 0x502d, 0xa82e, | |||
| 0x0033, 0xf830, 0x7030, 0x8833, 0xe035, 0x1836, 0x9036, 0x6835, | |||
| 0x403a, 0xb839, 0x3039, 0xc83a, 0xa03c, 0x583f, 0xd03f, 0x283c, | |||
| 0x8047, 0x7844, 0xf044, 0x0847, 0x6041, 0x9842, 0x1042, 0xe841, | |||
| 0xc04e, 0x384d, 0xb04d, 0x484e, 0x2048, 0xd84b, 0x504b, 0xa848, | |||
| 0x0055, 0xf856, 0x7056, 0x8855, 0xe053, 0x1850, 0x9050, 0x6853, | |||
| 0x405c, 0xb85f, 0x305f, 0xc85c, 0xa05a, 0x5859, 0xd059, 0x285a, | |||
| 0x0066, 0xf865, 0x7065, 0x8866, 0xe060, 0x1863, 0x9063, 0x6860, | |||
| 0x406f, 0xb86c, 0x306c, 0xc86f, 0xa069, 0x586a, 0xd06a, 0x2869, | |||
| 0x8074, 0x7877, 0xf077, 0x0874, 0x6072, 0x9871, 0x1071, 0xe872, | |||
| 0xc07d, 0x387e, 0xb07e, 0x487d, 0x207b, 0xd878, 0x5078, 0xa87b, | |||
| 0x808b, 0x7888, 0xf088, 0x088b, 0x608d, 0x988e, 0x108e, 0xe88d, | |||
| 0xc082, 0x3881, 0xb081, 0x4882, 0x2084, 0xd887, 0x5087, 0xa884, | |||
| 0x0099, 0xf89a, 0x709a, 0x8899, 0xe09f, 0x189c, 0x909c, 0x689f, | |||
| 0x4090, 0xb893, 0x3093, 0xc890, 0xa096, 0x5895, 0xd095, 0x2896, | |||
| 0x00aa, 0xf8a9, 0x70a9, 0x88aa, 0xe0ac, 0x18af, 0x90af, 0x68ac, | |||
| 0x40a3, 0xb8a0, 0x30a0, 0xc8a3, 0xa0a5, 0x58a6, 0xd0a6, 0x28a5, | |||
| 0x80b8, 0x78bb, 0xf0bb, 0x08b8, 0x60be, 0x98bd, 0x10bd, 0xe8be, | |||
| 0xc0b1, 0x38b2, 0xb0b2, 0x48b1, 0x20b7, 0xd8b4, 0x50b4, 0xa8b7, | |||
| 0x00cc, 0xf8cf, 0x70cf, 0x88cc, 0xe0ca, 0x18c9, 0x90c9, 0x68ca, | |||
| 0x40c5, 0xb8c6, 0x30c6, 0xc8c5, 0xa0c3, 0x58c0, 0xd0c0, 0x28c3, | |||
| 0x80de, 0x78dd, 0xf0dd, 0x08de, 0x60d8, 0x98db, 0x10db, 0xe8d8, | |||
| 0xc0d7, 0x38d4, 0xb0d4, 0x48d7, 0x20d1, 0xd8d2, 0x50d2, 0xa8d1, | |||
| 0x80ed, 0x78ee, 0xf0ee, 0x08ed, 0x60eb, 0x98e8, 0x10e8, 0xe8eb, | |||
| 0xc0e4, 0x38e7, 0xb0e7, 0x48e4, 0x20e2, 0xd8e1, 0x50e1, 0xa8e2, | |||
| 0x00ff, 0xf8fc, 0x70fc, 0x88ff, 0xe0f9, 0x18fa, 0x90fa, 0x68f9, | |||
| 0x40f6, 0xb8f5, 0x30f5, 0xc8f6, 0xa0f0, 0x58f3, 0xd0f3, 0x28f0 }, | |||
| { 0x0000, 0x8113, 0x8223, 0x0330, 0x8443, 0x0550, 0x0660, 0x8773, | |||
| 0x8883, 0x0990, 0x0aa0, 0x8bb3, 0x0cc0, 0x8dd3, 0x8ee3, 0x0ff0, | |||
| 0x9103, 0x1010, 0x1320, 0x9233, 0x1540, 0x9453, 0x9763, 0x1670, | |||
| 0x1980, 0x9893, 0x9ba3, 0x1ab0, 0x9dc3, 0x1cd0, 0x1fe0, 0x9ef3, | |||
| 0xa203, 0x2310, 0x2020, 0xa133, 0x2640, 0xa753, 0xa463, 0x2570, | |||
| 0x2a80, 0xab93, 0xa8a3, 0x29b0, 0xaec3, 0x2fd0, 0x2ce0, 0xadf3, | |||
| 0x3300, 0xb213, 0xb123, 0x3030, 0xb743, 0x3650, 0x3560, 0xb473, | |||
| 0xbb83, 0x3a90, 0x39a0, 0xb8b3, 0x3fc0, 0xbed3, 0xbde3, 0x3cf0, | |||
| 0xc403, 0x4510, 0x4620, 0xc733, 0x4040, 0xc153, 0xc263, 0x4370, | |||
| 0x4c80, 0xcd93, 0xcea3, 0x4fb0, 0xc8c3, 0x49d0, 0x4ae0, 0xcbf3, | |||
| 0x5500, 0xd413, 0xd723, 0x5630, 0xd143, 0x5050, 0x5360, 0xd273, | |||
| 0xdd83, 0x5c90, 0x5fa0, 0xdeb3, 0x59c0, 0xd8d3, 0xdbe3, 0x5af0, | |||
| 0x6600, 0xe713, 0xe423, 0x6530, 0xe243, 0x6350, 0x6060, 0xe173, | |||
| 0xee83, 0x6f90, 0x6ca0, 0xedb3, 0x6ac0, 0xebd3, 0xe8e3, 0x69f0, | |||
| 0xf703, 0x7610, 0x7520, 0xf433, 0x7340, 0xf253, 0xf163, 0x7070, | |||
| 0x7f80, 0xfe93, 0xfda3, 0x7cb0, 0xfbc3, 0x7ad0, 0x79e0, 0xf8f3, | |||
| 0x0803, 0x8910, 0x8a20, 0x0b33, 0x8c40, 0x0d53, 0x0e63, 0x8f70, | |||
| 0x8080, 0x0193, 0x02a3, 0x83b0, 0x04c3, 0x85d0, 0x86e0, 0x07f3, | |||
| 0x9900, 0x1813, 0x1b23, 0x9a30, 0x1d43, 0x9c50, 0x9f60, 0x1e73, | |||
| 0x1183, 0x9090, 0x93a0, 0x12b3, 0x95c0, 0x14d3, 0x17e3, 0x96f0, | |||
| 0xaa00, 0x2b13, 0x2823, 0xa930, 0x2e43, 0xaf50, 0xac60, 0x2d73, | |||
| 0x2283, 0xa390, 0xa0a0, 0x21b3, 0xa6c0, 0x27d3, 0x24e3, 0xa5f0, | |||
| 0x3b03, 0xba10, 0xb920, 0x3833, 0xbf40, 0x3e53, 0x3d63, 0xbc70, | |||
| 0xb380, 0x3293, 0x31a3, 0xb0b0, 0x37c3, 0xb6d0, 0xb5e0, 0x34f3, | |||
| 0xcc00, 0x4d13, 0x4e23, 0xcf30, 0x4843, 0xc950, 0xca60, 0x4b73, | |||
| 0x4483, 0xc590, 0xc6a0, 0x47b3, 0xc0c0, 0x41d3, 0x42e3, 0xc3f0, | |||
| 0x5d03, 0xdc10, 0xdf20, 0x5e33, 0xd940, 0x5853, 0x5b63, 0xda70, | |||
| 0xd580, 0x5493, 0x57a3, 0xd6b0, 0x51c3, 0xd0d0, 0xd3e0, 0x52f3, | |||
| 0x6e03, 0xef10, 0xec20, 0x6d33, 0xea40, 0x6b53, 0x6863, 0xe970, | |||
| 0xe680, 0x6793, 0x64a3, 0xe5b0, 0x62c3, 0xe3d0, 0xe0e0, 0x61f3, | |||
| 0xff00, 0x7e13, 0x7d23, 0xfc30, 0x7b43, 0xfa50, 0xf960, 0x7873, | |||
| 0x7783, 0xf690, 0xf5a0, 0x74b3, 0xf3c0, 0x72d3, 0x71e3, 0xf0f0 }, | |||
| { 0x0000, 0x1006, 0x200c, 0x300a, 0x4018, 0x501e, 0x6014, 0x7012, | |||
| 0x8030, 0x9036, 0xa03c, 0xb03a, 0xc028, 0xd02e, 0xe024, 0xf022, | |||
| 0x8065, 0x9063, 0xa069, 0xb06f, 0xc07d, 0xd07b, 0xe071, 0xf077, | |||
| 0x0055, 0x1053, 0x2059, 0x305f, 0x404d, 0x504b, 0x6041, 0x7047, | |||
| 0x80cf, 0x90c9, 0xa0c3, 0xb0c5, 0xc0d7, 0xd0d1, 0xe0db, 0xf0dd, | |||
| 0x00ff, 0x10f9, 0x20f3, 0x30f5, 0x40e7, 0x50e1, 0x60eb, 0x70ed, | |||
| 0x00aa, 0x10ac, 0x20a6, 0x30a0, 0x40b2, 0x50b4, 0x60be, 0x70b8, | |||
| 0x809a, 0x909c, 0xa096, 0xb090, 0xc082, 0xd084, 0xe08e, 0xf088, | |||
| 0x819b, 0x919d, 0xa197, 0xb191, 0xc183, 0xd185, 0xe18f, 0xf189, | |||
| 0x01ab, 0x11ad, 0x21a7, 0x31a1, 0x41b3, 0x51b5, 0x61bf, 0x71b9, | |||
| 0x01fe, 0x11f8, 0x21f2, 0x31f4, 0x41e6, 0x51e0, 0x61ea, 0x71ec, | |||
| 0x81ce, 0x91c8, 0xa1c2, 0xb1c4, 0xc1d6, 0xd1d0, 0xe1da, 0xf1dc, | |||
| 0x0154, 0x1152, 0x2158, 0x315e, 0x414c, 0x514a, 0x6140, 0x7146, | |||
| 0x8164, 0x9162, 0xa168, 0xb16e, 0xc17c, 0xd17a, 0xe170, 0xf176, | |||
| 0x8131, 0x9137, 0xa13d, 0xb13b, 0xc129, 0xd12f, 0xe125, 0xf123, | |||
| 0x0101, 0x1107, 0x210d, 0x310b, 0x4119, 0x511f, 0x6115, 0x7113, | |||
| 0x8333, 0x9335, 0xa33f, 0xb339, 0xc32b, 0xd32d, 0xe327, 0xf321, | |||
| 0x0303, 0x1305, 0x230f, 0x3309, 0x431b, 0x531d, 0x6317, 0x7311, | |||
| 0x0356, 0x1350, 0x235a, 0x335c, 0x434e, 0x5348, 0x6342, 0x7344, | |||
| 0x8366, 0x9360, 0xa36a, 0xb36c, 0xc37e, 0xd378, 0xe372, 0xf374, | |||
| 0x03fc, 0x13fa, 0x23f0, 0x33f6, 0x43e4, 0x53e2, 0x63e8, 0x73ee, | |||
| 0x83cc, 0x93ca, 0xa3c0, 0xb3c6, 0xc3d4, 0xd3d2, 0xe3d8, 0xf3de, | |||
| 0x8399, 0x939f, 0xa395, 0xb393, 0xc381, 0xd387, 0xe38d, 0xf38b, | |||
| 0x03a9, 0x13af, 0x23a5, 0x33a3, 0x43b1, 0x53b7, 0x63bd, 0x73bb, | |||
| 0x02a8, 0x12ae, 0x22a4, 0x32a2, 0x42b0, 0x52b6, 0x62bc, 0x72ba, | |||
| 0x8298, 0x929e, 0xa294, 0xb292, 0xc280, 0xd286, 0xe28c, 0xf28a, | |||
| 0x82cd, 0x92cb, 0xa2c1, 0xb2c7, 0xc2d5, 0xd2d3, 0xe2d9, 0xf2df, | |||
| 0x02fd, 0x12fb, 0x22f1, 0x32f7, 0x42e5, 0x52e3, 0x62e9, 0x72ef, | |||
| 0x8267, 0x9261, 0xa26b, 0xb26d, 0xc27f, 0xd279, 0xe273, 0xf275, | |||
| 0x0257, 0x1251, 0x225b, 0x325d, 0x424f, 0x5249, 0x6243, 0x7245, | |||
| 0x0202, 0x1204, 0x220e, 0x3208, 0x421a, 0x521c, 0x6216, 0x7210, | |||
| 0x8232, 0x9234, 0xa23e, 0xb238, 0xc22a, 0xd22c, 0xe226, 0xf220 } | |||
| }; | |||
| #if 0 | |||
| void FLAC__crc16_init_table(void) | |||
| { | |||
| int i, j; | |||
| FLAC__uint16 polynomial, crc; | |||
| polynomial = 0x8005; | |||
| for(i = 0; i <= 0xFF; i++){ | |||
| crc = i << 8; | |||
| for(j = 0; j < 8; j++) | |||
| crc = (crc << 1) ^ (crc & (1 << 15) ? polynomial : 0); | |||
| FLAC__crc16_table[0][i] = crc; | |||
| } | |||
| for(i = 0; i <= 0xFF; i++) | |||
| for(j = 1; j < 8; j++) | |||
| FLAC__crc16_table[j][i] = FLAC__crc16_table[0][FLAC__crc16_table[j - 1][i] >> 8] ^ (FLAC__crc16_table[j - 1][i] << 8); | |||
| } | |||
| #endif | |||
| FLAC__uint8 FLAC__crc8(const FLAC__byte *data, uint32_t len) | |||
| { | |||
| FLAC__uint8 crc = 0; | |||
| while(len--) | |||
| crc = FLAC__crc8_table[crc ^ *data++]; | |||
| return crc; | |||
| } | |||
| FLAC__uint16 FLAC__crc16(const FLAC__byte *data, uint32_t len) | |||
| { | |||
| FLAC__uint16 crc = 0; | |||
| while(len >= 8){ | |||
| crc ^= data[0] << 8 | data[1]; | |||
| crc = FLAC__crc16_table[7][crc >> 8] ^ FLAC__crc16_table[6][crc & 0xFF] ^ | |||
| FLAC__crc16_table[5][data[2] ] ^ FLAC__crc16_table[4][data[3] ] ^ | |||
| FLAC__crc16_table[3][data[4] ] ^ FLAC__crc16_table[2][data[5] ] ^ | |||
| FLAC__crc16_table[1][data[6] ] ^ FLAC__crc16_table[0][data[7] ]; | |||
| data += 8; | |||
| len -= 8; | |||
| } | |||
| while(len--) | |||
| crc = (crc<<8) ^ FLAC__crc16_table[0][(crc>>8) ^ *data++]; | |||
| return crc; | |||
| } | |||
| FLAC__uint16 FLAC__crc16_update_words32(const FLAC__uint32 *words, uint32_t len, FLAC__uint16 crc) | |||
| { | |||
| while (len >= 2) { | |||
| crc ^= words[0] >> 16; | |||
| crc = FLAC__crc16_table[7][crc >> 8 ] ^ FLAC__crc16_table[6][crc & 0xFF ] ^ | |||
| FLAC__crc16_table[5][(words[0] >> 8) & 0xFF] ^ FLAC__crc16_table[4][ words[0] & 0xFF] ^ | |||
| FLAC__crc16_table[3][ words[1] >> 24 ] ^ FLAC__crc16_table[2][(words[1] >> 16) & 0xFF] ^ | |||
| FLAC__crc16_table[1][(words[1] >> 8) & 0xFF] ^ FLAC__crc16_table[0][ words[1] & 0xFF]; | |||
| words += 2; | |||
| len -= 2; | |||
| } | |||
| if (len) { | |||
| crc ^= words[0] >> 16; | |||
| crc = FLAC__crc16_table[3][crc >> 8 ] ^ FLAC__crc16_table[2][crc & 0xFF ] ^ | |||
| FLAC__crc16_table[1][(words[0] >> 8) & 0xFF] ^ FLAC__crc16_table[0][words[0] & 0xFF]; | |||
| } | |||
| return crc; | |||
| } | |||
| FLAC__uint16 FLAC__crc16_update_words64(const FLAC__uint64 *words, uint32_t len, FLAC__uint16 crc) | |||
| { | |||
| while (len--) { | |||
| crc ^= words[0] >> 48; | |||
| crc = FLAC__crc16_table[7][crc >> 8 ] ^ FLAC__crc16_table[6][crc & 0xFF ] ^ | |||
| FLAC__crc16_table[5][(words[0] >> 40) & 0xFF] ^ FLAC__crc16_table[4][(words[0] >> 32) & 0xFF] ^ | |||
| FLAC__crc16_table[3][(words[0] >> 24) & 0xFF] ^ FLAC__crc16_table[2][(words[0] >> 16) & 0xFF] ^ | |||
| FLAC__crc16_table[1][(words[0] >> 8) & 0xFF] ^ FLAC__crc16_table[0][ words[0] & 0xFF]; | |||
| words++; | |||
| } | |||
| return crc; | |||
| } | |||
| @@ -0,0 +1,395 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include <math.h> | |||
| #include <string.h> | |||
| #include "../compat.h" | |||
| #include "include/private/bitmath.h" | |||
| #include "include/private/fixed.h" | |||
| #include "include/private/macros.h" | |||
| #include "../assert.h" | |||
| #ifdef local_abs | |||
| #undef local_abs | |||
| #endif | |||
| #define local_abs(x) ((uint32_t)((x)<0? -(x) : (x))) | |||
| #ifdef FLAC__INTEGER_ONLY_LIBRARY | |||
| /* rbps stands for residual bits per sample | |||
| * | |||
| * (ln(2) * err) | |||
| * rbps = log (-----------) | |||
| * 2 ( n ) | |||
| */ | |||
| static FLAC__fixedpoint local__compute_rbps_integerized(FLAC__uint32 err, FLAC__uint32 n) | |||
| { | |||
| FLAC__uint32 rbps; | |||
| uint32_t bits; /* the number of bits required to represent a number */ | |||
| int fracbits; /* the number of bits of rbps that comprise the fractional part */ | |||
| FLAC__ASSERT(sizeof(rbps) == sizeof(FLAC__fixedpoint)); | |||
| FLAC__ASSERT(err > 0); | |||
| FLAC__ASSERT(n > 0); | |||
| FLAC__ASSERT(n <= FLAC__MAX_BLOCK_SIZE); | |||
| if(err <= n) | |||
| return 0; | |||
| /* | |||
| * The above two things tell us 1) n fits in 16 bits; 2) err/n > 1. | |||
| * These allow us later to know we won't lose too much precision in the | |||
| * fixed-point division (err<<fracbits)/n. | |||
| */ | |||
| fracbits = (8*sizeof(err)) - (FLAC__bitmath_ilog2(err)+1); | |||
| err <<= fracbits; | |||
| err /= n; | |||
| /* err now holds err/n with fracbits fractional bits */ | |||
| /* | |||
| * Whittle err down to 16 bits max. 16 significant bits is enough for | |||
| * our purposes. | |||
| */ | |||
| FLAC__ASSERT(err > 0); | |||
| bits = FLAC__bitmath_ilog2(err)+1; | |||
| if(bits > 16) { | |||
| err >>= (bits-16); | |||
| fracbits -= (bits-16); | |||
| } | |||
| rbps = (FLAC__uint32)err; | |||
| /* Multiply by fixed-point version of ln(2), with 16 fractional bits */ | |||
| rbps *= FLAC__FP_LN2; | |||
| fracbits += 16; | |||
| FLAC__ASSERT(fracbits >= 0); | |||
| /* FLAC__fixedpoint_log2 requires fracbits%4 to be 0 */ | |||
| { | |||
| const int f = fracbits & 3; | |||
| if(f) { | |||
| rbps >>= f; | |||
| fracbits -= f; | |||
| } | |||
| } | |||
| rbps = FLAC__fixedpoint_log2(rbps, fracbits, (uint32_t)(-1)); | |||
| if(rbps == 0) | |||
| return 0; | |||
| /* | |||
| * The return value must have 16 fractional bits. Since the whole part | |||
| * of the base-2 log of a 32 bit number must fit in 5 bits, and fracbits | |||
| * must be >= -3, these assertion allows us to be able to shift rbps | |||
| * left if necessary to get 16 fracbits without losing any bits of the | |||
| * whole part of rbps. | |||
| * | |||
| * There is a slight chance due to accumulated error that the whole part | |||
| * will require 6 bits, so we use 6 in the assertion. Really though as | |||
| * long as it fits in 13 bits (32 - (16 - (-3))) we are fine. | |||
| */ | |||
| FLAC__ASSERT((int)FLAC__bitmath_ilog2(rbps)+1 <= fracbits + 6); | |||
| FLAC__ASSERT(fracbits >= -3); | |||
| /* now shift the decimal point into place */ | |||
| if(fracbits < 16) | |||
| return rbps << (16-fracbits); | |||
| else if(fracbits > 16) | |||
| return rbps >> (fracbits-16); | |||
| else | |||
| return rbps; | |||
| } | |||
| static FLAC__fixedpoint local__compute_rbps_wide_integerized(FLAC__uint64 err, FLAC__uint32 n) | |||
| { | |||
| FLAC__uint32 rbps; | |||
| uint32_t bits; /* the number of bits required to represent a number */ | |||
| int fracbits; /* the number of bits of rbps that comprise the fractional part */ | |||
| FLAC__ASSERT(sizeof(rbps) == sizeof(FLAC__fixedpoint)); | |||
| FLAC__ASSERT(err > 0); | |||
| FLAC__ASSERT(n > 0); | |||
| FLAC__ASSERT(n <= FLAC__MAX_BLOCK_SIZE); | |||
| if(err <= n) | |||
| return 0; | |||
| /* | |||
| * The above two things tell us 1) n fits in 16 bits; 2) err/n > 1. | |||
| * These allow us later to know we won't lose too much precision in the | |||
| * fixed-point division (err<<fracbits)/n. | |||
| */ | |||
| fracbits = (8*sizeof(err)) - (FLAC__bitmath_ilog2_wide(err)+1); | |||
| err <<= fracbits; | |||
| err /= n; | |||
| /* err now holds err/n with fracbits fractional bits */ | |||
| /* | |||
| * Whittle err down to 16 bits max. 16 significant bits is enough for | |||
| * our purposes. | |||
| */ | |||
| FLAC__ASSERT(err > 0); | |||
| bits = FLAC__bitmath_ilog2_wide(err)+1; | |||
| if(bits > 16) { | |||
| err >>= (bits-16); | |||
| fracbits -= (bits-16); | |||
| } | |||
| rbps = (FLAC__uint32)err; | |||
| /* Multiply by fixed-point version of ln(2), with 16 fractional bits */ | |||
| rbps *= FLAC__FP_LN2; | |||
| fracbits += 16; | |||
| FLAC__ASSERT(fracbits >= 0); | |||
| /* FLAC__fixedpoint_log2 requires fracbits%4 to be 0 */ | |||
| { | |||
| const int f = fracbits & 3; | |||
| if(f) { | |||
| rbps >>= f; | |||
| fracbits -= f; | |||
| } | |||
| } | |||
| rbps = FLAC__fixedpoint_log2(rbps, fracbits, (uint32_t)(-1)); | |||
| if(rbps == 0) | |||
| return 0; | |||
| /* | |||
| * The return value must have 16 fractional bits. Since the whole part | |||
| * of the base-2 log of a 32 bit number must fit in 5 bits, and fracbits | |||
| * must be >= -3, these assertion allows us to be able to shift rbps | |||
| * left if necessary to get 16 fracbits without losing any bits of the | |||
| * whole part of rbps. | |||
| * | |||
| * There is a slight chance due to accumulated error that the whole part | |||
| * will require 6 bits, so we use 6 in the assertion. Really though as | |||
| * long as it fits in 13 bits (32 - (16 - (-3))) we are fine. | |||
| */ | |||
| FLAC__ASSERT((int)FLAC__bitmath_ilog2(rbps)+1 <= fracbits + 6); | |||
| FLAC__ASSERT(fracbits >= -3); | |||
| /* now shift the decimal point into place */ | |||
| if(fracbits < 16) | |||
| return rbps << (16-fracbits); | |||
| else if(fracbits > 16) | |||
| return rbps >> (fracbits-16); | |||
| else | |||
| return rbps; | |||
| } | |||
| #endif | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) | |||
| #else | |||
| uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) | |||
| #endif | |||
| { | |||
| FLAC__int32 last_error_0 = data[-1]; | |||
| FLAC__int32 last_error_1 = data[-1] - data[-2]; | |||
| FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]); | |||
| FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]); | |||
| FLAC__int32 error, save; | |||
| FLAC__uint32 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0; | |||
| uint32_t i, order; | |||
| for(i = 0; i < data_len; i++) { | |||
| error = data[i] ; total_error_0 += local_abs(error); save = error; | |||
| error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error; | |||
| error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error; | |||
| error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error; | |||
| error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save; | |||
| } | |||
| if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) | |||
| order = 0; | |||
| else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) | |||
| order = 1; | |||
| else if(total_error_2 < flac_min(total_error_3, total_error_4)) | |||
| order = 2; | |||
| else if(total_error_3 < total_error_4) | |||
| order = 3; | |||
| else | |||
| order = 4; | |||
| /* Estimate the expected number of bits per residual signal sample. */ | |||
| /* 'total_error*' is linearly related to the variance of the residual */ | |||
| /* signal, so we use it directly to compute E(|x|) */ | |||
| FLAC__ASSERT(data_len > 0 || total_error_0 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_1 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_2 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_3 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_4 == 0); | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0); | |||
| #else | |||
| residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_integerized(total_error_0, data_len) : 0; | |||
| residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_integerized(total_error_1, data_len) : 0; | |||
| residual_bits_per_sample[2] = (total_error_2 > 0) ? local__compute_rbps_integerized(total_error_2, data_len) : 0; | |||
| residual_bits_per_sample[3] = (total_error_3 > 0) ? local__compute_rbps_integerized(total_error_3, data_len) : 0; | |||
| residual_bits_per_sample[4] = (total_error_4 > 0) ? local__compute_rbps_integerized(total_error_4, data_len) : 0; | |||
| #endif | |||
| return order; | |||
| } | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) | |||
| #else | |||
| uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) | |||
| #endif | |||
| { | |||
| FLAC__int32 last_error_0 = data[-1]; | |||
| FLAC__int32 last_error_1 = data[-1] - data[-2]; | |||
| FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]); | |||
| FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]); | |||
| FLAC__int32 error, save; | |||
| /* total_error_* are 64-bits to avoid overflow when encoding | |||
| * erratic signals when the bits-per-sample and blocksize are | |||
| * large. | |||
| */ | |||
| FLAC__uint64 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0; | |||
| uint32_t i, order; | |||
| for(i = 0; i < data_len; i++) { | |||
| error = data[i] ; total_error_0 += local_abs(error); save = error; | |||
| error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error; | |||
| error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error; | |||
| error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error; | |||
| error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save; | |||
| } | |||
| if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) | |||
| order = 0; | |||
| else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) | |||
| order = 1; | |||
| else if(total_error_2 < flac_min(total_error_3, total_error_4)) | |||
| order = 2; | |||
| else if(total_error_3 < total_error_4) | |||
| order = 3; | |||
| else | |||
| order = 4; | |||
| /* Estimate the expected number of bits per residual signal sample. */ | |||
| /* 'total_error*' is linearly related to the variance of the residual */ | |||
| /* signal, so we use it directly to compute E(|x|) */ | |||
| FLAC__ASSERT(data_len > 0 || total_error_0 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_1 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_2 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_3 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_4 == 0); | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0); | |||
| #else | |||
| residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_wide_integerized(total_error_0, data_len) : 0; | |||
| residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_wide_integerized(total_error_1, data_len) : 0; | |||
| residual_bits_per_sample[2] = (total_error_2 > 0) ? local__compute_rbps_wide_integerized(total_error_2, data_len) : 0; | |||
| residual_bits_per_sample[3] = (total_error_3 > 0) ? local__compute_rbps_wide_integerized(total_error_3, data_len) : 0; | |||
| residual_bits_per_sample[4] = (total_error_4 > 0) ? local__compute_rbps_wide_integerized(total_error_4, data_len) : 0; | |||
| #endif | |||
| return order; | |||
| } | |||
| void FLAC__fixed_compute_residual(const FLAC__int32 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[]) | |||
| { | |||
| const int idata_len = (int)data_len; | |||
| int i; | |||
| switch(order) { | |||
| case 0: | |||
| FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0])); | |||
| memcpy(residual, data, sizeof(residual[0])*data_len); | |||
| break; | |||
| case 1: | |||
| for(i = 0; i < idata_len; i++) | |||
| residual[i] = data[i] - data[i-1]; | |||
| break; | |||
| case 2: | |||
| for(i = 0; i < idata_len; i++) | |||
| residual[i] = data[i] - 2*data[i-1] + data[i-2]; | |||
| break; | |||
| case 3: | |||
| for(i = 0; i < idata_len; i++) | |||
| residual[i] = data[i] - 3*data[i-1] + 3*data[i-2] - data[i-3]; | |||
| break; | |||
| case 4: | |||
| for(i = 0; i < idata_len; i++) | |||
| residual[i] = data[i] - 4*data[i-1] + 6*data[i-2] - 4*data[i-3] + data[i-4]; | |||
| break; | |||
| default: | |||
| FLAC__ASSERT(0); | |||
| } | |||
| } | |||
| void FLAC__fixed_restore_signal(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int32 data[]) | |||
| { | |||
| int i, idata_len = (int)data_len; | |||
| switch(order) { | |||
| case 0: | |||
| FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0])); | |||
| memcpy(data, residual, sizeof(residual[0])*data_len); | |||
| break; | |||
| case 1: | |||
| for(i = 0; i < idata_len; i++) | |||
| data[i] = residual[i] + data[i-1]; | |||
| break; | |||
| case 2: | |||
| for(i = 0; i < idata_len; i++) | |||
| data[i] = residual[i] + 2*data[i-1] - data[i-2]; | |||
| break; | |||
| case 3: | |||
| for(i = 0; i < idata_len; i++) | |||
| data[i] = residual[i] + 3*data[i-1] - 3*data[i-2] + data[i-3]; | |||
| break; | |||
| case 4: | |||
| for(i = 0; i < idata_len; i++) | |||
| data[i] = residual[i] + 4*data[i-1] - 6*data[i-2] + 4*data[i-3] - data[i-4]; | |||
| break; | |||
| default: | |||
| FLAC__ASSERT(0); | |||
| } | |||
| } | |||
| @@ -0,0 +1,255 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include "include/private/cpu.h" | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| #ifndef FLAC__NO_ASM | |||
| #if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN | |||
| #include "include/private/fixed.h" | |||
| #ifdef FLAC__SSE2_SUPPORTED | |||
| #include <emmintrin.h> /* SSE2 */ | |||
| #include <math.h> | |||
| #include "include/private/macros.h" | |||
| #include "../compat.h" | |||
| #include "../assert.h" | |||
| #ifdef FLAC__CPU_IA32 | |||
| #define m128i_to_i64(dest, src) _mm_storel_epi64((__m128i*)&dest, src) | |||
| #else | |||
| #define m128i_to_i64(dest, src) dest = _mm_cvtsi128_si64(src) | |||
| #endif | |||
| FLAC__SSE_TARGET("sse2") | |||
| uint32_t FLAC__fixed_compute_best_predictor_intrin_sse2(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]) | |||
| { | |||
| FLAC__uint32 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4; | |||
| uint32_t i, order; | |||
| __m128i total_err0, total_err1, total_err2; | |||
| { | |||
| FLAC__int32 itmp; | |||
| __m128i last_error; | |||
| last_error = _mm_cvtsi32_si128(data[-1]); // 0 0 0 le0 | |||
| itmp = data[-2]; | |||
| last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); | |||
| last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 0 le0 le1 | |||
| itmp -= data[-3]; | |||
| last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); | |||
| last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 le0 le1 le2 | |||
| itmp -= data[-3] - data[-4]; | |||
| last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); | |||
| last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // le0 le1 le2 le3 | |||
| total_err0 = total_err1 = _mm_setzero_si128(); | |||
| for(i = 0; i < data_len; i++) { | |||
| __m128i err0, err1, tmp; | |||
| err0 = _mm_cvtsi32_si128(data[i]); // 0 0 0 e0 | |||
| err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0)); // e0 e0 e0 e0 | |||
| #if 1 /* OPT_SSE */ | |||
| err1 = _mm_sub_epi32(err1, last_error); | |||
| last_error = _mm_srli_si128(last_error, 4); // 0 le0 le1 le2 | |||
| err1 = _mm_sub_epi32(err1, last_error); | |||
| last_error = _mm_srli_si128(last_error, 4); // 0 0 le0 le1 | |||
| err1 = _mm_sub_epi32(err1, last_error); | |||
| last_error = _mm_srli_si128(last_error, 4); // 0 0 0 le0 | |||
| err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4 | |||
| #else | |||
| last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8)); // le0 le1 le2+le0 le3+le1 | |||
| last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4)); // le0 le1+le0 le2+le0+le1 le3+le1+le2+le0 | |||
| err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4 | |||
| #endif | |||
| tmp = _mm_slli_si128(err0, 12); // e0 0 0 0 | |||
| last_error = _mm_srli_si128(err1, 4); // 0 e1 e2 e3 | |||
| last_error = _mm_or_si128(last_error, tmp); // e0 e1 e2 e3 | |||
| tmp = _mm_srai_epi32(err0, 31); | |||
| err0 = _mm_xor_si128(err0, tmp); | |||
| err0 = _mm_sub_epi32(err0, tmp); | |||
| tmp = _mm_srai_epi32(err1, 31); | |||
| err1 = _mm_xor_si128(err1, tmp); | |||
| err1 = _mm_sub_epi32(err1, tmp); | |||
| total_err0 = _mm_add_epi32(total_err0, err0); // 0 0 0 te0 | |||
| total_err1 = _mm_add_epi32(total_err1, err1); // te1 te2 te3 te4 | |||
| } | |||
| } | |||
| total_error_0 = _mm_cvtsi128_si32(total_err0); | |||
| total_err2 = total_err1; // te1 te2 te3 te4 | |||
| total_err1 = _mm_srli_si128(total_err1, 8); // 0 0 te1 te2 | |||
| total_error_4 = _mm_cvtsi128_si32(total_err2); | |||
| total_error_2 = _mm_cvtsi128_si32(total_err1); | |||
| total_err2 = _mm_srli_si128(total_err2, 4); // 0 te1 te2 te3 | |||
| total_err1 = _mm_srli_si128(total_err1, 4); // 0 0 0 te1 | |||
| total_error_3 = _mm_cvtsi128_si32(total_err2); | |||
| total_error_1 = _mm_cvtsi128_si32(total_err1); | |||
| /* prefer higher order */ | |||
| if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) | |||
| order = 0; | |||
| else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) | |||
| order = 1; | |||
| else if(total_error_2 < flac_min(total_error_3, total_error_4)) | |||
| order = 2; | |||
| else if(total_error_3 < total_error_4) | |||
| order = 3; | |||
| else | |||
| order = 4; | |||
| /* Estimate the expected number of bits per residual signal sample. */ | |||
| /* 'total_error*' is linearly related to the variance of the residual */ | |||
| /* signal, so we use it directly to compute E(|x|) */ | |||
| FLAC__ASSERT(data_len > 0 || total_error_0 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_1 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_2 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_3 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_4 == 0); | |||
| residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0); | |||
| return order; | |||
| } | |||
| FLAC__SSE_TARGET("sse2") | |||
| uint32_t FLAC__fixed_compute_best_predictor_wide_intrin_sse2(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]) | |||
| { | |||
| FLAC__uint64 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4; | |||
| uint32_t i, order; | |||
| __m128i total_err0, total_err1, total_err3; | |||
| { | |||
| FLAC__int32 itmp; | |||
| __m128i last_error, zero = _mm_setzero_si128(); | |||
| last_error = _mm_cvtsi32_si128(data[-1]); // 0 0 0 le0 | |||
| itmp = data[-2]; | |||
| last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); | |||
| last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 0 le0 le1 | |||
| itmp -= data[-3]; | |||
| last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); | |||
| last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 le0 le1 le2 | |||
| itmp -= data[-3] - data[-4]; | |||
| last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); | |||
| last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // le0 le1 le2 le3 | |||
| total_err0 = total_err1 = total_err3 = _mm_setzero_si128(); | |||
| for(i = 0; i < data_len; i++) { | |||
| __m128i err0, err1, tmp; | |||
| err0 = _mm_cvtsi32_si128(data[i]); // 0 0 0 e0 | |||
| err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0)); // e0 e0 e0 e0 | |||
| #if 1 /* OPT_SSE */ | |||
| err1 = _mm_sub_epi32(err1, last_error); | |||
| last_error = _mm_srli_si128(last_error, 4); // 0 le0 le1 le2 | |||
| err1 = _mm_sub_epi32(err1, last_error); | |||
| last_error = _mm_srli_si128(last_error, 4); // 0 0 le0 le1 | |||
| err1 = _mm_sub_epi32(err1, last_error); | |||
| last_error = _mm_srli_si128(last_error, 4); // 0 0 0 le0 | |||
| err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4 | |||
| #else | |||
| last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8)); // le0 le1 le2+le0 le3+le1 | |||
| last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4)); // le0 le1+le0 le2+le0+le1 le3+le1+le2+le0 | |||
| err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4 | |||
| #endif | |||
| tmp = _mm_slli_si128(err0, 12); // e0 0 0 0 | |||
| last_error = _mm_srli_si128(err1, 4); // 0 e1 e2 e3 | |||
| last_error = _mm_or_si128(last_error, tmp); // e0 e1 e2 e3 | |||
| tmp = _mm_srai_epi32(err0, 31); | |||
| err0 = _mm_xor_si128(err0, tmp); | |||
| err0 = _mm_sub_epi32(err0, tmp); | |||
| tmp = _mm_srai_epi32(err1, 31); | |||
| err1 = _mm_xor_si128(err1, tmp); | |||
| err1 = _mm_sub_epi32(err1, tmp); | |||
| total_err0 = _mm_add_epi64(total_err0, err0); // 0 te0 | |||
| err0 = _mm_unpacklo_epi32(err1, zero); // 0 |e3| 0 |e4| | |||
| err1 = _mm_unpackhi_epi32(err1, zero); // 0 |e1| 0 |e2| | |||
| total_err3 = _mm_add_epi64(total_err3, err0); // te3 te4 | |||
| total_err1 = _mm_add_epi64(total_err1, err1); // te1 te2 | |||
| } | |||
| } | |||
| m128i_to_i64(total_error_0, total_err0); | |||
| m128i_to_i64(total_error_4, total_err3); | |||
| m128i_to_i64(total_error_2, total_err1); | |||
| total_err3 = _mm_srli_si128(total_err3, 8); // 0 te3 | |||
| total_err1 = _mm_srli_si128(total_err1, 8); // 0 te1 | |||
| m128i_to_i64(total_error_3, total_err3); | |||
| m128i_to_i64(total_error_1, total_err1); | |||
| /* prefer higher order */ | |||
| if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) | |||
| order = 0; | |||
| else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) | |||
| order = 1; | |||
| else if(total_error_2 < flac_min(total_error_3, total_error_4)) | |||
| order = 2; | |||
| else if(total_error_3 < total_error_4) | |||
| order = 3; | |||
| else | |||
| order = 4; | |||
| /* Estimate the expected number of bits per residual signal sample. */ | |||
| /* 'total_error*' is linearly related to the variance of the residual */ | |||
| /* signal, so we use it directly to compute E(|x|) */ | |||
| FLAC__ASSERT(data_len > 0 || total_error_0 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_1 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_2 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_3 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_4 == 0); | |||
| residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0); | |||
| return order; | |||
| } | |||
| #endif /* FLAC__SSE2_SUPPORTED */ | |||
| #endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */ | |||
| #endif /* FLAC__NO_ASM */ | |||
| #endif /* FLAC__INTEGER_ONLY_LIBRARY */ | |||
| @@ -0,0 +1,243 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include "include/private/cpu.h" | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| #ifndef FLAC__NO_ASM | |||
| #if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN | |||
| #include "include/private/fixed.h" | |||
| #ifdef FLAC__SSSE3_SUPPORTED | |||
| #include <tmmintrin.h> /* SSSE3 */ | |||
| #include <math.h> | |||
| #include "include/private/macros.h" | |||
| #include "../compat.h" | |||
| #include "../assert.h" | |||
| #ifdef FLAC__CPU_IA32 | |||
| #define m128i_to_i64(dest, src) _mm_storel_epi64((__m128i*)&dest, src) | |||
| #else | |||
| #define m128i_to_i64(dest, src) dest = _mm_cvtsi128_si64(src) | |||
| #endif | |||
| FLAC__SSE_TARGET("ssse3") | |||
| uint32_t FLAC__fixed_compute_best_predictor_intrin_ssse3(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]) | |||
| { | |||
| FLAC__uint32 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4; | |||
| uint32_t i, order; | |||
| __m128i total_err0, total_err1, total_err2; | |||
| { | |||
| FLAC__int32 itmp; | |||
| __m128i last_error; | |||
| last_error = _mm_cvtsi32_si128(data[-1]); // 0 0 0 le0 | |||
| itmp = data[-2]; | |||
| last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); | |||
| last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 0 le0 le1 | |||
| itmp -= data[-3]; | |||
| last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); | |||
| last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 le0 le1 le2 | |||
| itmp -= data[-3] - data[-4]; | |||
| last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); | |||
| last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // le0 le1 le2 le3 | |||
| total_err0 = total_err1 = _mm_setzero_si128(); | |||
| for(i = 0; i < data_len; i++) { | |||
| __m128i err0, err1; | |||
| err0 = _mm_cvtsi32_si128(data[i]); // 0 0 0 e0 | |||
| err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0)); // e0 e0 e0 e0 | |||
| #if 1 /* OPT_SSE */ | |||
| err1 = _mm_sub_epi32(err1, last_error); | |||
| last_error = _mm_srli_si128(last_error, 4); // 0 le0 le1 le2 | |||
| err1 = _mm_sub_epi32(err1, last_error); | |||
| last_error = _mm_srli_si128(last_error, 4); // 0 0 le0 le1 | |||
| err1 = _mm_sub_epi32(err1, last_error); | |||
| last_error = _mm_srli_si128(last_error, 4); // 0 0 0 le0 | |||
| err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4 | |||
| #else | |||
| last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8)); // le0 le1 le2+le0 le3+le1 | |||
| last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4)); // le0 le1+le0 le2+le0+le1 le3+le1+le2+le0 | |||
| err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4 | |||
| #endif | |||
| last_error = _mm_alignr_epi8(err0, err1, 4); // e0 e1 e2 e3 | |||
| err0 = _mm_abs_epi32(err0); | |||
| err1 = _mm_abs_epi32(err1); | |||
| total_err0 = _mm_add_epi32(total_err0, err0); // 0 0 0 te0 | |||
| total_err1 = _mm_add_epi32(total_err1, err1); // te1 te2 te3 te4 | |||
| } | |||
| } | |||
| total_error_0 = _mm_cvtsi128_si32(total_err0); | |||
| total_err2 = total_err1; // te1 te2 te3 te4 | |||
| total_err1 = _mm_srli_si128(total_err1, 8); // 0 0 te1 te2 | |||
| total_error_4 = _mm_cvtsi128_si32(total_err2); | |||
| total_error_2 = _mm_cvtsi128_si32(total_err1); | |||
| total_err2 = _mm_srli_si128(total_err2, 4); // 0 te1 te2 te3 | |||
| total_err1 = _mm_srli_si128(total_err1, 4); // 0 0 0 te1 | |||
| total_error_3 = _mm_cvtsi128_si32(total_err2); | |||
| total_error_1 = _mm_cvtsi128_si32(total_err1); | |||
| /* prefer higher order */ | |||
| if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) | |||
| order = 0; | |||
| else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) | |||
| order = 1; | |||
| else if(total_error_2 < flac_min(total_error_3, total_error_4)) | |||
| order = 2; | |||
| else if(total_error_3 < total_error_4) | |||
| order = 3; | |||
| else | |||
| order = 4; | |||
| /* Estimate the expected number of bits per residual signal sample. */ | |||
| /* 'total_error*' is linearly related to the variance of the residual */ | |||
| /* signal, so we use it directly to compute E(|x|) */ | |||
| FLAC__ASSERT(data_len > 0 || total_error_0 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_1 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_2 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_3 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_4 == 0); | |||
| residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0); | |||
| return order; | |||
| } | |||
| FLAC__SSE_TARGET("ssse3") | |||
| uint32_t FLAC__fixed_compute_best_predictor_wide_intrin_ssse3(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]) | |||
| { | |||
| FLAC__uint64 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4; | |||
| uint32_t i, order; | |||
| __m128i total_err0, total_err1, total_err3; | |||
| { | |||
| FLAC__int32 itmp; | |||
| __m128i last_error, zero = _mm_setzero_si128(); | |||
| last_error = _mm_cvtsi32_si128(data[-1]); // 0 0 0 le0 | |||
| itmp = data[-2]; | |||
| last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); | |||
| last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 0 le0 le1 | |||
| itmp -= data[-3]; | |||
| last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); | |||
| last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 le0 le1 le2 | |||
| itmp -= data[-3] - data[-4]; | |||
| last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0)); | |||
| last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // le0 le1 le2 le3 | |||
| total_err0 = total_err1 = total_err3 = _mm_setzero_si128(); | |||
| for(i = 0; i < data_len; i++) { | |||
| __m128i err0, err1; | |||
| err0 = _mm_cvtsi32_si128(data[i]); // 0 0 0 e0 | |||
| err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0)); // e0 e0 e0 e0 | |||
| #if 1 /* OPT_SSE */ | |||
| err1 = _mm_sub_epi32(err1, last_error); | |||
| last_error = _mm_srli_si128(last_error, 4); // 0 le0 le1 le2 | |||
| err1 = _mm_sub_epi32(err1, last_error); | |||
| last_error = _mm_srli_si128(last_error, 4); // 0 0 le0 le1 | |||
| err1 = _mm_sub_epi32(err1, last_error); | |||
| last_error = _mm_srli_si128(last_error, 4); // 0 0 0 le0 | |||
| err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4 | |||
| #else | |||
| last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8)); // le0 le1 le2+le0 le3+le1 | |||
| last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4)); // le0 le1+le0 le2+le0+le1 le3+le1+le2+le0 | |||
| err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4 | |||
| #endif | |||
| last_error = _mm_alignr_epi8(err0, err1, 4); // e0 e1 e2 e3 | |||
| err0 = _mm_abs_epi32(err0); | |||
| err1 = _mm_abs_epi32(err1); // |e1| |e2| |e3| |e4| | |||
| total_err0 = _mm_add_epi64(total_err0, err0); // 0 te0 | |||
| err0 = _mm_unpacklo_epi32(err1, zero); // 0 |e3| 0 |e4| | |||
| err1 = _mm_unpackhi_epi32(err1, zero); // 0 |e1| 0 |e2| | |||
| total_err3 = _mm_add_epi64(total_err3, err0); // te3 te4 | |||
| total_err1 = _mm_add_epi64(total_err1, err1); // te1 te2 | |||
| } | |||
| } | |||
| m128i_to_i64(total_error_0, total_err0); | |||
| m128i_to_i64(total_error_4, total_err3); | |||
| m128i_to_i64(total_error_2, total_err1); | |||
| total_err3 = _mm_srli_si128(total_err3, 8); // 0 te3 | |||
| total_err1 = _mm_srli_si128(total_err1, 8); // 0 te1 | |||
| m128i_to_i64(total_error_3, total_err3); | |||
| m128i_to_i64(total_error_1, total_err1); | |||
| /* prefer higher order */ | |||
| if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) | |||
| order = 0; | |||
| else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) | |||
| order = 1; | |||
| else if(total_error_2 < flac_min(total_error_3, total_error_4)) | |||
| order = 2; | |||
| else if(total_error_3 < total_error_4) | |||
| order = 3; | |||
| else | |||
| order = 4; | |||
| /* Estimate the expected number of bits per residual signal sample. */ | |||
| /* 'total_error*' is linearly related to the variance of the residual */ | |||
| /* signal, so we use it directly to compute E(|x|) */ | |||
| FLAC__ASSERT(data_len > 0 || total_error_0 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_1 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_2 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_3 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_4 == 0); | |||
| residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0); | |||
| return order; | |||
| } | |||
| #endif /* FLAC__SSSE3_SUPPORTED */ | |||
| #endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */ | |||
| #endif /* FLAC__NO_ASM */ | |||
| #endif /* FLAC__INTEGER_ONLY_LIBRARY */ | |||
| @@ -0,0 +1,302 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2004-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include "../assert.h" | |||
| #include "../compat.h" | |||
| #include "include/private/float.h" | |||
| #ifdef FLAC__INTEGER_ONLY_LIBRARY | |||
| const FLAC__fixedpoint FLAC__FP_ZERO = 0; | |||
| const FLAC__fixedpoint FLAC__FP_ONE_HALF = 0x00008000; | |||
| const FLAC__fixedpoint FLAC__FP_ONE = 0x00010000; | |||
| const FLAC__fixedpoint FLAC__FP_LN2 = 45426; | |||
| const FLAC__fixedpoint FLAC__FP_E = 178145; | |||
| /* Lookup tables for Knuth's logarithm algorithm */ | |||
| #define LOG2_LOOKUP_PRECISION 16 | |||
| static const FLAC__uint32 log2_lookup[][LOG2_LOOKUP_PRECISION] = { | |||
| { | |||
| /* | |||
| * 0 fraction bits | |||
| */ | |||
| /* undefined */ 0x00000000, | |||
| /* lg(2/1) = */ 0x00000001, | |||
| /* lg(4/3) = */ 0x00000000, | |||
| /* lg(8/7) = */ 0x00000000, | |||
| /* lg(16/15) = */ 0x00000000, | |||
| /* lg(32/31) = */ 0x00000000, | |||
| /* lg(64/63) = */ 0x00000000, | |||
| /* lg(128/127) = */ 0x00000000, | |||
| /* lg(256/255) = */ 0x00000000, | |||
| /* lg(512/511) = */ 0x00000000, | |||
| /* lg(1024/1023) = */ 0x00000000, | |||
| /* lg(2048/2047) = */ 0x00000000, | |||
| /* lg(4096/4095) = */ 0x00000000, | |||
| /* lg(8192/8191) = */ 0x00000000, | |||
| /* lg(16384/16383) = */ 0x00000000, | |||
| /* lg(32768/32767) = */ 0x00000000 | |||
| }, | |||
| { | |||
| /* | |||
| * 4 fraction bits | |||
| */ | |||
| /* undefined */ 0x00000000, | |||
| /* lg(2/1) = */ 0x00000010, | |||
| /* lg(4/3) = */ 0x00000007, | |||
| /* lg(8/7) = */ 0x00000003, | |||
| /* lg(16/15) = */ 0x00000001, | |||
| /* lg(32/31) = */ 0x00000001, | |||
| /* lg(64/63) = */ 0x00000000, | |||
| /* lg(128/127) = */ 0x00000000, | |||
| /* lg(256/255) = */ 0x00000000, | |||
| /* lg(512/511) = */ 0x00000000, | |||
| /* lg(1024/1023) = */ 0x00000000, | |||
| /* lg(2048/2047) = */ 0x00000000, | |||
| /* lg(4096/4095) = */ 0x00000000, | |||
| /* lg(8192/8191) = */ 0x00000000, | |||
| /* lg(16384/16383) = */ 0x00000000, | |||
| /* lg(32768/32767) = */ 0x00000000 | |||
| }, | |||
| { | |||
| /* | |||
| * 8 fraction bits | |||
| */ | |||
| /* undefined */ 0x00000000, | |||
| /* lg(2/1) = */ 0x00000100, | |||
| /* lg(4/3) = */ 0x0000006a, | |||
| /* lg(8/7) = */ 0x00000031, | |||
| /* lg(16/15) = */ 0x00000018, | |||
| /* lg(32/31) = */ 0x0000000c, | |||
| /* lg(64/63) = */ 0x00000006, | |||
| /* lg(128/127) = */ 0x00000003, | |||
| /* lg(256/255) = */ 0x00000001, | |||
| /* lg(512/511) = */ 0x00000001, | |||
| /* lg(1024/1023) = */ 0x00000000, | |||
| /* lg(2048/2047) = */ 0x00000000, | |||
| /* lg(4096/4095) = */ 0x00000000, | |||
| /* lg(8192/8191) = */ 0x00000000, | |||
| /* lg(16384/16383) = */ 0x00000000, | |||
| /* lg(32768/32767) = */ 0x00000000 | |||
| }, | |||
| { | |||
| /* | |||
| * 12 fraction bits | |||
| */ | |||
| /* undefined */ 0x00000000, | |||
| /* lg(2/1) = */ 0x00001000, | |||
| /* lg(4/3) = */ 0x000006a4, | |||
| /* lg(8/7) = */ 0x00000315, | |||
| /* lg(16/15) = */ 0x0000017d, | |||
| /* lg(32/31) = */ 0x000000bc, | |||
| /* lg(64/63) = */ 0x0000005d, | |||
| /* lg(128/127) = */ 0x0000002e, | |||
| /* lg(256/255) = */ 0x00000017, | |||
| /* lg(512/511) = */ 0x0000000c, | |||
| /* lg(1024/1023) = */ 0x00000006, | |||
| /* lg(2048/2047) = */ 0x00000003, | |||
| /* lg(4096/4095) = */ 0x00000001, | |||
| /* lg(8192/8191) = */ 0x00000001, | |||
| /* lg(16384/16383) = */ 0x00000000, | |||
| /* lg(32768/32767) = */ 0x00000000 | |||
| }, | |||
| { | |||
| /* | |||
| * 16 fraction bits | |||
| */ | |||
| /* undefined */ 0x00000000, | |||
| /* lg(2/1) = */ 0x00010000, | |||
| /* lg(4/3) = */ 0x00006a40, | |||
| /* lg(8/7) = */ 0x00003151, | |||
| /* lg(16/15) = */ 0x000017d6, | |||
| /* lg(32/31) = */ 0x00000bba, | |||
| /* lg(64/63) = */ 0x000005d1, | |||
| /* lg(128/127) = */ 0x000002e6, | |||
| /* lg(256/255) = */ 0x00000172, | |||
| /* lg(512/511) = */ 0x000000b9, | |||
| /* lg(1024/1023) = */ 0x0000005c, | |||
| /* lg(2048/2047) = */ 0x0000002e, | |||
| /* lg(4096/4095) = */ 0x00000017, | |||
| /* lg(8192/8191) = */ 0x0000000c, | |||
| /* lg(16384/16383) = */ 0x00000006, | |||
| /* lg(32768/32767) = */ 0x00000003 | |||
| }, | |||
| { | |||
| /* | |||
| * 20 fraction bits | |||
| */ | |||
| /* undefined */ 0x00000000, | |||
| /* lg(2/1) = */ 0x00100000, | |||
| /* lg(4/3) = */ 0x0006a3fe, | |||
| /* lg(8/7) = */ 0x00031513, | |||
| /* lg(16/15) = */ 0x00017d60, | |||
| /* lg(32/31) = */ 0x0000bb9d, | |||
| /* lg(64/63) = */ 0x00005d10, | |||
| /* lg(128/127) = */ 0x00002e59, | |||
| /* lg(256/255) = */ 0x00001721, | |||
| /* lg(512/511) = */ 0x00000b8e, | |||
| /* lg(1024/1023) = */ 0x000005c6, | |||
| /* lg(2048/2047) = */ 0x000002e3, | |||
| /* lg(4096/4095) = */ 0x00000171, | |||
| /* lg(8192/8191) = */ 0x000000b9, | |||
| /* lg(16384/16383) = */ 0x0000005c, | |||
| /* lg(32768/32767) = */ 0x0000002e | |||
| }, | |||
| { | |||
| /* | |||
| * 24 fraction bits | |||
| */ | |||
| /* undefined */ 0x00000000, | |||
| /* lg(2/1) = */ 0x01000000, | |||
| /* lg(4/3) = */ 0x006a3fe6, | |||
| /* lg(8/7) = */ 0x00315130, | |||
| /* lg(16/15) = */ 0x0017d605, | |||
| /* lg(32/31) = */ 0x000bb9ca, | |||
| /* lg(64/63) = */ 0x0005d0fc, | |||
| /* lg(128/127) = */ 0x0002e58f, | |||
| /* lg(256/255) = */ 0x0001720e, | |||
| /* lg(512/511) = */ 0x0000b8d8, | |||
| /* lg(1024/1023) = */ 0x00005c61, | |||
| /* lg(2048/2047) = */ 0x00002e2d, | |||
| /* lg(4096/4095) = */ 0x00001716, | |||
| /* lg(8192/8191) = */ 0x00000b8b, | |||
| /* lg(16384/16383) = */ 0x000005c5, | |||
| /* lg(32768/32767) = */ 0x000002e3 | |||
| }, | |||
| { | |||
| /* | |||
| * 28 fraction bits | |||
| */ | |||
| /* undefined */ 0x00000000, | |||
| /* lg(2/1) = */ 0x10000000, | |||
| /* lg(4/3) = */ 0x06a3fe5c, | |||
| /* lg(8/7) = */ 0x03151301, | |||
| /* lg(16/15) = */ 0x017d6049, | |||
| /* lg(32/31) = */ 0x00bb9ca6, | |||
| /* lg(64/63) = */ 0x005d0fba, | |||
| /* lg(128/127) = */ 0x002e58f7, | |||
| /* lg(256/255) = */ 0x001720da, | |||
| /* lg(512/511) = */ 0x000b8d87, | |||
| /* lg(1024/1023) = */ 0x0005c60b, | |||
| /* lg(2048/2047) = */ 0x0002e2d7, | |||
| /* lg(4096/4095) = */ 0x00017160, | |||
| /* lg(8192/8191) = */ 0x0000b8ad, | |||
| /* lg(16384/16383) = */ 0x00005c56, | |||
| /* lg(32768/32767) = */ 0x00002e2b | |||
| } | |||
| }; | |||
| #if 0 | |||
| static const FLAC__uint64 log2_lookup_wide[] = { | |||
| { | |||
| /* | |||
| * 32 fraction bits | |||
| */ | |||
| /* undefined */ 0x00000000, | |||
| /* lg(2/1) = */ FLAC__U64L(0x100000000), | |||
| /* lg(4/3) = */ FLAC__U64L(0x6a3fe5c6), | |||
| /* lg(8/7) = */ FLAC__U64L(0x31513015), | |||
| /* lg(16/15) = */ FLAC__U64L(0x17d60497), | |||
| /* lg(32/31) = */ FLAC__U64L(0x0bb9ca65), | |||
| /* lg(64/63) = */ FLAC__U64L(0x05d0fba2), | |||
| /* lg(128/127) = */ FLAC__U64L(0x02e58f74), | |||
| /* lg(256/255) = */ FLAC__U64L(0x01720d9c), | |||
| /* lg(512/511) = */ FLAC__U64L(0x00b8d875), | |||
| /* lg(1024/1023) = */ FLAC__U64L(0x005c60aa), | |||
| /* lg(2048/2047) = */ FLAC__U64L(0x002e2d72), | |||
| /* lg(4096/4095) = */ FLAC__U64L(0x00171600), | |||
| /* lg(8192/8191) = */ FLAC__U64L(0x000b8ad2), | |||
| /* lg(16384/16383) = */ FLAC__U64L(0x0005c55d), | |||
| /* lg(32768/32767) = */ FLAC__U64L(0x0002e2ac) | |||
| }, | |||
| { | |||
| /* | |||
| * 48 fraction bits | |||
| */ | |||
| /* undefined */ 0x00000000, | |||
| /* lg(2/1) = */ FLAC__U64L(0x1000000000000), | |||
| /* lg(4/3) = */ FLAC__U64L(0x6a3fe5c60429), | |||
| /* lg(8/7) = */ FLAC__U64L(0x315130157f7a), | |||
| /* lg(16/15) = */ FLAC__U64L(0x17d60496cfbb), | |||
| /* lg(32/31) = */ FLAC__U64L(0xbb9ca64ecac), | |||
| /* lg(64/63) = */ FLAC__U64L(0x5d0fba187cd), | |||
| /* lg(128/127) = */ FLAC__U64L(0x2e58f7441ee), | |||
| /* lg(256/255) = */ FLAC__U64L(0x1720d9c06a8), | |||
| /* lg(512/511) = */ FLAC__U64L(0xb8d8752173), | |||
| /* lg(1024/1023) = */ FLAC__U64L(0x5c60aa252e), | |||
| /* lg(2048/2047) = */ FLAC__U64L(0x2e2d71b0d8), | |||
| /* lg(4096/4095) = */ FLAC__U64L(0x1716001719), | |||
| /* lg(8192/8191) = */ FLAC__U64L(0xb8ad1de1b), | |||
| /* lg(16384/16383) = */ FLAC__U64L(0x5c55d640d), | |||
| /* lg(32768/32767) = */ FLAC__U64L(0x2e2abcf52) | |||
| } | |||
| }; | |||
| #endif | |||
| FLAC__uint32 FLAC__fixedpoint_log2(FLAC__uint32 x, uint32_t fracbits, uint32_t precision) | |||
| { | |||
| const FLAC__uint32 ONE = (1u << fracbits); | |||
| const FLAC__uint32 *table = log2_lookup[fracbits >> 2]; | |||
| FLAC__ASSERT(fracbits < 32); | |||
| FLAC__ASSERT((fracbits & 0x3) == 0); | |||
| if(x < ONE) | |||
| return 0; | |||
| if(precision > LOG2_LOOKUP_PRECISION) | |||
| precision = LOG2_LOOKUP_PRECISION; | |||
| /* Knuth's algorithm for computing logarithms, optimized for base-2 with lookup tables */ | |||
| { | |||
| FLAC__uint32 y = 0; | |||
| FLAC__uint32 z = x >> 1, k = 1; | |||
| while (x > ONE && k < precision) { | |||
| if (x - z >= ONE) { | |||
| x -= z; | |||
| z = x >> k; | |||
| y += table[k]; | |||
| } | |||
| else { | |||
| z >>= 1; | |||
| k++; | |||
| } | |||
| } | |||
| return y; | |||
| } | |||
| } | |||
| #endif /* defined FLAC__INTEGER_ONLY_LIBRARY */ | |||
| @@ -0,0 +1,589 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include <stdio.h> | |||
| #include <stdlib.h> /* for qsort() */ | |||
| #include <string.h> /* for memset() */ | |||
| #include "../assert.h" | |||
| #include "../format.h" | |||
| #include "../alloc.h" | |||
| #include "../compat.h" | |||
| #include "include/private/format.h" | |||
| #include "include/private/macros.h" | |||
| /* PACKAGE_VERSION should come from configure */ | |||
| FLAC_API const char *FLAC__VERSION_STRING = PACKAGE_VERSION; | |||
| FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " PACKAGE_VERSION " 20220220"; | |||
| FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' }; | |||
| FLAC_API const uint32_t FLAC__STREAM_SYNC = 0x664C6143; | |||
| FLAC_API const uint32_t FLAC__STREAM_SYNC_LEN = 32; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN = 16; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN = 16; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN = 24; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN = 24; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN = 20; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN = 3; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN = 5; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN = 36; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN = 128; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_APPLICATION_ID_LEN = 32; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN = 64; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN = 64; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN = 16; /* bits */ | |||
| FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER = FLAC__U64L(0xffffffffffffffff); | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN = 32; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN = 32; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN = 64; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN = 8; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN = 3*8; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN = 64; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN = 8; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN = 12*8; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN = 1; /* bit */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN = 1; /* bit */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN = 6+13*8; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN = 8; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN = 128*8; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN = 64; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN = 1; /* bit */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN = 7+258*8; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN = 8; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_TYPE_LEN = 32; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN = 32; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN = 32; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN = 32; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN = 32; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN = 32; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_COLORS_LEN = 32; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN = 32; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_IS_LAST_LEN = 1; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_TYPE_LEN = 7; /* bits */ | |||
| FLAC_API const uint32_t FLAC__STREAM_METADATA_LENGTH_LEN = 24; /* bits */ | |||
| FLAC_API const uint32_t FLAC__FRAME_HEADER_SYNC = 0x3ffe; | |||
| FLAC_API const uint32_t FLAC__FRAME_HEADER_SYNC_LEN = 14; /* bits */ | |||
| FLAC_API const uint32_t FLAC__FRAME_HEADER_RESERVED_LEN = 1; /* bits */ | |||
| FLAC_API const uint32_t FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN = 1; /* bits */ | |||
| FLAC_API const uint32_t FLAC__FRAME_HEADER_BLOCK_SIZE_LEN = 4; /* bits */ | |||
| FLAC_API const uint32_t FLAC__FRAME_HEADER_SAMPLE_RATE_LEN = 4; /* bits */ | |||
| FLAC_API const uint32_t FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN = 4; /* bits */ | |||
| FLAC_API const uint32_t FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN = 3; /* bits */ | |||
| FLAC_API const uint32_t FLAC__FRAME_HEADER_ZERO_PAD_LEN = 1; /* bits */ | |||
| FLAC_API const uint32_t FLAC__FRAME_HEADER_CRC_LEN = 8; /* bits */ | |||
| FLAC_API const uint32_t FLAC__FRAME_FOOTER_CRC_LEN = 16; /* bits */ | |||
| FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_TYPE_LEN = 2; /* bits */ | |||
| FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN = 4; /* bits */ | |||
| FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN = 4; /* bits */ | |||
| FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN = 5; /* bits */ | |||
| FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN = 5; /* bits */ | |||
| FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER = 15; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */ | |||
| FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER = 31; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN)-1 */ | |||
| FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[] = { | |||
| "PARTITIONED_RICE", | |||
| "PARTITIONED_RICE2" | |||
| }; | |||
| FLAC_API const uint32_t FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN = 4; /* bits */ | |||
| FLAC_API const uint32_t FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN = 5; /* bits */ | |||
| FLAC_API const uint32_t FLAC__SUBFRAME_ZERO_PAD_LEN = 1; /* bits */ | |||
| FLAC_API const uint32_t FLAC__SUBFRAME_TYPE_LEN = 6; /* bits */ | |||
| FLAC_API const uint32_t FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN = 1; /* bits */ | |||
| FLAC_API const uint32_t FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK = 0x00; | |||
| FLAC_API const uint32_t FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK = 0x02; | |||
| FLAC_API const uint32_t FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK = 0x10; | |||
| FLAC_API const uint32_t FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK = 0x40; | |||
| FLAC_API const char * const FLAC__SubframeTypeString[] = { | |||
| "CONSTANT", | |||
| "VERBATIM", | |||
| "FIXED", | |||
| "LPC" | |||
| }; | |||
| FLAC_API const char * const FLAC__ChannelAssignmentString[] = { | |||
| "INDEPENDENT", | |||
| "LEFT_SIDE", | |||
| "RIGHT_SIDE", | |||
| "MID_SIDE" | |||
| }; | |||
| FLAC_API const char * const FLAC__FrameNumberTypeString[] = { | |||
| "FRAME_NUMBER_TYPE_FRAME_NUMBER", | |||
| "FRAME_NUMBER_TYPE_SAMPLE_NUMBER" | |||
| }; | |||
| FLAC_API const char * const FLAC__MetadataTypeString[] = { | |||
| "STREAMINFO", | |||
| "PADDING", | |||
| "APPLICATION", | |||
| "SEEKTABLE", | |||
| "VORBIS_COMMENT", | |||
| "CUESHEET", | |||
| "PICTURE" | |||
| }; | |||
| FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[] = { | |||
| "Other", | |||
| "32x32 pixels 'file icon' (PNG only)", | |||
| "Other file icon", | |||
| "Cover (front)", | |||
| "Cover (back)", | |||
| "Leaflet page", | |||
| "Media (e.g. label side of CD)", | |||
| "Lead artist/lead performer/soloist", | |||
| "Artist/performer", | |||
| "Conductor", | |||
| "Band/Orchestra", | |||
| "Composer", | |||
| "Lyricist/text writer", | |||
| "Recording Location", | |||
| "During recording", | |||
| "During performance", | |||
| "Movie/video screen capture", | |||
| "A bright coloured fish", | |||
| "Illustration", | |||
| "Band/artist logotype", | |||
| "Publisher/Studio logotype" | |||
| }; | |||
| FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(uint32_t sample_rate) | |||
| { | |||
| if(sample_rate == 0 || sample_rate > FLAC__MAX_SAMPLE_RATE) { | |||
| return false; | |||
| } | |||
| else | |||
| return true; | |||
| } | |||
| FLAC_API FLAC__bool FLAC__format_blocksize_is_subset(uint32_t blocksize, uint32_t 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(uint32_t sample_rate) | |||
| { | |||
| if( | |||
| !FLAC__format_sample_rate_is_valid(sample_rate) || | |||
| ( | |||
| sample_rate >= (1u << 16) && | |||
| !(sample_rate % 1000 == 0 || sample_rate % 10 == 0) | |||
| ) | |||
| ) { | |||
| return false; | |||
| } | |||
| else | |||
| return true; | |||
| } | |||
| /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ | |||
| FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table) | |||
| { | |||
| uint32_t i; | |||
| FLAC__uint64 prev_sample_number = 0; | |||
| FLAC__bool got_prev = false; | |||
| FLAC__ASSERT(0 != seek_table); | |||
| for(i = 0; i < seek_table->num_points; i++) { | |||
| if(got_prev) { | |||
| if( | |||
| seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && | |||
| seek_table->points[i].sample_number <= prev_sample_number | |||
| ) | |||
| return false; | |||
| } | |||
| prev_sample_number = seek_table->points[i].sample_number; | |||
| got_prev = true; | |||
| } | |||
| return true; | |||
| } | |||
| /* used as the sort predicate for qsort() */ | |||
| 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' */ | |||
| if(l->sample_number == r->sample_number) | |||
| return 0; | |||
| else if(l->sample_number < r->sample_number) | |||
| return -1; | |||
| else | |||
| return 1; | |||
| } | |||
| /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ | |||
| FLAC_API uint32_t FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table) | |||
| { | |||
| uint32_t i, j; | |||
| FLAC__bool first; | |||
| FLAC__ASSERT(0 != seek_table); | |||
| if (seek_table->num_points == 0) | |||
| return 0; | |||
| /* sort the seekpoints */ | |||
| qsort(seek_table->points, seek_table->num_points, sizeof(FLAC__StreamMetadata_SeekPoint), (int (*)(const void *, const void *))seekpoint_compare_); | |||
| /* uniquify the seekpoints */ | |||
| first = true; | |||
| for(i = j = 0; i < seek_table->num_points; i++) { | |||
| if(seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER) { | |||
| if(!first) { | |||
| if(seek_table->points[i].sample_number == seek_table->points[j-1].sample_number) | |||
| continue; | |||
| } | |||
| } | |||
| first = false; | |||
| seek_table->points[j++] = seek_table->points[i]; | |||
| } | |||
| for(i = j; i < seek_table->num_points; i++) { | |||
| seek_table->points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; | |||
| seek_table->points[i].stream_offset = 0; | |||
| seek_table->points[i].frame_samples = 0; | |||
| } | |||
| return j; | |||
| } | |||
| /* | |||
| * also disallows non-shortest-form encodings, c.f. | |||
| * http://www.unicode.org/versions/corrigendum1.html | |||
| * and a more clear explanation at the end of this section: | |||
| * http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 | |||
| */ | |||
| static uint32_t utf8len_(const FLAC__byte *utf8) | |||
| { | |||
| FLAC__ASSERT(0 != utf8); | |||
| if ((utf8[0] & 0x80) == 0) { | |||
| return 1; | |||
| } | |||
| else if ((utf8[0] & 0xE0) == 0xC0 && (utf8[1] & 0xC0) == 0x80) { | |||
| if ((utf8[0] & 0xFE) == 0xC0) /* overlong sequence check */ | |||
| return 0; | |||
| return 2; | |||
| } | |||
| else if ((utf8[0] & 0xF0) == 0xE0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80) { | |||
| if (utf8[0] == 0xE0 && (utf8[1] & 0xE0) == 0x80) /* overlong sequence check */ | |||
| return 0; | |||
| /* illegal surrogates check (U+D800...U+DFFF and U+FFFE...U+FFFF) */ | |||
| if (utf8[0] == 0xED && (utf8[1] & 0xE0) == 0xA0) /* D800-DFFF */ | |||
| return 0; | |||
| if (utf8[0] == 0xEF && utf8[1] == 0xBF && (utf8[2] & 0xFE) == 0xBE) /* FFFE-FFFF */ | |||
| return 0; | |||
| return 3; | |||
| } | |||
| else if ((utf8[0] & 0xF8) == 0xF0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80) { | |||
| if (utf8[0] == 0xF0 && (utf8[1] & 0xF0) == 0x80) /* overlong sequence check */ | |||
| return 0; | |||
| return 4; | |||
| } | |||
| else if ((utf8[0] & 0xFC) == 0xF8 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80) { | |||
| if (utf8[0] == 0xF8 && (utf8[1] & 0xF8) == 0x80) /* overlong sequence check */ | |||
| return 0; | |||
| return 5; | |||
| } | |||
| else if ((utf8[0] & 0xFE) == 0xFC && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80 && (utf8[5] & 0xC0) == 0x80) { | |||
| if (utf8[0] == 0xFC && (utf8[1] & 0xFC) == 0x80) /* overlong sequence check */ | |||
| return 0; | |||
| return 6; | |||
| } | |||
| else { | |||
| return 0; | |||
| } | |||
| } | |||
| FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name) | |||
| { | |||
| char c; | |||
| for(c = *name; c; c = *(++name)) | |||
| if(c < 0x20 || c == 0x3d || c > 0x7d) | |||
| return false; | |||
| return true; | |||
| } | |||
| FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, uint32_t length) | |||
| { | |||
| if(length == (uint32_t)(-1)) { | |||
| while(*value) { | |||
| uint32_t n = utf8len_(value); | |||
| if(n == 0) | |||
| return false; | |||
| value += n; | |||
| } | |||
| } | |||
| else { | |||
| const FLAC__byte *end = value + length; | |||
| while(value < end) { | |||
| uint32_t n = utf8len_(value); | |||
| if(n == 0) | |||
| return false; | |||
| value += n; | |||
| } | |||
| if(value != end) | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, uint32_t length) | |||
| { | |||
| const FLAC__byte *s, *end; | |||
| for(s = entry, end = s + length; s < end && *s != '='; s++) { | |||
| if(*s < 0x20 || *s > 0x7D) | |||
| return false; | |||
| } | |||
| if(s == end) | |||
| return false; | |||
| s++; /* skip '=' */ | |||
| while(s < end) { | |||
| uint32_t n = utf8len_(s); | |||
| if(n == 0) | |||
| return false; | |||
| s += n; | |||
| } | |||
| if(s != end) | |||
| return false; | |||
| return true; | |||
| } | |||
| /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ | |||
| FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation) | |||
| { | |||
| uint32_t i, j; | |||
| if(check_cd_da_subset) { | |||
| if(cue_sheet->lead_in < 2 * 44100) { | |||
| if(violation) *violation = "CD-DA cue sheet must have a lead-in length of at least 2 seconds"; | |||
| return false; | |||
| } | |||
| if(cue_sheet->lead_in % 588 != 0) { | |||
| if(violation) *violation = "CD-DA cue sheet lead-in length must be evenly divisible by 588 samples"; | |||
| return false; | |||
| } | |||
| } | |||
| if(cue_sheet->num_tracks == 0) { | |||
| if(violation) *violation = "cue sheet must have at least one track (the lead-out)"; | |||
| return false; | |||
| } | |||
| if(check_cd_da_subset && cue_sheet->tracks[cue_sheet->num_tracks-1].number != 170) { | |||
| if(violation) *violation = "CD-DA cue sheet must have a lead-out track number 170 (0xAA)"; | |||
| return false; | |||
| } | |||
| for(i = 0; i < cue_sheet->num_tracks; i++) { | |||
| if(cue_sheet->tracks[i].number == 0) { | |||
| if(violation) *violation = "cue sheet may not have a track number 0"; | |||
| return false; | |||
| } | |||
| if(check_cd_da_subset) { | |||
| if(!((cue_sheet->tracks[i].number >= 1 && cue_sheet->tracks[i].number <= 99) || cue_sheet->tracks[i].number == 170)) { | |||
| if(violation) *violation = "CD-DA cue sheet track number must be 1-99 or 170"; | |||
| return false; | |||
| } | |||
| } | |||
| if(check_cd_da_subset && cue_sheet->tracks[i].offset % 588 != 0) { | |||
| if(violation) { | |||
| if(i == cue_sheet->num_tracks-1) /* the lead-out track... */ | |||
| *violation = "CD-DA cue sheet lead-out offset must be evenly divisible by 588 samples"; | |||
| else | |||
| *violation = "CD-DA cue sheet track offset must be evenly divisible by 588 samples"; | |||
| } | |||
| return false; | |||
| } | |||
| if(i < cue_sheet->num_tracks - 1) { | |||
| if(cue_sheet->tracks[i].num_indices == 0) { | |||
| if(violation) *violation = "cue sheet track must have at least one index point"; | |||
| return false; | |||
| } | |||
| if(cue_sheet->tracks[i].indices[0].number > 1) { | |||
| if(violation) *violation = "cue sheet track's first index number must be 0 or 1"; | |||
| return false; | |||
| } | |||
| } | |||
| for(j = 0; j < cue_sheet->tracks[i].num_indices; j++) { | |||
| if(check_cd_da_subset && cue_sheet->tracks[i].indices[j].offset % 588 != 0) { | |||
| if(violation) *violation = "CD-DA cue sheet track index offset must be evenly divisible by 588 samples"; | |||
| return false; | |||
| } | |||
| if(j > 0) { | |||
| if(cue_sheet->tracks[i].indices[j].number != cue_sheet->tracks[i].indices[j-1].number + 1) { | |||
| if(violation) *violation = "cue sheet track index numbers must increase by 1"; | |||
| return false; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| return true; | |||
| } | |||
| /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ | |||
| FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation) | |||
| { | |||
| char *p; | |||
| FLAC__byte *b; | |||
| for(p = picture->mime_type; *p; p++) { | |||
| if(*p < 0x20 || *p > 0x7e) { | |||
| if(violation) *violation = "MIME type string must contain only printable ASCII characters (0x20-0x7e)"; | |||
| return false; | |||
| } | |||
| } | |||
| for(b = picture->description; *b; ) { | |||
| uint32_t n = utf8len_(b); | |||
| if(n == 0) { | |||
| if(violation) *violation = "description string must be valid UTF-8"; | |||
| return false; | |||
| } | |||
| b += n; | |||
| } | |||
| return true; | |||
| } | |||
| /* | |||
| * These routines are private to libFLAC | |||
| */ | |||
| uint32_t FLAC__format_get_max_rice_partition_order(uint32_t blocksize, uint32_t predictor_order) | |||
| { | |||
| return | |||
| FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order( | |||
| FLAC__format_get_max_rice_partition_order_from_blocksize(blocksize), | |||
| blocksize, | |||
| predictor_order | |||
| ); | |||
| } | |||
| uint32_t FLAC__format_get_max_rice_partition_order_from_blocksize(uint32_t blocksize) | |||
| { | |||
| uint32_t max_rice_partition_order = 0; | |||
| while(!(blocksize & 1)) { | |||
| max_rice_partition_order++; | |||
| blocksize >>= 1; | |||
| } | |||
| return flac_min(FLAC__MAX_RICE_PARTITION_ORDER, max_rice_partition_order); | |||
| } | |||
| uint32_t FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(uint32_t limit, uint32_t blocksize, uint32_t predictor_order) | |||
| { | |||
| uint32_t max_rice_partition_order = limit; | |||
| while(max_rice_partition_order > 0 && (blocksize >> max_rice_partition_order) <= predictor_order) | |||
| max_rice_partition_order--; | |||
| FLAC__ASSERT( | |||
| (max_rice_partition_order == 0 && blocksize >= predictor_order) || | |||
| (max_rice_partition_order > 0 && blocksize >> max_rice_partition_order > predictor_order) | |||
| ); | |||
| return max_rice_partition_order; | |||
| } | |||
| void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object) | |||
| { | |||
| FLAC__ASSERT(0 != object); | |||
| object->parameters = 0; | |||
| object->raw_bits = 0; | |||
| object->capacity_by_order = 0; | |||
| } | |||
| void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object) | |||
| { | |||
| FLAC__ASSERT(0 != object); | |||
| if(0 != object->parameters) | |||
| free(object->parameters); | |||
| if(0 != object->raw_bits) | |||
| free(object->raw_bits); | |||
| FLAC__format_entropy_coding_method_partitioned_rice_contents_init(object); | |||
| } | |||
| FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, uint32_t max_partition_order) | |||
| { | |||
| FLAC__ASSERT(0 != object); | |||
| FLAC__ASSERT(object->capacity_by_order > 0 || (0 == object->parameters && 0 == object->raw_bits)); | |||
| if(object->capacity_by_order < max_partition_order) { | |||
| if(0 == (object->parameters = safe_realloc_(object->parameters, sizeof(uint32_t)*(1 << max_partition_order)))) | |||
| return false; | |||
| if(0 == (object->raw_bits = safe_realloc_(object->raw_bits, sizeof(uint32_t)*(1 << max_partition_order)))) | |||
| return false; | |||
| memset(object->raw_bits, 0, sizeof(uint32_t)*(1 << max_partition_order)); | |||
| object->capacity_by_order = max_partition_order; | |||
| } | |||
| return true; | |||
| } | |||
| @@ -0,0 +1,50 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__ALL_H | |||
| #define FLAC__PRIVATE__ALL_H | |||
| #include "bitmath.h" | |||
| #include "bitreader.h" | |||
| #include "bitwriter.h" | |||
| #include "cpu.h" | |||
| #include "crc.h" | |||
| #include "fixed.h" | |||
| #include "float.h" | |||
| #include "format.h" | |||
| #include "lpc.h" | |||
| #include "md5.h" | |||
| #include "memory.h" | |||
| #include "metadata.h" | |||
| #include "stream_encoder_framing.h" | |||
| #endif | |||
| @@ -0,0 +1,210 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2001-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__BITMATH_H | |||
| #define FLAC__PRIVATE__BITMATH_H | |||
| #include "../../../ordinals.h" | |||
| #include "../../../assert.h" | |||
| #include "../../../compat.h" | |||
| #if defined(_MSC_VER) | |||
| #include <intrin.h> /* for _BitScanReverse* */ | |||
| #endif | |||
| /* Will never be emitted for MSVC, GCC, Intel compilers */ | |||
| static inline uint32_t FLAC__clz_soft_uint32(FLAC__uint32 word) | |||
| { | |||
| static const uint8_t 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 uint32_t FLAC__clz_uint32(FLAC__uint32 v) | |||
| { | |||
| /* Never used with input 0 */ | |||
| FLAC__ASSERT(v > 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 routine in exotic machines. */ | |||
| return __builtin_clz(v); | |||
| #elif defined(_MSC_VER) | |||
| { | |||
| uint32_t idx; | |||
| _BitScanReverse(&idx, v); | |||
| return idx ^ 31U; | |||
| } | |||
| #else | |||
| return FLAC__clz_soft_uint32(v); | |||
| #endif | |||
| } | |||
| /* Used when 64-bit bsr/clz is unavailable; can use 32-bit bsr/clz when possible */ | |||
| static inline uint32_t FLAC__clz_soft_uint64(FLAC__uint64 word) | |||
| { | |||
| return (FLAC__uint32)(word>>32) ? FLAC__clz_uint32((FLAC__uint32)(word>>32)) : | |||
| FLAC__clz_uint32((FLAC__uint32)word) + 32; | |||
| } | |||
| static inline uint32_t FLAC__clz_uint64(FLAC__uint64 v) | |||
| { | |||
| /* Never used with input 0 */ | |||
| FLAC__ASSERT(v > 0); | |||
| #if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) | |||
| return __builtin_clzll(v); | |||
| #elif (defined(__INTEL_COMPILER) || defined(_MSC_VER)) && (defined(_M_IA64) || defined(_M_X64)) | |||
| { | |||
| uint32_t idx; | |||
| _BitScanReverse64(&idx, v); | |||
| return idx ^ 63U; | |||
| } | |||
| #else | |||
| return FLAC__clz_soft_uint64(v); | |||
| #endif | |||
| } | |||
| /* These two functions work with input 0 */ | |||
| static inline uint32_t FLAC__clz2_uint32(FLAC__uint32 v) | |||
| { | |||
| if (!v) | |||
| return 32; | |||
| return FLAC__clz_uint32(v); | |||
| } | |||
| static inline uint32_t FLAC__clz2_uint64(FLAC__uint64 v) | |||
| { | |||
| if (!v) | |||
| return 64; | |||
| return FLAC__clz_uint64(v); | |||
| } | |||
| /* 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 | |||
| */ | |||
| static inline uint32_t FLAC__bitmath_ilog2(FLAC__uint32 v) | |||
| { | |||
| FLAC__ASSERT(v > 0); | |||
| #if defined(__INTEL_COMPILER) | |||
| return _bit_scan_reverse(v); | |||
| #elif defined(_MSC_VER) | |||
| { | |||
| uint32_t idx; | |||
| _BitScanReverse(&idx, v); | |||
| return idx; | |||
| } | |||
| #else | |||
| return FLAC__clz_uint32(v) ^ 31U; | |||
| #endif | |||
| } | |||
| static inline uint32_t FLAC__bitmath_ilog2_wide(FLAC__uint64 v) | |||
| { | |||
| FLAC__ASSERT(v > 0); | |||
| #if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) | |||
| return __builtin_clzll(v) ^ 63U; | |||
| /* Sorry, only supported in x64/Itanium.. and both have fast FPU which makes integer-only encoder pointless */ | |||
| #elif (defined(__INTEL_COMPILER) || defined(_MSC_VER)) && (defined(_M_IA64) || defined(_M_X64)) | |||
| { | |||
| uint32_t idx; | |||
| _BitScanReverse64(&idx, v); | |||
| return idx; | |||
| } | |||
| #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 CC0 (Public domain). | |||
| */ | |||
| { | |||
| static const uint8_t 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 | |||
| }; | |||
| v|= v>>1; | |||
| v|= v>>2; | |||
| v|= v>>4; | |||
| v|= v>>8; | |||
| v|= v>>16; | |||
| v|= v>>32; | |||
| v= (v>>1)+1; | |||
| return DEBRUIJN_IDX64[v*FLAC__U64L(0x218A392CD3D5DBF)>>58&0x3F]; | |||
| } | |||
| #endif | |||
| } | |||
| uint32_t FLAC__bitmath_silog2(FLAC__int64 v); | |||
| #endif | |||
| @@ -0,0 +1,91 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__BITREADER_H | |||
| #define FLAC__PRIVATE__BITREADER_H | |||
| #include <stdio.h> /* for FILE */ | |||
| #include "../../../ordinals.h" | |||
| #include "cpu.h" | |||
| /* | |||
| * opaque structure definition | |||
| */ | |||
| struct FLAC__BitReader; | |||
| typedef struct FLAC__BitReader FLAC__BitReader; | |||
| typedef FLAC__bool (*FLAC__BitReaderReadCallback)(FLAC__byte buffer[], size_t *bytes, void *client_data); | |||
| /* | |||
| * construction, deletion, initialization, etc functions | |||
| */ | |||
| FLAC__BitReader *FLAC__bitreader_new(void); | |||
| void FLAC__bitreader_delete(FLAC__BitReader *br); | |||
| FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__BitReaderReadCallback rcb, void *cd); | |||
| void FLAC__bitreader_free(FLAC__BitReader *br); /* does not 'free(br)' */ | |||
| FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br); | |||
| void FLAC__bitreader_dump(const FLAC__BitReader *br, FILE *out); | |||
| /* | |||
| * CRC functions | |||
| */ | |||
| void FLAC__bitreader_reset_read_crc16(FLAC__BitReader *br, FLAC__uint16 seed); | |||
| FLAC__uint16 FLAC__bitreader_get_read_crc16(FLAC__BitReader *br); | |||
| /* | |||
| * info functions | |||
| */ | |||
| FLAC__bool FLAC__bitreader_is_consumed_byte_aligned(const FLAC__BitReader *br); | |||
| uint32_t FLAC__bitreader_bits_left_for_byte_alignment(const FLAC__BitReader *br); | |||
| uint32_t FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader *br); | |||
| /* | |||
| * read functions | |||
| */ | |||
| FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *val, uint32_t bits); | |||
| FLAC__bool FLAC__bitreader_read_raw_int32(FLAC__BitReader *br, FLAC__int32 *val, uint32_t bits); | |||
| FLAC__bool FLAC__bitreader_read_raw_uint64(FLAC__BitReader *br, FLAC__uint64 *val, uint32_t bits); | |||
| FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val); /*only for bits=32*/ | |||
| FLAC__bool FLAC__bitreader_skip_bits_no_crc(FLAC__BitReader *br, uint32_t bits); /* WATCHOUT: does not CRC the skipped data! */ /*@@@@ add to unit tests */ | |||
| FLAC__bool FLAC__bitreader_skip_byte_block_aligned_no_crc(FLAC__BitReader *br, uint32_t nvals); /* WATCHOUT: does not CRC the read data! */ | |||
| FLAC__bool FLAC__bitreader_read_byte_block_aligned_no_crc(FLAC__BitReader *br, FLAC__byte *val, uint32_t nvals); /* WATCHOUT: does not CRC the read data! */ | |||
| FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, uint32_t *val); | |||
| FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, uint32_t parameter); | |||
| FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], uint32_t nvals, uint32_t parameter); | |||
| #if 0 /* UNUSED */ | |||
| FLAC__bool FLAC__bitreader_read_golomb_signed(FLAC__BitReader *br, int *val, uint32_t parameter); | |||
| FLAC__bool FLAC__bitreader_read_golomb_unsigned(FLAC__BitReader *br, uint32_t *val, uint32_t parameter); | |||
| #endif | |||
| FLAC__bool FLAC__bitreader_read_utf8_uint32(FLAC__BitReader *br, FLAC__uint32 *val, FLAC__byte *raw, uint32_t *rawlen); | |||
| FLAC__bool FLAC__bitreader_read_utf8_uint64(FLAC__BitReader *br, FLAC__uint64 *val, FLAC__byte *raw, uint32_t *rawlen); | |||
| #endif | |||
| @@ -0,0 +1,104 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__BITWRITER_H | |||
| #define FLAC__PRIVATE__BITWRITER_H | |||
| #include <stdio.h> /* for FILE */ | |||
| #include "../../../ordinals.h" | |||
| /* | |||
| * opaque structure definition | |||
| */ | |||
| struct FLAC__BitWriter; | |||
| typedef struct FLAC__BitWriter FLAC__BitWriter; | |||
| /* | |||
| * construction, deletion, initialization, etc functions | |||
| */ | |||
| FLAC__BitWriter *FLAC__bitwriter_new(void); | |||
| void FLAC__bitwriter_delete(FLAC__BitWriter *bw); | |||
| FLAC__bool FLAC__bitwriter_init(FLAC__BitWriter *bw); | |||
| void FLAC__bitwriter_free(FLAC__BitWriter *bw); /* does not 'free(buffer)' */ | |||
| void FLAC__bitwriter_clear(FLAC__BitWriter *bw); | |||
| void FLAC__bitwriter_dump(const FLAC__BitWriter *bw, FILE *out); | |||
| /* | |||
| * CRC functions | |||
| * | |||
| * non-const *bw because they have to cal FLAC__bitwriter_get_buffer() | |||
| */ | |||
| FLAC__bool FLAC__bitwriter_get_write_crc16(FLAC__BitWriter *bw, FLAC__uint16 *crc); | |||
| FLAC__bool FLAC__bitwriter_get_write_crc8(FLAC__BitWriter *bw, FLAC__byte *crc); | |||
| /* | |||
| * info functions | |||
| */ | |||
| FLAC__bool FLAC__bitwriter_is_byte_aligned(const FLAC__BitWriter *bw); | |||
| uint32_t FLAC__bitwriter_get_input_bits_unconsumed(const FLAC__BitWriter *bw); /* can be called anytime, returns total # of bits unconsumed */ | |||
| /* | |||
| * direct buffer access | |||
| * | |||
| * there may be no calls on the bitwriter between get and release. | |||
| * the bitwriter continues to own the returned buffer. | |||
| * before get, bitwriter MUST be byte aligned: check with FLAC__bitwriter_is_byte_aligned() | |||
| */ | |||
| FLAC__bool FLAC__bitwriter_get_buffer(FLAC__BitWriter *bw, const FLAC__byte **buffer, size_t *bytes); | |||
| void FLAC__bitwriter_release_buffer(FLAC__BitWriter *bw); | |||
| /* | |||
| * write functions | |||
| */ | |||
| FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, uint32_t bits); | |||
| FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FLAC__uint32 val, uint32_t bits); | |||
| FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, uint32_t bits); | |||
| FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, uint32_t bits); | |||
| FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val); /*only for bits=32*/ | |||
| FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], uint32_t nvals); | |||
| FLAC__bool FLAC__bitwriter_write_unary_unsigned(FLAC__BitWriter *bw, uint32_t val); | |||
| uint32_t FLAC__bitwriter_rice_bits(FLAC__int32 val, uint32_t parameter); | |||
| #if 0 /* UNUSED */ | |||
| uint32_t FLAC__bitwriter_golomb_bits_signed(int val, uint32_t parameter); | |||
| uint32_t FLAC__bitwriter_golomb_bits_unsigned(uint32_t val, uint32_t parameter); | |||
| #endif | |||
| FLAC__bool FLAC__bitwriter_write_rice_signed(FLAC__BitWriter *bw, FLAC__int32 val, uint32_t parameter); | |||
| FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FLAC__int32 *vals, uint32_t nvals, uint32_t parameter); | |||
| #if 0 /* UNUSED */ | |||
| FLAC__bool FLAC__bitwriter_write_golomb_signed(FLAC__BitWriter *bw, int val, uint32_t parameter); | |||
| FLAC__bool FLAC__bitwriter_write_golomb_unsigned(FLAC__BitWriter *bw, uint32_t val, uint32_t parameter); | |||
| #endif | |||
| FLAC__bool FLAC__bitwriter_write_utf8_uint32(FLAC__BitWriter *bw, FLAC__uint32 val); | |||
| FLAC__bool FLAC__bitwriter_write_utf8_uint64(FLAC__BitWriter *bw, FLAC__uint64 val); | |||
| FLAC__bool FLAC__bitwriter_zero_pad_to_byte_boundary(FLAC__BitWriter *bw); | |||
| #endif | |||
| @@ -0,0 +1,201 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2001-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__CPU_H | |||
| #define FLAC__PRIVATE__CPU_H | |||
| #include "../../../ordinals.h" | |||
| #ifdef HAVE_CONFIG_H | |||
| #include <config.h> | |||
| #endif | |||
| #ifndef FLAC__CPU_X86_64 | |||
| #if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64) | |||
| #define FLAC__CPU_X86_64 | |||
| #endif | |||
| #endif | |||
| #ifndef FLAC__CPU_IA32 | |||
| #if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) ||defined( __i386) || defined(_M_IX86) | |||
| #define FLAC__CPU_IA32 | |||
| #endif | |||
| #endif | |||
| #ifndef __has_attribute | |||
| #define __has_attribute(x) 0 | |||
| #endif | |||
| #if FLAC__HAS_X86INTRIN | |||
| /* SSE intrinsics support by ICC/MSVC/GCC */ | |||
| #if defined __INTEL_COMPILER | |||
| #define FLAC__SSE_TARGET(x) | |||
| #define FLAC__SSE_SUPPORTED 1 | |||
| #define FLAC__SSE2_SUPPORTED 1 | |||
| #if (__INTEL_COMPILER >= 1000) /* Intel C++ Compiler 10.0 */ | |||
| #define FLAC__SSSE3_SUPPORTED 1 | |||
| #define FLAC__SSE4_1_SUPPORTED 1 | |||
| #endif | |||
| #if (__INTEL_COMPILER >= 1110) /* Intel C++ Compiler 11.1 */ | |||
| #define FLAC__AVX_SUPPORTED 1 | |||
| #endif | |||
| #if (__INTEL_COMPILER >= 1300) /* Intel C++ Compiler 13.0 */ | |||
| #define FLAC__AVX2_SUPPORTED 1 | |||
| #define FLAC__FMA_SUPPORTED 1 | |||
| #endif | |||
| #elif defined __clang__ && __has_attribute(__target__) /* clang */ | |||
| #define FLAC__SSE_TARGET(x) __attribute__ ((__target__ (x))) | |||
| #if __has_builtin(__builtin_ia32_maxps) | |||
| #define FLAC__SSE_SUPPORTED 1 | |||
| #endif | |||
| #if __has_builtin(__builtin_ia32_pmuludq128) | |||
| #define FLAC__SSE2_SUPPORTED 1 | |||
| #endif | |||
| #if __has_builtin(__builtin_ia32_pabsd128) | |||
| #define FLAC__SSSE3_SUPPORTED 1 | |||
| #endif | |||
| #if __has_builtin(__builtin_ia32_pmuldq128) | |||
| #define FLAC__SSE4_1_SUPPORTED 1 | |||
| #endif | |||
| #if __has_builtin(__builtin_ia32_maxps256) | |||
| #define FLAC__AVX_SUPPORTED 1 | |||
| #endif | |||
| #if __has_builtin(__builtin_ia32_pabsd256) | |||
| #define FLAC__AVX2_SUPPORTED 1 | |||
| #endif | |||
| #if __has_builtin(__builtin_ia32_vfmaddps) | |||
| #define FLAC__FMA_SUPPORTED 1 | |||
| #endif | |||
| #elif defined __GNUC__ && !defined __clang__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) /* GCC 4.9+ */ | |||
| #define FLAC__SSE_TARGET(x) __attribute__ ((__target__ (x))) | |||
| #define FLAC__SSE_SUPPORTED 1 | |||
| #define FLAC__SSE2_SUPPORTED 1 | |||
| #define FLAC__SSSE3_SUPPORTED 1 | |||
| #define FLAC__SSE4_1_SUPPORTED 1 | |||
| #ifdef FLAC__USE_AVX | |||
| #define FLAC__AVX_SUPPORTED 1 | |||
| #define FLAC__AVX2_SUPPORTED 1 | |||
| #define FLAC__FMA_SUPPORTED 1 | |||
| #endif | |||
| #elif defined _MSC_VER | |||
| #define FLAC__SSE_TARGET(x) | |||
| #define FLAC__SSE_SUPPORTED 1 | |||
| #define FLAC__SSE2_SUPPORTED 1 | |||
| #if (_MSC_VER >= 1500) /* MS Visual Studio 2008 */ | |||
| #define FLAC__SSSE3_SUPPORTED 1 | |||
| #define FLAC__SSE4_1_SUPPORTED 1 | |||
| #endif | |||
| #if (_MSC_FULL_VER >= 160040219) /* MS Visual Studio 2010 SP1 */ | |||
| #define FLAC__AVX_SUPPORTED 1 | |||
| #endif | |||
| #if (_MSC_VER >= 1700) /* MS Visual Studio 2012 */ | |||
| #define FLAC__AVX2_SUPPORTED 1 | |||
| #define FLAC__FMA_SUPPORTED 1 | |||
| #endif | |||
| #else | |||
| #define FLAC__SSE_TARGET(x) | |||
| #ifdef __SSE__ | |||
| #define FLAC__SSE_SUPPORTED 1 | |||
| #endif | |||
| #ifdef __SSE2__ | |||
| #define FLAC__SSE2_SUPPORTED 1 | |||
| #endif | |||
| #ifdef __SSSE3__ | |||
| #define FLAC__SSSE3_SUPPORTED 1 | |||
| #endif | |||
| #ifdef __SSE4_1__ | |||
| #define FLAC__SSE4_1_SUPPORTED 1 | |||
| #endif | |||
| #ifdef __AVX__ | |||
| #define FLAC__AVX_SUPPORTED 1 | |||
| #endif | |||
| #ifdef __AVX2__ | |||
| #define FLAC__AVX2_SUPPORTED 1 | |||
| #endif | |||
| #ifdef __FMA__ | |||
| #define FLAC__FMA_SUPPORTED 1 | |||
| #endif | |||
| #endif /* compiler version */ | |||
| #endif /* intrinsics support */ | |||
| #ifndef FLAC__AVX_SUPPORTED | |||
| #define FLAC__AVX_SUPPORTED 0 | |||
| #endif | |||
| typedef enum { | |||
| FLAC__CPUINFO_TYPE_IA32, | |||
| FLAC__CPUINFO_TYPE_X86_64, | |||
| FLAC__CPUINFO_TYPE_PPC, | |||
| FLAC__CPUINFO_TYPE_UNKNOWN | |||
| } FLAC__CPUInfo_Type; | |||
| typedef struct { | |||
| FLAC__bool intel; | |||
| FLAC__bool cmov; | |||
| FLAC__bool mmx; | |||
| FLAC__bool sse; | |||
| FLAC__bool sse2; | |||
| FLAC__bool sse3; | |||
| FLAC__bool ssse3; | |||
| FLAC__bool sse41; | |||
| FLAC__bool sse42; | |||
| FLAC__bool avx; | |||
| FLAC__bool avx2; | |||
| FLAC__bool fma; | |||
| } FLAC__CPUInfo_x86; | |||
| typedef struct { | |||
| FLAC__bool arch_3_00; | |||
| FLAC__bool arch_2_07; | |||
| } FLAC__CPUInfo_ppc; | |||
| typedef struct { | |||
| FLAC__bool use_asm; | |||
| FLAC__CPUInfo_Type type; | |||
| FLAC__CPUInfo_x86 x86; | |||
| FLAC__CPUInfo_ppc ppc; | |||
| } FLAC__CPUInfo; | |||
| void FLAC__cpu_info(FLAC__CPUInfo *info); | |||
| FLAC__uint32 FLAC__cpu_have_cpuid_asm_ia32(void); | |||
| void FLAC__cpu_info_asm_ia32(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx); | |||
| #endif | |||
| @@ -0,0 +1,60 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2018 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. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__CRC_H | |||
| #define FLAC__PRIVATE__CRC_H | |||
| #include "../../../ordinals.h" | |||
| /* 8 bit CRC generator, MSB shifted first | |||
| ** polynomial = x^8 + x^2 + x^1 + x^0 | |||
| ** init = 0 | |||
| */ | |||
| FLAC__uint8 FLAC__crc8(const FLAC__byte *data, uint32_t len); | |||
| /* 16 bit CRC generator, MSB shifted first | |||
| ** polynomial = x^16 + x^15 + x^2 + x^0 | |||
| ** init = 0 | |||
| */ | |||
| extern FLAC__uint16 const FLAC__crc16_table[8][256]; | |||
| #define FLAC__CRC16_UPDATE(data, crc) ((((crc)<<8) & 0xffff) ^ FLAC__crc16_table[0][((crc)>>8) ^ (data)]) | |||
| /* this alternate may be faster on some systems/compilers */ | |||
| #if 0 | |||
| #define FLAC__CRC16_UPDATE(data, crc) ((((crc)<<8) ^ FLAC__crc16_table[0][((crc)>>8) ^ (data)]) & 0xffff) | |||
| #endif | |||
| FLAC__uint16 FLAC__crc16(const FLAC__byte *data, uint32_t len); | |||
| FLAC__uint16 FLAC__crc16_update_words32(const FLAC__uint32 *words, uint32_t len, FLAC__uint16 crc); | |||
| FLAC__uint16 FLAC__crc16_update_words64(const FLAC__uint64 *words, uint32_t len, FLAC__uint16 crc); | |||
| #endif | |||
| @@ -0,0 +1,107 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__FIXED_H | |||
| #define FLAC__PRIVATE__FIXED_H | |||
| #ifdef HAVE_CONFIG_H | |||
| #include <config.h> | |||
| #endif | |||
| #include "cpu.h" | |||
| #include "float.h" | |||
| #include "../../../format.h" | |||
| /* | |||
| * FLAC__fixed_compute_best_predictor() | |||
| * -------------------------------------------------------------------- | |||
| * Compute the best fixed predictor and the expected bits-per-sample | |||
| * of the residual signal for each order. The _wide() version uses | |||
| * 64-bit integers which is statistically necessary when bits-per- | |||
| * sample + log2(blocksize) > 30 | |||
| * | |||
| * IN data[0,data_len-1] | |||
| * IN data_len | |||
| * OUT residual_bits_per_sample[0,FLAC__MAX_FIXED_ORDER] | |||
| */ | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); | |||
| uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); | |||
| # ifndef FLAC__NO_ASM | |||
| # if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN | |||
| # ifdef FLAC__SSE2_SUPPORTED | |||
| uint32_t FLAC__fixed_compute_best_predictor_intrin_sse2(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); | |||
| uint32_t FLAC__fixed_compute_best_predictor_wide_intrin_sse2(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); | |||
| # endif | |||
| # ifdef FLAC__SSSE3_SUPPORTED | |||
| uint32_t FLAC__fixed_compute_best_predictor_intrin_ssse3(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); | |||
| uint32_t FLAC__fixed_compute_best_predictor_wide_intrin_ssse3(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); | |||
| # endif | |||
| # endif | |||
| # if defined FLAC__CPU_IA32 && defined FLAC__HAS_NASM | |||
| uint32_t FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); | |||
| # endif | |||
| # endif | |||
| #else | |||
| uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); | |||
| uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); | |||
| #endif | |||
| /* | |||
| * FLAC__fixed_compute_residual() | |||
| * -------------------------------------------------------------------- | |||
| * Compute the residual signal obtained from sutracting the predicted | |||
| * signal from the original. | |||
| * | |||
| * IN data[-order,data_len-1] original signal (NOTE THE INDICES!) | |||
| * IN data_len length of original signal | |||
| * IN order <= FLAC__MAX_FIXED_ORDER fixed-predictor order | |||
| * OUT residual[0,data_len-1] residual signal | |||
| */ | |||
| void FLAC__fixed_compute_residual(const FLAC__int32 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[]); | |||
| /* | |||
| * FLAC__fixed_restore_signal() | |||
| * -------------------------------------------------------------------- | |||
| * Restore the original signal by summing the residual and the | |||
| * predictor. | |||
| * | |||
| * IN residual[0,data_len-1] residual signal | |||
| * IN data_len length of original signal | |||
| * IN order <= FLAC__MAX_FIXED_ORDER fixed-predictor order | |||
| * *** IMPORTANT: the caller must pass in the historical samples: | |||
| * IN data[-order,-1] previously-reconstructed historical samples | |||
| * OUT data[0,data_len-1] original signal | |||
| */ | |||
| void FLAC__fixed_restore_signal(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int32 data[]); | |||
| #endif | |||
| @@ -0,0 +1,95 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2004-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__FLOAT_H | |||
| #define FLAC__PRIVATE__FLOAT_H | |||
| #ifdef HAVE_CONFIG_H | |||
| #include <config.h> | |||
| #endif | |||
| #include "../../../ordinals.h" | |||
| /* | |||
| * All the code in libFLAC that uses float and double | |||
| * should be protected by checks of the macro | |||
| * FLAC__INTEGER_ONLY_LIBRARY. | |||
| * | |||
| */ | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| /* | |||
| * FLAC__real is the basic floating point type used in LPC analysis. | |||
| * | |||
| * WATCHOUT: changing FLAC__real will change the signatures of many | |||
| * functions that have assembly language equivalents and break them. | |||
| */ | |||
| typedef float FLAC__real; | |||
| #else | |||
| /* | |||
| * The convention for FLAC__fixedpoint is to use the upper 16 bits | |||
| * for the integer part and lower 16 bits for the fractional part. | |||
| */ | |||
| typedef FLAC__int32 FLAC__fixedpoint; | |||
| extern const FLAC__fixedpoint FLAC__FP_ZERO; | |||
| extern const FLAC__fixedpoint FLAC__FP_ONE_HALF; | |||
| extern const FLAC__fixedpoint FLAC__FP_ONE; | |||
| extern const FLAC__fixedpoint FLAC__FP_LN2; | |||
| extern const FLAC__fixedpoint FLAC__FP_E; | |||
| #define FLAC__fixedpoint_trunc(x) ((x)>>16) | |||
| #define FLAC__fixedpoint_mul(x, y) ( (FLAC__fixedpoint) ( ((FLAC__int64)(x)*(FLAC__int64)(y)) >> 16 ) ) | |||
| #define FLAC__fixedpoint_div(x, y) ( (FLAC__fixedpoint) ( ( ((FLAC__int64)(x)<<32) / (FLAC__int64)(y) ) >> 16 ) ) | |||
| /* | |||
| * FLAC__fixedpoint_log2() | |||
| * -------------------------------------------------------------------- | |||
| * Returns the base-2 logarithm of the fixed-point number 'x' using an | |||
| * algorithm by Knuth for x >= 1.0 | |||
| * | |||
| * 'fracbits' is the number of fractional bits of 'x'. 'fracbits' must | |||
| * be < 32 and evenly divisible by 4 (0 is OK but not very precise). | |||
| * | |||
| * 'precision' roughly limits the number of iterations that are done; | |||
| * use (uint32_t)(-1) for maximum precision. | |||
| * | |||
| * If 'x' is less than one -- that is, x < (1<<fracbits) -- then this | |||
| * function will punt and return 0. | |||
| * | |||
| * The return value will also have 'fracbits' fractional bits. | |||
| */ | |||
| FLAC__uint32 FLAC__fixedpoint_log2(FLAC__uint32 x, uint32_t fracbits, uint32_t precision); | |||
| #endif | |||
| #endif | |||
| @@ -0,0 +1,45 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__FORMAT_H | |||
| #define FLAC__PRIVATE__FORMAT_H | |||
| #include "../../../format.h" | |||
| uint32_t FLAC__format_get_max_rice_partition_order(uint32_t blocksize, uint32_t predictor_order); | |||
| uint32_t FLAC__format_get_max_rice_partition_order_from_blocksize(uint32_t blocksize); | |||
| uint32_t FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(uint32_t limit, uint32_t blocksize, uint32_t predictor_order); | |||
| void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object); | |||
| void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object); | |||
| FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, uint32_t max_partition_order); | |||
| #endif | |||
| @@ -0,0 +1,263 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__LPC_H | |||
| #define FLAC__PRIVATE__LPC_H | |||
| #ifdef HAVE_CONFIG_H | |||
| #include <config.h> | |||
| #endif | |||
| #include "cpu.h" | |||
| #include "float.h" | |||
| #include "../../../format.h" | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| /* | |||
| * FLAC__lpc_window_data() | |||
| * -------------------------------------------------------------------- | |||
| * Applies the given window to the data. | |||
| * OPT: asm implementation | |||
| * | |||
| * IN in[0,data_len-1] | |||
| * IN window[0,data_len-1] | |||
| * OUT out[0,lag-1] | |||
| * IN data_len | |||
| */ | |||
| void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], uint32_t data_len); | |||
| /* | |||
| * FLAC__lpc_compute_autocorrelation() | |||
| * -------------------------------------------------------------------- | |||
| * Compute the autocorrelation for lags between 0 and lag-1. | |||
| * Assumes data[] outside of [0,data_len-1] == 0. | |||
| * Asserts that lag > 0. | |||
| * | |||
| * IN data[0,data_len-1] | |||
| * IN data_len | |||
| * IN 0 < lag <= data_len | |||
| * OUT autoc[0,lag-1] | |||
| */ | |||
| void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| #ifndef FLAC__NO_ASM | |||
| # ifdef FLAC__CPU_IA32 | |||
| # ifdef FLAC__HAS_NASM | |||
| void FLAC__lpc_compute_autocorrelation_asm_ia32(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_16_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| # endif | |||
| # endif | |||
| # if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN | |||
| # ifdef FLAC__SSE_SUPPORTED | |||
| void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_new(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_new(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_new(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_new(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| # endif | |||
| # endif | |||
| #if defined(FLAC__CPU_PPC64) && defined(FLAC__USE_VSX) | |||
| #ifdef FLAC__HAS_TARGET_POWER9 | |||
| void FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_4(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_8(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_12(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_16(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| #endif | |||
| #ifdef FLAC__HAS_TARGET_POWER8 | |||
| void FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_4(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_8(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_12(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_16(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); | |||
| #endif | |||
| #endif | |||
| #endif | |||
| /* | |||
| * FLAC__lpc_compute_lp_coefficients() | |||
| * -------------------------------------------------------------------- | |||
| * Computes LP coefficients for orders 1..max_order. | |||
| * Do not call if autoc[0] == 0.0. This means the signal is zero | |||
| * and there is no point in calculating a predictor. | |||
| * | |||
| * IN autoc[0,max_order] autocorrelation values | |||
| * IN 0 < max_order <= FLAC__MAX_LPC_ORDER max LP order to compute | |||
| * OUT lp_coeff[0,max_order-1][0,max_order-1] LP coefficients for each order | |||
| * *** IMPORTANT: | |||
| * *** lp_coeff[0,max_order-1][max_order,FLAC__MAX_LPC_ORDER-1] are untouched | |||
| * OUT error[0,max_order-1] error for each order (more | |||
| * specifically, the variance of | |||
| * the error signal times # of | |||
| * samples in the signal) | |||
| * | |||
| * Example: if max_order is 9, the LP coefficients for order 9 will be | |||
| * in lp_coeff[8][0,8], the LP coefficients for order 8 will be | |||
| * in lp_coeff[7][0,7], etc. | |||
| */ | |||
| void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], uint32_t *max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], double error[]); | |||
| /* | |||
| * FLAC__lpc_quantize_coefficients() | |||
| * -------------------------------------------------------------------- | |||
| * Quantizes the LP coefficients. NOTE: precision + bits_per_sample | |||
| * must be less than 32 (sizeof(FLAC__int32)*8). | |||
| * | |||
| * IN lp_coeff[0,order-1] LP coefficients | |||
| * IN order LP order | |||
| * IN FLAC__MIN_QLP_COEFF_PRECISION < precision | |||
| * desired precision (in bits, including sign | |||
| * bit) of largest coefficient | |||
| * OUT qlp_coeff[0,order-1] quantized coefficients | |||
| * OUT shift # of bits to shift right to get approximated | |||
| * LP coefficients. NOTE: could be negative. | |||
| * RETURN 0 => quantization OK | |||
| * 1 => coefficients require too much shifting for *shift to | |||
| * fit in the LPC subframe header. 'shift' is unset. | |||
| * 2 => coefficients are all zero, which is bad. 'shift' is | |||
| * unset. | |||
| */ | |||
| int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], uint32_t order, uint32_t precision, FLAC__int32 qlp_coeff[], int *shift); | |||
| /* | |||
| * FLAC__lpc_compute_residual_from_qlp_coefficients() | |||
| * -------------------------------------------------------------------- | |||
| * Compute the residual signal obtained from sutracting the predicted | |||
| * signal from the original. | |||
| * | |||
| * IN data[-order,data_len-1] original signal (NOTE THE INDICES!) | |||
| * IN data_len length of original signal | |||
| * IN qlp_coeff[0,order-1] quantized LP coefficients | |||
| * IN order > 0 LP order | |||
| * IN lp_quantization quantization of LP coefficients in bits | |||
| * OUT residual[0,data_len-1] residual signal | |||
| */ | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); | |||
| #ifndef FLAC__NO_ASM | |||
| # ifdef FLAC__CPU_IA32 | |||
| # ifdef FLAC__HAS_NASM | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_asm_ia32(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); | |||
| # endif | |||
| # endif | |||
| # if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN | |||
| # ifdef FLAC__SSE2_SUPPORTED | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse2(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); | |||
| # endif | |||
| # ifdef FLAC__SSE4_1_SUPPORTED | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse41(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_sse41(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); | |||
| # endif | |||
| # ifdef FLAC__AVX2_SUPPORTED | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_avx2(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_avx2(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); | |||
| # endif | |||
| # endif | |||
| #endif | |||
| #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ | |||
| /* | |||
| * FLAC__lpc_restore_signal() | |||
| * -------------------------------------------------------------------- | |||
| * Restore the original signal by summing the residual and the | |||
| * predictor. | |||
| * | |||
| * IN residual[0,data_len-1] residual signal | |||
| * IN data_len length of original signal | |||
| * IN qlp_coeff[0,order-1] quantized LP coefficients | |||
| * IN order > 0 LP order | |||
| * IN lp_quantization quantization of LP coefficients in bits | |||
| * *** IMPORTANT: the caller must pass in the historical samples: | |||
| * IN data[-order,-1] previously-reconstructed historical samples | |||
| * OUT data[0,data_len-1] original signal | |||
| */ | |||
| void FLAC__lpc_restore_signal(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); | |||
| void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); | |||
| #ifndef FLAC__NO_ASM | |||
| # ifdef FLAC__CPU_IA32 | |||
| # ifdef FLAC__HAS_NASM | |||
| void FLAC__lpc_restore_signal_asm_ia32(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); | |||
| void FLAC__lpc_restore_signal_asm_ia32_mmx(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); | |||
| void FLAC__lpc_restore_signal_wide_asm_ia32(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); | |||
| # endif /* FLAC__HAS_NASM */ | |||
| # endif /* FLAC__CPU_IA32 */ | |||
| # if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN | |||
| # ifdef FLAC__SSE4_1_SUPPORTED | |||
| void FLAC__lpc_restore_signal_intrin_sse41(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); | |||
| void FLAC__lpc_restore_signal_16_intrin_sse41(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); | |||
| void FLAC__lpc_restore_signal_wide_intrin_sse41(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); | |||
| # endif | |||
| # endif | |||
| #endif /* FLAC__NO_ASM */ | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| /* | |||
| * FLAC__lpc_compute_expected_bits_per_residual_sample() | |||
| * -------------------------------------------------------------------- | |||
| * Compute the expected number of bits per residual signal sample | |||
| * based on the LP error (which is related to the residual variance). | |||
| * | |||
| * IN lpc_error >= 0.0 error returned from calculating LP coefficients | |||
| * IN total_samples > 0 # of samples in residual signal | |||
| * RETURN expected bits per sample | |||
| */ | |||
| double FLAC__lpc_compute_expected_bits_per_residual_sample(double lpc_error, uint32_t total_samples); | |||
| double FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(double lpc_error, double error_scale); | |||
| /* | |||
| * FLAC__lpc_compute_best_order() | |||
| * -------------------------------------------------------------------- | |||
| * Compute the best order from the array of signal errors returned | |||
| * during coefficient computation. | |||
| * | |||
| * IN lpc_error[0,max_order-1] >= 0.0 error returned from calculating LP coefficients | |||
| * IN max_order > 0 max LP order | |||
| * IN total_samples > 0 # of samples in residual signal | |||
| * IN overhead_bits_per_order # of bits overhead for each increased LP order | |||
| * (includes warmup sample size and quantized LP coefficient) | |||
| * RETURN [1,max_order] best order | |||
| */ | |||
| uint32_t FLAC__lpc_compute_best_order(const double lpc_error[], uint32_t max_order, uint32_t total_samples, uint32_t overhead_bits_per_order); | |||
| #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ | |||
| #endif | |||
| @@ -0,0 +1,74 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2012-2016 Xiph.org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__MACROS_H | |||
| #define FLAC__PRIVATE__MACROS_H | |||
| #if defined(__GNUC__) && (__GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 3)) | |||
| #define flac_max(a,b) \ | |||
| ({ __typeof__ (a) _a = (a); \ | |||
| __typeof__ (b) _b = (b); \ | |||
| _a > _b ? _a : _b; }) | |||
| #define MIN_PASTE(A,B) A##B | |||
| #define MIN_IMPL(A,B,L) ({ \ | |||
| __typeof__(A) MIN_PASTE(__a,L) = (A); \ | |||
| __typeof__(B) MIN_PASTE(__b,L) = (B); \ | |||
| MIN_PASTE(__a,L) < MIN_PASTE(__b,L) ? MIN_PASTE(__a,L) : MIN_PASTE(__b,L); \ | |||
| }) | |||
| #define flac_min(A,B) MIN_IMPL(A,B,__COUNTER__) | |||
| /* Whatever other unix that has sys/param.h */ | |||
| #elif defined(HAVE_SYS_PARAM_H) | |||
| #include <sys/param.h> | |||
| #if defined(MIN) && defined(MAX) | |||
| #define flac_max(a,b) MAX(a,b) | |||
| #define flac_min(a,b) MIN(a,b) | |||
| #endif | |||
| /* Windows VS has them in stdlib.h.. XXX:Untested */ | |||
| #elif defined(_MSC_VER) | |||
| #include <stdlib.h> | |||
| #define flac_max(a,b) __max(a,b) | |||
| #define flac_min(a,b) __min(a,b) | |||
| #endif | |||
| #ifndef flac_min | |||
| #define flac_min(x,y) ((x) <= (y) ? (x) : (y)) | |||
| #endif | |||
| #ifndef flac_max | |||
| #define flac_max(x,y) ((x) >= (y) ? (x) : (y)) | |||
| #endif | |||
| #endif | |||
| @@ -0,0 +1,50 @@ | |||
| #ifndef FLAC__PRIVATE__MD5_H | |||
| #define FLAC__PRIVATE__MD5_H | |||
| /* | |||
| * This is the header file for the MD5 message-digest algorithm. | |||
| * The algorithm is due to Ron Rivest. This code was | |||
| * written by Colin Plumb in 1993, no copyright is claimed. | |||
| * This code is in the public domain; do with it what you wish. | |||
| * | |||
| * Equivalent code is available from RSA Data Security, Inc. | |||
| * This code has been tested against that, and is equivalent, | |||
| * except that you don't need to include two pages of legalese | |||
| * with every copy. | |||
| * | |||
| * To compute the message digest of a chunk of bytes, declare an | |||
| * MD5Context structure, pass it to MD5Init, call MD5Update as | |||
| * needed on buffers full of bytes, and then call MD5Final, which | |||
| * will fill a supplied 16-byte array with the digest. | |||
| * | |||
| * Changed so as no longer to depend on Colin Plumb's `usual.h' | |||
| * header definitions; now uses stuff from dpkg's config.h | |||
| * - Ian Jackson <ijackson@nyx.cs.du.edu>. | |||
| * Still in the public domain. | |||
| * | |||
| * Josh Coalson: made some changes to integrate with libFLAC. | |||
| * Still in the public domain, with no warranty. | |||
| */ | |||
| #include "../../../ordinals.h" | |||
| typedef union { | |||
| FLAC__byte *p8; | |||
| FLAC__int16 *p16; | |||
| FLAC__int32 *p32; | |||
| } FLAC__multibyte; | |||
| typedef struct { | |||
| FLAC__uint32 in[16]; | |||
| FLAC__uint32 buf[4]; | |||
| FLAC__uint32 bytes[2]; | |||
| FLAC__multibyte internal_buf; | |||
| size_t capacity; | |||
| } FLAC__MD5Context; | |||
| void FLAC__MD5Init(FLAC__MD5Context *context); | |||
| void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *context); | |||
| FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const signal[], uint32_t channels, uint32_t samples, uint32_t bytes_per_sample); | |||
| #endif | |||
| @@ -0,0 +1,58 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2001-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__MEMORY_H | |||
| #define FLAC__PRIVATE__MEMORY_H | |||
| #ifdef HAVE_CONFIG_H | |||
| #include <config.h> | |||
| #endif | |||
| #include <stdlib.h> /* for size_t */ | |||
| #include "float.h" | |||
| #include "../../../ordinals.h" /* for FLAC__bool */ | |||
| /* Returns the unaligned address returned by malloc. | |||
| * Use free() on this address to deallocate. | |||
| */ | |||
| void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address); | |||
| 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, uint32_t **unaligned_pointer, uint32_t **aligned_pointer); | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| FLAC__bool FLAC__memory_alloc_aligned_real_array(size_t elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer); | |||
| #endif | |||
| void *safe_malloc_mul_2op_p(size_t size1, size_t size2); | |||
| #endif | |||
| @@ -0,0 +1,46 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2002-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__METADATA_H | |||
| #define FLAC__PRIVATE__METADATA_H | |||
| #include "../../../metadata.h" | |||
| /* 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 | |||
| * state after FLAC__metadata_object_new() | |||
| */ | |||
| void FLAC__metadata_object_delete_data(FLAC__StreamMetadata *object); | |||
| void FLAC__metadata_object_cuesheet_track_delete_data(FLAC__StreamMetadata_CueSheet_Track *object); | |||
| #endif | |||
| @@ -0,0 +1,80 @@ | |||
| /* libFLAC - Free Lossless Audio Codec | |||
| * Copyright (C) 2002-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__OGG_DECODER_ASPECT_H | |||
| #define FLAC__PRIVATE__OGG_DECODER_ASPECT_H | |||
| #include <ogg/ogg.h> | |||
| #include "../../../ordinals.h" | |||
| #include "../../../stream_decoder.h" /* for FLAC__StreamDecoderReadStatus */ | |||
| typedef struct FLAC__OggDecoderAspect { | |||
| /* these are storage for values that can be set through the API */ | |||
| FLAC__bool use_first_serial_number; | |||
| long serial_number; | |||
| /* these are for internal state related to Ogg decoding */ | |||
| ogg_stream_state stream_state; | |||
| ogg_sync_state sync_state; | |||
| uint32_t version_major, version_minor; | |||
| FLAC__bool need_serial_number; | |||
| FLAC__bool end_of_stream; | |||
| FLAC__bool have_working_page; /* only if true will the following vars be valid */ | |||
| ogg_page working_page; | |||
| FLAC__bool have_working_packet; /* only if true will the following vars be valid */ | |||
| ogg_packet working_packet; /* as we work through the packet we will move working_packet.packet forward and working_packet.bytes down */ | |||
| } FLAC__OggDecoderAspect; | |||
| void FLAC__ogg_decoder_aspect_set_serial_number(FLAC__OggDecoderAspect *aspect, long value); | |||
| void FLAC__ogg_decoder_aspect_set_defaults(FLAC__OggDecoderAspect *aspect); | |||
| FLAC__bool FLAC__ogg_decoder_aspect_init(FLAC__OggDecoderAspect *aspect); | |||
| void FLAC__ogg_decoder_aspect_finish(FLAC__OggDecoderAspect *aspect); | |||
| void FLAC__ogg_decoder_aspect_flush(FLAC__OggDecoderAspect *aspect); | |||
| void FLAC__ogg_decoder_aspect_reset(FLAC__OggDecoderAspect *aspect); | |||
| typedef enum { | |||
| FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK = 0, | |||
| FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM, | |||
| FLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC, | |||
| FLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC, | |||
| FLAC__OGG_DECODER_ASPECT_READ_STATUS_UNSUPPORTED_MAPPING_VERSION, | |||
| FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT, | |||
| FLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR, | |||
| FLAC__OGG_DECODER_ASPECT_READ_STATUS_MEMORY_ALLOCATION_ERROR | |||
| } FLAC__OggDecoderAspectReadStatus; | |||
| typedef FLAC__OggDecoderAspectReadStatus (*FLAC__OggDecoderAspectReadCallbackProxy)(const void *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data); | |||
| FLAC__OggDecoderAspectReadStatus FLAC__ogg_decoder_aspect_read_callback_wrapper(FLAC__OggDecoderAspect *aspect, FLAC__byte buffer[], size_t *bytes, FLAC__OggDecoderAspectReadCallbackProxy read_callback, const FLAC__StreamDecoder *decoder, void *client_data); | |||
| #endif | |||
| @@ -0,0 +1,63 @@ | |||
| /* libFLAC - Free Lossless Audio Codec | |||
| * Copyright (C) 2002-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__OGG_ENCODER_ASPECT_H | |||
| #define FLAC__PRIVATE__OGG_ENCODER_ASPECT_H | |||
| #include <ogg/ogg.h> | |||
| #include "../../../ordinals.h" | |||
| #include "../../../stream_encoder.h" /* for FLAC__StreamEncoderWriteStatus */ | |||
| typedef struct FLAC__OggEncoderAspect { | |||
| /* these are storage for values that can be set through the API */ | |||
| long serial_number; | |||
| uint32_t num_metadata; | |||
| /* these are for internal state related to Ogg encoding */ | |||
| ogg_stream_state stream_state; | |||
| ogg_page page; | |||
| FLAC__bool seen_magic; /* true if we've seen the fLaC magic in the write callback yet */ | |||
| FLAC__bool is_first_packet; | |||
| FLAC__uint64 samples_written; | |||
| } FLAC__OggEncoderAspect; | |||
| void FLAC__ogg_encoder_aspect_set_serial_number(FLAC__OggEncoderAspect *aspect, long value); | |||
| FLAC__bool FLAC__ogg_encoder_aspect_set_num_metadata(FLAC__OggEncoderAspect *aspect, uint32_t value); | |||
| void FLAC__ogg_encoder_aspect_set_defaults(FLAC__OggEncoderAspect *aspect); | |||
| FLAC__bool FLAC__ogg_encoder_aspect_init(FLAC__OggEncoderAspect *aspect); | |||
| void FLAC__ogg_encoder_aspect_finish(FLAC__OggEncoderAspect *aspect); | |||
| typedef FLAC__StreamEncoderWriteStatus (*FLAC__OggEncoderAspectWriteCallbackProxy)(const void *encoder, const FLAC__byte buffer[], size_t bytes, uint32_t samples, uint32_t current_frame, void *client_data); | |||
| FLAC__StreamEncoderWriteStatus FLAC__ogg_encoder_aspect_write_callback_wrapper(FLAC__OggEncoderAspect *aspect, const FLAC__byte buffer[], size_t bytes, uint32_t samples, uint32_t current_frame, FLAC__bool is_last_block, FLAC__OggEncoderAspectWriteCallbackProxy write_callback, void *encoder, void *client_data); | |||
| #endif | |||
| @@ -0,0 +1,44 @@ | |||
| /* libFLAC - Free Lossless Audio Codec | |||
| * Copyright (C) 2004-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__OGG_HELPER_H | |||
| #define FLAC__PRIVATE__OGG_HELPER_H | |||
| #include <ogg/ogg.h> | |||
| #include "../../../stream_encoder.h" /* for FLAC__StreamEncoder */ | |||
| void simple_ogg_page__init(ogg_page *page); | |||
| void simple_ogg_page__clear(ogg_page *page); | |||
| FLAC__bool simple_ogg_page__get_at(FLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderReadCallback read_callback, void *client_data); | |||
| FLAC__bool simple_ogg_page__set_at(FLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderWriteCallback write_callback, void *client_data); | |||
| #endif | |||
| @@ -0,0 +1,64 @@ | |||
| /* libFLAC - Free Lossless Audio Codec | |||
| * Copyright (C) 2004-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__OGG_MAPPING_H | |||
| #define FLAC__PRIVATE__OGG_MAPPING_H | |||
| #include "../../../ordinals.h" | |||
| /** The length of the packet type field in bytes. */ | |||
| #define FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH (1u) | |||
| extern const uint32_t FLAC__OGG_MAPPING_PACKET_TYPE_LEN; /* = 8 bits */ | |||
| extern const FLAC__byte FLAC__OGG_MAPPING_FIRST_HEADER_PACKET_TYPE; /* = 0x7f */ | |||
| /** The length of the 'FLAC' magic in bytes. */ | |||
| #define FLAC__OGG_MAPPING_MAGIC_LENGTH (4u) | |||
| extern const FLAC__byte * const FLAC__OGG_MAPPING_MAGIC; /* = "FLAC" */ | |||
| extern const uint32_t FLAC__OGG_MAPPING_VERSION_MAJOR_LEN; /* = 8 bits */ | |||
| extern const uint32_t FLAC__OGG_MAPPING_VERSION_MINOR_LEN; /* = 8 bits */ | |||
| /** The length of the Ogg FLAC mapping major version number in bytes. */ | |||
| #define FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH (1u) | |||
| /** The length of the Ogg FLAC mapping minor version number in bytes. */ | |||
| #define FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH (1u) | |||
| extern const uint32_t FLAC__OGG_MAPPING_NUM_HEADERS_LEN; /* = 16 bits */ | |||
| /** The length of the #-of-header-packets number bytes. */ | |||
| #define FLAC__OGG_MAPPING_NUM_HEADERS_LENGTH (2u) | |||
| #endif | |||
| @@ -0,0 +1,67 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__STREAM_ENCODER_H | |||
| #define FLAC__PRIVATE__STREAM_ENCODER_H | |||
| #ifdef HAVE_CONFIG_H | |||
| #include <config.h> | |||
| #endif | |||
| /* | |||
| * This is used to avoid overflow with unusual signals in 32-bit | |||
| * accumulator in the *precompute_partition_info_sums_* functions. | |||
| */ | |||
| #define FLAC__MAX_EXTRA_RESIDUAL_BPS 4 | |||
| #if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN | |||
| #include "cpu.h" | |||
| #include "../../../format.h" | |||
| #ifdef FLAC__SSE2_SUPPORTED | |||
| extern void FLAC__precompute_partition_info_sums_intrin_sse2(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], | |||
| uint32_t residual_samples, uint32_t predictor_order, uint32_t min_partition_order, uint32_t max_partition_order, uint32_t bps); | |||
| #endif | |||
| #ifdef FLAC__SSSE3_SUPPORTED | |||
| extern void FLAC__precompute_partition_info_sums_intrin_ssse3(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], | |||
| uint32_t residual_samples, uint32_t predictor_order, uint32_t min_partition_order, uint32_t max_partition_order, uint32_t bps); | |||
| #endif | |||
| #ifdef FLAC__AVX2_SUPPORTED | |||
| extern void FLAC__precompute_partition_info_sums_intrin_avx2(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], | |||
| uint32_t residual_samples, uint32_t predictor_order, uint32_t min_partition_order, uint32_t max_partition_order, uint32_t bps); | |||
| #endif | |||
| #endif | |||
| #endif | |||
| @@ -0,0 +1,46 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__STREAM_ENCODER_FRAMING_H | |||
| #define FLAC__PRIVATE__STREAM_ENCODER_FRAMING_H | |||
| #include "../../../format.h" | |||
| #include "bitwriter.h" | |||
| FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__BitWriter *bw); | |||
| FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWriter *bw); | |||
| FLAC__bool FLAC__subframe_add_constant(const FLAC__Subframe_Constant *subframe, uint32_t subframe_bps, uint32_t wasted_bits, FLAC__BitWriter *bw); | |||
| FLAC__bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, uint32_t residual_samples, uint32_t subframe_bps, uint32_t wasted_bits, FLAC__BitWriter *bw); | |||
| FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, uint32_t residual_samples, uint32_t subframe_bps, uint32_t wasted_bits, FLAC__BitWriter *bw); | |||
| FLAC__bool FLAC__subframe_add_verbatim(const FLAC__Subframe_Verbatim *subframe, uint32_t samples, uint32_t subframe_bps, uint32_t wasted_bits, FLAC__BitWriter *bw); | |||
| #endif | |||
| @@ -0,0 +1,74 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2006-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__WINDOW_H | |||
| #define FLAC__PRIVATE__WINDOW_H | |||
| #ifdef HAVE_CONFIG_H | |||
| #include <config.h> | |||
| #endif | |||
| #include "float.h" | |||
| #include "../../../format.h" | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| /* | |||
| * FLAC__window_*() | |||
| * -------------------------------------------------------------------- | |||
| * Calculates window coefficients according to different apodization | |||
| * functions. | |||
| * | |||
| * OUT window[0,L-1] | |||
| * IN L (number of points in window) | |||
| */ | |||
| void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_bartlett_hann(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_blackman(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_blackman_harris_4term_92db_sidelobe(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_connes(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_flattop(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_gauss(FLAC__real *window, const FLAC__int32 L, const FLAC__real stddev); /* 0.0 < stddev <= 0.5 */ | |||
| void FLAC__window_hamming(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_hann(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_kaiser_bessel(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_nuttall(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_rectangle(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p); | |||
| void FLAC__window_partial_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end); | |||
| void FLAC__window_punchout_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end); | |||
| void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L); | |||
| #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ | |||
| #endif | |||
| @@ -0,0 +1,39 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2001-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PROTECTED__ALL_H | |||
| #define FLAC__PROTECTED__ALL_H | |||
| #include "stream_decoder.h" | |||
| #include "stream_encoder.h" | |||
| #endif | |||
| @@ -0,0 +1,65 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PROTECTED__STREAM_DECODER_H | |||
| #define FLAC__PROTECTED__STREAM_DECODER_H | |||
| #include "../../../stream_decoder.h" | |||
| #if FLAC__HAS_OGG | |||
| #include "../private/ogg_decoder_aspect.h" | |||
| #endif | |||
| typedef struct FLAC__StreamDecoderProtected { | |||
| FLAC__StreamDecoderState state; | |||
| FLAC__StreamDecoderInitStatus initstate; | |||
| uint32_t channels; | |||
| FLAC__ChannelAssignment channel_assignment; | |||
| uint32_t bits_per_sample; | |||
| uint32_t sample_rate; /* in Hz */ | |||
| uint32_t blocksize; /* in samples (per channel) */ | |||
| FLAC__bool md5_checking; /* if true, generate MD5 signature of decoded data and compare against signature in the STREAMINFO metadata block */ | |||
| #if FLAC__HAS_OGG | |||
| FLAC__OggDecoderAspect ogg_decoder_aspect; | |||
| #endif | |||
| } FLAC__StreamDecoderProtected; | |||
| /* | |||
| * return the number of input bytes consumed | |||
| */ | |||
| uint32_t FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder); | |||
| /* | |||
| * return client_data from decoder | |||
| */ | |||
| FLAC_API void *get_client_data_from_decoder(FLAC__StreamDecoder *decoder); | |||
| #endif | |||
| @@ -0,0 +1,118 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2001-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PROTECTED__STREAM_ENCODER_H | |||
| #define FLAC__PROTECTED__STREAM_ENCODER_H | |||
| #include "../../../stream_encoder.h" | |||
| #if FLAC__HAS_OGG | |||
| #include "../private/ogg_encoder_aspect.h" | |||
| #endif | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| #include "../private/float.h" | |||
| #define FLAC__MAX_APODIZATION_FUNCTIONS 32 | |||
| typedef enum { | |||
| FLAC__APODIZATION_BARTLETT, | |||
| FLAC__APODIZATION_BARTLETT_HANN, | |||
| FLAC__APODIZATION_BLACKMAN, | |||
| FLAC__APODIZATION_BLACKMAN_HARRIS_4TERM_92DB_SIDELOBE, | |||
| FLAC__APODIZATION_CONNES, | |||
| FLAC__APODIZATION_FLATTOP, | |||
| FLAC__APODIZATION_GAUSS, | |||
| FLAC__APODIZATION_HAMMING, | |||
| FLAC__APODIZATION_HANN, | |||
| FLAC__APODIZATION_KAISER_BESSEL, | |||
| FLAC__APODIZATION_NUTTALL, | |||
| FLAC__APODIZATION_RECTANGLE, | |||
| FLAC__APODIZATION_TRIANGLE, | |||
| FLAC__APODIZATION_TUKEY, | |||
| FLAC__APODIZATION_PARTIAL_TUKEY, | |||
| FLAC__APODIZATION_PUNCHOUT_TUKEY, | |||
| FLAC__APODIZATION_WELCH | |||
| } FLAC__ApodizationFunction; | |||
| typedef struct { | |||
| FLAC__ApodizationFunction type; | |||
| union { | |||
| struct { | |||
| FLAC__real stddev; | |||
| } gauss; | |||
| struct { | |||
| FLAC__real p; | |||
| } tukey; | |||
| struct { | |||
| FLAC__real p; | |||
| FLAC__real start; | |||
| FLAC__real end; | |||
| } multiple_tukey; | |||
| } parameters; | |||
| } FLAC__ApodizationSpecification; | |||
| #endif // #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| typedef struct FLAC__StreamEncoderProtected { | |||
| FLAC__StreamEncoderState state; | |||
| FLAC__bool verify; | |||
| FLAC__bool streamable_subset; | |||
| FLAC__bool do_md5; | |||
| FLAC__bool do_mid_side_stereo; | |||
| FLAC__bool loose_mid_side_stereo; | |||
| uint32_t channels; | |||
| uint32_t bits_per_sample; | |||
| uint32_t sample_rate; | |||
| uint32_t blocksize; | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| uint32_t num_apodizations; | |||
| FLAC__ApodizationSpecification apodizations[FLAC__MAX_APODIZATION_FUNCTIONS]; | |||
| #endif | |||
| uint32_t max_lpc_order; | |||
| uint32_t qlp_coeff_precision; | |||
| FLAC__bool do_qlp_coeff_prec_search; | |||
| FLAC__bool do_exhaustive_model_search; | |||
| FLAC__bool do_escape_coding; | |||
| uint32_t min_residual_partition_order; | |||
| uint32_t max_residual_partition_order; | |||
| uint32_t rice_parameter_search_dist; | |||
| FLAC__uint64 total_samples_estimate; | |||
| FLAC__StreamMetadata **metadata; | |||
| uint32_t num_metadata_blocks; | |||
| FLAC__uint64 streaminfo_offset, seektable_offset, audio_offset; | |||
| #if FLAC__HAS_OGG | |||
| FLAC__OggEncoderAspect ogg_encoder_aspect; | |||
| #endif | |||
| } FLAC__StreamEncoderProtected; | |||
| #endif | |||
| @@ -0,0 +1,454 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include "include/private/cpu.h" | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| #ifndef FLAC__NO_ASM | |||
| #if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN | |||
| #include "include/private/lpc.h" | |||
| #ifdef FLAC__SSE_SUPPORTED | |||
| #include "../assert.h" | |||
| #include "../format.h" | |||
| #include <xmmintrin.h> /* SSE */ | |||
| /* new routines: more unaligned loads, less shuffle | |||
| * old routines: less unaligned loads, more shuffle | |||
| * these *_old routines are equivalent to the ASM routines in ia32/lpc_asm.nasm | |||
| */ | |||
| /* new routines: faster on current Intel (starting from Core i aka Nehalem) and all AMD CPUs */ | |||
| FLAC__SSE_TARGET("sse") | |||
| void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_new(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]) | |||
| { | |||
| int i; | |||
| int limit = data_len - 4; | |||
| __m128 sum0; | |||
| (void) lag; | |||
| FLAC__ASSERT(lag <= 4); | |||
| FLAC__ASSERT(lag <= data_len); | |||
| sum0 = _mm_setzero_ps(); | |||
| for(i = 0; i <= limit; i++) { | |||
| __m128 d, d0; | |||
| d0 = _mm_loadu_ps(data+i); | |||
| d = _mm_shuffle_ps(d0, d0, 0); | |||
| sum0 = _mm_add_ps(sum0, _mm_mul_ps(d0, d)); | |||
| } | |||
| { | |||
| __m128 d0 = _mm_setzero_ps(); | |||
| limit++; if(limit < 0) limit = 0; | |||
| for(i = data_len-1; i >= limit; i--) { | |||
| __m128 d; | |||
| d = _mm_load_ss(data+i); d = _mm_shuffle_ps(d, d, 0); | |||
| d0 = _mm_shuffle_ps(d0, d0, _MM_SHUFFLE(2,1,0,3)); | |||
| d0 = _mm_move_ss(d0, d); | |||
| sum0 = _mm_add_ps(sum0, _mm_mul_ps(d, d0)); | |||
| } | |||
| } | |||
| _mm_storeu_ps(autoc, sum0); | |||
| } | |||
| FLAC__SSE_TARGET("sse") | |||
| void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_new(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]) | |||
| { | |||
| int i; | |||
| int limit = data_len - 8; | |||
| __m128 sum0, sum1; | |||
| (void) lag; | |||
| FLAC__ASSERT(lag <= 8); | |||
| FLAC__ASSERT(lag <= data_len); | |||
| sum0 = _mm_setzero_ps(); | |||
| sum1 = _mm_setzero_ps(); | |||
| for(i = 0; i <= limit; i++) { | |||
| __m128 d, d0, d1; | |||
| d0 = _mm_loadu_ps(data+i); | |||
| d1 = _mm_loadu_ps(data+i+4); | |||
| d = _mm_shuffle_ps(d0, d0, 0); | |||
| sum0 = _mm_add_ps(sum0, _mm_mul_ps(d0, d)); | |||
| sum1 = _mm_add_ps(sum1, _mm_mul_ps(d1, d)); | |||
| } | |||
| { | |||
| __m128 d0 = _mm_setzero_ps(); | |||
| __m128 d1 = _mm_setzero_ps(); | |||
| limit++; if(limit < 0) limit = 0; | |||
| for(i = data_len-1; i >= limit; i--) { | |||
| __m128 d; | |||
| d = _mm_load_ss(data+i); d = _mm_shuffle_ps(d, d, 0); | |||
| d1 = _mm_shuffle_ps(d1, d1, _MM_SHUFFLE(2,1,0,3)); | |||
| d0 = _mm_shuffle_ps(d0, d0, _MM_SHUFFLE(2,1,0,3)); | |||
| d1 = _mm_move_ss(d1, d0); | |||
| d0 = _mm_move_ss(d0, d); | |||
| sum1 = _mm_add_ps(sum1, _mm_mul_ps(d, d1)); | |||
| sum0 = _mm_add_ps(sum0, _mm_mul_ps(d, d0)); | |||
| } | |||
| } | |||
| _mm_storeu_ps(autoc, sum0); | |||
| _mm_storeu_ps(autoc+4, sum1); | |||
| } | |||
| FLAC__SSE_TARGET("sse") | |||
| void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_new(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]) | |||
| { | |||
| int i; | |||
| int limit = data_len - 12; | |||
| __m128 sum0, sum1, sum2; | |||
| (void) lag; | |||
| FLAC__ASSERT(lag <= 12); | |||
| FLAC__ASSERT(lag <= data_len); | |||
| sum0 = _mm_setzero_ps(); | |||
| sum1 = _mm_setzero_ps(); | |||
| sum2 = _mm_setzero_ps(); | |||
| for(i = 0; i <= limit; i++) { | |||
| __m128 d, d0, d1, d2; | |||
| d0 = _mm_loadu_ps(data+i); | |||
| d1 = _mm_loadu_ps(data+i+4); | |||
| d2 = _mm_loadu_ps(data+i+8); | |||
| d = _mm_shuffle_ps(d0, d0, 0); | |||
| sum0 = _mm_add_ps(sum0, _mm_mul_ps(d0, d)); | |||
| sum1 = _mm_add_ps(sum1, _mm_mul_ps(d1, d)); | |||
| sum2 = _mm_add_ps(sum2, _mm_mul_ps(d2, d)); | |||
| } | |||
| { | |||
| __m128 d0 = _mm_setzero_ps(); | |||
| __m128 d1 = _mm_setzero_ps(); | |||
| __m128 d2 = _mm_setzero_ps(); | |||
| limit++; if(limit < 0) limit = 0; | |||
| for(i = data_len-1; i >= limit; i--) { | |||
| __m128 d; | |||
| d = _mm_load_ss(data+i); d = _mm_shuffle_ps(d, d, 0); | |||
| d2 = _mm_shuffle_ps(d2, d2, _MM_SHUFFLE(2,1,0,3)); | |||
| d1 = _mm_shuffle_ps(d1, d1, _MM_SHUFFLE(2,1,0,3)); | |||
| d0 = _mm_shuffle_ps(d0, d0, _MM_SHUFFLE(2,1,0,3)); | |||
| d2 = _mm_move_ss(d2, d1); | |||
| d1 = _mm_move_ss(d1, d0); | |||
| d0 = _mm_move_ss(d0, d); | |||
| sum2 = _mm_add_ps(sum2, _mm_mul_ps(d, d2)); | |||
| sum1 = _mm_add_ps(sum1, _mm_mul_ps(d, d1)); | |||
| sum0 = _mm_add_ps(sum0, _mm_mul_ps(d, d0)); | |||
| } | |||
| } | |||
| _mm_storeu_ps(autoc, sum0); | |||
| _mm_storeu_ps(autoc+4, sum1); | |||
| _mm_storeu_ps(autoc+8, sum2); | |||
| } | |||
| FLAC__SSE_TARGET("sse") | |||
| void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_new(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]) | |||
| { | |||
| int i; | |||
| int limit = data_len - 16; | |||
| __m128 sum0, sum1, sum2, sum3; | |||
| (void) lag; | |||
| FLAC__ASSERT(lag <= 16); | |||
| FLAC__ASSERT(lag <= data_len); | |||
| sum0 = _mm_setzero_ps(); | |||
| sum1 = _mm_setzero_ps(); | |||
| sum2 = _mm_setzero_ps(); | |||
| sum3 = _mm_setzero_ps(); | |||
| for(i = 0; i <= limit; i++) { | |||
| __m128 d, d0, d1, d2, d3; | |||
| d0 = _mm_loadu_ps(data+i); | |||
| d1 = _mm_loadu_ps(data+i+4); | |||
| d2 = _mm_loadu_ps(data+i+8); | |||
| d3 = _mm_loadu_ps(data+i+12); | |||
| d = _mm_shuffle_ps(d0, d0, 0); | |||
| sum0 = _mm_add_ps(sum0, _mm_mul_ps(d0, d)); | |||
| sum1 = _mm_add_ps(sum1, _mm_mul_ps(d1, d)); | |||
| sum2 = _mm_add_ps(sum2, _mm_mul_ps(d2, d)); | |||
| sum3 = _mm_add_ps(sum3, _mm_mul_ps(d3, d)); | |||
| } | |||
| { | |||
| __m128 d0 = _mm_setzero_ps(); | |||
| __m128 d1 = _mm_setzero_ps(); | |||
| __m128 d2 = _mm_setzero_ps(); | |||
| __m128 d3 = _mm_setzero_ps(); | |||
| limit++; if(limit < 0) limit = 0; | |||
| for(i = data_len-1; i >= limit; i--) { | |||
| __m128 d; | |||
| d = _mm_load_ss(data+i); d = _mm_shuffle_ps(d, d, 0); | |||
| d3 = _mm_shuffle_ps(d3, d3, _MM_SHUFFLE(2,1,0,3)); | |||
| d2 = _mm_shuffle_ps(d2, d2, _MM_SHUFFLE(2,1,0,3)); | |||
| d1 = _mm_shuffle_ps(d1, d1, _MM_SHUFFLE(2,1,0,3)); | |||
| d0 = _mm_shuffle_ps(d0, d0, _MM_SHUFFLE(2,1,0,3)); | |||
| d3 = _mm_move_ss(d3, d2); | |||
| d2 = _mm_move_ss(d2, d1); | |||
| d1 = _mm_move_ss(d1, d0); | |||
| d0 = _mm_move_ss(d0, d); | |||
| sum3 = _mm_add_ps(sum3, _mm_mul_ps(d, d3)); | |||
| sum2 = _mm_add_ps(sum2, _mm_mul_ps(d, d2)); | |||
| sum1 = _mm_add_ps(sum1, _mm_mul_ps(d, d1)); | |||
| sum0 = _mm_add_ps(sum0, _mm_mul_ps(d, d0)); | |||
| } | |||
| } | |||
| _mm_storeu_ps(autoc, sum0); | |||
| _mm_storeu_ps(autoc+4, sum1); | |||
| _mm_storeu_ps(autoc+8, sum2); | |||
| _mm_storeu_ps(autoc+12,sum3); | |||
| } | |||
| /* old routines: faster on older Intel CPUs (up to Core 2) */ | |||
| FLAC__SSE_TARGET("sse") | |||
| void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]) | |||
| { | |||
| __m128 xmm0, xmm2, xmm5; | |||
| (void) lag; | |||
| FLAC__ASSERT(lag > 0); | |||
| FLAC__ASSERT(lag <= 4); | |||
| FLAC__ASSERT(lag <= data_len); | |||
| FLAC__ASSERT(data_len > 0); | |||
| xmm5 = _mm_setzero_ps(); | |||
| xmm0 = _mm_load_ss(data++); | |||
| xmm2 = xmm0; | |||
| xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0); | |||
| xmm0 = _mm_mul_ps(xmm0, xmm2); | |||
| xmm5 = _mm_add_ps(xmm5, xmm0); | |||
| data_len--; | |||
| while(data_len) | |||
| { | |||
| xmm0 = _mm_load1_ps(data++); | |||
| xmm2 = _mm_shuffle_ps(xmm2, xmm2, _MM_SHUFFLE(2,1,0,3)); | |||
| xmm2 = _mm_move_ss(xmm2, xmm0); | |||
| xmm0 = _mm_mul_ps(xmm0, xmm2); | |||
| xmm5 = _mm_add_ps(xmm5, xmm0); | |||
| data_len--; | |||
| } | |||
| _mm_storeu_ps(autoc, xmm5); | |||
| } | |||
| FLAC__SSE_TARGET("sse") | |||
| void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]) | |||
| { | |||
| __m128 xmm0, xmm1, xmm2, xmm3, xmm5, xmm6; | |||
| (void) lag; | |||
| FLAC__ASSERT(lag > 0); | |||
| FLAC__ASSERT(lag <= 8); | |||
| FLAC__ASSERT(lag <= data_len); | |||
| FLAC__ASSERT(data_len > 0); | |||
| xmm5 = _mm_setzero_ps(); | |||
| xmm6 = _mm_setzero_ps(); | |||
| xmm0 = _mm_load_ss(data++); | |||
| xmm2 = xmm0; | |||
| xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0); | |||
| xmm3 = _mm_setzero_ps(); | |||
| xmm0 = _mm_mul_ps(xmm0, xmm2); | |||
| xmm5 = _mm_add_ps(xmm5, xmm0); | |||
| data_len--; | |||
| while(data_len) | |||
| { | |||
| xmm0 = _mm_load1_ps(data++); | |||
| xmm2 = _mm_shuffle_ps(xmm2, xmm2, _MM_SHUFFLE(2,1,0,3)); | |||
| xmm3 = _mm_shuffle_ps(xmm3, xmm3, _MM_SHUFFLE(2,1,0,3)); | |||
| xmm3 = _mm_move_ss(xmm3, xmm2); | |||
| xmm2 = _mm_move_ss(xmm2, xmm0); | |||
| xmm1 = xmm0; | |||
| xmm1 = _mm_mul_ps(xmm1, xmm3); | |||
| xmm0 = _mm_mul_ps(xmm0, xmm2); | |||
| xmm6 = _mm_add_ps(xmm6, xmm1); | |||
| xmm5 = _mm_add_ps(xmm5, xmm0); | |||
| data_len--; | |||
| } | |||
| _mm_storeu_ps(autoc, xmm5); | |||
| _mm_storeu_ps(autoc+4, xmm6); | |||
| } | |||
| FLAC__SSE_TARGET("sse") | |||
| void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]) | |||
| { | |||
| __m128 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7; | |||
| (void) lag; | |||
| FLAC__ASSERT(lag > 0); | |||
| FLAC__ASSERT(lag <= 12); | |||
| FLAC__ASSERT(lag <= data_len); | |||
| FLAC__ASSERT(data_len > 0); | |||
| xmm5 = _mm_setzero_ps(); | |||
| xmm6 = _mm_setzero_ps(); | |||
| xmm7 = _mm_setzero_ps(); | |||
| xmm0 = _mm_load_ss(data++); | |||
| xmm2 = xmm0; | |||
| xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0); | |||
| xmm3 = _mm_setzero_ps(); | |||
| xmm4 = _mm_setzero_ps(); | |||
| xmm0 = _mm_mul_ps(xmm0, xmm2); | |||
| xmm5 = _mm_add_ps(xmm5, xmm0); | |||
| data_len--; | |||
| while(data_len) | |||
| { | |||
| xmm0 = _mm_load1_ps(data++); | |||
| xmm2 = _mm_shuffle_ps(xmm2, xmm2, _MM_SHUFFLE(2,1,0,3)); | |||
| xmm3 = _mm_shuffle_ps(xmm3, xmm3, _MM_SHUFFLE(2,1,0,3)); | |||
| xmm4 = _mm_shuffle_ps(xmm4, xmm4, _MM_SHUFFLE(2,1,0,3)); | |||
| xmm4 = _mm_move_ss(xmm4, xmm3); | |||
| xmm3 = _mm_move_ss(xmm3, xmm2); | |||
| xmm2 = _mm_move_ss(xmm2, xmm0); | |||
| xmm1 = xmm0; | |||
| xmm1 = _mm_mul_ps(xmm1, xmm2); | |||
| xmm5 = _mm_add_ps(xmm5, xmm1); | |||
| xmm1 = xmm0; | |||
| xmm1 = _mm_mul_ps(xmm1, xmm3); | |||
| xmm6 = _mm_add_ps(xmm6, xmm1); | |||
| xmm0 = _mm_mul_ps(xmm0, xmm4); | |||
| xmm7 = _mm_add_ps(xmm7, xmm0); | |||
| data_len--; | |||
| } | |||
| _mm_storeu_ps(autoc, xmm5); | |||
| _mm_storeu_ps(autoc+4, xmm6); | |||
| _mm_storeu_ps(autoc+8, xmm7); | |||
| } | |||
| FLAC__SSE_TARGET("sse") | |||
| void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]) | |||
| { | |||
| __m128 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9; | |||
| (void) lag; | |||
| FLAC__ASSERT(lag > 0); | |||
| FLAC__ASSERT(lag <= 16); | |||
| FLAC__ASSERT(lag <= data_len); | |||
| FLAC__ASSERT(data_len > 0); | |||
| xmm6 = _mm_setzero_ps(); | |||
| xmm7 = _mm_setzero_ps(); | |||
| xmm8 = _mm_setzero_ps(); | |||
| xmm9 = _mm_setzero_ps(); | |||
| xmm0 = _mm_load_ss(data++); | |||
| xmm2 = xmm0; | |||
| xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0); | |||
| xmm3 = _mm_setzero_ps(); | |||
| xmm4 = _mm_setzero_ps(); | |||
| xmm5 = _mm_setzero_ps(); | |||
| xmm0 = _mm_mul_ps(xmm0, xmm2); | |||
| xmm6 = _mm_add_ps(xmm6, xmm0); | |||
| data_len--; | |||
| while(data_len) | |||
| { | |||
| xmm0 = _mm_load1_ps(data++); | |||
| /* shift xmm5:xmm4:xmm3:xmm2 left by one float */ | |||
| xmm5 = _mm_shuffle_ps(xmm5, xmm5, _MM_SHUFFLE(2,1,0,3)); | |||
| xmm4 = _mm_shuffle_ps(xmm4, xmm4, _MM_SHUFFLE(2,1,0,3)); | |||
| xmm3 = _mm_shuffle_ps(xmm3, xmm3, _MM_SHUFFLE(2,1,0,3)); | |||
| xmm2 = _mm_shuffle_ps(xmm2, xmm2, _MM_SHUFFLE(2,1,0,3)); | |||
| xmm5 = _mm_move_ss(xmm5, xmm4); | |||
| xmm4 = _mm_move_ss(xmm4, xmm3); | |||
| xmm3 = _mm_move_ss(xmm3, xmm2); | |||
| xmm2 = _mm_move_ss(xmm2, xmm0); | |||
| /* xmm9|xmm8|xmm7|xmm6 += xmm0|xmm0|xmm0|xmm0 * xmm5|xmm4|xmm3|xmm2 */ | |||
| xmm1 = xmm0; | |||
| xmm1 = _mm_mul_ps(xmm1, xmm5); | |||
| xmm9 = _mm_add_ps(xmm9, xmm1); | |||
| xmm1 = xmm0; | |||
| xmm1 = _mm_mul_ps(xmm1, xmm4); | |||
| xmm8 = _mm_add_ps(xmm8, xmm1); | |||
| xmm1 = xmm0; | |||
| xmm1 = _mm_mul_ps(xmm1, xmm3); | |||
| xmm7 = _mm_add_ps(xmm7, xmm1); | |||
| xmm0 = _mm_mul_ps(xmm0, xmm2); | |||
| xmm6 = _mm_add_ps(xmm6, xmm0); | |||
| data_len--; | |||
| } | |||
| _mm_storeu_ps(autoc, xmm6); | |||
| _mm_storeu_ps(autoc+4, xmm7); | |||
| _mm_storeu_ps(autoc+8, xmm8); | |||
| _mm_storeu_ps(autoc+12,xmm9); | |||
| } | |||
| #endif /* FLAC__SSE_SUPPORTED */ | |||
| #endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */ | |||
| #endif /* FLAC__NO_ASM */ | |||
| #endif /* FLAC__INTEGER_ONLY_LIBRARY */ | |||
| @@ -0,0 +1,937 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include "include/private/cpu.h" | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| #ifndef FLAC__NO_ASM | |||
| #if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN | |||
| #include "include/private/lpc.h" | |||
| #ifdef FLAC__SSE2_SUPPORTED | |||
| #include "../assert.h" | |||
| #include "../format.h" | |||
| #include <emmintrin.h> /* SSE2 */ | |||
| #define RESIDUAL32_RESULT(xmmN) residual[i] = data[i] - (_mm_cvtsi128_si32(xmmN) >> lp_quantization); | |||
| #define DATA32_RESULT(xmmN) data[i] = residual[i] + (_mm_cvtsi128_si32(xmmN) >> lp_quantization); | |||
| FLAC__SSE_TARGET("sse2") | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]) | |||
| { | |||
| int i; | |||
| FLAC__int32 sum; | |||
| const __m128i cnt = _mm_cvtsi32_si128(lp_quantization); | |||
| FLAC__ASSERT(order > 0); | |||
| FLAC__ASSERT(order <= 32); | |||
| if(order <= 12) { | |||
| if(order > 8) { | |||
| if(order > 10) { | |||
| if(order == 12) { | |||
| __m128i q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11; | |||
| q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); | |||
| q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); | |||
| q2 = _mm_cvtsi32_si128(0xffff & qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); | |||
| q3 = _mm_cvtsi32_si128(0xffff & qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); | |||
| q4 = _mm_cvtsi32_si128(0xffff & qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); | |||
| q5 = _mm_cvtsi32_si128(0xffff & qlp_coeff[5]); q5 = _mm_shuffle_epi32(q5, _MM_SHUFFLE(0,0,0,0)); | |||
| q6 = _mm_cvtsi32_si128(0xffff & qlp_coeff[6]); q6 = _mm_shuffle_epi32(q6, _MM_SHUFFLE(0,0,0,0)); | |||
| q7 = _mm_cvtsi32_si128(0xffff & qlp_coeff[7]); q7 = _mm_shuffle_epi32(q7, _MM_SHUFFLE(0,0,0,0)); | |||
| q8 = _mm_cvtsi32_si128(0xffff & qlp_coeff[8]); q8 = _mm_shuffle_epi32(q8, _MM_SHUFFLE(0,0,0,0)); | |||
| q9 = _mm_cvtsi32_si128(0xffff & qlp_coeff[9]); q9 = _mm_shuffle_epi32(q9, _MM_SHUFFLE(0,0,0,0)); | |||
| q10 = _mm_cvtsi32_si128(0xffff & qlp_coeff[10]); q10 = _mm_shuffle_epi32(q10, _MM_SHUFFLE(0,0,0,0)); | |||
| q11 = _mm_cvtsi32_si128(0xffff & qlp_coeff[11]); q11 = _mm_shuffle_epi32(q11, _MM_SHUFFLE(0,0,0,0)); | |||
| for(i = 0; i < (int)data_len-3; i+=4) { | |||
| __m128i summ, mull; | |||
| summ = _mm_madd_epi16(q11, _mm_loadu_si128((const __m128i*)(data+i-12))); | |||
| mull = _mm_madd_epi16(q10, _mm_loadu_si128((const __m128i*)(data+i-11))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q9, _mm_loadu_si128((const __m128i*)(data+i-10))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q8, _mm_loadu_si128((const __m128i*)(data+i-9))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q7, _mm_loadu_si128((const __m128i*)(data+i-8))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q6, _mm_loadu_si128((const __m128i*)(data+i-7))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q5, _mm_loadu_si128((const __m128i*)(data+i-6))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); | |||
| summ = _mm_sra_epi32(summ, cnt); | |||
| _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); | |||
| } | |||
| } | |||
| else { /* order == 11 */ | |||
| __m128i q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10; | |||
| q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); | |||
| q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); | |||
| q2 = _mm_cvtsi32_si128(0xffff & qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); | |||
| q3 = _mm_cvtsi32_si128(0xffff & qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); | |||
| q4 = _mm_cvtsi32_si128(0xffff & qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); | |||
| q5 = _mm_cvtsi32_si128(0xffff & qlp_coeff[5]); q5 = _mm_shuffle_epi32(q5, _MM_SHUFFLE(0,0,0,0)); | |||
| q6 = _mm_cvtsi32_si128(0xffff & qlp_coeff[6]); q6 = _mm_shuffle_epi32(q6, _MM_SHUFFLE(0,0,0,0)); | |||
| q7 = _mm_cvtsi32_si128(0xffff & qlp_coeff[7]); q7 = _mm_shuffle_epi32(q7, _MM_SHUFFLE(0,0,0,0)); | |||
| q8 = _mm_cvtsi32_si128(0xffff & qlp_coeff[8]); q8 = _mm_shuffle_epi32(q8, _MM_SHUFFLE(0,0,0,0)); | |||
| q9 = _mm_cvtsi32_si128(0xffff & qlp_coeff[9]); q9 = _mm_shuffle_epi32(q9, _MM_SHUFFLE(0,0,0,0)); | |||
| q10 = _mm_cvtsi32_si128(0xffff & qlp_coeff[10]); q10 = _mm_shuffle_epi32(q10, _MM_SHUFFLE(0,0,0,0)); | |||
| for(i = 0; i < (int)data_len-3; i+=4) { | |||
| __m128i summ, mull; | |||
| summ = _mm_madd_epi16(q10, _mm_loadu_si128((const __m128i*)(data+i-11))); | |||
| mull = _mm_madd_epi16(q9, _mm_loadu_si128((const __m128i*)(data+i-10))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q8, _mm_loadu_si128((const __m128i*)(data+i-9))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q7, _mm_loadu_si128((const __m128i*)(data+i-8))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q6, _mm_loadu_si128((const __m128i*)(data+i-7))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q5, _mm_loadu_si128((const __m128i*)(data+i-6))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); | |||
| summ = _mm_sra_epi32(summ, cnt); | |||
| _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); | |||
| } | |||
| } | |||
| } | |||
| else { | |||
| if(order == 10) { | |||
| __m128i q0, q1, q2, q3, q4, q5, q6, q7, q8, q9; | |||
| q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); | |||
| q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); | |||
| q2 = _mm_cvtsi32_si128(0xffff & qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); | |||
| q3 = _mm_cvtsi32_si128(0xffff & qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); | |||
| q4 = _mm_cvtsi32_si128(0xffff & qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); | |||
| q5 = _mm_cvtsi32_si128(0xffff & qlp_coeff[5]); q5 = _mm_shuffle_epi32(q5, _MM_SHUFFLE(0,0,0,0)); | |||
| q6 = _mm_cvtsi32_si128(0xffff & qlp_coeff[6]); q6 = _mm_shuffle_epi32(q6, _MM_SHUFFLE(0,0,0,0)); | |||
| q7 = _mm_cvtsi32_si128(0xffff & qlp_coeff[7]); q7 = _mm_shuffle_epi32(q7, _MM_SHUFFLE(0,0,0,0)); | |||
| q8 = _mm_cvtsi32_si128(0xffff & qlp_coeff[8]); q8 = _mm_shuffle_epi32(q8, _MM_SHUFFLE(0,0,0,0)); | |||
| q9 = _mm_cvtsi32_si128(0xffff & qlp_coeff[9]); q9 = _mm_shuffle_epi32(q9, _MM_SHUFFLE(0,0,0,0)); | |||
| for(i = 0; i < (int)data_len-3; i+=4) { | |||
| __m128i summ, mull; | |||
| summ = _mm_madd_epi16(q9, _mm_loadu_si128((const __m128i*)(data+i-10))); | |||
| mull = _mm_madd_epi16(q8, _mm_loadu_si128((const __m128i*)(data+i-9))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q7, _mm_loadu_si128((const __m128i*)(data+i-8))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q6, _mm_loadu_si128((const __m128i*)(data+i-7))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q5, _mm_loadu_si128((const __m128i*)(data+i-6))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); | |||
| summ = _mm_sra_epi32(summ, cnt); | |||
| _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); | |||
| } | |||
| } | |||
| else { /* order == 9 */ | |||
| __m128i q0, q1, q2, q3, q4, q5, q6, q7, q8; | |||
| q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); | |||
| q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); | |||
| q2 = _mm_cvtsi32_si128(0xffff & qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); | |||
| q3 = _mm_cvtsi32_si128(0xffff & qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); | |||
| q4 = _mm_cvtsi32_si128(0xffff & qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); | |||
| q5 = _mm_cvtsi32_si128(0xffff & qlp_coeff[5]); q5 = _mm_shuffle_epi32(q5, _MM_SHUFFLE(0,0,0,0)); | |||
| q6 = _mm_cvtsi32_si128(0xffff & qlp_coeff[6]); q6 = _mm_shuffle_epi32(q6, _MM_SHUFFLE(0,0,0,0)); | |||
| q7 = _mm_cvtsi32_si128(0xffff & qlp_coeff[7]); q7 = _mm_shuffle_epi32(q7, _MM_SHUFFLE(0,0,0,0)); | |||
| q8 = _mm_cvtsi32_si128(0xffff & qlp_coeff[8]); q8 = _mm_shuffle_epi32(q8, _MM_SHUFFLE(0,0,0,0)); | |||
| for(i = 0; i < (int)data_len-3; i+=4) { | |||
| __m128i summ, mull; | |||
| summ = _mm_madd_epi16(q8, _mm_loadu_si128((const __m128i*)(data+i-9))); | |||
| mull = _mm_madd_epi16(q7, _mm_loadu_si128((const __m128i*)(data+i-8))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q6, _mm_loadu_si128((const __m128i*)(data+i-7))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q5, _mm_loadu_si128((const __m128i*)(data+i-6))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); | |||
| summ = _mm_sra_epi32(summ, cnt); | |||
| _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| else if(order > 4) { | |||
| if(order > 6) { | |||
| if(order == 8) { | |||
| __m128i q0, q1, q2, q3, q4, q5, q6, q7; | |||
| q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); | |||
| q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); | |||
| q2 = _mm_cvtsi32_si128(0xffff & qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); | |||
| q3 = _mm_cvtsi32_si128(0xffff & qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); | |||
| q4 = _mm_cvtsi32_si128(0xffff & qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); | |||
| q5 = _mm_cvtsi32_si128(0xffff & qlp_coeff[5]); q5 = _mm_shuffle_epi32(q5, _MM_SHUFFLE(0,0,0,0)); | |||
| q6 = _mm_cvtsi32_si128(0xffff & qlp_coeff[6]); q6 = _mm_shuffle_epi32(q6, _MM_SHUFFLE(0,0,0,0)); | |||
| q7 = _mm_cvtsi32_si128(0xffff & qlp_coeff[7]); q7 = _mm_shuffle_epi32(q7, _MM_SHUFFLE(0,0,0,0)); | |||
| for(i = 0; i < (int)data_len-3; i+=4) { | |||
| __m128i summ, mull; | |||
| summ = _mm_madd_epi16(q7, _mm_loadu_si128((const __m128i*)(data+i-8))); | |||
| mull = _mm_madd_epi16(q6, _mm_loadu_si128((const __m128i*)(data+i-7))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q5, _mm_loadu_si128((const __m128i*)(data+i-6))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); | |||
| summ = _mm_sra_epi32(summ, cnt); | |||
| _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); | |||
| } | |||
| } | |||
| else { /* order == 7 */ | |||
| __m128i q0, q1, q2, q3, q4, q5, q6; | |||
| q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); | |||
| q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); | |||
| q2 = _mm_cvtsi32_si128(0xffff & qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); | |||
| q3 = _mm_cvtsi32_si128(0xffff & qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); | |||
| q4 = _mm_cvtsi32_si128(0xffff & qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); | |||
| q5 = _mm_cvtsi32_si128(0xffff & qlp_coeff[5]); q5 = _mm_shuffle_epi32(q5, _MM_SHUFFLE(0,0,0,0)); | |||
| q6 = _mm_cvtsi32_si128(0xffff & qlp_coeff[6]); q6 = _mm_shuffle_epi32(q6, _MM_SHUFFLE(0,0,0,0)); | |||
| for(i = 0; i < (int)data_len-3; i+=4) { | |||
| __m128i summ, mull; | |||
| summ = _mm_madd_epi16(q6, _mm_loadu_si128((const __m128i*)(data+i-7))); | |||
| mull = _mm_madd_epi16(q5, _mm_loadu_si128((const __m128i*)(data+i-6))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); | |||
| summ = _mm_sra_epi32(summ, cnt); | |||
| _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); | |||
| } | |||
| } | |||
| } | |||
| else { | |||
| if(order == 6) { | |||
| __m128i q0, q1, q2, q3, q4, q5; | |||
| q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); | |||
| q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); | |||
| q2 = _mm_cvtsi32_si128(0xffff & qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); | |||
| q3 = _mm_cvtsi32_si128(0xffff & qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); | |||
| q4 = _mm_cvtsi32_si128(0xffff & qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); | |||
| q5 = _mm_cvtsi32_si128(0xffff & qlp_coeff[5]); q5 = _mm_shuffle_epi32(q5, _MM_SHUFFLE(0,0,0,0)); | |||
| for(i = 0; i < (int)data_len-3; i+=4) { | |||
| __m128i summ, mull; | |||
| summ = _mm_madd_epi16(q5, _mm_loadu_si128((const __m128i*)(data+i-6))); | |||
| mull = _mm_madd_epi16(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); | |||
| summ = _mm_sra_epi32(summ, cnt); | |||
| _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); | |||
| } | |||
| } | |||
| else { /* order == 5 */ | |||
| __m128i q0, q1, q2, q3, q4; | |||
| q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); | |||
| q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); | |||
| q2 = _mm_cvtsi32_si128(0xffff & qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); | |||
| q3 = _mm_cvtsi32_si128(0xffff & qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); | |||
| q4 = _mm_cvtsi32_si128(0xffff & qlp_coeff[4]); q4 = _mm_shuffle_epi32(q4, _MM_SHUFFLE(0,0,0,0)); | |||
| for(i = 0; i < (int)data_len-3; i+=4) { | |||
| __m128i summ, mull; | |||
| summ = _mm_madd_epi16(q4, _mm_loadu_si128((const __m128i*)(data+i-5))); | |||
| mull = _mm_madd_epi16(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); | |||
| summ = _mm_sra_epi32(summ, cnt); | |||
| _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| else { | |||
| if(order > 2) { | |||
| if(order == 4) { | |||
| __m128i q0, q1, q2, q3; | |||
| q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); | |||
| q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); | |||
| q2 = _mm_cvtsi32_si128(0xffff & qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); | |||
| q3 = _mm_cvtsi32_si128(0xffff & qlp_coeff[3]); q3 = _mm_shuffle_epi32(q3, _MM_SHUFFLE(0,0,0,0)); | |||
| for(i = 0; i < (int)data_len-3; i+=4) { | |||
| __m128i summ, mull; | |||
| summ = _mm_madd_epi16(q3, _mm_loadu_si128((const __m128i*)(data+i-4))); | |||
| mull = _mm_madd_epi16(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); | |||
| summ = _mm_sra_epi32(summ, cnt); | |||
| _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); | |||
| } | |||
| } | |||
| else { /* order == 3 */ | |||
| __m128i q0, q1, q2; | |||
| q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); | |||
| q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); | |||
| q2 = _mm_cvtsi32_si128(0xffff & qlp_coeff[2]); q2 = _mm_shuffle_epi32(q2, _MM_SHUFFLE(0,0,0,0)); | |||
| for(i = 0; i < (int)data_len-3; i+=4) { | |||
| __m128i summ, mull; | |||
| summ = _mm_madd_epi16(q2, _mm_loadu_si128((const __m128i*)(data+i-3))); | |||
| mull = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); summ = _mm_add_epi32(summ, mull); | |||
| mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); | |||
| summ = _mm_sra_epi32(summ, cnt); | |||
| _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); | |||
| } | |||
| } | |||
| } | |||
| else { | |||
| if(order == 2) { | |||
| __m128i q0, q1; | |||
| q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); | |||
| q1 = _mm_cvtsi32_si128(0xffff & qlp_coeff[1]); q1 = _mm_shuffle_epi32(q1, _MM_SHUFFLE(0,0,0,0)); | |||
| for(i = 0; i < (int)data_len-3; i+=4) { | |||
| __m128i summ, mull; | |||
| summ = _mm_madd_epi16(q1, _mm_loadu_si128((const __m128i*)(data+i-2))); | |||
| mull = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); summ = _mm_add_epi32(summ, mull); | |||
| summ = _mm_sra_epi32(summ, cnt); | |||
| _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); | |||
| } | |||
| } | |||
| else { /* order == 1 */ | |||
| __m128i q0; | |||
| q0 = _mm_cvtsi32_si128(0xffff & qlp_coeff[0]); q0 = _mm_shuffle_epi32(q0, _MM_SHUFFLE(0,0,0,0)); | |||
| for(i = 0; i < (int)data_len-3; i+=4) { | |||
| __m128i summ; | |||
| summ = _mm_madd_epi16(q0, _mm_loadu_si128((const __m128i*)(data+i-1))); | |||
| summ = _mm_sra_epi32(summ, cnt); | |||
| _mm_storeu_si128((__m128i*)(residual+i), _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(data+i)), summ)); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| for(; i < (int)data_len; i++) { | |||
| sum = 0; | |||
| switch(order) { | |||
| case 12: sum += qlp_coeff[11] * data[i-12]; /* Falls through. */ | |||
| case 11: sum += qlp_coeff[10] * data[i-11]; /* Falls through. */ | |||
| case 10: sum += qlp_coeff[ 9] * data[i-10]; /* Falls through. */ | |||
| case 9: sum += qlp_coeff[ 8] * data[i- 9]; /* Falls through. */ | |||
| case 8: sum += qlp_coeff[ 7] * data[i- 8]; /* Falls through. */ | |||
| case 7: sum += qlp_coeff[ 6] * data[i- 7]; /* Falls through. */ | |||
| case 6: sum += qlp_coeff[ 5] * data[i- 6]; /* Falls through. */ | |||
| case 5: sum += qlp_coeff[ 4] * data[i- 5]; /* Falls through. */ | |||
| case 4: sum += qlp_coeff[ 3] * data[i- 4]; /* Falls through. */ | |||
| case 3: sum += qlp_coeff[ 2] * data[i- 3]; /* Falls through. */ | |||
| case 2: sum += qlp_coeff[ 1] * data[i- 2]; /* Falls through. */ | |||
| case 1: sum += qlp_coeff[ 0] * data[i- 1]; | |||
| } | |||
| residual[i] = data[i] - (sum >> lp_quantization); | |||
| } | |||
| } | |||
| else { /* order > 12 */ | |||
| for(i = 0; i < (int)data_len; i++) { | |||
| sum = 0; | |||
| switch(order) { | |||
| case 32: sum += qlp_coeff[31] * data[i-32]; /* Falls through. */ | |||
| case 31: sum += qlp_coeff[30] * data[i-31]; /* Falls through. */ | |||
| case 30: sum += qlp_coeff[29] * data[i-30]; /* Falls through. */ | |||
| case 29: sum += qlp_coeff[28] * data[i-29]; /* Falls through. */ | |||
| case 28: sum += qlp_coeff[27] * data[i-28]; /* Falls through. */ | |||
| case 27: sum += qlp_coeff[26] * data[i-27]; /* Falls through. */ | |||
| case 26: sum += qlp_coeff[25] * data[i-26]; /* Falls through. */ | |||
| case 25: sum += qlp_coeff[24] * data[i-25]; /* Falls through. */ | |||
| case 24: sum += qlp_coeff[23] * data[i-24]; /* Falls through. */ | |||
| case 23: sum += qlp_coeff[22] * data[i-23]; /* Falls through. */ | |||
| case 22: sum += qlp_coeff[21] * data[i-22]; /* Falls through. */ | |||
| case 21: sum += qlp_coeff[20] * data[i-21]; /* Falls through. */ | |||
| case 20: sum += qlp_coeff[19] * data[i-20]; /* Falls through. */ | |||
| case 19: sum += qlp_coeff[18] * data[i-19]; /* Falls through. */ | |||
| case 18: sum += qlp_coeff[17] * data[i-18]; /* Falls through. */ | |||
| case 17: sum += qlp_coeff[16] * data[i-17]; /* Falls through. */ | |||
| case 16: sum += qlp_coeff[15] * data[i-16]; /* Falls through. */ | |||
| case 15: sum += qlp_coeff[14] * data[i-15]; /* Falls through. */ | |||
| case 14: sum += qlp_coeff[13] * data[i-14]; /* Falls through. */ | |||
| case 13: sum += qlp_coeff[12] * data[i-13]; | |||
| sum += qlp_coeff[11] * data[i-12]; | |||
| sum += qlp_coeff[10] * data[i-11]; | |||
| sum += qlp_coeff[ 9] * data[i-10]; | |||
| sum += qlp_coeff[ 8] * data[i- 9]; | |||
| sum += qlp_coeff[ 7] * data[i- 8]; | |||
| sum += qlp_coeff[ 6] * data[i- 7]; | |||
| sum += qlp_coeff[ 5] * data[i- 6]; | |||
| sum += qlp_coeff[ 4] * data[i- 5]; | |||
| sum += qlp_coeff[ 3] * data[i- 4]; | |||
| sum += qlp_coeff[ 2] * data[i- 3]; | |||
| sum += qlp_coeff[ 1] * data[i- 2]; | |||
| sum += qlp_coeff[ 0] * data[i- 1]; | |||
| } | |||
| residual[i] = data[i] - (sum >> lp_quantization); | |||
| } | |||
| } | |||
| } | |||
| FLAC__SSE_TARGET("sse2") | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse2(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]) | |||
| { | |||
| int i; | |||
| FLAC__ASSERT(order > 0); | |||
| FLAC__ASSERT(order <= 32); | |||
| if(order <= 12) { | |||
| if(order > 8) { /* order == 9, 10, 11, 12 */ | |||
| if(order > 10) { /* order == 11, 12 */ | |||
| if(order == 12) { | |||
| __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7; | |||
| xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); // 0 0 q[1] q[0] | |||
| xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); // 0 0 q[3] q[2] | |||
| xmm2 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); // 0 0 q[5] q[4] | |||
| xmm3 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+6)); // 0 0 q[7] q[6] | |||
| xmm4 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+8)); // 0 0 q[9] q[8] | |||
| xmm5 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+10)); // 0 0 q[11] q[10] | |||
| xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); // 0 q[1] 0 q[0] | |||
| xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); // 0 q[3] 0 q[2] | |||
| xmm2 = _mm_shuffle_epi32(xmm2, _MM_SHUFFLE(3,1,2,0)); // 0 q[5] 0 q[4] | |||
| xmm3 = _mm_shuffle_epi32(xmm3, _MM_SHUFFLE(3,1,2,0)); // 0 q[7] 0 q[6] | |||
| xmm4 = _mm_shuffle_epi32(xmm4, _MM_SHUFFLE(3,1,2,0)); // 0 q[9] 0 q[8] | |||
| xmm5 = _mm_shuffle_epi32(xmm5, _MM_SHUFFLE(3,1,2,0)); // 0 q[11] 0 q[10] | |||
| for(i = 0; i < (int)data_len; i++) { | |||
| //sum = 0; | |||
| //sum += qlp_coeff[11] * data[i-12]; | |||
| //sum += qlp_coeff[10] * data[i-11]; | |||
| xmm7 = _mm_loadl_epi64((const __m128i*)(data+i-12)); // 0 0 d[i-11] d[i-12] | |||
| xmm7 = _mm_shuffle_epi32(xmm7, _MM_SHUFFLE(2,0,3,1)); // 0 d[i-12] 0 d[i-11] | |||
| xmm7 = _mm_mul_epu32(xmm7, xmm5); /* we use _unsigned_ multiplication and discard high dword of the result values */ | |||
| //sum += qlp_coeff[9] * data[i-10]; | |||
| //sum += qlp_coeff[8] * data[i-9]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-10)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm4); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| //sum += qlp_coeff[7] * data[i-8]; | |||
| //sum += qlp_coeff[6] * data[i-7]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-8)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm3); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| //sum += qlp_coeff[5] * data[i-6]; | |||
| //sum += qlp_coeff[4] * data[i-5]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-6)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm2); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| //sum += qlp_coeff[3] * data[i-4]; | |||
| //sum += qlp_coeff[2] * data[i-3]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm1); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| //sum += qlp_coeff[1] * data[i-2]; | |||
| //sum += qlp_coeff[0] * data[i-1]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm0); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); | |||
| RESIDUAL32_RESULT(xmm7); | |||
| } | |||
| } | |||
| else { /* order == 11 */ | |||
| __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7; | |||
| xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); | |||
| xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); | |||
| xmm2 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); | |||
| xmm3 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+6)); | |||
| xmm4 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+8)); | |||
| xmm5 = _mm_cvtsi32_si128(qlp_coeff[10]); | |||
| xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); | |||
| xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); | |||
| xmm2 = _mm_shuffle_epi32(xmm2, _MM_SHUFFLE(3,1,2,0)); | |||
| xmm3 = _mm_shuffle_epi32(xmm3, _MM_SHUFFLE(3,1,2,0)); | |||
| xmm4 = _mm_shuffle_epi32(xmm4, _MM_SHUFFLE(3,1,2,0)); | |||
| for(i = 0; i < (int)data_len; i++) { | |||
| //sum = 0; | |||
| //sum = qlp_coeff[10] * data[i-11]; | |||
| xmm7 = _mm_cvtsi32_si128(data[i-11]); | |||
| xmm7 = _mm_mul_epu32(xmm7, xmm5); | |||
| //sum += qlp_coeff[9] * data[i-10]; | |||
| //sum += qlp_coeff[8] * data[i-9]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-10)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm4); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| //sum += qlp_coeff[7] * data[i-8]; | |||
| //sum += qlp_coeff[6] * data[i-7]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-8)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm3); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| //sum += qlp_coeff[5] * data[i-6]; | |||
| //sum += qlp_coeff[4] * data[i-5]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-6)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm2); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| //sum += qlp_coeff[3] * data[i-4]; | |||
| //sum += qlp_coeff[2] * data[i-3]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm1); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| //sum += qlp_coeff[1] * data[i-2]; | |||
| //sum += qlp_coeff[0] * data[i-1]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm0); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); | |||
| RESIDUAL32_RESULT(xmm7); | |||
| } | |||
| } | |||
| } | |||
| else { /* order == 9, 10 */ | |||
| if(order == 10) { | |||
| __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm6, xmm7; | |||
| xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); | |||
| xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); | |||
| xmm2 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); | |||
| xmm3 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+6)); | |||
| xmm4 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+8)); | |||
| xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); | |||
| xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); | |||
| xmm2 = _mm_shuffle_epi32(xmm2, _MM_SHUFFLE(3,1,2,0)); | |||
| xmm3 = _mm_shuffle_epi32(xmm3, _MM_SHUFFLE(3,1,2,0)); | |||
| xmm4 = _mm_shuffle_epi32(xmm4, _MM_SHUFFLE(3,1,2,0)); | |||
| for(i = 0; i < (int)data_len; i++) { | |||
| //sum = 0; | |||
| //sum += qlp_coeff[9] * data[i-10]; | |||
| //sum += qlp_coeff[8] * data[i-9]; | |||
| xmm7 = _mm_loadl_epi64((const __m128i*)(data+i-10)); | |||
| xmm7 = _mm_shuffle_epi32(xmm7, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm7 = _mm_mul_epu32(xmm7, xmm4); | |||
| //sum += qlp_coeff[7] * data[i-8]; | |||
| //sum += qlp_coeff[6] * data[i-7]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-8)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm3); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| //sum += qlp_coeff[5] * data[i-6]; | |||
| //sum += qlp_coeff[4] * data[i-5]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-6)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm2); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| //sum += qlp_coeff[3] * data[i-4]; | |||
| //sum += qlp_coeff[2] * data[i-3]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm1); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| //sum += qlp_coeff[1] * data[i-2]; | |||
| //sum += qlp_coeff[0] * data[i-1]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm0); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); | |||
| RESIDUAL32_RESULT(xmm7); | |||
| } | |||
| } | |||
| else { /* order == 9 */ | |||
| __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm6, xmm7; | |||
| xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); | |||
| xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); | |||
| xmm2 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); | |||
| xmm3 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+6)); | |||
| xmm4 = _mm_cvtsi32_si128(qlp_coeff[8]); | |||
| xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); | |||
| xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); | |||
| xmm2 = _mm_shuffle_epi32(xmm2, _MM_SHUFFLE(3,1,2,0)); | |||
| xmm3 = _mm_shuffle_epi32(xmm3, _MM_SHUFFLE(3,1,2,0)); | |||
| for(i = 0; i < (int)data_len; i++) { | |||
| //sum = 0; | |||
| //sum = qlp_coeff[8] * data[i-9]; | |||
| xmm7 = _mm_cvtsi32_si128(data[i-9]); | |||
| xmm7 = _mm_mul_epu32(xmm7, xmm4); | |||
| //sum += qlp_coeff[7] * data[i-8]; | |||
| //sum += qlp_coeff[6] * data[i-7]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-8)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm3); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| //sum += qlp_coeff[5] * data[i-6]; | |||
| //sum += qlp_coeff[4] * data[i-5]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-6)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm2); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| //sum += qlp_coeff[3] * data[i-4]; | |||
| //sum += qlp_coeff[2] * data[i-3]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm1); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| //sum += qlp_coeff[1] * data[i-2]; | |||
| //sum += qlp_coeff[0] * data[i-1]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm0); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); | |||
| RESIDUAL32_RESULT(xmm7); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| else if(order > 4) { /* order == 5, 6, 7, 8 */ | |||
| if(order > 6) { /* order == 7, 8 */ | |||
| if(order == 8) { | |||
| __m128i xmm0, xmm1, xmm2, xmm3, xmm6, xmm7; | |||
| xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); | |||
| xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); | |||
| xmm2 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); | |||
| xmm3 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+6)); | |||
| xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); | |||
| xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); | |||
| xmm2 = _mm_shuffle_epi32(xmm2, _MM_SHUFFLE(3,1,2,0)); | |||
| xmm3 = _mm_shuffle_epi32(xmm3, _MM_SHUFFLE(3,1,2,0)); | |||
| for(i = 0; i < (int)data_len; i++) { | |||
| //sum = 0; | |||
| //sum += qlp_coeff[7] * data[i-8]; | |||
| //sum += qlp_coeff[6] * data[i-7]; | |||
| xmm7 = _mm_loadl_epi64((const __m128i*)(data+i-8)); | |||
| xmm7 = _mm_shuffle_epi32(xmm7, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm7 = _mm_mul_epu32(xmm7, xmm3); | |||
| //sum += qlp_coeff[5] * data[i-6]; | |||
| //sum += qlp_coeff[4] * data[i-5]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-6)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm2); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| //sum += qlp_coeff[3] * data[i-4]; | |||
| //sum += qlp_coeff[2] * data[i-3]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm1); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| //sum += qlp_coeff[1] * data[i-2]; | |||
| //sum += qlp_coeff[0] * data[i-1]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm0); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); | |||
| RESIDUAL32_RESULT(xmm7); | |||
| } | |||
| } | |||
| else { /* order == 7 */ | |||
| __m128i xmm0, xmm1, xmm2, xmm3, xmm6, xmm7; | |||
| xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); | |||
| xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); | |||
| xmm2 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); | |||
| xmm3 = _mm_cvtsi32_si128(qlp_coeff[6]); | |||
| xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); | |||
| xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); | |||
| xmm2 = _mm_shuffle_epi32(xmm2, _MM_SHUFFLE(3,1,2,0)); | |||
| for(i = 0; i < (int)data_len; i++) { | |||
| //sum = 0; | |||
| //sum = qlp_coeff[6] * data[i-7]; | |||
| xmm7 = _mm_cvtsi32_si128(data[i-7]); | |||
| xmm7 = _mm_mul_epu32(xmm7, xmm3); | |||
| //sum += qlp_coeff[5] * data[i-6]; | |||
| //sum += qlp_coeff[4] * data[i-5]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-6)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm2); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| //sum += qlp_coeff[3] * data[i-4]; | |||
| //sum += qlp_coeff[2] * data[i-3]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm1); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| //sum += qlp_coeff[1] * data[i-2]; | |||
| //sum += qlp_coeff[0] * data[i-1]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm0); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); | |||
| RESIDUAL32_RESULT(xmm7); | |||
| } | |||
| } | |||
| } | |||
| else { /* order == 5, 6 */ | |||
| if(order == 6) { | |||
| __m128i xmm0, xmm1, xmm2, xmm6, xmm7; | |||
| xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); | |||
| xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); | |||
| xmm2 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+4)); | |||
| xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); | |||
| xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); | |||
| xmm2 = _mm_shuffle_epi32(xmm2, _MM_SHUFFLE(3,1,2,0)); | |||
| for(i = 0; i < (int)data_len; i++) { | |||
| //sum = 0; | |||
| //sum += qlp_coeff[5] * data[i-6]; | |||
| //sum += qlp_coeff[4] * data[i-5]; | |||
| xmm7 = _mm_loadl_epi64((const __m128i*)(data+i-6)); | |||
| xmm7 = _mm_shuffle_epi32(xmm7, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm7 = _mm_mul_epu32(xmm7, xmm2); | |||
| //sum += qlp_coeff[3] * data[i-4]; | |||
| //sum += qlp_coeff[2] * data[i-3]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm1); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| //sum += qlp_coeff[1] * data[i-2]; | |||
| //sum += qlp_coeff[0] * data[i-1]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm0); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); | |||
| RESIDUAL32_RESULT(xmm7); | |||
| } | |||
| } | |||
| else { /* order == 5 */ | |||
| __m128i xmm0, xmm1, xmm2, xmm6, xmm7; | |||
| xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); | |||
| xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); | |||
| xmm2 = _mm_cvtsi32_si128(qlp_coeff[4]); | |||
| xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); | |||
| xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); | |||
| for(i = 0; i < (int)data_len; i++) { | |||
| //sum = 0; | |||
| //sum = qlp_coeff[4] * data[i-5]; | |||
| xmm7 = _mm_cvtsi32_si128(data[i-5]); | |||
| xmm7 = _mm_mul_epu32(xmm7, xmm2); | |||
| //sum += qlp_coeff[3] * data[i-4]; | |||
| //sum += qlp_coeff[2] * data[i-3]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-4)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm1); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| //sum += qlp_coeff[1] * data[i-2]; | |||
| //sum += qlp_coeff[0] * data[i-1]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm0); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); | |||
| RESIDUAL32_RESULT(xmm7); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| else { /* order == 1, 2, 3, 4 */ | |||
| if(order > 2) { /* order == 3, 4 */ | |||
| if(order == 4) { | |||
| __m128i xmm0, xmm1, xmm6, xmm7; | |||
| xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); | |||
| xmm1 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+2)); | |||
| xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); | |||
| xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0)); | |||
| for(i = 0; i < (int)data_len; i++) { | |||
| //sum = 0; | |||
| //sum += qlp_coeff[3] * data[i-4]; | |||
| //sum += qlp_coeff[2] * data[i-3]; | |||
| xmm7 = _mm_loadl_epi64((const __m128i*)(data+i-4)); | |||
| xmm7 = _mm_shuffle_epi32(xmm7, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm7 = _mm_mul_epu32(xmm7, xmm1); | |||
| //sum += qlp_coeff[1] * data[i-2]; | |||
| //sum += qlp_coeff[0] * data[i-1]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm0); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); | |||
| RESIDUAL32_RESULT(xmm7); | |||
| } | |||
| } | |||
| else { /* order == 3 */ | |||
| __m128i xmm0, xmm1, xmm6, xmm7; | |||
| xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); | |||
| xmm1 = _mm_cvtsi32_si128(qlp_coeff[2]); | |||
| xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); | |||
| for(i = 0; i < (int)data_len; i++) { | |||
| //sum = 0; | |||
| //sum = qlp_coeff[2] * data[i-3]; | |||
| xmm7 = _mm_cvtsi32_si128(data[i-3]); | |||
| xmm7 = _mm_mul_epu32(xmm7, xmm1); | |||
| //sum += qlp_coeff[1] * data[i-2]; | |||
| //sum += qlp_coeff[0] * data[i-1]; | |||
| xmm6 = _mm_loadl_epi64((const __m128i*)(data+i-2)); | |||
| xmm6 = _mm_shuffle_epi32(xmm6, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm6 = _mm_mul_epu32(xmm6, xmm0); | |||
| xmm7 = _mm_add_epi32(xmm7, xmm6); | |||
| xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); | |||
| RESIDUAL32_RESULT(xmm7); | |||
| } | |||
| } | |||
| } | |||
| else { /* order == 1, 2 */ | |||
| if(order == 2) { | |||
| __m128i xmm0, xmm7; | |||
| xmm0 = _mm_loadl_epi64((const __m128i*)(qlp_coeff+0)); | |||
| xmm0 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(3,1,2,0)); | |||
| for(i = 0; i < (int)data_len; i++) { | |||
| //sum = 0; | |||
| //sum += qlp_coeff[1] * data[i-2]; | |||
| //sum += qlp_coeff[0] * data[i-1]; | |||
| xmm7 = _mm_loadl_epi64((const __m128i*)(data+i-2)); | |||
| xmm7 = _mm_shuffle_epi32(xmm7, _MM_SHUFFLE(2,0,3,1)); | |||
| xmm7 = _mm_mul_epu32(xmm7, xmm0); | |||
| xmm7 = _mm_add_epi32(xmm7, _mm_srli_si128(xmm7, 8)); | |||
| RESIDUAL32_RESULT(xmm7); | |||
| } | |||
| } | |||
| else { /* order == 1 */ | |||
| for(i = 0; i < (int)data_len; i++) | |||
| residual[i] = data[i] - ((qlp_coeff[0] * data[i-1]) >> lp_quantization); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| else { /* order > 12 */ | |||
| FLAC__int32 sum; | |||
| for(i = 0; i < (int)data_len; i++) { | |||
| sum = 0; | |||
| switch(order) { | |||
| case 32: sum += qlp_coeff[31] * data[i-32]; /* Falls through. */ | |||
| case 31: sum += qlp_coeff[30] * data[i-31]; /* Falls through. */ | |||
| case 30: sum += qlp_coeff[29] * data[i-30]; /* Falls through. */ | |||
| case 29: sum += qlp_coeff[28] * data[i-29]; /* Falls through. */ | |||
| case 28: sum += qlp_coeff[27] * data[i-28]; /* Falls through. */ | |||
| case 27: sum += qlp_coeff[26] * data[i-27]; /* Falls through. */ | |||
| case 26: sum += qlp_coeff[25] * data[i-26]; /* Falls through. */ | |||
| case 25: sum += qlp_coeff[24] * data[i-25]; /* Falls through. */ | |||
| case 24: sum += qlp_coeff[23] * data[i-24]; /* Falls through. */ | |||
| case 23: sum += qlp_coeff[22] * data[i-23]; /* Falls through. */ | |||
| case 22: sum += qlp_coeff[21] * data[i-22]; /* Falls through. */ | |||
| case 21: sum += qlp_coeff[20] * data[i-21]; /* Falls through. */ | |||
| case 20: sum += qlp_coeff[19] * data[i-20]; /* Falls through. */ | |||
| case 19: sum += qlp_coeff[18] * data[i-19]; /* Falls through. */ | |||
| case 18: sum += qlp_coeff[17] * data[i-18]; /* Falls through. */ | |||
| case 17: sum += qlp_coeff[16] * data[i-17]; /* Falls through. */ | |||
| case 16: sum += qlp_coeff[15] * data[i-16]; /* Falls through. */ | |||
| case 15: sum += qlp_coeff[14] * data[i-15]; /* Falls through. */ | |||
| case 14: sum += qlp_coeff[13] * data[i-14]; /* Falls through. */ | |||
| case 13: sum += qlp_coeff[12] * data[i-13]; | |||
| sum += qlp_coeff[11] * data[i-12]; | |||
| sum += qlp_coeff[10] * data[i-11]; | |||
| sum += qlp_coeff[ 9] * data[i-10]; | |||
| sum += qlp_coeff[ 8] * data[i- 9]; | |||
| sum += qlp_coeff[ 7] * data[i- 8]; | |||
| sum += qlp_coeff[ 6] * data[i- 7]; | |||
| sum += qlp_coeff[ 5] * data[i- 6]; | |||
| sum += qlp_coeff[ 4] * data[i- 5]; | |||
| sum += qlp_coeff[ 3] * data[i- 4]; | |||
| sum += qlp_coeff[ 2] * data[i- 3]; | |||
| sum += qlp_coeff[ 1] * data[i- 2]; | |||
| sum += qlp_coeff[ 0] * data[i- 1]; | |||
| } | |||
| residual[i] = data[i] - (sum >> lp_quantization); | |||
| } | |||
| } | |||
| } | |||
| #endif /* FLAC__SSE2_SUPPORTED */ | |||
| #endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */ | |||
| #endif /* FLAC__NO_ASM */ | |||
| #endif /* FLAC__INTEGER_ONLY_LIBRARY */ | |||
| @@ -0,0 +1,942 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| #ifndef FLAC__NO_ASM | |||
| #if defined(FLAC__CPU_PPC64) && defined(FLAC__USE_VSX) | |||
| #include "include/private/cpu.h" | |||
| #include "include/private/lpc.h" | |||
| #include "../assert.h" | |||
| #include "../format.h" | |||
| #include <altivec.h> | |||
| #ifdef FLAC__HAS_TARGET_POWER8 | |||
| __attribute__((target("cpu=power8"))) | |||
| void FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_16(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]) | |||
| { | |||
| long i; | |||
| long limit = (long)data_len - 16; | |||
| const FLAC__real *base; | |||
| vector float sum0 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum1 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum2 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum3 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum10 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum11 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum12 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum13 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum20 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum21 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum22 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum23 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum30 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum31 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum32 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum33 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float d0, d1, d2, d3, d4; | |||
| #if WORDS_BIGENDIAN | |||
| vector unsigned int vsel1 = { 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF }; | |||
| vector unsigned int vsel2 = { 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF }; | |||
| vector unsigned int vsel3 = { 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; | |||
| vector unsigned int vperm1 = { 0x04050607, 0x08090A0B, 0x0C0D0E0F, 0x10111213 }; | |||
| vector unsigned int vperm2 = { 0x08090A0B, 0x0C0D0E0F, 0x10111213, 0x14151617 }; | |||
| vector unsigned int vperm3 = { 0x0C0D0E0F, 0x10111213, 0x14151617, 0x18191A1B }; | |||
| #else | |||
| vector unsigned int vsel1 = { 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000 }; | |||
| vector unsigned int vsel2 = { 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000 }; | |||
| vector unsigned int vsel3 = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }; | |||
| vector unsigned int vperm1 = { 0x07060504, 0x0B0A0908, 0x0F0E0D0C, 0x13121110 }; | |||
| vector unsigned int vperm2 = { 0x0B0A0908, 0x0F0E0D0C, 0x13121110, 0x17161514 }; | |||
| vector unsigned int vperm3 = { 0x0F0E0D0C, 0x13121110, 0x17161514, 0x1B1A1918 }; | |||
| #endif | |||
| (void) lag; | |||
| FLAC__ASSERT(lag <= 16); | |||
| FLAC__ASSERT(lag <= data_len); | |||
| base = data; | |||
| d0 = vec_vsx_ld(0, base); | |||
| d1 = vec_vsx_ld(16, base); | |||
| d2 = vec_vsx_ld(32, base); | |||
| d3 = vec_vsx_ld(48, base); | |||
| base += 16; | |||
| for (i = 0; i <= (limit-4); i += 4) { | |||
| vector float d, d0_orig = d0; | |||
| d4 = vec_vsx_ld(0, base); | |||
| base += 4; | |||
| d = vec_splat(d0_orig, 0); | |||
| sum0 += d0 * d; | |||
| sum1 += d1 * d; | |||
| sum2 += d2 * d; | |||
| sum3 += d3 * d; | |||
| d = vec_splat(d0_orig, 1); | |||
| d0 = vec_sel(d0_orig, d4, vsel1); | |||
| sum10 += d0 * d; | |||
| sum11 += d1 * d; | |||
| sum12 += d2 * d; | |||
| sum13 += d3 * d; | |||
| d = vec_splat(d0_orig, 2); | |||
| d0 = vec_sel(d0_orig, d4, vsel2); | |||
| sum20 += d0 * d; | |||
| sum21 += d1 * d; | |||
| sum22 += d2 * d; | |||
| sum23 += d3 * d; | |||
| d = vec_splat(d0_orig, 3); | |||
| d0 = vec_sel(d0_orig, d4, vsel3); | |||
| sum30 += d0 * d; | |||
| sum31 += d1 * d; | |||
| sum32 += d2 * d; | |||
| sum33 += d3 * d; | |||
| d0 = d1; | |||
| d1 = d2; | |||
| d2 = d3; | |||
| d3 = d4; | |||
| } | |||
| sum0 += vec_perm(sum10, sum11, (vector unsigned char)vperm1); | |||
| sum1 += vec_perm(sum11, sum12, (vector unsigned char)vperm1); | |||
| sum2 += vec_perm(sum12, sum13, (vector unsigned char)vperm1); | |||
| sum3 += vec_perm(sum13, sum10, (vector unsigned char)vperm1); | |||
| sum0 += vec_perm(sum20, sum21, (vector unsigned char)vperm2); | |||
| sum1 += vec_perm(sum21, sum22, (vector unsigned char)vperm2); | |||
| sum2 += vec_perm(sum22, sum23, (vector unsigned char)vperm2); | |||
| sum3 += vec_perm(sum23, sum20, (vector unsigned char)vperm2); | |||
| sum0 += vec_perm(sum30, sum31, (vector unsigned char)vperm3); | |||
| sum1 += vec_perm(sum31, sum32, (vector unsigned char)vperm3); | |||
| sum2 += vec_perm(sum32, sum33, (vector unsigned char)vperm3); | |||
| sum3 += vec_perm(sum33, sum30, (vector unsigned char)vperm3); | |||
| for (; i <= limit; i++) { | |||
| vector float d; | |||
| d0 = vec_vsx_ld(0, data+i); | |||
| d1 = vec_vsx_ld(16, data+i); | |||
| d2 = vec_vsx_ld(32, data+i); | |||
| d3 = vec_vsx_ld(48, data+i); | |||
| d = vec_splat(d0, 0); | |||
| sum0 += d0 * d; | |||
| sum1 += d1 * d; | |||
| sum2 += d2 * d; | |||
| sum3 += d3 * d; | |||
| } | |||
| vec_vsx_st(sum0, 0, autoc); | |||
| vec_vsx_st(sum1, 16, autoc); | |||
| vec_vsx_st(sum2, 32, autoc); | |||
| vec_vsx_st(sum3, 48, autoc); | |||
| for (; i < (long)data_len; i++) { | |||
| uint32_t coeff; | |||
| FLAC__real d = data[i]; | |||
| for (coeff = 0; coeff < data_len - i; coeff++) | |||
| autoc[coeff] += d * data[i+coeff]; | |||
| } | |||
| } | |||
| __attribute__((target("cpu=power8"))) | |||
| void FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_12(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]) | |||
| { | |||
| long i; | |||
| long limit = (long)data_len - 12; | |||
| const FLAC__real *base; | |||
| vector float sum0 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum1 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum2 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum10 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum11 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum12 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum20 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum21 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum22 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum30 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum31 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum32 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float d0, d1, d2, d3; | |||
| #if WORDS_BIGENDIAN | |||
| vector unsigned int vsel1 = { 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF }; | |||
| vector unsigned int vsel2 = { 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF }; | |||
| vector unsigned int vsel3 = { 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; | |||
| vector unsigned int vperm1 = { 0x04050607, 0x08090A0B, 0x0C0D0E0F, 0x10111213 }; | |||
| vector unsigned int vperm2 = { 0x08090A0B, 0x0C0D0E0F, 0x10111213, 0x14151617 }; | |||
| vector unsigned int vperm3 = { 0x0C0D0E0F, 0x10111213, 0x14151617, 0x18191A1B }; | |||
| #else | |||
| vector unsigned int vsel1 = { 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000 }; | |||
| vector unsigned int vsel2 = { 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000 }; | |||
| vector unsigned int vsel3 = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }; | |||
| vector unsigned int vperm1 = { 0x07060504, 0x0B0A0908, 0x0F0E0D0C, 0x13121110 }; | |||
| vector unsigned int vperm2 = { 0x0B0A0908, 0x0F0E0D0C, 0x13121110, 0x17161514 }; | |||
| vector unsigned int vperm3 = { 0x0F0E0D0C, 0x13121110, 0x17161514, 0x1B1A1918 }; | |||
| #endif | |||
| (void) lag; | |||
| FLAC__ASSERT(lag <= 12); | |||
| FLAC__ASSERT(lag <= data_len); | |||
| base = data; | |||
| d0 = vec_vsx_ld(0, base); | |||
| d1 = vec_vsx_ld(16, base); | |||
| d2 = vec_vsx_ld(32, base); | |||
| base += 12; | |||
| for (i = 0; i <= (limit-3); i += 4) { | |||
| vector float d, d0_orig = d0; | |||
| d3 = vec_vsx_ld(0, base); | |||
| base += 4; | |||
| d = vec_splat(d0_orig, 0); | |||
| sum0 += d0 * d; | |||
| sum1 += d1 * d; | |||
| sum2 += d2 * d; | |||
| d = vec_splat(d0_orig, 1); | |||
| d0 = vec_sel(d0_orig, d3, vsel1); | |||
| sum10 += d0 * d; | |||
| sum11 += d1 * d; | |||
| sum12 += d2 * d; | |||
| d = vec_splat(d0_orig, 2); | |||
| d0 = vec_sel(d0_orig, d3, vsel2); | |||
| sum20 += d0 * d; | |||
| sum21 += d1 * d; | |||
| sum22 += d2 * d; | |||
| d = vec_splat(d0_orig, 3); | |||
| d0 = vec_sel(d0_orig, d3, vsel3); | |||
| sum30 += d0 * d; | |||
| sum31 += d1 * d; | |||
| sum32 += d2 * d; | |||
| d0 = d1; | |||
| d1 = d2; | |||
| d2 = d3; | |||
| } | |||
| sum0 += vec_perm(sum10, sum11, (vector unsigned char)vperm1); | |||
| sum1 += vec_perm(sum11, sum12, (vector unsigned char)vperm1); | |||
| sum2 += vec_perm(sum12, sum10, (vector unsigned char)vperm1); | |||
| sum0 += vec_perm(sum20, sum21, (vector unsigned char)vperm2); | |||
| sum1 += vec_perm(sum21, sum22, (vector unsigned char)vperm2); | |||
| sum2 += vec_perm(sum22, sum20, (vector unsigned char)vperm2); | |||
| sum0 += vec_perm(sum30, sum31, (vector unsigned char)vperm3); | |||
| sum1 += vec_perm(sum31, sum32, (vector unsigned char)vperm3); | |||
| sum2 += vec_perm(sum32, sum30, (vector unsigned char)vperm3); | |||
| for (; i <= limit; i++) { | |||
| vector float d; | |||
| d0 = vec_vsx_ld(0, data+i); | |||
| d1 = vec_vsx_ld(16, data+i); | |||
| d2 = vec_vsx_ld(32, data+i); | |||
| d = vec_splat(d0, 0); | |||
| sum0 += d0 * d; | |||
| sum1 += d1 * d; | |||
| sum2 += d2 * d; | |||
| } | |||
| vec_vsx_st(sum0, 0, autoc); | |||
| vec_vsx_st(sum1, 16, autoc); | |||
| vec_vsx_st(sum2, 32, autoc); | |||
| for (; i < (long)data_len; i++) { | |||
| uint32_t coeff; | |||
| FLAC__real d = data[i]; | |||
| for (coeff = 0; coeff < data_len - i; coeff++) | |||
| autoc[coeff] += d * data[i+coeff]; | |||
| } | |||
| } | |||
| __attribute__((target("cpu=power8"))) | |||
| void FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_8(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]) | |||
| { | |||
| long i; | |||
| long limit = (long)data_len - 8; | |||
| const FLAC__real *base; | |||
| vector float sum0 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum1 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum10 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum11 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum20 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum21 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum30 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum31 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float d0, d1, d2; | |||
| #if WORDS_BIGENDIAN | |||
| vector unsigned int vsel1 = { 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF }; | |||
| vector unsigned int vsel2 = { 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF }; | |||
| vector unsigned int vsel3 = { 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; | |||
| vector unsigned int vperm1 = { 0x04050607, 0x08090A0B, 0x0C0D0E0F, 0x10111213 }; | |||
| vector unsigned int vperm2 = { 0x08090A0B, 0x0C0D0E0F, 0x10111213, 0x14151617 }; | |||
| vector unsigned int vperm3 = { 0x0C0D0E0F, 0x10111213, 0x14151617, 0x18191A1B }; | |||
| #else | |||
| vector unsigned int vsel1 = { 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000 }; | |||
| vector unsigned int vsel2 = { 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000 }; | |||
| vector unsigned int vsel3 = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }; | |||
| vector unsigned int vperm1 = { 0x07060504, 0x0B0A0908, 0x0F0E0D0C, 0x13121110 }; | |||
| vector unsigned int vperm2 = { 0x0B0A0908, 0x0F0E0D0C, 0x13121110, 0x17161514 }; | |||
| vector unsigned int vperm3 = { 0x0F0E0D0C, 0x13121110, 0x17161514, 0x1B1A1918 }; | |||
| #endif | |||
| (void) lag; | |||
| FLAC__ASSERT(lag <= 8); | |||
| FLAC__ASSERT(lag <= data_len); | |||
| base = data; | |||
| d0 = vec_vsx_ld(0, base); | |||
| d1 = vec_vsx_ld(16, base); | |||
| base += 8; | |||
| for (i = 0; i <= (limit-2); i += 4) { | |||
| vector float d, d0_orig = d0; | |||
| d2 = vec_vsx_ld(0, base); | |||
| base += 4; | |||
| d = vec_splat(d0_orig, 0); | |||
| sum0 += d0 * d; | |||
| sum1 += d1 * d; | |||
| d = vec_splat(d0_orig, 1); | |||
| d0 = vec_sel(d0_orig, d2, vsel1); | |||
| sum10 += d0 * d; | |||
| sum11 += d1 * d; | |||
| d = vec_splat(d0_orig, 2); | |||
| d0 = vec_sel(d0_orig, d2, vsel2); | |||
| sum20 += d0 * d; | |||
| sum21 += d1 * d; | |||
| d = vec_splat(d0_orig, 3); | |||
| d0 = vec_sel(d0_orig, d2, vsel3); | |||
| sum30 += d0 * d; | |||
| sum31 += d1 * d; | |||
| d0 = d1; | |||
| d1 = d2; | |||
| } | |||
| sum0 += vec_perm(sum10, sum11, (vector unsigned char)vperm1); | |||
| sum1 += vec_perm(sum11, sum10, (vector unsigned char)vperm1); | |||
| sum0 += vec_perm(sum20, sum21, (vector unsigned char)vperm2); | |||
| sum1 += vec_perm(sum21, sum20, (vector unsigned char)vperm2); | |||
| sum0 += vec_perm(sum30, sum31, (vector unsigned char)vperm3); | |||
| sum1 += vec_perm(sum31, sum30, (vector unsigned char)vperm3); | |||
| for (; i <= limit; i++) { | |||
| vector float d; | |||
| d0 = vec_vsx_ld(0, data+i); | |||
| d1 = vec_vsx_ld(16, data+i); | |||
| d = vec_splat(d0, 0); | |||
| sum0 += d0 * d; | |||
| sum1 += d1 * d; | |||
| } | |||
| vec_vsx_st(sum0, 0, autoc); | |||
| vec_vsx_st(sum1, 16, autoc); | |||
| for (; i < (long)data_len; i++) { | |||
| uint32_t coeff; | |||
| FLAC__real d = data[i]; | |||
| for (coeff = 0; coeff < data_len - i; coeff++) | |||
| autoc[coeff] += d * data[i+coeff]; | |||
| } | |||
| } | |||
| __attribute__((target("cpu=power8"))) | |||
| void FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_4(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]) | |||
| { | |||
| long i; | |||
| long limit = (long)data_len - 4; | |||
| const FLAC__real *base; | |||
| vector float sum0 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum10 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum20 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum30 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float d0, d1; | |||
| #if WORDS_BIGENDIAN | |||
| vector unsigned int vsel1 = { 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF }; | |||
| vector unsigned int vsel2 = { 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF }; | |||
| vector unsigned int vsel3 = { 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; | |||
| vector unsigned int vperm1 = { 0x04050607, 0x08090A0B, 0x0C0D0E0F, 0x10111213 }; | |||
| vector unsigned int vperm2 = { 0x08090A0B, 0x0C0D0E0F, 0x10111213, 0x14151617 }; | |||
| vector unsigned int vperm3 = { 0x0C0D0E0F, 0x10111213, 0x14151617, 0x18191A1B }; | |||
| #else | |||
| vector unsigned int vsel1 = { 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000 }; | |||
| vector unsigned int vsel2 = { 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000 }; | |||
| vector unsigned int vsel3 = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }; | |||
| vector unsigned int vperm1 = { 0x07060504, 0x0B0A0908, 0x0F0E0D0C, 0x13121110 }; | |||
| vector unsigned int vperm2 = { 0x0B0A0908, 0x0F0E0D0C, 0x13121110, 0x17161514 }; | |||
| vector unsigned int vperm3 = { 0x0F0E0D0C, 0x13121110, 0x17161514, 0x1B1A1918 }; | |||
| #endif | |||
| (void) lag; | |||
| FLAC__ASSERT(lag <= 4); | |||
| FLAC__ASSERT(lag <= data_len); | |||
| base = data; | |||
| d0 = vec_vsx_ld(0, base); | |||
| base += 4; | |||
| for (i = 0; i <= (limit-1); i += 4) { | |||
| vector float d, d0_orig = d0; | |||
| d1 = vec_vsx_ld(0, base); | |||
| base += 4; | |||
| d = vec_splat(d0_orig, 0); | |||
| sum0 += d0 * d; | |||
| d = vec_splat(d0_orig, 1); | |||
| d0 = vec_sel(d0_orig, d1, vsel1); | |||
| sum10 += d0 * d; | |||
| d = vec_splat(d0_orig, 2); | |||
| d0 = vec_sel(d0_orig, d1, vsel2); | |||
| sum20 += d0 * d; | |||
| d = vec_splat(d0_orig, 3); | |||
| d0 = vec_sel(d0_orig, d1, vsel3); | |||
| sum30 += d0 * d; | |||
| d0 = d1; | |||
| } | |||
| sum0 += vec_perm(sum10, sum10, (vector unsigned char)vperm1); | |||
| sum0 += vec_perm(sum20, sum20, (vector unsigned char)vperm2); | |||
| sum0 += vec_perm(sum30, sum30, (vector unsigned char)vperm3); | |||
| for (; i <= limit; i++) { | |||
| vector float d; | |||
| d0 = vec_vsx_ld(0, data+i); | |||
| d = vec_splat(d0, 0); | |||
| sum0 += d0 * d; | |||
| } | |||
| vec_vsx_st(sum0, 0, autoc); | |||
| for (; i < (long)data_len; i++) { | |||
| uint32_t coeff; | |||
| FLAC__real d = data[i]; | |||
| for (coeff = 0; coeff < data_len - i; coeff++) | |||
| autoc[coeff] += d * data[i+coeff]; | |||
| } | |||
| } | |||
| #endif /* FLAC__HAS_TARGET_POWER8 */ | |||
| #ifdef FLAC__HAS_TARGET_POWER9 | |||
| __attribute__((target("cpu=power9"))) | |||
| void FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_16(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]) | |||
| { | |||
| long i; | |||
| long limit = (long)data_len - 16; | |||
| const FLAC__real *base; | |||
| vector float sum0 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum1 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum2 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum3 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum10 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum11 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum12 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum13 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum20 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum21 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum22 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum23 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum30 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum31 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum32 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum33 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float d0, d1, d2, d3, d4; | |||
| #if WORDS_BIGENDIAN | |||
| vector unsigned int vsel1 = { 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF }; | |||
| vector unsigned int vsel2 = { 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF }; | |||
| vector unsigned int vsel3 = { 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; | |||
| vector unsigned int vperm1 = { 0x04050607, 0x08090A0B, 0x0C0D0E0F, 0x10111213 }; | |||
| vector unsigned int vperm2 = { 0x08090A0B, 0x0C0D0E0F, 0x10111213, 0x14151617 }; | |||
| vector unsigned int vperm3 = { 0x0C0D0E0F, 0x10111213, 0x14151617, 0x18191A1B }; | |||
| #else | |||
| vector unsigned int vsel1 = { 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000 }; | |||
| vector unsigned int vsel2 = { 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000 }; | |||
| vector unsigned int vsel3 = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }; | |||
| vector unsigned int vperm1 = { 0x07060504, 0x0B0A0908, 0x0F0E0D0C, 0x13121110 }; | |||
| vector unsigned int vperm2 = { 0x0B0A0908, 0x0F0E0D0C, 0x13121110, 0x17161514 }; | |||
| vector unsigned int vperm3 = { 0x0F0E0D0C, 0x13121110, 0x17161514, 0x1B1A1918 }; | |||
| #endif | |||
| (void) lag; | |||
| FLAC__ASSERT(lag <= 16); | |||
| FLAC__ASSERT(lag <= data_len); | |||
| base = data; | |||
| d0 = vec_vsx_ld(0, base); | |||
| d1 = vec_vsx_ld(16, base); | |||
| d2 = vec_vsx_ld(32, base); | |||
| d3 = vec_vsx_ld(48, base); | |||
| base += 16; | |||
| for (i = 0; i <= (limit-4); i += 4) { | |||
| vector float d, d0_orig = d0; | |||
| d4 = vec_vsx_ld(0, base); | |||
| base += 4; | |||
| d = vec_splat(d0_orig, 0); | |||
| sum0 += d0 * d; | |||
| sum1 += d1 * d; | |||
| sum2 += d2 * d; | |||
| sum3 += d3 * d; | |||
| d = vec_splat(d0_orig, 1); | |||
| d0 = vec_sel(d0_orig, d4, vsel1); | |||
| sum10 += d0 * d; | |||
| sum11 += d1 * d; | |||
| sum12 += d2 * d; | |||
| sum13 += d3 * d; | |||
| d = vec_splat(d0_orig, 2); | |||
| d0 = vec_sel(d0_orig, d4, vsel2); | |||
| sum20 += d0 * d; | |||
| sum21 += d1 * d; | |||
| sum22 += d2 * d; | |||
| sum23 += d3 * d; | |||
| d = vec_splat(d0_orig, 3); | |||
| d0 = vec_sel(d0_orig, d4, vsel3); | |||
| sum30 += d0 * d; | |||
| sum31 += d1 * d; | |||
| sum32 += d2 * d; | |||
| sum33 += d3 * d; | |||
| d0 = d1; | |||
| d1 = d2; | |||
| d2 = d3; | |||
| d3 = d4; | |||
| } | |||
| sum0 += vec_perm(sum10, sum11, (vector unsigned char)vperm1); | |||
| sum1 += vec_perm(sum11, sum12, (vector unsigned char)vperm1); | |||
| sum2 += vec_perm(sum12, sum13, (vector unsigned char)vperm1); | |||
| sum3 += vec_perm(sum13, sum10, (vector unsigned char)vperm1); | |||
| sum0 += vec_perm(sum20, sum21, (vector unsigned char)vperm2); | |||
| sum1 += vec_perm(sum21, sum22, (vector unsigned char)vperm2); | |||
| sum2 += vec_perm(sum22, sum23, (vector unsigned char)vperm2); | |||
| sum3 += vec_perm(sum23, sum20, (vector unsigned char)vperm2); | |||
| sum0 += vec_perm(sum30, sum31, (vector unsigned char)vperm3); | |||
| sum1 += vec_perm(sum31, sum32, (vector unsigned char)vperm3); | |||
| sum2 += vec_perm(sum32, sum33, (vector unsigned char)vperm3); | |||
| sum3 += vec_perm(sum33, sum30, (vector unsigned char)vperm3); | |||
| for (; i <= limit; i++) { | |||
| vector float d; | |||
| d0 = vec_vsx_ld(0, data+i); | |||
| d1 = vec_vsx_ld(16, data+i); | |||
| d2 = vec_vsx_ld(32, data+i); | |||
| d3 = vec_vsx_ld(48, data+i); | |||
| d = vec_splat(d0, 0); | |||
| sum0 += d0 * d; | |||
| sum1 += d1 * d; | |||
| sum2 += d2 * d; | |||
| sum3 += d3 * d; | |||
| } | |||
| vec_vsx_st(sum0, 0, autoc); | |||
| vec_vsx_st(sum1, 16, autoc); | |||
| vec_vsx_st(sum2, 32, autoc); | |||
| vec_vsx_st(sum3, 48, autoc); | |||
| for (; i < (long)data_len; i++) { | |||
| uint32_t coeff; | |||
| FLAC__real d = data[i]; | |||
| for (coeff = 0; coeff < data_len - i; coeff++) | |||
| autoc[coeff] += d * data[i+coeff]; | |||
| } | |||
| } | |||
| __attribute__((target("cpu=power9"))) | |||
| void FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_12(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]) | |||
| { | |||
| long i; | |||
| long limit = (long)data_len - 12; | |||
| const FLAC__real *base; | |||
| vector float sum0 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum1 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum2 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum10 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum11 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum12 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum20 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum21 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum22 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum30 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum31 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum32 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float d0, d1, d2, d3; | |||
| #if WORDS_BIGENDIAN | |||
| vector unsigned int vsel1 = { 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF }; | |||
| vector unsigned int vsel2 = { 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF }; | |||
| vector unsigned int vsel3 = { 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; | |||
| vector unsigned int vperm1 = { 0x04050607, 0x08090A0B, 0x0C0D0E0F, 0x10111213 }; | |||
| vector unsigned int vperm2 = { 0x08090A0B, 0x0C0D0E0F, 0x10111213, 0x14151617 }; | |||
| vector unsigned int vperm3 = { 0x0C0D0E0F, 0x10111213, 0x14151617, 0x18191A1B }; | |||
| #else | |||
| vector unsigned int vsel1 = { 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000 }; | |||
| vector unsigned int vsel2 = { 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000 }; | |||
| vector unsigned int vsel3 = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }; | |||
| vector unsigned int vperm1 = { 0x07060504, 0x0B0A0908, 0x0F0E0D0C, 0x13121110 }; | |||
| vector unsigned int vperm2 = { 0x0B0A0908, 0x0F0E0D0C, 0x13121110, 0x17161514 }; | |||
| vector unsigned int vperm3 = { 0x0F0E0D0C, 0x13121110, 0x17161514, 0x1B1A1918 }; | |||
| #endif | |||
| (void) lag; | |||
| FLAC__ASSERT(lag <= 12); | |||
| FLAC__ASSERT(lag <= data_len); | |||
| base = data; | |||
| d0 = vec_vsx_ld(0, base); | |||
| d1 = vec_vsx_ld(16, base); | |||
| d2 = vec_vsx_ld(32, base); | |||
| base += 12; | |||
| for (i = 0; i <= (limit-3); i += 4) { | |||
| vector float d, d0_orig = d0; | |||
| d3 = vec_vsx_ld(0, base); | |||
| base += 4; | |||
| d = vec_splat(d0_orig, 0); | |||
| sum0 += d0 * d; | |||
| sum1 += d1 * d; | |||
| sum2 += d2 * d; | |||
| d = vec_splat(d0_orig, 1); | |||
| d0 = vec_sel(d0_orig, d3, vsel1); | |||
| sum10 += d0 * d; | |||
| sum11 += d1 * d; | |||
| sum12 += d2 * d; | |||
| d = vec_splat(d0_orig, 2); | |||
| d0 = vec_sel(d0_orig, d3, vsel2); | |||
| sum20 += d0 * d; | |||
| sum21 += d1 * d; | |||
| sum22 += d2 * d; | |||
| d = vec_splat(d0_orig, 3); | |||
| d0 = vec_sel(d0_orig, d3, vsel3); | |||
| sum30 += d0 * d; | |||
| sum31 += d1 * d; | |||
| sum32 += d2 * d; | |||
| d0 = d1; | |||
| d1 = d2; | |||
| d2 = d3; | |||
| } | |||
| sum0 += vec_perm(sum10, sum11, (vector unsigned char)vperm1); | |||
| sum1 += vec_perm(sum11, sum12, (vector unsigned char)vperm1); | |||
| sum2 += vec_perm(sum12, sum10, (vector unsigned char)vperm1); | |||
| sum0 += vec_perm(sum20, sum21, (vector unsigned char)vperm2); | |||
| sum1 += vec_perm(sum21, sum22, (vector unsigned char)vperm2); | |||
| sum2 += vec_perm(sum22, sum20, (vector unsigned char)vperm2); | |||
| sum0 += vec_perm(sum30, sum31, (vector unsigned char)vperm3); | |||
| sum1 += vec_perm(sum31, sum32, (vector unsigned char)vperm3); | |||
| sum2 += vec_perm(sum32, sum30, (vector unsigned char)vperm3); | |||
| for (; i <= limit; i++) { | |||
| vector float d; | |||
| d0 = vec_vsx_ld(0, data+i); | |||
| d1 = vec_vsx_ld(16, data+i); | |||
| d2 = vec_vsx_ld(32, data+i); | |||
| d = vec_splat(d0, 0); | |||
| sum0 += d0 * d; | |||
| sum1 += d1 * d; | |||
| sum2 += d2 * d; | |||
| } | |||
| vec_vsx_st(sum0, 0, autoc); | |||
| vec_vsx_st(sum1, 16, autoc); | |||
| vec_vsx_st(sum2, 32, autoc); | |||
| for (; i < (long)data_len; i++) { | |||
| uint32_t coeff; | |||
| FLAC__real d = data[i]; | |||
| for (coeff = 0; coeff < data_len - i; coeff++) | |||
| autoc[coeff] += d * data[i+coeff]; | |||
| } | |||
| } | |||
| __attribute__((target("cpu=power9"))) | |||
| void FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_8(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]) | |||
| { | |||
| long i; | |||
| long limit = (long)data_len - 8; | |||
| const FLAC__real *base; | |||
| vector float sum0 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum1 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum10 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum11 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum20 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum21 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum30 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum31 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float d0, d1, d2; | |||
| #if WORDS_BIGENDIAN | |||
| vector unsigned int vsel1 = { 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF }; | |||
| vector unsigned int vsel2 = { 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF }; | |||
| vector unsigned int vsel3 = { 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; | |||
| vector unsigned int vperm1 = { 0x04050607, 0x08090A0B, 0x0C0D0E0F, 0x10111213 }; | |||
| vector unsigned int vperm2 = { 0x08090A0B, 0x0C0D0E0F, 0x10111213, 0x14151617 }; | |||
| vector unsigned int vperm3 = { 0x0C0D0E0F, 0x10111213, 0x14151617, 0x18191A1B }; | |||
| #else | |||
| vector unsigned int vsel1 = { 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000 }; | |||
| vector unsigned int vsel2 = { 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000 }; | |||
| vector unsigned int vsel3 = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }; | |||
| vector unsigned int vperm1 = { 0x07060504, 0x0B0A0908, 0x0F0E0D0C, 0x13121110 }; | |||
| vector unsigned int vperm2 = { 0x0B0A0908, 0x0F0E0D0C, 0x13121110, 0x17161514 }; | |||
| vector unsigned int vperm3 = { 0x0F0E0D0C, 0x13121110, 0x17161514, 0x1B1A1918 }; | |||
| #endif | |||
| (void) lag; | |||
| FLAC__ASSERT(lag <= 8); | |||
| FLAC__ASSERT(lag <= data_len); | |||
| base = data; | |||
| d0 = vec_vsx_ld(0, base); | |||
| d1 = vec_vsx_ld(16, base); | |||
| base += 8; | |||
| for (i = 0; i <= (limit-2); i += 4) { | |||
| vector float d, d0_orig = d0; | |||
| d2 = vec_vsx_ld(0, base); | |||
| base += 4; | |||
| d = vec_splat(d0_orig, 0); | |||
| sum0 += d0 * d; | |||
| sum1 += d1 * d; | |||
| d = vec_splat(d0_orig, 1); | |||
| d0 = vec_sel(d0_orig, d2, vsel1); | |||
| sum10 += d0 * d; | |||
| sum11 += d1 * d; | |||
| d = vec_splat(d0_orig, 2); | |||
| d0 = vec_sel(d0_orig, d2, vsel2); | |||
| sum20 += d0 * d; | |||
| sum21 += d1 * d; | |||
| d = vec_splat(d0_orig, 3); | |||
| d0 = vec_sel(d0_orig, d2, vsel3); | |||
| sum30 += d0 * d; | |||
| sum31 += d1 * d; | |||
| d0 = d1; | |||
| d1 = d2; | |||
| } | |||
| sum0 += vec_perm(sum10, sum11, (vector unsigned char)vperm1); | |||
| sum1 += vec_perm(sum11, sum10, (vector unsigned char)vperm1); | |||
| sum0 += vec_perm(sum20, sum21, (vector unsigned char)vperm2); | |||
| sum1 += vec_perm(sum21, sum20, (vector unsigned char)vperm2); | |||
| sum0 += vec_perm(sum30, sum31, (vector unsigned char)vperm3); | |||
| sum1 += vec_perm(sum31, sum30, (vector unsigned char)vperm3); | |||
| for (; i <= limit; i++) { | |||
| vector float d; | |||
| d0 = vec_vsx_ld(0, data+i); | |||
| d1 = vec_vsx_ld(16, data+i); | |||
| d = vec_splat(d0, 0); | |||
| sum0 += d0 * d; | |||
| sum1 += d1 * d; | |||
| } | |||
| vec_vsx_st(sum0, 0, autoc); | |||
| vec_vsx_st(sum1, 16, autoc); | |||
| for (; i < (long)data_len; i++) { | |||
| uint32_t coeff; | |||
| FLAC__real d = data[i]; | |||
| for (coeff = 0; coeff < data_len - i; coeff++) | |||
| autoc[coeff] += d * data[i+coeff]; | |||
| } | |||
| } | |||
| __attribute__((target("cpu=power9"))) | |||
| void FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_4(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]) | |||
| { | |||
| long i; | |||
| long limit = (long)data_len - 4; | |||
| const FLAC__real *base; | |||
| vector float sum0 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum10 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum20 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float sum30 = { 0.0f, 0.0f, 0.0f, 0.0f}; | |||
| vector float d0, d1; | |||
| #if WORDS_BIGENDIAN | |||
| vector unsigned int vsel1 = { 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF }; | |||
| vector unsigned int vsel2 = { 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF }; | |||
| vector unsigned int vsel3 = { 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; | |||
| vector unsigned int vperm1 = { 0x04050607, 0x08090A0B, 0x0C0D0E0F, 0x10111213 }; | |||
| vector unsigned int vperm2 = { 0x08090A0B, 0x0C0D0E0F, 0x10111213, 0x14151617 }; | |||
| vector unsigned int vperm3 = { 0x0C0D0E0F, 0x10111213, 0x14151617, 0x18191A1B }; | |||
| #else | |||
| vector unsigned int vsel1 = { 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000 }; | |||
| vector unsigned int vsel2 = { 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000 }; | |||
| vector unsigned int vsel3 = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }; | |||
| vector unsigned int vperm1 = { 0x07060504, 0x0B0A0908, 0x0F0E0D0C, 0x13121110 }; | |||
| vector unsigned int vperm2 = { 0x0B0A0908, 0x0F0E0D0C, 0x13121110, 0x17161514 }; | |||
| vector unsigned int vperm3 = { 0x0F0E0D0C, 0x13121110, 0x17161514, 0x1B1A1918 }; | |||
| #endif | |||
| (void) lag; | |||
| FLAC__ASSERT(lag <= 4); | |||
| FLAC__ASSERT(lag <= data_len); | |||
| base = data; | |||
| d0 = vec_vsx_ld(0, base); | |||
| base += 4; | |||
| for (i = 0; i <= (limit-1); i += 4) { | |||
| vector float d, d0_orig = d0; | |||
| d1 = vec_vsx_ld(0, base); | |||
| base += 4; | |||
| d = vec_splat(d0_orig, 0); | |||
| sum0 += d0 * d; | |||
| d = vec_splat(d0_orig, 1); | |||
| d0 = vec_sel(d0_orig, d1, vsel1); | |||
| sum10 += d0 * d; | |||
| d = vec_splat(d0_orig, 2); | |||
| d0 = vec_sel(d0_orig, d1, vsel2); | |||
| sum20 += d0 * d; | |||
| d = vec_splat(d0_orig, 3); | |||
| d0 = vec_sel(d0_orig, d1, vsel3); | |||
| sum30 += d0 * d; | |||
| d0 = d1; | |||
| } | |||
| sum0 += vec_perm(sum10, sum10, (vector unsigned char)vperm1); | |||
| sum0 += vec_perm(sum20, sum20, (vector unsigned char)vperm2); | |||
| sum0 += vec_perm(sum30, sum30, (vector unsigned char)vperm3); | |||
| for (; i <= limit; i++) { | |||
| vector float d; | |||
| d0 = vec_vsx_ld(0, data+i); | |||
| d = vec_splat(d0, 0); | |||
| sum0 += d0 * d; | |||
| } | |||
| vec_vsx_st(sum0, 0, autoc); | |||
| for (; i < (long)data_len; i++) { | |||
| uint32_t coeff; | |||
| FLAC__real d = data[i]; | |||
| for (coeff = 0; coeff < data_len - i; coeff++) | |||
| autoc[coeff] += d * data[i+coeff]; | |||
| } | |||
| } | |||
| #endif /* FLAC__HAS_TARGET_POWER9 */ | |||
| #endif /* FLAC__CPU_PPC64 && FLAC__USE_VSX */ | |||
| #endif /* FLAC__NO_ASM */ | |||
| #endif /* FLAC__INTEGER_ONLY_LIBRARY */ | |||
| @@ -0,0 +1,517 @@ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include <stdlib.h> /* for malloc() */ | |||
| #include <string.h> /* for memcpy() */ | |||
| #include "include/private/md5.h" | |||
| #include "../alloc.h" | |||
| #include "../compat.h" | |||
| #include "../endswap.h" | |||
| /* | |||
| * This code implements the MD5 message-digest algorithm. | |||
| * The algorithm is due to Ron Rivest. This code was | |||
| * written by Colin Plumb in 1993, no copyright is claimed. | |||
| * This code is in the public domain; do with it what you wish. | |||
| * | |||
| * Equivalent code is available from RSA Data Security, Inc. | |||
| * This code has been tested against that, and is equivalent, | |||
| * except that you don't need to include two pages of legalese | |||
| * with every copy. | |||
| * | |||
| * To compute the message digest of a chunk of bytes, declare an | |||
| * MD5Context structure, pass it to MD5Init, call MD5Update as | |||
| * needed on buffers full of bytes, and then call MD5Final, which | |||
| * will fill a supplied 16-byte array with the digest. | |||
| * | |||
| * Changed so as no longer to depend on Colin Plumb's `usual.h' header | |||
| * definitions; now uses stuff from dpkg's config.h. | |||
| * - Ian Jackson <ijackson@nyx.cs.du.edu>. | |||
| * Still in the public domain. | |||
| * | |||
| * Josh Coalson: made some changes to integrate with libFLAC. | |||
| * Still in the public domain. | |||
| */ | |||
| /* The four core functions - F1 is optimized somewhat */ | |||
| /* #define F1(x, y, z) (x & y | ~x & z) */ | |||
| #define F1(x, y, z) (z ^ (x & (y ^ z))) | |||
| #define F2(x, y, z) F1(z, x, y) | |||
| #define F3(x, y, z) (x ^ y ^ z) | |||
| #define F4(x, y, z) (y ^ (x | ~z)) | |||
| /* This is the central step in the MD5 algorithm. */ | |||
| #define MD5STEP(f,w,x,y,z,in,s) \ | |||
| (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x) | |||
| /* | |||
| * The core of the MD5 algorithm, this alters an existing MD5 hash to | |||
| * reflect the addition of 16 longwords of new data. MD5Update blocks | |||
| * the data and converts bytes into longwords for this routine. | |||
| */ | |||
| static void FLAC__MD5Transform(FLAC__uint32 buf[4], FLAC__uint32 const in[16]) | |||
| { | |||
| register FLAC__uint32 a, b, c, d; | |||
| a = buf[0]; | |||
| b = buf[1]; | |||
| c = buf[2]; | |||
| d = buf[3]; | |||
| MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); | |||
| MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); | |||
| MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); | |||
| MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); | |||
| MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); | |||
| MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); | |||
| MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); | |||
| MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); | |||
| MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); | |||
| MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); | |||
| MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); | |||
| MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); | |||
| MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); | |||
| MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); | |||
| MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); | |||
| MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); | |||
| MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); | |||
| MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); | |||
| MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); | |||
| MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); | |||
| MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); | |||
| MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); | |||
| MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); | |||
| MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); | |||
| MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); | |||
| MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); | |||
| MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); | |||
| MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); | |||
| MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); | |||
| MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); | |||
| MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); | |||
| MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); | |||
| MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); | |||
| MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); | |||
| MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); | |||
| MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); | |||
| MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); | |||
| MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); | |||
| MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); | |||
| MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); | |||
| MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); | |||
| MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); | |||
| MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); | |||
| MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); | |||
| MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); | |||
| MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); | |||
| MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); | |||
| MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); | |||
| MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); | |||
| MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); | |||
| MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); | |||
| MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); | |||
| MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); | |||
| MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); | |||
| MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); | |||
| MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); | |||
| MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); | |||
| MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); | |||
| MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); | |||
| MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); | |||
| MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); | |||
| MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); | |||
| MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); | |||
| MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); | |||
| buf[0] += a; | |||
| buf[1] += b; | |||
| buf[2] += c; | |||
| buf[3] += d; | |||
| } | |||
| #if WORDS_BIGENDIAN | |||
| //@@@@@@ OPT: use bswap/intrinsics | |||
| static void byteSwap(FLAC__uint32 *buf, uint32_t words) | |||
| { | |||
| register FLAC__uint32 x; | |||
| do { | |||
| x = *buf; | |||
| x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); | |||
| *buf++ = (x >> 16) | (x << 16); | |||
| } while (--words); | |||
| } | |||
| static void byteSwapX16(FLAC__uint32 *buf) | |||
| { | |||
| register FLAC__uint32 x; | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf = (x >> 16) | (x << 16); | |||
| } | |||
| #else | |||
| #define byteSwap(buf, words) | |||
| #define byteSwapX16(buf) | |||
| #endif | |||
| /* | |||
| * Update context to reflect the concatenation of another buffer full | |||
| * of bytes. | |||
| */ | |||
| static void FLAC__MD5Update(FLAC__MD5Context *ctx, FLAC__byte const *buf, uint32_t len) | |||
| { | |||
| FLAC__uint32 t; | |||
| /* Update byte count */ | |||
| t = ctx->bytes[0]; | |||
| if ((ctx->bytes[0] = t + len) < t) | |||
| ctx->bytes[1]++; /* Carry from low to high */ | |||
| t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */ | |||
| if (t > len) { | |||
| memcpy((FLAC__byte *)ctx->in + 64 - t, buf, len); | |||
| return; | |||
| } | |||
| /* First chunk is an odd size */ | |||
| memcpy((FLAC__byte *)ctx->in + 64 - t, buf, t); | |||
| byteSwapX16(ctx->in); | |||
| FLAC__MD5Transform(ctx->buf, ctx->in); | |||
| buf += t; | |||
| len -= t; | |||
| /* Process data in 64-byte chunks */ | |||
| while (len >= 64) { | |||
| memcpy(ctx->in, buf, 64); | |||
| byteSwapX16(ctx->in); | |||
| FLAC__MD5Transform(ctx->buf, ctx->in); | |||
| buf += 64; | |||
| len -= 64; | |||
| } | |||
| /* Handle any remaining bytes of data. */ | |||
| memcpy(ctx->in, buf, len); | |||
| } | |||
| /* | |||
| * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious | |||
| * initialization constants. | |||
| */ | |||
| void FLAC__MD5Init(FLAC__MD5Context *ctx) | |||
| { | |||
| ctx->buf[0] = 0x67452301; | |||
| ctx->buf[1] = 0xefcdab89; | |||
| ctx->buf[2] = 0x98badcfe; | |||
| ctx->buf[3] = 0x10325476; | |||
| ctx->bytes[0] = 0; | |||
| ctx->bytes[1] = 0; | |||
| ctx->internal_buf.p8 = 0; | |||
| ctx->capacity = 0; | |||
| } | |||
| /* | |||
| * Final wrapup - pad to 64-byte boundary with the bit pattern | |||
| * 1 0* (64-bit count of bits processed, MSB-first) | |||
| */ | |||
| void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *ctx) | |||
| { | |||
| int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */ | |||
| FLAC__byte *p = (FLAC__byte *)ctx->in + count; | |||
| /* Set the first char of padding to 0x80. There is always room. */ | |||
| *p++ = 0x80; | |||
| /* Bytes of padding needed to make 56 bytes (-8..55) */ | |||
| count = 56 - 1 - count; | |||
| if (count < 0) { /* Padding forces an extra block */ | |||
| memset(p, 0, count + 8); | |||
| byteSwapX16(ctx->in); | |||
| FLAC__MD5Transform(ctx->buf, ctx->in); | |||
| p = (FLAC__byte *)ctx->in; | |||
| count = 56; | |||
| } | |||
| memset(p, 0, count); | |||
| byteSwap(ctx->in, 14); | |||
| /* Append length in bits and transform */ | |||
| ctx->in[14] = ctx->bytes[0] << 3; | |||
| ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29; | |||
| FLAC__MD5Transform(ctx->buf, ctx->in); | |||
| byteSwap(ctx->buf, 4); | |||
| memcpy(digest, ctx->buf, 16); | |||
| if (0 != ctx->internal_buf.p8) { | |||
| free(ctx->internal_buf.p8); | |||
| ctx->internal_buf.p8 = 0; | |||
| ctx->capacity = 0; | |||
| } | |||
| memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ | |||
| } | |||
| /* | |||
| * Convert the incoming audio signal to a byte stream | |||
| */ | |||
| static void format_input_(FLAC__multibyte *mbuf, const FLAC__int32 * const signal[], uint32_t channels, uint32_t samples, uint32_t bytes_per_sample) | |||
| { | |||
| FLAC__byte *buf_ = mbuf->p8; | |||
| FLAC__int16 *buf16 = mbuf->p16; | |||
| FLAC__int32 *buf32 = mbuf->p32; | |||
| FLAC__int32 a_word; | |||
| uint32_t channel, sample; | |||
| /* Storage in the output buffer, buf, is little endian. */ | |||
| #define BYTES_CHANNEL_SELECTOR(bytes, channels) (bytes * 100 + channels) | |||
| /* First do the most commonly used combinations. */ | |||
| switch (BYTES_CHANNEL_SELECTOR (bytes_per_sample, channels)) { | |||
| /* One byte per sample. */ | |||
| case (BYTES_CHANNEL_SELECTOR (1, 1)): | |||
| for (sample = 0; sample < samples; sample++) | |||
| *buf_++ = signal[0][sample]; | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (1, 2)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf_++ = signal[0][sample]; | |||
| *buf_++ = signal[1][sample]; | |||
| } | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (1, 4)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf_++ = signal[0][sample]; | |||
| *buf_++ = signal[1][sample]; | |||
| *buf_++ = signal[2][sample]; | |||
| *buf_++ = signal[3][sample]; | |||
| } | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (1, 6)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf_++ = signal[0][sample]; | |||
| *buf_++ = signal[1][sample]; | |||
| *buf_++ = signal[2][sample]; | |||
| *buf_++ = signal[3][sample]; | |||
| *buf_++ = signal[4][sample]; | |||
| *buf_++ = signal[5][sample]; | |||
| } | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (1, 8)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf_++ = signal[0][sample]; | |||
| *buf_++ = signal[1][sample]; | |||
| *buf_++ = signal[2][sample]; | |||
| *buf_++ = signal[3][sample]; | |||
| *buf_++ = signal[4][sample]; | |||
| *buf_++ = signal[5][sample]; | |||
| *buf_++ = signal[6][sample]; | |||
| *buf_++ = signal[7][sample]; | |||
| } | |||
| return; | |||
| /* Two bytes per sample. */ | |||
| case (BYTES_CHANNEL_SELECTOR (2, 1)): | |||
| for (sample = 0; sample < samples; sample++) | |||
| *buf16++ = H2LE_16(signal[0][sample]); | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (2, 2)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf16++ = H2LE_16(signal[0][sample]); | |||
| *buf16++ = H2LE_16(signal[1][sample]); | |||
| } | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (2, 4)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf16++ = H2LE_16(signal[0][sample]); | |||
| *buf16++ = H2LE_16(signal[1][sample]); | |||
| *buf16++ = H2LE_16(signal[2][sample]); | |||
| *buf16++ = H2LE_16(signal[3][sample]); | |||
| } | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (2, 6)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf16++ = H2LE_16(signal[0][sample]); | |||
| *buf16++ = H2LE_16(signal[1][sample]); | |||
| *buf16++ = H2LE_16(signal[2][sample]); | |||
| *buf16++ = H2LE_16(signal[3][sample]); | |||
| *buf16++ = H2LE_16(signal[4][sample]); | |||
| *buf16++ = H2LE_16(signal[5][sample]); | |||
| } | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (2, 8)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf16++ = H2LE_16(signal[0][sample]); | |||
| *buf16++ = H2LE_16(signal[1][sample]); | |||
| *buf16++ = H2LE_16(signal[2][sample]); | |||
| *buf16++ = H2LE_16(signal[3][sample]); | |||
| *buf16++ = H2LE_16(signal[4][sample]); | |||
| *buf16++ = H2LE_16(signal[5][sample]); | |||
| *buf16++ = H2LE_16(signal[6][sample]); | |||
| *buf16++ = H2LE_16(signal[7][sample]); | |||
| } | |||
| return; | |||
| /* Three bytes per sample. */ | |||
| case (BYTES_CHANNEL_SELECTOR (3, 1)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| a_word = signal[0][sample]; | |||
| *buf_++ = (FLAC__byte)a_word; a_word >>= 8; | |||
| *buf_++ = (FLAC__byte)a_word; a_word >>= 8; | |||
| *buf_++ = (FLAC__byte)a_word; | |||
| } | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (3, 2)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| a_word = signal[0][sample]; | |||
| *buf_++ = (FLAC__byte)a_word; a_word >>= 8; | |||
| *buf_++ = (FLAC__byte)a_word; a_word >>= 8; | |||
| *buf_++ = (FLAC__byte)a_word; | |||
| a_word = signal[1][sample]; | |||
| *buf_++ = (FLAC__byte)a_word; a_word >>= 8; | |||
| *buf_++ = (FLAC__byte)a_word; a_word >>= 8; | |||
| *buf_++ = (FLAC__byte)a_word; | |||
| } | |||
| return; | |||
| /* Four bytes per sample. */ | |||
| case (BYTES_CHANNEL_SELECTOR (4, 1)): | |||
| for (sample = 0; sample < samples; sample++) | |||
| *buf32++ = H2LE_32(signal[0][sample]); | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (4, 2)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf32++ = H2LE_32(signal[0][sample]); | |||
| *buf32++ = H2LE_32(signal[1][sample]); | |||
| } | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (4, 4)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf32++ = H2LE_32(signal[0][sample]); | |||
| *buf32++ = H2LE_32(signal[1][sample]); | |||
| *buf32++ = H2LE_32(signal[2][sample]); | |||
| *buf32++ = H2LE_32(signal[3][sample]); | |||
| } | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (4, 6)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf32++ = H2LE_32(signal[0][sample]); | |||
| *buf32++ = H2LE_32(signal[1][sample]); | |||
| *buf32++ = H2LE_32(signal[2][sample]); | |||
| *buf32++ = H2LE_32(signal[3][sample]); | |||
| *buf32++ = H2LE_32(signal[4][sample]); | |||
| *buf32++ = H2LE_32(signal[5][sample]); | |||
| } | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (4, 8)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf32++ = H2LE_32(signal[0][sample]); | |||
| *buf32++ = H2LE_32(signal[1][sample]); | |||
| *buf32++ = H2LE_32(signal[2][sample]); | |||
| *buf32++ = H2LE_32(signal[3][sample]); | |||
| *buf32++ = H2LE_32(signal[4][sample]); | |||
| *buf32++ = H2LE_32(signal[5][sample]); | |||
| *buf32++ = H2LE_32(signal[6][sample]); | |||
| *buf32++ = H2LE_32(signal[7][sample]); | |||
| } | |||
| return; | |||
| default: | |||
| break; | |||
| } | |||
| /* General version. */ | |||
| switch (bytes_per_sample) { | |||
| case 1: | |||
| for (sample = 0; sample < samples; sample++) | |||
| for (channel = 0; channel < channels; channel++) | |||
| *buf_++ = signal[channel][sample]; | |||
| return; | |||
| case 2: | |||
| for (sample = 0; sample < samples; sample++) | |||
| for (channel = 0; channel < channels; channel++) | |||
| *buf16++ = H2LE_16(signal[channel][sample]); | |||
| return; | |||
| case 3: | |||
| for (sample = 0; sample < samples; sample++) | |||
| for (channel = 0; channel < channels; channel++) { | |||
| a_word = signal[channel][sample]; | |||
| *buf_++ = (FLAC__byte)a_word; a_word >>= 8; | |||
| *buf_++ = (FLAC__byte)a_word; a_word >>= 8; | |||
| *buf_++ = (FLAC__byte)a_word; | |||
| } | |||
| return; | |||
| case 4: | |||
| for (sample = 0; sample < samples; sample++) | |||
| for (channel = 0; channel < channels; channel++) | |||
| *buf32++ = H2LE_32(signal[channel][sample]); | |||
| return; | |||
| default: | |||
| break; | |||
| } | |||
| } | |||
| /* | |||
| * Convert the incoming audio signal to a byte stream and FLAC__MD5Update it. | |||
| */ | |||
| FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const signal[], uint32_t channels, uint32_t samples, uint32_t bytes_per_sample) | |||
| { | |||
| const size_t bytes_needed = (size_t)channels * (size_t)samples * (size_t)bytes_per_sample; | |||
| /* overflow check */ | |||
| if ((size_t)channels > SIZE_MAX / (size_t)bytes_per_sample) | |||
| return false; | |||
| if ((size_t)channels * (size_t)bytes_per_sample > SIZE_MAX / (size_t)samples) | |||
| return false; | |||
| if (ctx->capacity < bytes_needed) { | |||
| if (0 == (ctx->internal_buf.p8 = safe_realloc_(ctx->internal_buf.p8, bytes_needed))) { | |||
| if (0 == (ctx->internal_buf.p8 = safe_malloc_(bytes_needed))) { | |||
| ctx->capacity = 0; | |||
| return false; | |||
| } | |||
| } | |||
| ctx->capacity = bytes_needed; | |||
| } | |||
| format_input_(&ctx->internal_buf, signal, channels, samples, bytes_per_sample); | |||
| FLAC__MD5Update(ctx, ctx->internal_buf.p8, bytes_needed); | |||
| return true; | |||
| } | |||
| @@ -0,0 +1,219 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2001-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #ifdef HAVE_STDINT_H | |||
| #include <stdint.h> | |||
| #endif | |||
| #include "include/private/memory.h" | |||
| #include "../assert.h" | |||
| #include "../compat.h" | |||
| #include "../alloc.h" | |||
| void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address) | |||
| { | |||
| void *x; | |||
| FLAC__ASSERT(0 != aligned_address); | |||
| #ifdef FLAC__ALIGN_MALLOC_DATA | |||
| /* align on 32-byte (256-bit) boundary */ | |||
| x = safe_malloc_add_2op_(bytes, /*+*/31L); | |||
| *aligned_address = (void*)(((uintptr_t)x + 31L) & -32L); | |||
| #else | |||
| x = safe_malloc_(bytes); | |||
| *aligned_address = x; | |||
| #endif | |||
| return x; | |||
| } | |||
| FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer) | |||
| { | |||
| FLAC__int32 *pu; /* unaligned pointer */ | |||
| union { /* union needed to comply with C99 pointer aliasing rules */ | |||
| FLAC__int32 *pa; /* aligned pointer */ | |||
| void *pv; /* aligned pointer alias */ | |||
| } u; | |||
| FLAC__ASSERT(elements > 0); | |||
| FLAC__ASSERT(0 != unaligned_pointer); | |||
| FLAC__ASSERT(0 != aligned_pointer); | |||
| FLAC__ASSERT(unaligned_pointer != aligned_pointer); | |||
| if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ | |||
| return false; | |||
| pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); | |||
| if(0 == pu) { | |||
| return false; | |||
| } | |||
| else { | |||
| if(*unaligned_pointer != 0) | |||
| free(*unaligned_pointer); | |||
| *unaligned_pointer = pu; | |||
| *aligned_pointer = u.pa; | |||
| return true; | |||
| } | |||
| } | |||
| FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer) | |||
| { | |||
| FLAC__uint32 *pu; /* unaligned pointer */ | |||
| union { /* union needed to comply with C99 pointer aliasing rules */ | |||
| FLAC__uint32 *pa; /* aligned pointer */ | |||
| void *pv; /* aligned pointer alias */ | |||
| } u; | |||
| FLAC__ASSERT(elements > 0); | |||
| FLAC__ASSERT(0 != unaligned_pointer); | |||
| FLAC__ASSERT(0 != aligned_pointer); | |||
| FLAC__ASSERT(unaligned_pointer != aligned_pointer); | |||
| if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ | |||
| return false; | |||
| pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); | |||
| if(0 == pu) { | |||
| return false; | |||
| } | |||
| else { | |||
| if(*unaligned_pointer != 0) | |||
| free(*unaligned_pointer); | |||
| *unaligned_pointer = pu; | |||
| *aligned_pointer = u.pa; | |||
| return true; | |||
| } | |||
| } | |||
| FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer) | |||
| { | |||
| FLAC__uint64 *pu; /* unaligned pointer */ | |||
| union { /* union needed to comply with C99 pointer aliasing rules */ | |||
| FLAC__uint64 *pa; /* aligned pointer */ | |||
| void *pv; /* aligned pointer alias */ | |||
| } u; | |||
| FLAC__ASSERT(elements > 0); | |||
| FLAC__ASSERT(0 != unaligned_pointer); | |||
| FLAC__ASSERT(0 != aligned_pointer); | |||
| FLAC__ASSERT(unaligned_pointer != aligned_pointer); | |||
| if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ | |||
| return false; | |||
| pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); | |||
| if(0 == pu) { | |||
| return false; | |||
| } | |||
| else { | |||
| if(*unaligned_pointer != 0) | |||
| free(*unaligned_pointer); | |||
| *unaligned_pointer = pu; | |||
| *aligned_pointer = u.pa; | |||
| return true; | |||
| } | |||
| } | |||
| FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, uint32_t **unaligned_pointer, uint32_t **aligned_pointer) | |||
| { | |||
| uint32_t *pu; /* unaligned pointer */ | |||
| union { /* union needed to comply with C99 pointer aliasing rules */ | |||
| uint32_t *pa; /* aligned pointer */ | |||
| void *pv; /* aligned pointer alias */ | |||
| } u; | |||
| FLAC__ASSERT(elements > 0); | |||
| FLAC__ASSERT(0 != unaligned_pointer); | |||
| FLAC__ASSERT(0 != aligned_pointer); | |||
| FLAC__ASSERT(unaligned_pointer != aligned_pointer); | |||
| if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ | |||
| return false; | |||
| pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); | |||
| if(0 == pu) { | |||
| return false; | |||
| } | |||
| else { | |||
| if(*unaligned_pointer != 0) | |||
| free(*unaligned_pointer); | |||
| *unaligned_pointer = pu; | |||
| *aligned_pointer = u.pa; | |||
| return true; | |||
| } | |||
| } | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| FLAC__bool FLAC__memory_alloc_aligned_real_array(size_t elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer) | |||
| { | |||
| FLAC__real *pu; /* unaligned pointer */ | |||
| union { /* union needed to comply with C99 pointer aliasing rules */ | |||
| FLAC__real *pa; /* aligned pointer */ | |||
| void *pv; /* aligned pointer alias */ | |||
| } u; | |||
| FLAC__ASSERT(elements > 0); | |||
| FLAC__ASSERT(0 != unaligned_pointer); | |||
| FLAC__ASSERT(0 != aligned_pointer); | |||
| FLAC__ASSERT(unaligned_pointer != aligned_pointer); | |||
| if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ | |||
| return false; | |||
| pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); | |||
| if(0 == pu) { | |||
| return false; | |||
| } | |||
| else { | |||
| if(*unaligned_pointer != 0) | |||
| free(*unaligned_pointer); | |||
| *unaligned_pointer = pu; | |||
| *aligned_pointer = u.pa; | |||
| return true; | |||
| } | |||
| } | |||
| #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); | |||
| } | |||
| @@ -0,0 +1,251 @@ | |||
| /* libFLAC - Free Lossless Audio Codec | |||
| * Copyright (C) 2002-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include <string.h> /* for memcpy() */ | |||
| #include "../assert.h" | |||
| #include "include/private/ogg_decoder_aspect.h" | |||
| #include "include/private/ogg_mapping.h" | |||
| #include "include/private/macros.h" | |||
| /*********************************************************************** | |||
| * | |||
| * Public class methods | |||
| * | |||
| ***********************************************************************/ | |||
| FLAC__bool FLAC__ogg_decoder_aspect_init(FLAC__OggDecoderAspect *aspect) | |||
| { | |||
| /* we will determine the serial number later if necessary */ | |||
| if(ogg_stream_init(&aspect->stream_state, aspect->serial_number) != 0) | |||
| return false; | |||
| if(ogg_sync_init(&aspect->sync_state) != 0) | |||
| return false; | |||
| aspect->version_major = ~(0u); | |||
| aspect->version_minor = ~(0u); | |||
| aspect->need_serial_number = aspect->use_first_serial_number; | |||
| aspect->end_of_stream = false; | |||
| aspect->have_working_page = false; | |||
| return true; | |||
| } | |||
| void FLAC__ogg_decoder_aspect_finish(FLAC__OggDecoderAspect *aspect) | |||
| { | |||
| (void)ogg_sync_clear(&aspect->sync_state); | |||
| (void)ogg_stream_clear(&aspect->stream_state); | |||
| } | |||
| void FLAC__ogg_decoder_aspect_set_serial_number(FLAC__OggDecoderAspect *aspect, long value) | |||
| { | |||
| aspect->use_first_serial_number = false; | |||
| aspect->serial_number = value; | |||
| } | |||
| void FLAC__ogg_decoder_aspect_set_defaults(FLAC__OggDecoderAspect *aspect) | |||
| { | |||
| aspect->use_first_serial_number = true; | |||
| } | |||
| void FLAC__ogg_decoder_aspect_flush(FLAC__OggDecoderAspect *aspect) | |||
| { | |||
| (void)ogg_stream_reset(&aspect->stream_state); | |||
| (void)ogg_sync_reset(&aspect->sync_state); | |||
| aspect->end_of_stream = false; | |||
| aspect->have_working_page = false; | |||
| } | |||
| void FLAC__ogg_decoder_aspect_reset(FLAC__OggDecoderAspect *aspect) | |||
| { | |||
| FLAC__ogg_decoder_aspect_flush(aspect); | |||
| if(aspect->use_first_serial_number) | |||
| aspect->need_serial_number = true; | |||
| } | |||
| FLAC__OggDecoderAspectReadStatus FLAC__ogg_decoder_aspect_read_callback_wrapper(FLAC__OggDecoderAspect *aspect, FLAC__byte buffer[], size_t *bytes, FLAC__OggDecoderAspectReadCallbackProxy read_callback, const FLAC__StreamDecoder *decoder, void *client_data) | |||
| { | |||
| static const size_t OGG_BYTES_CHUNK = 8192; | |||
| const size_t bytes_requested = *bytes; | |||
| /* | |||
| * The FLAC decoding API uses pull-based reads, whereas Ogg decoding | |||
| * is push-based. In libFLAC, when you ask to decode a frame, the | |||
| * decoder will eventually call the read callback to supply some data, | |||
| * but how much it asks for depends on how much free space it has in | |||
| * its internal buffer. It does not try to grow its internal buffer | |||
| * to accommodate a whole frame because then the internal buffer size | |||
| * could not be limited, which is necessary in embedded applications. | |||
| * | |||
| * Ogg however grows its internal buffer until a whole page is present; | |||
| * only then can you get decoded data out. So we can't just ask for | |||
| * the same number of bytes from Ogg, then pass what's decoded down to | |||
| * libFLAC. If what libFLAC is asking for will not contain a whole | |||
| * page, then we will get no data from ogg_sync_pageout(), and at the | |||
| * same time cannot just read more data from the client for the purpose | |||
| * of getting a whole decoded page because the decoded size might be | |||
| * larger than libFLAC's internal buffer. | |||
| * | |||
| * Instead, whenever this read callback wrapper is called, we will | |||
| * continually request data from the client until we have at least one | |||
| * page, and manage pages internally so that we can send pieces of | |||
| * pages down to libFLAC in such a way that we obey its size | |||
| * requirement. To limit the amount of callbacks, we will always try | |||
| * to read in enough pages to return the full number of bytes | |||
| * requested. | |||
| */ | |||
| *bytes = 0; | |||
| while (*bytes < bytes_requested && !aspect->end_of_stream) { | |||
| if (aspect->have_working_page) { | |||
| if (aspect->have_working_packet) { | |||
| size_t n = bytes_requested - *bytes; | |||
| if ((size_t)aspect->working_packet.bytes <= n) { | |||
| /* the rest of the packet will fit in the buffer */ | |||
| n = aspect->working_packet.bytes; | |||
| memcpy(buffer, aspect->working_packet.packet, n); | |||
| *bytes += n; | |||
| buffer += n; | |||
| aspect->have_working_packet = false; | |||
| } | |||
| else { | |||
| /* only n bytes of the packet will fit in the buffer */ | |||
| memcpy(buffer, aspect->working_packet.packet, n); | |||
| *bytes += n; | |||
| buffer += n; | |||
| aspect->working_packet.packet += n; | |||
| aspect->working_packet.bytes -= n; | |||
| } | |||
| } | |||
| else { | |||
| /* try and get another packet */ | |||
| const int ret = ogg_stream_packetout(&aspect->stream_state, &aspect->working_packet); | |||
| if (ret > 0) { | |||
| aspect->have_working_packet = true; | |||
| /* if it is the first header packet, check for magic and a supported Ogg FLAC mapping version */ | |||
| if (aspect->working_packet.bytes > 0 && aspect->working_packet.packet[0] == FLAC__OGG_MAPPING_FIRST_HEADER_PACKET_TYPE) { | |||
| const FLAC__byte *b = aspect->working_packet.packet; | |||
| const uint32_t header_length = | |||
| FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH + | |||
| FLAC__OGG_MAPPING_MAGIC_LENGTH + | |||
| FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH + | |||
| FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH + | |||
| FLAC__OGG_MAPPING_NUM_HEADERS_LENGTH; | |||
| if (aspect->working_packet.bytes < (long)header_length) | |||
| return FLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC; | |||
| b += FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH; | |||
| if (memcmp(b, FLAC__OGG_MAPPING_MAGIC, FLAC__OGG_MAPPING_MAGIC_LENGTH)) | |||
| return FLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC; | |||
| b += FLAC__OGG_MAPPING_MAGIC_LENGTH; | |||
| aspect->version_major = (uint32_t)(*b); | |||
| b += FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH; | |||
| aspect->version_minor = (uint32_t)(*b); | |||
| if (aspect->version_major != 1) | |||
| return FLAC__OGG_DECODER_ASPECT_READ_STATUS_UNSUPPORTED_MAPPING_VERSION; | |||
| aspect->working_packet.packet += header_length; | |||
| aspect->working_packet.bytes -= header_length; | |||
| } | |||
| } | |||
| else if (ret == 0) { | |||
| aspect->have_working_page = false; | |||
| } | |||
| else { /* ret < 0 */ | |||
| /* lost sync, we'll leave the working page for the next call */ | |||
| return FLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC; | |||
| } | |||
| } | |||
| } | |||
| else { | |||
| /* try and get another page */ | |||
| const int ret = ogg_sync_pageout(&aspect->sync_state, &aspect->working_page); | |||
| if (ret > 0) { | |||
| /* got a page, grab the serial number if necessary */ | |||
| if(aspect->need_serial_number) { | |||
| aspect->stream_state.serialno = aspect->serial_number = ogg_page_serialno(&aspect->working_page); | |||
| aspect->need_serial_number = false; | |||
| } | |||
| if(ogg_stream_pagein(&aspect->stream_state, &aspect->working_page) == 0) { | |||
| aspect->have_working_page = true; | |||
| aspect->have_working_packet = false; | |||
| } | |||
| /* else do nothing, could be a page from another stream */ | |||
| } | |||
| else if (ret == 0) { | |||
| /* need more data */ | |||
| const size_t ogg_bytes_to_read = flac_max(bytes_requested - *bytes, OGG_BYTES_CHUNK); | |||
| char *oggbuf = ogg_sync_buffer(&aspect->sync_state, ogg_bytes_to_read); | |||
| if(0 == oggbuf) { | |||
| return FLAC__OGG_DECODER_ASPECT_READ_STATUS_MEMORY_ALLOCATION_ERROR; | |||
| } | |||
| else { | |||
| size_t ogg_bytes_read = ogg_bytes_to_read; | |||
| switch(read_callback(decoder, (FLAC__byte*)oggbuf, &ogg_bytes_read, client_data)) { | |||
| case FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK: | |||
| break; | |||
| case FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM: | |||
| aspect->end_of_stream = true; | |||
| break; | |||
| case FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT: | |||
| return FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT; | |||
| default: | |||
| FLAC__ASSERT(0); | |||
| } | |||
| if(ogg_sync_wrote(&aspect->sync_state, ogg_bytes_read) < 0) { | |||
| /* double protection; this will happen if the read callback returns more bytes than the max requested, which would overflow Ogg's internal buffer */ | |||
| FLAC__ASSERT(0); | |||
| return FLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR; | |||
| } | |||
| } | |||
| } | |||
| else { /* ret < 0 */ | |||
| /* lost sync, bail out */ | |||
| return FLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC; | |||
| } | |||
| } | |||
| } | |||
| if (aspect->end_of_stream && *bytes == 0) { | |||
| return FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM; | |||
| } | |||
| return FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK; | |||
| } | |||
| @@ -0,0 +1,228 @@ | |||
| /* libFLAC - Free Lossless Audio Codec | |||
| * Copyright (C) 2002-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include <string.h> /* for memset() */ | |||
| #include "../assert.h" | |||
| #include "include/private/ogg_encoder_aspect.h" | |||
| #include "include/private/ogg_mapping.h" | |||
| static const FLAC__byte FLAC__OGG_MAPPING_VERSION_MAJOR = 1; | |||
| static const FLAC__byte FLAC__OGG_MAPPING_VERSION_MINOR = 0; | |||
| /*********************************************************************** | |||
| * | |||
| * Public class methods | |||
| * | |||
| ***********************************************************************/ | |||
| FLAC__bool FLAC__ogg_encoder_aspect_init(FLAC__OggEncoderAspect *aspect) | |||
| { | |||
| /* we will determine the serial number later if necessary */ | |||
| if(ogg_stream_init(&aspect->stream_state, aspect->serial_number) != 0) | |||
| return false; | |||
| aspect->seen_magic = false; | |||
| aspect->is_first_packet = true; | |||
| aspect->samples_written = 0; | |||
| return true; | |||
| } | |||
| void FLAC__ogg_encoder_aspect_finish(FLAC__OggEncoderAspect *aspect) | |||
| { | |||
| (void)ogg_stream_clear(&aspect->stream_state); | |||
| /*@@@ what about the page? */ | |||
| } | |||
| void FLAC__ogg_encoder_aspect_set_serial_number(FLAC__OggEncoderAspect *aspect, long value) | |||
| { | |||
| aspect->serial_number = value; | |||
| } | |||
| FLAC__bool FLAC__ogg_encoder_aspect_set_num_metadata(FLAC__OggEncoderAspect *aspect, uint32_t value) | |||
| { | |||
| if(value < (1u << FLAC__OGG_MAPPING_NUM_HEADERS_LEN)) { | |||
| aspect->num_metadata = value; | |||
| return true; | |||
| } | |||
| else | |||
| return false; | |||
| } | |||
| void FLAC__ogg_encoder_aspect_set_defaults(FLAC__OggEncoderAspect *aspect) | |||
| { | |||
| aspect->serial_number = 0; | |||
| aspect->num_metadata = 0; | |||
| } | |||
| /* | |||
| * The basic FLAC -> Ogg mapping goes like this: | |||
| * | |||
| * - 'fLaC' magic and STREAMINFO block get combined into the first | |||
| * packet. The packet is prefixed with | |||
| * + the one-byte packet type 0x7F | |||
| * + 'FLAC' magic | |||
| * + the 2 byte Ogg FLAC mapping version number | |||
| * + tne 2 byte big-endian # of header packets | |||
| * - The first packet is flushed to the first page. | |||
| * - Each subsequent metadata block goes into its own packet. | |||
| * - Each metadata packet is flushed to page (this is not required, | |||
| * the mapping only requires that a flush must occur after all | |||
| * metadata is written). | |||
| * - Each subsequent FLAC audio frame goes into its own packet. | |||
| * | |||
| * WATCHOUT: | |||
| * This depends on the behavior of FLAC__StreamEncoder that we get a | |||
| * separate write callback for the fLaC magic, and then separate write | |||
| * callbacks for each metadata block and audio frame. | |||
| */ | |||
| FLAC__StreamEncoderWriteStatus FLAC__ogg_encoder_aspect_write_callback_wrapper(FLAC__OggEncoderAspect *aspect, const FLAC__byte buffer[], size_t bytes, uint32_t samples, uint32_t current_frame, FLAC__bool is_last_block, FLAC__OggEncoderAspectWriteCallbackProxy write_callback, void *encoder, void *client_data) | |||
| { | |||
| /* WATCHOUT: | |||
| * This depends on the behavior of FLAC__StreamEncoder that 'samples' | |||
| * will be 0 for metadata writes. | |||
| */ | |||
| const FLAC__bool is_metadata = (samples == 0); | |||
| /* | |||
| * Treat fLaC magic packet specially. We will note when we see it, then | |||
| * wait until we get the STREAMINFO and prepend it in that packet | |||
| */ | |||
| if(aspect->seen_magic) { | |||
| ogg_packet packet; | |||
| FLAC__byte synthetic_first_packet_body[ | |||
| FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH + | |||
| FLAC__OGG_MAPPING_MAGIC_LENGTH + | |||
| FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH + | |||
| FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH + | |||
| FLAC__OGG_MAPPING_NUM_HEADERS_LENGTH + | |||
| FLAC__STREAM_SYNC_LENGTH + | |||
| FLAC__STREAM_METADATA_HEADER_LENGTH + | |||
| FLAC__STREAM_METADATA_STREAMINFO_LENGTH | |||
| ]; | |||
| memset(&packet, 0, sizeof(packet)); | |||
| packet.granulepos = aspect->samples_written + samples; | |||
| if(aspect->is_first_packet) { | |||
| FLAC__byte *b = synthetic_first_packet_body; | |||
| if(bytes != FLAC__STREAM_METADATA_HEADER_LENGTH + FLAC__STREAM_METADATA_STREAMINFO_LENGTH) { | |||
| /* | |||
| * If we get here, our assumption about the way write callbacks happen | |||
| * (explained above) is wrong | |||
| */ | |||
| FLAC__ASSERT(0); | |||
| return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; | |||
| } | |||
| /* add first header packet type */ | |||
| *b = FLAC__OGG_MAPPING_FIRST_HEADER_PACKET_TYPE; | |||
| b += FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH; | |||
| /* add 'FLAC' mapping magic */ | |||
| memcpy(b, FLAC__OGG_MAPPING_MAGIC, FLAC__OGG_MAPPING_MAGIC_LENGTH); | |||
| b += FLAC__OGG_MAPPING_MAGIC_LENGTH; | |||
| /* add Ogg FLAC mapping major version number */ | |||
| memcpy(b, &FLAC__OGG_MAPPING_VERSION_MAJOR, FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH); | |||
| b += FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH; | |||
| /* add Ogg FLAC mapping minor version number */ | |||
| memcpy(b, &FLAC__OGG_MAPPING_VERSION_MINOR, FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH); | |||
| b += FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH; | |||
| /* add number of header packets */ | |||
| *b = (FLAC__byte)(aspect->num_metadata >> 8); | |||
| b++; | |||
| *b = (FLAC__byte)(aspect->num_metadata); | |||
| b++; | |||
| /* add native FLAC 'fLaC' magic */ | |||
| memcpy(b, FLAC__STREAM_SYNC_STRING, FLAC__STREAM_SYNC_LENGTH); | |||
| b += FLAC__STREAM_SYNC_LENGTH; | |||
| /* add STREAMINFO */ | |||
| memcpy(b, buffer, bytes); | |||
| FLAC__ASSERT(b + bytes - synthetic_first_packet_body == sizeof(synthetic_first_packet_body)); | |||
| packet.packet = (uint8_t *)synthetic_first_packet_body; | |||
| packet.bytes = sizeof(synthetic_first_packet_body); | |||
| packet.b_o_s = 1; | |||
| aspect->is_first_packet = false; | |||
| } | |||
| else { | |||
| packet.packet = (uint8_t *)buffer; | |||
| packet.bytes = bytes; | |||
| } | |||
| if(is_last_block) { | |||
| /* we used to check: | |||
| * FLAC__ASSERT(total_samples_estimate == 0 || total_samples_estimate == aspect->samples_written + samples); | |||
| * but it's really not useful since total_samples_estimate is an estimate and can be inexact | |||
| */ | |||
| packet.e_o_s = 1; | |||
| } | |||
| if(ogg_stream_packetin(&aspect->stream_state, &packet) != 0) | |||
| return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; | |||
| /*@@@ can't figure out a way to pass a useful number for 'samples' to the write_callback, so we'll just pass 0 */ | |||
| if(is_metadata) { | |||
| while(ogg_stream_flush(&aspect->stream_state, &aspect->page) != 0) { | |||
| if(write_callback(encoder, aspect->page.header, aspect->page.header_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) | |||
| return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; | |||
| if(write_callback(encoder, aspect->page.body, aspect->page.body_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) | |||
| return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; | |||
| } | |||
| } | |||
| else { | |||
| while(ogg_stream_pageout(&aspect->stream_state, &aspect->page) != 0) { | |||
| if(write_callback(encoder, aspect->page.header, aspect->page.header_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) | |||
| return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; | |||
| if(write_callback(encoder, aspect->page.body, aspect->page.body_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) | |||
| return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; | |||
| } | |||
| } | |||
| } | |||
| else if(is_metadata && current_frame == 0 && samples == 0 && bytes == 4 && 0 == memcmp(buffer, FLAC__STREAM_SYNC_STRING, sizeof(FLAC__STREAM_SYNC_STRING))) { | |||
| aspect->seen_magic = true; | |||
| } | |||
| else { | |||
| /* | |||
| * If we get here, our assumption about the way write callbacks happen | |||
| * explained above is wrong | |||
| */ | |||
| FLAC__ASSERT(0); | |||
| return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; | |||
| } | |||
| aspect->samples_written += samples; | |||
| return FLAC__STREAM_ENCODER_WRITE_STATUS_OK; | |||
| } | |||
| @@ -0,0 +1,210 @@ | |||
| /* libFLAC - Free Lossless Audio Codec | |||
| * Copyright (C) 2004-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include <stdlib.h> /* for malloc() */ | |||
| #include <string.h> /* for memcmp(), memcpy() */ | |||
| #include "../assert.h" | |||
| #include "../alloc.h" | |||
| #include "include/private/ogg_helper.h" | |||
| #include "include/protected/stream_encoder.h" | |||
| static FLAC__bool full_read_(FLAC__StreamEncoder *encoder, FLAC__byte *buffer, size_t bytes, FLAC__StreamEncoderReadCallback read_callback, void *client_data) | |||
| { | |||
| while(bytes > 0) { | |||
| size_t bytes_read = bytes; | |||
| switch(read_callback(encoder, buffer, &bytes_read, client_data)) { | |||
| case FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE: | |||
| bytes -= bytes_read; | |||
| buffer += bytes_read; | |||
| break; | |||
| case FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM: | |||
| if(bytes_read == 0) { | |||
| encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; | |||
| return false; | |||
| } | |||
| bytes -= bytes_read; | |||
| buffer += bytes_read; | |||
| break; | |||
| case FLAC__STREAM_ENCODER_READ_STATUS_ABORT: | |||
| encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; | |||
| return false; | |||
| case FLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED: | |||
| return false; | |||
| default: | |||
| /* double protection: */ | |||
| FLAC__ASSERT(0); | |||
| encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; | |||
| return false; | |||
| } | |||
| } | |||
| return true; | |||
| } | |||
| void simple_ogg_page__init(ogg_page *page) | |||
| { | |||
| page->header = 0; | |||
| page->header_len = 0; | |||
| page->body = 0; | |||
| page->body_len = 0; | |||
| } | |||
| void simple_ogg_page__clear(ogg_page *page) | |||
| { | |||
| if(page->header) | |||
| free(page->header); | |||
| if(page->body) | |||
| free(page->body); | |||
| simple_ogg_page__init(page); | |||
| } | |||
| FLAC__bool simple_ogg_page__get_at(FLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderReadCallback read_callback, void *client_data) | |||
| { | |||
| static const uint32_t OGG_HEADER_FIXED_PORTION_LEN = 27; | |||
| static const uint32_t OGG_MAX_HEADER_LEN = 27/*OGG_HEADER_FIXED_PORTION_LEN*/ + 255; | |||
| FLAC__byte crc[4]; | |||
| FLAC__StreamEncoderSeekStatus seek_status; | |||
| FLAC__ASSERT(page->header == 0); | |||
| FLAC__ASSERT(page->header_len == 0); | |||
| FLAC__ASSERT(page->body == 0); | |||
| FLAC__ASSERT(page->body_len == 0); | |||
| /* move the stream pointer to the supposed beginning of the page */ | |||
| if(0 == seek_callback) | |||
| return false; | |||
| if((seek_status = seek_callback((FLAC__StreamEncoder*)encoder, position, client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) { | |||
| if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR) | |||
| encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; | |||
| return false; | |||
| } | |||
| /* allocate space for the page header */ | |||
| if(0 == (page->header = safe_malloc_(OGG_MAX_HEADER_LEN))) { | |||
| encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; | |||
| return false; | |||
| } | |||
| /* read in the fixed part of the page header (up to but not including | |||
| * the segment table */ | |||
| if(!full_read_(encoder, page->header, OGG_HEADER_FIXED_PORTION_LEN, read_callback, client_data)) | |||
| return false; | |||
| page->header_len = OGG_HEADER_FIXED_PORTION_LEN + page->header[26]; | |||
| /* check to see if it's a correct, "simple" page (one packet only) */ | |||
| if( | |||
| memcmp(page->header, "OggS", 4) || /* doesn't start with OggS */ | |||
| (page->header[5] & 0x01) || /* continued packet */ | |||
| memcmp(page->header+6, "\0\0\0\0\0\0\0\0", 8) || /* granulepos is non-zero */ | |||
| page->header[26] == 0 /* packet is 0-size */ | |||
| ) { | |||
| encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; | |||
| return false; | |||
| } | |||
| /* read in the segment table */ | |||
| if(!full_read_(encoder, page->header + OGG_HEADER_FIXED_PORTION_LEN, page->header[26], read_callback, client_data)) | |||
| return false; | |||
| { | |||
| uint32_t i; | |||
| /* check to see that it specifies a single packet */ | |||
| for(i = 0; i < (uint32_t)page->header[26] - 1; i++) { | |||
| if(page->header[i + OGG_HEADER_FIXED_PORTION_LEN] != 255) { | |||
| encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; | |||
| return false; | |||
| } | |||
| } | |||
| page->body_len = 255 * i + page->header[i + OGG_HEADER_FIXED_PORTION_LEN]; | |||
| } | |||
| /* allocate space for the page body */ | |||
| if(0 == (page->body = safe_malloc_(page->body_len))) { | |||
| encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; | |||
| return false; | |||
| } | |||
| /* read in the page body */ | |||
| if(!full_read_(encoder, page->body, page->body_len, read_callback, client_data)) | |||
| return false; | |||
| /* check the CRC */ | |||
| memcpy(crc, page->header+22, 4); | |||
| ogg_page_checksum_set(page); | |||
| if(memcmp(crc, page->header+22, 4)) { | |||
| encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| FLAC__bool simple_ogg_page__set_at(FLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderWriteCallback write_callback, void *client_data) | |||
| { | |||
| FLAC__StreamEncoderSeekStatus seek_status; | |||
| FLAC__ASSERT(page->header != 0); | |||
| FLAC__ASSERT(page->header_len != 0); | |||
| FLAC__ASSERT(page->body != 0); | |||
| FLAC__ASSERT(page->body_len != 0); | |||
| /* move the stream pointer to the supposed beginning of the page */ | |||
| if(0 == seek_callback) | |||
| return false; | |||
| if((seek_status = seek_callback((FLAC__StreamEncoder*)encoder, position, client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) { | |||
| if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR) | |||
| encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; | |||
| return false; | |||
| } | |||
| ogg_page_checksum_set(page); | |||
| /* re-write the page */ | |||
| if(write_callback((FLAC__StreamEncoder*)encoder, page->header, page->header_len, 0, 0, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { | |||
| encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; | |||
| return false; | |||
| } | |||
| if(write_callback((FLAC__StreamEncoder*)encoder, page->body, page->body_len, 0, 0, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { | |||
| encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| @@ -0,0 +1,48 @@ | |||
| /* libFLAC - Free Lossless Audio Codec | |||
| * Copyright (C) 2004-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include "include/private/ogg_mapping.h" | |||
| const uint32_t FLAC__OGG_MAPPING_PACKET_TYPE_LEN = 8; /* bits */ | |||
| const FLAC__byte FLAC__OGG_MAPPING_FIRST_HEADER_PACKET_TYPE = 0x7f; | |||
| const FLAC__byte * const FLAC__OGG_MAPPING_MAGIC = (const FLAC__byte * const)"FLAC"; | |||
| const uint32_t FLAC__OGG_MAPPING_VERSION_MAJOR_LEN = 8; /* bits */ | |||
| const uint32_t FLAC__OGG_MAPPING_VERSION_MINOR_LEN = 8; /* bits */ | |||
| const uint32_t FLAC__OGG_MAPPING_NUM_HEADERS_LEN = 16; /* bits */ | |||
| @@ -0,0 +1,554 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include <stdio.h> | |||
| #include <string.h> /* for strlen() */ | |||
| #include "include/private/stream_encoder_framing.h" | |||
| #include "include/private/crc.h" | |||
| #include "../assert.h" | |||
| #include "../compat.h" | |||
| 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 uint32_t residual_samples, const uint32_t predictor_order, const uint32_t rice_parameters[], const uint32_t raw_bits[], const uint32_t partition_order, const FLAC__bool is_extended); | |||
| FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__BitWriter *bw) | |||
| { | |||
| uint32_t i, j; | |||
| const uint32_t vendor_string_length = (uint32_t)strlen(FLAC__VENDOR_STRING); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->is_last, FLAC__STREAM_METADATA_IS_LAST_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->type, FLAC__STREAM_METADATA_TYPE_LEN)) | |||
| return false; | |||
| /* | |||
| * First, for VORBIS_COMMENTs, adjust the length to reflect our vendor string | |||
| */ | |||
| i = metadata->length; | |||
| if(metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { | |||
| FLAC__ASSERT(metadata->data.vorbis_comment.vendor_string.length == 0 || 0 != metadata->data.vorbis_comment.vendor_string.entry); | |||
| i -= metadata->data.vorbis_comment.vendor_string.length; | |||
| i += vendor_string_length; | |||
| } | |||
| FLAC__ASSERT(i < (1u << FLAC__STREAM_METADATA_LENGTH_LEN)); | |||
| /* double protection */ | |||
| if(i >= (1u << FLAC__STREAM_METADATA_LENGTH_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, i, FLAC__STREAM_METADATA_LENGTH_LEN)) | |||
| return false; | |||
| switch(metadata->type) { | |||
| case FLAC__METADATA_TYPE_STREAMINFO: | |||
| FLAC__ASSERT(metadata->data.stream_info.min_blocksize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN)); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.min_blocksize, FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(metadata->data.stream_info.max_blocksize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN)); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.max_blocksize, FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(metadata->data.stream_info.min_framesize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN)); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.min_framesize, FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(metadata->data.stream_info.max_framesize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN)); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.max_framesize, FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(FLAC__format_sample_rate_is_valid(metadata->data.stream_info.sample_rate)); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.sample_rate, FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(metadata->data.stream_info.channels > 0); | |||
| FLAC__ASSERT(metadata->data.stream_info.channels <= (1u << FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN)); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.channels-1, FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(metadata->data.stream_info.bits_per_sample > 0); | |||
| FLAC__ASSERT(metadata->data.stream_info.bits_per_sample <= (1u << FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN)); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.bits_per_sample-1, FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(metadata->data.stream_info.total_samples < (FLAC__U64L(1) << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN)); | |||
| if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.stream_info.md5sum, 16)) | |||
| return false; | |||
| break; | |||
| case FLAC__METADATA_TYPE_PADDING: | |||
| if(!FLAC__bitwriter_write_zeroes(bw, metadata->length * 8)) | |||
| return false; | |||
| break; | |||
| case FLAC__METADATA_TYPE_APPLICATION: | |||
| if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.application.data, metadata->length - (FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8))) | |||
| return false; | |||
| break; | |||
| case FLAC__METADATA_TYPE_SEEKTABLE: | |||
| for(i = 0; i < metadata->data.seek_table.num_points; i++) { | |||
| if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.seek_table.points[i].sample_number, FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.seek_table.points[i].stream_offset, FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.seek_table.points[i].frame_samples, FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN)) | |||
| return false; | |||
| } | |||
| break; | |||
| case FLAC__METADATA_TYPE_VORBIS_COMMENT: | |||
| if(!FLAC__bitwriter_write_raw_uint32_little_endian(bw, vendor_string_length)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)FLAC__VENDOR_STRING, vendor_string_length)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32_little_endian(bw, metadata->data.vorbis_comment.num_comments)) | |||
| return false; | |||
| for(i = 0; i < metadata->data.vorbis_comment.num_comments; i++) { | |||
| if(!FLAC__bitwriter_write_raw_uint32_little_endian(bw, metadata->data.vorbis_comment.comments[i].length)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.vorbis_comment.comments[i].entry, metadata->data.vorbis_comment.comments[i].length)) | |||
| return false; | |||
| } | |||
| break; | |||
| case FLAC__METADATA_TYPE_CUESHEET: | |||
| FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN % 8 == 0); | |||
| if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)metadata->data.cue_sheet.media_catalog_number, FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN/8)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.cue_sheet.lead_in, FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.cue_sheet.is_cd? 1 : 0, FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_zeroes(bw, FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.cue_sheet.num_tracks, FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN)) | |||
| return false; | |||
| for(i = 0; i < metadata->data.cue_sheet.num_tracks; i++) { | |||
| const FLAC__StreamMetadata_CueSheet_Track *track = metadata->data.cue_sheet.tracks + i; | |||
| if(!FLAC__bitwriter_write_raw_uint64(bw, track->offset, FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, track->number, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 == 0); | |||
| if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)track->isrc, FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN/8)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, track->type, FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, track->pre_emphasis, FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_zeroes(bw, FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, track->num_indices, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN)) | |||
| return false; | |||
| for(j = 0; j < track->num_indices; j++) { | |||
| const FLAC__StreamMetadata_CueSheet_Index *indx = track->indices + j; | |||
| if(!FLAC__bitwriter_write_raw_uint64(bw, indx->offset, FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, indx->number, FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_zeroes(bw, FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN)) | |||
| return false; | |||
| } | |||
| } | |||
| break; | |||
| case FLAC__METADATA_TYPE_PICTURE: | |||
| { | |||
| size_t len; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.type, FLAC__STREAM_METADATA_PICTURE_TYPE_LEN)) | |||
| return false; | |||
| len = strlen(metadata->data.picture.mime_type); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, len, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)metadata->data.picture.mime_type, len)) | |||
| return false; | |||
| len = strlen((const char *)metadata->data.picture.description); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, len, FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.picture.description, len)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.width, FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.height, FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.depth, FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.colors, FLAC__STREAM_METADATA_PICTURE_COLORS_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.data_length, FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.picture.data, metadata->data.picture.data_length)) | |||
| return false; | |||
| } | |||
| break; | |||
| default: | |||
| if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.unknown.data, metadata->length)) | |||
| return false; | |||
| break; | |||
| } | |||
| FLAC__ASSERT(FLAC__bitwriter_is_byte_aligned(bw)); | |||
| return true; | |||
| } | |||
| FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWriter *bw) | |||
| { | |||
| uint32_t u, blocksize_hint, sample_rate_hint; | |||
| FLAC__byte crc; | |||
| FLAC__ASSERT(FLAC__bitwriter_is_byte_aligned(bw)); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__FRAME_HEADER_SYNC, FLAC__FRAME_HEADER_SYNC_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_RESERVED_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, (header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER)? 0 : 1, FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(header->blocksize > 0 && header->blocksize <= FLAC__MAX_BLOCK_SIZE); | |||
| /* when this assertion holds true, any legal blocksize can be expressed in the frame header */ | |||
| FLAC__ASSERT(FLAC__MAX_BLOCK_SIZE <= 65535u); | |||
| blocksize_hint = 0; | |||
| switch(header->blocksize) { | |||
| case 192: u = 1; break; | |||
| case 576: u = 2; break; | |||
| case 1152: u = 3; break; | |||
| case 2304: u = 4; break; | |||
| case 4608: u = 5; break; | |||
| case 256: u = 8; break; | |||
| case 512: u = 9; break; | |||
| case 1024: u = 10; break; | |||
| case 2048: u = 11; break; | |||
| case 4096: u = 12; break; | |||
| case 8192: u = 13; break; | |||
| case 16384: u = 14; break; | |||
| case 32768: u = 15; break; | |||
| default: | |||
| if(header->blocksize <= 0x100) | |||
| blocksize_hint = u = 6; | |||
| else | |||
| blocksize_hint = u = 7; | |||
| break; | |||
| } | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_BLOCK_SIZE_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(FLAC__format_sample_rate_is_valid(header->sample_rate)); | |||
| sample_rate_hint = 0; | |||
| switch(header->sample_rate) { | |||
| case 88200: u = 1; break; | |||
| case 176400: u = 2; break; | |||
| case 192000: u = 3; break; | |||
| case 8000: u = 4; break; | |||
| case 16000: u = 5; break; | |||
| case 22050: u = 6; break; | |||
| case 24000: u = 7; break; | |||
| case 32000: u = 8; break; | |||
| case 44100: u = 9; break; | |||
| case 48000: u = 10; break; | |||
| case 96000: u = 11; break; | |||
| default: | |||
| if(header->sample_rate <= 255000 && header->sample_rate % 1000 == 0) | |||
| sample_rate_hint = u = 12; | |||
| else if(header->sample_rate % 10 == 0) | |||
| sample_rate_hint = u = 14; | |||
| else if(header->sample_rate <= 0xffff) | |||
| sample_rate_hint = u = 13; | |||
| else | |||
| u = 0; | |||
| break; | |||
| } | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_SAMPLE_RATE_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(header->channels > 0 && header->channels <= (1u << FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN) && header->channels <= FLAC__MAX_CHANNELS); | |||
| switch(header->channel_assignment) { | |||
| case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: | |||
| u = header->channels - 1; | |||
| break; | |||
| case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE: | |||
| FLAC__ASSERT(header->channels == 2); | |||
| u = 8; | |||
| break; | |||
| case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE: | |||
| FLAC__ASSERT(header->channels == 2); | |||
| u = 9; | |||
| break; | |||
| case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE: | |||
| FLAC__ASSERT(header->channels == 2); | |||
| u = 10; | |||
| break; | |||
| default: | |||
| FLAC__ASSERT(0); | |||
| } | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(header->bits_per_sample > 0 && header->bits_per_sample <= (1u << FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN)); | |||
| switch(header->bits_per_sample) { | |||
| case 8 : u = 1; break; | |||
| case 12: u = 2; break; | |||
| case 16: u = 4; break; | |||
| case 20: u = 5; break; | |||
| case 24: u = 6; break; | |||
| default: u = 0; break; | |||
| } | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_ZERO_PAD_LEN)) | |||
| return false; | |||
| if(header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER) { | |||
| if(!FLAC__bitwriter_write_utf8_uint32(bw, header->number.frame_number)) | |||
| return false; | |||
| } | |||
| else { | |||
| if(!FLAC__bitwriter_write_utf8_uint64(bw, header->number.sample_number)) | |||
| return false; | |||
| } | |||
| if(blocksize_hint) | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, header->blocksize-1, (blocksize_hint==6)? 8:16)) | |||
| return false; | |||
| switch(sample_rate_hint) { | |||
| case 12: | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, header->sample_rate / 1000, 8)) | |||
| return false; | |||
| break; | |||
| case 13: | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, header->sample_rate, 16)) | |||
| return false; | |||
| break; | |||
| case 14: | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, header->sample_rate / 10, 16)) | |||
| return false; | |||
| break; | |||
| } | |||
| /* write the CRC */ | |||
| if(!FLAC__bitwriter_get_write_crc8(bw, &crc)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, crc, FLAC__FRAME_HEADER_CRC_LEN)) | |||
| return false; | |||
| return true; | |||
| } | |||
| FLAC__bool FLAC__subframe_add_constant(const FLAC__Subframe_Constant *subframe, uint32_t subframe_bps, uint32_t wasted_bits, FLAC__BitWriter *bw) | |||
| { | |||
| FLAC__bool ok; | |||
| ok = | |||
| FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN) && | |||
| (wasted_bits? FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1) : true) && | |||
| FLAC__bitwriter_write_raw_int32(bw, subframe->value, subframe_bps) | |||
| ; | |||
| return ok; | |||
| } | |||
| FLAC__bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, uint32_t residual_samples, uint32_t subframe_bps, uint32_t wasted_bits, FLAC__BitWriter *bw) | |||
| { | |||
| uint32_t i; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK | (subframe->order<<1) | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN)) | |||
| return false; | |||
| if(wasted_bits) | |||
| if(!FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1)) | |||
| return false; | |||
| for(i = 0; i < subframe->order; i++) | |||
| if(!FLAC__bitwriter_write_raw_int32(bw, subframe->warmup[i], subframe_bps)) | |||
| return false; | |||
| if(!add_entropy_coding_method_(bw, &subframe->entropy_coding_method)) | |||
| return false; | |||
| switch(subframe->entropy_coding_method.type) { | |||
| case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: | |||
| case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: | |||
| if(!add_residual_partitioned_rice_( | |||
| bw, | |||
| subframe->residual, | |||
| residual_samples, | |||
| subframe->order, | |||
| subframe->entropy_coding_method.data.partitioned_rice.contents->parameters, | |||
| subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits, | |||
| subframe->entropy_coding_method.data.partitioned_rice.order, | |||
| /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 | |||
| )) | |||
| return false; | |||
| break; | |||
| default: | |||
| FLAC__ASSERT(0); | |||
| } | |||
| return true; | |||
| } | |||
| FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, uint32_t residual_samples, uint32_t subframe_bps, uint32_t wasted_bits, FLAC__BitWriter *bw) | |||
| { | |||
| uint32_t i; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK | ((subframe->order-1)<<1) | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN)) | |||
| return false; | |||
| if(wasted_bits) | |||
| if(!FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1)) | |||
| return false; | |||
| for(i = 0; i < subframe->order; i++) | |||
| if(!FLAC__bitwriter_write_raw_int32(bw, subframe->warmup[i], subframe_bps)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, subframe->qlp_coeff_precision-1, FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_int32(bw, subframe->quantization_level, FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN)) | |||
| return false; | |||
| for(i = 0; i < subframe->order; i++) | |||
| if(!FLAC__bitwriter_write_raw_int32(bw, subframe->qlp_coeff[i], subframe->qlp_coeff_precision)) | |||
| return false; | |||
| if(!add_entropy_coding_method_(bw, &subframe->entropy_coding_method)) | |||
| return false; | |||
| switch(subframe->entropy_coding_method.type) { | |||
| case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: | |||
| case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: | |||
| if(!add_residual_partitioned_rice_( | |||
| bw, | |||
| subframe->residual, | |||
| residual_samples, | |||
| subframe->order, | |||
| subframe->entropy_coding_method.data.partitioned_rice.contents->parameters, | |||
| subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits, | |||
| subframe->entropy_coding_method.data.partitioned_rice.order, | |||
| /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 | |||
| )) | |||
| return false; | |||
| break; | |||
| default: | |||
| FLAC__ASSERT(0); | |||
| } | |||
| return true; | |||
| } | |||
| FLAC__bool FLAC__subframe_add_verbatim(const FLAC__Subframe_Verbatim *subframe, uint32_t samples, uint32_t subframe_bps, uint32_t wasted_bits, FLAC__BitWriter *bw) | |||
| { | |||
| uint32_t i; | |||
| const FLAC__int32 *signal = subframe->data; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN)) | |||
| return false; | |||
| if(wasted_bits) | |||
| if(!FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1)) | |||
| return false; | |||
| for(i = 0; i < samples; i++) | |||
| if(!FLAC__bitwriter_write_raw_int32(bw, signal[i], subframe_bps)) | |||
| return false; | |||
| return true; | |||
| } | |||
| FLAC__bool add_entropy_coding_method_(FLAC__BitWriter *bw, const FLAC__EntropyCodingMethod *method) | |||
| { | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, method->type, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN)) | |||
| return false; | |||
| switch(method->type) { | |||
| case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: | |||
| case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, method->data.partitioned_rice.order, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN)) | |||
| return false; | |||
| break; | |||
| default: | |||
| FLAC__ASSERT(0); | |||
| } | |||
| return true; | |||
| } | |||
| FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const uint32_t residual_samples, const uint32_t predictor_order, const uint32_t rice_parameters[], const uint32_t raw_bits[], const uint32_t partition_order, const FLAC__bool is_extended) | |||
| { | |||
| const uint32_t plen = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; | |||
| const uint32_t pesc = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; | |||
| if(partition_order == 0) { | |||
| uint32_t i; | |||
| if(raw_bits[0] == 0) { | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, rice_parameters[0], plen)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_rice_signed_block(bw, residual, residual_samples, rice_parameters[0])) | |||
| return false; | |||
| } | |||
| else { | |||
| FLAC__ASSERT(rice_parameters[0] == 0); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, pesc, plen)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, raw_bits[0], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN)) | |||
| return false; | |||
| for(i = 0; i < residual_samples; i++) { | |||
| if(!FLAC__bitwriter_write_raw_int32(bw, residual[i], raw_bits[0])) | |||
| return false; | |||
| } | |||
| } | |||
| return true; | |||
| } | |||
| else { | |||
| uint32_t i, j, k = 0, k_last = 0; | |||
| uint32_t partition_samples; | |||
| const uint32_t default_partition_samples = (residual_samples+predictor_order) >> partition_order; | |||
| for(i = 0; i < (1u<<partition_order); i++) { | |||
| partition_samples = default_partition_samples; | |||
| if(i == 0) | |||
| partition_samples -= predictor_order; | |||
| k += partition_samples; | |||
| if(raw_bits[i] == 0) { | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, rice_parameters[i], plen)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_rice_signed_block(bw, residual+k_last, k-k_last, rice_parameters[i])) | |||
| return false; | |||
| } | |||
| else { | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, pesc, plen)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, raw_bits[i], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN)) | |||
| return false; | |||
| for(j = k_last; j < k; j++) { | |||
| if(!FLAC__bitwriter_write_raw_int32(bw, residual[j], raw_bits[i])) | |||
| return false; | |||
| } | |||
| } | |||
| k_last = k; | |||
| } | |||
| return true; | |||
| } | |||
| } | |||
| @@ -0,0 +1,146 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include "include/private/cpu.h" | |||
| #ifndef FLAC__NO_ASM | |||
| #if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN | |||
| #include "include/private/stream_encoder.h" | |||
| #include "include/private/bitmath.h" | |||
| #ifdef FLAC__AVX2_SUPPORTED | |||
| #include <stdlib.h> /* for abs() */ | |||
| #include <immintrin.h> /* AVX2 */ | |||
| #include "../assert.h" | |||
| FLAC__SSE_TARGET("avx2") | |||
| void FLAC__precompute_partition_info_sums_intrin_avx2(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], | |||
| uint32_t residual_samples, uint32_t predictor_order, uint32_t min_partition_order, uint32_t max_partition_order, uint32_t bps) | |||
| { | |||
| const uint32_t default_partition_samples = (residual_samples + predictor_order) >> max_partition_order; | |||
| uint32_t partitions = 1u << max_partition_order; | |||
| FLAC__ASSERT(default_partition_samples > predictor_order); | |||
| /* first do max_partition_order */ | |||
| { | |||
| const uint32_t threshold = 32 - FLAC__bitmath_ilog2(default_partition_samples); | |||
| uint32_t partition, residual_sample, end = (uint32_t)(-(int32_t)predictor_order); | |||
| if(bps + FLAC__MAX_EXTRA_RESIDUAL_BPS < threshold) { | |||
| for(partition = residual_sample = 0; partition < partitions; partition++) { | |||
| __m256i sum256 = _mm256_setzero_si256(); | |||
| __m128i sum128; | |||
| end += default_partition_samples; | |||
| for( ; (int)residual_sample < (int)end-7; residual_sample+=8) { | |||
| __m256i res256 = _mm256_abs_epi32(_mm256_loadu_si256((const __m256i*)(residual+residual_sample))); | |||
| sum256 = _mm256_add_epi32(sum256, res256); | |||
| } | |||
| sum128 = _mm_add_epi32(_mm256_extracti128_si256(sum256, 1), _mm256_castsi256_si128(sum256)); | |||
| for( ; (int)residual_sample < (int)end-3; residual_sample+=4) { | |||
| __m128i res128 = _mm_abs_epi32(_mm_loadu_si128((const __m128i*)(residual+residual_sample))); | |||
| sum128 = _mm_add_epi32(sum128, res128); | |||
| } | |||
| for( ; residual_sample < end; residual_sample++) { | |||
| __m128i res128 = _mm_abs_epi32(_mm_cvtsi32_si128(residual[residual_sample])); | |||
| sum128 = _mm_add_epi32(sum128, res128); | |||
| } | |||
| sum128 = _mm_add_epi32(sum128, _mm_shuffle_epi32(sum128, _MM_SHUFFLE(1,0,3,2))); | |||
| sum128 = _mm_add_epi32(sum128, _mm_shufflelo_epi16(sum128, _MM_SHUFFLE(1,0,3,2))); | |||
| abs_residual_partition_sums[partition] = (FLAC__uint32)_mm_cvtsi128_si32(sum128); | |||
| /* workaround for MSVC bugs (at least versions 2015 and 2017 are affected) */ | |||
| #if (defined _MSC_VER) && (defined FLAC__CPU_X86_64) | |||
| abs_residual_partition_sums[partition] &= 0xFFFFFFFF; /**/ | |||
| #endif | |||
| } | |||
| } | |||
| else { /* have to pessimistically use 64 bits for accumulator */ | |||
| for(partition = residual_sample = 0; partition < partitions; partition++) { | |||
| __m256i sum256 = _mm256_setzero_si256(); | |||
| __m128i sum128; | |||
| end += default_partition_samples; | |||
| for( ; (int)residual_sample < (int)end-3; residual_sample+=4) { | |||
| __m128i res128 = _mm_abs_epi32(_mm_loadu_si128((const __m128i*)(residual+residual_sample))); | |||
| __m256i res256 = _mm256_cvtepu32_epi64(res128); | |||
| sum256 = _mm256_add_epi64(sum256, res256); | |||
| } | |||
| sum128 = _mm_add_epi64(_mm256_extracti128_si256(sum256, 1), _mm256_castsi256_si128(sum256)); | |||
| for( ; (int)residual_sample < (int)end-1; residual_sample+=2) { | |||
| __m128i res128 = _mm_abs_epi32(_mm_loadl_epi64((const __m128i*)(residual+residual_sample))); | |||
| res128 = _mm_cvtepu32_epi64(res128); | |||
| sum128 = _mm_add_epi64(sum128, res128); | |||
| } | |||
| for( ; residual_sample < end; residual_sample++) { | |||
| __m128i res128 = _mm_abs_epi32(_mm_cvtsi32_si128(residual[residual_sample])); | |||
| sum128 = _mm_add_epi64(sum128, res128); | |||
| } | |||
| sum128 = _mm_add_epi64(sum128, _mm_srli_si128(sum128, 8)); | |||
| _mm_storel_epi64((__m128i*)(abs_residual_partition_sums+partition), sum128); | |||
| } | |||
| } | |||
| } | |||
| /* now merge partitions for lower orders */ | |||
| { | |||
| uint32_t from_partition = 0, to_partition = partitions; | |||
| int partition_order; | |||
| for(partition_order = (int)max_partition_order - 1; partition_order >= (int)min_partition_order; partition_order--) { | |||
| uint32_t i; | |||
| partitions >>= 1; | |||
| for(i = 0; i < partitions; i++) { | |||
| abs_residual_partition_sums[to_partition++] = | |||
| abs_residual_partition_sums[from_partition ] + | |||
| abs_residual_partition_sums[from_partition+1]; | |||
| from_partition += 2; | |||
| } | |||
| } | |||
| } | |||
| _mm256_zeroupper(); | |||
| } | |||
| #endif /* FLAC__AVX2_SUPPORTED */ | |||
| #endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */ | |||
| #endif /* FLAC__NO_ASM */ | |||
| @@ -0,0 +1,159 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include "include/private/cpu.h" | |||
| #ifndef FLAC__NO_ASM | |||
| #if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN | |||
| #include "include/private/stream_encoder.h" | |||
| #include "include/private/bitmath.h" | |||
| #ifdef FLAC__SSE2_SUPPORTED | |||
| #include <stdlib.h> /* for abs() */ | |||
| #include <emmintrin.h> /* SSE2 */ | |||
| #include "../assert.h" | |||
| #include "../compat.h" | |||
| FLAC__SSE_TARGET("sse2") | |||
| static inline __m128i local_abs_epi32(__m128i val) | |||
| { | |||
| __m128i mask = _mm_srai_epi32(val, 31); | |||
| val = _mm_xor_si128(val, mask); | |||
| val = _mm_sub_epi32(val, mask); | |||
| return val; | |||
| } | |||
| FLAC__SSE_TARGET("sse2") | |||
| void FLAC__precompute_partition_info_sums_intrin_sse2(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], | |||
| uint32_t residual_samples, uint32_t predictor_order, uint32_t min_partition_order, uint32_t max_partition_order, uint32_t bps) | |||
| { | |||
| const uint32_t default_partition_samples = (residual_samples + predictor_order) >> max_partition_order; | |||
| uint32_t partitions = 1u << max_partition_order; | |||
| FLAC__ASSERT(default_partition_samples > predictor_order); | |||
| /* first do max_partition_order */ | |||
| { | |||
| const uint32_t threshold = 32 - FLAC__bitmath_ilog2(default_partition_samples); | |||
| uint32_t partition, residual_sample, end = (uint32_t)(-(int32_t)predictor_order); | |||
| if(bps + FLAC__MAX_EXTRA_RESIDUAL_BPS < threshold) { | |||
| for(partition = residual_sample = 0; partition < partitions; partition++) { | |||
| __m128i mm_sum = _mm_setzero_si128(); | |||
| uint32_t e1, e3; | |||
| end += default_partition_samples; | |||
| e1 = (residual_sample + 3) & ~3; e3 = end & ~3; | |||
| if(e1 > end) | |||
| e1 = end; /* try flac -l 1 -b 16 and you'll be here */ | |||
| /* assumption: residual[] is properly aligned so (residual + e1) is properly aligned too and _mm_loadu_si128() is fast */ | |||
| for( ; residual_sample < e1; residual_sample++) { | |||
| __m128i mm_res = local_abs_epi32(_mm_cvtsi32_si128(residual[residual_sample])); | |||
| mm_sum = _mm_add_epi32(mm_sum, mm_res); | |||
| } | |||
| for( ; residual_sample < e3; residual_sample+=4) { | |||
| __m128i mm_res = local_abs_epi32(_mm_loadu_si128((const __m128i*)(residual+residual_sample))); | |||
| mm_sum = _mm_add_epi32(mm_sum, mm_res); | |||
| } | |||
| for( ; residual_sample < end; residual_sample++) { | |||
| __m128i mm_res = local_abs_epi32(_mm_cvtsi32_si128(residual[residual_sample])); | |||
| mm_sum = _mm_add_epi32(mm_sum, mm_res); | |||
| } | |||
| mm_sum = _mm_add_epi32(mm_sum, _mm_shuffle_epi32(mm_sum, _MM_SHUFFLE(1,0,3,2))); | |||
| mm_sum = _mm_add_epi32(mm_sum, _mm_shufflelo_epi16(mm_sum, _MM_SHUFFLE(1,0,3,2))); | |||
| abs_residual_partition_sums[partition] = (FLAC__uint32)_mm_cvtsi128_si32(mm_sum); | |||
| /* workaround for MSVC bugs (at least versions 2015 and 2017 are affected) */ | |||
| #if (defined _MSC_VER) && (defined FLAC__CPU_X86_64) | |||
| abs_residual_partition_sums[partition] &= 0xFFFFFFFF; | |||
| #endif | |||
| } | |||
| } | |||
| else { /* have to pessimistically use 64 bits for accumulator */ | |||
| for(partition = residual_sample = 0; partition < partitions; partition++) { | |||
| __m128i mm_sum = _mm_setzero_si128(); | |||
| uint32_t e1, e3; | |||
| end += default_partition_samples; | |||
| e1 = (residual_sample + 1) & ~1; e3 = end & ~1; | |||
| FLAC__ASSERT(e1 <= end); | |||
| for( ; residual_sample < e1; residual_sample++) { | |||
| __m128i mm_res = local_abs_epi32(_mm_cvtsi32_si128(residual[residual_sample])); /* 0 0 0 |r0| == 00 |r0_64| */ | |||
| mm_sum = _mm_add_epi64(mm_sum, mm_res); | |||
| } | |||
| for( ; residual_sample < e3; residual_sample+=2) { | |||
| __m128i mm_res = local_abs_epi32(_mm_loadl_epi64((const __m128i*)(residual+residual_sample))); /* 0 0 |r1| |r0| */ | |||
| mm_res = _mm_shuffle_epi32(mm_res, _MM_SHUFFLE(3,1,2,0)); /* 0 |r1| 0 |r0| == |r1_64| |r0_64| */ | |||
| mm_sum = _mm_add_epi64(mm_sum, mm_res); | |||
| } | |||
| for( ; residual_sample < end; residual_sample++) { | |||
| __m128i mm_res = local_abs_epi32(_mm_cvtsi32_si128(residual[residual_sample])); | |||
| mm_sum = _mm_add_epi64(mm_sum, mm_res); | |||
| } | |||
| mm_sum = _mm_add_epi64(mm_sum, _mm_srli_si128(mm_sum, 8)); | |||
| _mm_storel_epi64((__m128i*)(abs_residual_partition_sums+partition), mm_sum); | |||
| } | |||
| } | |||
| } | |||
| /* now merge partitions for lower orders */ | |||
| { | |||
| uint32_t from_partition = 0, to_partition = partitions; | |||
| int partition_order; | |||
| for(partition_order = (int)max_partition_order - 1; partition_order >= (int)min_partition_order; partition_order--) { | |||
| uint32_t i; | |||
| partitions >>= 1; | |||
| for(i = 0; i < partitions; i++) { | |||
| abs_residual_partition_sums[to_partition++] = | |||
| abs_residual_partition_sums[from_partition ] + | |||
| abs_residual_partition_sums[from_partition+1]; | |||
| from_partition += 2; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| #endif /* FLAC__SSE2_SUPPORTED */ | |||
| #endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */ | |||
| #endif /* FLAC__NO_ASM */ | |||
| @@ -0,0 +1,148 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include "include/private/cpu.h" | |||
| #ifndef FLAC__NO_ASM | |||
| #if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN | |||
| #include "include/private/stream_encoder.h" | |||
| #include "include/private/bitmath.h" | |||
| #ifdef FLAC__SSSE3_SUPPORTED | |||
| #include <stdlib.h> /* for abs() */ | |||
| #include <tmmintrin.h> /* SSSE3 */ | |||
| #include "../assert.h" | |||
| FLAC__SSE_TARGET("ssse3") | |||
| void FLAC__precompute_partition_info_sums_intrin_ssse3(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], | |||
| uint32_t residual_samples, uint32_t predictor_order, uint32_t min_partition_order, uint32_t max_partition_order, uint32_t bps) | |||
| { | |||
| const uint32_t default_partition_samples = (residual_samples + predictor_order) >> max_partition_order; | |||
| uint32_t partitions = 1u << max_partition_order; | |||
| FLAC__ASSERT(default_partition_samples > predictor_order); | |||
| /* first do max_partition_order */ | |||
| { | |||
| const uint32_t threshold = 32 - FLAC__bitmath_ilog2(default_partition_samples); | |||
| uint32_t partition, residual_sample, end = (uint32_t)(-(int32_t)predictor_order); | |||
| if(bps + FLAC__MAX_EXTRA_RESIDUAL_BPS < threshold) { | |||
| for(partition = residual_sample = 0; partition < partitions; partition++) { | |||
| __m128i mm_sum = _mm_setzero_si128(); | |||
| uint32_t e1, e3; | |||
| end += default_partition_samples; | |||
| e1 = (residual_sample + 3) & ~3; e3 = end & ~3; | |||
| if(e1 > end) | |||
| e1 = end; /* try flac -l 1 -b 16 and you'll be here */ | |||
| /* assumption: residual[] is properly aligned so (residual + e1) is properly aligned too and _mm_loadu_si128() is fast */ | |||
| for( ; residual_sample < e1; residual_sample++) { | |||
| __m128i mm_res = _mm_abs_epi32(_mm_cvtsi32_si128(residual[residual_sample])); | |||
| mm_sum = _mm_add_epi32(mm_sum, mm_res); | |||
| } | |||
| for( ; residual_sample < e3; residual_sample+=4) { | |||
| __m128i mm_res = _mm_abs_epi32(_mm_loadu_si128((const __m128i*)(residual+residual_sample))); | |||
| mm_sum = _mm_add_epi32(mm_sum, mm_res); | |||
| } | |||
| for( ; residual_sample < end; residual_sample++) { | |||
| __m128i mm_res = _mm_abs_epi32(_mm_cvtsi32_si128(residual[residual_sample])); | |||
| mm_sum = _mm_add_epi32(mm_sum, mm_res); | |||
| } | |||
| mm_sum = _mm_add_epi32(mm_sum, _mm_shuffle_epi32(mm_sum, _MM_SHUFFLE(1,0,3,2))); | |||
| mm_sum = _mm_add_epi32(mm_sum, _mm_shufflelo_epi16(mm_sum, _MM_SHUFFLE(1,0,3,2))); | |||
| abs_residual_partition_sums[partition] = (FLAC__uint32)_mm_cvtsi128_si32(mm_sum); | |||
| /* workaround for MSVC bugs (at least versions 2015 and 2017 are affected) */ | |||
| #if (defined _MSC_VER) && (defined FLAC__CPU_X86_64) | |||
| abs_residual_partition_sums[partition] &= 0xFFFFFFFF; | |||
| #endif | |||
| } | |||
| } | |||
| else { /* have to pessimistically use 64 bits for accumulator */ | |||
| for(partition = residual_sample = 0; partition < partitions; partition++) { | |||
| __m128i mm_sum = _mm_setzero_si128(); | |||
| uint32_t e1, e3; | |||
| end += default_partition_samples; | |||
| e1 = (residual_sample + 1) & ~1; e3 = end & ~1; | |||
| FLAC__ASSERT(e1 <= end); | |||
| for( ; residual_sample < e1; residual_sample++) { | |||
| __m128i mm_res = _mm_abs_epi32(_mm_cvtsi32_si128(residual[residual_sample])); /* 0 0 0 |r0| == 00 |r0_64| */ | |||
| mm_sum = _mm_add_epi64(mm_sum, mm_res); | |||
| } | |||
| for( ; residual_sample < e3; residual_sample+=2) { | |||
| __m128i mm_res = _mm_abs_epi32(_mm_loadl_epi64((const __m128i*)(residual+residual_sample))); /* 0 0 |r1| |r0| */ | |||
| mm_res = _mm_shuffle_epi32(mm_res, _MM_SHUFFLE(3,1,2,0)); /* 0 |r1| 0 |r0| == |r1_64| |r0_64| */ | |||
| mm_sum = _mm_add_epi64(mm_sum, mm_res); | |||
| } | |||
| for( ; residual_sample < end; residual_sample++) { | |||
| __m128i mm_res = _mm_abs_epi32(_mm_cvtsi32_si128(residual[residual_sample])); | |||
| mm_sum = _mm_add_epi64(mm_sum, mm_res); | |||
| } | |||
| mm_sum = _mm_add_epi64(mm_sum, _mm_srli_si128(mm_sum, 8)); | |||
| _mm_storel_epi64((__m128i*)(abs_residual_partition_sums+partition), mm_sum); | |||
| } | |||
| } | |||
| } | |||
| /* now merge partitions for lower orders */ | |||
| { | |||
| uint32_t from_partition = 0, to_partition = partitions; | |||
| int partition_order; | |||
| for(partition_order = (int)max_partition_order - 1; partition_order >= (int)min_partition_order; partition_order--) { | |||
| uint32_t i; | |||
| partitions >>= 1; | |||
| for(i = 0; i < partitions; i++) { | |||
| abs_residual_partition_sums[to_partition++] = | |||
| abs_residual_partition_sums[from_partition ] + | |||
| abs_residual_partition_sums[from_partition+1]; | |||
| from_partition += 2; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| #endif /* FLAC__SSSE3_SUPPORTED */ | |||
| #endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */ | |||
| #endif /* FLAC__NO_ASM */ | |||
| @@ -0,0 +1,282 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2006-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include <math.h> | |||
| #include "../compat.h" | |||
| #include "../assert.h" | |||
| #include "../format.h" | |||
| #include "include/private/window.h" | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| FLAC__int32 n; | |||
| if (L & 1) { | |||
| for (n = 0; n <= N/2; n++) | |||
| window[n] = 2.0f * n / (float)N; | |||
| for (; n <= N; n++) | |||
| window[n] = 2.0f - 2.0f * n / (float)N; | |||
| } | |||
| else { | |||
| for (n = 0; n <= L/2-1; n++) | |||
| window[n] = 2.0f * n / (float)N; | |||
| for (; n <= N; n++) | |||
| window[n] = 2.0f - 2.0f * n / (float)N; | |||
| } | |||
| } | |||
| void FLAC__window_bartlett_hann(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| FLAC__int32 n; | |||
| for (n = 0; n < L; n++) | |||
| window[n] = (FLAC__real)(0.62f - 0.48f * fabsf((float)n/(float)N-0.5f) - 0.38f * cosf(2.0f * M_PI * ((float)n/(float)N))); | |||
| } | |||
| void FLAC__window_blackman(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| FLAC__int32 n; | |||
| for (n = 0; n < L; n++) | |||
| window[n] = (FLAC__real)(0.42f - 0.5f * cosf(2.0f * M_PI * n / N) + 0.08f * cosf(4.0f * M_PI * n / N)); | |||
| } | |||
| /* 4-term -92dB side-lobe */ | |||
| void FLAC__window_blackman_harris_4term_92db_sidelobe(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| FLAC__int32 n; | |||
| for (n = 0; n <= N; n++) | |||
| window[n] = (FLAC__real)(0.35875f - 0.48829f * cosf(2.0f * M_PI * n / N) + 0.14128f * cosf(4.0f * M_PI * n / N) - 0.01168f * cosf(6.0f * M_PI * n / N)); | |||
| } | |||
| void FLAC__window_connes(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| const double N2 = (double)N / 2.; | |||
| FLAC__int32 n; | |||
| for (n = 0; n <= N; n++) { | |||
| double k = ((double)n - N2) / N2; | |||
| k = 1.0f - k * k; | |||
| window[n] = (FLAC__real)(k * k); | |||
| } | |||
| } | |||
| void FLAC__window_flattop(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| FLAC__int32 n; | |||
| for (n = 0; n < L; n++) | |||
| window[n] = (FLAC__real)(0.21557895f - 0.41663158f * cosf(2.0f * M_PI * n / N) + 0.277263158f * cosf(4.0f * M_PI * n / N) - 0.083578947f * cosf(6.0f * M_PI * n / N) + 0.006947368f * cosf(8.0f * M_PI * n / N)); | |||
| } | |||
| void FLAC__window_gauss(FLAC__real *window, const FLAC__int32 L, const FLAC__real stddev) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| const double N2 = (double)N / 2.; | |||
| FLAC__int32 n; | |||
| for (n = 0; n <= N; n++) { | |||
| const double k = ((double)n - N2) / (stddev * N2); | |||
| window[n] = (FLAC__real)exp(-0.5f * k * k); | |||
| } | |||
| } | |||
| void FLAC__window_hamming(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| FLAC__int32 n; | |||
| for (n = 0; n < L; n++) | |||
| window[n] = (FLAC__real)(0.54f - 0.46f * cosf(2.0f * M_PI * n / N)); | |||
| } | |||
| void FLAC__window_hann(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| FLAC__int32 n; | |||
| for (n = 0; n < L; n++) | |||
| window[n] = (FLAC__real)(0.5f - 0.5f * cosf(2.0f * M_PI * n / N)); | |||
| } | |||
| void FLAC__window_kaiser_bessel(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| FLAC__int32 n; | |||
| for (n = 0; n < L; n++) | |||
| window[n] = (FLAC__real)(0.402f - 0.498f * cosf(2.0f * M_PI * n / N) + 0.098f * cosf(4.0f * M_PI * n / N) - 0.001f * cosf(6.0f * M_PI * n / N)); | |||
| } | |||
| void FLAC__window_nuttall(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| FLAC__int32 n; | |||
| for (n = 0; n < L; n++) | |||
| window[n] = (FLAC__real)(0.3635819f - 0.4891775f*cosf(2.0f*M_PI*n/N) + 0.1365995f*cosf(4.0f*M_PI*n/N) - 0.0106411f*cosf(6.0f*M_PI*n/N)); | |||
| } | |||
| void FLAC__window_rectangle(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| FLAC__int32 n; | |||
| for (n = 0; n < L; n++) | |||
| window[n] = 1.0f; | |||
| } | |||
| void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| FLAC__int32 n; | |||
| if (L & 1) { | |||
| for (n = 1; n <= (L+1)/2; n++) | |||
| window[n-1] = 2.0f * n / ((float)L + 1.0f); | |||
| for (; n <= L; n++) | |||
| window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f); | |||
| } | |||
| else { | |||
| for (n = 1; n <= L/2; n++) | |||
| window[n-1] = 2.0f * n / ((float)L + 1.0f); | |||
| for (; n <= L; n++) | |||
| window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f); | |||
| } | |||
| } | |||
| void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p) | |||
| { | |||
| if (p <= 0.0) | |||
| FLAC__window_rectangle(window, L); | |||
| else if (p >= 1.0) | |||
| FLAC__window_hann(window, L); | |||
| else { | |||
| const FLAC__int32 Np = (FLAC__int32)(p / 2.0f * L) - 1; | |||
| FLAC__int32 n; | |||
| /* start with rectangle... */ | |||
| FLAC__window_rectangle(window, L); | |||
| /* ...replace ends with hann */ | |||
| if (Np > 0) { | |||
| for (n = 0; n <= Np; n++) { | |||
| window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * n / Np)); | |||
| window[L-Np-1+n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * (n+Np) / Np)); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| void FLAC__window_partial_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end) | |||
| { | |||
| const FLAC__int32 start_n = (FLAC__int32)(start * L); | |||
| const FLAC__int32 end_n = (FLAC__int32)(end * L); | |||
| const FLAC__int32 N = end_n - start_n; | |||
| FLAC__int32 Np, n, i; | |||
| if (p <= 0.0f) | |||
| FLAC__window_partial_tukey(window, L, 0.05f, start, end); | |||
| else if (p >= 1.0f) | |||
| FLAC__window_partial_tukey(window, L, 0.95f, start, end); | |||
| else { | |||
| Np = (FLAC__int32)(p / 2.0f * N); | |||
| for (n = 0; n < start_n && n < L; n++) | |||
| window[n] = 0.0f; | |||
| for (i = 1; n < (start_n+Np) && n < L; n++, i++) | |||
| window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Np)); | |||
| for (; n < (end_n-Np) && n < L; n++) | |||
| window[n] = 1.0f; | |||
| for (i = Np; n < end_n && n < L; n++, i--) | |||
| window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Np)); | |||
| for (; n < L; n++) | |||
| window[n] = 0.0f; | |||
| } | |||
| } | |||
| void FLAC__window_punchout_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end) | |||
| { | |||
| const FLAC__int32 start_n = (FLAC__int32)(start * L); | |||
| const FLAC__int32 end_n = (FLAC__int32)(end * L); | |||
| FLAC__int32 Ns, Ne, n, i; | |||
| if (p <= 0.0f) | |||
| FLAC__window_punchout_tukey(window, L, 0.05f, start, end); | |||
| else if (p >= 1.0f) | |||
| FLAC__window_punchout_tukey(window, L, 0.95f, start, end); | |||
| else { | |||
| Ns = (FLAC__int32)(p / 2.0f * start_n); | |||
| Ne = (FLAC__int32)(p / 2.0f * (L - end_n)); | |||
| for (n = 0, i = 1; n < Ns && n < L; n++, i++) | |||
| window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Ns)); | |||
| for (; n < start_n-Ns && n < L; n++) | |||
| window[n] = 1.0f; | |||
| for (i = Ns; n < start_n && n < L; n++, i--) | |||
| window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Ns)); | |||
| for (; n < end_n && n < L; n++) | |||
| window[n] = 0.0f; | |||
| for (i = 1; n < end_n+Ne && n < L; n++, i++) | |||
| window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Ne)); | |||
| for (; n < L - (Ne) && n < L; n++) | |||
| window[n] = 1.0f; | |||
| for (i = Ne; n < L; n++, i--) | |||
| window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Ne)); | |||
| } | |||
| } | |||
| void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| const double N2 = (double)N / 2.; | |||
| FLAC__int32 n; | |||
| for (n = 0; n <= N; n++) { | |||
| const double k = ((double)n - N2) / N2; | |||
| window[n] = (FLAC__real)(1.0f - k * k); | |||
| } | |||
| } | |||
| #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ | |||
| @@ -0,0 +1,187 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2013-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include <io.h> | |||
| #include <windows.h> | |||
| #include "../windows_unicode_filenames.h" | |||
| /*** FIXME: KLUDGE: export these syms for flac.exe, metaflac.exe, etc. ***/ | |||
| /* convert UTF-8 back to WCHAR. Caller is responsible for freeing memory */ | |||
| static wchar_t *wchar_from_utf8(const char *str) | |||
| { | |||
| wchar_t *widestr; | |||
| int len; | |||
| if (!str) | |||
| return NULL; | |||
| if ((len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0)) == 0) | |||
| return NULL; | |||
| if ((widestr = (wchar_t *)malloc(len*sizeof(wchar_t))) == NULL) | |||
| return NULL; | |||
| if (MultiByteToWideChar(CP_UTF8, 0, str, -1, widestr, len) == 0) { | |||
| free(widestr); | |||
| widestr = NULL; | |||
| } | |||
| return widestr; | |||
| } | |||
| static FLAC__bool utf8_filenames = false; | |||
| FLAC_API void flac_internal_set_utf8_filenames(FLAC__bool flag) | |||
| { | |||
| utf8_filenames = flag ? true : false; | |||
| } | |||
| FLAC_API FLAC__bool flac_internal_get_utf8_filenames(void) | |||
| { | |||
| return utf8_filenames; | |||
| } | |||
| /* file functions */ | |||
| FLAC_API FILE* flac_internal_fopen_utf8(const char *filename, const char *mode) | |||
| { | |||
| if (!utf8_filenames) { | |||
| return fopen(filename, mode); | |||
| } else { | |||
| wchar_t *wname = NULL; | |||
| wchar_t *wmode = NULL; | |||
| FILE *f = NULL; | |||
| do { | |||
| if (!(wname = wchar_from_utf8(filename))) break; | |||
| if (!(wmode = wchar_from_utf8(mode))) break; | |||
| f = _wfopen(wname, wmode); | |||
| } while(0); | |||
| free(wname); | |||
| free(wmode); | |||
| return f; | |||
| } | |||
| } | |||
| FLAC_API int flac_internal_stat64_utf8(const char *path, struct __stat64 *buffer) | |||
| { | |||
| if (!utf8_filenames) { | |||
| return _stat64(path, buffer); | |||
| } else { | |||
| wchar_t *wpath; | |||
| int ret; | |||
| if (!(wpath = wchar_from_utf8(path))) return -1; | |||
| ret = _wstat64(wpath, buffer); | |||
| free(wpath); | |||
| return ret; | |||
| } | |||
| } | |||
| FLAC_API int flac_internal_chmod_utf8(const char *filename, int pmode) | |||
| { | |||
| if (!utf8_filenames) { | |||
| return _chmod(filename, pmode); | |||
| } else { | |||
| wchar_t *wname; | |||
| int ret; | |||
| if (!(wname = wchar_from_utf8(filename))) return -1; | |||
| ret = _wchmod(wname, pmode); | |||
| free(wname); | |||
| return ret; | |||
| } | |||
| } | |||
| FLAC_API int flac_internal_utime_utf8(const char *filename, struct utimbuf *times) | |||
| { | |||
| if (!utf8_filenames) { | |||
| return utime(filename, times); | |||
| } else { | |||
| wchar_t *wname; | |||
| struct __utimbuf64 ut; | |||
| int ret; | |||
| if (!(wname = wchar_from_utf8(filename))) return -1; | |||
| ut.actime = times->actime; | |||
| ut.modtime = times->modtime; | |||
| ret = _wutime64(wname, &ut); | |||
| free(wname); | |||
| return ret; | |||
| } | |||
| } | |||
| FLAC_API int flac_internal_unlink_utf8(const char *filename) | |||
| { | |||
| if (!utf8_filenames) { | |||
| return _unlink(filename); | |||
| } else { | |||
| wchar_t *wname; | |||
| int ret; | |||
| if (!(wname = wchar_from_utf8(filename))) return -1; | |||
| ret = _wunlink(wname); | |||
| free(wname); | |||
| return ret; | |||
| } | |||
| } | |||
| FLAC_API int flac_internal_rename_utf8(const char *oldname, const char *newname) | |||
| { | |||
| if (!utf8_filenames) { | |||
| return rename(oldname, newname); | |||
| } else { | |||
| wchar_t *wold = NULL; | |||
| wchar_t *wnew = NULL; | |||
| int ret = -1; | |||
| do { | |||
| if (!(wold = wchar_from_utf8(oldname))) break; | |||
| if (!(wnew = wchar_from_utf8(newname))) break; | |||
| ret = _wrename(wold, wnew); | |||
| } while(0); | |||
| free(wold); | |||
| free(wnew); | |||
| return ret; | |||
| } | |||
| } | |||
| @@ -0,0 +1,45 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2013-2016 Xiph.org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #include <errno.h> | |||
| /* FLAC_CHECK_RETURN : Check the return value of the provided function and | |||
| * print an error message if it fails (ie returns a value < 0). | |||
| * | |||
| * Ideally, a library should not print anything, but this macro is only used | |||
| * for things that extremely unlikely to fail, like `chown` to a previoulsy | |||
| * saved `uid`. | |||
| */ | |||
| #define FLAC_CHECK_RETURN(x) \ | |||
| { if ((x) < 0) \ | |||
| fprintf (stderr, "%s : %s\n", #x, strerror (errno)) ; \ | |||
| } | |||
| @@ -0,0 +1,53 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2017 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 header file defines integer [u]intNN_t types. | |||
| * It is auto-included in all files via "Force Includes" (/FI) | |||
| * option in all *.vcproj files (Visual Studio 2005, 2008) | |||
| */ | |||
| #ifndef FLAC__SHARE__MSVC2005_INT_H | |||
| #define FLAC__SHARE__MSVC2005_INT_H | |||
| #if defined _MSC_VER && _MSC_VER < 1600 | |||
| typedef signed __int8 int8_t; | |||
| typedef signed __int16 int16_t; | |||
| typedef signed __int32 int32_t; | |||
| typedef signed __int64 int64_t; | |||
| typedef unsigned __int8 uint8_t; | |||
| typedef unsigned __int16 uint16_t; | |||
| typedef unsigned __int32 uint32_t; | |||
| typedef unsigned __int64 uint64_t; | |||
| #endif | |||
| #endif /* FLAC__SHARE__MSVC2005_INT_H */ | |||
| @@ -0,0 +1,85 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__ORDINALS_H | |||
| #define FLAC__ORDINALS_H | |||
| #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 __int8 FLAC__int8; | |||
| typedef signed __int16 FLAC__int16; | |||
| typedef signed __int32 FLAC__int32; | |||
| typedef signed __int64 FLAC__int64; | |||
| typedef unsigned __int8 FLAC__uint8; | |||
| typedef unsigned __int16 FLAC__uint16; | |||
| typedef unsigned __int32 FLAC__uint32; | |||
| typedef unsigned __int64 FLAC__uint64; | |||
| #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 int32_t FLAC__int32; | |||
| typedef int64_t FLAC__int64; | |||
| typedef uint16_t FLAC__uint16; | |||
| typedef uint32_t FLAC__uint32; | |||
| typedef uint64_t FLAC__uint64; | |||
| #endif | |||
| typedef int FLAC__bool; | |||
| typedef FLAC__uint8 FLAC__byte; | |||
| #ifdef true | |||
| #undef true | |||
| #endif | |||
| #ifdef false | |||
| #undef false | |||
| #endif | |||
| #ifndef __cplusplus | |||
| #define true 1 | |||
| #define false 0 | |||
| #endif | |||
| #endif | |||
| @@ -0,0 +1,45 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2013-2016 Xiph.org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__SHARE__PRIVATE_H | |||
| #define FLAC__SHARE__PRIVATE_H | |||
| /* | |||
| * Unpublished debug routines from libFLAC. This should not be used from any | |||
| * client code other than code shipped with the FLAC sources. | |||
| */ | |||
| FLAC_API FLAC__bool FLAC__stream_encoder_disable_constant_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_verbatim_subframes(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_get_do_md5(const FLAC__StreamEncoder *encoder); | |||
| #endif /* FLAC__SHARE__PRIVATE_H */ | |||
| @@ -0,0 +1,59 @@ | |||
| /* | |||
| * ReplayGainAnalysis - analyzes input samples and give the recommended dB change | |||
| * Copyright (C) 2001 David Robinson and Glen Sawyer | |||
| * | |||
| * This library is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation; either | |||
| * version 2.1 of the License, or (at your option) any later version. | |||
| * | |||
| * This library is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| * Lesser General Public License for more details. | |||
| * | |||
| * You should have received a copy of the GNU Lesser General Public | |||
| * License along with this library; if not, write to the Free Software | |||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
| * | |||
| * concept and filter values by David Robinson (David@Robinson.org) | |||
| * -- blame him if you think the idea is flawed | |||
| * coding by Glen Sawyer (glensawyer@hotmail.com) 442 N 700 E, Provo, UT 84606 USA | |||
| * -- blame him if you think this runs too slowly, or the coding is otherwise flawed | |||
| * minor cosmetic tweaks to integrate with FLAC by Josh Coalson | |||
| * | |||
| * For an explanation of the concepts and the basic algorithms involved, go to: | |||
| * http://www.replaygain.org/ | |||
| */ | |||
| #ifndef GAIN_ANALYSIS_H | |||
| #define GAIN_ANALYSIS_H | |||
| #include <stddef.h> | |||
| #define GAIN_NOT_ENOUGH_SAMPLES -24601 | |||
| #define GAIN_ANALYSIS_ERROR 0 | |||
| #define GAIN_ANALYSIS_OK 1 | |||
| #define INIT_GAIN_ANALYSIS_ERROR 0 | |||
| #define INIT_GAIN_ANALYSIS_OK 1 | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| typedef float flac_float_t; /* Type used for filtering */ | |||
| extern flac_float_t ReplayGainReferenceLoudness; /* in dB SPL, currently == 89.0 */ | |||
| int InitGainAnalysis ( long samplefreq ); | |||
| int ValidGainFrequency ( long samplefreq ); | |||
| int AnalyzeSamples ( const flac_float_t* left_samples, const flac_float_t* right_samples, size_t num_samples, int num_channels ); | |||
| flac_float_t GetTitleGain ( void ); | |||
| flac_float_t GetAlbumGain ( void ); | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif /* GAIN_ANALYSIS_H */ | |||
| @@ -0,0 +1,52 @@ | |||
| /* replaygain_synthesis - Routines for applying ReplayGain to a signal | |||
| * Copyright (C) 2002-2009 Josh Coalson | |||
| * Copyright (C) 2011-2016 Xiph.Org Foundation | |||
| * | |||
| * This library is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation; either | |||
| * version 2.1 of the License, or (at your option) any later version. | |||
| * | |||
| * This library is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| * Lesser General Public License for more details. | |||
| * | |||
| * You should have received a copy of the GNU Lesser General Public | |||
| * License along with this library; if not, write to the Free Software | |||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
| */ | |||
| #ifndef FLAC__SHARE__REPLAYGAIN_SYNTHESIS_H | |||
| #define FLAC__SHARE__REPLAYGAIN_SYNTHESIS_H | |||
| #include <stdlib.h> /* for size_t */ | |||
| #include "format.h" | |||
| #define FLAC_SHARE__MAX_SUPPORTED_CHANNELS FLAC__MAX_CHANNELS | |||
| typedef enum { | |||
| NOISE_SHAPING_NONE = 0, | |||
| NOISE_SHAPING_LOW = 1, | |||
| NOISE_SHAPING_MEDIUM = 2, | |||
| NOISE_SHAPING_HIGH = 3 | |||
| } NoiseShaping; | |||
| typedef struct { | |||
| const float* FilterCoeff; | |||
| FLAC__uint64 Mask; | |||
| double Add; | |||
| float Dither; | |||
| float ErrorHistory [FLAC_SHARE__MAX_SUPPORTED_CHANNELS] [16]; /* 16th order Noise shaping */ | |||
| float DitherHistory [FLAC_SHARE__MAX_SUPPORTED_CHANNELS] [16]; | |||
| int LastRandomNumber [FLAC_SHARE__MAX_SUPPORTED_CHANNELS]; | |||
| unsigned LastHistoryIndex; | |||
| NoiseShaping ShapingType; | |||
| } DitherContext; | |||
| void FLAC__replaygain_synthesis__init_dither_context(DitherContext *dither, int bits, int shapingtype); | |||
| /* scale = (float) pow(10., (double)replaygain * 0.05); */ | |||
| size_t FLAC__replaygain_synthesis__apply_gain(FLAC__byte *data_out, FLAC__bool little_endian_data_out, FLAC__bool unsigned_data_out, const FLAC__int32 * const input[], uint32_t wide_samples, uint32_t channels, const uint32_t source_bps, const uint32_t target_bps, const double scale, const FLAC__bool hard_limit, FLAC__bool do_dithering, DitherContext *dither_context); | |||
| #endif | |||
| @@ -0,0 +1,71 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2013-2016 Xiph.org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| /* Safe string handling functions to replace things like strcpy, strncpy, | |||
| * strcat, strncat etc. | |||
| * All of these functions guarantee a correctly NUL terminated string but | |||
| * the string may be truncated if the destination buffer was too short. | |||
| */ | |||
| #ifndef FLAC__SHARE_SAFE_STR_H | |||
| #define FLAC__SHARE_SAFE_STR_H | |||
| static inline char * | |||
| safe_strncat(char *dest, const char *src, size_t dest_size) | |||
| { | |||
| char * ret; | |||
| if (dest_size < 1) | |||
| return dest; | |||
| /* Assume dist has space for a term character .. */ | |||
| ret = strncat(dest, src, dest_size - strlen (dest)); | |||
| /* .. but set it explicitly. */ | |||
| dest [dest_size - 1] = 0; | |||
| return ret; | |||
| } | |||
| static inline char * | |||
| safe_strncpy(char *dest, const char *src, size_t dest_size) | |||
| { | |||
| char * ret; | |||
| if (dest_size < 1) | |||
| return dest; | |||
| ret = strncpy(dest, src, dest_size - 1); | |||
| dest [dest_size - 1] = 0; | |||
| return ret; | |||
| } | |||
| #endif /* FLAC__SHARE_SAFE_STR_H */ | |||
| @@ -0,0 +1,25 @@ | |||
| #ifndef SHARE__UTF8_H | |||
| #define SHARE__UTF8_H | |||
| /* | |||
| * Convert a string between UTF-8 and the locale's charset. | |||
| * Invalid bytes are replaced by '#', and characters that are | |||
| * not available in the target encoding are replaced by '?'. | |||
| * | |||
| * If the locale's charset is not set explicitly then it is | |||
| * obtained using nl_langinfo(CODESET), where available, the | |||
| * environment variable CHARSET, or assumed to be US-ASCII. | |||
| * | |||
| * Return value of conversion functions: | |||
| * | |||
| * -1 : memory allocation failed | |||
| * 0 : data was converted exactly | |||
| * 1 : valid data was converted approximately (using '?') | |||
| * 2 : input was invalid (but still converted, using '#') | |||
| * 3 : unknown encoding (but still converted, using '?') | |||
| */ | |||
| int utf8_encode(const char *from, char **to); | |||
| int utf8_decode(const char *from, char **to); | |||
| #endif | |||
| @@ -0,0 +1,61 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2013-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef _WIN32 | |||
| #ifndef flac__win_utf8_io_h | |||
| #define flac__win_utf8_io_h | |||
| #include <stdio.h> | |||
| #include <stdarg.h> | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| size_t strlen_utf8(const char *str); | |||
| int win_get_console_width(void); | |||
| int get_utf8_argv(int *argc, char ***argv); | |||
| int printf_utf8(const char *format, ...); | |||
| int fprintf_utf8(FILE *stream, const char *format, ...); | |||
| int vfprintf_utf8(FILE *stream, const char *format, va_list argptr); | |||
| #include <windows.h> | |||
| HANDLE WINAPI CreateFile_utf8(const char *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); | |||
| #ifdef __cplusplus | |||
| } /* extern "C" */ | |||
| #endif | |||
| #endif | |||
| #endif | |||
| @@ -0,0 +1,66 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2013-2016 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef _WIN32 | |||
| #ifndef flac__windows_unicode_filenames_h | |||
| #define flac__windows_unicode_filenames_h | |||
| #include <stdio.h> | |||
| #include <sys/stat.h> | |||
| #include <sys/utime.h> | |||
| #include "ordinals.h" | |||
| /***** FIXME: KLUDGE: export these syms for flac.exe, metaflac.exe, etc. *****/ | |||
| #include "export.h" | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| FLAC_API void flac_internal_set_utf8_filenames(FLAC__bool flag); | |||
| FLAC_API FLAC__bool flac_internal_get_utf8_filenames(void); | |||
| #define flac_set_utf8_filenames flac_internal_set_utf8_filenames | |||
| #define flac_get_utf8_filenames flac_internal_get_utf8_filenames | |||
| FLAC_API FILE* flac_internal_fopen_utf8(const char *filename, const char *mode); | |||
| FLAC_API int flac_internal_stat64_utf8(const char *path, struct __stat64 *buffer); | |||
| FLAC_API int flac_internal_chmod_utf8(const char *filename, int pmode); | |||
| FLAC_API int flac_internal_utime_utf8(const char *filename, struct utimbuf *times); | |||
| FLAC_API int flac_internal_unlink_utf8(const char *filename); | |||
| FLAC_API int flac_internal_rename_utf8(const char *oldname, const char *newname); | |||
| #ifdef __cplusplus | |||
| } /* extern "C" */ | |||
| #endif | |||
| #endif | |||
| #endif | |||