diff --git a/src/external/stb_vorbis.h b/src/external/stb_vorbis.h index 2fcbc4afc..45e64b1aa 100644 --- a/src/external/stb_vorbis.h +++ b/src/external/stb_vorbis.h @@ -1,4 +1,4 @@ -// Ogg Vorbis audio decoder - v1.14 - public domain +// Ogg Vorbis audio decoder - v1.22 - public domain // http://nothings.org/stb_vorbis/ // // Original version written by Sean Barrett in 2007. @@ -26,18 +26,29 @@ // Terje Mathisen Niklas Frykholm Andy Hill // Casey Muratori John Bolton Gargaj // Laurent Gomila Marc LeBlanc Ronny Chevalier -// Bernhard Wodo Evan Balster alxprd@github +// Bernhard Wodo Evan Balster github:alxprd // Tom Beaumont Ingo Leitgeb Nicolas Guillemot // Phillip Bennefall Rohit Thiago Goulart -// manxorist@github saga musix github:infatum -// Timur Gagiev BareRose +// github:manxorist Saga Musix github:infatum +// Timur Gagiev Maxwell Koo Peter Waller +// github:audinowho Dougall Johnson David Reid +// github:Clownacy Pedro J. Estebanez Remi Verschelde +// AnthoFoxo github:morlat Gabriel Ravier // // Partial history: +// 1.22 - 2021-07-11 - various small fixes +// 1.21 - 2021-07-02 - fix bug for files with no comments +// 1.20 - 2020-07-11 - several small fixes +// 1.19 - 2020-02-05 - warnings +// 1.18 - 2020-02-02 - fix seek bugs; parse header comments; misc warnings etc. +// 1.17 - 2019-07-08 - fix CVE-2019-13217..CVE-2019-13223 (by ForAllSecure) +// 1.16 - 2019-03-04 - fix warnings +// 1.15 - 2019-02-07 - explicit failure if Ogg Skeleton data is found // 1.14 - 2018-02-11 - delete bogus dealloca usage // 1.13 - 2018-01-29 - fix truncation of last frame (hopefully) // 1.12 - 2017-11-21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files -// 1.11 - 2017-07-23 - fix MinGW compilation -// 1.10 - 2017-03-03 - more robust seeking; fix negative stbv_ilog(); clear error in open_memory +// 1.11 - 2017-07-23 - fix MinGW compilation +// 1.10 - 2017-03-03 - more robust seeking; fix negative ilog(); clear error in open_memory // 1.09 - 2016-04-04 - back out 'truncation of last frame' fix from previous version // 1.08 - 2016-04-02 - warnings; setup memory leaks; truncation of last frame // 1.07 - 2015-01-16 - fixes for crashes on invalid files; warning fixes; const @@ -64,28 +75,17 @@ #define STB_VORBIS_INCLUDE_STB_VORBIS_H #if defined(STB_VORBIS_NO_CRT) && !defined(STB_VORBIS_NO_STDIO) -#define STB_VORBIS_NO_STDIO +#define STB_VORBIS_NO_STDIO 1 #endif #ifndef STB_VORBIS_NO_STDIO #include #endif -// NOTE: Added to work with raylib on Android -#if defined(PLATFORM_ANDROID) - #include "utils.h" // Android fopen function map -#endif - #ifdef __cplusplus extern "C" { #endif -#ifdef STB_VORBIS_STATIC -#define STBVDEF static -#else -#define STBVDEF extern -#endif - /////////// THREAD SAFETY // Individual stb_vorbis* handles are not thread-safe; you cannot decode from @@ -101,8 +101,8 @@ extern "C" { // data in the file and how you set the compile flags for speed // vs. size. In my test files the maximal-size usage is ~150KB.) // -// You can modify the wrapper functions in the source (stbv_setup_malloc, -// stbv_setup_temp_malloc, temp_malloc) to change this behavior, or you +// You can modify the wrapper functions in the source (setup_malloc, +// setup_temp_malloc, temp_malloc) to change this behavior, or you // can use a simpler allocation model: you pass in a buffer from // which stb_vorbis will allocate _all_ its memory (including the // temp memory). "open" may fail with a VORBIS_outofmem if you @@ -138,25 +138,36 @@ typedef struct int max_frame_size; } stb_vorbis_info; +typedef struct +{ + char *vendor; + + int comment_list_length; + char **comment_list; +} stb_vorbis_comment; + // get general information about the file -STBVDEF stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f); +extern stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f); + +// get ogg comments +extern stb_vorbis_comment stb_vorbis_get_comment(stb_vorbis *f); // get the last error detected (clears it, too) -STBVDEF int stb_vorbis_get_error(stb_vorbis *f); +extern int stb_vorbis_get_error(stb_vorbis *f); // close an ogg vorbis file and free all memory in use -STBVDEF void stb_vorbis_close(stb_vorbis *f); +extern void stb_vorbis_close(stb_vorbis *f); // this function returns the offset (in samples) from the beginning of the // file that will be returned by the next decode, if it is known, or -1 // otherwise. after a flush_pushdata() call, this may take a while before // it becomes valid again. // NOT WORKING YET after a seek with PULLDATA API -STBVDEF int stb_vorbis_get_sample_offset(stb_vorbis *f); +extern int stb_vorbis_get_sample_offset(stb_vorbis *f); // returns the current seek point within the file, or offset from the beginning // of the memory buffer. In pushdata mode it returns 0. -STBVDEF unsigned int stb_vorbis_get_file_offset(stb_vorbis *f); +extern unsigned int stb_vorbis_get_file_offset(stb_vorbis *f); /////////// PUSHDATA API @@ -169,7 +180,7 @@ STBVDEF unsigned int stb_vorbis_get_file_offset(stb_vorbis *f); // need to give it the same data again PLUS more. Note that the Vorbis // specification does not bound the size of an individual frame. -STBVDEF stb_vorbis *stb_vorbis_open_pushdata( +extern stb_vorbis *stb_vorbis_open_pushdata( const unsigned char * datablock, int datablock_length_in_bytes, int *datablock_memory_consumed_in_bytes, int *error, @@ -183,7 +194,7 @@ STBVDEF stb_vorbis *stb_vorbis_open_pushdata( // if returns NULL and *error is VORBIS_need_more_data, then the input block was // incomplete and you need to pass in a larger block from the start of the file -STBVDEF int stb_vorbis_decode_frame_pushdata( +extern int stb_vorbis_decode_frame_pushdata( stb_vorbis *f, const unsigned char *datablock, int datablock_length_in_bytes, int *channels, // place to write number of float * buffers @@ -212,8 +223,14 @@ STBVDEF int stb_vorbis_decode_frame_pushdata( // channel. In other words, (*output)[0][0] contains the first sample from // the first channel, and (*output)[1][0] contains the first sample from // the second channel. +// +// *output points into stb_vorbis's internal output buffer storage; these +// buffers are owned by stb_vorbis and application code should not free +// them or modify their contents. They are transient and will be overwritten +// once you ask for more data to get decoded, so be sure to grab any data +// you need before then. -STBVDEF void stb_vorbis_flush_pushdata(stb_vorbis *f); +extern void stb_vorbis_flush_pushdata(stb_vorbis *f); // inform stb_vorbis that your next datablock will not be contiguous with // previous ones (e.g. you've seeked in the data); future attempts to decode // frames will cause stb_vorbis to resynchronize (as noted above), and @@ -238,38 +255,38 @@ STBVDEF void stb_vorbis_flush_pushdata(stb_vorbis *f); // just want to go ahead and use pushdata.) #if !defined(STB_VORBIS_NO_STDIO) && !defined(STB_VORBIS_NO_INTEGER_CONVERSION) -STBVDEF int stb_vorbis_decode_filename(const char *filename, int *channels, int *sample_rate, short **output); +extern int stb_vorbis_decode_filename(const char *filename, int *channels, int *sample_rate, short **output); #endif -#ifndef STB_VORBIS_NO_INTEGER_CONVERSION -STBVDEF int stb_vorbis_decode_memory(const unsigned char *mem, int len, int *channels, int *sample_rate, short **output); +#if !defined(STB_VORBIS_NO_INTEGER_CONVERSION) +extern int stb_vorbis_decode_memory(const unsigned char *mem, int len, int *channels, int *sample_rate, short **output); #endif // decode an entire file and output the data interleaved into a malloc()ed // buffer stored in *output. The return value is the number of samples // decoded, or -1 if the file could not be opened or was not an ogg vorbis file. // When you're done with it, just free() the pointer returned in *output. -STBVDEF stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len, +extern stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len, int *error, const stb_vorbis_alloc *alloc_buffer); // create an ogg vorbis decoder from an ogg vorbis stream in memory (note // this must be the entire stream!). on failure, returns NULL and sets *error #ifndef STB_VORBIS_NO_STDIO -STBVDEF stb_vorbis * stb_vorbis_open_filename(const char *filename, +extern stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, const stb_vorbis_alloc *alloc_buffer); // create an ogg vorbis decoder from a filename via fopen(). on failure, // returns NULL and sets *error (possibly to VORBIS_file_open_failure). -STBVDEF stb_vorbis * stb_vorbis_open_file(FILE *f, int close_handle_on_close, +extern stb_vorbis * stb_vorbis_open_file(FILE *f, int close_handle_on_close, int *error, const stb_vorbis_alloc *alloc_buffer); // create an ogg vorbis decoder from an open FILE *, looking for a stream at // the _current_ seek point (ftell). on failure, returns NULL and sets *error. // note that stb_vorbis must "own" this stream; if you seek it in between -// calls to stb_vorbis, it will become confused. Morever, if you attempt to +// calls to stb_vorbis, it will become confused. Moreover, if you attempt to // perform stb_vorbis_seek_*() operations on this file, it will assume it // owns the _entire_ rest of the file after the start point. Use the next // function, stb_vorbis_open_file_section(), to limit it. -STBVDEF stb_vorbis * stb_vorbis_open_file_section(FILE *f, int close_handle_on_close, +extern stb_vorbis * stb_vorbis_open_file_section(FILE *f, int close_handle_on_close, int *error, const stb_vorbis_alloc *alloc_buffer, unsigned int len); // create an ogg vorbis decoder from an open FILE *, looking for a stream at // the _current_ seek point (ftell); the stream will be of length 'len' bytes. @@ -278,8 +295,8 @@ STBVDEF stb_vorbis * stb_vorbis_open_file_section(FILE *f, int close_handle_on_c // confused. #endif -STBVDEF int stb_vorbis_seek_frame(stb_vorbis *f, unsigned int sample_number); -STBVDEF int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number); +extern int stb_vorbis_seek_frame(stb_vorbis *f, unsigned int sample_number); +extern int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number); // these functions seek in the Vorbis file to (approximately) 'sample_number'. // after calling seek_frame(), the next call to get_frame_*() will include // the specified sample. after calling stb_vorbis_seek(), the next call to @@ -287,14 +304,14 @@ STBVDEF int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number); // do not need to seek to EXACTLY the target sample when using get_samples_*, // you can also use seek_frame(). -STBVDEF int stb_vorbis_seek_start(stb_vorbis *f); +extern int stb_vorbis_seek_start(stb_vorbis *f); // this function is equivalent to stb_vorbis_seek(f,0) -STBVDEF unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f); -STBVDEF float stb_vorbis_stream_length_in_seconds(stb_vorbis *f); +extern unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f); +extern float stb_vorbis_stream_length_in_seconds(stb_vorbis *f); // these functions return the total length of the vorbis stream -STBVDEF int stb_vorbis_get_frame_float(stb_vorbis *f, int *channels, float ***output); +extern int stb_vorbis_get_frame_float(stb_vorbis *f, int *channels, float ***output); // decode the next frame and return the number of samples. the number of // channels returned are stored in *channels (which can be NULL--it is always // the same as the number of channels reported by get_info). *output will @@ -305,8 +322,8 @@ STBVDEF int stb_vorbis_get_frame_float(stb_vorbis *f, int *channels, float ***ou // and stb_vorbis_get_samples_*(), since the latter calls the former. #ifndef STB_VORBIS_NO_INTEGER_CONVERSION -STBVDEF int stb_vorbis_get_frame_short_interleaved(stb_vorbis *f, int num_c, short *buffer, int num_shorts); -STBVDEF int stb_vorbis_get_frame_short (stb_vorbis *f, int num_c, short **buffer, int num_samples); +extern int stb_vorbis_get_frame_short_interleaved(stb_vorbis *f, int num_c, short *buffer, int num_shorts); +extern int stb_vorbis_get_frame_short (stb_vorbis *f, int num_c, short **buffer, int num_samples); #endif // decode the next frame and return the number of *samples* per channel. // Note that for interleaved data, you pass in the number of shorts (the @@ -333,16 +350,16 @@ STBVDEF int stb_vorbis_get_frame_short (stb_vorbis *f, int num_c, sho // Note that this is not _good_ surround etc. mixing at all! It's just so // you get something useful. -STBVDEF int stb_vorbis_get_samples_float_interleaved(stb_vorbis *f, int channels, float *buffer, int num_floats); -STBVDEF int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, int num_samples); +extern int stb_vorbis_get_samples_float_interleaved(stb_vorbis *f, int channels, float *buffer, int num_floats); +extern int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, int num_samples); // gets num_samples samples, not necessarily on a frame boundary--this requires // buffering so you have to supply the buffers. DOES NOT APPLY THE COERCION RULES. // Returns the number of samples stored per channel; it may be less than requested // at the end of the file. If there are no more samples in the file, returns 0. #ifndef STB_VORBIS_NO_INTEGER_CONVERSION -STBVDEF int stb_vorbis_get_samples_short_interleaved(stb_vorbis *f, int channels, short *buffer, int num_shorts); -STBVDEF int stb_vorbis_get_samples_short(stb_vorbis *f, int channels, short **buffer, int num_samples); +extern int stb_vorbis_get_samples_short_interleaved(stb_vorbis *f, int channels, short *buffer, int num_shorts); +extern int stb_vorbis_get_samples_short(stb_vorbis *f, int channels, short **buffer, int num_samples); #endif // gets num_samples samples, not necessarily on a frame boundary--this requires // buffering so you have to supply the buffers. Applies the coercion rules above @@ -385,7 +402,8 @@ enum STBVorbisError VORBIS_invalid_first_page, VORBIS_bad_packet_type, VORBIS_cant_find_last_page, - VORBIS_seek_failed + VORBIS_seek_failed, + VORBIS_ogg_skeleton_not_supported }; @@ -428,7 +446,7 @@ enum STBVorbisError // STB_VORBIS_NO_FAST_SCALED_FLOAT // does not use a fast float-to-int trick to accelerate float-to-int on // most platforms which requires endianness be defined correctly. -// #define STB_VORBIS_NO_FAST_SCALED_FLOAT +//#define STB_VORBIS_NO_FAST_SCALED_FLOAT // STB_VORBIS_MAX_CHANNELS [number] @@ -570,7 +588,7 @@ enum STBVorbisError #if defined(_MSC_VER) || defined(__MINGW32__) #include #endif - #if defined(__linux__) || defined(__linux) || defined(__EMSCRIPTEN__) || defined(__APPLE__) || defined(__CYGWIN__) + #if defined(__linux__) || defined(__linux) || defined(__sun__) || defined(__EMSCRIPTEN__) || defined(__NEWLIB__) #include #endif #else // STB_VORBIS_NO_CRT @@ -593,7 +611,7 @@ enum STBVorbisError #endif #define __forceinline #ifndef alloca - #define alloca(s) __builtin_alloca(s) + #define alloca __builtin_alloca #endif #elif !defined(_MSC_VER) #if __GNUC__ @@ -614,28 +632,34 @@ enum STBVorbisError #if 0 #include -#define STBV_CHECK(f) _CrtIsValidHeapPointer(f->channel_buffers[1]) +#define CHECK(f) _CrtIsValidHeapPointer(f->channel_buffers[1]) #else -#define STBV_CHECK(f) ((void) 0) +#define CHECK(f) ((void) 0) #endif -#define STBV_MAX_BLOCKSIZE_LOG 13 // from specification -#define STBV_MAX_BLOCKSIZE (1 << STBV_MAX_BLOCKSIZE_LOG) +#define MAX_BLOCKSIZE_LOG 13 // from specification +#define MAX_BLOCKSIZE (1 << MAX_BLOCKSIZE_LOG) -typedef unsigned char stbv_uint8; -typedef signed char stbv_int8; -typedef unsigned short stbv_uint16; -typedef signed short stbv_int16; -typedef unsigned int stbv_uint32; -typedef signed int stbv_int32; +typedef unsigned char uint8; +typedef signed char int8; +typedef unsigned short uint16; +typedef signed short int16; +typedef unsigned int uint32; +typedef signed int int32; #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif -typedef float stbv_codetype; +typedef float codetype; + +#ifdef _MSC_VER +#define STBV_NOTUSED(v) (void)(v) +#else +#define STBV_NOTUSED(v) (void)sizeof(v) +#endif // @NOTE // @@ -650,113 +674,113 @@ typedef float stbv_codetype; // the sizes larger--nothing relies on silently truncating etc., nor the // order of variables. -#define STBV_FAST_HUFFMAN_TABLE_SIZE (1 << STB_VORBIS_FAST_HUFFMAN_LENGTH) -#define STBV_FAST_HUFFMAN_TABLE_MASK (STBV_FAST_HUFFMAN_TABLE_SIZE - 1) +#define FAST_HUFFMAN_TABLE_SIZE (1 << STB_VORBIS_FAST_HUFFMAN_LENGTH) +#define FAST_HUFFMAN_TABLE_MASK (FAST_HUFFMAN_TABLE_SIZE - 1) typedef struct { int dimensions, entries; - stbv_uint8 *codeword_lengths; + uint8 *codeword_lengths; float minimum_value; float delta_value; - stbv_uint8 value_bits; - stbv_uint8 lookup_type; - stbv_uint8 sequence_p; - stbv_uint8 sparse; - stbv_uint32 lookup_values; - stbv_codetype *multiplicands; - stbv_uint32 *codewords; + uint8 value_bits; + uint8 lookup_type; + uint8 sequence_p; + uint8 sparse; + uint32 lookup_values; + codetype *multiplicands; + uint32 *codewords; #ifdef STB_VORBIS_FAST_HUFFMAN_SHORT - stbv_int16 fast_huffman[STBV_FAST_HUFFMAN_TABLE_SIZE]; + int16 fast_huffman[FAST_HUFFMAN_TABLE_SIZE]; #else - stbv_int32 fast_huffman[STBV_FAST_HUFFMAN_TABLE_SIZE]; + int32 fast_huffman[FAST_HUFFMAN_TABLE_SIZE]; #endif - stbv_uint32 *sorted_codewords; + uint32 *sorted_codewords; int *sorted_values; int sorted_entries; -} StbvCodebook; +} Codebook; typedef struct { - stbv_uint8 order; - stbv_uint16 rate; - stbv_uint16 bark_map_size; - stbv_uint8 amplitude_bits; - stbv_uint8 amplitude_offset; - stbv_uint8 number_of_books; - stbv_uint8 book_list[16]; // varies -} StbvFloor0; + uint8 order; + uint16 rate; + uint16 bark_map_size; + uint8 amplitude_bits; + uint8 amplitude_offset; + uint8 number_of_books; + uint8 book_list[16]; // varies +} Floor0; typedef struct { - stbv_uint8 partitions; - stbv_uint8 partition_class_list[32]; // varies - stbv_uint8 class_dimensions[16]; // varies - stbv_uint8 class_subclasses[16]; // varies - stbv_uint8 class_masterbooks[16]; // varies - stbv_int16 subclass_books[16][8]; // varies - stbv_uint16 Xlist[31*8+2]; // varies - stbv_uint8 sorted_order[31*8+2]; - stbv_uint8 stbv_neighbors[31*8+2][2]; - stbv_uint8 floor1_multiplier; - stbv_uint8 rangebits; + uint8 partitions; + uint8 partition_class_list[32]; // varies + uint8 class_dimensions[16]; // varies + uint8 class_subclasses[16]; // varies + uint8 class_masterbooks[16]; // varies + int16 subclass_books[16][8]; // varies + uint16 Xlist[31*8+2]; // varies + uint8 sorted_order[31*8+2]; + uint8 neighbors[31*8+2][2]; + uint8 floor1_multiplier; + uint8 rangebits; int values; -} StbvFloor1; +} Floor1; typedef union { - StbvFloor0 floor0; - StbvFloor1 floor1; -} StbvFloor; + Floor0 floor0; + Floor1 floor1; +} Floor; typedef struct { - stbv_uint32 begin, end; - stbv_uint32 part_size; - stbv_uint8 classifications; - stbv_uint8 classbook; - stbv_uint8 **classdata; - stbv_int16 (*residue_books)[8]; -} StbvResidue; + uint32 begin, end; + uint32 part_size; + uint8 classifications; + uint8 classbook; + uint8 **classdata; + int16 (*residue_books)[8]; +} Residue; typedef struct { - stbv_uint8 magnitude; - stbv_uint8 angle; - stbv_uint8 mux; -} StbvMappingChannel; + uint8 magnitude; + uint8 angle; + uint8 mux; +} MappingChannel; typedef struct { - stbv_uint16 coupling_steps; - StbvMappingChannel *chan; - stbv_uint8 submaps; - stbv_uint8 submap_floor[15]; // varies - stbv_uint8 submap_residue[15]; // varies -} StbvMapping; + uint16 coupling_steps; + MappingChannel *chan; + uint8 submaps; + uint8 submap_floor[15]; // varies + uint8 submap_residue[15]; // varies +} Mapping; typedef struct { - stbv_uint8 blockflag; - stbv_uint8 mapping; - stbv_uint16 windowtype; - stbv_uint16 transformtype; -} StbvMode; + uint8 blockflag; + uint8 mapping; + uint16 windowtype; + uint16 transformtype; +} Mode; typedef struct { - stbv_uint32 goal_crc; // expected crc if match + uint32 goal_crc; // expected crc if match int bytes_left; // bytes left in packet - stbv_uint32 crc_so_far; // running crc + uint32 crc_so_far; // running crc int bytes_done; // bytes processed in _current_ chunk - stbv_uint32 sample_loc; // granule pos encoded in page -} StbvCRCscan; + uint32 sample_loc; // granule pos encoded in page +} CRCscan; typedef struct { - stbv_uint32 page_start, page_end; - stbv_uint32 last_decoded_sample; -} StbvProbedPage; + uint32 page_start, page_end; + uint32 last_decoded_sample; +} ProbedPage; struct stb_vorbis { @@ -768,24 +792,31 @@ struct stb_vorbis unsigned int temp_memory_required; unsigned int setup_temp_memory_required; + char *vendor; + int comment_list_length; + char **comment_list; + // input config #ifndef STB_VORBIS_NO_STDIO FILE *f; - stbv_uint32 f_start; + uint32 f_start; int close_on_free; #endif - stbv_uint8 *stream; - stbv_uint8 *stream_start; - stbv_uint8 *stream_end; + uint8 *stream; + uint8 *stream_start; + uint8 *stream_end; - stbv_uint32 stream_len; + uint32 stream_len; - stbv_uint8 push_mode; + uint8 push_mode; - stbv_uint32 first_audio_page_offset; + // the page to seek to when seeking to start, may be zero + uint32 first_audio_page_offset; - StbvProbedPage p_first, p_last; + // p_first is the page on which the first audio packet ends + // (but not necessarily the page on which it starts) + ProbedPage p_first, p_last; // memory management stb_vorbis_alloc alloc; @@ -802,19 +833,19 @@ struct stb_vorbis int blocksize[2]; int blocksize_0, blocksize_1; int codebook_count; - StbvCodebook *codebooks; + Codebook *codebooks; int floor_count; - stbv_uint16 floor_types[64]; // varies - StbvFloor *floor_config; + uint16 floor_types[64]; // varies + Floor *floor_config; int residue_count; - stbv_uint16 residue_types[64]; // varies - StbvResidue *residue_config; + uint16 residue_types[64]; // varies + Residue *residue_config; int mapping_count; - StbvMapping *mapping; + Mapping *mapping; int mode_count; - StbvMode mode_config[64]; // varies + Mode mode_config[64]; // varies - stbv_uint32 total_samples; + uint32 total_samples; // decode buffer float *channel_buffers[STB_VORBIS_MAX_CHANNELS]; @@ -824,44 +855,44 @@ struct stb_vorbis int previous_length; #ifndef STB_VORBIS_NO_DEFER_FLOOR - stbv_int16 *finalY[STB_VORBIS_MAX_CHANNELS]; + int16 *finalY[STB_VORBIS_MAX_CHANNELS]; #else float *floor_buffers[STB_VORBIS_MAX_CHANNELS]; #endif - stbv_uint32 current_loc; // sample location of next frame to decode + uint32 current_loc; // sample location of next frame to decode int current_loc_valid; // per-blocksize precomputed data - + // twiddle factors float *A[2],*B[2],*C[2]; float *window[2]; - stbv_uint16 *stbv_bit_reverse[2]; + uint16 *bit_reverse[2]; // current page/packet/segment streaming info - stbv_uint32 serial; // stream serial number for verification + uint32 serial; // stream serial number for verification int last_page; int segment_count; - stbv_uint8 segments[255]; - stbv_uint8 page_flag; - stbv_uint8 bytes_in_seg; - stbv_uint8 first_decode; + uint8 segments[255]; + uint8 page_flag; + uint8 bytes_in_seg; + uint8 first_decode; int next_seg; int last_seg; // flag that we're on the last segment int last_seg_which; // what was the segment number of the last seg? - stbv_uint32 acc; + uint32 acc; int valid_bits; int packet_bytes; int end_seg_with_known_loc; - stbv_uint32 known_loc_for_packet; + uint32 known_loc_for_packet; int discard_samples_deferred; - stbv_uint32 samples_output; + uint32 samples_output; // push mode scanning int page_crc_tests; // only in push_mode: number of tests active; -1 if not searching #ifndef STB_VORBIS_NO_PUSHDATA_API - StbvCRCscan scan[STB_VORBIS_PUSHDATA_CRC_COUNT]; + CRCscan scan[STB_VORBIS_PUSHDATA_CRC_COUNT]; #endif // sample-access @@ -870,16 +901,16 @@ struct stb_vorbis }; #if defined(STB_VORBIS_NO_PUSHDATA_API) - #define STBV_IS_PUSH_MODE(f) FALSE + #define IS_PUSH_MODE(f) FALSE #elif defined(STB_VORBIS_NO_PULLDATA_API) - #define STBV_IS_PUSH_MODE(f) TRUE + #define IS_PUSH_MODE(f) TRUE #else - #define STBV_IS_PUSH_MODE(f) ((f)->push_mode) + #define IS_PUSH_MODE(f) ((f)->push_mode) #endif -typedef struct stb_vorbis stbv_vorb; +typedef struct stb_vorbis vorb; -static int stbv_error(stbv_vorb *f, enum STBVorbisError e) +static int error(vorb *f, enum STBVorbisError e) { f->error = e; if (!f->eof && e != VORBIS_need_more_data) { @@ -894,17 +925,17 @@ static int stbv_error(stbv_vorb *f, enum STBVorbisError e) // alloca(); otherwise, provide a temp buffer and it will // allocate out of those. -#define stbv_array_size_required(count,size) (count*(sizeof(void *)+(size))) +#define array_size_required(count,size) (count*(sizeof(void *)+(size))) -#define stbv_temp_alloc(f,size) (f->alloc.alloc_buffer ? stbv_setup_temp_malloc(f,size) : alloca(size)) -#define stbv_temp_free(f,p) 0 -#define stbv_temp_alloc_save(f) ((f)->temp_offset) -#define stbv_temp_alloc_restore(f,p) ((f)->temp_offset = (p)) +#define temp_alloc(f,size) (f->alloc.alloc_buffer ? setup_temp_malloc(f,size) : alloca(size)) +#define temp_free(f,p) (void)0 +#define temp_alloc_save(f) ((f)->temp_offset) +#define temp_alloc_restore(f,p) ((f)->temp_offset = (p)) -#define stbv_temp_block_array(f,count,size) stbv_make_block_array(stbv_temp_alloc(f,stbv_array_size_required(count,size)), count, size) +#define temp_block_array(f,count,size) make_block_array(temp_alloc(f,array_size_required(count,size)), count, size) // given a sufficiently large block of memory, make an array of pointers to subblocks of it -static void *stbv_make_block_array(void *mem, int count, int size) +static void *make_block_array(void *mem, int count, int size) { int i; void ** p = (void **) mem; @@ -916,9 +947,9 @@ static void *stbv_make_block_array(void *mem, int count, int size) return p; } -static void *stbv_setup_malloc(stbv_vorb *f, int sz) +static void *setup_malloc(vorb *f, int sz) { - sz = (sz+3) & ~3; + sz = (sz+7) & ~7; // round up to nearest 8 for alignment of future allocs. f->setup_memory_required += sz; if (f->alloc.alloc_buffer) { void *p = (char *) f->alloc.alloc_buffer + f->setup_offset; @@ -929,15 +960,15 @@ static void *stbv_setup_malloc(stbv_vorb *f, int sz) return sz ? malloc(sz) : NULL; } -static void stbv_setup_free(stbv_vorb *f, void *p) +static void setup_free(vorb *f, void *p) { if (f->alloc.alloc_buffer) return; // do nothing; setup mem is a stack free(p); } -static void *stbv_setup_temp_malloc(stbv_vorb *f, int sz) +static void *setup_temp_malloc(vorb *f, int sz) { - sz = (sz+3) & ~3; + sz = (sz+7) & ~7; // round up to nearest 8 for alignment of future allocs. if (f->alloc.alloc_buffer) { if (f->temp_offset - sz < f->setup_offset) return NULL; f->temp_offset -= sz; @@ -946,37 +977,37 @@ static void *stbv_setup_temp_malloc(stbv_vorb *f, int sz) return malloc(sz); } -static void stbv_setup_temp_free(stbv_vorb *f, void *p, int sz) +static void setup_temp_free(vorb *f, void *p, int sz) { if (f->alloc.alloc_buffer) { - f->temp_offset += (sz+3)&~3; + f->temp_offset += (sz+7)&~7; return; } free(p); } -#define STBV_CRC32_POLY 0x04c11db7 // from spec +#define CRC32_POLY 0x04c11db7 // from spec -static stbv_uint32 stbv_crc_table[256]; -static void stbv_crc32_init(void) +static uint32 crc_table[256]; +static void crc32_init(void) { int i,j; - stbv_uint32 s; + uint32 s; for(i=0; i < 256; i++) { - for (s=(stbv_uint32) i << 24, j=0; j < 8; ++j) - s = (s << 1) ^ (s >= (1U<<31) ? STBV_CRC32_POLY : 0); - stbv_crc_table[i] = s; + for (s=(uint32) i << 24, j=0; j < 8; ++j) + s = (s << 1) ^ (s >= (1U<<31) ? CRC32_POLY : 0); + crc_table[i] = s; } } -static __forceinline stbv_uint32 stbv_crc32_update(stbv_uint32 crc, stbv_uint8 byte) +static __forceinline uint32 crc32_update(uint32 crc, uint8 byte) { - return (crc << 8) ^ stbv_crc_table[byte ^ (crc >> 24)]; + return (crc << 8) ^ crc_table[byte ^ (crc >> 24)]; } // used in setup, and for huffman that doesn't go fast path -static unsigned int stbv_bit_reverse(unsigned int n) +static unsigned int bit_reverse(unsigned int n) { n = ((n & 0xAAAAAAAA) >> 1) | ((n & 0x55555555) << 1); n = ((n & 0xCCCCCCCC) >> 2) | ((n & 0x33333333) << 2); @@ -985,7 +1016,7 @@ static unsigned int stbv_bit_reverse(unsigned int n) return (n >> 16) | (n << 16); } -static float stbv_square(float x) +static float square(float x) { return x*x; } @@ -993,7 +1024,7 @@ static float stbv_square(float x) // this is a weird definition of log2() for which log2(1) = 1, log2(2) = 2, log2(4) = 3 // as required by the specification. fast(?) implementation from stb.h // @OPTIMIZE: called multiple times per-packet with "constants"; move to setup -static int stbv_ilog(stbv_int32 n) +static int ilog(int32 n) { static signed char log2_4[16] = { 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4 }; @@ -1023,14 +1054,14 @@ static int stbv_ilog(stbv_int32 n) // these functions are only called at setup, and only a few times // per file -static float stbv_float32_unpack(stbv_uint32 x) +static float float32_unpack(uint32 x) { // from the specification - stbv_uint32 mantissa = x & 0x1fffff; - stbv_uint32 sign = x & 0x80000000; - stbv_uint32 exp = (x & 0x7fe00000) >> 21; + uint32 mantissa = x & 0x1fffff; + uint32 sign = x & 0x80000000; + uint32 exp = (x & 0x7fe00000) >> 21; double res = sign ? -(double)mantissa : (double)mantissa; - return (float) ldexp((float)res, exp-788); + return (float) ldexp((float)res, (int)exp-788); } @@ -1041,7 +1072,7 @@ static float stbv_float32_unpack(stbv_uint32 x) // vorbis allows a huffman table with non-sorted lengths. This // requires a more sophisticated construction, since symbols in // order do not map to huffman codes "in order". -static void stbv_add_entry(StbvCodebook *c, stbv_uint32 huff_code, int symbol, int count, int len, stbv_uint32 *values) +static void add_entry(Codebook *c, uint32 huff_code, int symbol, int count, int len, uint32 *values) { if (!c->sparse) { c->codewords [symbol] = huff_code; @@ -1052,17 +1083,18 @@ static void stbv_add_entry(StbvCodebook *c, stbv_uint32 huff_code, int symbol, i } } -static int stbv_compute_codewords(StbvCodebook *c, stbv_uint8 *len, int n, stbv_uint32 *values) +static int compute_codewords(Codebook *c, uint8 *len, int n, uint32 *values) { int i,k,m=0; - stbv_uint32 available[32]; + uint32 available[32]; memset(available, 0, sizeof(available)); // find the first entry for (k=0; k < n; ++k) if (len[k] < NO_CODE) break; if (k == n) { assert(c->sorted_entries == 0); return TRUE; } + assert(len[k] < 32); // no error return required, code reading lens checks this // add to the list - stbv_add_entry(c, 0, k, m++, len[k], values); + add_entry(c, 0, k, m++, len[k], values); // add all available leaves for (i=1; i <= len[k]; ++i) available[i] = 1U << (32-i); @@ -1071,9 +1103,10 @@ static int stbv_compute_codewords(StbvCodebook *c, stbv_uint8 *len, int n, stbv_ // could probably be combined (except the initial code is 0, // and I use 0 in available[] to mean 'empty') for (i=k+1; i < n; ++i) { - stbv_uint32 res; + uint32 res; int z = len[i], y; if (z == NO_CODE) continue; + assert(z < 32); // no error return required, code reading lens checks this // find lowest available leaf (should always be earliest, // which is what the specification calls for) // note that this property, and the fact we can never have @@ -1083,12 +1116,10 @@ static int stbv_compute_codewords(StbvCodebook *c, stbv_uint8 *len, int n, stbv_ while (z > 0 && !available[z]) --z; if (z == 0) { return FALSE; } res = available[z]; - assert(z >= 0 && z < 32); available[z] = 0; - stbv_add_entry(c, stbv_bit_reverse(res), i, m++, len[i], values); - // propogate availability up the tree + add_entry(c, bit_reverse(res), i, m++, len[i], values); + // propagate availability up the tree if (z != len[i]) { - assert(len[i] >= 0 && len[i] < 32); for (y=len[i]; y > z; --y) { assert(available[y] == 0); available[y] = res + (1 << (32-y)); @@ -1100,10 +1131,10 @@ static int stbv_compute_codewords(StbvCodebook *c, stbv_uint8 *len, int n, stbv_ // accelerated huffman table allows fast O(1) match of all symbols // of length <= STB_VORBIS_FAST_HUFFMAN_LENGTH -static void stbv_compute_accelerated_huffman(StbvCodebook *c) +static void compute_accelerated_huffman(Codebook *c) { int i, len; - for (i=0; i < STBV_FAST_HUFFMAN_TABLE_SIZE; ++i) + for (i=0; i < FAST_HUFFMAN_TABLE_SIZE; ++i) c->fast_huffman[i] = -1; len = c->sparse ? c->sorted_entries : c->entries; @@ -1112,9 +1143,9 @@ static void stbv_compute_accelerated_huffman(StbvCodebook *c) #endif for (i=0; i < len; ++i) { if (c->codeword_lengths[i] <= STB_VORBIS_FAST_HUFFMAN_LENGTH) { - stbv_uint32 z = c->sparse ? stbv_bit_reverse(c->sorted_codewords[i]) : c->codewords[i]; + uint32 z = c->sparse ? bit_reverse(c->sorted_codewords[i]) : c->codewords[i]; // set table entries for all bit combinations in the higher bits - while (z < STBV_FAST_HUFFMAN_TABLE_SIZE) { + while (z < FAST_HUFFMAN_TABLE_SIZE) { c->fast_huffman[z] = i; z += 1 << c->codeword_lengths[i]; } @@ -1128,14 +1159,14 @@ static void stbv_compute_accelerated_huffman(StbvCodebook *c) #define STBV_CDECL #endif -static int STBV_CDECL stbv_uint32_compare(const void *p, const void *q) +static int STBV_CDECL uint32_compare(const void *p, const void *q) { - stbv_uint32 x = * (stbv_uint32 *) p; - stbv_uint32 y = * (stbv_uint32 *) q; + uint32 x = * (uint32 *) p; + uint32 y = * (uint32 *) q; return x < y ? -1 : x > y; } -static int stbv_include_in_sort(StbvCodebook *c, stbv_uint8 len) +static int include_in_sort(Codebook *c, uint8 len) { if (c->sparse) { assert(len != NO_CODE); return TRUE; } if (len == NO_CODE) return FALSE; @@ -1145,7 +1176,7 @@ static int stbv_include_in_sort(StbvCodebook *c, stbv_uint8 len) // if the fast table above doesn't work, we want to binary // search them... need to reverse the bits -static void stbv_compute_sorted_huffman(StbvCodebook *c, stbv_uint8 *lengths, stbv_uint32 *values) +static void compute_sorted_huffman(Codebook *c, uint8 *lengths, uint32 *values) { int i, len; // build a list of all the entries @@ -1155,15 +1186,15 @@ static void stbv_compute_sorted_huffman(StbvCodebook *c, stbv_uint8 *lengths, st if (!c->sparse) { int k = 0; for (i=0; i < c->entries; ++i) - if (stbv_include_in_sort(c, lengths[i])) - c->sorted_codewords[k++] = stbv_bit_reverse(c->codewords[i]); + if (include_in_sort(c, lengths[i])) + c->sorted_codewords[k++] = bit_reverse(c->codewords[i]); assert(k == c->sorted_entries); } else { for (i=0; i < c->sorted_entries; ++i) - c->sorted_codewords[i] = stbv_bit_reverse(c->codewords[i]); + c->sorted_codewords[i] = bit_reverse(c->codewords[i]); } - qsort(c->sorted_codewords, c->sorted_entries, sizeof(c->sorted_codewords[0]), stbv_uint32_compare); + qsort(c->sorted_codewords, c->sorted_entries, sizeof(c->sorted_codewords[0]), uint32_compare); c->sorted_codewords[c->sorted_entries] = 0xffffffff; len = c->sparse ? c->sorted_entries : c->entries; @@ -1174,8 +1205,8 @@ static void stbv_compute_sorted_huffman(StbvCodebook *c, stbv_uint8 *lengths, st // #1 requires extra storage, #2 is slow, #3 can use binary search! for (i=0; i < len; ++i) { int huff_len = c->sparse ? lengths[values[i]] : lengths[i]; - if (stbv_include_in_sort(c,huff_len)) { - stbv_uint32 code = stbv_bit_reverse(c->codewords[i]); + if (include_in_sort(c,huff_len)) { + uint32 code = bit_reverse(c->codewords[i]); int x=0, n=c->sorted_entries; while (n > 1) { // invariant: sc[x] <= code < sc[x+n] @@ -1199,26 +1230,28 @@ static void stbv_compute_sorted_huffman(StbvCodebook *c, stbv_uint8 *lengths, st } // only run while parsing the header (3 times) -static int stbv_vorbis_validate(stbv_uint8 *data) +static int vorbis_validate(uint8 *data) { - static stbv_uint8 vorbis[6] = { 'v', 'o', 'r', 'b', 'i', 's' }; + static uint8 vorbis[6] = { 'v', 'o', 'r', 'b', 'i', 's' }; return memcmp(data, vorbis, 6) == 0; } // called from setup only, once per code book // (formula implied by specification) -static int stbv_lookup1_values(int entries, int dim) +static int lookup1_values(int entries, int dim) { int r = (int) floor(exp((float) log((float) entries) / dim)); if ((int) floor(pow((float) r+1, dim)) <= entries) // (int) cast for MinGW warning; ++r; // floor() to avoid _ftol() when non-CRT - assert(pow((float) r+1, dim) > entries); - assert((int) floor(pow((float) r, dim)) <= entries); // (int),floor() as above + if (pow((float) r+1, dim) <= entries) + return -1; + if ((int) floor(pow((float) r, dim)) > entries) + return -1; return r; } // called twice per file -static void stbv_compute_twiddle_factors(int n, float *A, float *B, float *C) +static void compute_twiddle_factors(int n, float *A, float *B, float *C) { int n4 = n >> 2, n8 = n >> 3; int k,k2; @@ -1235,39 +1268,39 @@ static void stbv_compute_twiddle_factors(int n, float *A, float *B, float *C) } } -static void stbv_compute_window(int n, float *window) +static void compute_window(int n, float *window) { int n2 = n >> 1, i; for (i=0; i < n2; ++i) - window[i] = (float) sin(0.5 * M_PI * stbv_square((float) sin((i - 0 + 0.5) / n2 * 0.5 * M_PI))); + window[i] = (float) sin(0.5 * M_PI * square((float) sin((i - 0 + 0.5) / n2 * 0.5 * M_PI))); } -static void stbv_compute_bitreverse(int n, stbv_uint16 *rev) +static void compute_bitreverse(int n, uint16 *rev) { - int ld = stbv_ilog(n) - 1; // stbv_ilog is off-by-one from normal definitions + int ld = ilog(n) - 1; // ilog is off-by-one from normal definitions int i, n8 = n >> 3; for (i=0; i < n8; ++i) - rev[i] = (stbv_bit_reverse(i) >> (32-ld+3)) << 2; + rev[i] = (bit_reverse(i) >> (32-ld+3)) << 2; } -static int stbv_init_blocksize(stbv_vorb *f, int b, int n) +static int init_blocksize(vorb *f, int b, int n) { int n2 = n >> 1, n4 = n >> 2, n8 = n >> 3; - f->A[b] = (float *) stbv_setup_malloc(f, sizeof(float) * n2); - f->B[b] = (float *) stbv_setup_malloc(f, sizeof(float) * n2); - f->C[b] = (float *) stbv_setup_malloc(f, sizeof(float) * n4); - if (!f->A[b] || !f->B[b] || !f->C[b]) return stbv_error(f, VORBIS_outofmem); - stbv_compute_twiddle_factors(n, f->A[b], f->B[b], f->C[b]); - f->window[b] = (float *) stbv_setup_malloc(f, sizeof(float) * n2); - if (!f->window[b]) return stbv_error(f, VORBIS_outofmem); - stbv_compute_window(n, f->window[b]); - f->stbv_bit_reverse[b] = (stbv_uint16 *) stbv_setup_malloc(f, sizeof(stbv_uint16) * n8); - if (!f->stbv_bit_reverse[b]) return stbv_error(f, VORBIS_outofmem); - stbv_compute_bitreverse(n, f->stbv_bit_reverse[b]); + f->A[b] = (float *) setup_malloc(f, sizeof(float) * n2); + f->B[b] = (float *) setup_malloc(f, sizeof(float) * n2); + f->C[b] = (float *) setup_malloc(f, sizeof(float) * n4); + if (!f->A[b] || !f->B[b] || !f->C[b]) return error(f, VORBIS_outofmem); + compute_twiddle_factors(n, f->A[b], f->B[b], f->C[b]); + f->window[b] = (float *) setup_malloc(f, sizeof(float) * n2); + if (!f->window[b]) return error(f, VORBIS_outofmem); + compute_window(n, f->window[b]); + f->bit_reverse[b] = (uint16 *) setup_malloc(f, sizeof(uint16) * n8); + if (!f->bit_reverse[b]) return error(f, VORBIS_outofmem); + compute_bitreverse(n, f->bit_reverse[b]); return TRUE; } -static void stbv_neighbors(stbv_uint16 *x, int n, int *plow, int *phigh) +static void neighbors(uint16 *x, int n, int *plow, int *phigh) { int low = -1; int high = 65536; @@ -1281,13 +1314,13 @@ static void stbv_neighbors(stbv_uint16 *x, int n, int *plow, int *phigh) // this has been repurposed so y is now the original index instead of y typedef struct { - stbv_uint16 x,id; -} stbv_floor_ordering; + uint16 x,id; +} stbv__floor_ordering; -static int STBV_CDECL stbv_point_compare(const void *p, const void *q) +static int STBV_CDECL point_compare(const void *p, const void *q) { - stbv_floor_ordering *a = (stbv_floor_ordering *) p; - stbv_floor_ordering *b = (stbv_floor_ordering *) q; + stbv__floor_ordering *a = (stbv__floor_ordering *) p; + stbv__floor_ordering *b = (stbv__floor_ordering *) q; return a->x < b->x ? -1 : a->x > b->x; } @@ -1296,14 +1329,14 @@ static int STBV_CDECL stbv_point_compare(const void *p, const void *q) #if defined(STB_VORBIS_NO_STDIO) - #define STBV_USE_MEMORY(z) TRUE + #define USE_MEMORY(z) TRUE #else - #define STBV_USE_MEMORY(z) ((z)->stream) + #define USE_MEMORY(z) ((z)->stream) #endif -static stbv_uint8 stbv_get8(stbv_vorb *z) +static uint8 get8(vorb *z) { - if (STBV_USE_MEMORY(z)) { + if (USE_MEMORY(z)) { if (z->stream >= z->stream_end) { z->eof = TRUE; return 0; } return *z->stream++; } @@ -1317,26 +1350,26 @@ static stbv_uint8 stbv_get8(stbv_vorb *z) #endif } -static stbv_uint32 stbv_get32(stbv_vorb *f) +static uint32 get32(vorb *f) { - stbv_uint32 x; - x = stbv_get8(f); - x += stbv_get8(f) << 8; - x += stbv_get8(f) << 16; - x += (stbv_uint32) stbv_get8(f) << 24; + uint32 x; + x = get8(f); + x += get8(f) << 8; + x += get8(f) << 16; + x += (uint32) get8(f) << 24; return x; } -static int stbv_getn(stbv_vorb *z, stbv_uint8 *data, int n) +static int getn(vorb *z, uint8 *data, int n) { - if (STBV_USE_MEMORY(z)) { + if (USE_MEMORY(z)) { if (z->stream+n > z->stream_end) { z->eof = 1; return 0; } memcpy(data, z->stream, n); z->stream += n; return 1; } - #ifndef STB_VORBIS_NO_STDIO + #ifndef STB_VORBIS_NO_STDIO if (fread(data, n, 1, z->f) == 1) return 1; else { @@ -1346,9 +1379,9 @@ static int stbv_getn(stbv_vorb *z, stbv_uint8 *data, int n) #endif } -static void stbv_skip(stbv_vorb *z, int n) +static void skip(vorb *z, int n) { - if (STBV_USE_MEMORY(z)) { + if (USE_MEMORY(z)) { z->stream += n; if (z->stream >= z->stream_end) z->eof = 1; return; @@ -1361,13 +1394,13 @@ static void stbv_skip(stbv_vorb *z, int n) #endif } -static int stbv_set_file_offset(stb_vorbis *f, unsigned int loc) +static int set_file_offset(stb_vorbis *f, unsigned int loc) { #ifndef STB_VORBIS_NO_PUSHDATA_API if (f->push_mode) return 0; #endif f->eof = 0; - if (STBV_USE_MEMORY(f)) { + if (USE_MEMORY(f)) { if (f->stream_start + loc >= f->stream_end || f->stream_start + loc < f->stream_start) { f->stream = f->stream_end; f->eof = 1; @@ -1393,44 +1426,47 @@ static int stbv_set_file_offset(stb_vorbis *f, unsigned int loc) } -static stbv_uint8 stbv_ogg_page_header[4] = { 0x4f, 0x67, 0x67, 0x53 }; +static uint8 ogg_page_header[4] = { 0x4f, 0x67, 0x67, 0x53 }; -static int stbv_capture_pattern(stbv_vorb *f) +static int capture_pattern(vorb *f) { - if (0x4f != stbv_get8(f)) return FALSE; - if (0x67 != stbv_get8(f)) return FALSE; - if (0x67 != stbv_get8(f)) return FALSE; - if (0x53 != stbv_get8(f)) return FALSE; + if (0x4f != get8(f)) return FALSE; + if (0x67 != get8(f)) return FALSE; + if (0x67 != get8(f)) return FALSE; + if (0x53 != get8(f)) return FALSE; return TRUE; } -#define STBV_PAGEFLAG_continued_packet 1 -#define STBV_PAGEFLAG_first_page 2 -#define STBV_PAGEFLAG_last_page 4 +#define PAGEFLAG_continued_packet 1 +#define PAGEFLAG_first_page 2 +#define PAGEFLAG_last_page 4 -static int stbv_start_page_no_capturepattern(stbv_vorb *f) +static int start_page_no_capturepattern(vorb *f) { - stbv_uint32 loc0,loc1,n; + uint32 loc0,loc1,n; + if (f->first_decode && !IS_PUSH_MODE(f)) { + f->p_first.page_start = stb_vorbis_get_file_offset(f) - 4; + } // stream structure version - if (0 != stbv_get8(f)) return stbv_error(f, VORBIS_invalid_stream_structure_version); + if (0 != get8(f)) return error(f, VORBIS_invalid_stream_structure_version); // header flag - f->page_flag = stbv_get8(f); + f->page_flag = get8(f); // absolute granule position - loc0 = stbv_get32(f); - loc1 = stbv_get32(f); + loc0 = get32(f); + loc1 = get32(f); // @TODO: validate loc0,loc1 as valid positions? // stream serial number -- vorbis doesn't interleave, so discard - stbv_get32(f); - //if (f->serial != stbv_get32(f)) return stbv_error(f, VORBIS_incorrect_stream_serial_number); + get32(f); + //if (f->serial != get32(f)) return error(f, VORBIS_incorrect_stream_serial_number); // page sequence number - n = stbv_get32(f); + n = get32(f); f->last_page = n; // CRC32 - stbv_get32(f); + get32(f); // page_segments - f->segment_count = stbv_get8(f); - if (!stbv_getn(f, f->segments, f->segment_count)) - return stbv_error(f, VORBIS_unexpected_eof); + f->segment_count = get8(f); + if (!getn(f, f->segments, f->segment_count)) + return error(f, VORBIS_unexpected_eof); // assume we _don't_ know any the sample position of any segments f->end_seg_with_known_loc = -2; if (loc0 != ~0U || loc1 != ~0U) { @@ -1447,32 +1483,29 @@ static int stbv_start_page_no_capturepattern(stbv_vorb *f) } if (f->first_decode) { int i,len; - StbvProbedPage p; len = 0; for (i=0; i < f->segment_count; ++i) len += f->segments[i]; len += 27 + f->segment_count; - p.page_start = f->first_audio_page_offset; - p.page_end = p.page_start + len; - p.last_decoded_sample = loc0; - f->p_first = p; + f->p_first.page_end = f->p_first.page_start + len; + f->p_first.last_decoded_sample = loc0; } f->next_seg = 0; return TRUE; } -static int stbv_start_page(stbv_vorb *f) +static int start_page(vorb *f) { - if (!stbv_capture_pattern(f)) return stbv_error(f, VORBIS_missing_capture_pattern); - return stbv_start_page_no_capturepattern(f); + if (!capture_pattern(f)) return error(f, VORBIS_missing_capture_pattern); + return start_page_no_capturepattern(f); } -static int stbv_start_packet(stbv_vorb *f) +static int start_packet(vorb *f) { while (f->next_seg == -1) { - if (!stbv_start_page(f)) return FALSE; - if (f->page_flag & STBV_PAGEFLAG_continued_packet) - return stbv_error(f, VORBIS_continued_packet_flag_invalid); + if (!start_page(f)) return FALSE; + if (f->page_flag & PAGEFLAG_continued_packet) + return error(f, VORBIS_continued_packet_flag_invalid); } f->last_seg = FALSE; f->valid_bits = 0; @@ -1482,35 +1515,35 @@ static int stbv_start_packet(stbv_vorb *f) return TRUE; } -static int stbv_maybe_start_packet(stbv_vorb *f) +static int maybe_start_packet(vorb *f) { if (f->next_seg == -1) { - int x = stbv_get8(f); + int x = get8(f); if (f->eof) return FALSE; // EOF at page boundary is not an error! - if (0x4f != x ) return stbv_error(f, VORBIS_missing_capture_pattern); - if (0x67 != stbv_get8(f)) return stbv_error(f, VORBIS_missing_capture_pattern); - if (0x67 != stbv_get8(f)) return stbv_error(f, VORBIS_missing_capture_pattern); - if (0x53 != stbv_get8(f)) return stbv_error(f, VORBIS_missing_capture_pattern); - if (!stbv_start_page_no_capturepattern(f)) return FALSE; - if (f->page_flag & STBV_PAGEFLAG_continued_packet) { + if (0x4f != x ) return error(f, VORBIS_missing_capture_pattern); + if (0x67 != get8(f)) return error(f, VORBIS_missing_capture_pattern); + if (0x67 != get8(f)) return error(f, VORBIS_missing_capture_pattern); + if (0x53 != get8(f)) return error(f, VORBIS_missing_capture_pattern); + if (!start_page_no_capturepattern(f)) return FALSE; + if (f->page_flag & PAGEFLAG_continued_packet) { // set up enough state that we can read this packet if we want, // e.g. during recovery f->last_seg = FALSE; f->bytes_in_seg = 0; - return stbv_error(f, VORBIS_continued_packet_flag_invalid); + return error(f, VORBIS_continued_packet_flag_invalid); } } - return stbv_start_packet(f); + return start_packet(f); } -static int stbv_next_segment(stbv_vorb *f) +static int next_segment(vorb *f) { int len; if (f->last_seg) return 0; if (f->next_seg == -1) { - f->last_seg_which = f->segment_count-1; // in case stbv_start_page fails - if (!stbv_start_page(f)) { f->last_seg = 1; return 0; } - if (!(f->page_flag & STBV_PAGEFLAG_continued_packet)) return stbv_error(f, VORBIS_continued_packet_flag_invalid); + f->last_seg_which = f->segment_count-1; // in case start_page fails + if (!start_page(f)) { f->last_seg = 1; return 0; } + if (!(f->page_flag & PAGEFLAG_continued_packet)) return error(f, VORBIS_continued_packet_flag_invalid); } len = f->segments[f->next_seg++]; if (len < 255) { @@ -1524,59 +1557,70 @@ static int stbv_next_segment(stbv_vorb *f) return len; } -#define STBV_EOP (-1) -#define STBV_INVALID_BITS (-1) +#define EOP (-1) +#define INVALID_BITS (-1) -static int stbv_get8_packet_raw(stbv_vorb *f) +static int get8_packet_raw(vorb *f) { if (!f->bytes_in_seg) { // CLANG! - if (f->last_seg) return STBV_EOP; - else if (!stbv_next_segment(f)) return STBV_EOP; + if (f->last_seg) return EOP; + else if (!next_segment(f)) return EOP; } assert(f->bytes_in_seg > 0); --f->bytes_in_seg; ++f->packet_bytes; - return stbv_get8(f); + return get8(f); } -static int stbv_get8_packet(stbv_vorb *f) +static int get8_packet(vorb *f) { - int x = stbv_get8_packet_raw(f); + int x = get8_packet_raw(f); f->valid_bits = 0; return x; } -static void stbv_flush_packet(stbv_vorb *f) +static int get32_packet(vorb *f) { - while (stbv_get8_packet_raw(f) != STBV_EOP); + uint32 x; + x = get8_packet(f); + x += get8_packet(f) << 8; + x += get8_packet(f) << 16; + x += (uint32) get8_packet(f) << 24; + return x; +} + +static void flush_packet(vorb *f) +{ + while (get8_packet_raw(f) != EOP); } // @OPTIMIZE: this is the secondary bit decoder, so it's probably not as important // as the huffman decoder? -static stbv_uint32 stbv_get_bits(stbv_vorb *f, int n) +static uint32 get_bits(vorb *f, int n) { - stbv_uint32 z; + uint32 z; if (f->valid_bits < 0) return 0; if (f->valid_bits < n) { if (n > 24) { // the accumulator technique below would not work correctly in this case - z = stbv_get_bits(f, 24); - z += stbv_get_bits(f, n-24) << 24; + z = get_bits(f, 24); + z += get_bits(f, n-24) << 24; return z; } if (f->valid_bits == 0) f->acc = 0; while (f->valid_bits < n) { - int z = stbv_get8_packet_raw(f); - if (z == STBV_EOP) { - f->valid_bits = STBV_INVALID_BITS; + int z = get8_packet_raw(f); + if (z == EOP) { + f->valid_bits = INVALID_BITS; return 0; } f->acc += z << f->valid_bits; f->valid_bits += 8; } } - if (f->valid_bits < 0) return 0; + + assert(f->valid_bits >= n); z = f->acc & ((1 << n)-1); f->acc >>= n; f->valid_bits -= n; @@ -1587,15 +1631,15 @@ static stbv_uint32 stbv_get_bits(stbv_vorb *f, int n) // expand the buffer to as many bits as possible without reading off end of packet // it might be nice to allow f->valid_bits and f->acc to be stored in registers, // e.g. cache them locally and decode locally -static __forceinline void stbv_prep_huffman(stbv_vorb *f) +static __forceinline void prep_huffman(vorb *f) { if (f->valid_bits <= 24) { if (f->valid_bits == 0) f->acc = 0; do { int z; if (f->last_seg && !f->bytes_in_seg) return; - z = stbv_get8_packet_raw(f); - if (z == STBV_EOP) return; + z = get8_packet_raw(f); + if (z == EOP) return; f->acc += (unsigned) z << f->valid_bits; f->valid_bits += 8; } while (f->valid_bits <= 24); @@ -1604,15 +1648,15 @@ static __forceinline void stbv_prep_huffman(stbv_vorb *f) enum { - STBV_VORBIS_packet_id = 1, - STBV_VORBIS_packet_comment = 3, - STBV_VORBIS_packet_setup = 5 + VORBIS_packet_id = 1, + VORBIS_packet_comment = 3, + VORBIS_packet_setup = 5 }; -static int stbv_codebook_decode_scalar_raw(stbv_vorb *f, StbvCodebook *c) +static int codebook_decode_scalar_raw(vorb *f, Codebook *c) { int i; - stbv_prep_huffman(f); + prep_huffman(f); if (c->codewords == NULL && c->sorted_codewords == NULL) return -1; @@ -1621,7 +1665,7 @@ static int stbv_codebook_decode_scalar_raw(stbv_vorb *f, StbvCodebook *c) // sorted_codewords && c->entries > 8 if (c->entries > 8 ? c->sorted_codewords!=NULL : !c->codewords) { // binary search - stbv_uint32 code = stbv_bit_reverse(f->acc); + uint32 code = bit_reverse(f->acc); int x=0, n=c->sorted_entries, len; while (n > 1) { @@ -1663,17 +1707,17 @@ static int stbv_codebook_decode_scalar_raw(stbv_vorb *f, StbvCodebook *c) } } - stbv_error(f, VORBIS_invalid_stream); + error(f, VORBIS_invalid_stream); f->valid_bits = 0; return -1; } #ifndef STB_VORBIS_NO_INLINE_DECODE -#define STBV_DECODE_RAW(var, f,c) \ +#define DECODE_RAW(var, f,c) \ if (f->valid_bits < STB_VORBIS_FAST_HUFFMAN_LENGTH) \ - stbv_prep_huffman(f); \ - var = f->acc & STBV_FAST_HUFFMAN_TABLE_MASK; \ + prep_huffman(f); \ + var = f->acc & FAST_HUFFMAN_TABLE_MASK; \ var = c->fast_huffman[var]; \ if (var >= 0) { \ int n = c->codeword_lengths[var]; \ @@ -1681,18 +1725,18 @@ static int stbv_codebook_decode_scalar_raw(stbv_vorb *f, StbvCodebook *c) f->valid_bits -= n; \ if (f->valid_bits < 0) { f->valid_bits = 0; var = -1; } \ } else { \ - var = stbv_codebook_decode_scalar_raw(f,c); \ + var = codebook_decode_scalar_raw(f,c); \ } #else -static int stbv_codebook_decode_scalar(stbv_vorb *f, StbvCodebook *c) +static int codebook_decode_scalar(vorb *f, Codebook *c) { int i; if (f->valid_bits < STB_VORBIS_FAST_HUFFMAN_LENGTH) - stbv_prep_huffman(f); + prep_huffman(f); // fast huffman table lookup - i = f->acc & STBV_FAST_HUFFMAN_TABLE_MASK; + i = f->acc & FAST_HUFFMAN_TABLE_MASK; i = c->fast_huffman[i]; if (i >= 0) { f->acc >>= c->codeword_lengths[i]; @@ -1700,21 +1744,21 @@ static int stbv_codebook_decode_scalar(stbv_vorb *f, StbvCodebook *c) if (f->valid_bits < 0) { f->valid_bits = 0; return -1; } return i; } - return stbv_codebook_decode_scalar_raw(f,c); + return codebook_decode_scalar_raw(f,c); } -#define STBV_DECODE_RAW(var,f,c) var = stbv_codebook_decode_scalar(f,c); +#define DECODE_RAW(var,f,c) var = codebook_decode_scalar(f,c); #endif -#define STBV_DECODE(var,f,c) \ - STBV_DECODE_RAW(var,f,c) \ +#define DECODE(var,f,c) \ + DECODE_RAW(var,f,c) \ if (c->sparse) var = c->sorted_values[var]; #ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK - #define DECODE_VQ(var,f,c) STBV_DECODE_RAW(var,f,c) + #define DECODE_VQ(var,f,c) DECODE_RAW(var,f,c) #else - #define DECODE_VQ(var,f,c) STBV_DECODE(var,f,c) + #define DECODE_VQ(var,f,c) DECODE(var,f,c) #endif @@ -1722,45 +1766,45 @@ static int stbv_codebook_decode_scalar(stbv_vorb *f, StbvCodebook *c) -// STBV_CODEBOOK_ELEMENT_FAST is an optimization for the CODEBOOK_FLOATS case +// CODEBOOK_ELEMENT_FAST is an optimization for the CODEBOOK_FLOATS case // where we avoid one addition -#define STBV_CODEBOOK_ELEMENT(c,off) (c->multiplicands[off]) -#define STBV_CODEBOOK_ELEMENT_FAST(c,off) (c->multiplicands[off]) -#define STBV_CODEBOOK_ELEMENT_BASE(c) (0) +#define CODEBOOK_ELEMENT(c,off) (c->multiplicands[off]) +#define CODEBOOK_ELEMENT_FAST(c,off) (c->multiplicands[off]) +#define CODEBOOK_ELEMENT_BASE(c) (0) -static int stbv_codebook_decode_start(stbv_vorb *f, StbvCodebook *c) +static int codebook_decode_start(vorb *f, Codebook *c) { int z = -1; // type 0 is only legal in a scalar context if (c->lookup_type == 0) - stbv_error(f, VORBIS_invalid_stream); + error(f, VORBIS_invalid_stream); else { DECODE_VQ(z,f,c); if (c->sparse) assert(z < c->sorted_entries); - if (z < 0) { // check for STBV_EOP + if (z < 0) { // check for EOP if (!f->bytes_in_seg) if (f->last_seg) return z; - stbv_error(f, VORBIS_invalid_stream); + error(f, VORBIS_invalid_stream); } } return z; } -static int stbv_codebook_decode(stbv_vorb *f, StbvCodebook *c, float *output, int len) +static int codebook_decode(vorb *f, Codebook *c, float *output, int len) { - int i,z = stbv_codebook_decode_start(f,c); + int i,z = codebook_decode_start(f,c); if (z < 0) return FALSE; if (len > c->dimensions) len = c->dimensions; #ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK if (c->lookup_type == 1) { - float last = STBV_CODEBOOK_ELEMENT_BASE(c); + float last = CODEBOOK_ELEMENT_BASE(c); int div = 1; for (i=0; i < len; ++i) { int off = (z / div) % c->lookup_values; - float val = STBV_CODEBOOK_ELEMENT_FAST(c,off) + last; + float val = CODEBOOK_ELEMENT_FAST(c,off) + last; output[i] += val; if (c->sequence_p) last = val + c->minimum_value; div *= c->lookup_values; @@ -1771,26 +1815,26 @@ static int stbv_codebook_decode(stbv_vorb *f, StbvCodebook *c, float *output, in z *= c->dimensions; if (c->sequence_p) { - float last = STBV_CODEBOOK_ELEMENT_BASE(c); + float last = CODEBOOK_ELEMENT_BASE(c); for (i=0; i < len; ++i) { - float val = STBV_CODEBOOK_ELEMENT_FAST(c,z+i) + last; + float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last; output[i] += val; last = val + c->minimum_value; } } else { - float last = STBV_CODEBOOK_ELEMENT_BASE(c); + float last = CODEBOOK_ELEMENT_BASE(c); for (i=0; i < len; ++i) { - output[i] += STBV_CODEBOOK_ELEMENT_FAST(c,z+i) + last; + output[i] += CODEBOOK_ELEMENT_FAST(c,z+i) + last; } } return TRUE; } -static int stbv_codebook_decode_step(stbv_vorb *f, StbvCodebook *c, float *output, int len, int step) +static int codebook_decode_step(vorb *f, Codebook *c, float *output, int len, int step) { - int i,z = stbv_codebook_decode_start(f,c); - float last = STBV_CODEBOOK_ELEMENT_BASE(c); + int i,z = codebook_decode_start(f,c); + float last = CODEBOOK_ELEMENT_BASE(c); if (z < 0) return FALSE; if (len > c->dimensions) len = c->dimensions; @@ -1799,7 +1843,7 @@ static int stbv_codebook_decode_step(stbv_vorb *f, StbvCodebook *c, float *outpu int div = 1; for (i=0; i < len; ++i) { int off = (z / div) % c->lookup_values; - float val = STBV_CODEBOOK_ELEMENT_FAST(c,off) + last; + float val = CODEBOOK_ELEMENT_FAST(c,off) + last; output[i*step] += val; if (c->sequence_p) last = val; div *= c->lookup_values; @@ -1810,7 +1854,7 @@ static int stbv_codebook_decode_step(stbv_vorb *f, StbvCodebook *c, float *outpu z *= c->dimensions; for (i=0; i < len; ++i) { - float val = STBV_CODEBOOK_ELEMENT_FAST(c,z+i) + last; + float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last; output[i*step] += val; if (c->sequence_p) last = val; } @@ -1818,17 +1862,17 @@ static int stbv_codebook_decode_step(stbv_vorb *f, StbvCodebook *c, float *outpu return TRUE; } -static int stbv_codebook_decode_deinterleave_repeat(stbv_vorb *f, StbvCodebook *c, float **outputs, int ch, int *c_inter_p, int *p_inter_p, int len, int total_decode) +static int codebook_decode_deinterleave_repeat(vorb *f, Codebook *c, float **outputs, int ch, int *c_inter_p, int *p_inter_p, int len, int total_decode) { int c_inter = *c_inter_p; int p_inter = *p_inter_p; int i,z, effective = c->dimensions; // type 0 is only legal in a scalar context - if (c->lookup_type == 0) return stbv_error(f, VORBIS_invalid_stream); + if (c->lookup_type == 0) return error(f, VORBIS_invalid_stream); while (total_decode > 0) { - float last = STBV_CODEBOOK_ELEMENT_BASE(c); + float last = CODEBOOK_ELEMENT_BASE(c); DECODE_VQ(z,f,c); #ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK assert(!c->sparse || z < c->sorted_entries); @@ -1836,7 +1880,7 @@ static int stbv_codebook_decode_deinterleave_repeat(stbv_vorb *f, StbvCodebook * if (z < 0) { if (!f->bytes_in_seg) if (f->last_seg) return FALSE; - return stbv_error(f, VORBIS_invalid_stream); + return error(f, VORBIS_invalid_stream); } // if this will take us off the end of the buffers, stop short! @@ -1852,7 +1896,7 @@ static int stbv_codebook_decode_deinterleave_repeat(stbv_vorb *f, StbvCodebook * int div = 1; for (i=0; i < effective; ++i) { int off = (z / div) % c->lookup_values; - float val = STBV_CODEBOOK_ELEMENT_FAST(c,off) + last; + float val = CODEBOOK_ELEMENT_FAST(c,off) + last; if (outputs[c_inter]) outputs[c_inter][p_inter] += val; if (++c_inter == ch) { c_inter = 0; ++p_inter; } @@ -1865,7 +1909,7 @@ static int stbv_codebook_decode_deinterleave_repeat(stbv_vorb *f, StbvCodebook * z *= c->dimensions; if (c->sequence_p) { for (i=0; i < effective; ++i) { - float val = STBV_CODEBOOK_ELEMENT_FAST(c,z+i) + last; + float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last; if (outputs[c_inter]) outputs[c_inter][p_inter] += val; if (++c_inter == ch) { c_inter = 0; ++p_inter; } @@ -1873,7 +1917,7 @@ static int stbv_codebook_decode_deinterleave_repeat(stbv_vorb *f, StbvCodebook * } } else { for (i=0; i < effective; ++i) { - float val = STBV_CODEBOOK_ELEMENT_FAST(c,z+i) + last; + float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last; if (outputs[c_inter]) outputs[c_inter][p_inter] += val; if (++c_inter == ch) { c_inter = 0; ++p_inter; } @@ -1888,7 +1932,7 @@ static int stbv_codebook_decode_deinterleave_repeat(stbv_vorb *f, StbvCodebook * return TRUE; } -static int stbv_predict_point(int x, int x0, int x1, int y0, int y1) +static int predict_point(int x, int x0, int x1, int y0, int y1) { int dy = y1 - y0; int adx = x1 - x0; @@ -1899,71 +1943,71 @@ static int stbv_predict_point(int x, int x0, int x1, int y0, int y1) } // the following table is block-copied from the specification -static float stbv_inverse_db_table[256] = +static float inverse_db_table[256] = { - 1.0649863e-07f, 1.1341951e-07f, 1.2079015e-07f, 1.2863978e-07f, - 1.3699951e-07f, 1.4590251e-07f, 1.5538408e-07f, 1.6548181e-07f, - 1.7623575e-07f, 1.8768855e-07f, 1.9988561e-07f, 2.1287530e-07f, - 2.2670913e-07f, 2.4144197e-07f, 2.5713223e-07f, 2.7384213e-07f, - 2.9163793e-07f, 3.1059021e-07f, 3.3077411e-07f, 3.5226968e-07f, - 3.7516214e-07f, 3.9954229e-07f, 4.2550680e-07f, 4.5315863e-07f, - 4.8260743e-07f, 5.1396998e-07f, 5.4737065e-07f, 5.8294187e-07f, - 6.2082472e-07f, 6.6116941e-07f, 7.0413592e-07f, 7.4989464e-07f, - 7.9862701e-07f, 8.5052630e-07f, 9.0579828e-07f, 9.6466216e-07f, - 1.0273513e-06f, 1.0941144e-06f, 1.1652161e-06f, 1.2409384e-06f, - 1.3215816e-06f, 1.4074654e-06f, 1.4989305e-06f, 1.5963394e-06f, - 1.7000785e-06f, 1.8105592e-06f, 1.9282195e-06f, 2.0535261e-06f, - 2.1869758e-06f, 2.3290978e-06f, 2.4804557e-06f, 2.6416497e-06f, - 2.8133190e-06f, 2.9961443e-06f, 3.1908506e-06f, 3.3982101e-06f, - 3.6190449e-06f, 3.8542308e-06f, 4.1047004e-06f, 4.3714470e-06f, - 4.6555282e-06f, 4.9580707e-06f, 5.2802740e-06f, 5.6234160e-06f, - 5.9888572e-06f, 6.3780469e-06f, 6.7925283e-06f, 7.2339451e-06f, - 7.7040476e-06f, 8.2047000e-06f, 8.7378876e-06f, 9.3057248e-06f, - 9.9104632e-06f, 1.0554501e-05f, 1.1240392e-05f, 1.1970856e-05f, - 1.2748789e-05f, 1.3577278e-05f, 1.4459606e-05f, 1.5399272e-05f, - 1.6400004e-05f, 1.7465768e-05f, 1.8600792e-05f, 1.9809576e-05f, - 2.1096914e-05f, 2.2467911e-05f, 2.3928002e-05f, 2.5482978e-05f, - 2.7139006e-05f, 2.8902651e-05f, 3.0780908e-05f, 3.2781225e-05f, - 3.4911534e-05f, 3.7180282e-05f, 3.9596466e-05f, 4.2169667e-05f, - 4.4910090e-05f, 4.7828601e-05f, 5.0936773e-05f, 5.4246931e-05f, - 5.7772202e-05f, 6.1526565e-05f, 6.5524908e-05f, 6.9783085e-05f, - 7.4317983e-05f, 7.9147585e-05f, 8.4291040e-05f, 8.9768747e-05f, - 9.5602426e-05f, 0.00010181521f, 0.00010843174f, 0.00011547824f, - 0.00012298267f, 0.00013097477f, 0.00013948625f, 0.00014855085f, - 0.00015820453f, 0.00016848555f, 0.00017943469f, 0.00019109536f, - 0.00020351382f, 0.00021673929f, 0.00023082423f, 0.00024582449f, - 0.00026179955f, 0.00027881276f, 0.00029693158f, 0.00031622787f, - 0.00033677814f, 0.00035866388f, 0.00038197188f, 0.00040679456f, - 0.00043323036f, 0.00046138411f, 0.00049136745f, 0.00052329927f, - 0.00055730621f, 0.00059352311f, 0.00063209358f, 0.00067317058f, - 0.00071691700f, 0.00076350630f, 0.00081312324f, 0.00086596457f, - 0.00092223983f, 0.00098217216f, 0.0010459992f, 0.0011139742f, - 0.0011863665f, 0.0012634633f, 0.0013455702f, 0.0014330129f, - 0.0015261382f, 0.0016253153f, 0.0017309374f, 0.0018434235f, - 0.0019632195f, 0.0020908006f, 0.0022266726f, 0.0023713743f, - 0.0025254795f, 0.0026895994f, 0.0028643847f, 0.0030505286f, - 0.0032487691f, 0.0034598925f, 0.0036847358f, 0.0039241906f, - 0.0041792066f, 0.0044507950f, 0.0047400328f, 0.0050480668f, - 0.0053761186f, 0.0057254891f, 0.0060975636f, 0.0064938176f, - 0.0069158225f, 0.0073652516f, 0.0078438871f, 0.0083536271f, - 0.0088964928f, 0.009474637f, 0.010090352f, 0.010746080f, - 0.011444421f, 0.012188144f, 0.012980198f, 0.013823725f, - 0.014722068f, 0.015678791f, 0.016697687f, 0.017782797f, - 0.018938423f, 0.020169149f, 0.021479854f, 0.022875735f, - 0.024362330f, 0.025945531f, 0.027631618f, 0.029427276f, - 0.031339626f, 0.033376252f, 0.035545228f, 0.037855157f, - 0.040315199f, 0.042935108f, 0.045725273f, 0.048696758f, - 0.051861348f, 0.055231591f, 0.058820850f, 0.062643361f, - 0.066714279f, 0.071049749f, 0.075666962f, 0.080584227f, - 0.085821044f, 0.091398179f, 0.097337747f, 0.10366330f, - 0.11039993f, 0.11757434f, 0.12521498f, 0.13335215f, - 0.14201813f, 0.15124727f, 0.16107617f, 0.17154380f, - 0.18269168f, 0.19456402f, 0.20720788f, 0.22067342f, - 0.23501402f, 0.25028656f, 0.26655159f, 0.28387361f, - 0.30232132f, 0.32196786f, 0.34289114f, 0.36517414f, - 0.38890521f, 0.41417847f, 0.44109412f, 0.46975890f, - 0.50028648f, 0.53279791f, 0.56742212f, 0.60429640f, - 0.64356699f, 0.68538959f, 0.72993007f, 0.77736504f, + 1.0649863e-07f, 1.1341951e-07f, 1.2079015e-07f, 1.2863978e-07f, + 1.3699951e-07f, 1.4590251e-07f, 1.5538408e-07f, 1.6548181e-07f, + 1.7623575e-07f, 1.8768855e-07f, 1.9988561e-07f, 2.1287530e-07f, + 2.2670913e-07f, 2.4144197e-07f, 2.5713223e-07f, 2.7384213e-07f, + 2.9163793e-07f, 3.1059021e-07f, 3.3077411e-07f, 3.5226968e-07f, + 3.7516214e-07f, 3.9954229e-07f, 4.2550680e-07f, 4.5315863e-07f, + 4.8260743e-07f, 5.1396998e-07f, 5.4737065e-07f, 5.8294187e-07f, + 6.2082472e-07f, 6.6116941e-07f, 7.0413592e-07f, 7.4989464e-07f, + 7.9862701e-07f, 8.5052630e-07f, 9.0579828e-07f, 9.6466216e-07f, + 1.0273513e-06f, 1.0941144e-06f, 1.1652161e-06f, 1.2409384e-06f, + 1.3215816e-06f, 1.4074654e-06f, 1.4989305e-06f, 1.5963394e-06f, + 1.7000785e-06f, 1.8105592e-06f, 1.9282195e-06f, 2.0535261e-06f, + 2.1869758e-06f, 2.3290978e-06f, 2.4804557e-06f, 2.6416497e-06f, + 2.8133190e-06f, 2.9961443e-06f, 3.1908506e-06f, 3.3982101e-06f, + 3.6190449e-06f, 3.8542308e-06f, 4.1047004e-06f, 4.3714470e-06f, + 4.6555282e-06f, 4.9580707e-06f, 5.2802740e-06f, 5.6234160e-06f, + 5.9888572e-06f, 6.3780469e-06f, 6.7925283e-06f, 7.2339451e-06f, + 7.7040476e-06f, 8.2047000e-06f, 8.7378876e-06f, 9.3057248e-06f, + 9.9104632e-06f, 1.0554501e-05f, 1.1240392e-05f, 1.1970856e-05f, + 1.2748789e-05f, 1.3577278e-05f, 1.4459606e-05f, 1.5399272e-05f, + 1.6400004e-05f, 1.7465768e-05f, 1.8600792e-05f, 1.9809576e-05f, + 2.1096914e-05f, 2.2467911e-05f, 2.3928002e-05f, 2.5482978e-05f, + 2.7139006e-05f, 2.8902651e-05f, 3.0780908e-05f, 3.2781225e-05f, + 3.4911534e-05f, 3.7180282e-05f, 3.9596466e-05f, 4.2169667e-05f, + 4.4910090e-05f, 4.7828601e-05f, 5.0936773e-05f, 5.4246931e-05f, + 5.7772202e-05f, 6.1526565e-05f, 6.5524908e-05f, 6.9783085e-05f, + 7.4317983e-05f, 7.9147585e-05f, 8.4291040e-05f, 8.9768747e-05f, + 9.5602426e-05f, 0.00010181521f, 0.00010843174f, 0.00011547824f, + 0.00012298267f, 0.00013097477f, 0.00013948625f, 0.00014855085f, + 0.00015820453f, 0.00016848555f, 0.00017943469f, 0.00019109536f, + 0.00020351382f, 0.00021673929f, 0.00023082423f, 0.00024582449f, + 0.00026179955f, 0.00027881276f, 0.00029693158f, 0.00031622787f, + 0.00033677814f, 0.00035866388f, 0.00038197188f, 0.00040679456f, + 0.00043323036f, 0.00046138411f, 0.00049136745f, 0.00052329927f, + 0.00055730621f, 0.00059352311f, 0.00063209358f, 0.00067317058f, + 0.00071691700f, 0.00076350630f, 0.00081312324f, 0.00086596457f, + 0.00092223983f, 0.00098217216f, 0.0010459992f, 0.0011139742f, + 0.0011863665f, 0.0012634633f, 0.0013455702f, 0.0014330129f, + 0.0015261382f, 0.0016253153f, 0.0017309374f, 0.0018434235f, + 0.0019632195f, 0.0020908006f, 0.0022266726f, 0.0023713743f, + 0.0025254795f, 0.0026895994f, 0.0028643847f, 0.0030505286f, + 0.0032487691f, 0.0034598925f, 0.0036847358f, 0.0039241906f, + 0.0041792066f, 0.0044507950f, 0.0047400328f, 0.0050480668f, + 0.0053761186f, 0.0057254891f, 0.0060975636f, 0.0064938176f, + 0.0069158225f, 0.0073652516f, 0.0078438871f, 0.0083536271f, + 0.0088964928f, 0.009474637f, 0.010090352f, 0.010746080f, + 0.011444421f, 0.012188144f, 0.012980198f, 0.013823725f, + 0.014722068f, 0.015678791f, 0.016697687f, 0.017782797f, + 0.018938423f, 0.020169149f, 0.021479854f, 0.022875735f, + 0.024362330f, 0.025945531f, 0.027631618f, 0.029427276f, + 0.031339626f, 0.033376252f, 0.035545228f, 0.037855157f, + 0.040315199f, 0.042935108f, 0.045725273f, 0.048696758f, + 0.051861348f, 0.055231591f, 0.058820850f, 0.062643361f, + 0.066714279f, 0.071049749f, 0.075666962f, 0.080584227f, + 0.085821044f, 0.091398179f, 0.097337747f, 0.10366330f, + 0.11039993f, 0.11757434f, 0.12521498f, 0.13335215f, + 0.14201813f, 0.15124727f, 0.16107617f, 0.17154380f, + 0.18269168f, 0.19456402f, 0.20720788f, 0.22067342f, + 0.23501402f, 0.25028656f, 0.26655159f, 0.28387361f, + 0.30232132f, 0.32196786f, 0.34289114f, 0.36517414f, + 0.38890521f, 0.41417847f, 0.44109412f, 0.46975890f, + 0.50028648f, 0.53279791f, 0.56742212f, 0.60429640f, + 0.64356699f, 0.68538959f, 0.72993007f, 0.77736504f, 0.82788260f, 0.88168307f, 0.9389798f, 1.0f }; @@ -1976,18 +2020,18 @@ static float stbv_inverse_db_table[256] = // ... also, isn't the whole point of Bresenham's algorithm to NOT // have to divide in the setup? sigh. #ifndef STB_VORBIS_NO_DEFER_FLOOR -#define STBV_LINE_OP(a,b) a *= b +#define LINE_OP(a,b) a *= b #else -#define STBV_LINE_OP(a,b) a = b +#define LINE_OP(a,b) a = b #endif #ifdef STB_VORBIS_DIVIDE_TABLE -#define STBV_DIVTAB_NUMER 32 -#define STBV_DIVTAB_DENOM 64 -stbv_int8 stbv_integer_divide_table[STBV_DIVTAB_NUMER][STBV_DIVTAB_DENOM]; // 2KB +#define DIVTAB_NUMER 32 +#define DIVTAB_DENOM 64 +int8 integer_divide_table[DIVTAB_NUMER][DIVTAB_DENOM]; // 2KB #endif -static __forceinline void stbv_draw_line(float *output, int x0, int y0, int x1, int y1, int n) +static __forceinline void draw_line(float *output, int x0, int y0, int x1, int y1, int n) { int dy = y1 - y0; int adx = x1 - x0; @@ -1998,12 +2042,12 @@ static __forceinline void stbv_draw_line(float *output, int x0, int y0, int x1, int sy; #ifdef STB_VORBIS_DIVIDE_TABLE - if (adx < STBV_DIVTAB_DENOM && ady < STBV_DIVTAB_NUMER) { + if (adx < DIVTAB_DENOM && ady < DIVTAB_NUMER) { if (dy < 0) { - base = -stbv_integer_divide_table[ady][adx]; + base = -integer_divide_table[ady][adx]; sy = base-1; } else { - base = stbv_integer_divide_table[ady][adx]; + base = integer_divide_table[ady][adx]; sy = base+1; } } else { @@ -2023,7 +2067,7 @@ static __forceinline void stbv_draw_line(float *output, int x0, int y0, int x1, ady -= abs(base) * adx; if (x1 > n) x1 = n; if (x < x1) { - STBV_LINE_OP(output[x], stbv_inverse_db_table[y]); + LINE_OP(output[x], inverse_db_table[y&255]); for (++x; x < x1; ++x) { err += ady; if (err >= adx) { @@ -2031,22 +2075,22 @@ static __forceinline void stbv_draw_line(float *output, int x0, int y0, int x1, y += sy; } else y += base; - STBV_LINE_OP(output[x], stbv_inverse_db_table[y]); + LINE_OP(output[x], inverse_db_table[y&255]); } } } -static int stbv_residue_decode(stbv_vorb *f, StbvCodebook *book, float *target, int offset, int n, int rtype) +static int residue_decode(vorb *f, Codebook *book, float *target, int offset, int n, int rtype) { int k; if (rtype == 0) { int step = n / book->dimensions; for (k=0; k < step; ++k) - if (!stbv_codebook_decode_step(f, book, target+offset+k, n-offset-k, step)) + if (!codebook_decode_step(f, book, target+offset+k, n-offset-k, step)) return FALSE; } else { for (k=0; k < n; ) { - if (!stbv_codebook_decode(f, book, target+offset, n-k)) + if (!codebook_decode(f, book, target+offset, n-k)) return FALSE; k += book->dimensions; offset += book->dimensions; @@ -2057,10 +2101,10 @@ static int stbv_residue_decode(stbv_vorb *f, StbvCodebook *book, float *target, // n is 1/2 of the blocksize -- // specification: "Correct per-vector decode length is [n]/2" -static void stbv_decode_residue(stbv_vorb *f, float *residue_buffers[], int ch, int n, int rn, stbv_uint8 *do_not_decode) +static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int rn, uint8 *do_not_decode) { int i,j,pass; - StbvResidue *r = f->residue_config + rn; + Residue *r = f->residue_config + rn; int rtype = f->residue_types[rn]; int c = r->classbook; int classwords = f->codebooks[c].dimensions; @@ -2069,14 +2113,14 @@ static void stbv_decode_residue(stbv_vorb *f, float *residue_buffers[], int ch, unsigned int limit_r_end = (r->end < actual_size ? r->end : actual_size); int n_read = limit_r_end - limit_r_begin; int part_read = n_read / r->part_size; - int temp_alloc_point = stbv_temp_alloc_save(f); + int temp_alloc_point = temp_alloc_save(f); #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - stbv_uint8 ***part_classdata = (stbv_uint8 ***) stbv_temp_block_array(f,f->channels, part_read * sizeof(**part_classdata)); + uint8 ***part_classdata = (uint8 ***) temp_block_array(f,f->channels, part_read * sizeof(**part_classdata)); #else - int **classifications = (int **) stbv_temp_block_array(f,f->channels, part_read * sizeof(**classifications)); + int **classifications = (int **) temp_block_array(f,f->channels, part_read * sizeof(**classifications)); #endif - STBV_CHECK(f); + CHECK(f); for (i=0; i < ch; ++i) if (!do_not_decode[i]) @@ -2096,10 +2140,10 @@ static void stbv_decode_residue(stbv_vorb *f, float *residue_buffers[], int ch, int z = r->begin + pcount*r->part_size; int c_inter = (z & 1), p_inter = z>>1; if (pass == 0) { - StbvCodebook *c = f->codebooks+r->classbook; + Codebook *c = f->codebooks+r->classbook; int q; - STBV_DECODE(q,f,c); - if (q == STBV_EOP) goto done; + DECODE(q,f,c); + if (q == EOP) goto done; #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE part_classdata[0][class_set] = r->classdata[q]; #else @@ -2118,13 +2162,13 @@ static void stbv_decode_residue(stbv_vorb *f, float *residue_buffers[], int ch, #endif int b = r->residue_books[c][pass]; if (b >= 0) { - StbvCodebook *book = f->codebooks + b; + Codebook *book = f->codebooks + b; #ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK - if (!stbv_codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) + if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) goto done; #else // saves 1% - if (!stbv_codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) + if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) goto done; #endif } else { @@ -2137,55 +2181,15 @@ static void stbv_decode_residue(stbv_vorb *f, float *residue_buffers[], int ch, ++class_set; #endif } - } else if (ch == 1) { - while (pcount < part_read) { - int z = r->begin + pcount*r->part_size; - int c_inter = 0, p_inter = z; - if (pass == 0) { - StbvCodebook *c = f->codebooks+r->classbook; - int q; - STBV_DECODE(q,f,c); - if (q == STBV_EOP) goto done; - #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - part_classdata[0][class_set] = r->classdata[q]; - #else - for (i=classwords-1; i >= 0; --i) { - classifications[0][i+pcount] = q % r->classifications; - q /= r->classifications; - } - #endif - } - for (i=0; i < classwords && pcount < part_read; ++i, ++pcount) { - int z = r->begin + pcount*r->part_size; - #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - int c = part_classdata[0][class_set][i]; - #else - int c = classifications[0][pcount]; - #endif - int b = r->residue_books[c][pass]; - if (b >= 0) { - StbvCodebook *book = f->codebooks + b; - if (!stbv_codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) - goto done; - } else { - z += r->part_size; - c_inter = 0; - p_inter = z; - } - } - #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - ++class_set; - #endif - } - } else { + } else if (ch > 2) { while (pcount < part_read) { int z = r->begin + pcount*r->part_size; int c_inter = z % ch, p_inter = z/ch; if (pass == 0) { - StbvCodebook *c = f->codebooks+r->classbook; + Codebook *c = f->codebooks+r->classbook; int q; - STBV_DECODE(q,f,c); - if (q == STBV_EOP) goto done; + DECODE(q,f,c); + if (q == EOP) goto done; #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE part_classdata[0][class_set] = r->classdata[q]; #else @@ -2204,8 +2208,8 @@ static void stbv_decode_residue(stbv_vorb *f, float *residue_buffers[], int ch, #endif int b = r->residue_books[c][pass]; if (b >= 0) { - StbvCodebook *book = f->codebooks + b; - if (!stbv_codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) + Codebook *book = f->codebooks + b; + if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) goto done; } else { z += r->part_size; @@ -2221,7 +2225,7 @@ static void stbv_decode_residue(stbv_vorb *f, float *residue_buffers[], int ch, } goto done; } - STBV_CHECK(f); + CHECK(f); for (pass=0; pass < 8; ++pass) { int pcount = 0, class_set=0; @@ -2229,10 +2233,10 @@ static void stbv_decode_residue(stbv_vorb *f, float *residue_buffers[], int ch, if (pass == 0) { for (j=0; j < ch; ++j) { if (!do_not_decode[j]) { - StbvCodebook *c = f->codebooks+r->classbook; + Codebook *c = f->codebooks+r->classbook; int temp; - STBV_DECODE(temp,f,c); - if (temp == STBV_EOP) goto done; + DECODE(temp,f,c); + if (temp == EOP) goto done; #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE part_classdata[j][class_set] = r->classdata[temp]; #else @@ -2257,8 +2261,8 @@ static void stbv_decode_residue(stbv_vorb *f, float *residue_buffers[], int ch, float *target = residue_buffers[j]; int offset = r->begin + pcount * r->part_size; int n = r->part_size; - StbvCodebook *book = f->codebooks + b; - if (!stbv_residue_decode(f, book, target, offset, n, rtype)) + Codebook *book = f->codebooks + b; + if (!residue_decode(f, book, target, offset, n, rtype)) goto done; } } @@ -2270,13 +2274,13 @@ static void stbv_decode_residue(stbv_vorb *f, float *residue_buffers[], int ch, } } done: - STBV_CHECK(f); + CHECK(f); #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - stbv_temp_free(f,part_classdata); + temp_free(f,part_classdata); #else - stbv_temp_free(f,classifications); + temp_free(f,classifications); #endif - stbv_temp_alloc_restore(f,temp_alloc_point); + temp_alloc_restore(f,temp_alloc_point); } @@ -2305,7 +2309,7 @@ void inverse_mdct_slow(float *buffer, int n) } #elif 0 // same as above, but just barely able to run in real time on modern machines -void inverse_mdct_slow(float *buffer, int n, stbv_vorb *f, int blocktype) +void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype) { float mcos[16384]; int i,j; @@ -2343,7 +2347,7 @@ void dct_iv_slow(float *buffer, int n) } } -void inverse_mdct_slow(float *buffer, int n, stbv_vorb *f, int blocktype) +void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype) { int i, n4 = n >> 2, n2 = n >> 1, n3_4 = n - n4; float temp[4096]; @@ -2364,11 +2368,11 @@ void inverse_mdct_slow(float *buffer, int n, stbv_vorb *f, int blocktype) #if LIBVORBIS_MDCT // directly call the vorbis MDCT using an interface documented // by Jeff Roberts... useful for performance comparison -typedef struct +typedef struct { int n; int log2n; - + float *trig; int *bitrev; @@ -2381,13 +2385,13 @@ extern void mdct_backward(mdct_lookup *init, float *in, float *out); mdct_lookup M1,M2; -void stbv_inverse_mdct(float *buffer, int n, stbv_vorb *f, int blocktype) +void inverse_mdct(float *buffer, int n, vorb *f, int blocktype) { mdct_lookup *M; if (M1.n == n) M = &M1; else if (M2.n == n) M = &M2; else if (M1.n == 0) { mdct_init(&M1, n); M = &M1; } - else { + else { if (M2.n) __asm int 3; mdct_init(&M2, n); M = &M2; @@ -2401,7 +2405,7 @@ void stbv_inverse_mdct(float *buffer, int n, stbv_vorb *f, int blocktype) // the following were split out into separate functions while optimizing; // they could be pushed back up but eh. __forceinline showed no change; // they're probably already being inlined. -static void stbv_imdct_step3_iter0_loop(int n, float *e, int i_off, int k_off, float *A) +static void imdct_step3_iter0_loop(int n, float *e, int i_off, int k_off, float *A) { float *ee0 = e + i_off; float *ee2 = ee0 + k_off; @@ -2446,7 +2450,7 @@ static void stbv_imdct_step3_iter0_loop(int n, float *e, int i_off, int k_off, f } } -static void stbv_imdct_step3_inner_r_loop(int lim, float *e, int d0, int k_off, float *A, int k1) +static void imdct_step3_inner_r_loop(int lim, float *e, int d0, int k_off, float *A, int k1) { int i; float k00_20, k01_21; @@ -2496,7 +2500,7 @@ static void stbv_imdct_step3_inner_r_loop(int lim, float *e, int d0, int k_off, } } -static void stbv_imdct_step3_inner_s_loop(int n, float *e, int i_off, int k_off, float *A, int a_off, int k0) +static void imdct_step3_inner_s_loop(int n, float *e, int i_off, int k_off, float *A, int a_off, int k0) { int i; float A0 = A[0]; @@ -2547,7 +2551,7 @@ static void stbv_imdct_step3_inner_s_loop(int n, float *e, int i_off, int k_off, } } -static __forceinline void stbv_iter_54(float *z) +static __forceinline void iter_54(float *z) { float k00,k11,k22,k33; float y0,y1,y2,y3; @@ -2579,7 +2583,7 @@ static __forceinline void stbv_iter_54(float *z) z[-7] = k11 + k22; // z1 - z5 - z2 + z6 } -static void stbv_imdct_step3_inner_s_loop_ld654(int n, float *e, int i_off, float *A, int base_n) +static void imdct_step3_inner_s_loop_ld654(int n, float *e, int i_off, float *A, int base_n) { int a_off = base_n >> 3; float A2 = A[0+a_off]; @@ -2588,48 +2592,47 @@ static void stbv_imdct_step3_inner_s_loop_ld654(int n, float *e, int i_off, floa while (z > base) { float k00,k11; + float l00,l11; - k00 = z[-0] - z[-8]; - k11 = z[-1] - z[-9]; - z[-0] = z[-0] + z[-8]; - z[-1] = z[-1] + z[-9]; - z[-8] = k00; - z[-9] = k11 ; + k00 = z[-0] - z[ -8]; + k11 = z[-1] - z[ -9]; + l00 = z[-2] - z[-10]; + l11 = z[-3] - z[-11]; + z[ -0] = z[-0] + z[ -8]; + z[ -1] = z[-1] + z[ -9]; + z[ -2] = z[-2] + z[-10]; + z[ -3] = z[-3] + z[-11]; + z[ -8] = k00; + z[ -9] = k11; + z[-10] = (l00+l11) * A2; + z[-11] = (l11-l00) * A2; - k00 = z[ -2] - z[-10]; - k11 = z[ -3] - z[-11]; - z[ -2] = z[ -2] + z[-10]; - z[ -3] = z[ -3] + z[-11]; - z[-10] = (k00+k11) * A2; - z[-11] = (k11-k00) * A2; - - k00 = z[-12] - z[ -4]; // reverse to avoid a unary negation + k00 = z[ -4] - z[-12]; k11 = z[ -5] - z[-13]; + l00 = z[ -6] - z[-14]; + l11 = z[ -7] - z[-15]; z[ -4] = z[ -4] + z[-12]; z[ -5] = z[ -5] + z[-13]; - z[-12] = k11; - z[-13] = k00; - - k00 = z[-14] - z[ -6]; // reverse to avoid a unary negation - k11 = z[ -7] - z[-15]; z[ -6] = z[ -6] + z[-14]; z[ -7] = z[ -7] + z[-15]; - z[-14] = (k00+k11) * A2; - z[-15] = (k00-k11) * A2; + z[-12] = k11; + z[-13] = -k00; + z[-14] = (l11-l00) * A2; + z[-15] = (l00+l11) * -A2; - stbv_iter_54(z); - stbv_iter_54(z-8); + iter_54(z); + iter_54(z-8); z -= 16; } } -static void stbv_inverse_mdct(float *buffer, int n, stbv_vorb *f, int blocktype) +static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype) { int n2 = n >> 1, n4 = n >> 2, n8 = n >> 3, l; int ld; // @OPTIMIZE: reduce register pressure by using fewer variables? - int save_point = stbv_temp_alloc_save(f); - float *buf2 = (float *) stbv_temp_alloc(f, n2 * sizeof(*buf2)); + int save_point = temp_alloc_save(f); + float *buf2 = (float *) temp_alloc(f, n2 * sizeof(*buf2)); float *u=NULL,*v=NULL; // twiddle factors float *A = f->A[blocktype]; @@ -2650,7 +2653,7 @@ static void stbv_inverse_mdct(float *buffer, int n, stbv_vorb *f, int blocktype) // once I combined the passes. // so there's a missing 'times 2' here (for adding X to itself). - // this propogates through linearly to the end, where the numbers + // this propagates through linearly to the end, where the numbers // are 1/2 too small, and need to be compensated for. { @@ -2724,7 +2727,7 @@ static void stbv_inverse_mdct(float *buffer, int n, stbv_vorb *f, int blocktype) } // step 3 - ld = stbv_ilog(n) - 1; // stbv_ilog is off-by-one from normal definitions + ld = ilog(n) - 1; // ilog is off-by-one from normal definitions // optimized step 3: @@ -2734,14 +2737,14 @@ static void stbv_inverse_mdct(float *buffer, int n, stbv_vorb *f, int blocktype) // switch between them halfway. // this is iteration 0 of step 3 - stbv_imdct_step3_iter0_loop(n >> 4, u, n2-1-n4*0, -(n >> 3), A); - stbv_imdct_step3_iter0_loop(n >> 4, u, n2-1-n4*1, -(n >> 3), A); + imdct_step3_iter0_loop(n >> 4, u, n2-1-n4*0, -(n >> 3), A); + imdct_step3_iter0_loop(n >> 4, u, n2-1-n4*1, -(n >> 3), A); // this is iteration 1 of step 3 - stbv_imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*0, -(n >> 4), A, 16); - stbv_imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*1, -(n >> 4), A, 16); - stbv_imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*2, -(n >> 4), A, 16); - stbv_imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*3, -(n >> 4), A, 16); + imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*0, -(n >> 4), A, 16); + imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*1, -(n >> 4), A, 16); + imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*2, -(n >> 4), A, 16); + imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*3, -(n >> 4), A, 16); l=2; for (; l < (ld-3)>>1; ++l) { @@ -2749,7 +2752,7 @@ static void stbv_inverse_mdct(float *buffer, int n, stbv_vorb *f, int blocktype) int lim = 1 << (l+1); int i; for (i=0; i < lim; ++i) - stbv_imdct_step3_inner_r_loop(n >> (l+4), u, n2-1 - k0*i, -k0_2, A, 1 << (l+3)); + imdct_step3_inner_r_loop(n >> (l+4), u, n2-1 - k0*i, -k0_2, A, 1 << (l+3)); } for (; l < ld-6; ++l) { @@ -2760,7 +2763,7 @@ static void stbv_inverse_mdct(float *buffer, int n, stbv_vorb *f, int blocktype) float *A0 = A; i_off = n2-1; for (r=rlim; r > 0; --r) { - stbv_imdct_step3_inner_s_loop(lim, u, i_off, -k0_2, A0, k1, k0); + imdct_step3_inner_s_loop(lim, u, i_off, -k0_2, A0, k1, k0); A0 += k1*4; i_off -= 8; } @@ -2771,14 +2774,14 @@ static void stbv_inverse_mdct(float *buffer, int n, stbv_vorb *f, int blocktype) // the big win comes from getting rid of needless flops // due to the constants on pass 5 & 4 being all 1 and 0; // combining them to be simultaneous to improve cache made little difference - stbv_imdct_step3_inner_s_loop_ld654(n >> 5, u, n2-1, A, n); + imdct_step3_inner_s_loop_ld654(n >> 5, u, n2-1, A, n); // output is u // step 4, 5, and 6 // cannot be in-place because of step 5 { - stbv_uint16 *bitrev = f->stbv_bit_reverse[blocktype]; + uint16 *bitrev = f->bit_reverse[blocktype]; // weirdly, I'd have thought reading sequentially and writing // erratically would have been better than vice-versa, but in // fact that's not what my testing showed. (That is, with @@ -2800,7 +2803,7 @@ static void stbv_inverse_mdct(float *buffer, int n, stbv_vorb *f, int blocktype) d1[0] = u[k4+1]; d0[1] = u[k4+2]; d0[0] = u[k4+3]; - + d0 -= 4; d1 -= 4; bitrev += 2; @@ -2881,7 +2884,7 @@ static void stbv_inverse_mdct(float *buffer, int n, stbv_vorb *f, int blocktype) float p0,p1,p2,p3; p3 = e[6]*B[7] - e[7]*B[6]; - p2 = -e[6]*B[6] - e[7]*B[7]; + p2 = -e[6]*B[6] - e[7]*B[7]; d0[0] = p3; d1[3] = - p3; @@ -2889,7 +2892,7 @@ static void stbv_inverse_mdct(float *buffer, int n, stbv_vorb *f, int blocktype) d3[3] = p2; p1 = e[4]*B[5] - e[5]*B[4]; - p0 = -e[4]*B[4] - e[5]*B[5]; + p0 = -e[4]*B[4] - e[5]*B[5]; d0[1] = p1; d1[2] = - p1; @@ -2897,7 +2900,7 @@ static void stbv_inverse_mdct(float *buffer, int n, stbv_vorb *f, int blocktype) d3[2] = p0; p3 = e[2]*B[3] - e[3]*B[2]; - p2 = -e[2]*B[2] - e[3]*B[3]; + p2 = -e[2]*B[2] - e[3]*B[3]; d0[2] = p3; d1[1] = - p3; @@ -2905,7 +2908,7 @@ static void stbv_inverse_mdct(float *buffer, int n, stbv_vorb *f, int blocktype) d3[1] = p2; p1 = e[0]*B[1] - e[1]*B[0]; - p0 = -e[0]*B[0] - e[1]*B[1]; + p0 = -e[0]*B[0] - e[1]*B[1]; d0[3] = p1; d1[0] = - p1; @@ -2921,8 +2924,8 @@ static void stbv_inverse_mdct(float *buffer, int n, stbv_vorb *f, int blocktype) } } - stbv_temp_free(f,buf2); - stbv_temp_alloc_restore(f,save_point); + temp_free(f,buf2); + temp_alloc_restore(f,save_point); } #if 0 @@ -2973,7 +2976,7 @@ void inverse_mdct_naive(float *buffer, int n) w[k4+1] = (v[n2+1+k4] - v[k4+1])*A[n2-4-k4] + (v[n2+3+k4]-v[k4+3])*A[n2-3-k4]; } // step 3 - ld = stbv_ilog(n) - 1; // stbv_ilog is off-by-one from normal definitions + ld = ilog(n) - 1; // ilog is off-by-one from normal definitions for (l=0; l < ld-3; ++l) { int k0 = n >> (l+2), k1 = 1 << (l+3); int rlim = n >> (l+4), r4, r; @@ -2996,7 +2999,7 @@ void inverse_mdct_naive(float *buffer, int n) // step 4 for (i=0; i < n8; ++i) { - int j = stbv_bit_reverse(i) >> (32-ld+3); + int j = bit_reverse(i) >> (32-ld+3); assert(j < n8); if (i == j) { // paper bug: original code probably swapped in place; if copying, @@ -3053,34 +3056,34 @@ void inverse_mdct_naive(float *buffer, int n) } #endif -static float *stbv_get_window(stbv_vorb *f, int len) +static float *get_window(vorb *f, int len) { len <<= 1; if (len == f->blocksize_0) return f->window[0]; if (len == f->blocksize_1) return f->window[1]; - assert(0); return NULL; } #ifndef STB_VORBIS_NO_DEFER_FLOOR -typedef stbv_int16 STBV_YTYPE; +typedef int16 YTYPE; #else -typedef int STBV_YTYPE; +typedef int YTYPE; #endif -static int stbv_do_floor(stbv_vorb *f, StbvMapping *map, int i, int n, float *target, STBV_YTYPE *finalY, stbv_uint8 *step2_flag) +static int do_floor(vorb *f, Mapping *map, int i, int n, float *target, YTYPE *finalY, uint8 *step2_flag) { int n2 = n >> 1; int s = map->chan[i].mux, floor; floor = map->submap_floor[s]; if (f->floor_types[floor] == 0) { - return stbv_error(f, VORBIS_invalid_stream); + return error(f, VORBIS_invalid_stream); } else { - StbvFloor1 *g = &f->floor_config[floor].floor1; + Floor1 *g = &f->floor_config[floor].floor1; int j,q; int lx = 0, ly = finalY[0] * g->floor1_multiplier; for (q=1; q < g->values; ++q) { j = g->sorted_order[q]; #ifndef STB_VORBIS_NO_DEFER_FLOOR + STBV_NOTUSED(step2_flag); if (finalY[j] >= 0) #else if (step2_flag[j]) @@ -3089,16 +3092,16 @@ static int stbv_do_floor(stbv_vorb *f, StbvMapping *map, int i, int n, float *ta int hy = finalY[j] * g->floor1_multiplier; int hx = g->Xlist[j]; if (lx != hx) - stbv_draw_line(target, lx,ly, hx,hy, n2); - STBV_CHECK(f); + draw_line(target, lx,ly, hx,hy, n2); + CHECK(f); lx = hx, ly = hy; } } if (lx < n2) { - // optimization of: stbv_draw_line(target, lx,ly, n,ly, n2); + // optimization of: draw_line(target, lx,ly, n,ly, n2); for (j=lx; j < n2; ++j) - STBV_LINE_OP(target[j], stbv_inverse_db_table[ly]); - STBV_CHECK(f); + LINE_OP(target[j], inverse_db_table[ly]); + CHECK(f); } } return TRUE; @@ -3118,36 +3121,36 @@ static int stbv_do_floor(stbv_vorb *f, StbvMapping *map, int i, int n, float *ta // has to be the same as frame N+1's left_end-left_start (which they are by // construction) -static int stbv_vorbis_decode_initial(stbv_vorb *f, int *p_left_start, int *p_left_end, int *p_right_start, int *p_right_end, int *mode) +static int vorbis_decode_initial(vorb *f, int *p_left_start, int *p_left_end, int *p_right_start, int *p_right_end, int *mode) { - StbvMode *m; + Mode *m; int i, n, prev, next, window_center; f->channel_buffer_start = f->channel_buffer_end = 0; retry: if (f->eof) return FALSE; - if (!stbv_maybe_start_packet(f)) + if (!maybe_start_packet(f)) return FALSE; // check packet type - if (stbv_get_bits(f,1) != 0) { - if (STBV_IS_PUSH_MODE(f)) - return stbv_error(f,VORBIS_bad_packet_type); - while (STBV_EOP != stbv_get8_packet(f)); + if (get_bits(f,1) != 0) { + if (IS_PUSH_MODE(f)) + return error(f,VORBIS_bad_packet_type); + while (EOP != get8_packet(f)); goto retry; } if (f->alloc.alloc_buffer) assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); - i = stbv_get_bits(f, stbv_ilog(f->mode_count-1)); - if (i == STBV_EOP) return FALSE; + i = get_bits(f, ilog(f->mode_count-1)); + if (i == EOP) return FALSE; if (i >= f->mode_count) return FALSE; *mode = i; m = f->mode_config + i; if (m->blockflag) { n = f->blocksize_1; - prev = stbv_get_bits(f,1); - next = stbv_get_bits(f,1); + prev = get_bits(f,1); + next = get_bits(f,1); } else { prev = next = 0; n = f->blocksize_0; @@ -3174,40 +3177,41 @@ static int stbv_vorbis_decode_initial(stbv_vorb *f, int *p_left_start, int *p_le return TRUE; } -static int stbv_vorbis_decode_packet_rest(stbv_vorb *f, int *len, StbvMode *m, int left_start, int left_end, int right_start, int right_end, int *p_left) +static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start, int left_end, int right_start, int right_end, int *p_left) { - StbvMapping *map; + Mapping *map; int i,j,k,n,n2; int zero_channel[256]; int really_zero_channel[256]; // WINDOWING + STBV_NOTUSED(left_end); n = f->blocksize[m->blockflag]; map = &f->mapping[m->mapping]; // FLOORS n2 = n >> 1; - STBV_CHECK(f); + CHECK(f); for (i=0; i < f->channels; ++i) { int s = map->chan[i].mux, floor; zero_channel[i] = FALSE; floor = map->submap_floor[s]; if (f->floor_types[floor] == 0) { - return stbv_error(f, VORBIS_invalid_stream); + return error(f, VORBIS_invalid_stream); } else { - StbvFloor1 *g = &f->floor_config[floor].floor1; - if (stbv_get_bits(f, 1)) { + Floor1 *g = &f->floor_config[floor].floor1; + if (get_bits(f, 1)) { short *finalY; - stbv_uint8 step2_flag[256]; + uint8 step2_flag[256]; static int range_list[4] = { 256, 128, 86, 64 }; int range = range_list[g->floor1_multiplier-1]; int offset = 2; finalY = f->finalY[i]; - finalY[0] = stbv_get_bits(f, stbv_ilog(range)-1); - finalY[1] = stbv_get_bits(f, stbv_ilog(range)-1); + finalY[0] = get_bits(f, ilog(range)-1); + finalY[1] = get_bits(f, ilog(range)-1); for (j=0; j < g->partitions; ++j) { int pclass = g->partition_class_list[j]; int cdim = g->class_dimensions[pclass]; @@ -3215,29 +3219,29 @@ static int stbv_vorbis_decode_packet_rest(stbv_vorb *f, int *len, StbvMode *m, i int csub = (1 << cbits)-1; int cval = 0; if (cbits) { - StbvCodebook *c = f->codebooks + g->class_masterbooks[pclass]; - STBV_DECODE(cval,f,c); + Codebook *c = f->codebooks + g->class_masterbooks[pclass]; + DECODE(cval,f,c); } for (k=0; k < cdim; ++k) { int book = g->subclass_books[pclass][cval & csub]; cval = cval >> cbits; if (book >= 0) { int temp; - StbvCodebook *c = f->codebooks + book; - STBV_DECODE(temp,f,c); + Codebook *c = f->codebooks + book; + DECODE(temp,f,c); finalY[offset++] = temp; } else finalY[offset++] = 0; } } - if (f->valid_bits == STBV_INVALID_BITS) goto error; // behavior according to spec + if (f->valid_bits == INVALID_BITS) goto error; // behavior according to spec step2_flag[0] = step2_flag[1] = 1; for (j=2; j < g->values; ++j) { int low, high, pred, highroom, lowroom, room, val; - low = g->stbv_neighbors[j][0]; - high = g->stbv_neighbors[j][1]; - //stbv_neighbors(g->Xlist, j, &low, &high); - pred = stbv_predict_point(g->Xlist[j], g->Xlist[low], g->Xlist[high], finalY[low], finalY[high]); + low = g->neighbors[j][0]; + high = g->neighbors[j][1]; + //neighbors(g->Xlist, j, &low, &high); + pred = predict_point(g->Xlist[j], g->Xlist[low], g->Xlist[high], finalY[low], finalY[high]); val = finalY[j]; highroom = range - pred; lowroom = pred; @@ -3265,7 +3269,7 @@ static int stbv_vorbis_decode_packet_rest(stbv_vorb *f, int *len, StbvMode *m, i } #ifdef STB_VORBIS_NO_DEFER_FLOOR - stbv_do_floor(f, map, i, n, f->floor_buffers[i], finalY, step2_flag); + do_floor(f, map, i, n, f->floor_buffers[i], finalY, step2_flag); #else // defer final floor computation until _after_ residue for (j=0; j < g->values; ++j) { @@ -3282,7 +3286,7 @@ static int stbv_vorbis_decode_packet_rest(stbv_vorb *f, int *len, StbvMode *m, i // at this point we've decoded the floor into buffer } } - STBV_CHECK(f); + CHECK(f); // at this point we've decoded all floors if (f->alloc.alloc_buffer) @@ -3295,12 +3299,12 @@ static int stbv_vorbis_decode_packet_rest(stbv_vorb *f, int *len, StbvMode *m, i zero_channel[map->chan[i].magnitude] = zero_channel[map->chan[i].angle] = FALSE; } - STBV_CHECK(f); -// RESIDUE STBV_DECODE + CHECK(f); +// RESIDUE DECODE for (i=0; i < map->submaps; ++i) { float *residue_buffers[STB_VORBIS_MAX_CHANNELS]; int r; - stbv_uint8 do_not_decode[256]; + uint8 do_not_decode[256]; int ch = 0; for (j=0; j < f->channels; ++j) { if (map->chan[j].mux == i) { @@ -3315,12 +3319,12 @@ static int stbv_vorbis_decode_packet_rest(stbv_vorb *f, int *len, StbvMode *m, i } } r = map->submap_residue[i]; - stbv_decode_residue(f, residue_buffers, ch, n2, r, do_not_decode); + decode_residue(f, residue_buffers, ch, n2, r, do_not_decode); } if (f->alloc.alloc_buffer) assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); - STBV_CHECK(f); + CHECK(f); // INVERSE COUPLING for (i = map->coupling_steps-1; i >= 0; --i) { @@ -3343,7 +3347,7 @@ static int stbv_vorbis_decode_packet_rest(stbv_vorb *f, int *len, StbvMode *m, i a[j] = a2; } } - STBV_CHECK(f); + CHECK(f); // finish decoding the floors #ifndef STB_VORBIS_NO_DEFER_FLOOR @@ -3351,7 +3355,7 @@ static int stbv_vorbis_decode_packet_rest(stbv_vorb *f, int *len, StbvMode *m, i if (really_zero_channel[i]) { memset(f->channel_buffers[i], 0, sizeof(*f->channel_buffers[i]) * n2); } else { - stbv_do_floor(f, map, i, n, f->channel_buffers[i], f->finalY[i], NULL); + do_floor(f, map, i, n, f->channel_buffers[i], f->finalY[i], NULL); } } #else @@ -3366,21 +3370,21 @@ static int stbv_vorbis_decode_packet_rest(stbv_vorb *f, int *len, StbvMode *m, i #endif // INVERSE MDCT - STBV_CHECK(f); + CHECK(f); for (i=0; i < f->channels; ++i) - stbv_inverse_mdct(f->channel_buffers[i], n, f, m->blockflag); - STBV_CHECK(f); + inverse_mdct(f->channel_buffers[i], n, f, m->blockflag); + CHECK(f); // this shouldn't be necessary, unless we exited on an error // and want to flush to get to the next packet - stbv_flush_packet(f); + flush_packet(f); if (f->first_decode) { // assume we start so first non-discarded sample is sample 0 // this isn't to spec, but spec would require us to read ahead // and decode the size of all current frames--could be done, // but presumably it's not a commonly used feature - f->current_loc = -n2; // start of first frame is positioned for discard + f->current_loc = 0u - n2; // start of first frame is positioned for discard (NB this is an intentional unsigned overflow/wrap-around) // we might have to discard samples "from" the next frame too, // if we're lapping a large block then a small at the start? f->discard_samples_deferred = n - right_end; @@ -3408,8 +3412,8 @@ static int stbv_vorbis_decode_packet_rest(stbv_vorb *f, int *len, StbvMode *m, i // check if we have ogg information about the sample # for this packet if (f->last_seg_which == f->end_seg_with_known_loc) { // if we have a valid current loc, and this is final: - if (f->current_loc_valid && (f->page_flag & STBV_PAGEFLAG_last_page)) { - stbv_uint32 current_end = f->known_loc_for_packet; + if (f->current_loc_valid && (f->page_flag & PAGEFLAG_last_page)) { + uint32 current_end = f->known_loc_for_packet; // then let's infer the size of the (probably) short final frame if (current_end < f->current_loc + (right_end-left_start)) { if (current_end < f->current_loc) { @@ -3437,19 +3441,19 @@ static int stbv_vorbis_decode_packet_rest(stbv_vorb *f, int *len, StbvMode *m, i if (f->alloc.alloc_buffer) assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); *len = right_end; // ignore samples after the window goes to 0 - STBV_CHECK(f); + CHECK(f); return TRUE; } -static int stbv_vorbis_decode_packet(stbv_vorb *f, int *len, int *p_left, int *p_right) +static int vorbis_decode_packet(vorb *f, int *len, int *p_left, int *p_right) { int mode, left_end, right_end; - if (!stbv_vorbis_decode_initial(f, p_left, &left_end, p_right, &right_end, &mode)) return 0; - return stbv_vorbis_decode_packet_rest(f, len, f->mode_config + mode, *p_left, left_end, *p_right, right_end, p_left); + if (!vorbis_decode_initial(f, p_left, &left_end, p_right, &right_end, &mode)) return 0; + return vorbis_decode_packet_rest(f, len, f->mode_config + mode, *p_left, left_end, *p_right, right_end, p_left); } -static int stbv_vorbis_finish_frame(stb_vorbis *f, int len, int left, int right) +static int vorbis_finish_frame(stb_vorbis *f, int len, int left, int right) { int prev,i,j; // we use right&left (the start of the right- and left-window sin()-regions) @@ -3463,7 +3467,8 @@ static int stbv_vorbis_finish_frame(stb_vorbis *f, int len, int left, int right) // mixin from previous window if (f->previous_length) { int i,j, n = f->previous_length; - float *w = stbv_get_window(f, n); + float *w = get_window(f, n); + if (w == NULL) return 0; for (i=0; i < f->channels; ++i) { for (j=0; j < n; ++j) f->channel_buffers[i][left+j] = @@ -3501,28 +3506,28 @@ static int stbv_vorbis_finish_frame(stb_vorbis *f, int len, int left, int right) return right - left; } -static int stbv_vorbis_pump_first_frame(stb_vorbis *f) +static int vorbis_pump_first_frame(stb_vorbis *f) { int len, right, left, res; - res = stbv_vorbis_decode_packet(f, &len, &left, &right); + res = vorbis_decode_packet(f, &len, &left, &right); if (res) - stbv_vorbis_finish_frame(f, len, left, right); + vorbis_finish_frame(f, len, left, right); return res; } #ifndef STB_VORBIS_NO_PUSHDATA_API -static int stbv_is_whole_packet_present(stb_vorbis *f, int end_page) +static int is_whole_packet_present(stb_vorbis *f) { // make sure that we have the packet available before continuing... // this requires a full ogg parse, but we know we can fetch from f->stream // instead of coding this out explicitly, we could save the current read state, - // read the next packet with stbv_get8() until end-of-packet, check f->eof, then + // read the next packet with get8() until end-of-packet, check f->eof, then // reset the state? but that would be slower, esp. since we'd have over 256 bytes // of state to restore (primarily the page segment table) int s = f->next_seg, first = TRUE; - stbv_uint8 *p = f->stream; + uint8 *p = f->stream; if (s != -1) { // if we're not starting the packet with a 'continue on next page' flag for (; s < f->segment_count; ++s) { @@ -3531,112 +3536,166 @@ static int stbv_is_whole_packet_present(stb_vorbis *f, int end_page) break; } // either this continues, or it ends it... - if (end_page) - if (s < f->segment_count-1) return stbv_error(f, VORBIS_invalid_stream); if (s == f->segment_count) s = -1; // set 'crosses page' flag - if (p > f->stream_end) return stbv_error(f, VORBIS_need_more_data); + if (p > f->stream_end) return error(f, VORBIS_need_more_data); first = FALSE; } for (; s == -1;) { - stbv_uint8 *q; + uint8 *q; int n; // check that we have the page header ready - if (p + 26 >= f->stream_end) return stbv_error(f, VORBIS_need_more_data); + if (p + 26 >= f->stream_end) return error(f, VORBIS_need_more_data); // validate the page - if (memcmp(p, stbv_ogg_page_header, 4)) return stbv_error(f, VORBIS_invalid_stream); - if (p[4] != 0) return stbv_error(f, VORBIS_invalid_stream); + if (memcmp(p, ogg_page_header, 4)) return error(f, VORBIS_invalid_stream); + if (p[4] != 0) return error(f, VORBIS_invalid_stream); if (first) { // the first segment must NOT have 'continued_packet', later ones MUST if (f->previous_length) - if ((p[5] & STBV_PAGEFLAG_continued_packet)) return stbv_error(f, VORBIS_invalid_stream); + if ((p[5] & PAGEFLAG_continued_packet)) return error(f, VORBIS_invalid_stream); // if no previous length, we're resynching, so we can come in on a continued-packet, // which we'll just drop } else { - if (!(p[5] & STBV_PAGEFLAG_continued_packet)) return stbv_error(f, VORBIS_invalid_stream); + if (!(p[5] & PAGEFLAG_continued_packet)) return error(f, VORBIS_invalid_stream); } n = p[26]; // segment counts q = p+27; // q points to segment table p = q + n; // advance past header // make sure we've read the segment table - if (p > f->stream_end) return stbv_error(f, VORBIS_need_more_data); + if (p > f->stream_end) return error(f, VORBIS_need_more_data); for (s=0; s < n; ++s) { p += q[s]; if (q[s] < 255) break; } - if (end_page) - if (s < n-1) return stbv_error(f, VORBIS_invalid_stream); if (s == n) s = -1; // set 'crosses page' flag - if (p > f->stream_end) return stbv_error(f, VORBIS_need_more_data); + if (p > f->stream_end) return error(f, VORBIS_need_more_data); first = FALSE; } return TRUE; } #endif // !STB_VORBIS_NO_PUSHDATA_API -static int stbv_start_decoder(stbv_vorb *f) +static int start_decoder(vorb *f) { - stbv_uint8 header[6], x,y; + uint8 header[6], x,y; int len,i,j,k, max_submaps = 0; int longest_floorlist=0; // first page, first packet + f->first_decode = TRUE; - if (!stbv_start_page(f)) return FALSE; + if (!start_page(f)) return FALSE; // validate page flag - if (!(f->page_flag & STBV_PAGEFLAG_first_page)) return stbv_error(f, VORBIS_invalid_first_page); - if (f->page_flag & STBV_PAGEFLAG_last_page) return stbv_error(f, VORBIS_invalid_first_page); - if (f->page_flag & STBV_PAGEFLAG_continued_packet) return stbv_error(f, VORBIS_invalid_first_page); + if (!(f->page_flag & PAGEFLAG_first_page)) return error(f, VORBIS_invalid_first_page); + if (f->page_flag & PAGEFLAG_last_page) return error(f, VORBIS_invalid_first_page); + if (f->page_flag & PAGEFLAG_continued_packet) return error(f, VORBIS_invalid_first_page); // check for expected packet length - if (f->segment_count != 1) return stbv_error(f, VORBIS_invalid_first_page); - if (f->segments[0] != 30) return stbv_error(f, VORBIS_invalid_first_page); + if (f->segment_count != 1) return error(f, VORBIS_invalid_first_page); + if (f->segments[0] != 30) { + // check for the Ogg skeleton fishead identifying header to refine our error + if (f->segments[0] == 64 && + getn(f, header, 6) && + header[0] == 'f' && + header[1] == 'i' && + header[2] == 's' && + header[3] == 'h' && + header[4] == 'e' && + header[5] == 'a' && + get8(f) == 'd' && + get8(f) == '\0') return error(f, VORBIS_ogg_skeleton_not_supported); + else + return error(f, VORBIS_invalid_first_page); + } + // read packet // check packet header - if (stbv_get8(f) != STBV_VORBIS_packet_id) return stbv_error(f, VORBIS_invalid_first_page); - if (!stbv_getn(f, header, 6)) return stbv_error(f, VORBIS_unexpected_eof); - if (!stbv_vorbis_validate(header)) return stbv_error(f, VORBIS_invalid_first_page); + if (get8(f) != VORBIS_packet_id) return error(f, VORBIS_invalid_first_page); + if (!getn(f, header, 6)) return error(f, VORBIS_unexpected_eof); + if (!vorbis_validate(header)) return error(f, VORBIS_invalid_first_page); // vorbis_version - if (stbv_get32(f) != 0) return stbv_error(f, VORBIS_invalid_first_page); - f->channels = stbv_get8(f); if (!f->channels) return stbv_error(f, VORBIS_invalid_first_page); - if (f->channels > STB_VORBIS_MAX_CHANNELS) return stbv_error(f, VORBIS_too_many_channels); - f->sample_rate = stbv_get32(f); if (!f->sample_rate) return stbv_error(f, VORBIS_invalid_first_page); - stbv_get32(f); // bitrate_maximum - stbv_get32(f); // bitrate_nominal - stbv_get32(f); // bitrate_minimum - x = stbv_get8(f); + if (get32(f) != 0) return error(f, VORBIS_invalid_first_page); + f->channels = get8(f); if (!f->channels) return error(f, VORBIS_invalid_first_page); + if (f->channels > STB_VORBIS_MAX_CHANNELS) return error(f, VORBIS_too_many_channels); + f->sample_rate = get32(f); if (!f->sample_rate) return error(f, VORBIS_invalid_first_page); + get32(f); // bitrate_maximum + get32(f); // bitrate_nominal + get32(f); // bitrate_minimum + x = get8(f); { int log0,log1; log0 = x & 15; log1 = x >> 4; f->blocksize_0 = 1 << log0; f->blocksize_1 = 1 << log1; - if (log0 < 6 || log0 > 13) return stbv_error(f, VORBIS_invalid_setup); - if (log1 < 6 || log1 > 13) return stbv_error(f, VORBIS_invalid_setup); - if (log0 > log1) return stbv_error(f, VORBIS_invalid_setup); + if (log0 < 6 || log0 > 13) return error(f, VORBIS_invalid_setup); + if (log1 < 6 || log1 > 13) return error(f, VORBIS_invalid_setup); + if (log0 > log1) return error(f, VORBIS_invalid_setup); } // framing_flag - x = stbv_get8(f); - if (!(x & 1)) return stbv_error(f, VORBIS_invalid_first_page); + x = get8(f); + if (!(x & 1)) return error(f, VORBIS_invalid_first_page); // second packet! - if (!stbv_start_page(f)) return FALSE; + if (!start_page(f)) return FALSE; + + if (!start_packet(f)) return FALSE; + + if (!next_segment(f)) return FALSE; + + if (get8_packet(f) != VORBIS_packet_comment) return error(f, VORBIS_invalid_setup); + for (i=0; i < 6; ++i) header[i] = get8_packet(f); + if (!vorbis_validate(header)) return error(f, VORBIS_invalid_setup); + //file vendor + len = get32_packet(f); + f->vendor = (char*)setup_malloc(f, sizeof(char) * (len+1)); + if (f->vendor == NULL) return error(f, VORBIS_outofmem); + for(i=0; i < len; ++i) { + f->vendor[i] = get8_packet(f); + } + f->vendor[len] = (char)'\0'; + //user comments + f->comment_list_length = get32_packet(f); + f->comment_list = NULL; + if (f->comment_list_length > 0) + { + f->comment_list = (char**) setup_malloc(f, sizeof(char*) * (f->comment_list_length)); + if (f->comment_list == NULL) return error(f, VORBIS_outofmem); + } + + for(i=0; i < f->comment_list_length; ++i) { + len = get32_packet(f); + f->comment_list[i] = (char*)setup_malloc(f, sizeof(char) * (len+1)); + if (f->comment_list[i] == NULL) return error(f, VORBIS_outofmem); + + for(j=0; j < len; ++j) { + f->comment_list[i][j] = get8_packet(f); + } + f->comment_list[i][len] = (char)'\0'; + } + + // framing_flag + x = get8_packet(f); + if (!(x & 1)) return error(f, VORBIS_invalid_setup); + + + skip(f, f->bytes_in_seg); + f->bytes_in_seg = 0; - if (!stbv_start_packet(f)) return FALSE; do { - len = stbv_next_segment(f); - stbv_skip(f, len); + len = next_segment(f); + skip(f, len); f->bytes_in_seg = 0; } while (len); // third packet! - if (!stbv_start_packet(f)) return FALSE; + if (!start_packet(f)) return FALSE; #ifndef STB_VORBIS_NO_PUSHDATA_API - if (STBV_IS_PUSH_MODE(f)) { - if (!stbv_is_whole_packet_present(f, TRUE)) { + if (IS_PUSH_MODE(f)) { + if (!is_whole_packet_present(f)) { // convert error in ogg header to write type if (f->error == VORBIS_invalid_stream) f->error = VORBIS_invalid_setup; @@ -3645,64 +3704,65 @@ static int stbv_start_decoder(stbv_vorb *f) } #endif - stbv_crc32_init(); // always init it, to avoid multithread race conditions + crc32_init(); // always init it, to avoid multithread race conditions - if (stbv_get8_packet(f) != STBV_VORBIS_packet_setup) return stbv_error(f, VORBIS_invalid_setup); - for (i=0; i < 6; ++i) header[i] = stbv_get8_packet(f); - if (!stbv_vorbis_validate(header)) return stbv_error(f, VORBIS_invalid_setup); + if (get8_packet(f) != VORBIS_packet_setup) return error(f, VORBIS_invalid_setup); + for (i=0; i < 6; ++i) header[i] = get8_packet(f); + if (!vorbis_validate(header)) return error(f, VORBIS_invalid_setup); // codebooks - f->codebook_count = stbv_get_bits(f,8) + 1; - f->codebooks = (StbvCodebook *) stbv_setup_malloc(f, sizeof(*f->codebooks) * f->codebook_count); - if (f->codebooks == NULL) return stbv_error(f, VORBIS_outofmem); + f->codebook_count = get_bits(f,8) + 1; + f->codebooks = (Codebook *) setup_malloc(f, sizeof(*f->codebooks) * f->codebook_count); + if (f->codebooks == NULL) return error(f, VORBIS_outofmem); memset(f->codebooks, 0, sizeof(*f->codebooks) * f->codebook_count); for (i=0; i < f->codebook_count; ++i) { - stbv_uint32 *values; + uint32 *values; int ordered, sorted_count; int total=0; - stbv_uint8 *lengths; - StbvCodebook *c = f->codebooks+i; - STBV_CHECK(f); - x = stbv_get_bits(f, 8); if (x != 0x42) return stbv_error(f, VORBIS_invalid_setup); - x = stbv_get_bits(f, 8); if (x != 0x43) return stbv_error(f, VORBIS_invalid_setup); - x = stbv_get_bits(f, 8); if (x != 0x56) return stbv_error(f, VORBIS_invalid_setup); - x = stbv_get_bits(f, 8); - c->dimensions = (stbv_get_bits(f, 8)<<8) + x; - x = stbv_get_bits(f, 8); - y = stbv_get_bits(f, 8); - c->entries = (stbv_get_bits(f, 8)<<16) + (y<<8) + x; - ordered = stbv_get_bits(f,1); - c->sparse = ordered ? 0 : stbv_get_bits(f,1); + uint8 *lengths; + Codebook *c = f->codebooks+i; + CHECK(f); + x = get_bits(f, 8); if (x != 0x42) return error(f, VORBIS_invalid_setup); + x = get_bits(f, 8); if (x != 0x43) return error(f, VORBIS_invalid_setup); + x = get_bits(f, 8); if (x != 0x56) return error(f, VORBIS_invalid_setup); + x = get_bits(f, 8); + c->dimensions = (get_bits(f, 8)<<8) + x; + x = get_bits(f, 8); + y = get_bits(f, 8); + c->entries = (get_bits(f, 8)<<16) + (y<<8) + x; + ordered = get_bits(f,1); + c->sparse = ordered ? 0 : get_bits(f,1); - if (c->dimensions == 0 && c->entries != 0) return stbv_error(f, VORBIS_invalid_setup); + if (c->dimensions == 0 && c->entries != 0) return error(f, VORBIS_invalid_setup); if (c->sparse) - lengths = (stbv_uint8 *) stbv_setup_temp_malloc(f, c->entries); + lengths = (uint8 *) setup_temp_malloc(f, c->entries); else - lengths = c->codeword_lengths = (stbv_uint8 *) stbv_setup_malloc(f, c->entries); + lengths = c->codeword_lengths = (uint8 *) setup_malloc(f, c->entries); - if (!lengths) return stbv_error(f, VORBIS_outofmem); + if (!lengths) return error(f, VORBIS_outofmem); if (ordered) { int current_entry = 0; - int current_length = stbv_get_bits(f,5) + 1; + int current_length = get_bits(f,5) + 1; while (current_entry < c->entries) { int limit = c->entries - current_entry; - int n = stbv_get_bits(f, stbv_ilog(limit)); - if (current_entry + n > (int) c->entries) { return stbv_error(f, VORBIS_invalid_setup); } + int n = get_bits(f, ilog(limit)); + if (current_length >= 32) return error(f, VORBIS_invalid_setup); + if (current_entry + n > (int) c->entries) { return error(f, VORBIS_invalid_setup); } memset(lengths + current_entry, current_length, n); current_entry += n; ++current_length; } } else { for (j=0; j < c->entries; ++j) { - int present = c->sparse ? stbv_get_bits(f,1) : 1; + int present = c->sparse ? get_bits(f,1) : 1; if (present) { - lengths[j] = stbv_get_bits(f, 5) + 1; + lengths[j] = get_bits(f, 5) + 1; ++total; if (lengths[j] == 32) - return stbv_error(f, VORBIS_invalid_setup); + return error(f, VORBIS_invalid_setup); } else { lengths[j] = NO_CODE; } @@ -3714,10 +3774,10 @@ static int stbv_start_decoder(stbv_vorb *f) if (c->entries > (int) f->setup_temp_memory_required) f->setup_temp_memory_required = c->entries; - c->codeword_lengths = (stbv_uint8 *) stbv_setup_malloc(f, c->entries); - if (c->codeword_lengths == NULL) return stbv_error(f, VORBIS_outofmem); + c->codeword_lengths = (uint8 *) setup_malloc(f, c->entries); + if (c->codeword_lengths == NULL) return error(f, VORBIS_outofmem); memcpy(c->codeword_lengths, lengths, c->entries); - stbv_setup_temp_free(f, lengths, c->entries); // note this is only safe if there have been no intervening temp mallocs! + setup_temp_free(f, lengths, c->entries); // note this is only safe if there have been no intervening temp mallocs! lengths = c->codeword_lengths; c->sparse = 0; } @@ -3737,72 +3797,74 @@ static int stbv_start_decoder(stbv_vorb *f) c->sorted_entries = sorted_count; values = NULL; - STBV_CHECK(f); + CHECK(f); if (!c->sparse) { - c->codewords = (stbv_uint32 *) stbv_setup_malloc(f, sizeof(c->codewords[0]) * c->entries); - if (!c->codewords) return stbv_error(f, VORBIS_outofmem); + c->codewords = (uint32 *) setup_malloc(f, sizeof(c->codewords[0]) * c->entries); + if (!c->codewords) return error(f, VORBIS_outofmem); } else { unsigned int size; if (c->sorted_entries) { - c->codeword_lengths = (stbv_uint8 *) stbv_setup_malloc(f, c->sorted_entries); - if (!c->codeword_lengths) return stbv_error(f, VORBIS_outofmem); - c->codewords = (stbv_uint32 *) stbv_setup_temp_malloc(f, sizeof(*c->codewords) * c->sorted_entries); - if (!c->codewords) return stbv_error(f, VORBIS_outofmem); - values = (stbv_uint32 *) stbv_setup_temp_malloc(f, sizeof(*values) * c->sorted_entries); - if (!values) return stbv_error(f, VORBIS_outofmem); + c->codeword_lengths = (uint8 *) setup_malloc(f, c->sorted_entries); + if (!c->codeword_lengths) return error(f, VORBIS_outofmem); + c->codewords = (uint32 *) setup_temp_malloc(f, sizeof(*c->codewords) * c->sorted_entries); + if (!c->codewords) return error(f, VORBIS_outofmem); + values = (uint32 *) setup_temp_malloc(f, sizeof(*values) * c->sorted_entries); + if (!values) return error(f, VORBIS_outofmem); } size = c->entries + (sizeof(*c->codewords) + sizeof(*values)) * c->sorted_entries; if (size > f->setup_temp_memory_required) f->setup_temp_memory_required = size; } - if (!stbv_compute_codewords(c, lengths, c->entries, values)) { - if (c->sparse) stbv_setup_temp_free(f, values, 0); - return stbv_error(f, VORBIS_invalid_setup); + if (!compute_codewords(c, lengths, c->entries, values)) { + if (c->sparse) setup_temp_free(f, values, 0); + return error(f, VORBIS_invalid_setup); } if (c->sorted_entries) { // allocate an extra slot for sentinels - c->sorted_codewords = (stbv_uint32 *) stbv_setup_malloc(f, sizeof(*c->sorted_codewords) * (c->sorted_entries+1)); - if (c->sorted_codewords == NULL) return stbv_error(f, VORBIS_outofmem); + c->sorted_codewords = (uint32 *) setup_malloc(f, sizeof(*c->sorted_codewords) * (c->sorted_entries+1)); + if (c->sorted_codewords == NULL) return error(f, VORBIS_outofmem); // allocate an extra slot at the front so that c->sorted_values[-1] is defined // so that we can catch that case without an extra if - c->sorted_values = ( int *) stbv_setup_malloc(f, sizeof(*c->sorted_values ) * (c->sorted_entries+1)); - if (c->sorted_values == NULL) return stbv_error(f, VORBIS_outofmem); + c->sorted_values = ( int *) setup_malloc(f, sizeof(*c->sorted_values ) * (c->sorted_entries+1)); + if (c->sorted_values == NULL) return error(f, VORBIS_outofmem); ++c->sorted_values; c->sorted_values[-1] = -1; - stbv_compute_sorted_huffman(c, lengths, values); + compute_sorted_huffman(c, lengths, values); } if (c->sparse) { - stbv_setup_temp_free(f, values, sizeof(*values)*c->sorted_entries); - stbv_setup_temp_free(f, c->codewords, sizeof(*c->codewords)*c->sorted_entries); - stbv_setup_temp_free(f, lengths, c->entries); + setup_temp_free(f, values, sizeof(*values)*c->sorted_entries); + setup_temp_free(f, c->codewords, sizeof(*c->codewords)*c->sorted_entries); + setup_temp_free(f, lengths, c->entries); c->codewords = NULL; } - stbv_compute_accelerated_huffman(c); + compute_accelerated_huffman(c); - STBV_CHECK(f); - c->lookup_type = stbv_get_bits(f, 4); - if (c->lookup_type > 2) return stbv_error(f, VORBIS_invalid_setup); + CHECK(f); + c->lookup_type = get_bits(f, 4); + if (c->lookup_type > 2) return error(f, VORBIS_invalid_setup); if (c->lookup_type > 0) { - stbv_uint16 *mults; - c->minimum_value = stbv_float32_unpack(stbv_get_bits(f, 32)); - c->delta_value = stbv_float32_unpack(stbv_get_bits(f, 32)); - c->value_bits = stbv_get_bits(f, 4)+1; - c->sequence_p = stbv_get_bits(f,1); + uint16 *mults; + c->minimum_value = float32_unpack(get_bits(f, 32)); + c->delta_value = float32_unpack(get_bits(f, 32)); + c->value_bits = get_bits(f, 4)+1; + c->sequence_p = get_bits(f,1); if (c->lookup_type == 1) { - c->lookup_values = stbv_lookup1_values(c->entries, c->dimensions); + int values = lookup1_values(c->entries, c->dimensions); + if (values < 0) return error(f, VORBIS_invalid_setup); + c->lookup_values = (uint32) values; } else { c->lookup_values = c->entries * c->dimensions; } - if (c->lookup_values == 0) return stbv_error(f, VORBIS_invalid_setup); - mults = (stbv_uint16 *) stbv_setup_temp_malloc(f, sizeof(mults[0]) * c->lookup_values); - if (mults == NULL) return stbv_error(f, VORBIS_outofmem); + if (c->lookup_values == 0) return error(f, VORBIS_invalid_setup); + mults = (uint16 *) setup_temp_malloc(f, sizeof(mults[0]) * c->lookup_values); + if (mults == NULL) return error(f, VORBIS_outofmem); for (j=0; j < (int) c->lookup_values; ++j) { - int q = stbv_get_bits(f, c->value_bits); - if (q == STBV_EOP) { stbv_setup_temp_free(f,mults,sizeof(mults[0])*c->lookup_values); return stbv_error(f, VORBIS_invalid_setup); } + int q = get_bits(f, c->value_bits); + if (q == EOP) { setup_temp_free(f,mults,sizeof(mults[0])*c->lookup_values); return error(f, VORBIS_invalid_setup); } mults[j] = q; } @@ -3812,26 +3874,25 @@ static int stbv_start_decoder(stbv_vorb *f) float last=0; // pre-expand the lookup1-style multiplicands, to avoid a divide in the inner loop if (sparse) { - if (c->sorted_entries == 0) goto stbv_skip; - c->multiplicands = (stbv_codetype *) stbv_setup_malloc(f, sizeof(c->multiplicands[0]) * c->sorted_entries * c->dimensions); + if (c->sorted_entries == 0) goto skip; + c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->sorted_entries * c->dimensions); } else - c->multiplicands = (stbv_codetype *) stbv_setup_malloc(f, sizeof(c->multiplicands[0]) * c->entries * c->dimensions); - if (c->multiplicands == NULL) { stbv_setup_temp_free(f,mults,sizeof(mults[0])*c->lookup_values); return stbv_error(f, VORBIS_outofmem); } + c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->entries * c->dimensions); + if (c->multiplicands == NULL) { setup_temp_free(f,mults,sizeof(mults[0])*c->lookup_values); return error(f, VORBIS_outofmem); } len = sparse ? c->sorted_entries : c->entries; for (j=0; j < len; ++j) { unsigned int z = sparse ? c->sorted_values[j] : j; unsigned int div=1; for (k=0; k < c->dimensions; ++k) { int off = (z / div) % c->lookup_values; - float val = mults[off]; - val = mults[off]*c->delta_value + c->minimum_value + last; + float val = mults[off]*c->delta_value + c->minimum_value + last; c->multiplicands[j*c->dimensions + k] = val; if (c->sequence_p) last = val; if (k+1 < c->dimensions) { if (div > UINT_MAX / (unsigned int) c->lookup_values) { - stbv_setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values); - return stbv_error(f, VORBIS_invalid_setup); + setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values); + return error(f, VORBIS_invalid_setup); } div *= c->lookup_values; } @@ -3843,9 +3904,9 @@ static int stbv_start_decoder(stbv_vorb *f) #endif { float last=0; - STBV_CHECK(f); - c->multiplicands = (stbv_codetype *) stbv_setup_malloc(f, sizeof(c->multiplicands[0]) * c->lookup_values); - if (c->multiplicands == NULL) { stbv_setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values); return stbv_error(f, VORBIS_outofmem); } + CHECK(f); + c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->lookup_values); + if (c->multiplicands == NULL) { setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values); return error(f, VORBIS_outofmem); } for (j=0; j < (int) c->lookup_values; ++j) { float val = mults[j] * c->delta_value + c->minimum_value + last; c->multiplicands[j] = val; @@ -3854,72 +3915,72 @@ static int stbv_start_decoder(stbv_vorb *f) } } #ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK - stbv_skip:; + skip:; #endif - stbv_setup_temp_free(f, mults, sizeof(mults[0])*c->lookup_values); + setup_temp_free(f, mults, sizeof(mults[0])*c->lookup_values); - STBV_CHECK(f); + CHECK(f); } - STBV_CHECK(f); + CHECK(f); } // time domain transfers (notused) - x = stbv_get_bits(f, 6) + 1; + x = get_bits(f, 6) + 1; for (i=0; i < x; ++i) { - stbv_uint32 z = stbv_get_bits(f, 16); - if (z != 0) return stbv_error(f, VORBIS_invalid_setup); + uint32 z = get_bits(f, 16); + if (z != 0) return error(f, VORBIS_invalid_setup); } // Floors - f->floor_count = stbv_get_bits(f, 6)+1; - f->floor_config = (StbvFloor *) stbv_setup_malloc(f, f->floor_count * sizeof(*f->floor_config)); - if (f->floor_config == NULL) return stbv_error(f, VORBIS_outofmem); + f->floor_count = get_bits(f, 6)+1; + f->floor_config = (Floor *) setup_malloc(f, f->floor_count * sizeof(*f->floor_config)); + if (f->floor_config == NULL) return error(f, VORBIS_outofmem); for (i=0; i < f->floor_count; ++i) { - f->floor_types[i] = stbv_get_bits(f, 16); - if (f->floor_types[i] > 1) return stbv_error(f, VORBIS_invalid_setup); + f->floor_types[i] = get_bits(f, 16); + if (f->floor_types[i] > 1) return error(f, VORBIS_invalid_setup); if (f->floor_types[i] == 0) { - StbvFloor0 *g = &f->floor_config[i].floor0; - g->order = stbv_get_bits(f,8); - g->rate = stbv_get_bits(f,16); - g->bark_map_size = stbv_get_bits(f,16); - g->amplitude_bits = stbv_get_bits(f,6); - g->amplitude_offset = stbv_get_bits(f,8); - g->number_of_books = stbv_get_bits(f,4) + 1; + Floor0 *g = &f->floor_config[i].floor0; + g->order = get_bits(f,8); + g->rate = get_bits(f,16); + g->bark_map_size = get_bits(f,16); + g->amplitude_bits = get_bits(f,6); + g->amplitude_offset = get_bits(f,8); + g->number_of_books = get_bits(f,4) + 1; for (j=0; j < g->number_of_books; ++j) - g->book_list[j] = stbv_get_bits(f,8); - return stbv_error(f, VORBIS_feature_not_supported); + g->book_list[j] = get_bits(f,8); + return error(f, VORBIS_feature_not_supported); } else { - stbv_floor_ordering p[31*8+2]; - StbvFloor1 *g = &f->floor_config[i].floor1; - int max_class = -1; - g->partitions = stbv_get_bits(f, 5); + stbv__floor_ordering p[31*8+2]; + Floor1 *g = &f->floor_config[i].floor1; + int max_class = -1; + g->partitions = get_bits(f, 5); for (j=0; j < g->partitions; ++j) { - g->partition_class_list[j] = stbv_get_bits(f, 4); + g->partition_class_list[j] = get_bits(f, 4); if (g->partition_class_list[j] > max_class) max_class = g->partition_class_list[j]; } for (j=0; j <= max_class; ++j) { - g->class_dimensions[j] = stbv_get_bits(f, 3)+1; - g->class_subclasses[j] = stbv_get_bits(f, 2); + g->class_dimensions[j] = get_bits(f, 3)+1; + g->class_subclasses[j] = get_bits(f, 2); if (g->class_subclasses[j]) { - g->class_masterbooks[j] = stbv_get_bits(f, 8); - if (g->class_masterbooks[j] >= f->codebook_count) return stbv_error(f, VORBIS_invalid_setup); + g->class_masterbooks[j] = get_bits(f, 8); + if (g->class_masterbooks[j] >= f->codebook_count) return error(f, VORBIS_invalid_setup); } for (k=0; k < 1 << g->class_subclasses[j]; ++k) { - g->subclass_books[j][k] = stbv_get_bits(f,8)-1; - if (g->subclass_books[j][k] >= f->codebook_count) return stbv_error(f, VORBIS_invalid_setup); + g->subclass_books[j][k] = (int16)get_bits(f,8)-1; + if (g->subclass_books[j][k] >= f->codebook_count) return error(f, VORBIS_invalid_setup); } } - g->floor1_multiplier = stbv_get_bits(f,2)+1; - g->rangebits = stbv_get_bits(f,4); + g->floor1_multiplier = get_bits(f,2)+1; + g->rangebits = get_bits(f,4); g->Xlist[0] = 0; g->Xlist[1] = 1 << g->rangebits; g->values = 2; for (j=0; j < g->partitions; ++j) { int c = g->partition_class_list[j]; for (k=0; k < g->class_dimensions[c]; ++k) { - g->Xlist[g->values] = stbv_get_bits(f, g->rangebits); + g->Xlist[g->values] = get_bits(f, g->rangebits); ++g->values; } } @@ -3928,15 +3989,18 @@ static int stbv_start_decoder(stbv_vorb *f) p[j].x = g->Xlist[j]; p[j].id = j; } - qsort(p, g->values, sizeof(p[0]), stbv_point_compare); + qsort(p, g->values, sizeof(p[0]), point_compare); + for (j=0; j < g->values-1; ++j) + if (p[j].x == p[j+1].x) + return error(f, VORBIS_invalid_setup); for (j=0; j < g->values; ++j) - g->sorted_order[j] = (stbv_uint8) p[j].id; - // precompute the stbv_neighbors + g->sorted_order[j] = (uint8) p[j].id; + // precompute the neighbors for (j=2; j < g->values; ++j) { - int low,hi; - stbv_neighbors(g->Xlist, j, &low,&hi); - g->stbv_neighbors[j][0] = low; - g->stbv_neighbors[j][1] = hi; + int low = 0,hi = 0; + neighbors(g->Xlist, j, &low,&hi); + g->neighbors[j][0] = low; + g->neighbors[j][1] = hi; } if (g->values > longest_floorlist) @@ -3944,37 +4008,37 @@ static int stbv_start_decoder(stbv_vorb *f) } } - // StbvResidue - f->residue_count = stbv_get_bits(f, 6)+1; - f->residue_config = (StbvResidue *) stbv_setup_malloc(f, f->residue_count * sizeof(f->residue_config[0])); - if (f->residue_config == NULL) return stbv_error(f, VORBIS_outofmem); + // Residue + f->residue_count = get_bits(f, 6)+1; + f->residue_config = (Residue *) setup_malloc(f, f->residue_count * sizeof(f->residue_config[0])); + if (f->residue_config == NULL) return error(f, VORBIS_outofmem); memset(f->residue_config, 0, f->residue_count * sizeof(f->residue_config[0])); for (i=0; i < f->residue_count; ++i) { - stbv_uint8 residue_cascade[64]; - StbvResidue *r = f->residue_config+i; - f->residue_types[i] = stbv_get_bits(f, 16); - if (f->residue_types[i] > 2) return stbv_error(f, VORBIS_invalid_setup); - r->begin = stbv_get_bits(f, 24); - r->end = stbv_get_bits(f, 24); - if (r->end < r->begin) return stbv_error(f, VORBIS_invalid_setup); - r->part_size = stbv_get_bits(f,24)+1; - r->classifications = stbv_get_bits(f,6)+1; - r->classbook = stbv_get_bits(f,8); - if (r->classbook >= f->codebook_count) return stbv_error(f, VORBIS_invalid_setup); + uint8 residue_cascade[64]; + Residue *r = f->residue_config+i; + f->residue_types[i] = get_bits(f, 16); + if (f->residue_types[i] > 2) return error(f, VORBIS_invalid_setup); + r->begin = get_bits(f, 24); + r->end = get_bits(f, 24); + if (r->end < r->begin) return error(f, VORBIS_invalid_setup); + r->part_size = get_bits(f,24)+1; + r->classifications = get_bits(f,6)+1; + r->classbook = get_bits(f,8); + if (r->classbook >= f->codebook_count) return error(f, VORBIS_invalid_setup); for (j=0; j < r->classifications; ++j) { - stbv_uint8 high_bits=0; - stbv_uint8 low_bits=stbv_get_bits(f,3); - if (stbv_get_bits(f,1)) - high_bits = stbv_get_bits(f,5); + uint8 high_bits=0; + uint8 low_bits=get_bits(f,3); + if (get_bits(f,1)) + high_bits = get_bits(f,5); residue_cascade[j] = high_bits*8 + low_bits; } - r->residue_books = (short (*)[8]) stbv_setup_malloc(f, sizeof(r->residue_books[0]) * r->classifications); - if (r->residue_books == NULL) return stbv_error(f, VORBIS_outofmem); + r->residue_books = (short (*)[8]) setup_malloc(f, sizeof(r->residue_books[0]) * r->classifications); + if (r->residue_books == NULL) return error(f, VORBIS_outofmem); for (j=0; j < r->classifications; ++j) { for (k=0; k < 8; ++k) { if (residue_cascade[j] & (1 << k)) { - r->residue_books[j][k] = stbv_get_bits(f, 8); - if (r->residue_books[j][k] >= f->codebook_count) return stbv_error(f, VORBIS_invalid_setup); + r->residue_books[j][k] = get_bits(f, 8); + if (r->residue_books[j][k] >= f->codebook_count) return error(f, VORBIS_invalid_setup); } else { r->residue_books[j][k] = -1; } @@ -3982,14 +4046,14 @@ static int stbv_start_decoder(stbv_vorb *f) } // precompute the classifications[] array to avoid inner-loop mod/divide // call it 'classdata' since we already have r->classifications - r->classdata = (stbv_uint8 **) stbv_setup_malloc(f, sizeof(*r->classdata) * f->codebooks[r->classbook].entries); - if (!r->classdata) return stbv_error(f, VORBIS_outofmem); + r->classdata = (uint8 **) setup_malloc(f, sizeof(*r->classdata) * f->codebooks[r->classbook].entries); + if (!r->classdata) return error(f, VORBIS_outofmem); memset(r->classdata, 0, sizeof(*r->classdata) * f->codebooks[r->classbook].entries); for (j=0; j < f->codebooks[r->classbook].entries; ++j) { int classwords = f->codebooks[r->classbook].dimensions; int temp = j; - r->classdata[j] = (stbv_uint8 *) stbv_setup_malloc(f, sizeof(r->classdata[j][0]) * classwords); - if (r->classdata[j] == NULL) return stbv_error(f, VORBIS_outofmem); + r->classdata[j] = (uint8 *) setup_malloc(f, sizeof(r->classdata[j][0]) * classwords); + if (r->classdata[j] == NULL) return error(f, VORBIS_outofmem); for (k=classwords-1; k >= 0; --k) { r->classdata[j][k] = temp % r->classifications; temp /= r->classifications; @@ -3997,40 +4061,41 @@ static int stbv_start_decoder(stbv_vorb *f) } } - f->mapping_count = stbv_get_bits(f,6)+1; - f->mapping = (StbvMapping *) stbv_setup_malloc(f, f->mapping_count * sizeof(*f->mapping)); - if (f->mapping == NULL) return stbv_error(f, VORBIS_outofmem); + f->mapping_count = get_bits(f,6)+1; + f->mapping = (Mapping *) setup_malloc(f, f->mapping_count * sizeof(*f->mapping)); + if (f->mapping == NULL) return error(f, VORBIS_outofmem); memset(f->mapping, 0, f->mapping_count * sizeof(*f->mapping)); for (i=0; i < f->mapping_count; ++i) { - StbvMapping *m = f->mapping + i; - int mapping_type = stbv_get_bits(f,16); - if (mapping_type != 0) return stbv_error(f, VORBIS_invalid_setup); - m->chan = (StbvMappingChannel *) stbv_setup_malloc(f, f->channels * sizeof(*m->chan)); - if (m->chan == NULL) return stbv_error(f, VORBIS_outofmem); - if (stbv_get_bits(f,1)) - m->submaps = stbv_get_bits(f,4)+1; + Mapping *m = f->mapping + i; + int mapping_type = get_bits(f,16); + if (mapping_type != 0) return error(f, VORBIS_invalid_setup); + m->chan = (MappingChannel *) setup_malloc(f, f->channels * sizeof(*m->chan)); + if (m->chan == NULL) return error(f, VORBIS_outofmem); + if (get_bits(f,1)) + m->submaps = get_bits(f,4)+1; else m->submaps = 1; if (m->submaps > max_submaps) max_submaps = m->submaps; - if (stbv_get_bits(f,1)) { - m->coupling_steps = stbv_get_bits(f,8)+1; + if (get_bits(f,1)) { + m->coupling_steps = get_bits(f,8)+1; + if (m->coupling_steps > f->channels) return error(f, VORBIS_invalid_setup); for (k=0; k < m->coupling_steps; ++k) { - m->chan[k].magnitude = stbv_get_bits(f, stbv_ilog(f->channels-1)); - m->chan[k].angle = stbv_get_bits(f, stbv_ilog(f->channels-1)); - if (m->chan[k].magnitude >= f->channels) return stbv_error(f, VORBIS_invalid_setup); - if (m->chan[k].angle >= f->channels) return stbv_error(f, VORBIS_invalid_setup); - if (m->chan[k].magnitude == m->chan[k].angle) return stbv_error(f, VORBIS_invalid_setup); + m->chan[k].magnitude = get_bits(f, ilog(f->channels-1)); + m->chan[k].angle = get_bits(f, ilog(f->channels-1)); + if (m->chan[k].magnitude >= f->channels) return error(f, VORBIS_invalid_setup); + if (m->chan[k].angle >= f->channels) return error(f, VORBIS_invalid_setup); + if (m->chan[k].magnitude == m->chan[k].angle) return error(f, VORBIS_invalid_setup); } } else m->coupling_steps = 0; // reserved field - if (stbv_get_bits(f,2)) return stbv_error(f, VORBIS_invalid_setup); + if (get_bits(f,2)) return error(f, VORBIS_invalid_setup); if (m->submaps > 1) { for (j=0; j < f->channels; ++j) { - m->chan[j].mux = stbv_get_bits(f, 4); - if (m->chan[j].mux >= m->submaps) return stbv_error(f, VORBIS_invalid_setup); + m->chan[j].mux = get_bits(f, 4); + if (m->chan[j].mux >= m->submaps) return error(f, VORBIS_invalid_setup); } } else // @SPECIFICATION: this case is missing from the spec @@ -4038,64 +4103,64 @@ static int stbv_start_decoder(stbv_vorb *f) m->chan[j].mux = 0; for (j=0; j < m->submaps; ++j) { - stbv_get_bits(f,8); // discard - m->submap_floor[j] = stbv_get_bits(f,8); - m->submap_residue[j] = stbv_get_bits(f,8); - if (m->submap_floor[j] >= f->floor_count) return stbv_error(f, VORBIS_invalid_setup); - if (m->submap_residue[j] >= f->residue_count) return stbv_error(f, VORBIS_invalid_setup); + get_bits(f,8); // discard + m->submap_floor[j] = get_bits(f,8); + m->submap_residue[j] = get_bits(f,8); + if (m->submap_floor[j] >= f->floor_count) return error(f, VORBIS_invalid_setup); + if (m->submap_residue[j] >= f->residue_count) return error(f, VORBIS_invalid_setup); } } // Modes - f->mode_count = stbv_get_bits(f, 6)+1; + f->mode_count = get_bits(f, 6)+1; for (i=0; i < f->mode_count; ++i) { - StbvMode *m = f->mode_config+i; - m->blockflag = stbv_get_bits(f,1); - m->windowtype = stbv_get_bits(f,16); - m->transformtype = stbv_get_bits(f,16); - m->mapping = stbv_get_bits(f,8); - if (m->windowtype != 0) return stbv_error(f, VORBIS_invalid_setup); - if (m->transformtype != 0) return stbv_error(f, VORBIS_invalid_setup); - if (m->mapping >= f->mapping_count) return stbv_error(f, VORBIS_invalid_setup); + Mode *m = f->mode_config+i; + m->blockflag = get_bits(f,1); + m->windowtype = get_bits(f,16); + m->transformtype = get_bits(f,16); + m->mapping = get_bits(f,8); + if (m->windowtype != 0) return error(f, VORBIS_invalid_setup); + if (m->transformtype != 0) return error(f, VORBIS_invalid_setup); + if (m->mapping >= f->mapping_count) return error(f, VORBIS_invalid_setup); } - stbv_flush_packet(f); + flush_packet(f); f->previous_length = 0; for (i=0; i < f->channels; ++i) { - f->channel_buffers[i] = (float *) stbv_setup_malloc(f, sizeof(float) * f->blocksize_1); - f->previous_window[i] = (float *) stbv_setup_malloc(f, sizeof(float) * f->blocksize_1/2); - f->finalY[i] = (stbv_int16 *) stbv_setup_malloc(f, sizeof(stbv_int16) * longest_floorlist); - if (f->channel_buffers[i] == NULL || f->previous_window[i] == NULL || f->finalY[i] == NULL) return stbv_error(f, VORBIS_outofmem); + f->channel_buffers[i] = (float *) setup_malloc(f, sizeof(float) * f->blocksize_1); + f->previous_window[i] = (float *) setup_malloc(f, sizeof(float) * f->blocksize_1/2); + f->finalY[i] = (int16 *) setup_malloc(f, sizeof(int16) * longest_floorlist); + if (f->channel_buffers[i] == NULL || f->previous_window[i] == NULL || f->finalY[i] == NULL) return error(f, VORBIS_outofmem); memset(f->channel_buffers[i], 0, sizeof(float) * f->blocksize_1); #ifdef STB_VORBIS_NO_DEFER_FLOOR - f->floor_buffers[i] = (float *) stbv_setup_malloc(f, sizeof(float) * f->blocksize_1/2); - if (f->floor_buffers[i] == NULL) return stbv_error(f, VORBIS_outofmem); + f->floor_buffers[i] = (float *) setup_malloc(f, sizeof(float) * f->blocksize_1/2); + if (f->floor_buffers[i] == NULL) return error(f, VORBIS_outofmem); #endif } - if (!stbv_init_blocksize(f, 0, f->blocksize_0)) return FALSE; - if (!stbv_init_blocksize(f, 1, f->blocksize_1)) return FALSE; + if (!init_blocksize(f, 0, f->blocksize_0)) return FALSE; + if (!init_blocksize(f, 1, f->blocksize_1)) return FALSE; f->blocksize[0] = f->blocksize_0; f->blocksize[1] = f->blocksize_1; #ifdef STB_VORBIS_DIVIDE_TABLE - if (stbv_integer_divide_table[1][1]==0) - for (i=0; i < STBV_DIVTAB_NUMER; ++i) - for (j=1; j < STBV_DIVTAB_DENOM; ++j) - stbv_integer_divide_table[i][j] = i / j; + if (integer_divide_table[1][1]==0) + for (i=0; i < DIVTAB_NUMER; ++i) + for (j=1; j < DIVTAB_DENOM; ++j) + integer_divide_table[i][j] = i / j; #endif // compute how much temporary memory is needed // 1. { - stbv_uint32 imdct_mem = (f->blocksize_1 * sizeof(float) >> 1); - stbv_uint32 classify_mem; + uint32 imdct_mem = (f->blocksize_1 * sizeof(float) >> 1); + uint32 classify_mem; int i,max_part_read=0; for (i=0; i < f->residue_count; ++i) { - StbvResidue *r = f->residue_config + i; + Residue *r = f->residue_config + i; unsigned int actual_size = f->blocksize_1 / 2; unsigned int limit_r_begin = r->begin < actual_size ? r->begin : actual_size; unsigned int limit_r_end = r->end < actual_size ? r->end : actual_size; @@ -4105,7 +4170,7 @@ static int stbv_start_decoder(stbv_vorb *f) max_part_read = part_read; } #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - classify_mem = f->channels * (sizeof(void*) + max_part_read * sizeof(stbv_uint8 *)); + classify_mem = f->channels * (sizeof(void*) + max_part_read * sizeof(uint8 *)); #else classify_mem = f->channels * (sizeof(void*) + max_part_read * sizeof(int *)); #endif @@ -4117,89 +4182,105 @@ static int stbv_start_decoder(stbv_vorb *f) f->temp_memory_required = imdct_mem; } - f->first_decode = TRUE; if (f->alloc.alloc_buffer) { assert(f->temp_offset == f->alloc.alloc_buffer_length_in_bytes); // check if there's enough temp memory so we don't error later if (f->setup_offset + sizeof(*f) + f->temp_memory_required > (unsigned) f->temp_offset) - return stbv_error(f, VORBIS_outofmem); + return error(f, VORBIS_outofmem); } - f->first_audio_page_offset = stb_vorbis_get_file_offset(f); + // @TODO: stb_vorbis_seek_start expects first_audio_page_offset to point to a page + // without PAGEFLAG_continued_packet, so this either points to the first page, or + // the page after the end of the headers. It might be cleaner to point to a page + // in the middle of the headers, when that's the page where the first audio packet + // starts, but we'd have to also correctly skip the end of any continued packet in + // stb_vorbis_seek_start. + if (f->next_seg == -1) { + f->first_audio_page_offset = stb_vorbis_get_file_offset(f); + } else { + f->first_audio_page_offset = 0; + } return TRUE; } -static void stbv_vorbis_deinit(stb_vorbis *p) +static void vorbis_deinit(stb_vorbis *p) { int i,j; + + setup_free(p, p->vendor); + for (i=0; i < p->comment_list_length; ++i) { + setup_free(p, p->comment_list[i]); + } + setup_free(p, p->comment_list); + if (p->residue_config) { for (i=0; i < p->residue_count; ++i) { - StbvResidue *r = p->residue_config+i; + Residue *r = p->residue_config+i; if (r->classdata) { for (j=0; j < p->codebooks[r->classbook].entries; ++j) - stbv_setup_free(p, r->classdata[j]); - stbv_setup_free(p, r->classdata); + setup_free(p, r->classdata[j]); + setup_free(p, r->classdata); } - stbv_setup_free(p, r->residue_books); + setup_free(p, r->residue_books); } } if (p->codebooks) { - STBV_CHECK(p); + CHECK(p); for (i=0; i < p->codebook_count; ++i) { - StbvCodebook *c = p->codebooks + i; - stbv_setup_free(p, c->codeword_lengths); - stbv_setup_free(p, c->multiplicands); - stbv_setup_free(p, c->codewords); - stbv_setup_free(p, c->sorted_codewords); + Codebook *c = p->codebooks + i; + setup_free(p, c->codeword_lengths); + setup_free(p, c->multiplicands); + setup_free(p, c->codewords); + setup_free(p, c->sorted_codewords); // c->sorted_values[-1] is the first entry in the array - stbv_setup_free(p, c->sorted_values ? c->sorted_values-1 : NULL); + setup_free(p, c->sorted_values ? c->sorted_values-1 : NULL); } - stbv_setup_free(p, p->codebooks); + setup_free(p, p->codebooks); } - stbv_setup_free(p, p->floor_config); - stbv_setup_free(p, p->residue_config); + setup_free(p, p->floor_config); + setup_free(p, p->residue_config); if (p->mapping) { for (i=0; i < p->mapping_count; ++i) - stbv_setup_free(p, p->mapping[i].chan); - stbv_setup_free(p, p->mapping); + setup_free(p, p->mapping[i].chan); + setup_free(p, p->mapping); } - STBV_CHECK(p); + CHECK(p); for (i=0; i < p->channels && i < STB_VORBIS_MAX_CHANNELS; ++i) { - stbv_setup_free(p, p->channel_buffers[i]); - stbv_setup_free(p, p->previous_window[i]); + setup_free(p, p->channel_buffers[i]); + setup_free(p, p->previous_window[i]); #ifdef STB_VORBIS_NO_DEFER_FLOOR - stbv_setup_free(p, p->floor_buffers[i]); + setup_free(p, p->floor_buffers[i]); #endif - stbv_setup_free(p, p->finalY[i]); + setup_free(p, p->finalY[i]); } for (i=0; i < 2; ++i) { - stbv_setup_free(p, p->A[i]); - stbv_setup_free(p, p->B[i]); - stbv_setup_free(p, p->C[i]); - stbv_setup_free(p, p->window[i]); - stbv_setup_free(p, p->stbv_bit_reverse[i]); + setup_free(p, p->A[i]); + setup_free(p, p->B[i]); + setup_free(p, p->C[i]); + setup_free(p, p->window[i]); + setup_free(p, p->bit_reverse[i]); } #ifndef STB_VORBIS_NO_STDIO if (p->close_on_free) fclose(p->f); #endif } -STBVDEF void stb_vorbis_close(stb_vorbis *p) +void stb_vorbis_close(stb_vorbis *p) { if (p == NULL) return; - stbv_vorbis_deinit(p); - stbv_setup_free(p,p); + vorbis_deinit(p); + setup_free(p,p); } -static void stbv_vorbis_init(stb_vorbis *p, const stb_vorbis_alloc *z) +static void vorbis_init(stb_vorbis *p, const stb_vorbis_alloc *z) { memset(p, 0, sizeof(*p)); // NULL out all malloc'd pointers to start if (z) { p->alloc = *z; - p->alloc.alloc_buffer_length_in_bytes = (p->alloc.alloc_buffer_length_in_bytes+3) & ~3; + p->alloc.alloc_buffer_length_in_bytes &= ~7; p->temp_offset = p->alloc.alloc_buffer_length_in_bytes; } p->eof = 0; @@ -4213,7 +4294,7 @@ static void stbv_vorbis_init(stb_vorbis *p, const stb_vorbis_alloc *z) #endif } -STBVDEF int stb_vorbis_get_sample_offset(stb_vorbis *f) +int stb_vorbis_get_sample_offset(stb_vorbis *f) { if (f->current_loc_valid) return f->current_loc; @@ -4221,7 +4302,7 @@ STBVDEF int stb_vorbis_get_sample_offset(stb_vorbis *f) return -1; } -STBVDEF stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f) +stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f) { stb_vorbis_info d; d.channels = f->channels; @@ -4233,22 +4314,31 @@ STBVDEF stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f) return d; } -STBVDEF int stb_vorbis_get_error(stb_vorbis *f) +stb_vorbis_comment stb_vorbis_get_comment(stb_vorbis *f) +{ + stb_vorbis_comment d; + d.vendor = f->vendor; + d.comment_list_length = f->comment_list_length; + d.comment_list = f->comment_list; + return d; +} + +int stb_vorbis_get_error(stb_vorbis *f) { int e = f->error; f->error = VORBIS__no_error; return e; } -static stb_vorbis * stbv_vorbis_alloc(stb_vorbis *f) +static stb_vorbis * vorbis_alloc(stb_vorbis *f) { - stb_vorbis *p = (stb_vorbis *) stbv_setup_malloc(f, sizeof(*p)); + stb_vorbis *p = (stb_vorbis *) setup_malloc(f, sizeof(*p)); return p; } #ifndef STB_VORBIS_NO_PUSHDATA_API -STBVDEF void stb_vorbis_flush_pushdata(stb_vorbis *f) +void stb_vorbis_flush_pushdata(stb_vorbis *f) { f->previous_length = 0; f->page_crc_tests = 0; @@ -4260,7 +4350,7 @@ STBVDEF void stb_vorbis_flush_pushdata(stb_vorbis *f) f->channel_buffer_end = 0; } -static int stbv_vorbis_search_for_page_pushdata(stbv_vorb *f, stbv_uint8 *data, int data_len) +static int vorbis_search_for_page_pushdata(vorb *f, uint8 *data, int data_len) { int i,n; for (i=0; i < f->page_crc_tests; ++i) @@ -4274,9 +4364,9 @@ static int stbv_vorbis_search_for_page_pushdata(stbv_vorb *f, stbv_uint8 *data, // one that straddles a boundary for (i=0; i < data_len; ++i) { if (data[i] == 0x4f) { - if (0==memcmp(data+i, stbv_ogg_page_header, 4)) { + if (0==memcmp(data+i, ogg_page_header, 4)) { int j,len; - stbv_uint32 crc; + uint32 crc; // make sure we have the whole page header if (i+26 >= data_len || i+27+data[i+26] >= data_len) { // only read up to this page start, so hopefully we'll @@ -4291,10 +4381,10 @@ static int stbv_vorbis_search_for_page_pushdata(stbv_vorb *f, stbv_uint8 *data, // scan everything up to the embedded crc (which we must 0) crc = 0; for (j=0; j < 22; ++j) - crc = stbv_crc32_update(crc, data[i+j]); + crc = crc32_update(crc, data[i+j]); // now process 4 0-bytes for ( ; j < 26; ++j) - crc = stbv_crc32_update(crc, 0); + crc = crc32_update(crc, 0); // len is the total number of bytes we need to scan n = f->page_crc_tests++; f->scan[n].bytes_left = len-j; @@ -4316,7 +4406,7 @@ static int stbv_vorbis_search_for_page_pushdata(stbv_vorb *f, stbv_uint8 *data, } for (i=0; i < f->page_crc_tests;) { - stbv_uint32 crc; + uint32 crc; int j; int n = f->scan[i].bytes_done; int m = f->scan[i].bytes_left; @@ -4324,7 +4414,7 @@ static int stbv_vorbis_search_for_page_pushdata(stbv_vorb *f, stbv_uint8 *data, // m is the bytes to scan in the current chunk crc = f->scan[i].crc_so_far; for (j=0; j < m; ++j) - crc = stbv_crc32_update(crc, data[n+j]); + crc = crc32_update(crc, data[n+j]); f->scan[i].bytes_left -= m; f->scan[i].crc_so_far = crc; if (f->scan[i].bytes_left == 0) { @@ -4351,9 +4441,9 @@ static int stbv_vorbis_search_for_page_pushdata(stbv_vorb *f, stbv_uint8 *data, } // return value: number of bytes we used -STBVDEF int stb_vorbis_decode_frame_pushdata( +int stb_vorbis_decode_frame_pushdata( stb_vorbis *f, // the file we're decoding - const stbv_uint8 *data, int data_len, // the memory available for decoding + const uint8 *data, int data_len, // the memory available for decoding int *channels, // place to write number of float * buffers float ***output, // place to write float ** array of float * buffers int *samples // place to write number of output samples @@ -4362,30 +4452,30 @@ STBVDEF int stb_vorbis_decode_frame_pushdata( int i; int len,right,left; - if (!STBV_IS_PUSH_MODE(f)) return stbv_error(f, VORBIS_invalid_api_mixing); + if (!IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing); if (f->page_crc_tests >= 0) { *samples = 0; - return stbv_vorbis_search_for_page_pushdata(f, (stbv_uint8 *) data, data_len); + return vorbis_search_for_page_pushdata(f, (uint8 *) data, data_len); } - f->stream = (stbv_uint8 *) data; - f->stream_end = (stbv_uint8 *) data + data_len; + f->stream = (uint8 *) data; + f->stream_end = (uint8 *) data + data_len; f->error = VORBIS__no_error; // check that we have the entire packet in memory - if (!stbv_is_whole_packet_present(f, FALSE)) { + if (!is_whole_packet_present(f)) { *samples = 0; return 0; } - if (!stbv_vorbis_decode_packet(f, &len, &left, &right)) { + if (!vorbis_decode_packet(f, &len, &left, &right)) { // save the actual error we encountered enum STBVorbisError error = f->error; if (error == VORBIS_bad_packet_type) { // flush and resynch f->error = VORBIS__no_error; - while (stbv_get8_packet(f) != STBV_EOP) + while (get8_packet(f) != EOP) if (f->eof) break; *samples = 0; return (int) (f->stream - data); @@ -4395,7 +4485,7 @@ STBVDEF int stb_vorbis_decode_frame_pushdata( // we may be resynching, in which case it's ok to hit one // of these; just discard the packet f->error = VORBIS__no_error; - while (stbv_get8_packet(f) != STBV_EOP) + while (get8_packet(f) != EOP) if (f->eof) break; *samples = 0; return (int) (f->stream - data); @@ -4411,7 +4501,7 @@ STBVDEF int stb_vorbis_decode_frame_pushdata( } // success! - len = stbv_vorbis_finish_frame(f, len, left, right); + len = vorbis_finish_frame(f, len, left, right); for (i=0; i < f->channels; ++i) f->outputs[i] = f->channel_buffers[i] + left; @@ -4421,42 +4511,43 @@ STBVDEF int stb_vorbis_decode_frame_pushdata( return (int) (f->stream - data); } -STBVDEF stb_vorbis *stb_vorbis_open_pushdata( +stb_vorbis *stb_vorbis_open_pushdata( const unsigned char *data, int data_len, // the memory available for decoding int *data_used, // only defined if result is not NULL int *error, const stb_vorbis_alloc *alloc) { stb_vorbis *f, p; - stbv_vorbis_init(&p, alloc); - p.stream = (stbv_uint8 *) data; - p.stream_end = (stbv_uint8 *) data + data_len; + vorbis_init(&p, alloc); + p.stream = (uint8 *) data; + p.stream_end = (uint8 *) data + data_len; p.push_mode = TRUE; - if (!stbv_start_decoder(&p)) { + if (!start_decoder(&p)) { if (p.eof) *error = VORBIS_need_more_data; else *error = p.error; + vorbis_deinit(&p); return NULL; } - f = stbv_vorbis_alloc(&p); + f = vorbis_alloc(&p); if (f) { *f = p; *data_used = (int) (f->stream - data); *error = 0; return f; } else { - stbv_vorbis_deinit(&p); + vorbis_deinit(&p); return NULL; } } #endif // STB_VORBIS_NO_PUSHDATA_API -STBVDEF unsigned int stb_vorbis_get_file_offset(stb_vorbis *f) +unsigned int stb_vorbis_get_file_offset(stb_vorbis *f) { #ifndef STB_VORBIS_NO_PUSHDATA_API if (f->push_mode) return 0; #endif - if (STBV_USE_MEMORY(f)) return (unsigned int) (f->stream - f->stream_start); + if (USE_MEMORY(f)) return (unsigned int) (f->stream - f->stream_start); #ifndef STB_VORBIS_NO_STDIO return (unsigned int) (ftell(f->f) - f->f_start); #endif @@ -4467,12 +4558,12 @@ STBVDEF unsigned int stb_vorbis_get_file_offset(stb_vorbis *f) // DATA-PULLING API // -static stbv_uint32 stbv_vorbis_find_page(stb_vorbis *f, stbv_uint32 *end, stbv_uint32 *last) +static uint32 vorbis_find_page(stb_vorbis *f, uint32 *end, uint32 *last) { for(;;) { int n; if (f->eof) return 0; - n = stbv_get8(f); + n = get8(f); if (n == 0x4f) { // page header candidate unsigned int retry_loc = stb_vorbis_get_file_offset(f); int i; @@ -4481,33 +4572,33 @@ static stbv_uint32 stbv_vorbis_find_page(stb_vorbis *f, stbv_uint32 *end, stbv_u return 0; // check the rest of the header for (i=1; i < 4; ++i) - if (stbv_get8(f) != stbv_ogg_page_header[i]) + if (get8(f) != ogg_page_header[i]) break; if (f->eof) return 0; if (i == 4) { - stbv_uint8 header[27]; - stbv_uint32 i, crc, goal, len; + uint8 header[27]; + uint32 i, crc, goal, len; for (i=0; i < 4; ++i) - header[i] = stbv_ogg_page_header[i]; + header[i] = ogg_page_header[i]; for (; i < 27; ++i) - header[i] = stbv_get8(f); + header[i] = get8(f); if (f->eof) return 0; if (header[4] != 0) goto invalid; - goal = header[22] + (header[23] << 8) + (header[24]<<16) + (header[25]<<24); + goal = header[22] + (header[23] << 8) + (header[24]<<16) + ((uint32)header[25]<<24); for (i=22; i < 26; ++i) header[i] = 0; crc = 0; for (i=0; i < 27; ++i) - crc = stbv_crc32_update(crc, header[i]); + crc = crc32_update(crc, header[i]); len = 0; for (i=0; i < header[26]; ++i) { - int s = stbv_get8(f); - crc = stbv_crc32_update(crc, s); + int s = get8(f); + crc = crc32_update(crc, s); len += s; } if (len && f->eof) return 0; for (i=0; i < len; ++i) - crc = stbv_crc32_update(crc, stbv_get8(f)); + crc = crc32_update(crc, get8(f)); // finished parsing probable page if (crc == goal) { // we could now check that it's either got the last @@ -4526,19 +4617,19 @@ static stbv_uint32 stbv_vorbis_find_page(stb_vorbis *f, stbv_uint32 *end, stbv_u else *last = 0; } - stbv_set_file_offset(f, retry_loc-1); + set_file_offset(f, retry_loc-1); return 1; } } invalid: // not a valid page, so rewind and look for next one - stbv_set_file_offset(f, retry_loc); + set_file_offset(f, retry_loc); } } } -#define STBV_SAMPLE_unknown 0xffffffff +#define SAMPLE_unknown 0xffffffff // seeking is implemented with a binary search, which narrows down the range to // 64K, before using a linear search (because finding the synchronization @@ -4549,19 +4640,19 @@ static stbv_uint32 stbv_vorbis_find_page(stb_vorbis *f, stbv_uint32 *end, stbv_u // to try to bound either side of the binary search sensibly, while still // working in O(log n) time if they fail. -static int stbv_get_seek_page_info(stb_vorbis *f, StbvProbedPage *z) +static int get_seek_page_info(stb_vorbis *f, ProbedPage *z) { - stbv_uint8 header[27], lacing[255]; + uint8 header[27], lacing[255]; int i,len; // record where the page starts z->page_start = stb_vorbis_get_file_offset(f); // parse the header - stbv_getn(f, header, 27); + getn(f, header, 27); if (header[0] != 'O' || header[1] != 'g' || header[2] != 'g' || header[3] != 'S') return 0; - stbv_getn(f, lacing, header[26]); + getn(f, lacing, header[26]); // determine the length of the payload len = 0; @@ -4575,13 +4666,13 @@ static int stbv_get_seek_page_info(stb_vorbis *f, StbvProbedPage *z) z->last_decoded_sample = header[6] + (header[7] << 8) + (header[8] << 16) + (header[9] << 24); // restore file state to where we were - stbv_set_file_offset(f, z->page_start); + set_file_offset(f, z->page_start); return 1; } -// rarely used function to seek back to the preceeding page while finding the +// rarely used function to seek back to the preceding page while finding the // start of a packet -static int stbv_go_to_page_before(stb_vorbis *f, unsigned int limit_offset) +static int go_to_page_before(stb_vorbis *f, unsigned int limit_offset) { unsigned int previous_safe, end; @@ -4591,12 +4682,12 @@ static int stbv_go_to_page_before(stb_vorbis *f, unsigned int limit_offset) else previous_safe = f->first_audio_page_offset; - stbv_set_file_offset(f, previous_safe); + set_file_offset(f, previous_safe); - while (stbv_vorbis_find_page(f, &end, NULL)) { + while (vorbis_find_page(f, &end, NULL)) { if (end >= limit_offset && stb_vorbis_get_file_offset(f) < limit_offset) return 1; - stbv_set_file_offset(f, end); + set_file_offset(f, end); } return 0; @@ -4606,42 +4697,45 @@ static int stbv_go_to_page_before(stb_vorbis *f, unsigned int limit_offset) // the function succeeds, current_loc_valid will be true and current_loc will // be less than or equal to the provided sample number (the closer the // better). -static int stbv_seek_to_sample_coarse(stb_vorbis *f, stbv_uint32 sample_number) +static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number) { - StbvProbedPage left, right, mid; + ProbedPage left, right, mid; int i, start_seg_with_known_loc, end_pos, page_start; - stbv_uint32 delta, stream_length, padding; - double offset, bytes_per_sample; + uint32 delta, stream_length, padding, last_sample_limit; + double offset = 0.0, bytes_per_sample = 0.0; int probe = 0; // find the last page and validate the target sample stream_length = stb_vorbis_stream_length_in_samples(f); - if (stream_length == 0) return stbv_error(f, VORBIS_seek_without_length); - if (sample_number > stream_length) return stbv_error(f, VORBIS_seek_invalid); + if (stream_length == 0) return error(f, VORBIS_seek_without_length); + if (sample_number > stream_length) return error(f, VORBIS_seek_invalid); // this is the maximum difference between the window-center (which is the // actual granule position value), and the right-start (which the spec // indicates should be the granule position (give or take one)). padding = ((f->blocksize_1 - f->blocksize_0) >> 2); if (sample_number < padding) - sample_number = 0; + last_sample_limit = 0; else - sample_number -= padding; + last_sample_limit = sample_number - padding; left = f->p_first; while (left.last_decoded_sample == ~0U) { // (untested) the first page does not have a 'last_decoded_sample' - stbv_set_file_offset(f, left.page_end); - if (!stbv_get_seek_page_info(f, &left)) goto error; + set_file_offset(f, left.page_end); + if (!get_seek_page_info(f, &left)) goto error; } right = f->p_last; assert(right.last_decoded_sample != ~0U); // starting from the start is handled differently - if (sample_number <= left.last_decoded_sample) { - if (stb_vorbis_seek_start(f)) + if (last_sample_limit <= left.last_decoded_sample) { + if (stb_vorbis_seek_start(f)) { + if (f->current_loc > sample_number) + return error(f, VORBIS_seek_failed); return 1; + } return 0; } @@ -4651,17 +4745,17 @@ static int stbv_seek_to_sample_coarse(stb_vorbis *f, stbv_uint32 sample_number) delta = right.page_start - left.page_end; if (delta <= 65536) { // there's only 64K left to search - handle it linearly - stbv_set_file_offset(f, left.page_end); + set_file_offset(f, left.page_end); } else { if (probe < 2) { if (probe == 0) { // first probe (interpolate) double data_bytes = right.page_end - left.page_start; bytes_per_sample = data_bytes / right.last_decoded_sample; - offset = left.page_start + bytes_per_sample * (sample_number - left.last_decoded_sample); + offset = left.page_start + bytes_per_sample * (last_sample_limit - left.last_decoded_sample); } else { // second probe (try to bound the other side) - double error = ((double) sample_number - mid.last_decoded_sample) * bytes_per_sample; + double error = ((double) last_sample_limit - mid.last_decoded_sample) * bytes_per_sample; if (error >= 0 && error < 8000) error = 8000; if (error < 0 && error > -8000) error = -8000; offset += error * 2; @@ -4673,41 +4767,43 @@ static int stbv_seek_to_sample_coarse(stb_vorbis *f, stbv_uint32 sample_number) if (offset > right.page_start - 65536) offset = right.page_start - 65536; - stbv_set_file_offset(f, (unsigned int) offset); + set_file_offset(f, (unsigned int) offset); } else { // binary search for large ranges (offset by 32K to ensure // we don't hit the right page) - stbv_set_file_offset(f, left.page_end + (delta / 2) - 32768); + set_file_offset(f, left.page_end + (delta / 2) - 32768); } - if (!stbv_vorbis_find_page(f, NULL, NULL)) goto error; + if (!vorbis_find_page(f, NULL, NULL)) goto error; } for (;;) { - if (!stbv_get_seek_page_info(f, &mid)) goto error; + if (!get_seek_page_info(f, &mid)) goto error; if (mid.last_decoded_sample != ~0U) break; // (untested) no frames end on this page - stbv_set_file_offset(f, mid.page_end); + set_file_offset(f, mid.page_end); assert(mid.page_start < right.page_start); } // if we've just found the last page again then we're in a tricky file, - // and we're close enough. - if (mid.page_start == right.page_start) - break; - - if (sample_number < mid.last_decoded_sample) - right = mid; - else - left = mid; + // and we're close enough (if it wasn't an interpolation probe). + if (mid.page_start == right.page_start) { + if (probe >= 2 || delta <= 65536) + break; + } else { + if (last_sample_limit < mid.last_decoded_sample) + right = mid; + else + left = mid; + } ++probe; } // seek back to start of the last packet page_start = left.page_start; - stbv_set_file_offset(f, page_start); - if (!stbv_start_page(f)) return stbv_error(f, VORBIS_seek_failed); + set_file_offset(f, page_start); + if (!start_page(f)) return error(f, VORBIS_seek_failed); end_pos = f->end_seg_with_known_loc; assert(end_pos >= 0); @@ -4718,15 +4814,15 @@ static int stbv_seek_to_sample_coarse(stb_vorbis *f, stbv_uint32 sample_number) start_seg_with_known_loc = i; - if (start_seg_with_known_loc > 0 || !(f->page_flag & STBV_PAGEFLAG_continued_packet)) + if (start_seg_with_known_loc > 0 || !(f->page_flag & PAGEFLAG_continued_packet)) break; // (untested) the final packet begins on an earlier page - if (!stbv_go_to_page_before(f, page_start)) + if (!go_to_page_before(f, page_start)) goto error; page_start = stb_vorbis_get_file_offset(f); - if (!stbv_start_page(f)) goto error; + if (!start_page(f)) goto error; end_pos = f->segment_count - 1; } @@ -4740,38 +4836,38 @@ static int stbv_seek_to_sample_coarse(stb_vorbis *f, stbv_uint32 sample_number) f->next_seg = start_seg_with_known_loc; for (i = 0; i < start_seg_with_known_loc; i++) - stbv_skip(f, f->segments[i]); + skip(f, f->segments[i]); // start decoding (optimizable - this frame is generally discarded) - if (!stbv_vorbis_pump_first_frame(f)) + if (!vorbis_pump_first_frame(f)) return 0; if (f->current_loc > sample_number) - return stbv_error(f, VORBIS_seek_failed); + return error(f, VORBIS_seek_failed); return 1; error: // try to restore the file to a valid state stb_vorbis_seek_start(f); - return stbv_error(f, VORBIS_seek_failed); + return error(f, VORBIS_seek_failed); } -// the same as stbv_vorbis_decode_initial, but without advancing -static int stbv_peek_decode_initial(stbv_vorb *f, int *p_left_start, int *p_left_end, int *p_right_start, int *p_right_end, int *mode) +// the same as vorbis_decode_initial, but without advancing +static int peek_decode_initial(vorb *f, int *p_left_start, int *p_left_end, int *p_right_start, int *p_right_end, int *mode) { int bits_read, bytes_read; - if (!stbv_vorbis_decode_initial(f, p_left_start, p_left_end, p_right_start, p_right_end, mode)) + if (!vorbis_decode_initial(f, p_left_start, p_left_end, p_right_start, p_right_end, mode)) return 0; // either 1 or 2 bytes were read, figure out which so we can rewind - bits_read = 1 + stbv_ilog(f->mode_count-1); + bits_read = 1 + ilog(f->mode_count-1); if (f->mode_config[*mode].blockflag) bits_read += 2; bytes_read = (bits_read + 7) / 8; f->bytes_in_seg += bytes_read; f->packet_bytes -= bytes_read; - stbv_skip(f, -bytes_read); + skip(f, -bytes_read); if (f->next_seg == -1) f->next_seg = f->segment_count - 1; else @@ -4781,14 +4877,14 @@ static int stbv_peek_decode_initial(stbv_vorb *f, int *p_left_start, int *p_left return 1; } -STBVDEF int stb_vorbis_seek_frame(stb_vorbis *f, unsigned int sample_number) +int stb_vorbis_seek_frame(stb_vorbis *f, unsigned int sample_number) { - stbv_uint32 max_frame_samples; + uint32 max_frame_samples; - if (STBV_IS_PUSH_MODE(f)) return stbv_error(f, VORBIS_invalid_api_mixing); + if (IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing); // fast page-level search - if (!stbv_seek_to_sample_coarse(f, sample_number)) + if (!seek_to_sample_coarse(f, sample_number)) return 0; assert(f->current_loc_valid); @@ -4798,36 +4894,36 @@ STBVDEF int stb_vorbis_seek_frame(stb_vorbis *f, unsigned int sample_number) max_frame_samples = (f->blocksize_1*3 - f->blocksize_0) >> 2; while (f->current_loc < sample_number) { int left_start, left_end, right_start, right_end, mode, frame_samples; - if (!stbv_peek_decode_initial(f, &left_start, &left_end, &right_start, &right_end, &mode)) - return stbv_error(f, VORBIS_seek_failed); + if (!peek_decode_initial(f, &left_start, &left_end, &right_start, &right_end, &mode)) + return error(f, VORBIS_seek_failed); // calculate the number of samples returned by the next frame frame_samples = right_start - left_start; if (f->current_loc + frame_samples > sample_number) { return 1; // the next frame will contain the sample } else if (f->current_loc + frame_samples + max_frame_samples > sample_number) { // there's a chance the frame after this could contain the sample - stbv_vorbis_pump_first_frame(f); + vorbis_pump_first_frame(f); } else { // this frame is too early to be relevant f->current_loc += frame_samples; f->previous_length = 0; - stbv_maybe_start_packet(f); - stbv_flush_packet(f); + maybe_start_packet(f); + flush_packet(f); } } - // the next frame will start with the sample - assert(f->current_loc == sample_number); + // the next frame should start with the sample + if (f->current_loc != sample_number) return error(f, VORBIS_seek_failed); return 1; } -STBVDEF int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number) +int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number) { if (!stb_vorbis_seek_frame(f, sample_number)) return 0; if (sample_number != f->current_loc) { int n; - stbv_uint32 frame_start = f->current_loc; + uint32 frame_start = f->current_loc; stb_vorbis_get_frame_float(f, &n, NULL); assert(sample_number > frame_start); assert(f->channel_buffer_start + (int) (sample_number-frame_start) <= f->channel_buffer_end); @@ -4837,25 +4933,25 @@ STBVDEF int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number) return 1; } -STBVDEF int stb_vorbis_seek_start(stb_vorbis *f) +int stb_vorbis_seek_start(stb_vorbis *f) { - if (STBV_IS_PUSH_MODE(f)) { return stbv_error(f, VORBIS_invalid_api_mixing); } - stbv_set_file_offset(f, f->first_audio_page_offset); + if (IS_PUSH_MODE(f)) { return error(f, VORBIS_invalid_api_mixing); } + set_file_offset(f, f->first_audio_page_offset); f->previous_length = 0; f->first_decode = TRUE; f->next_seg = -1; - return stbv_vorbis_pump_first_frame(f); + return vorbis_pump_first_frame(f); } -STBVDEF unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f) +unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f) { unsigned int restore_offset, previous_safe; unsigned int end, last_page_loc; - if (STBV_IS_PUSH_MODE(f)) return stbv_error(f, VORBIS_invalid_api_mixing); + if (IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing); if (!f->total_samples) { unsigned int last; - stbv_uint32 lo,hi; + uint32 lo,hi; char header[6]; // first, store the current decode position so we can restore it @@ -4868,11 +4964,11 @@ STBVDEF unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f) else previous_safe = f->first_audio_page_offset; - stbv_set_file_offset(f, previous_safe); + set_file_offset(f, previous_safe); // previous_safe is now our candidate 'earliest known place that seeking // to will lead to the final page' - if (!stbv_vorbis_find_page(f, &end, &last)) { + if (!vorbis_find_page(f, &end, &last)) { // if we can't find a page, we're hosed! f->error = VORBIS_cant_find_last_page; f->total_samples = 0xffffffff; @@ -4886,26 +4982,26 @@ STBVDEF unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f) // this allows us to stop short of a 'file_section' end without // explicitly checking the length of the section while (!last) { - stbv_set_file_offset(f, end); - if (!stbv_vorbis_find_page(f, &end, &last)) { + set_file_offset(f, end); + if (!vorbis_find_page(f, &end, &last)) { // the last page we found didn't have the 'last page' flag // set. whoops! break; } - previous_safe = last_page_loc+1; + //previous_safe = last_page_loc+1; // NOTE: not used after this point, but note for debugging last_page_loc = stb_vorbis_get_file_offset(f); } - stbv_set_file_offset(f, last_page_loc); + set_file_offset(f, last_page_loc); // parse the header - stbv_getn(f, (unsigned char *)header, 6); + getn(f, (unsigned char *)header, 6); // extract the absolute granule position - lo = stbv_get32(f); - hi = stbv_get32(f); + lo = get32(f); + hi = get32(f); if (lo == 0xffffffff && hi == 0xffffffff) { f->error = VORBIS_cant_find_last_page; - f->total_samples = STBV_SAMPLE_unknown; + f->total_samples = SAMPLE_unknown; goto done; } if (hi) @@ -4917,29 +5013,29 @@ STBVDEF unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f) f->p_last.last_decoded_sample = lo; done: - stbv_set_file_offset(f, restore_offset); + set_file_offset(f, restore_offset); } - return f->total_samples == STBV_SAMPLE_unknown ? 0 : f->total_samples; + return f->total_samples == SAMPLE_unknown ? 0 : f->total_samples; } -STBVDEF float stb_vorbis_stream_length_in_seconds(stb_vorbis *f) +float stb_vorbis_stream_length_in_seconds(stb_vorbis *f) { return stb_vorbis_stream_length_in_samples(f) / (float) f->sample_rate; } -STBVDEF int stb_vorbis_get_frame_float(stb_vorbis *f, int *channels, float ***output) +int stb_vorbis_get_frame_float(stb_vorbis *f, int *channels, float ***output) { int len, right,left,i; - if (STBV_IS_PUSH_MODE(f)) return stbv_error(f, VORBIS_invalid_api_mixing); + if (IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing); - if (!stbv_vorbis_decode_packet(f, &len, &left, &right)) { + if (!vorbis_decode_packet(f, &len, &left, &right)) { f->channel_buffer_start = f->channel_buffer_end = 0; return 0; } - len = stbv_vorbis_finish_frame(f, len, left, right); + len = vorbis_finish_frame(f, len, left, right); for (i=0; i < f->channels; ++i) f->outputs[i] = f->channel_buffers[i] + left; @@ -4953,28 +5049,28 @@ STBVDEF int stb_vorbis_get_frame_float(stb_vorbis *f, int *channels, float ***ou #ifndef STB_VORBIS_NO_STDIO -STBVDEF stb_vorbis * stb_vorbis_open_file_section(FILE *file, int close_on_free, int *error, const stb_vorbis_alloc *alloc, unsigned int length) +stb_vorbis * stb_vorbis_open_file_section(FILE *file, int close_on_free, int *error, const stb_vorbis_alloc *alloc, unsigned int length) { stb_vorbis *f, p; - stbv_vorbis_init(&p, alloc); + vorbis_init(&p, alloc); p.f = file; - p.f_start = (stbv_uint32) ftell(file); + p.f_start = (uint32) ftell(file); p.stream_len = length; p.close_on_free = close_on_free; - if (stbv_start_decoder(&p)) { - f = stbv_vorbis_alloc(&p); + if (start_decoder(&p)) { + f = vorbis_alloc(&p); if (f) { *f = p; - stbv_vorbis_pump_first_frame(f); + vorbis_pump_first_frame(f); return f; } } if (error) *error = p.error; - stbv_vorbis_deinit(&p); + vorbis_deinit(&p); return NULL; } -STBVDEF stb_vorbis * stb_vorbis_open_file(FILE *file, int close_on_free, int *error, const stb_vorbis_alloc *alloc) +stb_vorbis * stb_vorbis_open_file(FILE *file, int close_on_free, int *error, const stb_vorbis_alloc *alloc) { unsigned int len, start; start = (unsigned int) ftell(file); @@ -4984,58 +5080,67 @@ STBVDEF stb_vorbis * stb_vorbis_open_file(FILE *file, int close_on_free, int *er return stb_vorbis_open_file_section(file, close_on_free, error, alloc, len); } -STBVDEF stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, const stb_vorbis_alloc *alloc) +stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, const stb_vorbis_alloc *alloc) { - FILE *f = fopen(filename, "rb"); - if (f) + FILE *f; +#if defined(_WIN32) && defined(__STDC_WANT_SECURE_LIB__) + if (0 != fopen_s(&f, filename, "rb")) + f = NULL; +#else + f = fopen(filename, "rb"); +#endif + if (f) return stb_vorbis_open_file(f, TRUE, error, alloc); if (error) *error = VORBIS_file_open_failure; return NULL; } #endif // STB_VORBIS_NO_STDIO -STBVDEF stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len, int *error, const stb_vorbis_alloc *alloc) +stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len, int *error, const stb_vorbis_alloc *alloc) { stb_vorbis *f, p; - if (data == NULL) return NULL; - stbv_vorbis_init(&p, alloc); - p.stream = (stbv_uint8 *) data; - p.stream_end = (stbv_uint8 *) data + len; - p.stream_start = (stbv_uint8 *) p.stream; + if (!data) { + if (error) *error = VORBIS_unexpected_eof; + return NULL; + } + vorbis_init(&p, alloc); + p.stream = (uint8 *) data; + p.stream_end = (uint8 *) data + len; + p.stream_start = (uint8 *) p.stream; p.stream_len = len; p.push_mode = FALSE; - if (stbv_start_decoder(&p)) { - f = stbv_vorbis_alloc(&p); + if (start_decoder(&p)) { + f = vorbis_alloc(&p); if (f) { *f = p; - stbv_vorbis_pump_first_frame(f); + vorbis_pump_first_frame(f); if (error) *error = VORBIS__no_error; return f; } } if (error) *error = p.error; - stbv_vorbis_deinit(&p); + vorbis_deinit(&p); return NULL; } #ifndef STB_VORBIS_NO_INTEGER_CONVERSION -#define STBV_PLAYBACK_MONO 1 -#define STBV_PLAYBACK_LEFT 2 -#define STBV_PLAYBACK_RIGHT 4 +#define PLAYBACK_MONO 1 +#define PLAYBACK_LEFT 2 +#define PLAYBACK_RIGHT 4 -#define STBV_L (STBV_PLAYBACK_LEFT | STBV_PLAYBACK_MONO) -#define STBV_C (STBV_PLAYBACK_LEFT | STBV_PLAYBACK_RIGHT | STBV_PLAYBACK_MONO) -#define STBV_R (STBV_PLAYBACK_RIGHT | STBV_PLAYBACK_MONO) +#define L (PLAYBACK_LEFT | PLAYBACK_MONO) +#define C (PLAYBACK_LEFT | PLAYBACK_RIGHT | PLAYBACK_MONO) +#define R (PLAYBACK_RIGHT | PLAYBACK_MONO) -static stbv_int8 stbv_channel_position[7][6] = +static int8 channel_position[7][6] = { { 0 }, - { STBV_C }, - { STBV_L, STBV_R }, - { STBV_L, STBV_C, STBV_R }, - { STBV_L, STBV_R, STBV_L, STBV_R }, - { STBV_L, STBV_C, STBV_R, STBV_L, STBV_R }, - { STBV_L, STBV_C, STBV_R, STBV_L, STBV_R, STBV_C }, + { C }, + { L, R }, + { L, C, R }, + { L, R, L, R }, + { L, C, R, L, R }, + { L, C, R, L, R, C }, }; @@ -5043,139 +5148,141 @@ static stbv_int8 stbv_channel_position[7][6] = typedef union { float f; int i; - } stbv_float_conv; + } float_conv; typedef char stb_vorbis_float_size_test[sizeof(float)==4 && sizeof(int) == 4]; - #define STBV_FASTDEF(x) stbv_float_conv x + #define FASTDEF(x) float_conv x // add (1<<23) to convert to int, then divide by 2^SHIFT, then add 0.5/2^SHIFT to round - #define STBV_MAGIC(SHIFT) (1.5f * (1 << (23-SHIFT)) + 0.5f/(1 << SHIFT)) - #define STBV_ADDEND(SHIFT) (((150-SHIFT) << 23) + (1 << 22)) - #define STBV_FAST_SCALED_FLOAT_TO_INT(temp,x,s) (temp.f = (x) + STBV_MAGIC(s), temp.i - STBV_ADDEND(s)) - #define stbv_check_endianness() + #define MAGIC(SHIFT) (1.5f * (1 << (23-SHIFT)) + 0.5f/(1 << SHIFT)) + #define ADDEND(SHIFT) (((150-SHIFT) << 23) + (1 << 22)) + #define FAST_SCALED_FLOAT_TO_INT(temp,x,s) (temp.f = (x) + MAGIC(s), temp.i - ADDEND(s)) + #define check_endianness() #else - #define STBV_FAST_SCALED_FLOAT_TO_INT(temp,x,s) ((int) ((x) * (1 << (s)))) - #define stbv_check_endianness() - #define STBV_FASTDEF(x) + #define FAST_SCALED_FLOAT_TO_INT(temp,x,s) ((int) ((x) * (1 << (s)))) + #define check_endianness() + #define FASTDEF(x) #endif -static void stbv_copy_samples(short *dest, float *src, int len) +static void copy_samples(short *dest, float *src, int len) { int i; - stbv_check_endianness(); + check_endianness(); for (i=0; i < len; ++i) { - STBV_FASTDEF(temp); - int v = STBV_FAST_SCALED_FLOAT_TO_INT(temp, src[i],15); + FASTDEF(temp); + int v = FAST_SCALED_FLOAT_TO_INT(temp, src[i],15); if ((unsigned int) (v + 32768) > 65535) v = v < 0 ? -32768 : 32767; dest[i] = v; } } -static void stbv_compute_samples(int mask, short *output, int num_c, float **data, int d_offset, int len) +static void compute_samples(int mask, short *output, int num_c, float **data, int d_offset, int len) { - #define BUFFER_SIZE 32 - float buffer[BUFFER_SIZE]; - int i,j,o,n = BUFFER_SIZE; - stbv_check_endianness(); - for (o = 0; o < len; o += BUFFER_SIZE) { + #define STB_BUFFER_SIZE 32 + float buffer[STB_BUFFER_SIZE]; + int i,j,o,n = STB_BUFFER_SIZE; + check_endianness(); + for (o = 0; o < len; o += STB_BUFFER_SIZE) { memset(buffer, 0, sizeof(buffer)); if (o + n > len) n = len - o; for (j=0; j < num_c; ++j) { - if (stbv_channel_position[num_c][j] & mask) { + if (channel_position[num_c][j] & mask) { for (i=0; i < n; ++i) buffer[i] += data[j][d_offset+o+i]; } } for (i=0; i < n; ++i) { - STBV_FASTDEF(temp); - int v = STBV_FAST_SCALED_FLOAT_TO_INT(temp,buffer[i],15); + FASTDEF(temp); + int v = FAST_SCALED_FLOAT_TO_INT(temp,buffer[i],15); if ((unsigned int) (v + 32768) > 65535) v = v < 0 ? -32768 : 32767; output[o+i] = v; } } + #undef STB_BUFFER_SIZE } -static void stbv_compute_stereo_samples(short *output, int num_c, float **data, int d_offset, int len) +static void compute_stereo_samples(short *output, int num_c, float **data, int d_offset, int len) { - #define BUFFER_SIZE 32 - float buffer[BUFFER_SIZE]; - int i,j,o,n = BUFFER_SIZE >> 1; + #define STB_BUFFER_SIZE 32 + float buffer[STB_BUFFER_SIZE]; + int i,j,o,n = STB_BUFFER_SIZE >> 1; // o is the offset in the source data - stbv_check_endianness(); - for (o = 0; o < len; o += BUFFER_SIZE >> 1) { + check_endianness(); + for (o = 0; o < len; o += STB_BUFFER_SIZE >> 1) { // o2 is the offset in the output data int o2 = o << 1; memset(buffer, 0, sizeof(buffer)); if (o + n > len) n = len - o; for (j=0; j < num_c; ++j) { - int m = stbv_channel_position[num_c][j] & (STBV_PLAYBACK_LEFT | STBV_PLAYBACK_RIGHT); - if (m == (STBV_PLAYBACK_LEFT | STBV_PLAYBACK_RIGHT)) { + int m = channel_position[num_c][j] & (PLAYBACK_LEFT | PLAYBACK_RIGHT); + if (m == (PLAYBACK_LEFT | PLAYBACK_RIGHT)) { for (i=0; i < n; ++i) { buffer[i*2+0] += data[j][d_offset+o+i]; buffer[i*2+1] += data[j][d_offset+o+i]; } - } else if (m == STBV_PLAYBACK_LEFT) { + } else if (m == PLAYBACK_LEFT) { for (i=0; i < n; ++i) { buffer[i*2+0] += data[j][d_offset+o+i]; } - } else if (m == STBV_PLAYBACK_RIGHT) { + } else if (m == PLAYBACK_RIGHT) { for (i=0; i < n; ++i) { buffer[i*2+1] += data[j][d_offset+o+i]; } } } for (i=0; i < (n<<1); ++i) { - STBV_FASTDEF(temp); - int v = STBV_FAST_SCALED_FLOAT_TO_INT(temp,buffer[i],15); + FASTDEF(temp); + int v = FAST_SCALED_FLOAT_TO_INT(temp,buffer[i],15); if ((unsigned int) (v + 32768) > 65535) v = v < 0 ? -32768 : 32767; output[o2+i] = v; } } + #undef STB_BUFFER_SIZE } -static void stbv_convert_samples_short(int buf_c, short **buffer, int b_offset, int data_c, float **data, int d_offset, int samples) +static void convert_samples_short(int buf_c, short **buffer, int b_offset, int data_c, float **data, int d_offset, int samples) { int i; if (buf_c != data_c && buf_c <= 2 && data_c <= 6) { - static int channel_selector[3][2] = { {0}, {STBV_PLAYBACK_MONO}, {STBV_PLAYBACK_LEFT, STBV_PLAYBACK_RIGHT} }; + static int channel_selector[3][2] = { {0}, {PLAYBACK_MONO}, {PLAYBACK_LEFT, PLAYBACK_RIGHT} }; for (i=0; i < buf_c; ++i) - stbv_compute_samples(channel_selector[buf_c][i], buffer[i]+b_offset, data_c, data, d_offset, samples); + compute_samples(channel_selector[buf_c][i], buffer[i]+b_offset, data_c, data, d_offset, samples); } else { int limit = buf_c < data_c ? buf_c : data_c; for (i=0; i < limit; ++i) - stbv_copy_samples(buffer[i]+b_offset, data[i]+d_offset, samples); + copy_samples(buffer[i]+b_offset, data[i]+d_offset, samples); for ( ; i < buf_c; ++i) memset(buffer[i]+b_offset, 0, sizeof(short) * samples); } } -STBVDEF int stb_vorbis_get_frame_short(stb_vorbis *f, int num_c, short **buffer, int num_samples) +int stb_vorbis_get_frame_short(stb_vorbis *f, int num_c, short **buffer, int num_samples) { - float **output; + float **output = NULL; int len = stb_vorbis_get_frame_float(f, NULL, &output); if (len > num_samples) len = num_samples; if (len) - stbv_convert_samples_short(num_c, buffer, 0, f->channels, output, 0, len); + convert_samples_short(num_c, buffer, 0, f->channels, output, 0, len); return len; } -static void stbv_convert_channels_short_interleaved(int buf_c, short *buffer, int data_c, float **data, int d_offset, int len) +static void convert_channels_short_interleaved(int buf_c, short *buffer, int data_c, float **data, int d_offset, int len) { int i; - stbv_check_endianness(); + check_endianness(); if (buf_c != data_c && buf_c <= 2 && data_c <= 6) { assert(buf_c == 2); for (i=0; i < buf_c; ++i) - stbv_compute_stereo_samples(buffer, data_c, data, d_offset, len); + compute_stereo_samples(buffer, data_c, data, d_offset, len); } else { int limit = buf_c < data_c ? buf_c : data_c; int j; for (j=0; j < len; ++j) { for (i=0; i < limit; ++i) { - STBV_FASTDEF(temp); + FASTDEF(temp); float f = data[i][d_offset+j]; - int v = STBV_FAST_SCALED_FLOAT_TO_INT(temp, f,15);//data[i][d_offset+j],15); + int v = FAST_SCALED_FLOAT_TO_INT(temp, f,15);//data[i][d_offset+j],15); if ((unsigned int) (v + 32768) > 65535) v = v < 0 ? -32768 : 32767; *buffer++ = v; @@ -5186,7 +5293,7 @@ static void stbv_convert_channels_short_interleaved(int buf_c, short *buffer, in } } -STBVDEF int stb_vorbis_get_frame_short_interleaved(stb_vorbis *f, int num_c, short *buffer, int num_shorts) +int stb_vorbis_get_frame_short_interleaved(stb_vorbis *f, int num_c, short *buffer, int num_shorts) { float **output; int len; @@ -5194,23 +5301,21 @@ STBVDEF int stb_vorbis_get_frame_short_interleaved(stb_vorbis *f, int num_c, sho len = stb_vorbis_get_frame_float(f, NULL, &output); if (len) { if (len*num_c > num_shorts) len = num_shorts / num_c; - stbv_convert_channels_short_interleaved(num_c, buffer, f->channels, output, 0, len); + convert_channels_short_interleaved(num_c, buffer, f->channels, output, 0, len); } return len; } -STBVDEF int stb_vorbis_get_samples_short_interleaved(stb_vorbis *f, int channels, short *buffer, int num_shorts) +int stb_vorbis_get_samples_short_interleaved(stb_vorbis *f, int channels, short *buffer, int num_shorts) { float **outputs; int len = num_shorts / channels; int n=0; - int z = f->channels; - if (z > channels) z = channels; while (n < len) { int k = f->channel_buffer_end - f->channel_buffer_start; if (n+k >= len) k = len - n; if (k) - stbv_convert_channels_short_interleaved(channels, buffer, f->channels, f->channel_buffers, f->channel_buffer_start, k); + convert_channels_short_interleaved(channels, buffer, f->channels, f->channel_buffers, f->channel_buffer_start, k); buffer += k*channels; n += k; f->channel_buffer_start += k; @@ -5220,17 +5325,15 @@ STBVDEF int stb_vorbis_get_samples_short_interleaved(stb_vorbis *f, int channels return n; } -STBVDEF int stb_vorbis_get_samples_short(stb_vorbis *f, int channels, short **buffer, int len) +int stb_vorbis_get_samples_short(stb_vorbis *f, int channels, short **buffer, int len) { float **outputs; int n=0; - int z = f->channels; - if (z > channels) z = channels; while (n < len) { int k = f->channel_buffer_end - f->channel_buffer_start; if (n+k >= len) k = len - n; if (k) - stbv_convert_samples_short(channels, buffer, n, f->channels, f->channel_buffers, f->channel_buffer_start, k); + convert_samples_short(channels, buffer, n, f->channels, f->channel_buffers, f->channel_buffer_start, k); n += k; f->channel_buffer_start += k; if (n == len) break; @@ -5240,7 +5343,7 @@ STBVDEF int stb_vorbis_get_samples_short(stb_vorbis *f, int channels, short **bu } #ifndef STB_VORBIS_NO_STDIO -STBVDEF int stb_vorbis_decode_filename(const char *filename, int *channels, int *sample_rate, short **output) +int stb_vorbis_decode_filename(const char *filename, int *channels, int *sample_rate, short **output) { int data_len, offset, total, limit, error; short *data; @@ -5280,7 +5383,7 @@ STBVDEF int stb_vorbis_decode_filename(const char *filename, int *channels, int } #endif // NO_STDIO -STBVDEF int stb_vorbis_decode_memory(const stbv_uint8 *mem, int len, int *channels, int *sample_rate, short **output) +int stb_vorbis_decode_memory(const uint8 *mem, int len, int *channels, int *sample_rate, short **output) { int data_len, offset, total, limit, error; short *data; @@ -5320,7 +5423,7 @@ STBVDEF int stb_vorbis_decode_memory(const stbv_uint8 *mem, int len, int *channe } #endif // STB_VORBIS_NO_INTEGER_CONVERSION -STBVDEF int stb_vorbis_get_samples_float_interleaved(stb_vorbis *f, int channels, float *buffer, int num_floats) +int stb_vorbis_get_samples_float_interleaved(stb_vorbis *f, int channels, float *buffer, int num_floats) { float **outputs; int len = num_floats / channels; @@ -5347,7 +5450,7 @@ STBVDEF int stb_vorbis_get_samples_float_interleaved(stb_vorbis *f, int channels return n; } -STBVDEF int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, int num_samples) +int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, int num_samples) { float **outputs; int n=0; @@ -5375,14 +5478,20 @@ STBVDEF int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **bu #endif // STB_VORBIS_NO_PULLDATA_API /* Version history + 1.17 - 2019-07-08 - fix CVE-2019-13217, -13218, -13219, -13220, -13221, -13222, -13223 + found with Mayhem by ForAllSecure + 1.16 - 2019-03-04 - fix warnings + 1.15 - 2019-02-07 - explicit failure if Ogg Skeleton data is found + 1.14 - 2018-02-11 - delete bogus dealloca usage + 1.13 - 2018-01-29 - fix truncation of last frame (hopefully) 1.12 - 2017-11-21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files - 1.11 - 2017-07-23 - fix MinGW compilation - 1.10 - 2017-03-03 - more robust seeking; fix negative stbv_ilog(); clear error in open_memory + 1.11 - 2017-07-23 - fix MinGW compilation + 1.10 - 2017-03-03 - more robust seeking; fix negative ilog(); clear error in open_memory 1.09 - 2016-04-04 - back out 'avoid discarding last frame' fix from previous version 1.08 - 2016-04-02 - fixed multiple warnings; fix setup memory leaks; avoid discarding last frame of audio data 1.07 - 2015-01-16 - fixed some warnings, fix mingw, const-correct API - some more crash fixes when out of memory or with corrupt files + some more crash fixes when out of memory or with corrupt files 1.06 - 2015-08-31 - full, correct support for seeking API (Dougall Johnson) some crash fixes when out of memory or with corrupt files 1.05 - 2015-04-19 - don't define __forceinline if it's redundant @@ -5438,38 +5547,38 @@ This software is available under 2 licenses -- choose whichever you prefer. ------------------------------------------------------------------------------ ALTERNATIVE A - MIT License Copyright (c) 2017 Sean Barrett -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ ALTERNATIVE B - Public Domain (www.unlicense.org) This is free and unencumbered software released into the public domain. -Anyone is free to copy, modify, publish, use, compile, sell, or distribute this -software, either in source code form or as a compiled binary, for any purpose, +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. -In jurisdictions that recognize copyright laws, the author or authors of this -software dedicate any and all copyright interest in the software to the public -domain. We make this dedication for the benefit of the public at large and to -the detriment of our heirs and successors. We intend this dedication to be an -overt act of relinquishment in perpetuity of all present and future rights to +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ */