2001-02-08 00:38:41 +00:00
/* libFLAC - Free Lossless Audio Codec library
2006-04-25 06:59:33 +00:00
* Copyright ( C ) 2000 , 2001 , 2002 , 2003 , 2004 , 2005 , 2006 Josh Coalson
2000-12-10 04:09:52 +00:00
*
2003-01-31 23:34:56 +00:00
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
2000-12-10 04:09:52 +00:00
*
2003-01-31 23:34:56 +00:00
* - Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
2000-12-10 04:09:52 +00:00
*
2003-01-31 23:34:56 +00:00
* - Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
*
* - Neither the name of the Xiph . org Foundation nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ` ` AS IS ' ' AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE FOUNDATION OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL ,
* EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO ,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE , DATA , OR
* PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING
* NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
2000-12-10 04:09:52 +00:00
*/
2006-05-24 04:41:36 +00:00
# if HAVE_CONFIG_H
# include <config.h>
# endif
2006-09-13 01:42:27 +00:00
# if defined _MSC_VER || defined __MINGW32__
# include <io.h> /* for _setmode() */
# include <fcntl.h> /* for _O_BINARY */
# endif
# if defined __CYGWIN__ || defined __EMX__
# include <io.h> /* for setmode(), O_BINARY */
# include <fcntl.h> /* for _O_BINARY */
# endif
2000-12-10 04:09:52 +00:00
# include <stdio.h>
# include <stdlib.h> /* for malloc() */
2001-04-01 05:34:16 +00:00
# include <string.h> /* for memset/memcpy() */
2006-09-13 01:42:27 +00:00
# include <sys/stat.h> /* for stat() */
# include <sys/types.h> /* for off_t */
# if defined _MSC_VER || defined __MINGW32__
2006-10-03 01:16:59 +00:00
# if _MSC_VER <= 1200 /* @@@ [2G limit] */
2006-09-13 01:42:27 +00:00
# define fseeko fseek
# define ftello ftell
# endif
2006-10-03 01:16:59 +00:00
# endif
2001-05-31 20:11:02 +00:00
# include "FLAC/assert.h"
2001-06-13 17:59:57 +00:00
# include "protected/stream_decoder.h"
2000-12-10 04:09:52 +00:00
# include "private/bitbuffer.h"
2002-10-26 04:33:49 +00:00
# include "private/bitmath.h"
2001-05-23 21:59:52 +00:00
# include "private/cpu.h"
2000-12-10 04:09:52 +00:00
# include "private/crc.h"
# include "private/fixed.h"
2002-08-17 15:23:43 +00:00
# include "private/format.h"
2000-12-10 04:09:52 +00:00
# include "private/lpc.h"
2006-09-13 01:42:27 +00:00
# include "private/md5.h"
2004-07-27 01:13:16 +00:00
# include "private/memory.h"
2000-12-10 04:09:52 +00:00
2002-08-17 15:23:43 +00:00
# ifdef max
# undef max
# endif
# define max(a,b) ((a)>(b)?(a):(b))
2004-07-29 06:28:59 +00:00
/* adjust for compilers that can't understand using LLU suffix for uint64_t literals */
# ifdef _MSC_VER
# define FLAC__U64L(x) x
# else
# define FLAC__U64L(x) x##LLU
# endif
2001-06-13 17:59:57 +00:00
/***********************************************************************
*
* Private static data
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-06-23 03:03:24 +00:00
static FLAC__byte ID3V2_TAG_ [ 3 ] = { ' I ' , ' D ' , ' 3 ' } ;
2001-06-13 17:59:57 +00:00
/***********************************************************************
*
* Private class method prototypes
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-31 06:58:16 +00:00
static void set_defaults_ ( FLAC__StreamDecoder * decoder ) ;
2006-09-13 01:42:27 +00:00
static FILE * get_binary_stdin_ ( ) ;
2002-07-31 06:58:16 +00:00
static FLAC__bool allocate_output_ ( FLAC__StreamDecoder * decoder , unsigned size , unsigned channels ) ;
static FLAC__bool has_id_filtered_ ( FLAC__StreamDecoder * decoder , FLAC__byte * id ) ;
static FLAC__bool find_metadata_ ( FLAC__StreamDecoder * decoder ) ;
static FLAC__bool read_metadata_ ( FLAC__StreamDecoder * decoder ) ;
2002-11-14 04:58:42 +00:00
static FLAC__bool read_metadata_streaminfo_ ( FLAC__StreamDecoder * decoder , FLAC__bool is_last , unsigned length ) ;
static FLAC__bool read_metadata_seektable_ ( FLAC__StreamDecoder * decoder , FLAC__bool is_last , unsigned length ) ;
static FLAC__bool read_metadata_vorbiscomment_ ( FLAC__StreamDecoder * decoder , FLAC__StreamMetadata_VorbisComment * obj ) ;
2002-11-15 05:41:48 +00:00
static FLAC__bool read_metadata_cuesheet_ ( FLAC__StreamDecoder * decoder , FLAC__StreamMetadata_CueSheet * obj ) ;
2006-09-23 19:21:19 +00:00
static FLAC__bool read_metadata_picture_ ( FLAC__StreamDecoder * decoder , FLAC__StreamMetadata_Picture * obj ) ;
2002-07-31 06:58:16 +00:00
static FLAC__bool skip_id3v2_tag_ ( FLAC__StreamDecoder * decoder ) ;
static FLAC__bool frame_sync_ ( FLAC__StreamDecoder * decoder ) ;
2004-07-16 00:53:38 +00:00
static FLAC__bool read_frame_ ( FLAC__StreamDecoder * decoder , FLAC__bool * got_a_frame , FLAC__bool do_full_decode ) ;
2002-07-31 06:58:16 +00:00
static FLAC__bool read_frame_header_ ( FLAC__StreamDecoder * decoder ) ;
2004-07-16 00:53:38 +00:00
static FLAC__bool read_subframe_ ( FLAC__StreamDecoder * decoder , unsigned channel , unsigned bps , FLAC__bool do_full_decode ) ;
static FLAC__bool read_subframe_constant_ ( FLAC__StreamDecoder * decoder , unsigned channel , unsigned bps , FLAC__bool do_full_decode ) ;
static FLAC__bool read_subframe_fixed_ ( FLAC__StreamDecoder * decoder , unsigned channel , unsigned bps , const unsigned order , FLAC__bool do_full_decode ) ;
static FLAC__bool read_subframe_lpc_ ( FLAC__StreamDecoder * decoder , unsigned channel , unsigned bps , const unsigned order , FLAC__bool do_full_decode ) ;
static FLAC__bool read_subframe_verbatim_ ( FLAC__StreamDecoder * decoder , unsigned channel , unsigned bps , FLAC__bool do_full_decode ) ;
2002-08-19 21:36:39 +00:00
static FLAC__bool read_residual_partitioned_rice_ ( FLAC__StreamDecoder * decoder , unsigned predictor_order , unsigned partition_order , FLAC__EntropyCodingMethod_PartitionedRiceContents * partitioned_rice_contents , FLAC__int32 * residual ) ;
2002-07-31 06:58:16 +00:00
static FLAC__bool read_zero_padding_ ( FLAC__StreamDecoder * decoder ) ;
2001-06-23 03:03:24 +00:00
static FLAC__bool read_callback_ ( FLAC__byte buffer [ ] , unsigned * bytes , void * client_data ) ;
2006-09-13 01:42:27 +00:00
static FLAC__StreamDecoderWriteStatus write_audio_frame_to_client_ ( FLAC__StreamDecoder * decoder , const FLAC__Frame * frame , const FLAC__int32 * const buffer [ ] ) ;
static void send_error_to_client_ ( const FLAC__StreamDecoder * decoder , FLAC__StreamDecoderErrorStatus status ) ;
static FLAC__bool seek_to_absolute_sample_ ( FLAC__StreamDecoder * decoder , FLAC__uint64 stream_length , FLAC__uint64 target_sample ) ;
static FLAC__StreamDecoderReadStatus file_read_callback_ ( const FLAC__StreamDecoder * decoder , FLAC__byte buffer [ ] , unsigned * bytes , void * client_data ) ;
static FLAC__StreamDecoderSeekStatus file_seek_callback_ ( const FLAC__StreamDecoder * decoder , FLAC__uint64 absolute_byte_offset , void * client_data ) ;
static FLAC__StreamDecoderTellStatus file_tell_callback_ ( const FLAC__StreamDecoder * decoder , FLAC__uint64 * absolute_byte_offset , void * client_data ) ;
static FLAC__StreamDecoderLengthStatus file_length_callback_ ( const FLAC__StreamDecoder * decoder , FLAC__uint64 * stream_length , void * client_data ) ;
static FLAC__bool file_eof_callback_ ( const FLAC__StreamDecoder * decoder , void * client_data ) ;
2001-06-13 17:59:57 +00:00
/***********************************************************************
*
* Private class data
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-12-10 04:09:52 +00:00
typedef struct FLAC__StreamDecoderPrivate {
2002-08-01 08:19:37 +00:00
FLAC__StreamDecoderReadCallback read_callback ;
2006-09-13 01:42:27 +00:00
FLAC__StreamDecoderSeekCallback seek_callback ;
FLAC__StreamDecoderTellCallback tell_callback ;
FLAC__StreamDecoderLengthCallback length_callback ;
FLAC__StreamDecoderEofCallback eof_callback ;
2002-08-01 08:19:37 +00:00
FLAC__StreamDecoderWriteCallback write_callback ;
FLAC__StreamDecoderMetadataCallback metadata_callback ;
FLAC__StreamDecoderErrorCallback error_callback ;
2004-07-27 01:13:16 +00:00
/* generic 32-bit datapath: */
2001-06-23 03:03:24 +00:00
void ( * local_lpc_restore_signal ) ( const FLAC__int32 residual [ ] , unsigned data_len , const FLAC__int32 qlp_coeff [ ] , unsigned order , int lp_quantization , FLAC__int32 data [ ] ) ;
2004-07-27 01:13:16 +00:00
/* generic 64-bit datapath: */
2002-10-04 05:27:49 +00:00
void ( * local_lpc_restore_signal_64bit ) ( const FLAC__int32 residual [ ] , unsigned data_len , const FLAC__int32 qlp_coeff [ ] , unsigned order , int lp_quantization , FLAC__int32 data [ ] ) ;
2004-07-27 01:13:16 +00:00
/* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit): */
2001-06-23 03:03:24 +00:00
void ( * local_lpc_restore_signal_16bit ) ( const FLAC__int32 residual [ ] , unsigned data_len , const FLAC__int32 qlp_coeff [ ] , unsigned order , int lp_quantization , FLAC__int32 data [ ] ) ;
2004-07-27 01:13:16 +00:00
/* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit), AND order <= 8: */
void ( * local_lpc_restore_signal_16bit_order8 ) ( const FLAC__int32 residual [ ] , unsigned data_len , const FLAC__int32 qlp_coeff [ ] , unsigned order , int lp_quantization , FLAC__int32 data [ ] ) ;
2000-12-10 04:09:52 +00:00
void * client_data ;
2006-09-13 01:42:27 +00:00
FILE * file ; /* only used if FLAC__stream_decoder_init_file()/FLAC__stream_decoder_init_file() called, else NULL */
2002-03-12 16:19:54 +00:00
FLAC__BitBuffer * input ;
2001-06-23 03:03:24 +00:00
FLAC__int32 * output [ FLAC__MAX_CHANNELS ] ;
2004-07-27 01:13:16 +00:00
FLAC__int32 * residual [ FLAC__MAX_CHANNELS ] ; /* WATCHOUT: these are the aligned pointers; the real pointers that should be free()'d are residual_unaligned[] below */
2002-08-19 21:36:39 +00:00
FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents [ FLAC__MAX_CHANNELS ] ;
2001-03-23 20:20:43 +00:00
unsigned output_capacity , output_channels ;
2001-06-23 03:03:24 +00:00
FLAC__uint32 last_frame_number ;
2005-01-24 00:20:49 +00:00
FLAC__uint32 last_block_size ;
2001-06-23 03:03:24 +00:00
FLAC__uint64 samples_decoded ;
FLAC__bool has_stream_info , has_seek_table ;
2002-06-08 04:53:42 +00:00
FLAC__StreamMetadata stream_info ;
FLAC__StreamMetadata seek_table ;
2003-01-10 05:37:13 +00:00
FLAC__bool metadata_filter [ 128 ] ; /* MAGIC number 128 == total number of metadata block types == 1 << 7 */
2002-05-07 05:30:27 +00:00
FLAC__byte * metadata_filter_ids ;
unsigned metadata_filter_ids_count , metadata_filter_ids_capacity ; /* units for both are IDs, not bytes */
2001-01-23 23:07:36 +00:00
FLAC__Frame frame ;
2001-06-23 03:03:24 +00:00
FLAC__bool cached ; /* true if there is a byte in lookahead */
2001-05-23 21:59:52 +00:00
FLAC__CPUInfo cpuinfo ;
2001-06-23 03:03:24 +00:00
FLAC__byte header_warmup [ 2 ] ; /* contains the sync code and reserved bits */
FLAC__byte lookahead ; /* temp storage when we need to look ahead one byte in the stream */
2004-07-27 01:13:16 +00:00
/* unaligned (original) pointers to allocated data */
FLAC__int32 * residual_unaligned [ FLAC__MAX_CHANNELS ] ;
2006-09-13 01:42:27 +00:00
FLAC__bool do_md5_checking ; /* initially gets protected_->md5_checking but is turned off after a seek or if the metadata has a zero MD5 */
FLAC__bool internal_reset_hack ; /* used only during init() so we can call reset to set up the decoder without rewinding the input */
FLAC__bool is_seeking ;
struct FLAC__MD5Context md5context ;
FLAC__byte computed_md5sum [ 16 ] ; /* this is the sum we computed from the decoded data */
/* (the rest of these are only used for seeking) */
FLAC__Frame last_frame ; /* holds the info of the last frame we seeked to */
FLAC__uint64 first_frame_offset ; /* hint to the seek routine of where in the stream the first audio frame starts */
FLAC__uint64 target_sample ;
unsigned unparseable_frame_count ; /* used to tell whether we're decoding a future version of FLAC or just got a bad sync */
2000-12-10 04:09:52 +00:00
} FLAC__StreamDecoderPrivate ;
2001-06-13 17:59:57 +00:00
/***********************************************************************
*
* Public static class data
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-12-10 04:09:52 +00:00
2002-10-16 22:29:47 +00:00
FLAC_API const char * const FLAC__StreamDecoderStateString [ ] = {
2000-12-22 22:35:33 +00:00
" FLAC__STREAM_DECODER_SEARCH_FOR_METADATA " ,
" FLAC__STREAM_DECODER_READ_METADATA " ,
" FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC " ,
" FLAC__STREAM_DECODER_READ_FRAME " ,
" FLAC__STREAM_DECODER_END_OF_STREAM " ,
2006-09-13 01:42:27 +00:00
" FLAC__STREAM_DECODER_SEEK_ERROR " ,
2000-12-22 22:35:33 +00:00
" FLAC__STREAM_DECODER_ABORTED " ,
" FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR " ,
" FLAC__STREAM_DECODER_UNINITIALIZED "
} ;
2006-09-13 01:42:27 +00:00
FLAC_API const char * const FLAC__StreamDecoderInitStatusString [ ] = {
" FLAC__STREAM_DECODER_INIT_STATUS_OK " ,
" FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS " ,
" FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR " ,
" FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE " ,
" FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED "
} ;
2002-10-16 22:29:47 +00:00
FLAC_API const char * const FLAC__StreamDecoderReadStatusString [ ] = {
2002-06-04 05:53:04 +00:00
" FLAC__STREAM_DECODER_READ_STATUS_CONTINUE " ,
" FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM " ,
" FLAC__STREAM_DECODER_READ_STATUS_ABORT "
2000-12-22 22:35:33 +00:00
} ;
2006-09-13 01:42:27 +00:00
FLAC_API const char * const FLAC__StreamDecoderSeekStatusString [ ] = {
" FLAC__STREAM_DECODER_SEEK_STATUS_OK " ,
" FLAC__STREAM_DECODER_SEEK_STATUS_ERROR " ,
" FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED "
} ;
FLAC_API const char * const FLAC__StreamDecoderTellStatusString [ ] = {
" FLAC__STREAM_DECODER_TELL_STATUS_OK " ,
" FLAC__STREAM_DECODER_TELL_STATUS_ERROR " ,
" FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED "
} ;
FLAC_API const char * const FLAC__StreamDecoderLengthStatusString [ ] = {
" FLAC__STREAM_DECODER_LENGTH_STATUS_OK " ,
" FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR " ,
" FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED "
} ;
2002-10-16 22:29:47 +00:00
FLAC_API const char * const FLAC__StreamDecoderWriteStatusString [ ] = {
2002-06-04 05:53:04 +00:00
" FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE " ,
" FLAC__STREAM_DECODER_WRITE_STATUS_ABORT "
2000-12-22 22:35:33 +00:00
} ;
2002-10-16 22:29:47 +00:00
FLAC_API const char * const FLAC__StreamDecoderErrorStatusString [ ] = {
2002-06-04 05:53:04 +00:00
" FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC " ,
" FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER " ,
2006-07-06 07:49:07 +00:00
" FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH " ,
" FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM "
2000-12-22 22:35:33 +00:00
} ;
2001-06-13 17:59:57 +00:00
/***********************************************************************
*
* Class constructor / destructor
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-10-16 22:29:47 +00:00
FLAC_API FLAC__StreamDecoder * FLAC__stream_decoder_new ( )
2000-12-10 04:09:52 +00:00
{
2001-06-13 17:59:57 +00:00
FLAC__StreamDecoder * decoder ;
2002-06-14 06:36:16 +00:00
unsigned i ;
2001-06-13 17:59:57 +00:00
FLAC__ASSERT ( sizeof ( int ) > = 4 ) ; /* we want to die right away if this is not true */
2002-10-18 05:49:19 +00:00
decoder = ( FLAC__StreamDecoder * ) calloc ( 1 , sizeof ( FLAC__StreamDecoder ) ) ;
2001-06-13 17:59:57 +00:00
if ( decoder = = 0 ) {
return 0 ;
2000-12-10 04:09:52 +00:00
}
2002-08-03 22:05:11 +00:00
2002-10-18 05:49:19 +00:00
decoder - > protected_ = ( FLAC__StreamDecoderProtected * ) calloc ( 1 , sizeof ( FLAC__StreamDecoderProtected ) ) ;
2001-08-16 20:07:29 +00:00
if ( decoder - > protected_ = = 0 ) {
2001-06-13 17:59:57 +00:00
free ( decoder ) ;
return 0 ;
}
2002-08-03 22:05:11 +00:00
2002-10-18 05:49:19 +00:00
decoder - > private_ = ( FLAC__StreamDecoderPrivate * ) calloc ( 1 , sizeof ( FLAC__StreamDecoderPrivate ) ) ;
2001-08-16 20:07:29 +00:00
if ( decoder - > private_ = = 0 ) {
free ( decoder - > protected_ ) ;
2001-06-13 17:59:57 +00:00
free ( decoder ) ;
return 0 ;
}
2002-08-03 22:05:11 +00:00
2002-03-12 16:19:54 +00:00
decoder - > private_ - > input = FLAC__bitbuffer_new ( ) ;
if ( decoder - > private_ - > input = = 0 ) {
free ( decoder - > private_ ) ;
free ( decoder - > protected_ ) ;
free ( decoder ) ;
return 0 ;
}
2001-06-13 17:59:57 +00:00
2002-05-10 06:42:02 +00:00
decoder - > private_ - > metadata_filter_ids_capacity = 16 ;
2002-11-06 07:11:26 +00:00
if ( 0 = = ( decoder - > private_ - > metadata_filter_ids = ( FLAC__byte * ) malloc ( ( FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8 ) * decoder - > private_ - > metadata_filter_ids_capacity ) ) ) {
2002-05-10 06:42:02 +00:00
FLAC__bitbuffer_delete ( decoder - > private_ - > input ) ;
free ( decoder - > private_ ) ;
free ( decoder - > protected_ ) ;
free ( decoder ) ;
return 0 ;
}
2002-06-04 05:53:04 +00:00
2002-06-14 06:36:16 +00:00
for ( i = 0 ; i < FLAC__MAX_CHANNELS ; i + + ) {
decoder - > private_ - > output [ i ] = 0 ;
2004-07-27 01:13:16 +00:00
decoder - > private_ - > residual_unaligned [ i ] = decoder - > private_ - > residual [ i ] = 0 ;
2002-06-14 06:36:16 +00:00
}
decoder - > private_ - > output_capacity = 0 ;
decoder - > private_ - > output_channels = 0 ;
decoder - > private_ - > has_seek_table = false ;
2002-08-19 21:36:39 +00:00
for ( i = 0 ; i < FLAC__MAX_CHANNELS ; i + + )
FLAC__format_entropy_coding_method_partitioned_rice_contents_init ( & decoder - > private_ - > partitioned_rice_contents [ i ] ) ;
2002-06-14 06:36:16 +00:00
2006-09-13 01:42:27 +00:00
decoder - > private_ - > file = 0 ;
2002-07-31 06:58:16 +00:00
set_defaults_ ( decoder ) ;
2002-05-10 06:42:02 +00:00
2002-06-14 06:36:16 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_UNINITIALIZED ;
2000-12-10 04:09:52 +00:00
return decoder ;
}
2002-10-16 22:29:47 +00:00
FLAC_API void FLAC__stream_decoder_delete ( FLAC__StreamDecoder * decoder )
2000-12-10 04:09:52 +00:00
{
2002-08-19 21:36:39 +00:00
unsigned i ;
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
FLAC__ASSERT ( 0 ! = decoder - > private_ ) ;
FLAC__ASSERT ( 0 ! = decoder - > private_ - > input ) ;
2001-06-13 17:59:57 +00:00
2002-06-14 06:36:16 +00:00
FLAC__stream_decoder_finish ( decoder ) ;
2002-07-31 06:58:16 +00:00
if ( 0 ! = decoder - > private_ - > metadata_filter_ids )
2002-06-04 05:53:04 +00:00
free ( decoder - > private_ - > metadata_filter_ids ) ;
2002-03-12 16:19:54 +00:00
FLAC__bitbuffer_delete ( decoder - > private_ - > input ) ;
2002-08-17 15:23:43 +00:00
2002-08-19 21:36:39 +00:00
for ( i = 0 ; i < FLAC__MAX_CHANNELS ; i + + )
FLAC__format_entropy_coding_method_partitioned_rice_contents_clear ( & decoder - > private_ - > partitioned_rice_contents [ i ] ) ;
2002-08-17 15:23:43 +00:00
2001-08-16 20:07:29 +00:00
free ( decoder - > private_ ) ;
free ( decoder - > protected_ ) ;
2000-12-10 04:09:52 +00:00
free ( decoder ) ;
}
2001-06-13 17:59:57 +00:00
/***********************************************************************
*
* Public class methods
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-13 01:42:27 +00:00
FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_stream (
FLAC__StreamDecoder * decoder ,
FLAC__StreamDecoderReadCallback read_callback ,
FLAC__StreamDecoderSeekCallback seek_callback ,
FLAC__StreamDecoderTellCallback tell_callback ,
FLAC__StreamDecoderLengthCallback length_callback ,
FLAC__StreamDecoderEofCallback eof_callback ,
FLAC__StreamDecoderWriteCallback write_callback ,
FLAC__StreamDecoderMetadataCallback metadata_callback ,
FLAC__StreamDecoderErrorCallback error_callback ,
void * client_data
)
2000-12-10 04:09:52 +00:00
{
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
2000-12-10 04:09:52 +00:00
2001-08-16 20:07:29 +00:00
if ( decoder - > protected_ - > state ! = FLAC__STREAM_DECODER_UNINITIALIZED )
2006-09-13 01:42:27 +00:00
return FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED ;
2000-12-10 04:09:52 +00:00
2006-09-13 01:42:27 +00:00
if (
0 = = read_callback | |
0 = = write_callback | |
0 = = error_callback | |
( seek_callback & & ( 0 = = tell_callback | | 0 = = length_callback | | 0 = = eof_callback ) )
)
return FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS ;
2000-12-10 04:09:52 +00:00
2001-05-23 21:59:52 +00:00
/*
* get the CPU info and set the function pointers
*/
2001-08-16 20:07:29 +00:00
FLAC__cpu_info ( & decoder - > private_ - > cpuinfo ) ;
2001-05-23 21:59:52 +00:00
/* first default to the non-asm routines */
2001-08-16 20:07:29 +00:00
decoder - > private_ - > local_lpc_restore_signal = FLAC__lpc_restore_signal ;
2002-10-04 05:27:49 +00:00
decoder - > private_ - > local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide ;
2001-08-16 20:07:29 +00:00
decoder - > private_ - > local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal ;
2004-07-27 01:13:16 +00:00
decoder - > private_ - > local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal ;
2001-05-23 21:59:52 +00:00
/* now override with asm where appropriate */
2001-05-25 00:04:45 +00:00
# ifndef FLAC__NO_ASM
2001-08-16 20:07:29 +00:00
if ( decoder - > private_ - > cpuinfo . use_asm ) {
2001-05-23 21:59:52 +00:00
# ifdef FLAC__CPU_IA32
2001-08-16 20:07:29 +00:00
FLAC__ASSERT ( decoder - > private_ - > cpuinfo . type = = FLAC__CPUINFO_TYPE_IA32 ) ;
2001-05-24 19:29:30 +00:00
# ifdef FLAC__HAS_NASM
2001-08-16 20:07:29 +00:00
if ( decoder - > private_ - > cpuinfo . data . ia32 . mmx ) {
decoder - > private_ - > local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32 ;
decoder - > private_ - > local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32_mmx ;
2004-07-27 01:13:16 +00:00
decoder - > private_ - > local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ia32_mmx ;
2001-07-18 00:25:52 +00:00
}
else {
2001-08-16 20:07:29 +00:00
decoder - > private_ - > local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32 ;
decoder - > private_ - > local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32 ;
2004-07-27 01:13:16 +00:00
decoder - > private_ - > local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ia32 ;
2001-07-18 00:25:52 +00:00
}
2001-05-25 00:04:45 +00:00
# endif
2004-07-27 01:13:16 +00:00
# elif defined FLAC__CPU_PPC
FLAC__ASSERT ( decoder - > private_ - > cpuinfo . type = = FLAC__CPUINFO_TYPE_PPC ) ;
if ( decoder - > private_ - > cpuinfo . data . ppc . altivec ) {
decoder - > private_ - > local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ppc_altivec_16 ;
decoder - > private_ - > local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ppc_altivec_16_order8 ;
}
2001-05-24 19:29:30 +00:00
# endif
2001-07-18 00:25:52 +00:00
}
2001-05-23 21:59:52 +00:00
# endif
2006-09-13 01:42:27 +00:00
/* from here on, errors are fatal */
2002-08-02 06:12:36 +00:00
2006-09-13 01:42:27 +00:00
if ( ! FLAC__bitbuffer_init ( decoder - > private_ - > input ) ) {
decoder - > protected_ - > state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR ;
return FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR ;
}
decoder - > private_ - > read_callback = read_callback ;
decoder - > private_ - > seek_callback = seek_callback ;
decoder - > private_ - > tell_callback = tell_callback ;
decoder - > private_ - > length_callback = length_callback ;
decoder - > private_ - > eof_callback = eof_callback ;
decoder - > private_ - > write_callback = write_callback ;
decoder - > private_ - > metadata_callback = metadata_callback ;
decoder - > private_ - > error_callback = error_callback ;
decoder - > private_ - > client_data = client_data ;
decoder - > private_ - > last_frame_number = 0 ;
decoder - > private_ - > last_block_size = 0 ;
decoder - > private_ - > samples_decoded = 0 ;
decoder - > private_ - > has_stream_info = false ;
decoder - > private_ - > cached = false ;
decoder - > private_ - > do_md5_checking = decoder - > protected_ - > md5_checking ;
decoder - > private_ - > is_seeking = false ;
decoder - > private_ - > internal_reset_hack = true ; /* so the following reset does not try to rewind the input */
if ( ! FLAC__stream_decoder_reset ( decoder ) ) {
/* above call sets the state for us */
return FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR ;
}
return FLAC__STREAM_DECODER_INIT_STATUS_OK ;
}
FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_FILE (
FLAC__StreamDecoder * decoder ,
FILE * file ,
FLAC__StreamDecoderWriteCallback write_callback ,
FLAC__StreamDecoderMetadataCallback metadata_callback ,
FLAC__StreamDecoderErrorCallback error_callback ,
void * client_data
)
{
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = file ) ;
if ( decoder - > protected_ - > state ! = FLAC__STREAM_DECODER_UNINITIALIZED )
return decoder - > protected_ - > state = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED ;
if ( 0 = = write_callback | | 0 = = error_callback )
return decoder - > protected_ - > state = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS ;
/*
* To make sure that our file does not go unclosed after an error , we
* must assign the FILE pointer before any further error can occur in
* this routine .
*/
if ( file = = stdin )
file = get_binary_stdin_ ( ) ; /* just to be safe */
decoder - > private_ - > file = file ;
return FLAC__stream_decoder_init_stream (
decoder ,
file_read_callback_ ,
decoder - > private_ - > file = = stdin ? 0 : file_seek_callback_ ,
2006-10-10 00:39:27 +00:00
decoder - > private_ - > file = = stdin ? 0 : file_tell_callback_ ,
2006-09-13 01:42:27 +00:00
decoder - > private_ - > file = = stdin ? 0 : file_length_callback_ ,
2006-10-10 00:39:27 +00:00
file_eof_callback_ ,
2006-09-13 01:42:27 +00:00
write_callback ,
metadata_callback ,
error_callback ,
client_data
) ;
}
FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_file (
FLAC__StreamDecoder * decoder ,
const char * filename ,
FLAC__StreamDecoderWriteCallback write_callback ,
FLAC__StreamDecoderMetadataCallback metadata_callback ,
FLAC__StreamDecoderErrorCallback error_callback ,
void * client_data
)
{
FILE * file ;
FLAC__ASSERT ( 0 ! = decoder ) ;
/*
* To make sure that our file does not go unclosed after an error , we
* have to do the same entrance checks here that are later performed
* in FLAC__stream_decoder_init_FILE ( ) before the FILE * is assigned .
*/
if ( decoder - > protected_ - > state ! = FLAC__STREAM_DECODER_UNINITIALIZED )
return decoder - > protected_ - > state = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED ;
if ( 0 = = write_callback | | 0 = = error_callback )
return decoder - > protected_ - > state = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS ;
file = filename ? fopen ( filename , " rb " ) : stdin ;
if ( 0 = = file )
return FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE ;
return FLAC__stream_decoder_init_FILE ( decoder , file , write_callback , metadata_callback , error_callback , client_data ) ;
2000-12-10 04:09:52 +00:00
}
2006-09-13 01:42:27 +00:00
FLAC_API FLAC__bool FLAC__stream_decoder_finish ( FLAC__StreamDecoder * decoder )
2000-12-10 04:09:52 +00:00
{
2006-09-13 01:42:27 +00:00
FLAC__bool md5_failed = false ;
2000-12-10 04:09:52 +00:00
unsigned i ;
2006-09-13 01:42:27 +00:00
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
2006-09-13 01:42:27 +00:00
FLAC__ASSERT ( 0 ! = decoder - > private_ ) ;
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
2001-08-16 20:07:29 +00:00
if ( decoder - > protected_ - > state = = FLAC__STREAM_DECODER_UNINITIALIZED )
2006-09-13 01:42:27 +00:00
return true ;
/* see the comment in FLAC__seekable_stream_decoder_reset() as to why we
* always call FLAC__MD5Final ( )
*/
FLAC__MD5Final ( decoder - > private_ - > computed_md5sum , & decoder - > private_ - > md5context ) ;
if ( decoder - > private_ - > has_seek_table & & 0 ! = decoder - > private_ - > seek_table . data . seek_table . points ) {
2001-08-16 20:07:29 +00:00
free ( decoder - > private_ - > seek_table . data . seek_table . points ) ;
decoder - > private_ - > seek_table . data . seek_table . points = 0 ;
2002-06-14 06:36:16 +00:00
decoder - > private_ - > has_seek_table = false ;
2001-06-13 17:59:57 +00:00
}
2002-03-12 16:19:54 +00:00
FLAC__bitbuffer_free ( decoder - > private_ - > input ) ;
2001-06-13 17:59:57 +00:00
for ( i = 0 ; i < FLAC__MAX_CHANNELS ; i + + ) {
2002-08-17 15:23:43 +00:00
/* WATCHOUT:
* FLAC__lpc_restore_signal_asm_ia32_mmx ( ) requires that the
* output arrays have a buffer of up to 3 zeroes in front
* ( at negative indices ) for alignment purposes ; we use 4
* to keep the data well - aligned .
*/
2002-07-31 06:58:16 +00:00
if ( 0 ! = decoder - > private_ - > output [ i ] ) {
2001-08-16 20:07:29 +00:00
free ( decoder - > private_ - > output [ i ] - 4 ) ;
decoder - > private_ - > output [ i ] = 0 ;
2001-04-05 21:32:54 +00:00
}
2004-07-27 01:13:16 +00:00
if ( 0 ! = decoder - > private_ - > residual_unaligned [ i ] ) {
free ( decoder - > private_ - > residual_unaligned [ i ] ) ;
decoder - > private_ - > residual_unaligned [ i ] = decoder - > private_ - > residual [ i ] = 0 ;
2000-12-10 04:09:52 +00:00
}
}
2001-08-16 20:07:29 +00:00
decoder - > private_ - > output_capacity = 0 ;
decoder - > private_ - > output_channels = 0 ;
2002-06-04 05:53:04 +00:00
2006-09-16 00:08:45 +00:00
if ( 0 ! = decoder - > private_ - > file ) {
if ( decoder - > private_ - > file ! = stdin )
fclose ( decoder - > private_ - > file ) ;
2006-09-13 01:42:27 +00:00
decoder - > private_ - > file = 0 ;
}
2002-06-04 05:53:04 +00:00
2006-09-13 01:42:27 +00:00
if ( decoder - > private_ - > do_md5_checking ) {
if ( memcmp ( decoder - > private_ - > stream_info . data . stream_info . md5sum , decoder - > private_ - > computed_md5sum , 16 ) )
md5_failed = true ;
}
decoder - > private_ - > is_seeking = false ;
2001-06-16 07:32:25 +00:00
2006-09-13 01:42:27 +00:00
set_defaults_ ( decoder ) ;
2001-06-16 07:32:25 +00:00
2006-09-13 01:42:27 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_UNINITIALIZED ;
2001-06-16 07:32:25 +00:00
2006-09-13 01:42:27 +00:00
return ! md5_failed ;
2001-06-16 07:32:25 +00:00
}
2006-09-13 01:42:27 +00:00
FLAC_API FLAC__bool FLAC__stream_decoder_set_md5_checking ( FLAC__StreamDecoder * decoder , FLAC__bool value )
2001-06-16 07:32:25 +00:00
{
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
2001-08-16 20:07:29 +00:00
if ( decoder - > protected_ - > state ! = FLAC__STREAM_DECODER_UNINITIALIZED )
2001-06-16 07:32:25 +00:00
return false ;
2006-09-13 01:42:27 +00:00
decoder - > protected_ - > md5_checking = value ;
2001-06-16 07:32:25 +00:00
return true ;
}
2002-10-16 22:29:47 +00:00
FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond ( FLAC__StreamDecoder * decoder , FLAC__MetadataType type )
2002-05-07 05:30:27 +00:00
{
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = decoder - > private_ ) ;
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
2004-07-22 01:32:00 +00:00
FLAC__ASSERT ( ( unsigned ) type < = FLAC__MAX_METADATA_TYPE_CODE ) ;
2003-01-10 05:37:13 +00:00
/* double protection */
2004-07-22 01:32:00 +00:00
if ( ( unsigned ) type > FLAC__MAX_METADATA_TYPE_CODE )
2003-01-10 05:37:13 +00:00
return false ;
2002-05-07 05:30:27 +00:00
if ( decoder - > protected_ - > state ! = FLAC__STREAM_DECODER_UNINITIALIZED )
return false ;
decoder - > private_ - > metadata_filter [ type ] = true ;
if ( type = = FLAC__METADATA_TYPE_APPLICATION )
decoder - > private_ - > metadata_filter_ids_count = 0 ;
return true ;
}
2002-10-16 22:29:47 +00:00
FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application ( FLAC__StreamDecoder * decoder , const FLAC__byte id [ 4 ] )
2002-05-07 05:30:27 +00:00
{
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = decoder - > private_ ) ;
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
FLAC__ASSERT ( 0 ! = id ) ;
2002-05-07 05:30:27 +00:00
if ( decoder - > protected_ - > state ! = FLAC__STREAM_DECODER_UNINITIALIZED )
return false ;
if ( decoder - > private_ - > metadata_filter [ FLAC__METADATA_TYPE_APPLICATION ] )
return true ;
FLAC__ASSERT ( 0 ! = decoder - > private_ - > metadata_filter_ids ) ;
if ( decoder - > private_ - > metadata_filter_ids_count = = decoder - > private_ - > metadata_filter_ids_capacity ) {
2005-09-03 01:41:11 +00:00
if ( 0 = = ( decoder - > private_ - > metadata_filter_ids = ( FLAC__byte * ) realloc ( decoder - > private_ - > metadata_filter_ids , decoder - > private_ - > metadata_filter_ids_capacity * 2 ) ) ) {
decoder - > protected_ - > state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR ;
return false ;
}
2002-05-07 05:30:27 +00:00
decoder - > private_ - > metadata_filter_ids_capacity * = 2 ;
}
memcpy ( decoder - > private_ - > metadata_filter_ids + decoder - > private_ - > metadata_filter_ids_count * ( FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8 ) , id , ( FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8 ) ) ;
decoder - > private_ - > metadata_filter_ids_count + + ;
return true ;
}
2002-10-16 22:29:47 +00:00
FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_all ( FLAC__StreamDecoder * decoder )
2002-05-07 05:30:27 +00:00
{
2002-06-04 05:53:04 +00:00
unsigned i ;
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = decoder - > private_ ) ;
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
2002-05-07 05:30:27 +00:00
if ( decoder - > protected_ - > state ! = FLAC__STREAM_DECODER_UNINITIALIZED )
return false ;
2002-06-04 05:53:04 +00:00
for ( i = 0 ; i < sizeof ( decoder - > private_ - > metadata_filter ) / sizeof ( decoder - > private_ - > metadata_filter [ 0 ] ) ; i + + )
decoder - > private_ - > metadata_filter [ i ] = true ;
2002-05-07 05:30:27 +00:00
decoder - > private_ - > metadata_filter_ids_count = 0 ;
return true ;
}
2002-10-16 22:29:47 +00:00
FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore ( FLAC__StreamDecoder * decoder , FLAC__MetadataType type )
2002-05-07 05:30:27 +00:00
{
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = decoder - > private_ ) ;
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
2004-07-22 01:32:00 +00:00
FLAC__ASSERT ( ( unsigned ) type < = FLAC__MAX_METADATA_TYPE_CODE ) ;
2003-01-10 05:37:13 +00:00
/* double protection */
2004-07-22 01:32:00 +00:00
if ( ( unsigned ) type > FLAC__MAX_METADATA_TYPE_CODE )
2003-01-10 05:37:13 +00:00
return false ;
2002-05-07 05:30:27 +00:00
if ( decoder - > protected_ - > state ! = FLAC__STREAM_DECODER_UNINITIALIZED )
return false ;
decoder - > private_ - > metadata_filter [ type ] = false ;
if ( type = = FLAC__METADATA_TYPE_APPLICATION )
decoder - > private_ - > metadata_filter_ids_count = 0 ;
return true ;
}
2002-10-16 22:29:47 +00:00
FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application ( FLAC__StreamDecoder * decoder , const FLAC__byte id [ 4 ] )
2002-05-07 05:30:27 +00:00
{
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = decoder - > private_ ) ;
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
FLAC__ASSERT ( 0 ! = id ) ;
2002-05-07 05:30:27 +00:00
if ( decoder - > protected_ - > state ! = FLAC__STREAM_DECODER_UNINITIALIZED )
return false ;
if ( ! decoder - > private_ - > metadata_filter [ FLAC__METADATA_TYPE_APPLICATION ] )
return true ;
FLAC__ASSERT ( 0 ! = decoder - > private_ - > metadata_filter_ids ) ;
if ( decoder - > private_ - > metadata_filter_ids_count = = decoder - > private_ - > metadata_filter_ids_capacity ) {
2005-09-03 01:41:11 +00:00
if ( 0 = = ( decoder - > private_ - > metadata_filter_ids = ( FLAC__byte * ) realloc ( decoder - > private_ - > metadata_filter_ids , decoder - > private_ - > metadata_filter_ids_capacity * 2 ) ) ) {
decoder - > protected_ - > state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR ;
return false ;
}
2002-05-07 05:30:27 +00:00
decoder - > private_ - > metadata_filter_ids_capacity * = 2 ;
}
memcpy ( decoder - > private_ - > metadata_filter_ids + decoder - > private_ - > metadata_filter_ids_count * ( FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8 ) , id , ( FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8 ) ) ;
decoder - > private_ - > metadata_filter_ids_count + + ;
return true ;
}
2002-10-16 22:29:47 +00:00
FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_all ( FLAC__StreamDecoder * decoder )
2002-05-07 05:30:27 +00:00
{
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = decoder - > private_ ) ;
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
2002-05-07 05:30:27 +00:00
if ( decoder - > protected_ - > state ! = FLAC__STREAM_DECODER_UNINITIALIZED )
return false ;
memset ( decoder - > private_ - > metadata_filter , 0 , sizeof ( decoder - > private_ - > metadata_filter ) ) ;
decoder - > private_ - > metadata_filter_ids_count = 0 ;
return true ;
}
2002-10-16 22:29:47 +00:00
FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_get_state ( const FLAC__StreamDecoder * decoder )
2001-06-13 17:59:57 +00:00
{
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
2001-08-16 20:07:29 +00:00
return decoder - > protected_ - > state ;
2001-06-13 17:59:57 +00:00
}
2003-09-24 22:08:00 +00:00
FLAC_API const char * FLAC__stream_decoder_get_resolved_state_string ( const FLAC__StreamDecoder * decoder )
{
return FLAC__StreamDecoderStateString [ decoder - > protected_ - > state ] ;
}
2006-09-13 01:42:27 +00:00
FLAC_API FLAC__bool FLAC__stream_decoder_get_md5_checking ( const FLAC__StreamDecoder * decoder )
{
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
return decoder - > protected_ - > md5_checking ;
}
FLAC_API FLAC__uint64 FLAC__stream_decoder_get_total_samples ( const FLAC__StreamDecoder * decoder )
{
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
return decoder - > private_ - > has_stream_info ? decoder - > private_ - > stream_info . data . stream_info . total_samples : 0 ;
}
2002-10-16 22:29:47 +00:00
FLAC_API unsigned FLAC__stream_decoder_get_channels ( const FLAC__StreamDecoder * decoder )
2001-06-13 17:59:57 +00:00
{
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
2001-08-16 20:07:29 +00:00
return decoder - > protected_ - > channels ;
2001-06-13 17:59:57 +00:00
}
2002-10-16 22:29:47 +00:00
FLAC_API FLAC__ChannelAssignment FLAC__stream_decoder_get_channel_assignment ( const FLAC__StreamDecoder * decoder )
2001-06-13 17:59:57 +00:00
{
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
2001-08-16 20:07:29 +00:00
return decoder - > protected_ - > channel_assignment ;
2001-06-13 17:59:57 +00:00
}
2002-10-16 22:29:47 +00:00
FLAC_API unsigned FLAC__stream_decoder_get_bits_per_sample ( const FLAC__StreamDecoder * decoder )
2001-06-13 17:59:57 +00:00
{
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
2001-08-16 20:07:29 +00:00
return decoder - > protected_ - > bits_per_sample ;
2001-06-13 17:59:57 +00:00
}
2002-10-16 22:29:47 +00:00
FLAC_API unsigned FLAC__stream_decoder_get_sample_rate ( const FLAC__StreamDecoder * decoder )
2001-06-13 17:59:57 +00:00
{
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
2001-08-16 20:07:29 +00:00
return decoder - > protected_ - > sample_rate ;
2001-06-13 17:59:57 +00:00
}
2002-10-16 22:29:47 +00:00
FLAC_API unsigned FLAC__stream_decoder_get_blocksize ( const FLAC__StreamDecoder * decoder )
2001-06-13 17:59:57 +00:00
{
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
2001-08-16 20:07:29 +00:00
return decoder - > protected_ - > blocksize ;
2000-12-10 04:09:52 +00:00
}
2006-09-13 01:42:27 +00:00
FLAC_API FLAC__bool FLAC__stream_decoder_get_decode_position ( const FLAC__StreamDecoder * decoder , FLAC__uint64 * position )
{
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = decoder - > private_ ) ;
FLAC__ASSERT ( 0 ! = position ) ;
if ( 0 = = decoder - > private_ - > tell_callback )
return false ;
if ( decoder - > private_ - > tell_callback ( decoder , position , decoder - > private_ - > client_data ) ! = FLAC__STREAM_DECODER_TELL_STATUS_OK )
return false ;
FLAC__ASSERT ( * position > = FLAC__stream_decoder_get_input_bytes_unconsumed ( decoder ) ) ;
* position - = FLAC__stream_decoder_get_input_bytes_unconsumed ( decoder ) ;
return true ;
}
2002-10-16 22:29:47 +00:00
FLAC_API FLAC__bool FLAC__stream_decoder_flush ( FLAC__StreamDecoder * decoder )
2000-12-10 04:09:52 +00:00
{
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = decoder - > private_ ) ;
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
2000-12-10 04:09:52 +00:00
2006-09-13 01:42:27 +00:00
decoder - > private_ - > samples_decoded = 0 ;
decoder - > private_ - > do_md5_checking = false ;
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_clear ( decoder - > private_ - > input ) ) {
2001-08-16 20:07:29 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR ;
2000-12-10 04:09:52 +00:00
return false ;
}
2005-01-24 00:20:49 +00:00
decoder - > private_ - > last_frame_number = 0 ;
decoder - > private_ - > last_block_size = 0 ;
2001-11-01 05:23:48 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ;
2000-12-10 04:09:52 +00:00
return true ;
}
2002-10-16 22:29:47 +00:00
FLAC_API FLAC__bool FLAC__stream_decoder_reset ( FLAC__StreamDecoder * decoder )
2000-12-10 04:09:52 +00:00
{
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = decoder - > private_ ) ;
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
2000-12-10 04:09:52 +00:00
if ( ! FLAC__stream_decoder_flush ( decoder ) ) {
2006-09-13 01:42:27 +00:00
/* above call sets the state for us */
2000-12-10 04:09:52 +00:00
return false ;
}
2006-09-13 01:42:27 +00:00
/* Rewind if necessary. If FLAC__stream_decoder_init() is calling us,
* ( internal_reset_hack ) don ' t try to rewind since we are already at
* the beginning of the stream and don ' t want to fail if the input is
* not seekable .
*/
if ( ! decoder - > private_ - > internal_reset_hack ) {
if ( decoder - > private_ - > file = = stdin )
return false ; /* can't rewind stdin, reset fails */
if ( decoder - > private_ - > seek_callback & & decoder - > private_ - > seek_callback ( decoder , 0 , decoder - > private_ - > client_data ) = = FLAC__STREAM_DECODER_SEEK_STATUS_ERROR )
return false ; /* seekable and seek fails, reset fails */
}
else
decoder - > private_ - > internal_reset_hack = false ;
2001-08-16 20:07:29 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEARCH_FOR_METADATA ;
2000-12-10 04:09:52 +00:00
2006-09-13 01:42:27 +00:00
decoder - > private_ - > has_stream_info = false ;
if ( decoder - > private_ - > has_seek_table & & 0 ! = decoder - > private_ - > seek_table . data . seek_table . points ) {
free ( decoder - > private_ - > seek_table . data . seek_table . points ) ;
decoder - > private_ - > seek_table . data . seek_table . points = 0 ;
decoder - > private_ - > has_seek_table = false ;
}
decoder - > private_ - > do_md5_checking = decoder - > protected_ - > md5_checking ;
/* We initialize the FLAC__MD5Context even though we may never use it. This
* is because md5 checking may be turned on to start and then turned off if
* a seek occurs . So we init the context here and finalize it in
* FLAC__seekable_stream_decoder_finish ( ) to make sure things are always
* cleaned up properly .
*/
FLAC__MD5Init ( & decoder - > private_ - > md5context ) ;
decoder - > private_ - > first_frame_offset = 0 ;
decoder - > private_ - > unparseable_frame_count = 0 ;
2001-04-17 17:32:01 +00:00
2000-12-10 04:09:52 +00:00
return true ;
}
2002-10-16 22:29:47 +00:00
FLAC_API FLAC__bool FLAC__stream_decoder_process_single ( FLAC__StreamDecoder * decoder )
2000-12-10 04:09:52 +00:00
{
2002-08-02 06:12:36 +00:00
FLAC__bool got_a_frame ;
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
2002-08-02 06:12:36 +00:00
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
2000-12-10 04:09:52 +00:00
while ( 1 ) {
2001-08-16 20:07:29 +00:00
switch ( decoder - > protected_ - > state ) {
2000-12-10 04:09:52 +00:00
case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA :
2002-07-31 06:58:16 +00:00
if ( ! find_metadata_ ( decoder ) )
2000-12-10 04:09:52 +00:00
return false ; /* above function sets the status for us */
break ;
case FLAC__STREAM_DECODER_READ_METADATA :
2002-07-31 06:58:16 +00:00
if ( ! read_metadata_ ( decoder ) )
2000-12-10 04:09:52 +00:00
return false ; /* above function sets the status for us */
2002-08-02 06:12:36 +00:00
else
return true ;
2000-12-10 04:09:52 +00:00
case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC :
2002-07-31 06:58:16 +00:00
if ( ! frame_sync_ ( decoder ) )
2000-12-10 04:09:52 +00:00
return true ; /* above function sets the status for us */
break ;
case FLAC__STREAM_DECODER_READ_FRAME :
2004-07-16 00:53:38 +00:00
if ( ! read_frame_ ( decoder , & got_a_frame , /*do_full_decode=*/ true ) )
2000-12-10 04:09:52 +00:00
return false ; /* above function sets the status for us */
2002-08-02 06:12:36 +00:00
if ( got_a_frame )
return true ; /* above function sets the status for us */
2000-12-10 04:09:52 +00:00
break ;
case FLAC__STREAM_DECODER_END_OF_STREAM :
2002-07-24 06:08:37 +00:00
case FLAC__STREAM_DECODER_ABORTED :
2000-12-10 04:09:52 +00:00
return true ;
default :
2001-05-31 20:11:02 +00:00
FLAC__ASSERT ( 0 ) ;
2002-08-02 06:12:36 +00:00
return false ;
2000-12-10 04:09:52 +00:00
}
}
}
2002-10-16 22:29:47 +00:00
FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata ( FLAC__StreamDecoder * decoder )
2000-12-10 04:09:52 +00:00
{
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
2002-08-02 06:12:36 +00:00
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
2000-12-10 04:09:52 +00:00
while ( 1 ) {
2001-08-16 20:07:29 +00:00
switch ( decoder - > protected_ - > state ) {
2000-12-10 04:09:52 +00:00
case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA :
2002-07-31 06:58:16 +00:00
if ( ! find_metadata_ ( decoder ) )
2000-12-10 04:09:52 +00:00
return false ; /* above function sets the status for us */
break ;
case FLAC__STREAM_DECODER_READ_METADATA :
2002-07-31 06:58:16 +00:00
if ( ! read_metadata_ ( decoder ) )
2000-12-10 04:09:52 +00:00
return false ; /* above function sets the status for us */
break ;
case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC :
2001-11-01 19:47:06 +00:00
case FLAC__STREAM_DECODER_READ_FRAME :
2000-12-10 04:09:52 +00:00
case FLAC__STREAM_DECODER_END_OF_STREAM :
2002-07-24 06:08:37 +00:00
case FLAC__STREAM_DECODER_ABORTED :
2000-12-10 04:09:52 +00:00
return true ;
default :
2001-05-31 20:11:02 +00:00
FLAC__ASSERT ( 0 ) ;
2002-08-02 06:12:36 +00:00
return false ;
2000-12-10 04:09:52 +00:00
}
}
}
2002-10-16 22:29:47 +00:00
FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_stream ( FLAC__StreamDecoder * decoder )
2000-12-10 04:09:52 +00:00
{
2002-08-02 06:12:36 +00:00
FLAC__bool dummy ;
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
2002-08-02 06:12:36 +00:00
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
2000-12-10 04:09:52 +00:00
while ( 1 ) {
2001-08-16 20:07:29 +00:00
switch ( decoder - > protected_ - > state ) {
2002-08-02 06:12:36 +00:00
case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA :
if ( ! find_metadata_ ( decoder ) )
return false ; /* above function sets the status for us */
2000-12-10 04:09:52 +00:00
break ;
2002-08-02 06:12:36 +00:00
case FLAC__STREAM_DECODER_READ_METADATA :
if ( ! read_metadata_ ( decoder ) )
2000-12-10 04:09:52 +00:00
return false ; /* above function sets the status for us */
break ;
case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC :
2002-07-31 06:58:16 +00:00
if ( ! frame_sync_ ( decoder ) )
2000-12-10 04:09:52 +00:00
return true ; /* above function sets the status for us */
break ;
case FLAC__STREAM_DECODER_READ_FRAME :
2004-07-16 00:53:38 +00:00
if ( ! read_frame_ ( decoder , & dummy , /*do_full_decode=*/ true ) )
2000-12-10 04:09:52 +00:00
return false ; /* above function sets the status for us */
break ;
case FLAC__STREAM_DECODER_END_OF_STREAM :
2002-07-24 06:08:37 +00:00
case FLAC__STREAM_DECODER_ABORTED :
2000-12-10 04:09:52 +00:00
return true ;
default :
2001-05-31 20:11:02 +00:00
FLAC__ASSERT ( 0 ) ;
2002-08-02 06:12:36 +00:00
return false ;
2000-12-10 04:09:52 +00:00
}
}
}
2004-07-16 00:53:38 +00:00
FLAC_API FLAC__bool FLAC__stream_decoder_skip_single_frame ( FLAC__StreamDecoder * decoder )
{
FLAC__bool got_a_frame ;
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = decoder - > protected_ ) ;
while ( 1 ) {
switch ( decoder - > protected_ - > state ) {
case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA :
case FLAC__STREAM_DECODER_READ_METADATA :
return false ; /* above function sets the status for us */
case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC :
if ( ! frame_sync_ ( decoder ) )
return true ; /* above function sets the status for us */
break ;
case FLAC__STREAM_DECODER_READ_FRAME :
if ( ! read_frame_ ( decoder , & got_a_frame , /*do_full_decode=*/ false ) )
return false ; /* above function sets the status for us */
if ( got_a_frame )
return true ; /* above function sets the status for us */
break ;
case FLAC__STREAM_DECODER_END_OF_STREAM :
case FLAC__STREAM_DECODER_ABORTED :
return true ;
default :
FLAC__ASSERT ( 0 ) ;
return false ;
}
}
}
2006-09-13 01:42:27 +00:00
FLAC_API FLAC__bool FLAC__stream_decoder_seek_absolute ( FLAC__StreamDecoder * decoder , FLAC__uint64 sample )
{
FLAC__uint64 length ;
FLAC__ASSERT ( 0 ! = decoder ) ;
if (
decoder - > protected_ - > state ! = FLAC__STREAM_DECODER_SEARCH_FOR_METADATA & &
decoder - > protected_ - > state ! = FLAC__STREAM_DECODER_READ_METADATA & &
decoder - > protected_ - > state ! = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC & &
decoder - > protected_ - > state ! = FLAC__STREAM_DECODER_READ_FRAME & &
decoder - > protected_ - > state ! = FLAC__STREAM_DECODER_END_OF_STREAM
)
return false ;
if ( 0 = = decoder - > private_ - > seek_callback )
return false ;
FLAC__ASSERT ( decoder - > private_ - > seek_callback ) ;
FLAC__ASSERT ( decoder - > private_ - > tell_callback ) ;
FLAC__ASSERT ( decoder - > private_ - > length_callback ) ;
FLAC__ASSERT ( decoder - > private_ - > eof_callback ) ;
if ( FLAC__stream_decoder_get_total_samples ( decoder ) > 0 & & sample > = FLAC__stream_decoder_get_total_samples ( decoder ) )
return false ;
decoder - > private_ - > is_seeking = true ;
/* turn off md5 checking if a seek is attempted */
decoder - > private_ - > do_md5_checking = false ;
/* get the file length (currently our algorithm needs to know the length so it's also an error to get FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED) */
if ( decoder - > private_ - > length_callback ( decoder , & length , decoder - > private_ - > client_data ) ! = FLAC__STREAM_DECODER_LENGTH_STATUS_OK ) {
decoder - > private_ - > is_seeking = false ;
return false ;
}
/* if we haven't finished processing the metadata yet, do that so we have the STREAMINFO, SEEK_TABLE, and first_frame_offset */
if (
decoder - > protected_ - > state = = FLAC__STREAM_DECODER_SEARCH_FOR_METADATA | |
decoder - > protected_ - > state = = FLAC__STREAM_DECODER_READ_METADATA
) {
if ( ! FLAC__stream_decoder_process_until_end_of_metadata ( decoder ) ) {
/* above call sets the state for us */
decoder - > private_ - > is_seeking = false ;
return false ;
}
/* check this again in case we didn't know total_samples the first time */
if ( FLAC__stream_decoder_get_total_samples ( decoder ) > 0 & & sample > = FLAC__stream_decoder_get_total_samples ( decoder ) ) {
decoder - > private_ - > is_seeking = false ;
return false ;
}
}
{
FLAC__bool ok = seek_to_absolute_sample_ ( decoder , length , sample ) ;
decoder - > private_ - > is_seeking = false ;
return ok ;
}
}
2001-06-13 17:59:57 +00:00
/***********************************************************************
*
* Protected class methods
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-06-16 07:32:25 +00:00
unsigned FLAC__stream_decoder_get_input_bytes_unconsumed ( const FLAC__StreamDecoder * decoder )
2000-12-10 04:09:52 +00:00
{
2002-07-31 06:58:16 +00:00
FLAC__ASSERT ( 0 ! = decoder ) ;
2002-03-12 16:19:54 +00:00
return FLAC__bitbuffer_get_input_bytes_unconsumed ( decoder - > private_ - > input ) ;
2000-12-10 04:09:52 +00:00
}
2001-06-13 17:59:57 +00:00
/***********************************************************************
*
* Private class methods
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-31 06:58:16 +00:00
void set_defaults_ ( FLAC__StreamDecoder * decoder )
2002-06-04 05:53:04 +00:00
{
decoder - > private_ - > read_callback = 0 ;
2006-09-13 01:42:27 +00:00
decoder - > private_ - > seek_callback = 0 ;
decoder - > private_ - > tell_callback = 0 ;
decoder - > private_ - > length_callback = 0 ;
decoder - > private_ - > eof_callback = 0 ;
2002-06-04 05:53:04 +00:00
decoder - > private_ - > write_callback = 0 ;
decoder - > private_ - > metadata_callback = 0 ;
decoder - > private_ - > error_callback = 0 ;
decoder - > private_ - > client_data = 0 ;
memset ( decoder - > private_ - > metadata_filter , 0 , sizeof ( decoder - > private_ - > metadata_filter ) ) ;
decoder - > private_ - > metadata_filter [ FLAC__METADATA_TYPE_STREAMINFO ] = true ;
decoder - > private_ - > metadata_filter_ids_count = 0 ;
2006-09-13 01:42:27 +00:00
decoder - > protected_ - > md5_checking = false ;
}
/*
* This will forcibly set stdin to binary mode ( for OSes that require it )
*/
FILE * get_binary_stdin_ ( )
{
/* if something breaks here it is probably due to the presence or
* absence of an underscore before the identifiers ' setmode ' ,
* ' fileno ' , and / or ' O_BINARY ' ; check your system header files .
*/
# if defined _MSC_VER || defined __MINGW32__
_setmode ( _fileno ( stdin ) , _O_BINARY ) ;
# elif defined __CYGWIN__ || defined __EMX__
/* almost certainly not needed for any modern Cygwin, but let's be safe... */
setmode ( _fileno ( stdin ) , _O_BINARY ) ;
# endif
return stdin ;
2002-06-04 05:53:04 +00:00
}
2002-07-31 06:58:16 +00:00
FLAC__bool allocate_output_ ( FLAC__StreamDecoder * decoder , unsigned size , unsigned channels )
2000-12-10 04:09:52 +00:00
{
unsigned i ;
2001-06-23 03:03:24 +00:00
FLAC__int32 * tmp ;
2000-12-10 04:09:52 +00:00
2001-08-16 20:07:29 +00:00
if ( size < = decoder - > private_ - > output_capacity & & channels < = decoder - > private_ - > output_channels )
2000-12-10 04:09:52 +00:00
return true ;
2002-09-04 07:59:02 +00:00
/* simply using realloc() is not practical because the number of channels may change mid-stream */
2001-01-23 23:07:36 +00:00
2000-12-10 04:09:52 +00:00
for ( i = 0 ; i < FLAC__MAX_CHANNELS ; i + + ) {
2002-07-31 06:58:16 +00:00
if ( 0 ! = decoder - > private_ - > output [ i ] ) {
2002-10-21 06:43:48 +00:00
free ( decoder - > private_ - > output [ i ] - 4 ) ;
2001-08-16 20:07:29 +00:00
decoder - > private_ - > output [ i ] = 0 ;
2000-12-10 04:09:52 +00:00
}
2004-07-27 01:13:16 +00:00
if ( 0 ! = decoder - > private_ - > residual_unaligned [ i ] ) {
free ( decoder - > private_ - > residual_unaligned [ i ] ) ;
decoder - > private_ - > residual_unaligned [ i ] = decoder - > private_ - > residual [ i ] = 0 ;
2001-01-23 23:07:36 +00:00
}
2000-12-10 04:09:52 +00:00
}
2001-03-23 20:20:43 +00:00
for ( i = 0 ; i < channels ; i + + ) {
2002-08-17 15:23:43 +00:00
/* WATCHOUT:
* FLAC__lpc_restore_signal_asm_ia32_mmx ( ) requires that the
* output arrays have a buffer of up to 3 zeroes in front
* ( at negative indices ) for alignment purposes ; we use 4
* to keep the data well - aligned .
*/
2001-07-12 21:26:57 +00:00
tmp = ( FLAC__int32 * ) malloc ( sizeof ( FLAC__int32 ) * ( size + 4 ) ) ;
2000-12-10 04:09:52 +00:00
if ( tmp = = 0 ) {
2001-08-16 20:07:29 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR ;
2000-12-10 04:09:52 +00:00
return false ;
}
2001-07-12 21:26:57 +00:00
memset ( tmp , 0 , sizeof ( FLAC__int32 ) * 4 ) ;
2001-08-16 20:07:29 +00:00
decoder - > private_ - > output [ i ] = tmp + 4 ;
2001-01-23 23:07:36 +00:00
2004-07-27 01:13:16 +00:00
/* WATCHOUT:
* minimum of quadword alignment for PPC vector optimizations is REQUIRED :
*/
if ( ! FLAC__memory_alloc_aligned_int32_array ( size , & decoder - > private_ - > residual_unaligned [ i ] , & decoder - > private_ - > residual [ i ] ) ) {
2001-08-16 20:07:29 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR ;
2001-01-23 23:07:36 +00:00
return false ;
}
2000-12-10 04:09:52 +00:00
}
2001-08-16 20:07:29 +00:00
decoder - > private_ - > output_capacity = size ;
decoder - > private_ - > output_channels = channels ;
2000-12-10 04:09:52 +00:00
return true ;
}
2002-07-31 06:58:16 +00:00
FLAC__bool has_id_filtered_ ( FLAC__StreamDecoder * decoder , FLAC__byte * id )
2002-05-07 05:30:27 +00:00
{
unsigned i ;
FLAC__ASSERT ( 0 ! = decoder ) ;
FLAC__ASSERT ( 0 ! = decoder - > private_ ) ;
for ( i = 0 ; i < decoder - > private_ - > metadata_filter_ids_count ; i + + )
if ( 0 = = memcmp ( decoder - > private_ - > metadata_filter_ids + i * ( FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8 ) , id , ( FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8 ) ) )
return true ;
return false ;
}
2002-07-31 06:58:16 +00:00
FLAC__bool find_metadata_ ( FLAC__StreamDecoder * decoder )
2000-12-10 04:09:52 +00:00
{
2001-06-23 03:03:24 +00:00
FLAC__uint32 x ;
2000-12-10 04:09:52 +00:00
unsigned i , id ;
2001-06-23 03:03:24 +00:00
FLAC__bool first = true ;
2000-12-10 04:09:52 +00:00
2002-03-12 16:19:54 +00:00
FLAC__ASSERT ( FLAC__bitbuffer_is_consumed_byte_aligned ( decoder - > private_ - > input ) ) ;
2000-12-10 04:09:52 +00:00
for ( i = id = 0 ; i < 4 ; ) {
2001-08-16 20:07:29 +00:00
if ( decoder - > private_ - > cached ) {
x = ( FLAC__uint32 ) decoder - > private_ - > lookahead ;
decoder - > private_ - > cached = false ;
2001-03-27 01:15:58 +00:00
}
else {
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , 8 , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-03-27 01:15:58 +00:00
}
2000-12-10 04:09:52 +00:00
if ( x = = FLAC__STREAM_SYNC_STRING [ i ] ) {
2001-03-27 01:15:58 +00:00
first = true ;
2000-12-10 04:09:52 +00:00
i + + ;
id = 0 ;
continue ;
}
if ( x = = ID3V2_TAG_ [ id ] ) {
id + + ;
i = 0 ;
if ( id = = 3 ) {
2002-07-31 06:58:16 +00:00
if ( ! skip_id3v2_tag_ ( decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* skip_id3v2_tag_ sets the state for us */
2000-12-10 04:09:52 +00:00
}
continue ;
}
2006-10-06 06:21:41 +00:00
id = 0 ;
2000-12-10 04:09:52 +00:00
if ( x = = 0xff ) { /* MAGIC NUMBER for the first 8 frame sync bits */
2001-08-16 20:07:29 +00:00
decoder - > private_ - > header_warmup [ 0 ] = ( FLAC__byte ) x ;
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , 8 , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-03-27 01:15:58 +00:00
/* we have to check if we just read two 0xff's in a row; the second may actually be the beginning of the sync code */
/* else we have to check if the second byte is the end of a sync code */
if ( x = = 0xff ) { /* MAGIC NUMBER for the first 8 frame sync bits */
2001-08-16 20:07:29 +00:00
decoder - > private_ - > lookahead = ( FLAC__byte ) x ;
decoder - > private_ - > cached = true ;
2001-03-27 01:15:58 +00:00
}
else if ( x > > 2 = = 0x3e ) { /* MAGIC NUMBER for the last 6 sync bits */
2001-08-16 20:07:29 +00:00
decoder - > private_ - > header_warmup [ 1 ] = ( FLAC__byte ) x ;
decoder - > protected_ - > state = FLAC__STREAM_DECODER_READ_FRAME ;
2000-12-10 04:09:52 +00:00
return true ;
}
}
i = 0 ;
if ( first ) {
2006-09-13 01:42:27 +00:00
send_error_to_client_ ( decoder , FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC ) ;
2001-03-27 01:15:58 +00:00
first = false ;
2000-12-10 04:09:52 +00:00
}
}
2001-08-16 20:07:29 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_READ_METADATA ;
2000-12-10 04:09:52 +00:00
return true ;
}
2002-07-31 06:58:16 +00:00
FLAC__bool read_metadata_ ( FLAC__StreamDecoder * decoder )
2000-12-10 04:09:52 +00:00
{
2002-11-14 04:58:42 +00:00
FLAC__bool is_last ;
FLAC__uint32 i , x , type , length ;
2000-12-10 04:09:52 +00:00
2002-03-12 16:19:54 +00:00
FLAC__ASSERT ( FLAC__bitbuffer_is_consumed_byte_aligned ( decoder - > private_ - > input ) ) ;
2000-12-10 04:09:52 +00:00
2002-11-14 04:58:42 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , FLAC__STREAM_METADATA_IS_LAST_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-14 04:58:42 +00:00
is_last = x ? true : false ;
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & type , FLAC__STREAM_METADATA_TYPE_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-14 04:58:42 +00:00
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & length , FLAC__STREAM_METADATA_LENGTH_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-01-12 23:55:11 +00:00
2002-11-14 04:58:42 +00:00
if ( type = = FLAC__METADATA_TYPE_STREAMINFO ) {
if ( ! read_metadata_streaminfo_ ( decoder , is_last , length ) )
return false ;
2001-01-03 00:26:42 +00:00
2001-08-16 20:07:29 +00:00
decoder - > private_ - > has_stream_info = true ;
2006-09-13 01:42:27 +00:00
if ( 0 = = memcmp ( decoder - > private_ - > stream_info . data . stream_info . md5sum , " \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 " , 16 ) )
decoder - > private_ - > do_md5_checking = false ;
if ( ! decoder - > private_ - > is_seeking & & decoder - > private_ - > metadata_filter [ FLAC__METADATA_TYPE_STREAMINFO ] & & decoder - > private_ - > metadata_callback )
2002-05-07 05:30:27 +00:00
decoder - > private_ - > metadata_callback ( decoder , & decoder - > private_ - > stream_info , decoder - > private_ - > client_data ) ;
2001-04-05 21:32:54 +00:00
}
else if ( type = = FLAC__METADATA_TYPE_SEEKTABLE ) {
2002-11-14 04:58:42 +00:00
if ( ! read_metadata_seektable_ ( decoder , is_last , length ) )
2001-04-05 21:32:54 +00:00
return false ;
2002-05-07 05:30:27 +00:00
2001-08-16 20:07:29 +00:00
decoder - > private_ - > has_seek_table = true ;
2006-09-13 01:42:27 +00:00
if ( ! decoder - > private_ - > is_seeking & & decoder - > private_ - > metadata_filter [ FLAC__METADATA_TYPE_SEEKTABLE ] & & decoder - > private_ - > metadata_callback )
2002-05-07 05:30:27 +00:00
decoder - > private_ - > metadata_callback ( decoder , & decoder - > private_ - > seek_table , decoder - > private_ - > client_data ) ;
2000-12-10 04:09:52 +00:00
}
else {
2002-05-07 05:30:27 +00:00
FLAC__bool skip_it = ! decoder - > private_ - > metadata_filter [ type ] ;
unsigned real_length = length ;
2002-06-08 04:53:42 +00:00
FLAC__StreamMetadata block ;
2002-05-07 05:30:27 +00:00
2002-11-14 04:58:42 +00:00
block . is_last = is_last ;
2002-11-06 07:11:26 +00:00
block . type = ( FLAC__MetadataType ) type ;
2002-05-07 05:30:27 +00:00
block . length = length ;
2002-05-09 05:41:35 +00:00
if ( type = = FLAC__METADATA_TYPE_APPLICATION ) {
2002-11-15 05:41:48 +00:00
if ( ! FLAC__bitbuffer_read_byte_block_aligned_no_crc ( decoder - > private_ - > input , block . data . application . id , FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8 , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-05-07 05:30:27 +00:00
real_length - = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8 ;
2002-07-31 06:58:16 +00:00
if ( decoder - > private_ - > metadata_filter_ids_count > 0 & & has_id_filtered_ ( decoder , block . data . application . id ) )
2002-05-07 05:30:27 +00:00
skip_it = ! skip_it ;
}
if ( skip_it ) {
2002-11-15 05:41:48 +00:00
if ( ! FLAC__bitbuffer_read_byte_block_aligned_no_crc ( decoder - > private_ - > input , 0 , real_length , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2000-12-10 04:09:52 +00:00
}
2002-05-07 05:30:27 +00:00
else {
switch ( type ) {
case FLAC__METADATA_TYPE_PADDING :
/* skip the padding bytes */
2002-11-15 05:41:48 +00:00
if ( ! FLAC__bitbuffer_read_byte_block_aligned_no_crc ( decoder - > private_ - > input , 0 , real_length , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-05-07 05:30:27 +00:00
break ;
case FLAC__METADATA_TYPE_APPLICATION :
/* remember, we read the ID already */
2002-05-31 06:24:03 +00:00
if ( real_length > 0 ) {
2002-11-06 07:11:26 +00:00
if ( 0 = = ( block . data . application . data = ( FLAC__byte * ) malloc ( real_length ) ) ) {
2002-05-31 06:24:03 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR ;
return false ;
}
2002-11-15 05:41:48 +00:00
if ( ! FLAC__bitbuffer_read_byte_block_aligned_no_crc ( decoder - > private_ - > input , block . data . application . data , real_length , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-05-07 05:30:27 +00:00
}
2002-05-31 06:24:03 +00:00
else
block . data . application . data = 0 ;
2002-05-07 05:30:27 +00:00
break ;
case FLAC__METADATA_TYPE_VORBIS_COMMENT :
2002-11-14 04:58:42 +00:00
if ( ! read_metadata_vorbiscomment_ ( decoder , & block . data . vorbis_comment ) )
return false ;
2002-05-07 05:30:27 +00:00
break ;
2002-11-15 05:41:48 +00:00
case FLAC__METADATA_TYPE_CUESHEET :
if ( ! read_metadata_cuesheet_ ( decoder , & block . data . cue_sheet ) )
return false ;
break ;
2006-09-23 19:21:19 +00:00
case FLAC__METADATA_TYPE_PICTURE :
if ( ! read_metadata_picture_ ( decoder , & block . data . picture ) )
return false ;
break ;
2002-05-07 05:30:27 +00:00
case FLAC__METADATA_TYPE_STREAMINFO :
case FLAC__METADATA_TYPE_SEEKTABLE :
2003-01-11 06:25:42 +00:00
FLAC__ASSERT ( 0 ) ;
2003-01-10 05:37:13 +00:00
break ;
2002-05-07 05:30:27 +00:00
default :
2003-01-10 05:37:13 +00:00
if ( real_length > 0 ) {
if ( 0 = = ( block . data . unknown . data = ( FLAC__byte * ) malloc ( real_length ) ) ) {
decoder - > protected_ - > state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR ;
return false ;
}
if ( ! FLAC__bitbuffer_read_byte_block_aligned_no_crc ( decoder - > private_ - > input , block . data . unknown . data , real_length , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2003-01-10 05:37:13 +00:00
}
else
block . data . unknown . data = 0 ;
break ;
2002-05-07 05:30:27 +00:00
}
2006-09-13 01:42:27 +00:00
if ( ! decoder - > private_ - > is_seeking & & decoder - > private_ - > metadata_callback )
decoder - > private_ - > metadata_callback ( decoder , & block , decoder - > private_ - > client_data ) ;
2002-05-07 05:30:27 +00:00
/* now we have to free any malloc'ed data in the block */
switch ( type ) {
case FLAC__METADATA_TYPE_PADDING :
break ;
case FLAC__METADATA_TYPE_APPLICATION :
if ( 0 ! = block . data . application . data )
free ( block . data . application . data ) ;
break ;
case FLAC__METADATA_TYPE_VORBIS_COMMENT :
if ( 0 ! = block . data . vorbis_comment . vendor_string . entry )
free ( block . data . vorbis_comment . vendor_string . entry ) ;
if ( block . data . vorbis_comment . num_comments > 0 )
for ( i = 0 ; i < block . data . vorbis_comment . num_comments ; i + + )
if ( 0 ! = block . data . vorbis_comment . comments [ i ] . entry )
free ( block . data . vorbis_comment . comments [ i ] . entry ) ;
if ( 0 ! = block . data . vorbis_comment . comments )
free ( block . data . vorbis_comment . comments ) ;
break ;
2002-11-15 05:41:48 +00:00
case FLAC__METADATA_TYPE_CUESHEET :
if ( block . data . cue_sheet . num_tracks > 0 )
for ( i = 0 ; i < block . data . cue_sheet . num_tracks ; i + + )
if ( 0 ! = block . data . cue_sheet . tracks [ i ] . indices )
free ( block . data . cue_sheet . tracks [ i ] . indices ) ;
if ( 0 ! = block . data . cue_sheet . tracks )
free ( block . data . cue_sheet . tracks ) ;
break ;
2006-09-23 19:21:19 +00:00
case FLAC__METADATA_TYPE_PICTURE :
if ( 0 ! = block . data . picture . mime_type )
free ( block . data . picture . mime_type ) ;
if ( 0 ! = block . data . picture . description )
free ( block . data . picture . description ) ;
if ( 0 ! = block . data . picture . data )
free ( block . data . picture . data ) ;
break ;
2002-05-07 05:30:27 +00:00
case FLAC__METADATA_TYPE_STREAMINFO :
case FLAC__METADATA_TYPE_SEEKTABLE :
FLAC__ASSERT ( 0 ) ;
2003-01-10 05:37:13 +00:00
default :
if ( 0 ! = block . data . unknown . data )
free ( block . data . unknown . data ) ;
break ;
2002-05-07 05:30:27 +00:00
}
}
2000-12-10 04:09:52 +00:00
}
2006-09-13 01:42:27 +00:00
if ( is_last ) {
/* if this fails, it's OK, it's just a hint for the seek routine */
if ( ! FLAC__stream_decoder_get_decode_position ( decoder , & decoder - > private_ - > first_frame_offset ) )
decoder - > private_ - > first_frame_offset = 0 ;
2001-08-16 20:07:29 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ;
2006-09-13 01:42:27 +00:00
}
2000-12-10 04:09:52 +00:00
return true ;
}
2002-11-14 04:58:42 +00:00
FLAC__bool read_metadata_streaminfo_ ( FLAC__StreamDecoder * decoder , FLAC__bool is_last , unsigned length )
{
FLAC__uint32 x ;
unsigned bits , used_bits = 0 ;
FLAC__ASSERT ( FLAC__bitbuffer_is_consumed_byte_aligned ( decoder - > private_ - > input ) ) ;
decoder - > private_ - > stream_info . type = FLAC__METADATA_TYPE_STREAMINFO ;
decoder - > private_ - > stream_info . is_last = is_last ;
decoder - > private_ - > stream_info . length = length ;
bits = FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN ;
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , bits , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-14 04:58:42 +00:00
decoder - > private_ - > stream_info . data . stream_info . min_blocksize = x ;
used_bits + = bits ;
bits = FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN ;
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-14 04:58:42 +00:00
decoder - > private_ - > stream_info . data . stream_info . max_blocksize = x ;
used_bits + = bits ;
bits = FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN ;
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-14 04:58:42 +00:00
decoder - > private_ - > stream_info . data . stream_info . min_framesize = x ;
used_bits + = bits ;
bits = FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN ;
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-14 04:58:42 +00:00
decoder - > private_ - > stream_info . data . stream_info . max_framesize = x ;
used_bits + = bits ;
bits = FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN ;
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-14 04:58:42 +00:00
decoder - > private_ - > stream_info . data . stream_info . sample_rate = x ;
used_bits + = bits ;
bits = FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN ;
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-14 04:58:42 +00:00
decoder - > private_ - > stream_info . data . stream_info . channels = x + 1 ;
used_bits + = bits ;
bits = FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN ;
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-14 04:58:42 +00:00
decoder - > private_ - > stream_info . data . stream_info . bits_per_sample = x + 1 ;
used_bits + = bits ;
bits = FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN ;
if ( ! FLAC__bitbuffer_read_raw_uint64 ( decoder - > private_ - > input , & decoder - > private_ - > stream_info . data . stream_info . total_samples , FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-14 04:58:42 +00:00
used_bits + = bits ;
2002-11-15 05:41:48 +00:00
if ( ! FLAC__bitbuffer_read_byte_block_aligned_no_crc ( decoder - > private_ - > input , decoder - > private_ - > stream_info . data . stream_info . md5sum , 16 , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-14 04:58:42 +00:00
used_bits + = 16 * 8 ;
/* skip the rest of the block */
FLAC__ASSERT ( used_bits % 8 = = 0 ) ;
length - = ( used_bits / 8 ) ;
2002-11-15 05:41:48 +00:00
if ( ! FLAC__bitbuffer_read_byte_block_aligned_no_crc ( decoder - > private_ - > input , 0 , length , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-14 04:58:42 +00:00
return true ;
}
FLAC__bool read_metadata_seektable_ ( FLAC__StreamDecoder * decoder , FLAC__bool is_last , unsigned length )
{
FLAC__uint32 i , x ;
FLAC__uint64 xx ;
FLAC__ASSERT ( FLAC__bitbuffer_is_consumed_byte_aligned ( decoder - > private_ - > input ) ) ;
decoder - > private_ - > seek_table . type = FLAC__METADATA_TYPE_SEEKTABLE ;
decoder - > private_ - > seek_table . is_last = is_last ;
decoder - > private_ - > seek_table . length = length ;
decoder - > private_ - > seek_table . data . seek_table . num_points = length / FLAC__STREAM_METADATA_SEEKPOINT_LENGTH ;
2002-12-04 07:01:37 +00:00
/* use realloc since we may pass through here several times (e.g. after seeking) */
if ( 0 = = ( decoder - > private_ - > seek_table . data . seek_table . points = ( FLAC__StreamMetadata_SeekPoint * ) realloc ( decoder - > private_ - > seek_table . data . seek_table . points , decoder - > private_ - > seek_table . data . seek_table . num_points * sizeof ( FLAC__StreamMetadata_SeekPoint ) ) ) ) {
2002-11-14 04:58:42 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR ;
return false ;
}
for ( i = 0 ; i < decoder - > private_ - > seek_table . data . seek_table . num_points ; i + + ) {
if ( ! FLAC__bitbuffer_read_raw_uint64 ( decoder - > private_ - > input , & xx , FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-14 04:58:42 +00:00
decoder - > private_ - > seek_table . data . seek_table . points [ i ] . sample_number = xx ;
if ( ! FLAC__bitbuffer_read_raw_uint64 ( decoder - > private_ - > input , & xx , FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-14 04:58:42 +00:00
decoder - > private_ - > seek_table . data . seek_table . points [ i ] . stream_offset = xx ;
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-14 04:58:42 +00:00
decoder - > private_ - > seek_table . data . seek_table . points [ i ] . frame_samples = x ;
}
length - = ( decoder - > private_ - > seek_table . data . seek_table . num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH ) ;
/* if there is a partial point left, skip over it */
if ( length > 0 ) {
/*@@@ do an error_callback() here? there's an argument for either way */
2002-11-15 05:41:48 +00:00
if ( ! FLAC__bitbuffer_read_byte_block_aligned_no_crc ( decoder - > private_ - > input , 0 , length , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-14 04:58:42 +00:00
}
return true ;
}
FLAC__bool read_metadata_vorbiscomment_ ( FLAC__StreamDecoder * decoder , FLAC__StreamMetadata_VorbisComment * obj )
{
FLAC__uint32 i ;
FLAC__ASSERT ( FLAC__bitbuffer_is_consumed_byte_aligned ( decoder - > private_ - > input ) ) ;
/* read vendor string */
FLAC__ASSERT ( FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN = = 32 ) ;
if ( ! FLAC__bitbuffer_read_raw_uint32_little_endian ( decoder - > private_ - > input , & obj - > vendor_string . length , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-14 04:58:42 +00:00
if ( obj - > vendor_string . length > 0 ) {
2004-12-30 00:59:30 +00:00
if ( 0 = = ( obj - > vendor_string . entry = ( FLAC__byte * ) malloc ( obj - > vendor_string . length + 1 ) ) ) {
2002-11-14 04:58:42 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR ;
return false ;
}
2002-11-15 05:41:48 +00:00
if ( ! FLAC__bitbuffer_read_byte_block_aligned_no_crc ( decoder - > private_ - > input , obj - > vendor_string . entry , obj - > vendor_string . length , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2004-12-30 00:59:30 +00:00
obj - > vendor_string . entry [ obj - > vendor_string . length ] = ' \0 ' ;
2002-11-14 04:58:42 +00:00
}
else
obj - > vendor_string . entry = 0 ;
/* read num comments */
FLAC__ASSERT ( FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN = = 32 ) ;
if ( ! FLAC__bitbuffer_read_raw_uint32_little_endian ( decoder - > private_ - > input , & obj - > num_comments , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-14 04:58:42 +00:00
/* read comments */
if ( obj - > num_comments > 0 ) {
if ( 0 = = ( obj - > comments = ( FLAC__StreamMetadata_VorbisComment_Entry * ) malloc ( obj - > num_comments * sizeof ( FLAC__StreamMetadata_VorbisComment_Entry ) ) ) ) {
decoder - > protected_ - > state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR ;
return false ;
}
for ( i = 0 ; i < obj - > num_comments ; i + + ) {
FLAC__ASSERT ( FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN = = 32 ) ;
if ( ! FLAC__bitbuffer_read_raw_uint32_little_endian ( decoder - > private_ - > input , & obj - > comments [ i ] . length , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-14 04:58:42 +00:00
if ( obj - > comments [ i ] . length > 0 ) {
2004-12-30 00:59:30 +00:00
if ( 0 = = ( obj - > comments [ i ] . entry = ( FLAC__byte * ) malloc ( obj - > comments [ i ] . length + 1 ) ) ) {
2002-11-14 04:58:42 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR ;
return false ;
}
2002-11-15 05:41:48 +00:00
if ( ! FLAC__bitbuffer_read_byte_block_aligned_no_crc ( decoder - > private_ - > input , obj - > comments [ i ] . entry , obj - > comments [ i ] . length , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2004-12-30 00:59:30 +00:00
obj - > comments [ i ] . entry [ obj - > comments [ i ] . length ] = ' \0 ' ;
2002-11-14 04:58:42 +00:00
}
else
obj - > comments [ i ] . entry = 0 ;
}
}
else {
obj - > comments = 0 ;
}
return true ;
}
2002-11-15 05:41:48 +00:00
FLAC__bool read_metadata_cuesheet_ ( FLAC__StreamDecoder * decoder , FLAC__StreamMetadata_CueSheet * obj )
{
FLAC__uint32 i , j , x ;
FLAC__ASSERT ( FLAC__bitbuffer_is_consumed_byte_aligned ( decoder - > private_ - > input ) ) ;
memset ( obj , 0 , sizeof ( FLAC__StreamMetadata_CueSheet ) ) ;
FLAC__ASSERT ( FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN % 8 = = 0 ) ;
2003-05-20 00:01:49 +00:00
if ( ! FLAC__bitbuffer_read_byte_block_aligned_no_crc ( decoder - > private_ - > input , ( FLAC__byte * ) obj - > media_catalog_number , FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN / 8 , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-15 05:41:48 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint64 ( decoder - > private_ - > input , & obj - > lead_in , FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-15 05:41:48 +00:00
2002-12-05 06:37:46 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-12-05 06:37:46 +00:00
obj - > is_cd = x ? true : false ;
2002-11-16 06:31:54 +00:00
if ( ! FLAC__bitbuffer_skip_bits_no_crc ( decoder - > private_ - > input , FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-16 06:31:54 +00:00
2002-11-15 05:41:48 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-15 05:41:48 +00:00
obj - > num_tracks = x ;
if ( obj - > num_tracks > 0 ) {
if ( 0 = = ( obj - > tracks = ( FLAC__StreamMetadata_CueSheet_Track * ) calloc ( obj - > num_tracks , sizeof ( FLAC__StreamMetadata_CueSheet_Track ) ) ) ) {
decoder - > protected_ - > state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR ;
return false ;
}
for ( i = 0 ; i < obj - > num_tracks ; i + + ) {
FLAC__StreamMetadata_CueSheet_Track * track = & obj - > tracks [ i ] ;
if ( ! FLAC__bitbuffer_read_raw_uint64 ( decoder - > private_ - > input , & track - > offset , FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-15 05:41:48 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-15 19:32:57 +00:00
track - > number = ( FLAC__byte ) x ;
2002-11-15 05:41:48 +00:00
FLAC__ASSERT ( FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 = = 0 ) ;
2003-05-20 00:01:49 +00:00
if ( ! FLAC__bitbuffer_read_byte_block_aligned_no_crc ( decoder - > private_ - > input , ( FLAC__byte * ) track - > isrc , FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN / 8 , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-15 05:41:48 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-15 05:41:48 +00:00
track - > type = x ;
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-15 05:41:48 +00:00
track - > pre_emphasis = x ;
if ( ! FLAC__bitbuffer_skip_bits_no_crc ( decoder - > private_ - > input , FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-15 05:41:48 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-15 19:32:57 +00:00
track - > num_indices = ( FLAC__byte ) x ;
2002-11-15 05:41:48 +00:00
if ( track - > num_indices > 0 ) {
if ( 0 = = ( track - > indices = ( FLAC__StreamMetadata_CueSheet_Index * ) calloc ( track - > num_indices , sizeof ( FLAC__StreamMetadata_CueSheet_Index ) ) ) ) {
decoder - > protected_ - > state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR ;
return false ;
}
for ( j = 0 ; j < track - > num_indices ; j + + ) {
FLAC__StreamMetadata_CueSheet_Index * index = & track - > indices [ j ] ;
if ( ! FLAC__bitbuffer_read_raw_uint64 ( decoder - > private_ - > input , & index - > offset , FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-15 05:41:48 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-15 19:32:57 +00:00
index - > number = ( FLAC__byte ) x ;
2002-11-15 05:41:48 +00:00
if ( ! FLAC__bitbuffer_skip_bits_no_crc ( decoder - > private_ - > input , FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-15 05:41:48 +00:00
}
}
}
}
return true ;
}
2006-09-23 19:21:19 +00:00
FLAC__bool read_metadata_picture_ ( FLAC__StreamDecoder * decoder , FLAC__StreamMetadata_Picture * obj )
{
FLAC__uint32 len ;
FLAC__ASSERT ( FLAC__bitbuffer_is_consumed_byte_aligned ( decoder - > private_ - > input ) ) ;
/* read type */
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & obj - > type , FLAC__STREAM_METADATA_PICTURE_TYPE_LEN , read_callback_ , decoder ) )
return false ; /* read_callback_ sets the state for us */
/* read MIME type */
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & len , FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN , read_callback_ , decoder ) )
return false ; /* read_callback_ sets the state for us */
if ( 0 = = ( obj - > mime_type = ( char * ) malloc ( len + 1 ) ) ) {
decoder - > protected_ - > state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR ;
return false ;
}
if ( len > 0 ) {
if ( ! FLAC__bitbuffer_read_byte_block_aligned_no_crc ( decoder - > private_ - > input , ( FLAC__byte * ) obj - > mime_type , len , read_callback_ , decoder ) )
return false ; /* read_callback_ sets the state for us */
}
obj - > mime_type [ len ] = ' \0 ' ;
/* read description */
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & len , FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN , read_callback_ , decoder ) )
return false ; /* read_callback_ sets the state for us */
if ( 0 = = ( obj - > description = ( FLAC__byte * ) malloc ( len + 1 ) ) ) {
decoder - > protected_ - > state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR ;
return false ;
}
if ( len > 0 ) {
if ( ! FLAC__bitbuffer_read_byte_block_aligned_no_crc ( decoder - > private_ - > input , obj - > description , len , read_callback_ , decoder ) )
return false ; /* read_callback_ sets the state for us */
}
obj - > description [ len ] = ' \0 ' ;
/* read width */
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & obj - > width , FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN , read_callback_ , decoder ) )
return false ; /* read_callback_ sets the state for us */
/* read height */
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & obj - > height , FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN , read_callback_ , decoder ) )
return false ; /* read_callback_ sets the state for us */
/* read depth */
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & obj - > depth , FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN , read_callback_ , decoder ) )
return false ; /* read_callback_ sets the state for us */
2006-09-23 23:15:05 +00:00
/* read colors */
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & obj - > colors , FLAC__STREAM_METADATA_PICTURE_COLORS_LEN , read_callback_ , decoder ) )
return false ; /* read_callback_ sets the state for us */
2006-09-23 19:21:19 +00:00
/* read data */
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & ( obj - > data_length ) , FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN , read_callback_ , decoder ) )
return false ; /* read_callback_ sets the state for us */
if ( 0 = = ( obj - > data = ( FLAC__byte * ) malloc ( obj - > data_length ) ) ) {
decoder - > protected_ - > state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR ;
return false ;
}
if ( obj - > data_length > 0 ) {
if ( ! FLAC__bitbuffer_read_byte_block_aligned_no_crc ( decoder - > private_ - > input , obj - > data , obj - > data_length , read_callback_ , decoder ) )
return false ; /* read_callback_ sets the state for us */
}
return true ;
}
2002-07-31 06:58:16 +00:00
FLAC__bool skip_id3v2_tag_ ( FLAC__StreamDecoder * decoder )
2000-12-10 04:09:52 +00:00
{
2001-06-23 03:03:24 +00:00
FLAC__uint32 x ;
2000-12-10 04:09:52 +00:00
unsigned i , skip ;
/* skip the version and flags bytes */
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , 24 , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2000-12-10 04:09:52 +00:00
/* get the size (in bytes) to skip */
skip = 0 ;
for ( i = 0 ; i < 4 ; i + + ) {
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , 8 , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2000-12-10 04:09:52 +00:00
skip < < = 7 ;
skip | = ( x & 0x7f ) ;
}
/* skip the rest of the tag */
2002-11-15 05:41:48 +00:00
if ( ! FLAC__bitbuffer_read_byte_block_aligned_no_crc ( decoder - > private_ - > input , 0 , skip , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2000-12-10 04:09:52 +00:00
return true ;
}
2002-07-31 06:58:16 +00:00
FLAC__bool frame_sync_ ( FLAC__StreamDecoder * decoder )
2000-12-10 04:09:52 +00:00
{
2001-06-23 03:03:24 +00:00
FLAC__uint32 x ;
FLAC__bool first = true ;
2000-12-10 04:09:52 +00:00
/* If we know the total number of samples in the stream, stop if we've read that many. */
/* This will stop us, for example, from wasting time trying to sync on an ID3V1 tag. */
2006-09-13 01:42:27 +00:00
if ( FLAC__stream_decoder_get_total_samples ( decoder ) > 0 ) {
if ( decoder - > private_ - > samples_decoded > = FLAC__stream_decoder_get_total_samples ( decoder ) ) {
2001-08-16 20:07:29 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_END_OF_STREAM ;
2000-12-10 04:09:52 +00:00
return true ;
}
}
/* make sure we're byte aligned */
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_is_consumed_byte_aligned ( decoder - > private_ - > input ) ) {
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , FLAC__bitbuffer_bits_left_for_byte_alignment ( decoder - > private_ - > input ) , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2000-12-10 04:09:52 +00:00
}
while ( 1 ) {
2001-08-16 20:07:29 +00:00
if ( decoder - > private_ - > cached ) {
x = ( FLAC__uint32 ) decoder - > private_ - > lookahead ;
decoder - > private_ - > cached = false ;
2001-03-27 01:15:58 +00:00
}
else {
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , 8 , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-03-27 01:15:58 +00:00
}
2000-12-10 04:09:52 +00:00
if ( x = = 0xff ) { /* MAGIC NUMBER for the first 8 frame sync bits */
2001-08-16 20:07:29 +00:00
decoder - > private_ - > header_warmup [ 0 ] = ( FLAC__byte ) x ;
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , 8 , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-03-27 01:15:58 +00:00
/* we have to check if we just read two 0xff's in a row; the second may actually be the beginning of the sync code */
/* else we have to check if the second byte is the end of a sync code */
if ( x = = 0xff ) { /* MAGIC NUMBER for the first 8 frame sync bits */
2001-08-16 20:07:29 +00:00
decoder - > private_ - > lookahead = ( FLAC__byte ) x ;
decoder - > private_ - > cached = true ;
2001-03-27 01:15:58 +00:00
}
else if ( x > > 2 = = 0x3e ) { /* MAGIC NUMBER for the last 6 sync bits */
2001-08-16 20:07:29 +00:00
decoder - > private_ - > header_warmup [ 1 ] = ( FLAC__byte ) x ;
decoder - > protected_ - > state = FLAC__STREAM_DECODER_READ_FRAME ;
2000-12-10 04:09:52 +00:00
return true ;
}
}
if ( first ) {
2006-09-13 01:42:27 +00:00
send_error_to_client_ ( decoder , FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC ) ;
2002-02-12 22:58:59 +00:00
first = false ;
2000-12-10 04:09:52 +00:00
}
}
return true ;
}
2004-07-16 00:53:38 +00:00
FLAC__bool read_frame_ ( FLAC__StreamDecoder * decoder , FLAC__bool * got_a_frame , FLAC__bool do_full_decode )
2000-12-10 04:09:52 +00:00
{
unsigned channel ;
unsigned i ;
2001-06-23 03:03:24 +00:00
FLAC__int32 mid , side , left , right ;
FLAC__uint16 frame_crc ; /* the one we calculate from the input stream */
FLAC__uint32 x ;
2000-12-10 04:09:52 +00:00
* got_a_frame = false ;
2001-03-27 01:15:58 +00:00
/* init the CRC */
frame_crc = 0 ;
2001-08-16 20:07:29 +00:00
FLAC__CRC16_UPDATE ( decoder - > private_ - > header_warmup [ 0 ] , frame_crc ) ;
FLAC__CRC16_UPDATE ( decoder - > private_ - > header_warmup [ 1 ] , frame_crc ) ;
2002-03-12 16:19:54 +00:00
FLAC__bitbuffer_reset_read_crc16 ( decoder - > private_ - > input , frame_crc ) ;
2001-03-27 01:15:58 +00:00
2002-07-31 06:58:16 +00:00
if ( ! read_frame_header_ ( decoder ) )
2000-12-10 04:09:52 +00:00
return false ;
2006-07-06 07:49:07 +00:00
if ( decoder - > protected_ - > state = = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ) /* means we didn't sync on a valid header */
2000-12-10 04:09:52 +00:00
return true ;
2002-07-31 06:58:16 +00:00
if ( ! allocate_output_ ( decoder , decoder - > private_ - > frame . header . blocksize , decoder - > private_ - > frame . header . channels ) )
2000-12-10 04:09:52 +00:00
return false ;
2001-08-16 20:07:29 +00:00
for ( channel = 0 ; channel < decoder - > private_ - > frame . header . channels ; channel + + ) {
2001-01-28 09:27:27 +00:00
/*
* first figure the correct bits - per - sample of the subframe
*/
2001-08-16 20:07:29 +00:00
unsigned bps = decoder - > private_ - > frame . header . bits_per_sample ;
switch ( decoder - > private_ - > frame . header . channel_assignment ) {
2001-01-28 09:27:27 +00:00
case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT :
/* no adjustment needed */
break ;
case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE :
2001-08-16 20:07:29 +00:00
FLAC__ASSERT ( decoder - > private_ - > frame . header . channels = = 2 ) ;
2001-01-28 09:27:27 +00:00
if ( channel = = 1 )
bps + + ;
break ;
case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE :
2001-08-16 20:07:29 +00:00
FLAC__ASSERT ( decoder - > private_ - > frame . header . channels = = 2 ) ;
2001-01-28 09:27:27 +00:00
if ( channel = = 0 )
bps + + ;
break ;
case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE :
2001-08-16 20:07:29 +00:00
FLAC__ASSERT ( decoder - > private_ - > frame . header . channels = = 2 ) ;
2001-01-28 09:27:27 +00:00
if ( channel = = 1 )
bps + + ;
break ;
default :
2001-05-31 20:11:02 +00:00
FLAC__ASSERT ( 0 ) ;
2001-01-28 09:27:27 +00:00
}
/*
* now read it
*/
2004-07-16 00:53:38 +00:00
if ( ! read_subframe_ ( decoder , channel , bps , do_full_decode ) )
2000-12-10 04:09:52 +00:00
return false ;
2006-07-06 07:49:07 +00:00
if ( decoder - > protected_ - > state = = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ) /* means bad sync or got corruption */
2000-12-10 04:09:52 +00:00
return true ;
}
2002-07-31 06:58:16 +00:00
if ( ! read_zero_padding_ ( decoder ) )
2000-12-10 04:09:52 +00:00
return false ;
2001-03-27 01:15:58 +00:00
/*
* Read the frame CRC - 16 from the footer and check
*/
2002-03-12 16:19:54 +00:00
frame_crc = FLAC__bitbuffer_get_read_crc16 ( decoder - > private_ - > input ) ;
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , FLAC__FRAME_FOOTER_CRC_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-06-23 03:03:24 +00:00
if ( frame_crc = = ( FLAC__uint16 ) x ) {
2004-07-16 00:53:38 +00:00
if ( do_full_decode ) {
/* Undo any special channel coding */
switch ( decoder - > private_ - > frame . header . channel_assignment ) {
case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT :
/* do nothing */
break ;
case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE :
FLAC__ASSERT ( decoder - > private_ - > frame . header . channels = = 2 ) ;
for ( i = 0 ; i < decoder - > private_ - > frame . header . blocksize ; i + + )
decoder - > private_ - > output [ 1 ] [ i ] = decoder - > private_ - > output [ 0 ] [ i ] - decoder - > private_ - > output [ 1 ] [ i ] ;
break ;
case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE :
FLAC__ASSERT ( decoder - > private_ - > frame . header . channels = = 2 ) ;
for ( i = 0 ; i < decoder - > private_ - > frame . header . blocksize ; i + + )
decoder - > private_ - > output [ 0 ] [ i ] + = decoder - > private_ - > output [ 1 ] [ i ] ;
break ;
case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE :
FLAC__ASSERT ( decoder - > private_ - > frame . header . channels = = 2 ) ;
for ( i = 0 ; i < decoder - > private_ - > frame . header . blocksize ; i + + ) {
mid = decoder - > private_ - > output [ 0 ] [ i ] ;
side = decoder - > private_ - > output [ 1 ] [ i ] ;
mid < < = 1 ;
if ( side & 1 ) /* i.e. if 'side' is odd... */
mid + + ;
left = mid + side ;
right = mid - side ;
decoder - > private_ - > output [ 0 ] [ i ] = left > > 1 ;
decoder - > private_ - > output [ 1 ] [ i ] = right > > 1 ;
}
break ;
default :
FLAC__ASSERT ( 0 ) ;
break ;
}
2001-03-27 01:15:58 +00:00
}
}
else {
/* Bad frame, emit error and zero the output signal */
2006-09-13 01:42:27 +00:00
send_error_to_client_ ( decoder , FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH ) ;
2004-07-16 00:53:38 +00:00
if ( do_full_decode ) {
for ( channel = 0 ; channel < decoder - > private_ - > frame . header . channels ; channel + + ) {
memset ( decoder - > private_ - > output [ channel ] , 0 , sizeof ( FLAC__int32 ) * decoder - > private_ - > frame . header . blocksize ) ;
}
2001-03-27 01:15:58 +00:00
}
2000-12-10 04:09:52 +00:00
}
* got_a_frame = true ;
/* put the latest values into the public section of the decoder instance */
2001-08-16 20:07:29 +00:00
decoder - > protected_ - > channels = decoder - > private_ - > frame . header . channels ;
decoder - > protected_ - > channel_assignment = decoder - > private_ - > frame . header . channel_assignment ;
decoder - > protected_ - > bits_per_sample = decoder - > private_ - > frame . header . bits_per_sample ;
decoder - > protected_ - > sample_rate = decoder - > private_ - > frame . header . sample_rate ;
decoder - > protected_ - > blocksize = decoder - > private_ - > frame . header . blocksize ;
2000-12-10 04:09:52 +00:00
2001-08-16 20:07:29 +00:00
FLAC__ASSERT ( decoder - > private_ - > frame . header . number_type = = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER ) ;
decoder - > private_ - > samples_decoded = decoder - > private_ - > frame . header . number . sample_number + decoder - > private_ - > frame . header . blocksize ;
2000-12-10 04:09:52 +00:00
/* write it */
2004-07-16 00:53:38 +00:00
if ( do_full_decode ) {
2006-09-13 01:42:27 +00:00
if ( write_audio_frame_to_client_ ( decoder , & decoder - > private_ - > frame , ( const FLAC__int32 * const * ) decoder - > private_ - > output ) ! = FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE )
2004-07-16 00:53:38 +00:00
return false ;
}
2000-12-10 04:09:52 +00:00
2001-08-16 20:07:29 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ;
2000-12-10 04:09:52 +00:00
return true ;
}
2002-07-31 06:58:16 +00:00
FLAC__bool read_frame_header_ ( FLAC__StreamDecoder * decoder )
2000-12-10 04:09:52 +00:00
{
2001-06-23 03:03:24 +00:00
FLAC__uint32 x ;
FLAC__uint64 xx ;
2000-12-10 04:09:52 +00:00
unsigned i , blocksize_hint = 0 , sample_rate_hint = 0 ;
2001-06-23 03:03:24 +00:00
FLAC__byte crc8 , raw_header [ 16 ] ; /* MAGIC NUMBER based on the maximum frame header size, including CRC */
2000-12-10 04:09:52 +00:00
unsigned raw_header_len ;
2001-06-23 03:03:24 +00:00
FLAC__bool is_unparseable = false ;
2001-08-16 20:07:29 +00:00
const FLAC__bool is_known_variable_blocksize_stream = ( decoder - > private_ - > has_stream_info & & decoder - > private_ - > stream_info . data . stream_info . min_blocksize ! = decoder - > private_ - > stream_info . data . stream_info . max_blocksize ) ;
const FLAC__bool is_known_fixed_blocksize_stream = ( decoder - > private_ - > has_stream_info & & decoder - > private_ - > stream_info . data . stream_info . min_blocksize = = decoder - > private_ - > stream_info . data . stream_info . max_blocksize ) ;
2000-12-10 04:09:52 +00:00
2002-03-12 16:19:54 +00:00
FLAC__ASSERT ( FLAC__bitbuffer_is_consumed_byte_aligned ( decoder - > private_ - > input ) ) ;
2000-12-10 04:09:52 +00:00
2001-03-27 01:15:58 +00:00
/* init the raw header with the saved bits from synchronization */
2001-08-16 20:07:29 +00:00
raw_header [ 0 ] = decoder - > private_ - > header_warmup [ 0 ] ;
raw_header [ 1 ] = decoder - > private_ - > header_warmup [ 1 ] ;
2001-03-27 01:15:58 +00:00
raw_header_len = 2 ;
/*
* check to make sure that the reserved bits are 0
*/
if ( raw_header [ 1 ] & 0x03 ) { /* MAGIC NUMBER */
is_unparseable = true ;
}
/*
* Note that along the way as we read the header , we look for a sync
* code inside . If we find one it would indicate that our original
* sync was bad since there cannot be a sync code in a valid header .
*/
2000-12-10 04:09:52 +00:00
/*
* read in the raw header as bytes so we can CRC it , and parse it on the way
*/
for ( i = 0 ; i < 2 ; i + + ) {
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , 8 , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-03-27 01:15:58 +00:00
if ( x = = 0xff ) { /* MAGIC NUMBER for the first 8 frame sync bits */
2000-12-10 04:09:52 +00:00
/* if we get here it means our original sync was erroneous since the sync code cannot appear in the header */
2001-08-16 20:07:29 +00:00
decoder - > private_ - > lookahead = ( FLAC__byte ) x ;
decoder - > private_ - > cached = true ;
2006-09-13 01:42:27 +00:00
send_error_to_client_ ( decoder , FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER ) ;
2001-08-16 20:07:29 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ;
2001-03-27 01:15:58 +00:00
return true ;
2000-12-10 04:09:52 +00:00
}
2001-06-23 03:03:24 +00:00
raw_header [ raw_header_len + + ] = ( FLAC__byte ) x ;
2000-12-10 04:09:52 +00:00
}
2001-03-27 01:15:58 +00:00
switch ( x = raw_header [ 2 ] > > 4 ) {
2000-12-10 04:09:52 +00:00
case 0 :
2001-04-14 00:24:32 +00:00
if ( is_known_fixed_blocksize_stream )
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . blocksize = decoder - > private_ - > stream_info . data . stream_info . min_blocksize ;
2000-12-10 04:09:52 +00:00
else
is_unparseable = true ;
break ;
case 1 :
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . blocksize = 192 ;
2000-12-10 04:09:52 +00:00
break ;
case 2 :
case 3 :
case 4 :
case 5 :
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . blocksize = 576 < < ( x - 2 ) ;
2000-12-10 04:09:52 +00:00
break ;
case 6 :
case 7 :
blocksize_hint = x ;
break ;
2001-03-27 01:15:58 +00:00
case 8 :
case 9 :
case 10 :
case 11 :
case 12 :
case 13 :
case 14 :
case 15 :
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . blocksize = 256 < < ( x - 8 ) ;
2001-03-27 01:15:58 +00:00
break ;
2000-12-10 04:09:52 +00:00
default :
2001-05-31 20:11:02 +00:00
FLAC__ASSERT ( 0 ) ;
2000-12-10 04:09:52 +00:00
break ;
}
2001-03-27 01:15:58 +00:00
switch ( x = raw_header [ 2 ] & 0x0f ) {
2000-12-10 04:09:52 +00:00
case 0 :
2001-08-16 20:07:29 +00:00
if ( decoder - > private_ - > has_stream_info )
decoder - > private_ - > frame . header . sample_rate = decoder - > private_ - > stream_info . data . stream_info . sample_rate ;
2000-12-10 04:09:52 +00:00
else
is_unparseable = true ;
break ;
case 1 :
case 2 :
case 3 :
is_unparseable = true ;
break ;
case 4 :
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . sample_rate = 8000 ;
2000-12-10 04:09:52 +00:00
break ;
case 5 :
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . sample_rate = 16000 ;
2000-12-10 04:09:52 +00:00
break ;
case 6 :
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . sample_rate = 22050 ;
2000-12-10 04:09:52 +00:00
break ;
case 7 :
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . sample_rate = 24000 ;
2000-12-10 04:09:52 +00:00
break ;
case 8 :
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . sample_rate = 32000 ;
2000-12-10 04:09:52 +00:00
break ;
case 9 :
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . sample_rate = 44100 ;
2000-12-10 04:09:52 +00:00
break ;
case 10 :
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . sample_rate = 48000 ;
2000-12-10 04:09:52 +00:00
break ;
case 11 :
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . sample_rate = 96000 ;
2000-12-10 04:09:52 +00:00
break ;
case 12 :
case 13 :
case 14 :
sample_rate_hint = x ;
break ;
case 15 :
2006-09-13 01:42:27 +00:00
send_error_to_client_ ( decoder , FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER ) ;
2001-08-16 20:07:29 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ;
2000-12-10 04:09:52 +00:00
return true ;
default :
2001-05-31 20:11:02 +00:00
FLAC__ASSERT ( 0 ) ;
2000-12-10 04:09:52 +00:00
}
2001-03-27 01:15:58 +00:00
x = ( unsigned ) ( raw_header [ 3 ] > > 4 ) ;
2000-12-10 04:09:52 +00:00
if ( x & 8 ) {
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . channels = 2 ;
2000-12-10 04:09:52 +00:00
switch ( x & 7 ) {
case 0 :
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . channel_assignment = FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE ;
2000-12-10 04:09:52 +00:00
break ;
case 1 :
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . channel_assignment = FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE ;
2000-12-10 04:09:52 +00:00
break ;
case 2 :
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . channel_assignment = FLAC__CHANNEL_ASSIGNMENT_MID_SIDE ;
2000-12-10 04:09:52 +00:00
break ;
default :
is_unparseable = true ;
break ;
}
}
else {
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . channels = ( unsigned ) x + 1 ;
decoder - > private_ - > frame . header . channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT ;
2000-12-10 04:09:52 +00:00
}
2001-03-27 01:15:58 +00:00
switch ( x = ( unsigned ) ( raw_header [ 3 ] & 0x0e ) > > 1 ) {
2000-12-10 04:09:52 +00:00
case 0 :
2001-08-16 20:07:29 +00:00
if ( decoder - > private_ - > has_stream_info )
decoder - > private_ - > frame . header . bits_per_sample = decoder - > private_ - > stream_info . data . stream_info . bits_per_sample ;
2000-12-10 04:09:52 +00:00
else
is_unparseable = true ;
break ;
case 1 :
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . bits_per_sample = 8 ;
2000-12-10 04:09:52 +00:00
break ;
case 2 :
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . bits_per_sample = 12 ;
2000-12-10 04:09:52 +00:00
break ;
case 4 :
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . bits_per_sample = 16 ;
2000-12-10 04:09:52 +00:00
break ;
case 5 :
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . bits_per_sample = 20 ;
2000-12-10 04:09:52 +00:00
break ;
case 6 :
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . bits_per_sample = 24 ;
2000-12-10 04:09:52 +00:00
break ;
case 3 :
case 7 :
is_unparseable = true ;
break ;
default :
2001-05-31 20:11:02 +00:00
FLAC__ASSERT ( 0 ) ;
2000-12-10 04:09:52 +00:00
break ;
}
2001-03-27 01:15:58 +00:00
if ( raw_header [ 3 ] & 0x01 ) { /* this should be a zero padding bit */
2006-09-13 01:42:27 +00:00
send_error_to_client_ ( decoder , FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER ) ;
2001-08-16 20:07:29 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ;
2000-12-10 04:09:52 +00:00
return true ;
}
2005-01-24 00:20:49 +00:00
/*
* Now we get to the regrettable consequences of not knowing for sure
* whether we got a frame number or a sample number . There are no
* encoders that do variable - blocksize encoding so unless we know from
* the STREAMINFO that it is variable - blocksize we will assume it is
* fixed - blocksize . The trouble comes when we have no STREAMINFO ; again
* we will guess that is fixed - blocksize . Where this can go wrong : 1 ) a
* variable - blocksize stream with no STREAMINFO ; 2 ) a fixed - blocksize
* stream that was edited such that one or more frames before or
* including this one do not have the same number of samples as the
* STREAMINFO ' s min and max blocksize .
*/
if ( is_known_variable_blocksize_stream ) {
if ( blocksize_hint ) {
if ( ! FLAC__bitbuffer_read_utf8_uint64 ( decoder - > private_ - > input , & xx , read_callback_ , decoder , raw_header , & raw_header_len ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2005-01-24 00:20:49 +00:00
if ( xx = = FLAC__U64L ( 0xffffffffffffffff ) ) { /* i.e. non-UTF8 code... */
decoder - > private_ - > lookahead = raw_header [ raw_header_len - 1 ] ; /* back up as much as we can */
decoder - > private_ - > cached = true ;
2006-09-13 01:42:27 +00:00
send_error_to_client_ ( decoder , FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER ) ;
2005-01-24 00:20:49 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ;
return true ;
}
decoder - > private_ - > frame . header . number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER ;
decoder - > private_ - > frame . header . number . sample_number = xx ;
2000-12-10 04:09:52 +00:00
}
2005-01-24 00:20:49 +00:00
else
is_unparseable = true ;
2000-12-10 04:09:52 +00:00
}
else {
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_utf8_uint32 ( decoder - > private_ - > input , & x , read_callback_ , decoder , raw_header , & raw_header_len ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-03-27 01:15:58 +00:00
if ( x = = 0xffffffff ) { /* i.e. non-UTF8 code... */
2001-08-16 20:07:29 +00:00
decoder - > private_ - > lookahead = raw_header [ raw_header_len - 1 ] ; /* back up as much as we can */
decoder - > private_ - > cached = true ;
2006-09-13 01:42:27 +00:00
send_error_to_client_ ( decoder , FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER ) ;
2001-08-16 20:07:29 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ;
2001-03-27 01:15:58 +00:00
return true ;
2000-12-10 04:09:52 +00:00
}
2001-08-16 20:07:29 +00:00
decoder - > private_ - > last_frame_number = x ;
2003-11-27 18:15:17 +00:00
decoder - > private_ - > frame . header . number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER ;
2005-01-24 00:20:49 +00:00
if ( decoder - > private_ - > has_stream_info ) {
FLAC__ASSERT ( decoder - > private_ - > stream_info . data . stream_info . min_blocksize = = decoder - > private_ - > stream_info . data . stream_info . max_blocksize ) ;
decoder - > private_ - > frame . header . number . sample_number = ( FLAC__uint64 ) decoder - > private_ - > stream_info . data . stream_info . min_blocksize * ( FLAC__uint64 ) x ;
2005-01-30 18:17:11 +00:00
decoder - > private_ - > last_block_size = decoder - > private_ - > frame . header . blocksize ;
2005-01-24 00:20:49 +00:00
}
else if ( blocksize_hint ) {
if ( decoder - > private_ - > last_block_size )
decoder - > private_ - > frame . header . number . sample_number = ( FLAC__uint64 ) decoder - > private_ - > last_block_size * ( FLAC__uint64 ) x ;
2003-11-27 18:15:17 +00:00
else
is_unparseable = true ;
2000-12-10 04:09:52 +00:00
}
2005-01-24 00:20:49 +00:00
else {
decoder - > private_ - > frame . header . number . sample_number = ( FLAC__uint64 ) decoder - > private_ - > frame . header . blocksize * ( FLAC__uint64 ) x ;
2005-01-30 18:17:11 +00:00
decoder - > private_ - > last_block_size = decoder - > private_ - > frame . header . blocksize ;
2005-01-24 00:20:49 +00:00
}
2000-12-10 04:09:52 +00:00
}
if ( blocksize_hint ) {
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , 8 , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-06-23 03:03:24 +00:00
raw_header [ raw_header_len + + ] = ( FLAC__byte ) x ;
2000-12-10 04:09:52 +00:00
if ( blocksize_hint = = 7 ) {
2001-06-23 03:03:24 +00:00
FLAC__uint32 _x ;
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & _x , 8 , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-06-23 03:03:24 +00:00
raw_header [ raw_header_len + + ] = ( FLAC__byte ) _x ;
2000-12-10 04:09:52 +00:00
x = ( x < < 8 ) | _x ;
}
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . blocksize = x + 1 ;
2000-12-10 04:09:52 +00:00
}
if ( sample_rate_hint ) {
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , 8 , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-06-23 03:03:24 +00:00
raw_header [ raw_header_len + + ] = ( FLAC__byte ) x ;
2000-12-10 04:09:52 +00:00
if ( sample_rate_hint ! = 12 ) {
2001-06-23 03:03:24 +00:00
FLAC__uint32 _x ;
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & _x , 8 , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-06-23 03:03:24 +00:00
raw_header [ raw_header_len + + ] = ( FLAC__byte ) _x ;
2000-12-10 04:09:52 +00:00
x = ( x < < 8 ) | _x ;
}
if ( sample_rate_hint = = 12 )
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . sample_rate = x * 1000 ;
2000-12-10 04:09:52 +00:00
else if ( sample_rate_hint = = 13 )
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . sample_rate = x ;
2000-12-10 04:09:52 +00:00
else
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . header . sample_rate = x * 10 ;
2000-12-10 04:09:52 +00:00
}
2001-03-27 01:15:58 +00:00
/* read the CRC-8 byte */
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , 8 , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-06-23 03:03:24 +00:00
crc8 = ( FLAC__byte ) x ;
2000-12-10 04:09:52 +00:00
2001-03-27 01:15:58 +00:00
if ( FLAC__crc8 ( raw_header , raw_header_len ) ! = crc8 ) {
2006-09-13 01:42:27 +00:00
send_error_to_client_ ( decoder , FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER ) ;
2001-08-16 20:07:29 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ;
2000-12-10 04:09:52 +00:00
return true ;
}
if ( is_unparseable ) {
2006-09-13 01:42:27 +00:00
send_error_to_client_ ( decoder , FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM ) ;
2006-07-06 07:49:07 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ;
return true ;
2000-12-10 04:09:52 +00:00
}
return true ;
}
2004-07-16 00:53:38 +00:00
FLAC__bool read_subframe_ ( FLAC__StreamDecoder * decoder , unsigned channel , unsigned bps , FLAC__bool do_full_decode )
2000-12-10 04:09:52 +00:00
{
2001-06-23 03:03:24 +00:00
FLAC__uint32 x ;
FLAC__bool wasted_bits ;
2006-07-06 07:49:07 +00:00
unsigned i ;
2000-12-10 04:09:52 +00:00
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & x , 8 , read_callback_ , decoder ) ) /* MAGIC NUMBER */
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-03-27 01:15:58 +00:00
wasted_bits = ( x & 1 ) ;
x & = 0xfe ;
if ( wasted_bits ) {
unsigned u ;
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_unary_unsigned ( decoder - > private_ - > input , & u , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . subframes [ channel ] . wasted_bits = u + 1 ;
bps - = decoder - > private_ - > frame . subframes [ channel ] . wasted_bits ;
2001-03-27 01:15:58 +00:00
}
else
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . subframes [ channel ] . wasted_bits = 0 ;
2001-03-27 01:15:58 +00:00
2001-03-27 22:22:27 +00:00
/*
* Lots of magic numbers here
*/
2001-03-27 01:15:58 +00:00
if ( x & 0x80 ) {
2006-09-13 01:42:27 +00:00
send_error_to_client_ ( decoder , FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC ) ;
2001-08-16 20:07:29 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ;
2000-12-10 04:09:52 +00:00
return true ;
}
else if ( x = = 0 ) {
2004-07-16 00:53:38 +00:00
if ( ! read_subframe_constant_ ( decoder , channel , bps , do_full_decode ) )
2001-03-27 01:15:58 +00:00
return false ;
2000-12-10 04:09:52 +00:00
}
else if ( x = = 2 ) {
2004-07-16 00:53:38 +00:00
if ( ! read_subframe_verbatim_ ( decoder , channel , bps , do_full_decode ) )
2001-03-27 01:15:58 +00:00
return false ;
2000-12-10 04:09:52 +00:00
}
else if ( x < 16 ) {
2006-09-13 01:42:27 +00:00
send_error_to_client_ ( decoder , FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM ) ;
2006-07-06 07:49:07 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ;
return true ;
2000-12-10 04:09:52 +00:00
}
else if ( x < = 24 ) {
2004-07-16 00:53:38 +00:00
if ( ! read_subframe_fixed_ ( decoder , channel , bps , ( x > > 1 ) & 7 , do_full_decode ) )
2001-03-27 01:15:58 +00:00
return false ;
2006-07-06 07:49:07 +00:00
if ( decoder - > protected_ - > state = = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ) /* means bad sync or got corruption */
return true ;
2000-12-10 04:09:52 +00:00
}
else if ( x < 64 ) {
2006-09-13 01:42:27 +00:00
send_error_to_client_ ( decoder , FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM ) ;
2006-07-06 07:49:07 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ;
return true ;
2000-12-10 04:09:52 +00:00
}
else {
2004-07-16 00:53:38 +00:00
if ( ! read_subframe_lpc_ ( decoder , channel , bps , ( ( x > > 1 ) & 31 ) + 1 , do_full_decode ) )
2001-03-27 01:15:58 +00:00
return false ;
2006-07-06 07:49:07 +00:00
if ( decoder - > protected_ - > state = = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ) /* means bad sync or got corruption */
return true ;
2000-12-10 04:09:52 +00:00
}
2001-03-27 01:15:58 +00:00
2004-07-16 00:53:38 +00:00
if ( wasted_bits & & do_full_decode ) {
2001-08-16 20:07:29 +00:00
x = decoder - > private_ - > frame . subframes [ channel ] . wasted_bits ;
for ( i = 0 ; i < decoder - > private_ - > frame . header . blocksize ; i + + )
decoder - > private_ - > output [ channel ] [ i ] < < = x ;
2001-03-27 01:15:58 +00:00
}
2001-03-27 22:22:27 +00:00
2001-03-27 01:15:58 +00:00
return true ;
2000-12-10 04:09:52 +00:00
}
2004-07-16 00:53:38 +00:00
FLAC__bool read_subframe_constant_ ( FLAC__StreamDecoder * decoder , unsigned channel , unsigned bps , FLAC__bool do_full_decode )
2000-12-10 04:09:52 +00:00
{
2001-08-16 20:07:29 +00:00
FLAC__Subframe_Constant * subframe = & decoder - > private_ - > frame . subframes [ channel ] . data . constant ;
2001-06-23 03:03:24 +00:00
FLAC__int32 x ;
2000-12-10 04:09:52 +00:00
unsigned i ;
2001-08-16 20:07:29 +00:00
FLAC__int32 * output = decoder - > private_ - > output [ channel ] ;
2000-12-10 04:09:52 +00:00
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . subframes [ channel ] . type = FLAC__SUBFRAME_TYPE_CONSTANT ;
2001-01-23 23:07:36 +00:00
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_int32 ( decoder - > private_ - > input , & x , bps , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2000-12-10 04:09:52 +00:00
2001-01-23 23:07:36 +00:00
subframe - > value = x ;
/* decode the subframe */
2004-07-16 00:53:38 +00:00
if ( do_full_decode ) {
for ( i = 0 ; i < decoder - > private_ - > frame . header . blocksize ; i + + )
output [ i ] = x ;
}
2000-12-10 04:09:52 +00:00
return true ;
}
2004-07-16 00:53:38 +00:00
FLAC__bool read_subframe_fixed_ ( FLAC__StreamDecoder * decoder , unsigned channel , unsigned bps , const unsigned order , FLAC__bool do_full_decode )
2000-12-10 04:09:52 +00:00
{
2001-08-16 20:07:29 +00:00
FLAC__Subframe_Fixed * subframe = & decoder - > private_ - > frame . subframes [ channel ] . data . fixed ;
2001-06-23 03:03:24 +00:00
FLAC__int32 i32 ;
FLAC__uint32 u32 ;
2000-12-10 04:09:52 +00:00
unsigned u ;
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . subframes [ channel ] . type = FLAC__SUBFRAME_TYPE_FIXED ;
2001-01-23 23:07:36 +00:00
2001-08-16 20:07:29 +00:00
subframe - > residual = decoder - > private_ - > residual [ channel ] ;
2001-01-23 23:07:36 +00:00
subframe - > order = order ;
2000-12-10 04:09:52 +00:00
/* read warm-up samples */
for ( u = 0 ; u < order ; u + + ) {
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_int32 ( decoder - > private_ - > input , & i32 , bps , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-01-23 23:07:36 +00:00
subframe - > warmup [ u ] = i32 ;
2000-12-10 04:09:52 +00:00
}
/* read entropy coding method info */
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & u32 , FLAC__ENTROPY_CODING_METHOD_TYPE_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-06 07:11:26 +00:00
subframe - > entropy_coding_method . type = ( FLAC__EntropyCodingMethodType ) u32 ;
2001-01-23 23:07:36 +00:00
switch ( subframe - > entropy_coding_method . type ) {
2000-12-10 04:09:52 +00:00
case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE :
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & u32 , FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-01-23 23:07:36 +00:00
subframe - > entropy_coding_method . data . partitioned_rice . order = u32 ;
2002-08-19 21:36:39 +00:00
subframe - > entropy_coding_method . data . partitioned_rice . contents = & decoder - > private_ - > partitioned_rice_contents [ channel ] ;
2000-12-10 04:09:52 +00:00
break ;
default :
2006-09-13 01:42:27 +00:00
send_error_to_client_ ( decoder , FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM ) ;
2006-07-06 07:49:07 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ;
return true ;
2000-12-10 04:09:52 +00:00
}
/* read residual */
2001-01-23 23:07:36 +00:00
switch ( subframe - > entropy_coding_method . type ) {
2000-12-10 04:09:52 +00:00
case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE :
2002-08-19 21:36:39 +00:00
if ( ! read_residual_partitioned_rice_ ( decoder , order , subframe - > entropy_coding_method . data . partitioned_rice . order , & decoder - > private_ - > partitioned_rice_contents [ channel ] , decoder - > private_ - > residual [ channel ] ) )
2000-12-10 04:09:52 +00:00
return false ;
break ;
default :
2001-05-31 20:11:02 +00:00
FLAC__ASSERT ( 0 ) ;
2000-12-10 04:09:52 +00:00
}
/* decode the subframe */
2004-07-16 00:53:38 +00:00
if ( do_full_decode ) {
memcpy ( decoder - > private_ - > output [ channel ] , subframe - > warmup , sizeof ( FLAC__int32 ) * order ) ;
FLAC__fixed_restore_signal ( decoder - > private_ - > residual [ channel ] , decoder - > private_ - > frame . header . blocksize - order , order , decoder - > private_ - > output [ channel ] + order ) ;
}
2000-12-10 04:09:52 +00:00
return true ;
}
2004-07-16 00:53:38 +00:00
FLAC__bool read_subframe_lpc_ ( FLAC__StreamDecoder * decoder , unsigned channel , unsigned bps , const unsigned order , FLAC__bool do_full_decode )
2000-12-10 04:09:52 +00:00
{
2001-08-16 20:07:29 +00:00
FLAC__Subframe_LPC * subframe = & decoder - > private_ - > frame . subframes [ channel ] . data . lpc ;
2001-06-23 03:03:24 +00:00
FLAC__int32 i32 ;
FLAC__uint32 u32 ;
2000-12-10 04:09:52 +00:00
unsigned u ;
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . subframes [ channel ] . type = FLAC__SUBFRAME_TYPE_LPC ;
2001-01-23 23:07:36 +00:00
2001-08-16 20:07:29 +00:00
subframe - > residual = decoder - > private_ - > residual [ channel ] ;
2001-01-23 23:07:36 +00:00
subframe - > order = order ;
2000-12-10 04:09:52 +00:00
/* read warm-up samples */
for ( u = 0 ; u < order ; u + + ) {
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_int32 ( decoder - > private_ - > input , & i32 , bps , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-01-23 23:07:36 +00:00
subframe - > warmup [ u ] = i32 ;
2000-12-10 04:09:52 +00:00
}
/* read qlp coeff precision */
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & u32 , FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-04-13 18:44:46 +00:00
if ( u32 = = ( 1u < < FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN ) - 1 ) {
2006-09-13 01:42:27 +00:00
send_error_to_client_ ( decoder , FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC ) ;
2001-08-16 20:07:29 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ;
2000-12-10 04:09:52 +00:00
return true ;
}
2001-01-23 23:07:36 +00:00
subframe - > qlp_coeff_precision = u32 + 1 ;
2000-12-10 04:09:52 +00:00
/* read qlp shift */
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_int32 ( decoder - > private_ - > input , & i32 , FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-01-23 23:07:36 +00:00
subframe - > quantization_level = i32 ;
2000-12-10 04:09:52 +00:00
/* read quantized lp coefficiencts */
for ( u = 0 ; u < order ; u + + ) {
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_int32 ( decoder - > private_ - > input , & i32 , subframe - > qlp_coeff_precision , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-01-23 23:07:36 +00:00
subframe - > qlp_coeff [ u ] = i32 ;
2000-12-10 04:09:52 +00:00
}
/* read entropy coding method info */
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & u32 , FLAC__ENTROPY_CODING_METHOD_TYPE_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-11-06 07:11:26 +00:00
subframe - > entropy_coding_method . type = ( FLAC__EntropyCodingMethodType ) u32 ;
2001-01-23 23:07:36 +00:00
switch ( subframe - > entropy_coding_method . type ) {
2000-12-10 04:09:52 +00:00
case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE :
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & u32 , FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-01-23 23:07:36 +00:00
subframe - > entropy_coding_method . data . partitioned_rice . order = u32 ;
2002-08-19 21:36:39 +00:00
subframe - > entropy_coding_method . data . partitioned_rice . contents = & decoder - > private_ - > partitioned_rice_contents [ channel ] ;
2000-12-10 04:09:52 +00:00
break ;
default :
2006-09-13 01:42:27 +00:00
send_error_to_client_ ( decoder , FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM ) ;
2006-07-06 07:49:07 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ;
return true ;
2000-12-10 04:09:52 +00:00
}
/* read residual */
2001-01-23 23:07:36 +00:00
switch ( subframe - > entropy_coding_method . type ) {
2000-12-10 04:09:52 +00:00
case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE :
2002-08-19 21:36:39 +00:00
if ( ! read_residual_partitioned_rice_ ( decoder , order , subframe - > entropy_coding_method . data . partitioned_rice . order , & decoder - > private_ - > partitioned_rice_contents [ channel ] , decoder - > private_ - > residual [ channel ] ) )
2000-12-10 04:09:52 +00:00
return false ;
break ;
default :
2001-05-31 20:11:02 +00:00
FLAC__ASSERT ( 0 ) ;
2000-12-10 04:09:52 +00:00
}
/* decode the subframe */
2004-07-16 00:53:38 +00:00
if ( do_full_decode ) {
memcpy ( decoder - > private_ - > output [ channel ] , subframe - > warmup , sizeof ( FLAC__int32 ) * order ) ;
if ( bps + subframe - > qlp_coeff_precision + FLAC__bitmath_ilog2 ( order ) < = 32 )
2004-07-27 01:13:16 +00:00
if ( bps < = 16 & & subframe - > qlp_coeff_precision < = 16 ) {
if ( order < = 8 )
decoder - > private_ - > local_lpc_restore_signal_16bit_order8 ( decoder - > private_ - > residual [ channel ] , decoder - > private_ - > frame . header . blocksize - order , subframe - > qlp_coeff , order , subframe - > quantization_level , decoder - > private_ - > output [ channel ] + order ) ;
else
decoder - > private_ - > local_lpc_restore_signal_16bit ( decoder - > private_ - > residual [ channel ] , decoder - > private_ - > frame . header . blocksize - order , subframe - > qlp_coeff , order , subframe - > quantization_level , decoder - > private_ - > output [ channel ] + order ) ;
}
2004-07-16 00:53:38 +00:00
else
decoder - > private_ - > local_lpc_restore_signal ( decoder - > private_ - > residual [ channel ] , decoder - > private_ - > frame . header . blocksize - order , subframe - > qlp_coeff , order , subframe - > quantization_level , decoder - > private_ - > output [ channel ] + order ) ;
2002-10-21 07:04:07 +00:00
else
2004-07-16 00:53:38 +00:00
decoder - > private_ - > local_lpc_restore_signal_64bit ( decoder - > private_ - > residual [ channel ] , decoder - > private_ - > frame . header . blocksize - order , subframe - > qlp_coeff , order , subframe - > quantization_level , decoder - > private_ - > output [ channel ] + order ) ;
}
2000-12-10 04:09:52 +00:00
return true ;
}
2004-07-16 00:53:38 +00:00
FLAC__bool read_subframe_verbatim_ ( FLAC__StreamDecoder * decoder , unsigned channel , unsigned bps , FLAC__bool do_full_decode )
2000-12-10 04:09:52 +00:00
{
2001-08-16 20:07:29 +00:00
FLAC__Subframe_Verbatim * subframe = & decoder - > private_ - > frame . subframes [ channel ] . data . verbatim ;
FLAC__int32 x , * residual = decoder - > private_ - > residual [ channel ] ;
2000-12-10 04:09:52 +00:00
unsigned i ;
2001-08-16 20:07:29 +00:00
decoder - > private_ - > frame . subframes [ channel ] . type = FLAC__SUBFRAME_TYPE_VERBATIM ;
2001-01-23 23:07:36 +00:00
2001-01-28 09:27:27 +00:00
subframe - > data = residual ;
2001-01-23 23:07:36 +00:00
2001-08-16 20:07:29 +00:00
for ( i = 0 ; i < decoder - > private_ - > frame . header . blocksize ; i + + ) {
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_int32 ( decoder - > private_ - > input , & x , bps , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-01-28 09:27:27 +00:00
residual [ i ] = x ;
2000-12-10 04:09:52 +00:00
}
2001-01-23 23:07:36 +00:00
/* decode the subframe */
2004-07-16 00:53:38 +00:00
if ( do_full_decode )
memcpy ( decoder - > private_ - > output [ channel ] , subframe - > data , sizeof ( FLAC__int32 ) * decoder - > private_ - > frame . header . blocksize ) ;
2001-01-23 23:07:36 +00:00
2000-12-10 04:09:52 +00:00
return true ;
}
2002-08-19 21:36:39 +00:00
FLAC__bool read_residual_partitioned_rice_ ( FLAC__StreamDecoder * decoder , unsigned predictor_order , unsigned partition_order , FLAC__EntropyCodingMethod_PartitionedRiceContents * partitioned_rice_contents , FLAC__int32 * residual )
2000-12-10 04:09:52 +00:00
{
2001-06-23 03:03:24 +00:00
FLAC__uint32 rice_parameter ;
2000-12-10 04:09:52 +00:00
int i ;
unsigned partition , sample , u ;
const unsigned partitions = 1u < < partition_order ;
2001-08-16 20:07:29 +00:00
const unsigned partition_samples = partition_order > 0 ? decoder - > private_ - > frame . header . blocksize > > partition_order : decoder - > private_ - > frame . header . blocksize - predictor_order ;
2000-12-10 04:09:52 +00:00
2004-10-06 00:56:51 +00:00
/* sanity checks */
if ( partition_order = = 0 ) {
if ( decoder - > private_ - > frame . header . blocksize < predictor_order ) {
2006-09-13 01:42:27 +00:00
send_error_to_client_ ( decoder , FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC ) ;
2004-10-06 00:56:51 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ;
return true ;
}
}
else {
if ( partition_samples < predictor_order ) {
2006-09-13 01:42:27 +00:00
send_error_to_client_ ( decoder , FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC ) ;
2004-10-06 00:56:51 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ;
return true ;
}
}
2002-08-19 21:36:39 +00:00
if ( ! FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size ( partitioned_rice_contents , max ( 6 , partition_order ) ) ) {
2002-08-17 15:23:43 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR ;
return false ;
}
2000-12-10 04:09:52 +00:00
sample = 0 ;
for ( partition = 0 ; partition < partitions ; partition + + ) {
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & rice_parameter , FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-08-19 21:36:39 +00:00
partitioned_rice_contents - > parameters [ partition ] = rice_parameter ;
2001-04-12 22:22:34 +00:00
if ( rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER ) {
2002-04-25 05:21:09 +00:00
u = ( partition_order = = 0 | | partition > 0 ) ? partition_samples : partition_samples - predictor_order ;
if ( ! FLAC__bitbuffer_read_rice_signed_block ( decoder - > private_ - > input , residual + sample , u , rice_parameter , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-04-25 05:21:09 +00:00
sample + = u ;
2001-04-12 22:22:34 +00:00
}
else {
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & rice_parameter , FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2002-08-19 21:36:39 +00:00
partitioned_rice_contents - > raw_bits [ partition ] = rice_parameter ;
2001-04-12 22:22:34 +00:00
for ( u = ( partition_order = = 0 | | partition > 0 ) ? 0 : predictor_order ; u < partition_samples ; u + + , sample + + ) {
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_int32 ( decoder - > private_ - > input , & i , rice_parameter , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2001-04-12 22:22:34 +00:00
residual [ sample ] = i ;
}
2000-12-10 04:09:52 +00:00
}
}
return true ;
}
2002-07-31 06:58:16 +00:00
FLAC__bool read_zero_padding_ ( FLAC__StreamDecoder * decoder )
2000-12-10 04:09:52 +00:00
{
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_is_consumed_byte_aligned ( decoder - > private_ - > input ) ) {
2001-06-23 03:03:24 +00:00
FLAC__uint32 zero = 0 ;
2002-03-12 16:19:54 +00:00
if ( ! FLAC__bitbuffer_read_raw_uint32 ( decoder - > private_ - > input , & zero , FLAC__bitbuffer_bits_left_for_byte_alignment ( decoder - > private_ - > input ) , read_callback_ , decoder ) )
2006-09-13 01:42:27 +00:00
return false ; /* read_callback_ sets the state for us */
2000-12-10 04:09:52 +00:00
if ( zero ! = 0 ) {
2006-09-13 01:42:27 +00:00
send_error_to_client_ ( decoder , FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC ) ;
2001-08-16 20:07:29 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ;
2000-12-10 04:09:52 +00:00
}
}
return true ;
}
2001-06-23 03:03:24 +00:00
FLAC__bool read_callback_ ( FLAC__byte buffer [ ] , unsigned * bytes , void * client_data )
2000-12-10 04:09:52 +00:00
{
FLAC__StreamDecoder * decoder = ( FLAC__StreamDecoder * ) client_data ;
2002-03-12 16:19:54 +00:00
2006-09-13 01:42:27 +00:00
if ( decoder - > private_ - > eof_callback & & decoder - > private_ - > eof_callback ( decoder , decoder - > private_ - > client_data ) ) {
* bytes = 0 ;
2001-08-16 20:07:29 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_END_OF_STREAM ;
2006-09-13 01:42:27 +00:00
return false ;
}
else if ( * bytes > 0 ) {
/* While seeking, it is possible for our seek to land in the
* middle of audio data that looks exactly like a frame header
* from a future version of an encoder . When that happens , our
* error callback will get an
* FLAC__STREAM_DECODER_UNPARSEABLE_STREAM and increment its
* unparseable_frame_count . But there is a remote possibility
* that it is properly synced at such a " future-codec frame " ,
* so to make sure , we wait to see many " unparseable " errors in
* a row before bailing out .
*/
if ( decoder - > private_ - > is_seeking & & decoder - > private_ - > unparseable_frame_count > 20 ) {
decoder - > protected_ - > state = FLAC__STREAM_DECODER_ABORTED ;
return false ;
}
else {
const FLAC__StreamDecoderReadStatus status = decoder - > private_ - > read_callback ( decoder , buffer , bytes , decoder - > private_ - > client_data ) ;
if ( status = = FLAC__STREAM_DECODER_READ_STATUS_ABORT ) {
decoder - > protected_ - > state = FLAC__STREAM_DECODER_ABORTED ;
return false ;
}
else if ( * bytes = = 0 ) {
if ( status = = FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM | | ( decoder - > private_ - > eof_callback & & decoder - > private_ - > eof_callback ( decoder , decoder - > private_ - > client_data ) ) ) {
decoder - > protected_ - > state = FLAC__STREAM_DECODER_END_OF_STREAM ;
return false ;
}
else
return true ;
}
else
return true ;
}
}
else {
/* abort to avoid a deadlock */
2001-08-16 20:07:29 +00:00
decoder - > protected_ - > state = FLAC__STREAM_DECODER_ABORTED ;
2006-09-13 01:42:27 +00:00
return false ;
}
}
FLAC__StreamDecoderWriteStatus write_audio_frame_to_client_ ( FLAC__StreamDecoder * decoder , const FLAC__Frame * frame , const FLAC__int32 * const buffer [ ] )
{
if ( decoder - > private_ - > is_seeking ) {
FLAC__uint64 this_frame_sample = frame - > header . number . sample_number ;
FLAC__uint64 next_frame_sample = this_frame_sample + ( FLAC__uint64 ) frame - > header . blocksize ;
FLAC__uint64 target_sample = decoder - > private_ - > target_sample ;
FLAC__ASSERT ( frame - > header . number_type = = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER ) ;
decoder - > private_ - > last_frame = * frame ; /* save the frame */
if ( this_frame_sample < = target_sample & & target_sample < next_frame_sample ) { /* we hit our target frame */
unsigned delta = ( unsigned ) ( target_sample - this_frame_sample ) ;
/* kick out of seek mode */
decoder - > private_ - > is_seeking = false ;
/* shift out the samples before target_sample */
if ( delta > 0 ) {
unsigned channel ;
const FLAC__int32 * newbuffer [ FLAC__MAX_CHANNELS ] ;
for ( channel = 0 ; channel < frame - > header . channels ; channel + + )
newbuffer [ channel ] = buffer [ channel ] + delta ;
decoder - > private_ - > last_frame . header . blocksize - = delta ;
decoder - > private_ - > last_frame . header . number . sample_number + = ( FLAC__uint64 ) delta ;
/* write the relevant samples */
return decoder - > private_ - > write_callback ( decoder , & decoder - > private_ - > last_frame , newbuffer , decoder - > private_ - > client_data ) ;
}
else {
/* write the relevant samples */
return decoder - > private_ - > write_callback ( decoder , frame , buffer , decoder - > private_ - > client_data ) ;
}
}
else {
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE ;
}
}
else {
/*
* If we never got STREAMINFO , turn off MD5 checking to save
* cycles since we don ' t have a sum to compare to anyway
*/
if ( ! decoder - > private_ - > has_stream_info )
decoder - > private_ - > do_md5_checking = false ;
if ( decoder - > private_ - > do_md5_checking ) {
if ( ! FLAC__MD5Accumulate ( & decoder - > private_ - > md5context , buffer , frame - > header . channels , frame - > header . blocksize , ( frame - > header . bits_per_sample + 7 ) / 8 ) )
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT ;
}
return decoder - > private_ - > write_callback ( decoder , frame , buffer , decoder - > private_ - > client_data ) ;
}
}
void send_error_to_client_ ( const FLAC__StreamDecoder * decoder , FLAC__StreamDecoderErrorStatus status )
{
if ( ! decoder - > private_ - > is_seeking )
decoder - > private_ - > error_callback ( decoder , status , decoder - > private_ - > client_data ) ;
else if ( status = = FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM )
decoder - > private_ - > unparseable_frame_count + + ;
}
FLAC__bool seek_to_absolute_sample_ ( FLAC__StreamDecoder * decoder , FLAC__uint64 stream_length , FLAC__uint64 target_sample )
{
FLAC__uint64 first_frame_offset = decoder - > private_ - > first_frame_offset , lower_bound , upper_bound ;
FLAC__int64 pos = - 1 , last_pos = - 1 ;
int i , lower_seek_point = - 1 , upper_seek_point = - 1 ;
unsigned approx_bytes_per_frame ;
FLAC__uint64 last_frame_sample = FLAC__U64L ( 0xffffffffffffffff ) ;
FLAC__bool needs_seek ;
const FLAC__uint64 total_samples = FLAC__stream_decoder_get_total_samples ( decoder ) ;
const unsigned min_blocksize = decoder - > private_ - > stream_info . data . stream_info . min_blocksize ;
const unsigned max_blocksize = decoder - > private_ - > stream_info . data . stream_info . max_blocksize ;
const unsigned max_framesize = decoder - > private_ - > stream_info . data . stream_info . max_framesize ;
const unsigned channels = FLAC__stream_decoder_get_channels ( decoder ) ;
const unsigned bps = FLAC__stream_decoder_get_bits_per_sample ( decoder ) ;
const FLAC__StreamMetadata_SeekTable * seek_table = decoder - > private_ - > has_seek_table ? & decoder - > private_ - > seek_table . data . seek_table : 0 ;
/* we are just guessing here, but we want to guess high, not low */
if ( max_framesize > 0 )
approx_bytes_per_frame = max_framesize ;
/*
* Check if it ' s a known fixed - blocksize stream . Note that though
* the spec doesn ' t allow zeroes in the STREAMINFO block , we may
* never get a STREAMINFO block when decoding so the value of
* min_blocksize might be zero .
*/
else if ( min_blocksize = = max_blocksize & & min_blocksize > 0 ) {
/* note there are no () around 'bps/8' to keep precision up since it's an integer calulation */
approx_bytes_per_frame = min_blocksize * channels * bps / 8 + 64 ;
}
else
approx_bytes_per_frame = 4608 * channels * bps / 8 + 64 ;
/*
* First , we set an upper and lower bound on where in the
* stream we will search . For now we assume the worst case
* scenario , which is our best guess at the beginning of
* the first and last frames .
*/
lower_bound = first_frame_offset ;
/* calc the upper_bound, beyond which we never want to seek */
if ( max_framesize > 0 )
upper_bound = stream_length - ( max_framesize + 128 + 2 ) ; /* 128 for a possible ID3V1 tag, 2 for indexing differences */
else
upper_bound = stream_length - ( ( channels * bps * FLAC__MAX_BLOCK_SIZE ) / 8 + 128 + 2 ) ;
/*
* Now we refine the bounds if we have a seektable with
* suitable points . Note that according to the spec they
* must be ordered by ascending sample number .
*/
if ( seek_table ) {
/* find the closest seek point <= target_sample, if it exists */
for ( i = ( int ) seek_table - > num_points - 1 ; i > = 0 ; i - - ) {
if ( seek_table - > points [ i ] . sample_number ! = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER & & seek_table - > points [ i ] . sample_number < = target_sample )
break ;
}
if ( i > = 0 ) { /* i.e. we found a suitable seek point... */
lower_bound = first_frame_offset + seek_table - > points [ i ] . stream_offset ;
lower_seek_point = i ;
}
/* find the closest seek point > target_sample, if it exists */
for ( i = 0 ; i < ( int ) seek_table - > num_points ; i + + ) {
if ( seek_table - > points [ i ] . sample_number ! = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER & & seek_table - > points [ i ] . sample_number > target_sample )
break ;
}
if ( i < ( int ) seek_table - > num_points ) { /* i.e. we found a suitable seek point... */
upper_bound = first_frame_offset + seek_table - > points [ i ] . stream_offset ;
upper_seek_point = i ;
}
}
/*
* Now guess at where within those bounds our target
* sample will be .
*/
if ( seek_table & & lower_seek_point > = 0 ) {
/* first see if our sample is within a few frames of the lower seekpoint */
if ( seek_table - > points [ lower_seek_point ] . sample_number < = target_sample & & target_sample < seek_table - > points [ lower_seek_point ] . sample_number + ( seek_table - > points [ lower_seek_point ] . frame_samples * 4 ) ) {
pos = ( FLAC__int64 ) lower_bound ;
}
else if ( upper_seek_point > = 0 ) {
const FLAC__uint64 target_offset = target_sample - seek_table - > points [ lower_seek_point ] . sample_number ;
const FLAC__uint64 range_samples = seek_table - > points [ upper_seek_point ] . sample_number - seek_table - > points [ lower_seek_point ] . sample_number ;
const FLAC__uint64 range_bytes = ( upper_bound > lower_bound ? upper_bound - lower_bound - 1 : 0 ) ;
# ifndef FLAC__INTEGER_ONLY_LIBRARY
# if defined _MSC_VER || defined __MINGW32__
/* with MSVC you have to spoon feed it the casting */
pos = ( FLAC__int64 ) lower_bound + ( FLAC__int64 ) ( ( ( FLAC__double ) ( FLAC__int64 ) target_offset / ( FLAC__double ) ( FLAC__int64 ) range_samples ) * ( FLAC__double ) ( FLAC__int64 ) ( range_bytes - 1 ) ) - approx_bytes_per_frame ;
# else
pos = ( FLAC__int64 ) lower_bound + ( FLAC__int64 ) ( ( ( FLAC__double ) target_offset / ( FLAC__double ) range_samples ) * ( FLAC__double ) range_bytes ) - approx_bytes_per_frame ;
# endif
# else
/* a little less accurate: */
if ( range_bytes < = 0xffffffff )
pos = ( FLAC__int64 ) lower_bound + ( FLAC__int64 ) ( ( target_offset * range_bytes ) / range_samples ) - approx_bytes_per_frame ;
else /* @@@ WATCHOUT, ~2TB limit */
pos = ( FLAC__int64 ) lower_bound + ( FLAC__int64 ) ( ( ( target_offset > > 8 ) * ( range_bytes > > 8 ) ) / ( range_samples > > 16 ) ) - approx_bytes_per_frame ;
# endif
}
}
/*
* If there ' s no seek table , we need to use the metadata ( if we
* have it ) and the filelength to estimate the position of the
* frame with the correct sample .
*/
if ( pos < 0 & & total_samples > 0 ) {
/*
* For max accuracy we should be using
* ( stream_length - first_frame_offset - 1 ) in the divisor , but the
* difference is trivial and ( stream_length - first_frame_offset )
* has no chance of underflow .
*/
# ifndef FLAC__INTEGER_ONLY_LIBRARY
# if defined _MSC_VER || defined __MINGW32__
/* with VC++ you have to spoon feed it the casting */
pos = ( FLAC__int64 ) first_frame_offset + ( FLAC__int64 ) ( ( ( FLAC__double ) ( FLAC__int64 ) target_sample / ( FLAC__double ) ( FLAC__int64 ) total_samples ) * ( FLAC__double ) ( FLAC__int64 ) ( stream_length - first_frame_offset ) ) - approx_bytes_per_frame ;
# else
pos = ( FLAC__int64 ) first_frame_offset + ( FLAC__int64 ) ( ( ( FLAC__double ) target_sample / ( FLAC__double ) total_samples ) * ( FLAC__double ) ( stream_length - first_frame_offset ) ) - approx_bytes_per_frame ;
# endif
# else
/* a little less accurate: */
if ( stream_length < 0xffffffff )
pos = ( FLAC__int64 ) first_frame_offset + ( FLAC__int64 ) ( ( target_sample * ( stream_length - first_frame_offset ) ) / total_samples ) - approx_bytes_per_frame ;
else /* @@@ WATCHOUT, ~2TB limit */
pos = ( FLAC__int64 ) first_frame_offset + ( FLAC__int64 ) ( ( ( target_sample > > 8 ) * ( ( stream_length - first_frame_offset ) > > 8 ) ) / ( total_samples > > 16 ) ) - approx_bytes_per_frame ;
# endif
}
/*
* If there ' s no seek table and total_samples is unknown , we
* don ' t even bother trying to figure out a target , we just use
* our current position .
*/
if ( pos < 0 ) {
FLAC__uint64 upos ;
if ( decoder - > private_ - > tell_callback ( decoder , & upos , decoder - > private_ - > client_data ) ! = FLAC__STREAM_DECODER_TELL_STATUS_OK ) {
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEEK_ERROR ;
return false ;
}
pos = ( FLAC__int64 ) upos ;
needs_seek = false ;
}
else
needs_seek = true ;
/* clip the position to the bounds, lower bound takes precedence */
if ( pos > = ( FLAC__int64 ) upper_bound ) {
pos = ( FLAC__int64 ) upper_bound - 1 ;
needs_seek = true ;
}
if ( pos < ( FLAC__int64 ) lower_bound ) {
pos = ( FLAC__int64 ) lower_bound ;
needs_seek = true ;
}
decoder - > private_ - > target_sample = target_sample ;
while ( 1 ) {
if ( needs_seek ) {
if ( decoder - > private_ - > seek_callback ( decoder , ( FLAC__uint64 ) pos , decoder - > private_ - > client_data ) ! = FLAC__STREAM_DECODER_SEEK_STATUS_OK ) {
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEEK_ERROR ;
return false ;
}
if ( ! FLAC__stream_decoder_flush ( decoder ) ) {
/* above call sets the state for us */
return false ;
}
}
/* Now we need to get a frame. First we need to reset our
* unparseable_frame_count ; if we get too many unparseable
* frames in a row , the read callback will return
* FLAC__STREAM_DECODER_READ_STATUS_ABORT , causing
* FLAC__stream_decoder_process_single ( ) to return false .
*/
decoder - > private_ - > unparseable_frame_count = 0 ;
if ( ! FLAC__stream_decoder_process_single ( decoder ) ) {
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEEK_ERROR ;
return false ;
}
/* our write callback will change the state when it gets to the target frame */
/* actually, we could have got_a_frame if our decoder is at FLAC__STREAM_DECODER_END_OF_STREAM so we need to check for that also */
#if 0
/*@@@@@@ used to be the following; not clear if the check for end of stream is needed anymore */
if ( decoder - > protected_ - > state ! = FLAC__SEEKABLE_STREAM_DECODER_SEEKING & & decoder - > protected_ - > state ! = FLAC__STREAM_DECODER_END_OF_STREAM )
break ;
# endif
if ( ! decoder - > private_ - > is_seeking ) {
break ;
}
else { /* we need to narrow the search */
const FLAC__uint64 this_frame_sample = decoder - > private_ - > last_frame . header . number . sample_number ;
FLAC__ASSERT ( decoder - > private_ - > last_frame . header . number_type = = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER ) ;
if ( this_frame_sample = = last_frame_sample & & pos < last_pos ) {
/* our last move backwards wasn't big enough, double it */
pos - = ( last_pos - pos ) ;
needs_seek = true ;
}
else {
if ( target_sample < this_frame_sample ) {
last_pos = pos ;
approx_bytes_per_frame = decoder - > private_ - > last_frame . header . blocksize * channels * bps / 8 + 64 ;
pos - = approx_bytes_per_frame ;
needs_seek = true ;
}
else { /* target_sample >= this_frame_sample + this frame's blocksize */
FLAC__uint64 upos ;
if ( decoder - > private_ - > tell_callback ( decoder , & upos , decoder - > private_ - > client_data ) ! = FLAC__STREAM_DECODER_TELL_STATUS_OK ) {
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEEK_ERROR ;
return false ;
}
last_pos = pos ;
pos = ( FLAC__int64 ) upos ;
pos - = FLAC__stream_decoder_get_input_bytes_unconsumed ( decoder ) ;
needs_seek = false ;
/*
* if we haven ' t hit the target frame yet and our position hasn ' t changed ,
* it means we ' re at the end of the stream and the seek target does not exist .
*/
if ( last_pos = = pos ) {
decoder - > protected_ - > state = FLAC__STREAM_DECODER_SEEK_ERROR ;
return false ;
}
}
}
if ( pos < ( FLAC__int64 ) lower_bound )
pos = ( FLAC__int64 ) lower_bound ;
last_frame_sample = this_frame_sample ;
}
}
return true ;
}
FLAC__StreamDecoderReadStatus file_read_callback_ ( const FLAC__StreamDecoder * decoder , FLAC__byte buffer [ ] , unsigned * bytes , void * client_data )
{
( void ) client_data ;
if ( * bytes > 0 ) {
* bytes = ( unsigned ) fread ( buffer , sizeof ( FLAC__byte ) , * bytes , decoder - > private_ - > file ) ;
if ( ferror ( decoder - > private_ - > file ) )
return FLAC__STREAM_DECODER_READ_STATUS_ABORT ;
else if ( * bytes = = 0 )
return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM ;
else
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE ;
}
else
return FLAC__STREAM_DECODER_READ_STATUS_ABORT ; /* abort to avoid a deadlock */
}
FLAC__StreamDecoderSeekStatus file_seek_callback_ ( const FLAC__StreamDecoder * decoder , FLAC__uint64 absolute_byte_offset , void * client_data )
{
( void ) client_data ;
if ( decoder - > private_ - > file = = stdin )
return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED ;
else if ( fseeko ( decoder - > private_ - > file , ( off_t ) absolute_byte_offset , SEEK_SET ) < 0 )
return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR ;
else
return FLAC__STREAM_DECODER_SEEK_STATUS_OK ;
}
FLAC__StreamDecoderTellStatus file_tell_callback_ ( const FLAC__StreamDecoder * decoder , FLAC__uint64 * absolute_byte_offset , void * client_data )
{
off_t pos ;
( void ) client_data ;
2006-10-10 00:39:27 +00:00
if ( decoder - > private_ - > file = = stdin )
2006-09-13 01:42:27 +00:00
return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED ;
else if ( ( pos = ftello ( decoder - > private_ - > file ) ) < 0 )
return FLAC__STREAM_DECODER_TELL_STATUS_ERROR ;
else {
* absolute_byte_offset = ( FLAC__uint64 ) pos ;
return FLAC__STREAM_DECODER_TELL_STATUS_OK ;
}
}
FLAC__StreamDecoderLengthStatus file_length_callback_ ( const FLAC__StreamDecoder * decoder , FLAC__uint64 * stream_length , void * client_data )
{
struct stat filestats ;
( void ) client_data ;
if ( decoder - > private_ - > file = = stdin )
return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED ;
else if ( fstat ( fileno ( decoder - > private_ - > file ) , & filestats ) ! = 0 )
return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR ;
else {
* stream_length = ( FLAC__uint64 ) filestats . st_size ;
return FLAC__STREAM_DECODER_LENGTH_STATUS_OK ;
}
}
FLAC__bool file_eof_callback_ ( const FLAC__StreamDecoder * decoder , void * client_data )
{
( void ) client_data ;
return feof ( decoder - > private_ - > file ) ? true : false ;
2000-12-10 04:09:52 +00:00
}