#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "share/compat.h"
#include "FLAC/assert.h"
#include "share/alloc.h"
#include "protected/stream_decoder.h"
#include "private/bitreader.h"
#include "private/bitmath.h"
#include "private/crc.h"
#include "private/fixed.h"
#include "private/format.h"
#include "private/lpc.h"
#include "private/md5.h"
#include "private/memory.h"
#include "private/macros.h"
FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC = …;
static const FLAC__byte ID3V2_TAG_[3] = …;
static void set_defaults_(FLAC__StreamDecoder *decoder);
static FILE *get_binary_stdin_(void);
static FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, uint32_t size, uint32_t channels, uint32_t bps);
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);
static FLAC__bool read_metadata_streaminfo_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, uint32_t length);
static FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, uint32_t length);
static FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj, uint32_t length);
static FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_CueSheet *obj);
static FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_Picture *obj);
static FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder);
static FLAC__bool frame_sync_(FLAC__StreamDecoder *decoder);
static FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FLAC__bool do_full_decode);
static FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder);
static FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, FLAC__bool do_full_decode);
static FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, FLAC__bool do_full_decode);
static FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, const uint32_t order, FLAC__bool do_full_decode);
static FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, const uint32_t order, FLAC__bool do_full_decode);
static FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, FLAC__bool do_full_decode);
static FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, uint32_t predictor_order, uint32_t partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, FLAC__int32 *residual, FLAC__bool is_extended);
static FLAC__bool read_zero_padding_(FLAC__StreamDecoder *decoder);
static void undo_channel_coding(FLAC__StreamDecoder *decoder);
static FLAC__bool read_callback_(FLAC__byte buffer[], size_t *bytes, void *client_data);
#if FLAC__HAS_OGG
static FLAC__StreamDecoderReadStatus read_callback_ogg_aspect_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes);
static FLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
#endif
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);
#if FLAC__HAS_OGG
static FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample);
#endif
static FLAC__StreamDecoderReadStatus file_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
static FLAC__StreamDecoderSeekStatus file_seek_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
static FLAC__StreamDecoderTellStatus file_tell_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
static FLAC__StreamDecoderLengthStatus file_length_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
static FLAC__bool file_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_data);
FLAC__StreamDecoderPrivate;
FLAC_API const char * const FLAC__StreamDecoderStateString[] = …;
FLAC_API const char * const FLAC__StreamDecoderInitStatusString[] = …;
FLAC_API const char * const FLAC__StreamDecoderReadStatusString[] = …;
FLAC_API const char * const FLAC__StreamDecoderSeekStatusString[] = …;
FLAC_API const char * const FLAC__StreamDecoderTellStatusString[] = …;
FLAC_API const char * const FLAC__StreamDecoderLengthStatusString[] = …;
FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[] = …;
FLAC_API const char * const FLAC__StreamDecoderErrorStatusString[] = …;
FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(void)
{ … }
FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder)
{ … }
static FLAC__StreamDecoderInitStatus init_stream_internal_(
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,
FLAC__bool is_ogg
)
{ … }
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
)
{ … }
FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_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
)
{ … }
static FLAC__StreamDecoderInitStatus init_FILE_internal_(
FLAC__StreamDecoder *decoder,
FILE *file,
FLAC__StreamDecoderWriteCallback write_callback,
FLAC__StreamDecoderMetadataCallback metadata_callback,
FLAC__StreamDecoderErrorCallback error_callback,
void *client_data,
FLAC__bool is_ogg
)
{ … }
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_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_FILE(
FLAC__StreamDecoder *decoder,
FILE *file,
FLAC__StreamDecoderWriteCallback write_callback,
FLAC__StreamDecoderMetadataCallback metadata_callback,
FLAC__StreamDecoderErrorCallback error_callback,
void *client_data
)
{ … }
static FLAC__StreamDecoderInitStatus init_file_internal_(
FLAC__StreamDecoder *decoder,
const char *filename,
FLAC__StreamDecoderWriteCallback write_callback,
FLAC__StreamDecoderMetadataCallback metadata_callback,
FLAC__StreamDecoderErrorCallback error_callback,
void *client_data,
FLAC__bool is_ogg
)
{ … }
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
)
{ … }
FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_file(
FLAC__StreamDecoder *decoder,
const char *filename,
FLAC__StreamDecoderWriteCallback write_callback,
FLAC__StreamDecoderMetadataCallback metadata_callback,
FLAC__StreamDecoderErrorCallback error_callback,
void *client_data
)
{ … }
FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder)
{ … }
FLAC_API FLAC__bool FLAC__stream_decoder_set_ogg_serial_number(FLAC__StreamDecoder *decoder, long value)
{ … }
FLAC_API FLAC__bool FLAC__stream_decoder_set_md5_checking(FLAC__StreamDecoder *decoder, FLAC__bool value)
{ … }
FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond(FLAC__StreamDecoder *decoder, FLAC__MetadataType type)
{ … }
FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4])
{ … }
FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_all(FLAC__StreamDecoder *decoder)
{ … }
FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore(FLAC__StreamDecoder *decoder, FLAC__MetadataType type)
{ … }
FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4])
{ … }
FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_all(FLAC__StreamDecoder *decoder)
{ … }
FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_get_state(const FLAC__StreamDecoder *decoder)
{ … }
FLAC_API const char *FLAC__stream_decoder_get_resolved_state_string(const FLAC__StreamDecoder *decoder)
{ … }
FLAC_API FLAC__bool FLAC__stream_decoder_get_md5_checking(const FLAC__StreamDecoder *decoder)
{ … }
FLAC_API FLAC__uint64 FLAC__stream_decoder_get_total_samples(const FLAC__StreamDecoder *decoder)
{ … }
FLAC_API uint32_t FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder)
{ … }
FLAC_API FLAC__ChannelAssignment FLAC__stream_decoder_get_channel_assignment(const FLAC__StreamDecoder *decoder)
{ … }
FLAC_API uint32_t FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder)
{ … }
FLAC_API uint32_t FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder)
{ … }
FLAC_API uint32_t FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder *decoder)
{ … }
FLAC_API FLAC__bool FLAC__stream_decoder_get_decode_position(const FLAC__StreamDecoder *decoder, FLAC__uint64 *position)
{ … }
FLAC_API const void *FLAC__stream_decoder_get_client_data(FLAC__StreamDecoder *decoder)
{ … }
FLAC_API FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder)
{ … }
FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder)
{ … }
FLAC_API FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *decoder)
{ … }
FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata(FLAC__StreamDecoder *decoder)
{ … }
FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder)
{ … }
FLAC_API FLAC__bool FLAC__stream_decoder_skip_single_frame(FLAC__StreamDecoder *decoder)
{ … }
FLAC_API FLAC__bool FLAC__stream_decoder_seek_absolute(FLAC__StreamDecoder *decoder, FLAC__uint64 sample)
{ … }
uint32_t FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder)
{ … }
void set_defaults_(FLAC__StreamDecoder *decoder)
{ … }
FILE *get_binary_stdin_(void)
{ … }
FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, uint32_t size, uint32_t channels, uint32_t bps)
{ … }
FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id)
{ … }
FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder)
{ … }
FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
{ … }
FLAC__bool read_metadata_streaminfo_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, uint32_t length)
{ … }
FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, uint32_t length)
{ … }
FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj, uint32_t length)
{ … }
FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_CueSheet *obj)
{ … }
FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_Picture *obj)
{ … }
FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder)
{ … }
FLAC__bool frame_sync_(FLAC__StreamDecoder *decoder)
{ … }
FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FLAC__bool do_full_decode)
{ … }
FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder)
{ … }
FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, FLAC__bool do_full_decode)
{ … }
FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, FLAC__bool do_full_decode)
{ … }
FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, const uint32_t order, FLAC__bool do_full_decode)
{ … }
FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, const uint32_t order, FLAC__bool do_full_decode)
{ … }
FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, FLAC__bool do_full_decode)
{ … }
FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, uint32_t predictor_order, uint32_t partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, FLAC__int32 *residual, FLAC__bool is_extended)
{ … }
FLAC__bool read_zero_padding_(FLAC__StreamDecoder *decoder)
{ … }
FLAC__bool read_callback_(FLAC__byte buffer[], size_t *bytes, void *client_data)
{ … }
#ifdef FUZZING_BUILD_MODE_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW
__attribute__((no_sanitize("signed-integer-overflow")))
#endif
void undo_channel_coding(FLAC__StreamDecoder *decoder) { … }
#if FLAC__HAS_OGG
FLAC__StreamDecoderReadStatus read_callback_ogg_aspect_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes)
{
switch(FLAC__ogg_decoder_aspect_read_callback_wrapper(&decoder->protected_->ogg_decoder_aspect, buffer, bytes, read_callback_proxy_, decoder, decoder->private_->client_data)) {
case FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK:
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
case FLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC:
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
case FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM:
return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
case FLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC:
case FLAC__OGG_DECODER_ASPECT_READ_STATUS_UNSUPPORTED_MAPPING_VERSION:
case FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT:
case FLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR:
case FLAC__OGG_DECODER_ASPECT_READ_STATUS_MEMORY_ALLOCATION_ERROR:
return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
default:
FLAC__ASSERT(0);
return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
}
}
FLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
{
FLAC__StreamDecoder *decoder = (FLAC__StreamDecoder*)void_decoder;
switch(decoder->private_->read_callback(decoder, buffer, bytes, client_data)) {
case FLAC__STREAM_DECODER_READ_STATUS_CONTINUE:
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK;
case FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM:
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM;
case FLAC__STREAM_DECODER_READ_STATUS_ABORT:
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT;
default:
FLAC__ASSERT(0);
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT;
}
}
#endif
FLAC__StreamDecoderWriteStatus write_audio_frame_to_client_(FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[])
{ … }
void send_error_to_client_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status)
{ … }
FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample)
{ … }
#if FLAC__HAS_OGG
FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample)
{
FLAC__uint64 left_pos = 0, right_pos = stream_length;
FLAC__uint64 left_sample = 0, right_sample = FLAC__stream_decoder_get_total_samples(decoder);
FLAC__uint64 this_frame_sample = (FLAC__uint64)0 - 1;
FLAC__uint64 pos = 0;
FLAC__bool did_a_seek;
uint32_t iteration = 0;
uint32_t BINARY_SEARCH_AFTER_ITERATION = 2;
static const FLAC__uint64 LINEAR_SEARCH_WITHIN_SAMPLES = FLAC__MAX_BLOCK_SIZE * 2;
if(right_sample == 0) {
right_sample = (FLAC__uint64)(-1);
BINARY_SEARCH_AFTER_ITERATION = 0;
}
decoder->private_->target_sample = target_sample;
for( ; ; iteration++) {
if(right_pos <= left_pos || right_pos - left_pos < 9) {
decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
return false;
}
if (iteration == 0 || this_frame_sample > target_sample || target_sample - this_frame_sample > LINEAR_SEARCH_WITHIN_SAMPLES) {
if (iteration >= BINARY_SEARCH_AFTER_ITERATION) {
pos = (right_pos + left_pos) / 2;
}
else {
#ifndef FLAC__INTEGER_ONLY_LIBRARY
pos = (FLAC__uint64)((double)(target_sample - left_sample) / (double)(right_sample - left_sample) * (double)(right_pos - left_pos));
#else
if ((target_sample-left_sample <= 0xffffffff) && (right_pos-left_pos <= 0xffffffff))
pos = (FLAC__int64)(((target_sample-left_sample) * (right_pos-left_pos)) / (right_sample-left_sample));
else
pos = (FLAC__int64)((((target_sample-left_sample)>>8) * ((right_pos-left_pos)>>8)) / ((right_sample-left_sample)>>16));
#endif
}
if(decoder->private_->seek_callback((FLAC__StreamDecoder*)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)) {
return false;
}
did_a_seek = true;
}
else
did_a_seek = false;
decoder->private_->got_a_frame = false;
if(!FLAC__stream_decoder_process_single(decoder) ||
decoder->protected_->state == FLAC__STREAM_DECODER_ABORTED) {
decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
return false;
}
if(!decoder->private_->got_a_frame) {
if(did_a_seek) {
right_pos = pos;
BINARY_SEARCH_AFTER_ITERATION = 0;
}
else {
decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
return false;
}
}
else if(!decoder->private_->is_seeking) {
break;
}
else {
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 (did_a_seek) {
if (this_frame_sample <= target_sample) {
FLAC__ASSERT(this_frame_sample != target_sample);
left_sample = this_frame_sample;
if (left_pos == pos) {
decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
return false;
}
left_pos = pos;
}
else {
right_sample = this_frame_sample;
if (right_pos == pos) {
decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
return false;
}
right_pos = pos;
}
}
}
}
return true;
}
#endif
FLAC__StreamDecoderReadStatus file_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
{ … }
FLAC__StreamDecoderSeekStatus file_seek_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
{ … }
FLAC__StreamDecoderTellStatus file_tell_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
{ … }
FLAC__StreamDecoderLengthStatus file_length_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
{ … }
FLAC__bool file_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_data)
{ … }