The "GR-PEACH_Audio_Playback_Sample" is a sample code that can provides high-resolution audio playback of FLAC format files. It also allows the user to audio-playback control functions such as play, pause, and stop by manipulating key switches.

Dependencies:   R_BSP TLV320_RBSP USBHost_custom

Note

For a sample program of with LCD Board,
please refer to GR-PEACH_Audio_Playback_7InchLCD_Sample.

Introduction

The "GR-PEACH_Audio_Playback_Sample" is a sample code that can provides high-resolution audio playback of FLAC format files. It also allows the user to audio-playback control functions such as play, pause, and stop by manipulating key switches.

1. Overview of the Sample Code

1.1 Software Block Diagram

Figure 1.1 shows the software block diagram.

/media/uploads/dkato/audioplayback_figure1_1x.png

1.2 Pin Definitions

Table 1.1 shows the pins that this sample code are to use.

/media/uploads/dkato/audioplayback_table1_1.png

2. Sample Code Operating Environment

This sample code runs in GR-PEACH + the Audio/Camera shield for the GR-PEACH environment. This section explains the functions of the ports that are used by this sample code.

2.1 Operating Environment

Figure 2.1 shows the configuration of the operating environment for running this sample code.

/media/uploads/dkato/audioplayback_figure2_1.png /media/uploads/1050186/figure2_2.png /media/uploads/dkato/audioplayback_figure2_3.png

2.2 List of User Operations

A list of user operations on the command line, TFT touch keys, and switch key that the user can perform for this sample code is shown in. Table 2.1.

/media/uploads/dkato/audioplayback_table2_1x.png

3. Function Outline

The functions of this sample code are summarized in Table 3.1 to Table 3.3.

/media/uploads/dkato/audioplayback_table3_1.png /media/uploads/dkato/audioplayback_table3_2.png /media/uploads/dkato/audioplayback_table3_3.png /media/uploads/dkato/audioplayback_figure3_1.png

3.1 Playback Control

The playback control that the sample code supports include play, pause, stop, skip to next, and skip to previous.

3.2 Trick Play Control

Manipulating "Repeat" alternates between "Repeat mode On" and "Repeat mode Off". The default mode is "Repeat mode On". When the repeat mode is on, the playback of the first song starts after the playback of the last song is finished. When the repeat mode is off, the sample code enters the stopped state after the playback of the last song is finished.

3.3 Acquisition of the Song Information

The information of the song being played is obtained by operating the "Play info" during the playback of the song. Table 3.4 lists the items of information that can be obtained by the "Play info" operation.

/media/uploads/dkato/audioplayback_table3_4.png

3.4 How the Folder Structure is Analyzed

The sample coded analyzes the folder structure in the breadth-first search order. The order in which files are numbered is illustrated in Table 3.5. The sample code does not sort the files by file or folder name.

/media/uploads/dkato/audioplayback_table3_5.png

4.Others

The default setting of serial communication (baud rate etc.) in mbed is shown the following link.
Please refer to the link and change the settings of your PC terminal software.
The default value of baud rate in mbed is 9600, and this application uses baud rate 9600.
https://developer.mbed.org/teams/Renesas/wiki/GR-PEACH-Getting-Started#install-the-usb-serial-communication

Committer:
dkato
Date:
Fri Oct 16 04:28:07 2015 +0000
Revision:
0:ee40da884cfc
first commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dkato 0:ee40da884cfc 1 /* libFLAC - Free Lossless Audio Codec library
dkato 0:ee40da884cfc 2 * Copyright (C) 2000-2009 Josh Coalson
dkato 0:ee40da884cfc 3 * Copyright (C) 2011-2014 Xiph.Org Foundation
dkato 0:ee40da884cfc 4 *
dkato 0:ee40da884cfc 5 * Redistribution and use in source and binary forms, with or without
dkato 0:ee40da884cfc 6 * modification, are permitted provided that the following conditions
dkato 0:ee40da884cfc 7 * are met:
dkato 0:ee40da884cfc 8 *
dkato 0:ee40da884cfc 9 * - Redistributions of source code must retain the above copyright
dkato 0:ee40da884cfc 10 * notice, this list of conditions and the following disclaimer.
dkato 0:ee40da884cfc 11 *
dkato 0:ee40da884cfc 12 * - Redistributions in binary form must reproduce the above copyright
dkato 0:ee40da884cfc 13 * notice, this list of conditions and the following disclaimer in the
dkato 0:ee40da884cfc 14 * documentation and/or other materials provided with the distribution.
dkato 0:ee40da884cfc 15 *
dkato 0:ee40da884cfc 16 * - Neither the name of the Xiph.org Foundation nor the names of its
dkato 0:ee40da884cfc 17 * contributors may be used to endorse or promote products derived from
dkato 0:ee40da884cfc 18 * this software without specific prior written permission.
dkato 0:ee40da884cfc 19 *
dkato 0:ee40da884cfc 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
dkato 0:ee40da884cfc 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
dkato 0:ee40da884cfc 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
dkato 0:ee40da884cfc 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
dkato 0:ee40da884cfc 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
dkato 0:ee40da884cfc 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
dkato 0:ee40da884cfc 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
dkato 0:ee40da884cfc 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
dkato 0:ee40da884cfc 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
dkato 0:ee40da884cfc 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
dkato 0:ee40da884cfc 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dkato 0:ee40da884cfc 31 */
dkato 0:ee40da884cfc 32
dkato 0:ee40da884cfc 33 #ifdef HAVE_CONFIG_H
dkato 0:ee40da884cfc 34 # include <config.h>
dkato 0:ee40da884cfc 35 #endif
dkato 0:ee40da884cfc 36
dkato 0:ee40da884cfc 37 #include <stdio.h>
dkato 0:ee40da884cfc 38 #include <stdlib.h> /* for malloc() */
dkato 0:ee40da884cfc 39 #include <string.h> /* for memset/memcpy() */
dkato 0:ee40da884cfc 40 #if(1) /* mbed */
dkato 0:ee40da884cfc 41 #else /* not mbed */
dkato 0:ee40da884cfc 42 #include <sys/stat.h> /* for stat() */
dkato 0:ee40da884cfc 43 #include <sys/types.h> /* for off_t */
dkato 0:ee40da884cfc 44 #endif /* end mbed */
dkato 0:ee40da884cfc 45 #include "share/compat.h"
dkato 0:ee40da884cfc 46 #include "FLAC/assert.h"
dkato 0:ee40da884cfc 47 #include "share/alloc.h"
dkato 0:ee40da884cfc 48 #include "protected/stream_decoder.h"
dkato 0:ee40da884cfc 49 #include "private/bitreader.h"
dkato 0:ee40da884cfc 50 #include "private/bitmath.h"
dkato 0:ee40da884cfc 51 #include "private/cpu.h"
dkato 0:ee40da884cfc 52 #include "private/crc.h"
dkato 0:ee40da884cfc 53 #include "private/fixed.h"
dkato 0:ee40da884cfc 54 #include "private/format.h"
dkato 0:ee40da884cfc 55 #include "private/lpc.h"
dkato 0:ee40da884cfc 56 #include "private/md5.h"
dkato 0:ee40da884cfc 57 #include "private/memory.h"
dkato 0:ee40da884cfc 58 #include "private/macros.h"
dkato 0:ee40da884cfc 59
dkato 0:ee40da884cfc 60
dkato 0:ee40da884cfc 61 /* technically this should be in an "export.c" but this is convenient enough */
dkato 0:ee40da884cfc 62 FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC =
dkato 0:ee40da884cfc 63 #if FLAC__HAS_OGG
dkato 0:ee40da884cfc 64 1
dkato 0:ee40da884cfc 65 #else
dkato 0:ee40da884cfc 66 0
dkato 0:ee40da884cfc 67 #endif
dkato 0:ee40da884cfc 68 ;
dkato 0:ee40da884cfc 69
dkato 0:ee40da884cfc 70
dkato 0:ee40da884cfc 71 /***********************************************************************
dkato 0:ee40da884cfc 72 *
dkato 0:ee40da884cfc 73 * Private static data
dkato 0:ee40da884cfc 74 *
dkato 0:ee40da884cfc 75 ***********************************************************************/
dkato 0:ee40da884cfc 76
dkato 0:ee40da884cfc 77 static const FLAC__byte ID3V2_TAG_[3] = { 'I', 'D', '3' };
dkato 0:ee40da884cfc 78
dkato 0:ee40da884cfc 79 /***********************************************************************
dkato 0:ee40da884cfc 80 *
dkato 0:ee40da884cfc 81 * Private class method prototypes
dkato 0:ee40da884cfc 82 *
dkato 0:ee40da884cfc 83 ***********************************************************************/
dkato 0:ee40da884cfc 84
dkato 0:ee40da884cfc 85 static void set_defaults_(FLAC__StreamDecoder *decoder);
dkato 0:ee40da884cfc 86 static FILE *get_binary_stdin_(void);
dkato 0:ee40da884cfc 87 static FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigned channels);
dkato 0:ee40da884cfc 88 static FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id);
dkato 0:ee40da884cfc 89 static FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder);
dkato 0:ee40da884cfc 90 static FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder);
dkato 0:ee40da884cfc 91 static FLAC__bool read_metadata_streaminfo_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length);
dkato 0:ee40da884cfc 92 static FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length);
dkato 0:ee40da884cfc 93 static FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj, unsigned length);
dkato 0:ee40da884cfc 94 static FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_CueSheet *obj);
dkato 0:ee40da884cfc 95 static FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_Picture *obj);
dkato 0:ee40da884cfc 96 static FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder);
dkato 0:ee40da884cfc 97 static FLAC__bool frame_sync_(FLAC__StreamDecoder *decoder);
dkato 0:ee40da884cfc 98 static FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FLAC__bool do_full_decode);
dkato 0:ee40da884cfc 99 static FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder);
dkato 0:ee40da884cfc 100 static FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode);
dkato 0:ee40da884cfc 101 static FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode);
dkato 0:ee40da884cfc 102 static FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode);
dkato 0:ee40da884cfc 103 static FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode);
dkato 0:ee40da884cfc 104 static FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode);
dkato 0:ee40da884cfc 105 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, FLAC__bool is_extended);
dkato 0:ee40da884cfc 106 static FLAC__bool read_zero_padding_(FLAC__StreamDecoder *decoder);
dkato 0:ee40da884cfc 107 static FLAC__bool read_callback_(FLAC__byte buffer[], size_t *bytes, void *client_data);
dkato 0:ee40da884cfc 108 #if FLAC__HAS_OGG
dkato 0:ee40da884cfc 109 static FLAC__StreamDecoderReadStatus read_callback_ogg_aspect_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes);
dkato 0:ee40da884cfc 110 static FLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
dkato 0:ee40da884cfc 111 #endif
dkato 0:ee40da884cfc 112 static FLAC__StreamDecoderWriteStatus write_audio_frame_to_client_(FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
dkato 0:ee40da884cfc 113 static void send_error_to_client_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status);
dkato 0:ee40da884cfc 114 static FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample);
dkato 0:ee40da884cfc 115 #if FLAC__HAS_OGG
dkato 0:ee40da884cfc 116 static FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample);
dkato 0:ee40da884cfc 117 #endif
dkato 0:ee40da884cfc 118 static FLAC__StreamDecoderReadStatus file_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
dkato 0:ee40da884cfc 119 static FLAC__StreamDecoderSeekStatus file_seek_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
dkato 0:ee40da884cfc 120 static FLAC__StreamDecoderTellStatus file_tell_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
dkato 0:ee40da884cfc 121 static FLAC__StreamDecoderLengthStatus file_length_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
dkato 0:ee40da884cfc 122 static FLAC__bool file_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_data);
dkato 0:ee40da884cfc 123
dkato 0:ee40da884cfc 124 /***********************************************************************
dkato 0:ee40da884cfc 125 *
dkato 0:ee40da884cfc 126 * Private class data
dkato 0:ee40da884cfc 127 *
dkato 0:ee40da884cfc 128 ***********************************************************************/
dkato 0:ee40da884cfc 129
dkato 0:ee40da884cfc 130 typedef struct FLAC__StreamDecoderPrivate {
dkato 0:ee40da884cfc 131 #if FLAC__HAS_OGG
dkato 0:ee40da884cfc 132 FLAC__bool is_ogg;
dkato 0:ee40da884cfc 133 #endif
dkato 0:ee40da884cfc 134 FLAC__StreamDecoderReadCallback read_callback;
dkato 0:ee40da884cfc 135 FLAC__StreamDecoderSeekCallback seek_callback;
dkato 0:ee40da884cfc 136 FLAC__StreamDecoderTellCallback tell_callback;
dkato 0:ee40da884cfc 137 FLAC__StreamDecoderLengthCallback length_callback;
dkato 0:ee40da884cfc 138 FLAC__StreamDecoderEofCallback eof_callback;
dkato 0:ee40da884cfc 139 FLAC__StreamDecoderWriteCallback write_callback;
dkato 0:ee40da884cfc 140 FLAC__StreamDecoderMetadataCallback metadata_callback;
dkato 0:ee40da884cfc 141 FLAC__StreamDecoderErrorCallback error_callback;
dkato 0:ee40da884cfc 142 /* generic 32-bit datapath: */
dkato 0:ee40da884cfc 143 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[]);
dkato 0:ee40da884cfc 144 /* generic 64-bit datapath: */
dkato 0:ee40da884cfc 145 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[]);
dkato 0:ee40da884cfc 146 /* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit): */
dkato 0:ee40da884cfc 147 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[]);
dkato 0:ee40da884cfc 148 void *client_data;
dkato 0:ee40da884cfc 149 FILE *file; /* only used if FLAC__stream_decoder_init_file()/FLAC__stream_decoder_init_file() called, else NULL */
dkato 0:ee40da884cfc 150 FLAC__BitReader *input;
dkato 0:ee40da884cfc 151 FLAC__int32 *output[FLAC__MAX_CHANNELS];
dkato 0:ee40da884cfc 152 FLAC__int32 *residual[FLAC__MAX_CHANNELS]; /* WATCHOUT: these are the aligned pointers; the real pointers that should be free()'d are residual_unaligned[] below */
dkato 0:ee40da884cfc 153 FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents[FLAC__MAX_CHANNELS];
dkato 0:ee40da884cfc 154 unsigned output_capacity, output_channels;
dkato 0:ee40da884cfc 155 FLAC__uint32 fixed_block_size, next_fixed_block_size;
dkato 0:ee40da884cfc 156 FLAC__uint64 samples_decoded;
dkato 0:ee40da884cfc 157 FLAC__bool has_stream_info, has_seek_table;
dkato 0:ee40da884cfc 158 FLAC__StreamMetadata stream_info;
dkato 0:ee40da884cfc 159 FLAC__StreamMetadata seek_table;
dkato 0:ee40da884cfc 160 FLAC__bool metadata_filter[128]; /* MAGIC number 128 == total number of metadata block types == 1 << 7 */
dkato 0:ee40da884cfc 161 FLAC__byte *metadata_filter_ids;
dkato 0:ee40da884cfc 162 size_t metadata_filter_ids_count, metadata_filter_ids_capacity; /* units for both are IDs, not bytes */
dkato 0:ee40da884cfc 163 FLAC__Frame frame;
dkato 0:ee40da884cfc 164 FLAC__bool cached; /* true if there is a byte in lookahead */
dkato 0:ee40da884cfc 165 FLAC__CPUInfo cpuinfo;
dkato 0:ee40da884cfc 166 FLAC__byte header_warmup[2]; /* contains the sync code and reserved bits */
dkato 0:ee40da884cfc 167 FLAC__byte lookahead; /* temp storage when we need to look ahead one byte in the stream */
dkato 0:ee40da884cfc 168 /* unaligned (original) pointers to allocated data */
dkato 0:ee40da884cfc 169 FLAC__int32 *residual_unaligned[FLAC__MAX_CHANNELS];
dkato 0:ee40da884cfc 170 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 */
dkato 0:ee40da884cfc 171 FLAC__bool internal_reset_hack; /* used only during init() so we can call reset to set up the decoder without rewinding the input */
dkato 0:ee40da884cfc 172 FLAC__bool is_seeking;
dkato 0:ee40da884cfc 173 FLAC__MD5Context md5context;
dkato 0:ee40da884cfc 174 FLAC__byte computed_md5sum[16]; /* this is the sum we computed from the decoded data */
dkato 0:ee40da884cfc 175 /* (the rest of these are only used for seeking) */
dkato 0:ee40da884cfc 176 FLAC__Frame last_frame; /* holds the info of the last frame we seeked to */
dkato 0:ee40da884cfc 177 FLAC__uint64 first_frame_offset; /* hint to the seek routine of where in the stream the first audio frame starts */
dkato 0:ee40da884cfc 178 FLAC__uint64 target_sample;
dkato 0:ee40da884cfc 179 unsigned unparseable_frame_count; /* used to tell whether we're decoding a future version of FLAC or just got a bad sync */
dkato 0:ee40da884cfc 180 #if FLAC__HAS_OGG
dkato 0:ee40da884cfc 181 FLAC__bool got_a_frame; /* hack needed in Ogg FLAC seek routine to check when process_single() actually writes a frame */
dkato 0:ee40da884cfc 182 #endif
dkato 0:ee40da884cfc 183 } FLAC__StreamDecoderPrivate;
dkato 0:ee40da884cfc 184
dkato 0:ee40da884cfc 185 /***********************************************************************
dkato 0:ee40da884cfc 186 *
dkato 0:ee40da884cfc 187 * Public static class data
dkato 0:ee40da884cfc 188 *
dkato 0:ee40da884cfc 189 ***********************************************************************/
dkato 0:ee40da884cfc 190
dkato 0:ee40da884cfc 191 FLAC_API const char * const FLAC__StreamDecoderStateString[] = {
dkato 0:ee40da884cfc 192 "FLAC__STREAM_DECODER_SEARCH_FOR_METADATA",
dkato 0:ee40da884cfc 193 "FLAC__STREAM_DECODER_READ_METADATA",
dkato 0:ee40da884cfc 194 "FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC",
dkato 0:ee40da884cfc 195 "FLAC__STREAM_DECODER_READ_FRAME",
dkato 0:ee40da884cfc 196 "FLAC__STREAM_DECODER_END_OF_STREAM",
dkato 0:ee40da884cfc 197 "FLAC__STREAM_DECODER_OGG_ERROR",
dkato 0:ee40da884cfc 198 "FLAC__STREAM_DECODER_SEEK_ERROR",
dkato 0:ee40da884cfc 199 "FLAC__STREAM_DECODER_ABORTED",
dkato 0:ee40da884cfc 200 "FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR",
dkato 0:ee40da884cfc 201 "FLAC__STREAM_DECODER_UNINITIALIZED"
dkato 0:ee40da884cfc 202 };
dkato 0:ee40da884cfc 203
dkato 0:ee40da884cfc 204 FLAC_API const char * const FLAC__StreamDecoderInitStatusString[] = {
dkato 0:ee40da884cfc 205 "FLAC__STREAM_DECODER_INIT_STATUS_OK",
dkato 0:ee40da884cfc 206 "FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER",
dkato 0:ee40da884cfc 207 "FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS",
dkato 0:ee40da884cfc 208 "FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR",
dkato 0:ee40da884cfc 209 "FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE",
dkato 0:ee40da884cfc 210 "FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED"
dkato 0:ee40da884cfc 211 };
dkato 0:ee40da884cfc 212
dkato 0:ee40da884cfc 213 FLAC_API const char * const FLAC__StreamDecoderReadStatusString[] = {
dkato 0:ee40da884cfc 214 "FLAC__STREAM_DECODER_READ_STATUS_CONTINUE",
dkato 0:ee40da884cfc 215 "FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM",
dkato 0:ee40da884cfc 216 "FLAC__STREAM_DECODER_READ_STATUS_ABORT"
dkato 0:ee40da884cfc 217 };
dkato 0:ee40da884cfc 218
dkato 0:ee40da884cfc 219 FLAC_API const char * const FLAC__StreamDecoderSeekStatusString[] = {
dkato 0:ee40da884cfc 220 "FLAC__STREAM_DECODER_SEEK_STATUS_OK",
dkato 0:ee40da884cfc 221 "FLAC__STREAM_DECODER_SEEK_STATUS_ERROR",
dkato 0:ee40da884cfc 222 "FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED"
dkato 0:ee40da884cfc 223 };
dkato 0:ee40da884cfc 224
dkato 0:ee40da884cfc 225 FLAC_API const char * const FLAC__StreamDecoderTellStatusString[] = {
dkato 0:ee40da884cfc 226 "FLAC__STREAM_DECODER_TELL_STATUS_OK",
dkato 0:ee40da884cfc 227 "FLAC__STREAM_DECODER_TELL_STATUS_ERROR",
dkato 0:ee40da884cfc 228 "FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED"
dkato 0:ee40da884cfc 229 };
dkato 0:ee40da884cfc 230
dkato 0:ee40da884cfc 231 FLAC_API const char * const FLAC__StreamDecoderLengthStatusString[] = {
dkato 0:ee40da884cfc 232 "FLAC__STREAM_DECODER_LENGTH_STATUS_OK",
dkato 0:ee40da884cfc 233 "FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR",
dkato 0:ee40da884cfc 234 "FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED"
dkato 0:ee40da884cfc 235 };
dkato 0:ee40da884cfc 236
dkato 0:ee40da884cfc 237 FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[] = {
dkato 0:ee40da884cfc 238 "FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE",
dkato 0:ee40da884cfc 239 "FLAC__STREAM_DECODER_WRITE_STATUS_ABORT"
dkato 0:ee40da884cfc 240 };
dkato 0:ee40da884cfc 241
dkato 0:ee40da884cfc 242 FLAC_API const char * const FLAC__StreamDecoderErrorStatusString[] = {
dkato 0:ee40da884cfc 243 "FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC",
dkato 0:ee40da884cfc 244 "FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER",
dkato 0:ee40da884cfc 245 "FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH",
dkato 0:ee40da884cfc 246 "FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM"
dkato 0:ee40da884cfc 247 };
dkato 0:ee40da884cfc 248
dkato 0:ee40da884cfc 249 /***********************************************************************
dkato 0:ee40da884cfc 250 *
dkato 0:ee40da884cfc 251 * Class constructor/destructor
dkato 0:ee40da884cfc 252 *
dkato 0:ee40da884cfc 253 ***********************************************************************/
dkato 0:ee40da884cfc 254 FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(void)
dkato 0:ee40da884cfc 255 {
dkato 0:ee40da884cfc 256 FLAC__StreamDecoder *decoder;
dkato 0:ee40da884cfc 257 unsigned i;
dkato 0:ee40da884cfc 258
dkato 0:ee40da884cfc 259 FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
dkato 0:ee40da884cfc 260
dkato 0:ee40da884cfc 261 decoder = calloc(1, sizeof(FLAC__StreamDecoder));
dkato 0:ee40da884cfc 262 if(decoder == 0) {
dkato 0:ee40da884cfc 263 return 0;
dkato 0:ee40da884cfc 264 }
dkato 0:ee40da884cfc 265
dkato 0:ee40da884cfc 266 decoder->protected_ = calloc(1, sizeof(FLAC__StreamDecoderProtected));
dkato 0:ee40da884cfc 267 if(decoder->protected_ == 0) {
dkato 0:ee40da884cfc 268 free(decoder);
dkato 0:ee40da884cfc 269 return 0;
dkato 0:ee40da884cfc 270 }
dkato 0:ee40da884cfc 271
dkato 0:ee40da884cfc 272 decoder->private_ = calloc(1, sizeof(FLAC__StreamDecoderPrivate));
dkato 0:ee40da884cfc 273 if(decoder->private_ == 0) {
dkato 0:ee40da884cfc 274 free(decoder->protected_);
dkato 0:ee40da884cfc 275 free(decoder);
dkato 0:ee40da884cfc 276 return 0;
dkato 0:ee40da884cfc 277 }
dkato 0:ee40da884cfc 278
dkato 0:ee40da884cfc 279 decoder->private_->input = FLAC__bitreader_new();
dkato 0:ee40da884cfc 280 if(decoder->private_->input == 0) {
dkato 0:ee40da884cfc 281 free(decoder->private_);
dkato 0:ee40da884cfc 282 free(decoder->protected_);
dkato 0:ee40da884cfc 283 free(decoder);
dkato 0:ee40da884cfc 284 return 0;
dkato 0:ee40da884cfc 285 }
dkato 0:ee40da884cfc 286
dkato 0:ee40da884cfc 287 decoder->private_->metadata_filter_ids_capacity = 16;
dkato 0:ee40da884cfc 288 if(0 == (decoder->private_->metadata_filter_ids = malloc((FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) * decoder->private_->metadata_filter_ids_capacity))) {
dkato 0:ee40da884cfc 289 FLAC__bitreader_delete(decoder->private_->input);
dkato 0:ee40da884cfc 290 free(decoder->private_);
dkato 0:ee40da884cfc 291 free(decoder->protected_);
dkato 0:ee40da884cfc 292 free(decoder);
dkato 0:ee40da884cfc 293 return 0;
dkato 0:ee40da884cfc 294 }
dkato 0:ee40da884cfc 295
dkato 0:ee40da884cfc 296 for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
dkato 0:ee40da884cfc 297 decoder->private_->output[i] = 0;
dkato 0:ee40da884cfc 298 decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0;
dkato 0:ee40da884cfc 299 }
dkato 0:ee40da884cfc 300
dkato 0:ee40da884cfc 301 decoder->private_->output_capacity = 0;
dkato 0:ee40da884cfc 302 decoder->private_->output_channels = 0;
dkato 0:ee40da884cfc 303 decoder->private_->has_seek_table = false;
dkato 0:ee40da884cfc 304
dkato 0:ee40da884cfc 305 for(i = 0; i < FLAC__MAX_CHANNELS; i++)
dkato 0:ee40da884cfc 306 FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&decoder->private_->partitioned_rice_contents[i]);
dkato 0:ee40da884cfc 307
dkato 0:ee40da884cfc 308 decoder->private_->file = 0;
dkato 0:ee40da884cfc 309
dkato 0:ee40da884cfc 310 set_defaults_(decoder);
dkato 0:ee40da884cfc 311
dkato 0:ee40da884cfc 312 decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED;
dkato 0:ee40da884cfc 313
dkato 0:ee40da884cfc 314 return decoder;
dkato 0:ee40da884cfc 315 }
dkato 0:ee40da884cfc 316
dkato 0:ee40da884cfc 317 FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 318 {
dkato 0:ee40da884cfc 319 unsigned i;
dkato 0:ee40da884cfc 320
dkato 0:ee40da884cfc 321 if (decoder == NULL)
dkato 0:ee40da884cfc 322 return ;
dkato 0:ee40da884cfc 323
dkato 0:ee40da884cfc 324 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 325 FLAC__ASSERT(0 != decoder->private_);
dkato 0:ee40da884cfc 326 FLAC__ASSERT(0 != decoder->private_->input);
dkato 0:ee40da884cfc 327
dkato 0:ee40da884cfc 328 (void)FLAC__stream_decoder_finish(decoder);
dkato 0:ee40da884cfc 329
dkato 0:ee40da884cfc 330 if(0 != decoder->private_->metadata_filter_ids)
dkato 0:ee40da884cfc 331 free(decoder->private_->metadata_filter_ids);
dkato 0:ee40da884cfc 332
dkato 0:ee40da884cfc 333 FLAC__bitreader_delete(decoder->private_->input);
dkato 0:ee40da884cfc 334
dkato 0:ee40da884cfc 335 for(i = 0; i < FLAC__MAX_CHANNELS; i++)
dkato 0:ee40da884cfc 336 FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&decoder->private_->partitioned_rice_contents[i]);
dkato 0:ee40da884cfc 337
dkato 0:ee40da884cfc 338 free(decoder->private_);
dkato 0:ee40da884cfc 339 free(decoder->protected_);
dkato 0:ee40da884cfc 340 free(decoder);
dkato 0:ee40da884cfc 341 }
dkato 0:ee40da884cfc 342
dkato 0:ee40da884cfc 343 /***********************************************************************
dkato 0:ee40da884cfc 344 *
dkato 0:ee40da884cfc 345 * Public class methods
dkato 0:ee40da884cfc 346 *
dkato 0:ee40da884cfc 347 ***********************************************************************/
dkato 0:ee40da884cfc 348
dkato 0:ee40da884cfc 349 static FLAC__StreamDecoderInitStatus init_stream_internal_(
dkato 0:ee40da884cfc 350 FLAC__StreamDecoder *decoder,
dkato 0:ee40da884cfc 351 FLAC__StreamDecoderReadCallback read_callback,
dkato 0:ee40da884cfc 352 FLAC__StreamDecoderSeekCallback seek_callback,
dkato 0:ee40da884cfc 353 FLAC__StreamDecoderTellCallback tell_callback,
dkato 0:ee40da884cfc 354 FLAC__StreamDecoderLengthCallback length_callback,
dkato 0:ee40da884cfc 355 FLAC__StreamDecoderEofCallback eof_callback,
dkato 0:ee40da884cfc 356 FLAC__StreamDecoderWriteCallback write_callback,
dkato 0:ee40da884cfc 357 FLAC__StreamDecoderMetadataCallback metadata_callback,
dkato 0:ee40da884cfc 358 FLAC__StreamDecoderErrorCallback error_callback,
dkato 0:ee40da884cfc 359 void *client_data,
dkato 0:ee40da884cfc 360 FLAC__bool is_ogg
dkato 0:ee40da884cfc 361 )
dkato 0:ee40da884cfc 362 {
dkato 0:ee40da884cfc 363 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 364
dkato 0:ee40da884cfc 365 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
dkato 0:ee40da884cfc 366 return FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED;
dkato 0:ee40da884cfc 367
dkato 0:ee40da884cfc 368 #if !FLAC__HAS_OGG
dkato 0:ee40da884cfc 369 if(is_ogg)
dkato 0:ee40da884cfc 370 return FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER;
dkato 0:ee40da884cfc 371 #endif
dkato 0:ee40da884cfc 372
dkato 0:ee40da884cfc 373 if(
dkato 0:ee40da884cfc 374 0 == read_callback ||
dkato 0:ee40da884cfc 375 0 == write_callback ||
dkato 0:ee40da884cfc 376 0 == error_callback ||
dkato 0:ee40da884cfc 377 (seek_callback && (0 == tell_callback || 0 == length_callback || 0 == eof_callback))
dkato 0:ee40da884cfc 378 )
dkato 0:ee40da884cfc 379 return FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS;
dkato 0:ee40da884cfc 380
dkato 0:ee40da884cfc 381 #if FLAC__HAS_OGG
dkato 0:ee40da884cfc 382 decoder->private_->is_ogg = is_ogg;
dkato 0:ee40da884cfc 383 if(is_ogg && !FLAC__ogg_decoder_aspect_init(&decoder->protected_->ogg_decoder_aspect))
dkato 0:ee40da884cfc 384 return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE;
dkato 0:ee40da884cfc 385 #endif
dkato 0:ee40da884cfc 386
dkato 0:ee40da884cfc 387 /*
dkato 0:ee40da884cfc 388 * get the CPU info and set the function pointers
dkato 0:ee40da884cfc 389 */
dkato 0:ee40da884cfc 390 FLAC__cpu_info(&decoder->private_->cpuinfo);
dkato 0:ee40da884cfc 391 /* first default to the non-asm routines */
dkato 0:ee40da884cfc 392 decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal;
dkato 0:ee40da884cfc 393 decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide;
dkato 0:ee40da884cfc 394 decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal;
dkato 0:ee40da884cfc 395 /* now override with asm where appropriate */
dkato 0:ee40da884cfc 396 #ifndef FLAC__NO_ASM
dkato 0:ee40da884cfc 397 if(decoder->private_->cpuinfo.use_asm) {
dkato 0:ee40da884cfc 398 #ifdef FLAC__CPU_IA32
dkato 0:ee40da884cfc 399 FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32);
dkato 0:ee40da884cfc 400 #ifdef FLAC__HAS_NASM
dkato 0:ee40da884cfc 401 decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide_asm_ia32; /* OPT_IA32: was really necessary for GCC < 4.9 */
dkato 0:ee40da884cfc 402 if(decoder->private_->cpuinfo.ia32.mmx) {
dkato 0:ee40da884cfc 403 decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32;
dkato 0:ee40da884cfc 404 decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32_mmx;
dkato 0:ee40da884cfc 405 }
dkato 0:ee40da884cfc 406 else {
dkato 0:ee40da884cfc 407 decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32;
dkato 0:ee40da884cfc 408 decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32;
dkato 0:ee40da884cfc 409 }
dkato 0:ee40da884cfc 410 #endif
dkato 0:ee40da884cfc 411 #ifdef FLAC__HAS_X86INTRIN
dkato 0:ee40da884cfc 412 # if defined FLAC__SSE2_SUPPORTED && !defined FLAC__HAS_NASM /* OPT_SSE: not better than MMX asm */
dkato 0:ee40da884cfc 413 if(decoder->private_->cpuinfo.ia32.sse2) {
dkato 0:ee40da884cfc 414 decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_16_intrin_sse2;
dkato 0:ee40da884cfc 415 }
dkato 0:ee40da884cfc 416 # endif
dkato 0:ee40da884cfc 417 # if defined FLAC__SSE4_1_SUPPORTED
dkato 0:ee40da884cfc 418 if(decoder->private_->cpuinfo.ia32.sse41) {
dkato 0:ee40da884cfc 419 decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide_intrin_sse41;
dkato 0:ee40da884cfc 420 }
dkato 0:ee40da884cfc 421 # endif
dkato 0:ee40da884cfc 422 #endif
dkato 0:ee40da884cfc 423 #elif defined FLAC__CPU_X86_64
dkato 0:ee40da884cfc 424 FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_X86_64);
dkato 0:ee40da884cfc 425 /* No useful SSE optimizations yet */
dkato 0:ee40da884cfc 426 #endif
dkato 0:ee40da884cfc 427 }
dkato 0:ee40da884cfc 428 #endif
dkato 0:ee40da884cfc 429
dkato 0:ee40da884cfc 430 /* from here on, errors are fatal */
dkato 0:ee40da884cfc 431
dkato 0:ee40da884cfc 432 if(!FLAC__bitreader_init(decoder->private_->input, read_callback_, decoder)) {
dkato 0:ee40da884cfc 433 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
dkato 0:ee40da884cfc 434 return FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR;
dkato 0:ee40da884cfc 435 }
dkato 0:ee40da884cfc 436
dkato 0:ee40da884cfc 437 decoder->private_->read_callback = read_callback;
dkato 0:ee40da884cfc 438 decoder->private_->seek_callback = seek_callback;
dkato 0:ee40da884cfc 439 decoder->private_->tell_callback = tell_callback;
dkato 0:ee40da884cfc 440 decoder->private_->length_callback = length_callback;
dkato 0:ee40da884cfc 441 decoder->private_->eof_callback = eof_callback;
dkato 0:ee40da884cfc 442 decoder->private_->write_callback = write_callback;
dkato 0:ee40da884cfc 443 decoder->private_->metadata_callback = metadata_callback;
dkato 0:ee40da884cfc 444 decoder->private_->error_callback = error_callback;
dkato 0:ee40da884cfc 445 decoder->private_->client_data = client_data;
dkato 0:ee40da884cfc 446 decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size = 0;
dkato 0:ee40da884cfc 447 decoder->private_->samples_decoded = 0;
dkato 0:ee40da884cfc 448 decoder->private_->has_stream_info = false;
dkato 0:ee40da884cfc 449 decoder->private_->cached = false;
dkato 0:ee40da884cfc 450
dkato 0:ee40da884cfc 451 decoder->private_->do_md5_checking = decoder->protected_->md5_checking;
dkato 0:ee40da884cfc 452 decoder->private_->is_seeking = false;
dkato 0:ee40da884cfc 453
dkato 0:ee40da884cfc 454 decoder->private_->internal_reset_hack = true; /* so the following reset does not try to rewind the input */
dkato 0:ee40da884cfc 455 if(!FLAC__stream_decoder_reset(decoder)) {
dkato 0:ee40da884cfc 456 /* above call sets the state for us */
dkato 0:ee40da884cfc 457 return FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR;
dkato 0:ee40da884cfc 458 }
dkato 0:ee40da884cfc 459
dkato 0:ee40da884cfc 460 return FLAC__STREAM_DECODER_INIT_STATUS_OK;
dkato 0:ee40da884cfc 461 }
dkato 0:ee40da884cfc 462
dkato 0:ee40da884cfc 463 FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_stream(
dkato 0:ee40da884cfc 464 FLAC__StreamDecoder *decoder,
dkato 0:ee40da884cfc 465 FLAC__StreamDecoderReadCallback read_callback,
dkato 0:ee40da884cfc 466 FLAC__StreamDecoderSeekCallback seek_callback,
dkato 0:ee40da884cfc 467 FLAC__StreamDecoderTellCallback tell_callback,
dkato 0:ee40da884cfc 468 FLAC__StreamDecoderLengthCallback length_callback,
dkato 0:ee40da884cfc 469 FLAC__StreamDecoderEofCallback eof_callback,
dkato 0:ee40da884cfc 470 FLAC__StreamDecoderWriteCallback write_callback,
dkato 0:ee40da884cfc 471 FLAC__StreamDecoderMetadataCallback metadata_callback,
dkato 0:ee40da884cfc 472 FLAC__StreamDecoderErrorCallback error_callback,
dkato 0:ee40da884cfc 473 void *client_data
dkato 0:ee40da884cfc 474 )
dkato 0:ee40da884cfc 475 {
dkato 0:ee40da884cfc 476 return init_stream_internal_(
dkato 0:ee40da884cfc 477 decoder,
dkato 0:ee40da884cfc 478 read_callback,
dkato 0:ee40da884cfc 479 seek_callback,
dkato 0:ee40da884cfc 480 tell_callback,
dkato 0:ee40da884cfc 481 length_callback,
dkato 0:ee40da884cfc 482 eof_callback,
dkato 0:ee40da884cfc 483 write_callback,
dkato 0:ee40da884cfc 484 metadata_callback,
dkato 0:ee40da884cfc 485 error_callback,
dkato 0:ee40da884cfc 486 client_data,
dkato 0:ee40da884cfc 487 /*is_ogg=*/false
dkato 0:ee40da884cfc 488 );
dkato 0:ee40da884cfc 489 }
dkato 0:ee40da884cfc 490
dkato 0:ee40da884cfc 491 FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_stream(
dkato 0:ee40da884cfc 492 FLAC__StreamDecoder *decoder,
dkato 0:ee40da884cfc 493 FLAC__StreamDecoderReadCallback read_callback,
dkato 0:ee40da884cfc 494 FLAC__StreamDecoderSeekCallback seek_callback,
dkato 0:ee40da884cfc 495 FLAC__StreamDecoderTellCallback tell_callback,
dkato 0:ee40da884cfc 496 FLAC__StreamDecoderLengthCallback length_callback,
dkato 0:ee40da884cfc 497 FLAC__StreamDecoderEofCallback eof_callback,
dkato 0:ee40da884cfc 498 FLAC__StreamDecoderWriteCallback write_callback,
dkato 0:ee40da884cfc 499 FLAC__StreamDecoderMetadataCallback metadata_callback,
dkato 0:ee40da884cfc 500 FLAC__StreamDecoderErrorCallback error_callback,
dkato 0:ee40da884cfc 501 void *client_data
dkato 0:ee40da884cfc 502 )
dkato 0:ee40da884cfc 503 {
dkato 0:ee40da884cfc 504 return init_stream_internal_(
dkato 0:ee40da884cfc 505 decoder,
dkato 0:ee40da884cfc 506 read_callback,
dkato 0:ee40da884cfc 507 seek_callback,
dkato 0:ee40da884cfc 508 tell_callback,
dkato 0:ee40da884cfc 509 length_callback,
dkato 0:ee40da884cfc 510 eof_callback,
dkato 0:ee40da884cfc 511 write_callback,
dkato 0:ee40da884cfc 512 metadata_callback,
dkato 0:ee40da884cfc 513 error_callback,
dkato 0:ee40da884cfc 514 client_data,
dkato 0:ee40da884cfc 515 /*is_ogg=*/true
dkato 0:ee40da884cfc 516 );
dkato 0:ee40da884cfc 517 }
dkato 0:ee40da884cfc 518
dkato 0:ee40da884cfc 519 static FLAC__StreamDecoderInitStatus init_FILE_internal_(
dkato 0:ee40da884cfc 520 FLAC__StreamDecoder *decoder,
dkato 0:ee40da884cfc 521 FILE *file,
dkato 0:ee40da884cfc 522 FLAC__StreamDecoderWriteCallback write_callback,
dkato 0:ee40da884cfc 523 FLAC__StreamDecoderMetadataCallback metadata_callback,
dkato 0:ee40da884cfc 524 FLAC__StreamDecoderErrorCallback error_callback,
dkato 0:ee40da884cfc 525 void *client_data,
dkato 0:ee40da884cfc 526 FLAC__bool is_ogg
dkato 0:ee40da884cfc 527 )
dkato 0:ee40da884cfc 528 {
dkato 0:ee40da884cfc 529 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 530 FLAC__ASSERT(0 != file);
dkato 0:ee40da884cfc 531
dkato 0:ee40da884cfc 532 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
dkato 0:ee40da884cfc 533 return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED;
dkato 0:ee40da884cfc 534
dkato 0:ee40da884cfc 535 if(0 == write_callback || 0 == error_callback)
dkato 0:ee40da884cfc 536 return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS;
dkato 0:ee40da884cfc 537
dkato 0:ee40da884cfc 538 /*
dkato 0:ee40da884cfc 539 * To make sure that our file does not go unclosed after an error, we
dkato 0:ee40da884cfc 540 * must assign the FILE pointer before any further error can occur in
dkato 0:ee40da884cfc 541 * this routine.
dkato 0:ee40da884cfc 542 */
dkato 0:ee40da884cfc 543 if(file == stdin)
dkato 0:ee40da884cfc 544 file = get_binary_stdin_(); /* just to be safe */
dkato 0:ee40da884cfc 545
dkato 0:ee40da884cfc 546 decoder->private_->file = file;
dkato 0:ee40da884cfc 547
dkato 0:ee40da884cfc 548 return init_stream_internal_(
dkato 0:ee40da884cfc 549 decoder,
dkato 0:ee40da884cfc 550 file_read_callback_,
dkato 0:ee40da884cfc 551 decoder->private_->file == stdin? 0: file_seek_callback_,
dkato 0:ee40da884cfc 552 decoder->private_->file == stdin? 0: file_tell_callback_,
dkato 0:ee40da884cfc 553 decoder->private_->file == stdin? 0: file_length_callback_,
dkato 0:ee40da884cfc 554 file_eof_callback_,
dkato 0:ee40da884cfc 555 write_callback,
dkato 0:ee40da884cfc 556 metadata_callback,
dkato 0:ee40da884cfc 557 error_callback,
dkato 0:ee40da884cfc 558 client_data,
dkato 0:ee40da884cfc 559 is_ogg
dkato 0:ee40da884cfc 560 );
dkato 0:ee40da884cfc 561 }
dkato 0:ee40da884cfc 562
dkato 0:ee40da884cfc 563 FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_FILE(
dkato 0:ee40da884cfc 564 FLAC__StreamDecoder *decoder,
dkato 0:ee40da884cfc 565 FILE *file,
dkato 0:ee40da884cfc 566 FLAC__StreamDecoderWriteCallback write_callback,
dkato 0:ee40da884cfc 567 FLAC__StreamDecoderMetadataCallback metadata_callback,
dkato 0:ee40da884cfc 568 FLAC__StreamDecoderErrorCallback error_callback,
dkato 0:ee40da884cfc 569 void *client_data
dkato 0:ee40da884cfc 570 )
dkato 0:ee40da884cfc 571 {
dkato 0:ee40da884cfc 572 return init_FILE_internal_(decoder, file, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/false);
dkato 0:ee40da884cfc 573 }
dkato 0:ee40da884cfc 574
dkato 0:ee40da884cfc 575 FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_FILE(
dkato 0:ee40da884cfc 576 FLAC__StreamDecoder *decoder,
dkato 0:ee40da884cfc 577 FILE *file,
dkato 0:ee40da884cfc 578 FLAC__StreamDecoderWriteCallback write_callback,
dkato 0:ee40da884cfc 579 FLAC__StreamDecoderMetadataCallback metadata_callback,
dkato 0:ee40da884cfc 580 FLAC__StreamDecoderErrorCallback error_callback,
dkato 0:ee40da884cfc 581 void *client_data
dkato 0:ee40da884cfc 582 )
dkato 0:ee40da884cfc 583 {
dkato 0:ee40da884cfc 584 return init_FILE_internal_(decoder, file, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/true);
dkato 0:ee40da884cfc 585 }
dkato 0:ee40da884cfc 586
dkato 0:ee40da884cfc 587 static FLAC__StreamDecoderInitStatus init_file_internal_(
dkato 0:ee40da884cfc 588 FLAC__StreamDecoder *decoder,
dkato 0:ee40da884cfc 589 const char *filename,
dkato 0:ee40da884cfc 590 FLAC__StreamDecoderWriteCallback write_callback,
dkato 0:ee40da884cfc 591 FLAC__StreamDecoderMetadataCallback metadata_callback,
dkato 0:ee40da884cfc 592 FLAC__StreamDecoderErrorCallback error_callback,
dkato 0:ee40da884cfc 593 void *client_data,
dkato 0:ee40da884cfc 594 FLAC__bool is_ogg
dkato 0:ee40da884cfc 595 )
dkato 0:ee40da884cfc 596 {
dkato 0:ee40da884cfc 597 FILE *file;
dkato 0:ee40da884cfc 598
dkato 0:ee40da884cfc 599 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 600
dkato 0:ee40da884cfc 601 /*
dkato 0:ee40da884cfc 602 * To make sure that our file does not go unclosed after an error, we
dkato 0:ee40da884cfc 603 * have to do the same entrance checks here that are later performed
dkato 0:ee40da884cfc 604 * in FLAC__stream_decoder_init_FILE() before the FILE* is assigned.
dkato 0:ee40da884cfc 605 */
dkato 0:ee40da884cfc 606 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
dkato 0:ee40da884cfc 607 return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED;
dkato 0:ee40da884cfc 608
dkato 0:ee40da884cfc 609 if(0 == write_callback || 0 == error_callback)
dkato 0:ee40da884cfc 610 return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS;
dkato 0:ee40da884cfc 611
dkato 0:ee40da884cfc 612 file = filename? flac_fopen(filename, "rb") : stdin;
dkato 0:ee40da884cfc 613
dkato 0:ee40da884cfc 614 if(0 == file)
dkato 0:ee40da884cfc 615 return FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE;
dkato 0:ee40da884cfc 616
dkato 0:ee40da884cfc 617 return init_FILE_internal_(decoder, file, write_callback, metadata_callback, error_callback, client_data, is_ogg);
dkato 0:ee40da884cfc 618 }
dkato 0:ee40da884cfc 619
dkato 0:ee40da884cfc 620 FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_file(
dkato 0:ee40da884cfc 621 FLAC__StreamDecoder *decoder,
dkato 0:ee40da884cfc 622 const char *filename,
dkato 0:ee40da884cfc 623 FLAC__StreamDecoderWriteCallback write_callback,
dkato 0:ee40da884cfc 624 FLAC__StreamDecoderMetadataCallback metadata_callback,
dkato 0:ee40da884cfc 625 FLAC__StreamDecoderErrorCallback error_callback,
dkato 0:ee40da884cfc 626 void *client_data
dkato 0:ee40da884cfc 627 )
dkato 0:ee40da884cfc 628 {
dkato 0:ee40da884cfc 629 return init_file_internal_(decoder, filename, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/false);
dkato 0:ee40da884cfc 630 }
dkato 0:ee40da884cfc 631
dkato 0:ee40da884cfc 632 FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_file(
dkato 0:ee40da884cfc 633 FLAC__StreamDecoder *decoder,
dkato 0:ee40da884cfc 634 const char *filename,
dkato 0:ee40da884cfc 635 FLAC__StreamDecoderWriteCallback write_callback,
dkato 0:ee40da884cfc 636 FLAC__StreamDecoderMetadataCallback metadata_callback,
dkato 0:ee40da884cfc 637 FLAC__StreamDecoderErrorCallback error_callback,
dkato 0:ee40da884cfc 638 void *client_data
dkato 0:ee40da884cfc 639 )
dkato 0:ee40da884cfc 640 {
dkato 0:ee40da884cfc 641 return init_file_internal_(decoder, filename, write_callback, metadata_callback, error_callback, client_data, /*is_ogg=*/true);
dkato 0:ee40da884cfc 642 }
dkato 0:ee40da884cfc 643
dkato 0:ee40da884cfc 644 FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 645 {
dkato 0:ee40da884cfc 646 FLAC__bool md5_failed = false;
dkato 0:ee40da884cfc 647 unsigned i;
dkato 0:ee40da884cfc 648
dkato 0:ee40da884cfc 649 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 650 FLAC__ASSERT(0 != decoder->private_);
dkato 0:ee40da884cfc 651 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 652
dkato 0:ee40da884cfc 653 if(decoder->protected_->state == FLAC__STREAM_DECODER_UNINITIALIZED)
dkato 0:ee40da884cfc 654 return true;
dkato 0:ee40da884cfc 655
dkato 0:ee40da884cfc 656 /* see the comment in FLAC__stream_decoder_reset() as to why we
dkato 0:ee40da884cfc 657 * always call FLAC__MD5Final()
dkato 0:ee40da884cfc 658 */
dkato 0:ee40da884cfc 659 FLAC__MD5Final(decoder->private_->computed_md5sum, &decoder->private_->md5context);
dkato 0:ee40da884cfc 660
dkato 0:ee40da884cfc 661 if(decoder->private_->has_seek_table && 0 != decoder->private_->seek_table.data.seek_table.points) {
dkato 0:ee40da884cfc 662 free(decoder->private_->seek_table.data.seek_table.points);
dkato 0:ee40da884cfc 663 decoder->private_->seek_table.data.seek_table.points = 0;
dkato 0:ee40da884cfc 664 decoder->private_->has_seek_table = false;
dkato 0:ee40da884cfc 665 }
dkato 0:ee40da884cfc 666 FLAC__bitreader_free(decoder->private_->input);
dkato 0:ee40da884cfc 667 for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
dkato 0:ee40da884cfc 668 /* WATCHOUT:
dkato 0:ee40da884cfc 669 * FLAC__lpc_restore_signal_asm_ia32_mmx() requires that the
dkato 0:ee40da884cfc 670 * output arrays have a buffer of up to 3 zeroes in front
dkato 0:ee40da884cfc 671 * (at negative indices) for alignment purposes; we use 4
dkato 0:ee40da884cfc 672 * to keep the data well-aligned.
dkato 0:ee40da884cfc 673 */
dkato 0:ee40da884cfc 674 if(0 != decoder->private_->output[i]) {
dkato 0:ee40da884cfc 675 free(decoder->private_->output[i]-4);
dkato 0:ee40da884cfc 676 decoder->private_->output[i] = 0;
dkato 0:ee40da884cfc 677 }
dkato 0:ee40da884cfc 678 if(0 != decoder->private_->residual_unaligned[i]) {
dkato 0:ee40da884cfc 679 free(decoder->private_->residual_unaligned[i]);
dkato 0:ee40da884cfc 680 decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0;
dkato 0:ee40da884cfc 681 }
dkato 0:ee40da884cfc 682 }
dkato 0:ee40da884cfc 683 decoder->private_->output_capacity = 0;
dkato 0:ee40da884cfc 684 decoder->private_->output_channels = 0;
dkato 0:ee40da884cfc 685
dkato 0:ee40da884cfc 686 #if FLAC__HAS_OGG
dkato 0:ee40da884cfc 687 if(decoder->private_->is_ogg)
dkato 0:ee40da884cfc 688 FLAC__ogg_decoder_aspect_finish(&decoder->protected_->ogg_decoder_aspect);
dkato 0:ee40da884cfc 689 #endif
dkato 0:ee40da884cfc 690
dkato 0:ee40da884cfc 691 if(0 != decoder->private_->file) {
dkato 0:ee40da884cfc 692 if(decoder->private_->file != stdin)
dkato 0:ee40da884cfc 693 fclose(decoder->private_->file);
dkato 0:ee40da884cfc 694 decoder->private_->file = 0;
dkato 0:ee40da884cfc 695 }
dkato 0:ee40da884cfc 696
dkato 0:ee40da884cfc 697 if(decoder->private_->do_md5_checking) {
dkato 0:ee40da884cfc 698 if(memcmp(decoder->private_->stream_info.data.stream_info.md5sum, decoder->private_->computed_md5sum, 16))
dkato 0:ee40da884cfc 699 md5_failed = true;
dkato 0:ee40da884cfc 700 }
dkato 0:ee40da884cfc 701 decoder->private_->is_seeking = false;
dkato 0:ee40da884cfc 702
dkato 0:ee40da884cfc 703 set_defaults_(decoder);
dkato 0:ee40da884cfc 704
dkato 0:ee40da884cfc 705 decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED;
dkato 0:ee40da884cfc 706
dkato 0:ee40da884cfc 707 return !md5_failed;
dkato 0:ee40da884cfc 708 }
dkato 0:ee40da884cfc 709
dkato 0:ee40da884cfc 710 FLAC_API FLAC__bool FLAC__stream_decoder_set_ogg_serial_number(FLAC__StreamDecoder *decoder, long value)
dkato 0:ee40da884cfc 711 {
dkato 0:ee40da884cfc 712 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 713 FLAC__ASSERT(0 != decoder->private_);
dkato 0:ee40da884cfc 714 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 715 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
dkato 0:ee40da884cfc 716 return false;
dkato 0:ee40da884cfc 717 #if FLAC__HAS_OGG
dkato 0:ee40da884cfc 718 /* can't check decoder->private_->is_ogg since that's not set until init time */
dkato 0:ee40da884cfc 719 FLAC__ogg_decoder_aspect_set_serial_number(&decoder->protected_->ogg_decoder_aspect, value);
dkato 0:ee40da884cfc 720 return true;
dkato 0:ee40da884cfc 721 #else
dkato 0:ee40da884cfc 722 (void)value;
dkato 0:ee40da884cfc 723 return false;
dkato 0:ee40da884cfc 724 #endif
dkato 0:ee40da884cfc 725 }
dkato 0:ee40da884cfc 726
dkato 0:ee40da884cfc 727 FLAC_API FLAC__bool FLAC__stream_decoder_set_md5_checking(FLAC__StreamDecoder *decoder, FLAC__bool value)
dkato 0:ee40da884cfc 728 {
dkato 0:ee40da884cfc 729 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 730 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 731 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
dkato 0:ee40da884cfc 732 return false;
dkato 0:ee40da884cfc 733 decoder->protected_->md5_checking = value;
dkato 0:ee40da884cfc 734 return true;
dkato 0:ee40da884cfc 735 }
dkato 0:ee40da884cfc 736
dkato 0:ee40da884cfc 737 FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond(FLAC__StreamDecoder *decoder, FLAC__MetadataType type)
dkato 0:ee40da884cfc 738 {
dkato 0:ee40da884cfc 739 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 740 FLAC__ASSERT(0 != decoder->private_);
dkato 0:ee40da884cfc 741 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 742 FLAC__ASSERT((unsigned)type <= FLAC__MAX_METADATA_TYPE_CODE);
dkato 0:ee40da884cfc 743 /* double protection */
dkato 0:ee40da884cfc 744 if((unsigned)type > FLAC__MAX_METADATA_TYPE_CODE)
dkato 0:ee40da884cfc 745 return false;
dkato 0:ee40da884cfc 746 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
dkato 0:ee40da884cfc 747 return false;
dkato 0:ee40da884cfc 748 decoder->private_->metadata_filter[type] = true;
dkato 0:ee40da884cfc 749 if(type == FLAC__METADATA_TYPE_APPLICATION)
dkato 0:ee40da884cfc 750 decoder->private_->metadata_filter_ids_count = 0;
dkato 0:ee40da884cfc 751 return true;
dkato 0:ee40da884cfc 752 }
dkato 0:ee40da884cfc 753
dkato 0:ee40da884cfc 754 FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4])
dkato 0:ee40da884cfc 755 {
dkato 0:ee40da884cfc 756 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 757 FLAC__ASSERT(0 != decoder->private_);
dkato 0:ee40da884cfc 758 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 759 FLAC__ASSERT(0 != id);
dkato 0:ee40da884cfc 760 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
dkato 0:ee40da884cfc 761 return false;
dkato 0:ee40da884cfc 762
dkato 0:ee40da884cfc 763 if(decoder->private_->metadata_filter[FLAC__METADATA_TYPE_APPLICATION])
dkato 0:ee40da884cfc 764 return true;
dkato 0:ee40da884cfc 765
dkato 0:ee40da884cfc 766 FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids);
dkato 0:ee40da884cfc 767
dkato 0:ee40da884cfc 768 if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) {
dkato 0:ee40da884cfc 769 if(0 == (decoder->private_->metadata_filter_ids = safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2))) {
dkato 0:ee40da884cfc 770 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
dkato 0:ee40da884cfc 771 return false;
dkato 0:ee40da884cfc 772 }
dkato 0:ee40da884cfc 773 decoder->private_->metadata_filter_ids_capacity *= 2;
dkato 0:ee40da884cfc 774 }
dkato 0:ee40da884cfc 775
dkato 0:ee40da884cfc 776 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));
dkato 0:ee40da884cfc 777 decoder->private_->metadata_filter_ids_count++;
dkato 0:ee40da884cfc 778
dkato 0:ee40da884cfc 779 return true;
dkato 0:ee40da884cfc 780 }
dkato 0:ee40da884cfc 781
dkato 0:ee40da884cfc 782 FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_all(FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 783 {
dkato 0:ee40da884cfc 784 unsigned i;
dkato 0:ee40da884cfc 785 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 786 FLAC__ASSERT(0 != decoder->private_);
dkato 0:ee40da884cfc 787 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 788 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
dkato 0:ee40da884cfc 789 return false;
dkato 0:ee40da884cfc 790 for(i = 0; i < sizeof(decoder->private_->metadata_filter) / sizeof(decoder->private_->metadata_filter[0]); i++)
dkato 0:ee40da884cfc 791 decoder->private_->metadata_filter[i] = true;
dkato 0:ee40da884cfc 792 decoder->private_->metadata_filter_ids_count = 0;
dkato 0:ee40da884cfc 793 return true;
dkato 0:ee40da884cfc 794 }
dkato 0:ee40da884cfc 795
dkato 0:ee40da884cfc 796 FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore(FLAC__StreamDecoder *decoder, FLAC__MetadataType type)
dkato 0:ee40da884cfc 797 {
dkato 0:ee40da884cfc 798 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 799 FLAC__ASSERT(0 != decoder->private_);
dkato 0:ee40da884cfc 800 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 801 FLAC__ASSERT((unsigned)type <= FLAC__MAX_METADATA_TYPE_CODE);
dkato 0:ee40da884cfc 802 /* double protection */
dkato 0:ee40da884cfc 803 if((unsigned)type > FLAC__MAX_METADATA_TYPE_CODE)
dkato 0:ee40da884cfc 804 return false;
dkato 0:ee40da884cfc 805 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
dkato 0:ee40da884cfc 806 return false;
dkato 0:ee40da884cfc 807 decoder->private_->metadata_filter[type] = false;
dkato 0:ee40da884cfc 808 if(type == FLAC__METADATA_TYPE_APPLICATION)
dkato 0:ee40da884cfc 809 decoder->private_->metadata_filter_ids_count = 0;
dkato 0:ee40da884cfc 810 return true;
dkato 0:ee40da884cfc 811 }
dkato 0:ee40da884cfc 812
dkato 0:ee40da884cfc 813 FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4])
dkato 0:ee40da884cfc 814 {
dkato 0:ee40da884cfc 815 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 816 FLAC__ASSERT(0 != decoder->private_);
dkato 0:ee40da884cfc 817 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 818 FLAC__ASSERT(0 != id);
dkato 0:ee40da884cfc 819 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
dkato 0:ee40da884cfc 820 return false;
dkato 0:ee40da884cfc 821
dkato 0:ee40da884cfc 822 if(!decoder->private_->metadata_filter[FLAC__METADATA_TYPE_APPLICATION])
dkato 0:ee40da884cfc 823 return true;
dkato 0:ee40da884cfc 824
dkato 0:ee40da884cfc 825 FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids);
dkato 0:ee40da884cfc 826
dkato 0:ee40da884cfc 827 if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) {
dkato 0:ee40da884cfc 828 if(0 == (decoder->private_->metadata_filter_ids = safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2))) {
dkato 0:ee40da884cfc 829 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
dkato 0:ee40da884cfc 830 return false;
dkato 0:ee40da884cfc 831 }
dkato 0:ee40da884cfc 832 decoder->private_->metadata_filter_ids_capacity *= 2;
dkato 0:ee40da884cfc 833 }
dkato 0:ee40da884cfc 834
dkato 0:ee40da884cfc 835 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));
dkato 0:ee40da884cfc 836 decoder->private_->metadata_filter_ids_count++;
dkato 0:ee40da884cfc 837
dkato 0:ee40da884cfc 838 return true;
dkato 0:ee40da884cfc 839 }
dkato 0:ee40da884cfc 840
dkato 0:ee40da884cfc 841 FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_all(FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 842 {
dkato 0:ee40da884cfc 843 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 844 FLAC__ASSERT(0 != decoder->private_);
dkato 0:ee40da884cfc 845 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 846 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
dkato 0:ee40da884cfc 847 return false;
dkato 0:ee40da884cfc 848 memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter));
dkato 0:ee40da884cfc 849 decoder->private_->metadata_filter_ids_count = 0;
dkato 0:ee40da884cfc 850 return true;
dkato 0:ee40da884cfc 851 }
dkato 0:ee40da884cfc 852
dkato 0:ee40da884cfc 853 FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_get_state(const FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 854 {
dkato 0:ee40da884cfc 855 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 856 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 857 return decoder->protected_->state;
dkato 0:ee40da884cfc 858 }
dkato 0:ee40da884cfc 859
dkato 0:ee40da884cfc 860 FLAC_API const char *FLAC__stream_decoder_get_resolved_state_string(const FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 861 {
dkato 0:ee40da884cfc 862 return FLAC__StreamDecoderStateString[decoder->protected_->state];
dkato 0:ee40da884cfc 863 }
dkato 0:ee40da884cfc 864
dkato 0:ee40da884cfc 865 FLAC_API FLAC__bool FLAC__stream_decoder_get_md5_checking(const FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 866 {
dkato 0:ee40da884cfc 867 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 868 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 869 return decoder->protected_->md5_checking;
dkato 0:ee40da884cfc 870 }
dkato 0:ee40da884cfc 871
dkato 0:ee40da884cfc 872 FLAC_API FLAC__uint64 FLAC__stream_decoder_get_total_samples(const FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 873 {
dkato 0:ee40da884cfc 874 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 875 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 876 return decoder->private_->has_stream_info? decoder->private_->stream_info.data.stream_info.total_samples : 0;
dkato 0:ee40da884cfc 877 }
dkato 0:ee40da884cfc 878
dkato 0:ee40da884cfc 879 FLAC_API unsigned FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 880 {
dkato 0:ee40da884cfc 881 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 882 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 883 return decoder->protected_->channels;
dkato 0:ee40da884cfc 884 }
dkato 0:ee40da884cfc 885
dkato 0:ee40da884cfc 886 FLAC_API FLAC__ChannelAssignment FLAC__stream_decoder_get_channel_assignment(const FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 887 {
dkato 0:ee40da884cfc 888 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 889 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 890 return decoder->protected_->channel_assignment;
dkato 0:ee40da884cfc 891 }
dkato 0:ee40da884cfc 892
dkato 0:ee40da884cfc 893 FLAC_API unsigned FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 894 {
dkato 0:ee40da884cfc 895 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 896 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 897 return decoder->protected_->bits_per_sample;
dkato 0:ee40da884cfc 898 }
dkato 0:ee40da884cfc 899
dkato 0:ee40da884cfc 900 FLAC_API unsigned FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 901 {
dkato 0:ee40da884cfc 902 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 903 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 904 return decoder->protected_->sample_rate;
dkato 0:ee40da884cfc 905 }
dkato 0:ee40da884cfc 906
dkato 0:ee40da884cfc 907 FLAC_API unsigned FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 908 {
dkato 0:ee40da884cfc 909 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 910 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 911 return decoder->protected_->blocksize;
dkato 0:ee40da884cfc 912 }
dkato 0:ee40da884cfc 913
dkato 0:ee40da884cfc 914 FLAC_API FLAC__bool FLAC__stream_decoder_get_decode_position(const FLAC__StreamDecoder *decoder, FLAC__uint64 *position)
dkato 0:ee40da884cfc 915 {
dkato 0:ee40da884cfc 916 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 917 FLAC__ASSERT(0 != decoder->private_);
dkato 0:ee40da884cfc 918 FLAC__ASSERT(0 != position);
dkato 0:ee40da884cfc 919
dkato 0:ee40da884cfc 920 #if FLAC__HAS_OGG
dkato 0:ee40da884cfc 921 if(decoder->private_->is_ogg)
dkato 0:ee40da884cfc 922 return false;
dkato 0:ee40da884cfc 923 #endif
dkato 0:ee40da884cfc 924 if(0 == decoder->private_->tell_callback)
dkato 0:ee40da884cfc 925 return false;
dkato 0:ee40da884cfc 926 if(decoder->private_->tell_callback(decoder, position, decoder->private_->client_data) != FLAC__STREAM_DECODER_TELL_STATUS_OK)
dkato 0:ee40da884cfc 927 return false;
dkato 0:ee40da884cfc 928 /* should never happen since all FLAC frames and metadata blocks are byte aligned, but check just in case */
dkato 0:ee40da884cfc 929 if(!FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input))
dkato 0:ee40da884cfc 930 return false;
dkato 0:ee40da884cfc 931 FLAC__ASSERT(*position >= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder));
dkato 0:ee40da884cfc 932 *position -= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder);
dkato 0:ee40da884cfc 933 return true;
dkato 0:ee40da884cfc 934 }
dkato 0:ee40da884cfc 935
dkato 0:ee40da884cfc 936 FLAC_API FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 937 {
dkato 0:ee40da884cfc 938 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 939 FLAC__ASSERT(0 != decoder->private_);
dkato 0:ee40da884cfc 940 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 941
dkato 0:ee40da884cfc 942 decoder->private_->samples_decoded = 0;
dkato 0:ee40da884cfc 943 decoder->private_->do_md5_checking = false;
dkato 0:ee40da884cfc 944
dkato 0:ee40da884cfc 945 #if FLAC__HAS_OGG
dkato 0:ee40da884cfc 946 if(decoder->private_->is_ogg)
dkato 0:ee40da884cfc 947 FLAC__ogg_decoder_aspect_flush(&decoder->protected_->ogg_decoder_aspect);
dkato 0:ee40da884cfc 948 #endif
dkato 0:ee40da884cfc 949
dkato 0:ee40da884cfc 950 if(!FLAC__bitreader_clear(decoder->private_->input)) {
dkato 0:ee40da884cfc 951 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
dkato 0:ee40da884cfc 952 return false;
dkato 0:ee40da884cfc 953 }
dkato 0:ee40da884cfc 954 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
dkato 0:ee40da884cfc 955
dkato 0:ee40da884cfc 956 return true;
dkato 0:ee40da884cfc 957 }
dkato 0:ee40da884cfc 958
dkato 0:ee40da884cfc 959 FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 960 {
dkato 0:ee40da884cfc 961 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 962 FLAC__ASSERT(0 != decoder->private_);
dkato 0:ee40da884cfc 963 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 964
dkato 0:ee40da884cfc 965 if(!FLAC__stream_decoder_flush(decoder)) {
dkato 0:ee40da884cfc 966 /* above call sets the state for us */
dkato 0:ee40da884cfc 967 return false;
dkato 0:ee40da884cfc 968 }
dkato 0:ee40da884cfc 969
dkato 0:ee40da884cfc 970 #if FLAC__HAS_OGG
dkato 0:ee40da884cfc 971 /*@@@ could go in !internal_reset_hack block below */
dkato 0:ee40da884cfc 972 if(decoder->private_->is_ogg)
dkato 0:ee40da884cfc 973 FLAC__ogg_decoder_aspect_reset(&decoder->protected_->ogg_decoder_aspect);
dkato 0:ee40da884cfc 974 #endif
dkato 0:ee40da884cfc 975
dkato 0:ee40da884cfc 976 /* Rewind if necessary. If FLAC__stream_decoder_init() is calling us,
dkato 0:ee40da884cfc 977 * (internal_reset_hack) don't try to rewind since we are already at
dkato 0:ee40da884cfc 978 * the beginning of the stream and don't want to fail if the input is
dkato 0:ee40da884cfc 979 * not seekable.
dkato 0:ee40da884cfc 980 */
dkato 0:ee40da884cfc 981 if(!decoder->private_->internal_reset_hack) {
dkato 0:ee40da884cfc 982 if(decoder->private_->file == stdin)
dkato 0:ee40da884cfc 983 return false; /* can't rewind stdin, reset fails */
dkato 0:ee40da884cfc 984 if(decoder->private_->seek_callback && decoder->private_->seek_callback(decoder, 0, decoder->private_->client_data) == FLAC__STREAM_DECODER_SEEK_STATUS_ERROR)
dkato 0:ee40da884cfc 985 return false; /* seekable and seek fails, reset fails */
dkato 0:ee40da884cfc 986 }
dkato 0:ee40da884cfc 987 else
dkato 0:ee40da884cfc 988 decoder->private_->internal_reset_hack = false;
dkato 0:ee40da884cfc 989
dkato 0:ee40da884cfc 990 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_METADATA;
dkato 0:ee40da884cfc 991
dkato 0:ee40da884cfc 992 decoder->private_->has_stream_info = false;
dkato 0:ee40da884cfc 993 if(decoder->private_->has_seek_table && 0 != decoder->private_->seek_table.data.seek_table.points) {
dkato 0:ee40da884cfc 994 free(decoder->private_->seek_table.data.seek_table.points);
dkato 0:ee40da884cfc 995 decoder->private_->seek_table.data.seek_table.points = 0;
dkato 0:ee40da884cfc 996 decoder->private_->has_seek_table = false;
dkato 0:ee40da884cfc 997 }
dkato 0:ee40da884cfc 998 decoder->private_->do_md5_checking = decoder->protected_->md5_checking;
dkato 0:ee40da884cfc 999 /*
dkato 0:ee40da884cfc 1000 * This goes in reset() and not flush() because according to the spec, a
dkato 0:ee40da884cfc 1001 * fixed-blocksize stream must stay that way through the whole stream.
dkato 0:ee40da884cfc 1002 */
dkato 0:ee40da884cfc 1003 decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size = 0;
dkato 0:ee40da884cfc 1004
dkato 0:ee40da884cfc 1005 /* We initialize the FLAC__MD5Context even though we may never use it. This
dkato 0:ee40da884cfc 1006 * is because md5 checking may be turned on to start and then turned off if
dkato 0:ee40da884cfc 1007 * a seek occurs. So we init the context here and finalize it in
dkato 0:ee40da884cfc 1008 * FLAC__stream_decoder_finish() to make sure things are always cleaned up
dkato 0:ee40da884cfc 1009 * properly.
dkato 0:ee40da884cfc 1010 */
dkato 0:ee40da884cfc 1011 FLAC__MD5Init(&decoder->private_->md5context);
dkato 0:ee40da884cfc 1012
dkato 0:ee40da884cfc 1013 decoder->private_->first_frame_offset = 0;
dkato 0:ee40da884cfc 1014 decoder->private_->unparseable_frame_count = 0;
dkato 0:ee40da884cfc 1015
dkato 0:ee40da884cfc 1016 return true;
dkato 0:ee40da884cfc 1017 }
dkato 0:ee40da884cfc 1018
dkato 0:ee40da884cfc 1019 FLAC_API FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 1020 {
dkato 0:ee40da884cfc 1021 FLAC__bool got_a_frame;
dkato 0:ee40da884cfc 1022 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 1023 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 1024
dkato 0:ee40da884cfc 1025 while(1) {
dkato 0:ee40da884cfc 1026 switch(decoder->protected_->state) {
dkato 0:ee40da884cfc 1027 case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
dkato 0:ee40da884cfc 1028 if(!find_metadata_(decoder))
dkato 0:ee40da884cfc 1029 return false; /* above function sets the status for us */
dkato 0:ee40da884cfc 1030 break;
dkato 0:ee40da884cfc 1031 case FLAC__STREAM_DECODER_READ_METADATA:
dkato 0:ee40da884cfc 1032 if(!read_metadata_(decoder))
dkato 0:ee40da884cfc 1033 return false; /* above function sets the status for us */
dkato 0:ee40da884cfc 1034 else
dkato 0:ee40da884cfc 1035 return true;
dkato 0:ee40da884cfc 1036 case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
dkato 0:ee40da884cfc 1037 if(!frame_sync_(decoder))
dkato 0:ee40da884cfc 1038 return true; /* above function sets the status for us */
dkato 0:ee40da884cfc 1039 break;
dkato 0:ee40da884cfc 1040 case FLAC__STREAM_DECODER_READ_FRAME:
dkato 0:ee40da884cfc 1041 if(!read_frame_(decoder, &got_a_frame, /*do_full_decode=*/true))
dkato 0:ee40da884cfc 1042 return false; /* above function sets the status for us */
dkato 0:ee40da884cfc 1043 if(got_a_frame)
dkato 0:ee40da884cfc 1044 return true; /* above function sets the status for us */
dkato 0:ee40da884cfc 1045 break;
dkato 0:ee40da884cfc 1046 case FLAC__STREAM_DECODER_END_OF_STREAM:
dkato 0:ee40da884cfc 1047 case FLAC__STREAM_DECODER_ABORTED:
dkato 0:ee40da884cfc 1048 return true;
dkato 0:ee40da884cfc 1049 default:
dkato 0:ee40da884cfc 1050 FLAC__ASSERT(0);
dkato 0:ee40da884cfc 1051 return false;
dkato 0:ee40da884cfc 1052 }
dkato 0:ee40da884cfc 1053 }
dkato 0:ee40da884cfc 1054 }
dkato 0:ee40da884cfc 1055
dkato 0:ee40da884cfc 1056 FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata(FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 1057 {
dkato 0:ee40da884cfc 1058 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 1059 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 1060
dkato 0:ee40da884cfc 1061 while(1) {
dkato 0:ee40da884cfc 1062 switch(decoder->protected_->state) {
dkato 0:ee40da884cfc 1063 case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
dkato 0:ee40da884cfc 1064 if(!find_metadata_(decoder))
dkato 0:ee40da884cfc 1065 return false; /* above function sets the status for us */
dkato 0:ee40da884cfc 1066 break;
dkato 0:ee40da884cfc 1067 case FLAC__STREAM_DECODER_READ_METADATA:
dkato 0:ee40da884cfc 1068 if(!read_metadata_(decoder))
dkato 0:ee40da884cfc 1069 return false; /* above function sets the status for us */
dkato 0:ee40da884cfc 1070 break;
dkato 0:ee40da884cfc 1071 case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
dkato 0:ee40da884cfc 1072 case FLAC__STREAM_DECODER_READ_FRAME:
dkato 0:ee40da884cfc 1073 case FLAC__STREAM_DECODER_END_OF_STREAM:
dkato 0:ee40da884cfc 1074 case FLAC__STREAM_DECODER_ABORTED:
dkato 0:ee40da884cfc 1075 return true;
dkato 0:ee40da884cfc 1076 default:
dkato 0:ee40da884cfc 1077 FLAC__ASSERT(0);
dkato 0:ee40da884cfc 1078 return false;
dkato 0:ee40da884cfc 1079 }
dkato 0:ee40da884cfc 1080 }
dkato 0:ee40da884cfc 1081 }
dkato 0:ee40da884cfc 1082
dkato 0:ee40da884cfc 1083 FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 1084 {
dkato 0:ee40da884cfc 1085 FLAC__bool dummy;
dkato 0:ee40da884cfc 1086 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 1087 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 1088
dkato 0:ee40da884cfc 1089 while(1) {
dkato 0:ee40da884cfc 1090 switch(decoder->protected_->state) {
dkato 0:ee40da884cfc 1091 case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
dkato 0:ee40da884cfc 1092 if(!find_metadata_(decoder))
dkato 0:ee40da884cfc 1093 return false; /* above function sets the status for us */
dkato 0:ee40da884cfc 1094 break;
dkato 0:ee40da884cfc 1095 case FLAC__STREAM_DECODER_READ_METADATA:
dkato 0:ee40da884cfc 1096 if(!read_metadata_(decoder))
dkato 0:ee40da884cfc 1097 return false; /* above function sets the status for us */
dkato 0:ee40da884cfc 1098 break;
dkato 0:ee40da884cfc 1099 case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
dkato 0:ee40da884cfc 1100 if(!frame_sync_(decoder))
dkato 0:ee40da884cfc 1101 return true; /* above function sets the status for us */
dkato 0:ee40da884cfc 1102 break;
dkato 0:ee40da884cfc 1103 case FLAC__STREAM_DECODER_READ_FRAME:
dkato 0:ee40da884cfc 1104 if(!read_frame_(decoder, &dummy, /*do_full_decode=*/true))
dkato 0:ee40da884cfc 1105 return false; /* above function sets the status for us */
dkato 0:ee40da884cfc 1106 break;
dkato 0:ee40da884cfc 1107 case FLAC__STREAM_DECODER_END_OF_STREAM:
dkato 0:ee40da884cfc 1108 case FLAC__STREAM_DECODER_ABORTED:
dkato 0:ee40da884cfc 1109 return true;
dkato 0:ee40da884cfc 1110 default:
dkato 0:ee40da884cfc 1111 FLAC__ASSERT(0);
dkato 0:ee40da884cfc 1112 return false;
dkato 0:ee40da884cfc 1113 }
dkato 0:ee40da884cfc 1114 }
dkato 0:ee40da884cfc 1115 }
dkato 0:ee40da884cfc 1116
dkato 0:ee40da884cfc 1117 FLAC_API FLAC__bool FLAC__stream_decoder_skip_single_frame(FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 1118 {
dkato 0:ee40da884cfc 1119 FLAC__bool got_a_frame;
dkato 0:ee40da884cfc 1120 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 1121 FLAC__ASSERT(0 != decoder->protected_);
dkato 0:ee40da884cfc 1122
dkato 0:ee40da884cfc 1123 while(1) {
dkato 0:ee40da884cfc 1124 switch(decoder->protected_->state) {
dkato 0:ee40da884cfc 1125 case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
dkato 0:ee40da884cfc 1126 case FLAC__STREAM_DECODER_READ_METADATA:
dkato 0:ee40da884cfc 1127 return false; /* above function sets the status for us */
dkato 0:ee40da884cfc 1128 case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
dkato 0:ee40da884cfc 1129 if(!frame_sync_(decoder))
dkato 0:ee40da884cfc 1130 return true; /* above function sets the status for us */
dkato 0:ee40da884cfc 1131 break;
dkato 0:ee40da884cfc 1132 case FLAC__STREAM_DECODER_READ_FRAME:
dkato 0:ee40da884cfc 1133 if(!read_frame_(decoder, &got_a_frame, /*do_full_decode=*/false))
dkato 0:ee40da884cfc 1134 return false; /* above function sets the status for us */
dkato 0:ee40da884cfc 1135 if(got_a_frame)
dkato 0:ee40da884cfc 1136 return true; /* above function sets the status for us */
dkato 0:ee40da884cfc 1137 break;
dkato 0:ee40da884cfc 1138 case FLAC__STREAM_DECODER_END_OF_STREAM:
dkato 0:ee40da884cfc 1139 case FLAC__STREAM_DECODER_ABORTED:
dkato 0:ee40da884cfc 1140 return true;
dkato 0:ee40da884cfc 1141 default:
dkato 0:ee40da884cfc 1142 FLAC__ASSERT(0);
dkato 0:ee40da884cfc 1143 return false;
dkato 0:ee40da884cfc 1144 }
dkato 0:ee40da884cfc 1145 }
dkato 0:ee40da884cfc 1146 }
dkato 0:ee40da884cfc 1147
dkato 0:ee40da884cfc 1148 FLAC_API FLAC__bool FLAC__stream_decoder_seek_absolute(FLAC__StreamDecoder *decoder, FLAC__uint64 sample)
dkato 0:ee40da884cfc 1149 {
dkato 0:ee40da884cfc 1150 FLAC__uint64 length;
dkato 0:ee40da884cfc 1151
dkato 0:ee40da884cfc 1152 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 1153
dkato 0:ee40da884cfc 1154 if(
dkato 0:ee40da884cfc 1155 decoder->protected_->state != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA &&
dkato 0:ee40da884cfc 1156 decoder->protected_->state != FLAC__STREAM_DECODER_READ_METADATA &&
dkato 0:ee40da884cfc 1157 decoder->protected_->state != FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC &&
dkato 0:ee40da884cfc 1158 decoder->protected_->state != FLAC__STREAM_DECODER_READ_FRAME &&
dkato 0:ee40da884cfc 1159 decoder->protected_->state != FLAC__STREAM_DECODER_END_OF_STREAM
dkato 0:ee40da884cfc 1160 )
dkato 0:ee40da884cfc 1161 return false;
dkato 0:ee40da884cfc 1162
dkato 0:ee40da884cfc 1163 if(0 == decoder->private_->seek_callback)
dkato 0:ee40da884cfc 1164 return false;
dkato 0:ee40da884cfc 1165
dkato 0:ee40da884cfc 1166 FLAC__ASSERT(decoder->private_->seek_callback);
dkato 0:ee40da884cfc 1167 FLAC__ASSERT(decoder->private_->tell_callback);
dkato 0:ee40da884cfc 1168 FLAC__ASSERT(decoder->private_->length_callback);
dkato 0:ee40da884cfc 1169 FLAC__ASSERT(decoder->private_->eof_callback);
dkato 0:ee40da884cfc 1170
dkato 0:ee40da884cfc 1171 if(FLAC__stream_decoder_get_total_samples(decoder) > 0 && sample >= FLAC__stream_decoder_get_total_samples(decoder))
dkato 0:ee40da884cfc 1172 return false;
dkato 0:ee40da884cfc 1173
dkato 0:ee40da884cfc 1174 decoder->private_->is_seeking = true;
dkato 0:ee40da884cfc 1175
dkato 0:ee40da884cfc 1176 /* turn off md5 checking if a seek is attempted */
dkato 0:ee40da884cfc 1177 decoder->private_->do_md5_checking = false;
dkato 0:ee40da884cfc 1178
dkato 0:ee40da884cfc 1179 /* 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) */
dkato 0:ee40da884cfc 1180 if(decoder->private_->length_callback(decoder, &length, decoder->private_->client_data) != FLAC__STREAM_DECODER_LENGTH_STATUS_OK) {
dkato 0:ee40da884cfc 1181 decoder->private_->is_seeking = false;
dkato 0:ee40da884cfc 1182 return false;
dkato 0:ee40da884cfc 1183 }
dkato 0:ee40da884cfc 1184
dkato 0:ee40da884cfc 1185 /* if we haven't finished processing the metadata yet, do that so we have the STREAMINFO, SEEK_TABLE, and first_frame_offset */
dkato 0:ee40da884cfc 1186 if(
dkato 0:ee40da884cfc 1187 decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_METADATA ||
dkato 0:ee40da884cfc 1188 decoder->protected_->state == FLAC__STREAM_DECODER_READ_METADATA
dkato 0:ee40da884cfc 1189 ) {
dkato 0:ee40da884cfc 1190 if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder)) {
dkato 0:ee40da884cfc 1191 /* above call sets the state for us */
dkato 0:ee40da884cfc 1192 decoder->private_->is_seeking = false;
dkato 0:ee40da884cfc 1193 return false;
dkato 0:ee40da884cfc 1194 }
dkato 0:ee40da884cfc 1195 /* check this again in case we didn't know total_samples the first time */
dkato 0:ee40da884cfc 1196 if(FLAC__stream_decoder_get_total_samples(decoder) > 0 && sample >= FLAC__stream_decoder_get_total_samples(decoder)) {
dkato 0:ee40da884cfc 1197 decoder->private_->is_seeking = false;
dkato 0:ee40da884cfc 1198 return false;
dkato 0:ee40da884cfc 1199 }
dkato 0:ee40da884cfc 1200 }
dkato 0:ee40da884cfc 1201
dkato 0:ee40da884cfc 1202 {
dkato 0:ee40da884cfc 1203 const FLAC__bool ok =
dkato 0:ee40da884cfc 1204 #if FLAC__HAS_OGG
dkato 0:ee40da884cfc 1205 decoder->private_->is_ogg?
dkato 0:ee40da884cfc 1206 seek_to_absolute_sample_ogg_(decoder, length, sample) :
dkato 0:ee40da884cfc 1207 #endif
dkato 0:ee40da884cfc 1208 seek_to_absolute_sample_(decoder, length, sample)
dkato 0:ee40da884cfc 1209 ;
dkato 0:ee40da884cfc 1210 decoder->private_->is_seeking = false;
dkato 0:ee40da884cfc 1211 return ok;
dkato 0:ee40da884cfc 1212 }
dkato 0:ee40da884cfc 1213 }
dkato 0:ee40da884cfc 1214
dkato 0:ee40da884cfc 1215 /***********************************************************************
dkato 0:ee40da884cfc 1216 *
dkato 0:ee40da884cfc 1217 * Protected class methods
dkato 0:ee40da884cfc 1218 *
dkato 0:ee40da884cfc 1219 ***********************************************************************/
dkato 0:ee40da884cfc 1220
dkato 0:ee40da884cfc 1221 unsigned FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 1222 {
dkato 0:ee40da884cfc 1223 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 1224 FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
dkato 0:ee40da884cfc 1225 FLAC__ASSERT(!(FLAC__bitreader_get_input_bits_unconsumed(decoder->private_->input) & 7));
dkato 0:ee40da884cfc 1226 return FLAC__bitreader_get_input_bits_unconsumed(decoder->private_->input) / 8;
dkato 0:ee40da884cfc 1227 }
dkato 0:ee40da884cfc 1228
dkato 0:ee40da884cfc 1229 /***********************************************************************
dkato 0:ee40da884cfc 1230 *
dkato 0:ee40da884cfc 1231 * Private class methods
dkato 0:ee40da884cfc 1232 *
dkato 0:ee40da884cfc 1233 ***********************************************************************/
dkato 0:ee40da884cfc 1234
dkato 0:ee40da884cfc 1235 void set_defaults_(FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 1236 {
dkato 0:ee40da884cfc 1237 #if FLAC__HAS_OGG
dkato 0:ee40da884cfc 1238 decoder->private_->is_ogg = false;
dkato 0:ee40da884cfc 1239 #endif
dkato 0:ee40da884cfc 1240 decoder->private_->read_callback = 0;
dkato 0:ee40da884cfc 1241 decoder->private_->seek_callback = 0;
dkato 0:ee40da884cfc 1242 decoder->private_->tell_callback = 0;
dkato 0:ee40da884cfc 1243 decoder->private_->length_callback = 0;
dkato 0:ee40da884cfc 1244 decoder->private_->eof_callback = 0;
dkato 0:ee40da884cfc 1245 decoder->private_->write_callback = 0;
dkato 0:ee40da884cfc 1246 decoder->private_->metadata_callback = 0;
dkato 0:ee40da884cfc 1247 decoder->private_->error_callback = 0;
dkato 0:ee40da884cfc 1248 decoder->private_->client_data = 0;
dkato 0:ee40da884cfc 1249
dkato 0:ee40da884cfc 1250 memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter));
dkato 0:ee40da884cfc 1251 decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO] = true;
dkato 0:ee40da884cfc 1252 decoder->private_->metadata_filter_ids_count = 0;
dkato 0:ee40da884cfc 1253
dkato 0:ee40da884cfc 1254 decoder->protected_->md5_checking = false;
dkato 0:ee40da884cfc 1255
dkato 0:ee40da884cfc 1256 #if FLAC__HAS_OGG
dkato 0:ee40da884cfc 1257 FLAC__ogg_decoder_aspect_set_defaults(&decoder->protected_->ogg_decoder_aspect);
dkato 0:ee40da884cfc 1258 #endif
dkato 0:ee40da884cfc 1259 }
dkato 0:ee40da884cfc 1260
dkato 0:ee40da884cfc 1261 /*
dkato 0:ee40da884cfc 1262 * This will forcibly set stdin to binary mode (for OSes that require it)
dkato 0:ee40da884cfc 1263 */
dkato 0:ee40da884cfc 1264 FILE *get_binary_stdin_(void)
dkato 0:ee40da884cfc 1265 {
dkato 0:ee40da884cfc 1266 /* if something breaks here it is probably due to the presence or
dkato 0:ee40da884cfc 1267 * absence of an underscore before the identifiers 'setmode',
dkato 0:ee40da884cfc 1268 * 'fileno', and/or 'O_BINARY'; check your system header files.
dkato 0:ee40da884cfc 1269 */
dkato 0:ee40da884cfc 1270 #if defined _MSC_VER || defined __MINGW32__
dkato 0:ee40da884cfc 1271 _setmode(_fileno(stdin), _O_BINARY);
dkato 0:ee40da884cfc 1272 #elif defined __CYGWIN__
dkato 0:ee40da884cfc 1273 /* almost certainly not needed for any modern Cygwin, but let's be safe... */
dkato 0:ee40da884cfc 1274 setmode(_fileno(stdin), _O_BINARY);
dkato 0:ee40da884cfc 1275 #elif defined __EMX__
dkato 0:ee40da884cfc 1276 setmode(fileno(stdin), O_BINARY);
dkato 0:ee40da884cfc 1277 #endif
dkato 0:ee40da884cfc 1278
dkato 0:ee40da884cfc 1279 return stdin;
dkato 0:ee40da884cfc 1280 }
dkato 0:ee40da884cfc 1281
dkato 0:ee40da884cfc 1282 FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigned channels)
dkato 0:ee40da884cfc 1283 {
dkato 0:ee40da884cfc 1284 unsigned i;
dkato 0:ee40da884cfc 1285 FLAC__int32 *tmp;
dkato 0:ee40da884cfc 1286
dkato 0:ee40da884cfc 1287 if(size <= decoder->private_->output_capacity && channels <= decoder->private_->output_channels)
dkato 0:ee40da884cfc 1288 return true;
dkato 0:ee40da884cfc 1289
dkato 0:ee40da884cfc 1290 /* simply using realloc() is not practical because the number of channels may change mid-stream */
dkato 0:ee40da884cfc 1291
dkato 0:ee40da884cfc 1292 for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
dkato 0:ee40da884cfc 1293 if(0 != decoder->private_->output[i]) {
dkato 0:ee40da884cfc 1294 free(decoder->private_->output[i]-4);
dkato 0:ee40da884cfc 1295 decoder->private_->output[i] = 0;
dkato 0:ee40da884cfc 1296 }
dkato 0:ee40da884cfc 1297 if(0 != decoder->private_->residual_unaligned[i]) {
dkato 0:ee40da884cfc 1298 free(decoder->private_->residual_unaligned[i]);
dkato 0:ee40da884cfc 1299 decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0;
dkato 0:ee40da884cfc 1300 }
dkato 0:ee40da884cfc 1301 }
dkato 0:ee40da884cfc 1302
dkato 0:ee40da884cfc 1303 for(i = 0; i < channels; i++) {
dkato 0:ee40da884cfc 1304 /* WATCHOUT:
dkato 0:ee40da884cfc 1305 * FLAC__lpc_restore_signal_asm_ia32_mmx() requires that the
dkato 0:ee40da884cfc 1306 * output arrays have a buffer of up to 3 zeroes in front
dkato 0:ee40da884cfc 1307 * (at negative indices) for alignment purposes; we use 4
dkato 0:ee40da884cfc 1308 * to keep the data well-aligned.
dkato 0:ee40da884cfc 1309 */
dkato 0:ee40da884cfc 1310 tmp = safe_malloc_muladd2_(sizeof(FLAC__int32), /*times (*/size, /*+*/4/*)*/);
dkato 0:ee40da884cfc 1311 if(tmp == 0) {
dkato 0:ee40da884cfc 1312 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
dkato 0:ee40da884cfc 1313 return false;
dkato 0:ee40da884cfc 1314 }
dkato 0:ee40da884cfc 1315 memset(tmp, 0, sizeof(FLAC__int32)*4);
dkato 0:ee40da884cfc 1316 decoder->private_->output[i] = tmp + 4;
dkato 0:ee40da884cfc 1317
dkato 0:ee40da884cfc 1318 if(!FLAC__memory_alloc_aligned_int32_array(size, &decoder->private_->residual_unaligned[i], &decoder->private_->residual[i])) {
dkato 0:ee40da884cfc 1319 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
dkato 0:ee40da884cfc 1320 return false;
dkato 0:ee40da884cfc 1321 }
dkato 0:ee40da884cfc 1322 }
dkato 0:ee40da884cfc 1323
dkato 0:ee40da884cfc 1324 decoder->private_->output_capacity = size;
dkato 0:ee40da884cfc 1325 decoder->private_->output_channels = channels;
dkato 0:ee40da884cfc 1326
dkato 0:ee40da884cfc 1327 return true;
dkato 0:ee40da884cfc 1328 }
dkato 0:ee40da884cfc 1329
dkato 0:ee40da884cfc 1330 FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id)
dkato 0:ee40da884cfc 1331 {
dkato 0:ee40da884cfc 1332 size_t i;
dkato 0:ee40da884cfc 1333
dkato 0:ee40da884cfc 1334 FLAC__ASSERT(0 != decoder);
dkato 0:ee40da884cfc 1335 FLAC__ASSERT(0 != decoder->private_);
dkato 0:ee40da884cfc 1336
dkato 0:ee40da884cfc 1337 for(i = 0; i < decoder->private_->metadata_filter_ids_count; i++)
dkato 0:ee40da884cfc 1338 if(0 == memcmp(decoder->private_->metadata_filter_ids + i * (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), id, (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8)))
dkato 0:ee40da884cfc 1339 return true;
dkato 0:ee40da884cfc 1340
dkato 0:ee40da884cfc 1341 return false;
dkato 0:ee40da884cfc 1342 }
dkato 0:ee40da884cfc 1343
dkato 0:ee40da884cfc 1344 FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 1345 {
dkato 0:ee40da884cfc 1346 FLAC__uint32 x;
dkato 0:ee40da884cfc 1347 unsigned i, id;
dkato 0:ee40da884cfc 1348 FLAC__bool first = true;
dkato 0:ee40da884cfc 1349
dkato 0:ee40da884cfc 1350 FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
dkato 0:ee40da884cfc 1351
dkato 0:ee40da884cfc 1352 for(i = id = 0; i < 4; ) {
dkato 0:ee40da884cfc 1353 if(decoder->private_->cached) {
dkato 0:ee40da884cfc 1354 x = (FLAC__uint32)decoder->private_->lookahead;
dkato 0:ee40da884cfc 1355 decoder->private_->cached = false;
dkato 0:ee40da884cfc 1356 }
dkato 0:ee40da884cfc 1357 else {
dkato 0:ee40da884cfc 1358 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8))
dkato 0:ee40da884cfc 1359 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1360 }
dkato 0:ee40da884cfc 1361 if(x == FLAC__STREAM_SYNC_STRING[i]) {
dkato 0:ee40da884cfc 1362 first = true;
dkato 0:ee40da884cfc 1363 i++;
dkato 0:ee40da884cfc 1364 id = 0;
dkato 0:ee40da884cfc 1365 continue;
dkato 0:ee40da884cfc 1366 }
dkato 0:ee40da884cfc 1367
dkato 0:ee40da884cfc 1368 if(id >= 3)
dkato 0:ee40da884cfc 1369 return false;
dkato 0:ee40da884cfc 1370
dkato 0:ee40da884cfc 1371 if(x == ID3V2_TAG_[id]) {
dkato 0:ee40da884cfc 1372 id++;
dkato 0:ee40da884cfc 1373 i = 0;
dkato 0:ee40da884cfc 1374 if(id == 3) {
dkato 0:ee40da884cfc 1375 if(!skip_id3v2_tag_(decoder))
dkato 0:ee40da884cfc 1376 return false; /* skip_id3v2_tag_ sets the state for us */
dkato 0:ee40da884cfc 1377 }
dkato 0:ee40da884cfc 1378 continue;
dkato 0:ee40da884cfc 1379 }
dkato 0:ee40da884cfc 1380 id = 0;
dkato 0:ee40da884cfc 1381 if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
dkato 0:ee40da884cfc 1382 decoder->private_->header_warmup[0] = (FLAC__byte)x;
dkato 0:ee40da884cfc 1383 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8))
dkato 0:ee40da884cfc 1384 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1385
dkato 0:ee40da884cfc 1386 /* 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 */
dkato 0:ee40da884cfc 1387 /* else we have to check if the second byte is the end of a sync code */
dkato 0:ee40da884cfc 1388 if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
dkato 0:ee40da884cfc 1389 decoder->private_->lookahead = (FLAC__byte)x;
dkato 0:ee40da884cfc 1390 decoder->private_->cached = true;
dkato 0:ee40da884cfc 1391 }
dkato 0:ee40da884cfc 1392 else if(x >> 1 == 0x7c) { /* MAGIC NUMBER for the last 6 sync bits and reserved 7th bit */
dkato 0:ee40da884cfc 1393 decoder->private_->header_warmup[1] = (FLAC__byte)x;
dkato 0:ee40da884cfc 1394 decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME;
dkato 0:ee40da884cfc 1395 return true;
dkato 0:ee40da884cfc 1396 }
dkato 0:ee40da884cfc 1397 }
dkato 0:ee40da884cfc 1398 i = 0;
dkato 0:ee40da884cfc 1399 if(first) {
dkato 0:ee40da884cfc 1400 send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
dkato 0:ee40da884cfc 1401 first = false;
dkato 0:ee40da884cfc 1402 }
dkato 0:ee40da884cfc 1403 }
dkato 0:ee40da884cfc 1404
dkato 0:ee40da884cfc 1405 decoder->protected_->state = FLAC__STREAM_DECODER_READ_METADATA;
dkato 0:ee40da884cfc 1406 return true;
dkato 0:ee40da884cfc 1407 }
dkato 0:ee40da884cfc 1408
dkato 0:ee40da884cfc 1409 FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 1410 {
dkato 0:ee40da884cfc 1411 FLAC__bool is_last;
dkato 0:ee40da884cfc 1412 FLAC__uint32 i, x, type, length;
dkato 0:ee40da884cfc 1413
dkato 0:ee40da884cfc 1414 FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
dkato 0:ee40da884cfc 1415
dkato 0:ee40da884cfc 1416 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_IS_LAST_LEN))
dkato 0:ee40da884cfc 1417 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1418 is_last = x? true : false;
dkato 0:ee40da884cfc 1419
dkato 0:ee40da884cfc 1420 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &type, FLAC__STREAM_METADATA_TYPE_LEN))
dkato 0:ee40da884cfc 1421 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1422
dkato 0:ee40da884cfc 1423 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &length, FLAC__STREAM_METADATA_LENGTH_LEN))
dkato 0:ee40da884cfc 1424 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1425
dkato 0:ee40da884cfc 1426 if(type == FLAC__METADATA_TYPE_STREAMINFO) {
dkato 0:ee40da884cfc 1427 if(!read_metadata_streaminfo_(decoder, is_last, length))
dkato 0:ee40da884cfc 1428 return false;
dkato 0:ee40da884cfc 1429
dkato 0:ee40da884cfc 1430 decoder->private_->has_stream_info = true;
dkato 0:ee40da884cfc 1431 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))
dkato 0:ee40da884cfc 1432 decoder->private_->do_md5_checking = false;
dkato 0:ee40da884cfc 1433 if(!decoder->private_->is_seeking && decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO] && decoder->private_->metadata_callback)
dkato 0:ee40da884cfc 1434 decoder->private_->metadata_callback(decoder, &decoder->private_->stream_info, decoder->private_->client_data);
dkato 0:ee40da884cfc 1435 }
dkato 0:ee40da884cfc 1436 else if(type == FLAC__METADATA_TYPE_SEEKTABLE) {
dkato 0:ee40da884cfc 1437 if(!read_metadata_seektable_(decoder, is_last, length))
dkato 0:ee40da884cfc 1438 return false;
dkato 0:ee40da884cfc 1439
dkato 0:ee40da884cfc 1440 decoder->private_->has_seek_table = true;
dkato 0:ee40da884cfc 1441 if(!decoder->private_->is_seeking && decoder->private_->metadata_filter[FLAC__METADATA_TYPE_SEEKTABLE] && decoder->private_->metadata_callback)
dkato 0:ee40da884cfc 1442 decoder->private_->metadata_callback(decoder, &decoder->private_->seek_table, decoder->private_->client_data);
dkato 0:ee40da884cfc 1443 }
dkato 0:ee40da884cfc 1444 else {
dkato 0:ee40da884cfc 1445 FLAC__bool skip_it = !decoder->private_->metadata_filter[type];
dkato 0:ee40da884cfc 1446 unsigned real_length = length;
dkato 0:ee40da884cfc 1447 FLAC__StreamMetadata block;
dkato 0:ee40da884cfc 1448
dkato 0:ee40da884cfc 1449 memset(&block, 0, sizeof(block));
dkato 0:ee40da884cfc 1450 block.is_last = is_last;
dkato 0:ee40da884cfc 1451 block.type = (FLAC__MetadataType)type;
dkato 0:ee40da884cfc 1452 block.length = length;
dkato 0:ee40da884cfc 1453
dkato 0:ee40da884cfc 1454 if(type == FLAC__METADATA_TYPE_APPLICATION) {
dkato 0:ee40da884cfc 1455 if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8))
dkato 0:ee40da884cfc 1456 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1457
dkato 0:ee40da884cfc 1458 if(real_length < FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) { /* underflow check */
dkato 0:ee40da884cfc 1459 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;/*@@@@@@ maybe wrong error? need to resync?*/
dkato 0:ee40da884cfc 1460 return false;
dkato 0:ee40da884cfc 1461 }
dkato 0:ee40da884cfc 1462
dkato 0:ee40da884cfc 1463 real_length -= FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8;
dkato 0:ee40da884cfc 1464
dkato 0:ee40da884cfc 1465 if(decoder->private_->metadata_filter_ids_count > 0 && has_id_filtered_(decoder, block.data.application.id))
dkato 0:ee40da884cfc 1466 skip_it = !skip_it;
dkato 0:ee40da884cfc 1467 }
dkato 0:ee40da884cfc 1468
dkato 0:ee40da884cfc 1469 if(skip_it) {
dkato 0:ee40da884cfc 1470 if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, real_length))
dkato 0:ee40da884cfc 1471 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1472 }
dkato 0:ee40da884cfc 1473 else {
dkato 0:ee40da884cfc 1474 FLAC__bool ok = true;
dkato 0:ee40da884cfc 1475 switch(type) {
dkato 0:ee40da884cfc 1476 case FLAC__METADATA_TYPE_PADDING:
dkato 0:ee40da884cfc 1477 /* skip the padding bytes */
dkato 0:ee40da884cfc 1478 if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, real_length))
dkato 0:ee40da884cfc 1479 ok = false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1480 break;
dkato 0:ee40da884cfc 1481 case FLAC__METADATA_TYPE_APPLICATION:
dkato 0:ee40da884cfc 1482 /* remember, we read the ID already */
dkato 0:ee40da884cfc 1483 if(real_length > 0) {
dkato 0:ee40da884cfc 1484 if(0 == (block.data.application.data = malloc(real_length))) {
dkato 0:ee40da884cfc 1485 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
dkato 0:ee40da884cfc 1486 ok = false;
dkato 0:ee40da884cfc 1487 }
dkato 0:ee40da884cfc 1488 else if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.data, real_length))
dkato 0:ee40da884cfc 1489 ok = false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1490 }
dkato 0:ee40da884cfc 1491 else
dkato 0:ee40da884cfc 1492 block.data.application.data = 0;
dkato 0:ee40da884cfc 1493 break;
dkato 0:ee40da884cfc 1494 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
dkato 0:ee40da884cfc 1495 if(!read_metadata_vorbiscomment_(decoder, &block.data.vorbis_comment, real_length))
dkato 0:ee40da884cfc 1496 ok = false;
dkato 0:ee40da884cfc 1497 break;
dkato 0:ee40da884cfc 1498 case FLAC__METADATA_TYPE_CUESHEET:
dkato 0:ee40da884cfc 1499 if(!read_metadata_cuesheet_(decoder, &block.data.cue_sheet))
dkato 0:ee40da884cfc 1500 ok = false;
dkato 0:ee40da884cfc 1501 break;
dkato 0:ee40da884cfc 1502 case FLAC__METADATA_TYPE_PICTURE:
dkato 0:ee40da884cfc 1503 if(!read_metadata_picture_(decoder, &block.data.picture))
dkato 0:ee40da884cfc 1504 ok = false;
dkato 0:ee40da884cfc 1505 break;
dkato 0:ee40da884cfc 1506 case FLAC__METADATA_TYPE_STREAMINFO:
dkato 0:ee40da884cfc 1507 case FLAC__METADATA_TYPE_SEEKTABLE:
dkato 0:ee40da884cfc 1508 FLAC__ASSERT(0);
dkato 0:ee40da884cfc 1509 break;
dkato 0:ee40da884cfc 1510 default:
dkato 0:ee40da884cfc 1511 if(real_length > 0) {
dkato 0:ee40da884cfc 1512 if(0 == (block.data.unknown.data = malloc(real_length))) {
dkato 0:ee40da884cfc 1513 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
dkato 0:ee40da884cfc 1514 ok = false;
dkato 0:ee40da884cfc 1515 }
dkato 0:ee40da884cfc 1516 else if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.unknown.data, real_length))
dkato 0:ee40da884cfc 1517 ok = false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1518 }
dkato 0:ee40da884cfc 1519 else
dkato 0:ee40da884cfc 1520 block.data.unknown.data = 0;
dkato 0:ee40da884cfc 1521 break;
dkato 0:ee40da884cfc 1522 }
dkato 0:ee40da884cfc 1523 if(ok && !decoder->private_->is_seeking && decoder->private_->metadata_callback)
dkato 0:ee40da884cfc 1524 decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data);
dkato 0:ee40da884cfc 1525
dkato 0:ee40da884cfc 1526 /* now we have to free any malloc()ed data in the block */
dkato 0:ee40da884cfc 1527 switch(type) {
dkato 0:ee40da884cfc 1528 case FLAC__METADATA_TYPE_PADDING:
dkato 0:ee40da884cfc 1529 break;
dkato 0:ee40da884cfc 1530 case FLAC__METADATA_TYPE_APPLICATION:
dkato 0:ee40da884cfc 1531 if(0 != block.data.application.data)
dkato 0:ee40da884cfc 1532 free(block.data.application.data);
dkato 0:ee40da884cfc 1533 break;
dkato 0:ee40da884cfc 1534 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
dkato 0:ee40da884cfc 1535 if(0 != block.data.vorbis_comment.vendor_string.entry)
dkato 0:ee40da884cfc 1536 free(block.data.vorbis_comment.vendor_string.entry);
dkato 0:ee40da884cfc 1537 if(block.data.vorbis_comment.num_comments > 0)
dkato 0:ee40da884cfc 1538 for(i = 0; i < block.data.vorbis_comment.num_comments; i++)
dkato 0:ee40da884cfc 1539 if(0 != block.data.vorbis_comment.comments[i].entry)
dkato 0:ee40da884cfc 1540 free(block.data.vorbis_comment.comments[i].entry);
dkato 0:ee40da884cfc 1541 if(0 != block.data.vorbis_comment.comments)
dkato 0:ee40da884cfc 1542 free(block.data.vorbis_comment.comments);
dkato 0:ee40da884cfc 1543 break;
dkato 0:ee40da884cfc 1544 case FLAC__METADATA_TYPE_CUESHEET:
dkato 0:ee40da884cfc 1545 if(block.data.cue_sheet.num_tracks > 0)
dkato 0:ee40da884cfc 1546 for(i = 0; i < block.data.cue_sheet.num_tracks; i++)
dkato 0:ee40da884cfc 1547 if(0 != block.data.cue_sheet.tracks[i].indices)
dkato 0:ee40da884cfc 1548 free(block.data.cue_sheet.tracks[i].indices);
dkato 0:ee40da884cfc 1549 if(0 != block.data.cue_sheet.tracks)
dkato 0:ee40da884cfc 1550 free(block.data.cue_sheet.tracks);
dkato 0:ee40da884cfc 1551 break;
dkato 0:ee40da884cfc 1552 case FLAC__METADATA_TYPE_PICTURE:
dkato 0:ee40da884cfc 1553 if(0 != block.data.picture.mime_type)
dkato 0:ee40da884cfc 1554 free(block.data.picture.mime_type);
dkato 0:ee40da884cfc 1555 if(0 != block.data.picture.description)
dkato 0:ee40da884cfc 1556 free(block.data.picture.description);
dkato 0:ee40da884cfc 1557 if(0 != block.data.picture.data)
dkato 0:ee40da884cfc 1558 free(block.data.picture.data);
dkato 0:ee40da884cfc 1559 break;
dkato 0:ee40da884cfc 1560 case FLAC__METADATA_TYPE_STREAMINFO:
dkato 0:ee40da884cfc 1561 case FLAC__METADATA_TYPE_SEEKTABLE:
dkato 0:ee40da884cfc 1562 FLAC__ASSERT(0);
dkato 0:ee40da884cfc 1563 default:
dkato 0:ee40da884cfc 1564 if(0 != block.data.unknown.data)
dkato 0:ee40da884cfc 1565 free(block.data.unknown.data);
dkato 0:ee40da884cfc 1566 break;
dkato 0:ee40da884cfc 1567 }
dkato 0:ee40da884cfc 1568
dkato 0:ee40da884cfc 1569 if(!ok) /* anything that unsets "ok" should also make sure decoder->protected_->state is updated */
dkato 0:ee40da884cfc 1570 return false;
dkato 0:ee40da884cfc 1571 }
dkato 0:ee40da884cfc 1572 }
dkato 0:ee40da884cfc 1573
dkato 0:ee40da884cfc 1574 if(is_last) {
dkato 0:ee40da884cfc 1575 /* if this fails, it's OK, it's just a hint for the seek routine */
dkato 0:ee40da884cfc 1576 if(!FLAC__stream_decoder_get_decode_position(decoder, &decoder->private_->first_frame_offset))
dkato 0:ee40da884cfc 1577 decoder->private_->first_frame_offset = 0;
dkato 0:ee40da884cfc 1578 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
dkato 0:ee40da884cfc 1579 }
dkato 0:ee40da884cfc 1580
dkato 0:ee40da884cfc 1581 return true;
dkato 0:ee40da884cfc 1582 }
dkato 0:ee40da884cfc 1583
dkato 0:ee40da884cfc 1584 FLAC__bool read_metadata_streaminfo_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length)
dkato 0:ee40da884cfc 1585 {
dkato 0:ee40da884cfc 1586 FLAC__uint32 x;
dkato 0:ee40da884cfc 1587 unsigned bits, used_bits = 0;
dkato 0:ee40da884cfc 1588
dkato 0:ee40da884cfc 1589 FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
dkato 0:ee40da884cfc 1590
dkato 0:ee40da884cfc 1591 decoder->private_->stream_info.type = FLAC__METADATA_TYPE_STREAMINFO;
dkato 0:ee40da884cfc 1592 decoder->private_->stream_info.is_last = is_last;
dkato 0:ee40da884cfc 1593 decoder->private_->stream_info.length = length;
dkato 0:ee40da884cfc 1594
dkato 0:ee40da884cfc 1595 bits = FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN;
dkato 0:ee40da884cfc 1596 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, bits))
dkato 0:ee40da884cfc 1597 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1598 decoder->private_->stream_info.data.stream_info.min_blocksize = x;
dkato 0:ee40da884cfc 1599 used_bits += bits;
dkato 0:ee40da884cfc 1600
dkato 0:ee40da884cfc 1601 bits = FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN;
dkato 0:ee40da884cfc 1602 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN))
dkato 0:ee40da884cfc 1603 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1604 decoder->private_->stream_info.data.stream_info.max_blocksize = x;
dkato 0:ee40da884cfc 1605 used_bits += bits;
dkato 0:ee40da884cfc 1606
dkato 0:ee40da884cfc 1607 bits = FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN;
dkato 0:ee40da884cfc 1608 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN))
dkato 0:ee40da884cfc 1609 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1610 decoder->private_->stream_info.data.stream_info.min_framesize = x;
dkato 0:ee40da884cfc 1611 used_bits += bits;
dkato 0:ee40da884cfc 1612
dkato 0:ee40da884cfc 1613 bits = FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN;
dkato 0:ee40da884cfc 1614 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN))
dkato 0:ee40da884cfc 1615 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1616 decoder->private_->stream_info.data.stream_info.max_framesize = x;
dkato 0:ee40da884cfc 1617 used_bits += bits;
dkato 0:ee40da884cfc 1618
dkato 0:ee40da884cfc 1619 bits = FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN;
dkato 0:ee40da884cfc 1620 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN))
dkato 0:ee40da884cfc 1621 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1622 decoder->private_->stream_info.data.stream_info.sample_rate = x;
dkato 0:ee40da884cfc 1623 used_bits += bits;
dkato 0:ee40da884cfc 1624
dkato 0:ee40da884cfc 1625 bits = FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN;
dkato 0:ee40da884cfc 1626 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN))
dkato 0:ee40da884cfc 1627 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1628 decoder->private_->stream_info.data.stream_info.channels = x+1;
dkato 0:ee40da884cfc 1629 used_bits += bits;
dkato 0:ee40da884cfc 1630
dkato 0:ee40da884cfc 1631 bits = FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN;
dkato 0:ee40da884cfc 1632 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN))
dkato 0:ee40da884cfc 1633 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1634 decoder->private_->stream_info.data.stream_info.bits_per_sample = x+1;
dkato 0:ee40da884cfc 1635 used_bits += bits;
dkato 0:ee40da884cfc 1636
dkato 0:ee40da884cfc 1637 bits = FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN;
dkato 0:ee40da884cfc 1638 if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &decoder->private_->stream_info.data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN))
dkato 0:ee40da884cfc 1639 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1640 used_bits += bits;
dkato 0:ee40da884cfc 1641
dkato 0:ee40da884cfc 1642 if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, decoder->private_->stream_info.data.stream_info.md5sum, 16))
dkato 0:ee40da884cfc 1643 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1644 used_bits += 16*8;
dkato 0:ee40da884cfc 1645
dkato 0:ee40da884cfc 1646 /* skip the rest of the block */
dkato 0:ee40da884cfc 1647 FLAC__ASSERT(used_bits % 8 == 0);
dkato 0:ee40da884cfc 1648 length -= (used_bits / 8);
dkato 0:ee40da884cfc 1649 if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, length))
dkato 0:ee40da884cfc 1650 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1651
dkato 0:ee40da884cfc 1652 return true;
dkato 0:ee40da884cfc 1653 }
dkato 0:ee40da884cfc 1654
dkato 0:ee40da884cfc 1655 FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length)
dkato 0:ee40da884cfc 1656 {
dkato 0:ee40da884cfc 1657 FLAC__uint32 i, x;
dkato 0:ee40da884cfc 1658 FLAC__uint64 xx;
dkato 0:ee40da884cfc 1659
dkato 0:ee40da884cfc 1660 FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
dkato 0:ee40da884cfc 1661
dkato 0:ee40da884cfc 1662 decoder->private_->seek_table.type = FLAC__METADATA_TYPE_SEEKTABLE;
dkato 0:ee40da884cfc 1663 decoder->private_->seek_table.is_last = is_last;
dkato 0:ee40da884cfc 1664 decoder->private_->seek_table.length = length;
dkato 0:ee40da884cfc 1665
dkato 0:ee40da884cfc 1666 decoder->private_->seek_table.data.seek_table.num_points = length / FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
dkato 0:ee40da884cfc 1667
dkato 0:ee40da884cfc 1668 /* use realloc since we may pass through here several times (e.g. after seeking) */
dkato 0:ee40da884cfc 1669 if(0 == (decoder->private_->seek_table.data.seek_table.points = safe_realloc_mul_2op_(decoder->private_->seek_table.data.seek_table.points, decoder->private_->seek_table.data.seek_table.num_points, /*times*/sizeof(FLAC__StreamMetadata_SeekPoint)))) {
dkato 0:ee40da884cfc 1670 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
dkato 0:ee40da884cfc 1671 return false;
dkato 0:ee40da884cfc 1672 }
dkato 0:ee40da884cfc 1673 for(i = 0; i < decoder->private_->seek_table.data.seek_table.num_points; i++) {
dkato 0:ee40da884cfc 1674 if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &xx, FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN))
dkato 0:ee40da884cfc 1675 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1676 decoder->private_->seek_table.data.seek_table.points[i].sample_number = xx;
dkato 0:ee40da884cfc 1677
dkato 0:ee40da884cfc 1678 if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &xx, FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN))
dkato 0:ee40da884cfc 1679 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1680 decoder->private_->seek_table.data.seek_table.points[i].stream_offset = xx;
dkato 0:ee40da884cfc 1681
dkato 0:ee40da884cfc 1682 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN))
dkato 0:ee40da884cfc 1683 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1684 decoder->private_->seek_table.data.seek_table.points[i].frame_samples = x;
dkato 0:ee40da884cfc 1685 }
dkato 0:ee40da884cfc 1686 length -= (decoder->private_->seek_table.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH);
dkato 0:ee40da884cfc 1687 /* if there is a partial point left, skip over it */
dkato 0:ee40da884cfc 1688 if(length > 0) {
dkato 0:ee40da884cfc 1689 /*@@@ do a send_error_to_client_() here? there's an argument for either way */
dkato 0:ee40da884cfc 1690 if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, length))
dkato 0:ee40da884cfc 1691 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1692 }
dkato 0:ee40da884cfc 1693
dkato 0:ee40da884cfc 1694 return true;
dkato 0:ee40da884cfc 1695 }
dkato 0:ee40da884cfc 1696
dkato 0:ee40da884cfc 1697 FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj, unsigned length)
dkato 0:ee40da884cfc 1698 {
dkato 0:ee40da884cfc 1699 FLAC__uint32 i;
dkato 0:ee40da884cfc 1700
dkato 0:ee40da884cfc 1701 FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
dkato 0:ee40da884cfc 1702
dkato 0:ee40da884cfc 1703 /* read vendor string */
dkato 0:ee40da884cfc 1704 if (length >= 8) {
dkato 0:ee40da884cfc 1705 length -= 8; /* vendor string length + num comments entries alone take 8 bytes */
dkato 0:ee40da884cfc 1706 FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32);
dkato 0:ee40da884cfc 1707 if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length))
dkato 0:ee40da884cfc 1708 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1709 if (obj->vendor_string.length > 0) {
dkato 0:ee40da884cfc 1710 if (length < obj->vendor_string.length) {
dkato 0:ee40da884cfc 1711 obj->vendor_string.length = 0;
dkato 0:ee40da884cfc 1712 obj->vendor_string.entry = 0;
dkato 0:ee40da884cfc 1713 goto skip;
dkato 0:ee40da884cfc 1714 }
dkato 0:ee40da884cfc 1715 else
dkato 0:ee40da884cfc 1716 length -= obj->vendor_string.length;
dkato 0:ee40da884cfc 1717 if (0 == (obj->vendor_string.entry = safe_malloc_add_2op_(obj->vendor_string.length, /*+*/1))) {
dkato 0:ee40da884cfc 1718 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
dkato 0:ee40da884cfc 1719 return false;
dkato 0:ee40da884cfc 1720 }
dkato 0:ee40da884cfc 1721 if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->vendor_string.entry, obj->vendor_string.length))
dkato 0:ee40da884cfc 1722 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1723 obj->vendor_string.entry[obj->vendor_string.length] = '\0';
dkato 0:ee40da884cfc 1724 }
dkato 0:ee40da884cfc 1725 else
dkato 0:ee40da884cfc 1726 obj->vendor_string.entry = 0;
dkato 0:ee40da884cfc 1727
dkato 0:ee40da884cfc 1728 /* read num comments */
dkato 0:ee40da884cfc 1729 FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN == 32);
dkato 0:ee40da884cfc 1730 if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->num_comments))
dkato 0:ee40da884cfc 1731 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1732
dkato 0:ee40da884cfc 1733 /* read comments */
dkato 0:ee40da884cfc 1734 if (obj->num_comments > 0) {
dkato 0:ee40da884cfc 1735 if (0 == (obj->comments = safe_malloc_mul_2op_p(obj->num_comments, /*times*/sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) {
dkato 0:ee40da884cfc 1736 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
dkato 0:ee40da884cfc 1737 return false;
dkato 0:ee40da884cfc 1738 }
dkato 0:ee40da884cfc 1739 for (i = 0; i < obj->num_comments; i++) {
dkato 0:ee40da884cfc 1740 FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32);
dkato 0:ee40da884cfc 1741 if (length < 4) {
dkato 0:ee40da884cfc 1742 obj->num_comments = i;
dkato 0:ee40da884cfc 1743 goto skip;
dkato 0:ee40da884cfc 1744 }
dkato 0:ee40da884cfc 1745 else
dkato 0:ee40da884cfc 1746 length -= 4;
dkato 0:ee40da884cfc 1747 if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->comments[i].length))
dkato 0:ee40da884cfc 1748 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1749 if (obj->comments[i].length > 0) {
dkato 0:ee40da884cfc 1750 if (length < obj->comments[i].length) {
dkato 0:ee40da884cfc 1751 obj->comments[i].length = 0;
dkato 0:ee40da884cfc 1752 obj->comments[i].entry = 0;
dkato 0:ee40da884cfc 1753 obj->num_comments = i;
dkato 0:ee40da884cfc 1754 goto skip;
dkato 0:ee40da884cfc 1755 }
dkato 0:ee40da884cfc 1756 else
dkato 0:ee40da884cfc 1757 length -= obj->comments[i].length;
dkato 0:ee40da884cfc 1758 if (0 == (obj->comments[i].entry = safe_malloc_add_2op_(obj->comments[i].length, /*+*/1))) {
dkato 0:ee40da884cfc 1759 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
dkato 0:ee40da884cfc 1760 return false;
dkato 0:ee40da884cfc 1761 }
dkato 0:ee40da884cfc 1762 if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->comments[i].entry, obj->comments[i].length))
dkato 0:ee40da884cfc 1763 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1764 obj->comments[i].entry[obj->comments[i].length] = '\0';
dkato 0:ee40da884cfc 1765 }
dkato 0:ee40da884cfc 1766 else
dkato 0:ee40da884cfc 1767 obj->comments[i].entry = 0;
dkato 0:ee40da884cfc 1768 }
dkato 0:ee40da884cfc 1769 }
dkato 0:ee40da884cfc 1770 else
dkato 0:ee40da884cfc 1771 obj->comments = 0;
dkato 0:ee40da884cfc 1772 }
dkato 0:ee40da884cfc 1773
dkato 0:ee40da884cfc 1774 skip:
dkato 0:ee40da884cfc 1775 if (length > 0) {
dkato 0:ee40da884cfc 1776 /* This will only happen on files with invalid data in comments */
dkato 0:ee40da884cfc 1777 if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, length))
dkato 0:ee40da884cfc 1778 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1779 }
dkato 0:ee40da884cfc 1780
dkato 0:ee40da884cfc 1781 return true;
dkato 0:ee40da884cfc 1782 }
dkato 0:ee40da884cfc 1783
dkato 0:ee40da884cfc 1784 FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_CueSheet *obj)
dkato 0:ee40da884cfc 1785 {
dkato 0:ee40da884cfc 1786 FLAC__uint32 i, j, x;
dkato 0:ee40da884cfc 1787
dkato 0:ee40da884cfc 1788 FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
dkato 0:ee40da884cfc 1789
dkato 0:ee40da884cfc 1790 memset(obj, 0, sizeof(FLAC__StreamMetadata_CueSheet));
dkato 0:ee40da884cfc 1791
dkato 0:ee40da884cfc 1792 FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN % 8 == 0);
dkato 0:ee40da884cfc 1793 if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, (FLAC__byte*)obj->media_catalog_number, FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN/8))
dkato 0:ee40da884cfc 1794 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1795
dkato 0:ee40da884cfc 1796 if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &obj->lead_in, FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN))
dkato 0:ee40da884cfc 1797 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1798
dkato 0:ee40da884cfc 1799 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN))
dkato 0:ee40da884cfc 1800 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1801 obj->is_cd = x? true : false;
dkato 0:ee40da884cfc 1802
dkato 0:ee40da884cfc 1803 if(!FLAC__bitreader_skip_bits_no_crc(decoder->private_->input, FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN))
dkato 0:ee40da884cfc 1804 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1805
dkato 0:ee40da884cfc 1806 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN))
dkato 0:ee40da884cfc 1807 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1808 obj->num_tracks = x;
dkato 0:ee40da884cfc 1809
dkato 0:ee40da884cfc 1810 if(obj->num_tracks > 0) {
dkato 0:ee40da884cfc 1811 if(0 == (obj->tracks = safe_calloc_(obj->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) {
dkato 0:ee40da884cfc 1812 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
dkato 0:ee40da884cfc 1813 return false;
dkato 0:ee40da884cfc 1814 }
dkato 0:ee40da884cfc 1815 for(i = 0; i < obj->num_tracks; i++) {
dkato 0:ee40da884cfc 1816 FLAC__StreamMetadata_CueSheet_Track *track = &obj->tracks[i];
dkato 0:ee40da884cfc 1817 if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &track->offset, FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN))
dkato 0:ee40da884cfc 1818 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1819
dkato 0:ee40da884cfc 1820 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN))
dkato 0:ee40da884cfc 1821 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1822 track->number = (FLAC__byte)x;
dkato 0:ee40da884cfc 1823
dkato 0:ee40da884cfc 1824 FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 == 0);
dkato 0:ee40da884cfc 1825 if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, (FLAC__byte*)track->isrc, FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN/8))
dkato 0:ee40da884cfc 1826 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1827
dkato 0:ee40da884cfc 1828 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN))
dkato 0:ee40da884cfc 1829 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1830 track->type = x;
dkato 0:ee40da884cfc 1831
dkato 0:ee40da884cfc 1832 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN))
dkato 0:ee40da884cfc 1833 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1834 track->pre_emphasis = x;
dkato 0:ee40da884cfc 1835
dkato 0:ee40da884cfc 1836 if(!FLAC__bitreader_skip_bits_no_crc(decoder->private_->input, FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN))
dkato 0:ee40da884cfc 1837 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1838
dkato 0:ee40da884cfc 1839 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN))
dkato 0:ee40da884cfc 1840 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1841 track->num_indices = (FLAC__byte)x;
dkato 0:ee40da884cfc 1842
dkato 0:ee40da884cfc 1843 if(track->num_indices > 0) {
dkato 0:ee40da884cfc 1844 if(0 == (track->indices = safe_calloc_(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) {
dkato 0:ee40da884cfc 1845 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
dkato 0:ee40da884cfc 1846 return false;
dkato 0:ee40da884cfc 1847 }
dkato 0:ee40da884cfc 1848 for(j = 0; j < track->num_indices; j++) {
dkato 0:ee40da884cfc 1849 FLAC__StreamMetadata_CueSheet_Index *indx = &track->indices[j];
dkato 0:ee40da884cfc 1850 if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &indx->offset, FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN))
dkato 0:ee40da884cfc 1851 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1852
dkato 0:ee40da884cfc 1853 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN))
dkato 0:ee40da884cfc 1854 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1855 indx->number = (FLAC__byte)x;
dkato 0:ee40da884cfc 1856
dkato 0:ee40da884cfc 1857 if(!FLAC__bitreader_skip_bits_no_crc(decoder->private_->input, FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN))
dkato 0:ee40da884cfc 1858 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1859 }
dkato 0:ee40da884cfc 1860 }
dkato 0:ee40da884cfc 1861 }
dkato 0:ee40da884cfc 1862 }
dkato 0:ee40da884cfc 1863
dkato 0:ee40da884cfc 1864 return true;
dkato 0:ee40da884cfc 1865 }
dkato 0:ee40da884cfc 1866
dkato 0:ee40da884cfc 1867 FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_Picture *obj)
dkato 0:ee40da884cfc 1868 {
dkato 0:ee40da884cfc 1869 FLAC__uint32 x;
dkato 0:ee40da884cfc 1870
dkato 0:ee40da884cfc 1871 FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
dkato 0:ee40da884cfc 1872
dkato 0:ee40da884cfc 1873 /* read type */
dkato 0:ee40da884cfc 1874 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_TYPE_LEN))
dkato 0:ee40da884cfc 1875 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1876 obj->type = x;
dkato 0:ee40da884cfc 1877
dkato 0:ee40da884cfc 1878 /* read MIME type */
dkato 0:ee40da884cfc 1879 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN))
dkato 0:ee40da884cfc 1880 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1881 if(0 == (obj->mime_type = safe_malloc_add_2op_(x, /*+*/1))) {
dkato 0:ee40da884cfc 1882 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
dkato 0:ee40da884cfc 1883 return false;
dkato 0:ee40da884cfc 1884 }
dkato 0:ee40da884cfc 1885 if(x > 0) {
dkato 0:ee40da884cfc 1886 if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, (FLAC__byte*)obj->mime_type, x))
dkato 0:ee40da884cfc 1887 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1888 }
dkato 0:ee40da884cfc 1889 obj->mime_type[x] = '\0';
dkato 0:ee40da884cfc 1890
dkato 0:ee40da884cfc 1891 /* read description */
dkato 0:ee40da884cfc 1892 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN))
dkato 0:ee40da884cfc 1893 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1894 if(0 == (obj->description = safe_malloc_add_2op_(x, /*+*/1))) {
dkato 0:ee40da884cfc 1895 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
dkato 0:ee40da884cfc 1896 return false;
dkato 0:ee40da884cfc 1897 }
dkato 0:ee40da884cfc 1898 if(x > 0) {
dkato 0:ee40da884cfc 1899 if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->description, x))
dkato 0:ee40da884cfc 1900 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1901 }
dkato 0:ee40da884cfc 1902 obj->description[x] = '\0';
dkato 0:ee40da884cfc 1903
dkato 0:ee40da884cfc 1904 /* read width */
dkato 0:ee40da884cfc 1905 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &obj->width, FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN))
dkato 0:ee40da884cfc 1906 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1907
dkato 0:ee40da884cfc 1908 /* read height */
dkato 0:ee40da884cfc 1909 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &obj->height, FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN))
dkato 0:ee40da884cfc 1910 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1911
dkato 0:ee40da884cfc 1912 /* read depth */
dkato 0:ee40da884cfc 1913 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &obj->depth, FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN))
dkato 0:ee40da884cfc 1914 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1915
dkato 0:ee40da884cfc 1916 /* read colors */
dkato 0:ee40da884cfc 1917 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &obj->colors, FLAC__STREAM_METADATA_PICTURE_COLORS_LEN))
dkato 0:ee40da884cfc 1918 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1919
dkato 0:ee40da884cfc 1920 /* read data */
dkato 0:ee40da884cfc 1921 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &(obj->data_length), FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN))
dkato 0:ee40da884cfc 1922 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1923 if(0 == (obj->data = safe_malloc_(obj->data_length))) {
dkato 0:ee40da884cfc 1924 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
dkato 0:ee40da884cfc 1925 return false;
dkato 0:ee40da884cfc 1926 }
dkato 0:ee40da884cfc 1927 if(obj->data_length > 0) {
dkato 0:ee40da884cfc 1928 if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->data, obj->data_length))
dkato 0:ee40da884cfc 1929 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1930 }
dkato 0:ee40da884cfc 1931
dkato 0:ee40da884cfc 1932 return true;
dkato 0:ee40da884cfc 1933 }
dkato 0:ee40da884cfc 1934
dkato 0:ee40da884cfc 1935 FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 1936 {
dkato 0:ee40da884cfc 1937 FLAC__uint32 x;
dkato 0:ee40da884cfc 1938 unsigned i, skip;
dkato 0:ee40da884cfc 1939
dkato 0:ee40da884cfc 1940 /* skip the version and flags bytes */
dkato 0:ee40da884cfc 1941 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 24))
dkato 0:ee40da884cfc 1942 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1943 /* get the size (in bytes) to skip */
dkato 0:ee40da884cfc 1944 skip = 0;
dkato 0:ee40da884cfc 1945 for(i = 0; i < 4; i++) {
dkato 0:ee40da884cfc 1946 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8))
dkato 0:ee40da884cfc 1947 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1948 skip <<= 7;
dkato 0:ee40da884cfc 1949 skip |= (x & 0x7f);
dkato 0:ee40da884cfc 1950 }
dkato 0:ee40da884cfc 1951 /* skip the rest of the tag */
dkato 0:ee40da884cfc 1952 if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, skip))
dkato 0:ee40da884cfc 1953 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1954 return true;
dkato 0:ee40da884cfc 1955 }
dkato 0:ee40da884cfc 1956
dkato 0:ee40da884cfc 1957 FLAC__bool frame_sync_(FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 1958 {
dkato 0:ee40da884cfc 1959 FLAC__uint32 x;
dkato 0:ee40da884cfc 1960 FLAC__bool first = true;
dkato 0:ee40da884cfc 1961
dkato 0:ee40da884cfc 1962 /* If we know the total number of samples in the stream, stop if we've read that many. */
dkato 0:ee40da884cfc 1963 /* This will stop us, for example, from wasting time trying to sync on an ID3V1 tag. */
dkato 0:ee40da884cfc 1964 if(FLAC__stream_decoder_get_total_samples(decoder) > 0) {
dkato 0:ee40da884cfc 1965 if(decoder->private_->samples_decoded >= FLAC__stream_decoder_get_total_samples(decoder)) {
dkato 0:ee40da884cfc 1966 decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM;
dkato 0:ee40da884cfc 1967 return true;
dkato 0:ee40da884cfc 1968 }
dkato 0:ee40da884cfc 1969 }
dkato 0:ee40da884cfc 1970
dkato 0:ee40da884cfc 1971 /* make sure we're byte aligned */
dkato 0:ee40da884cfc 1972 if(!FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)) {
dkato 0:ee40da884cfc 1973 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__bitreader_bits_left_for_byte_alignment(decoder->private_->input)))
dkato 0:ee40da884cfc 1974 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1975 }
dkato 0:ee40da884cfc 1976
dkato 0:ee40da884cfc 1977 while(1) {
dkato 0:ee40da884cfc 1978 if(decoder->private_->cached) {
dkato 0:ee40da884cfc 1979 x = (FLAC__uint32)decoder->private_->lookahead;
dkato 0:ee40da884cfc 1980 decoder->private_->cached = false;
dkato 0:ee40da884cfc 1981 }
dkato 0:ee40da884cfc 1982 else {
dkato 0:ee40da884cfc 1983 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8))
dkato 0:ee40da884cfc 1984 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1985 }
dkato 0:ee40da884cfc 1986 if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
dkato 0:ee40da884cfc 1987 decoder->private_->header_warmup[0] = (FLAC__byte)x;
dkato 0:ee40da884cfc 1988 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8))
dkato 0:ee40da884cfc 1989 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 1990
dkato 0:ee40da884cfc 1991 /* 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 */
dkato 0:ee40da884cfc 1992 /* else we have to check if the second byte is the end of a sync code */
dkato 0:ee40da884cfc 1993 if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
dkato 0:ee40da884cfc 1994 decoder->private_->lookahead = (FLAC__byte)x;
dkato 0:ee40da884cfc 1995 decoder->private_->cached = true;
dkato 0:ee40da884cfc 1996 }
dkato 0:ee40da884cfc 1997 else if(x >> 1 == 0x7c) { /* MAGIC NUMBER for the last 6 sync bits and reserved 7th bit */
dkato 0:ee40da884cfc 1998 decoder->private_->header_warmup[1] = (FLAC__byte)x;
dkato 0:ee40da884cfc 1999 decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME;
dkato 0:ee40da884cfc 2000 return true;
dkato 0:ee40da884cfc 2001 }
dkato 0:ee40da884cfc 2002 }
dkato 0:ee40da884cfc 2003 if(first) {
dkato 0:ee40da884cfc 2004 send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
dkato 0:ee40da884cfc 2005 first = false;
dkato 0:ee40da884cfc 2006 }
dkato 0:ee40da884cfc 2007 }
dkato 0:ee40da884cfc 2008
dkato 0:ee40da884cfc 2009 return true;
dkato 0:ee40da884cfc 2010 }
dkato 0:ee40da884cfc 2011
dkato 0:ee40da884cfc 2012 FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FLAC__bool do_full_decode)
dkato 0:ee40da884cfc 2013 {
dkato 0:ee40da884cfc 2014 unsigned channel;
dkato 0:ee40da884cfc 2015 unsigned i;
dkato 0:ee40da884cfc 2016 FLAC__int32 mid, side;
dkato 0:ee40da884cfc 2017 unsigned frame_crc; /* the one we calculate from the input stream */
dkato 0:ee40da884cfc 2018 FLAC__uint32 x;
dkato 0:ee40da884cfc 2019
dkato 0:ee40da884cfc 2020 *got_a_frame = false;
dkato 0:ee40da884cfc 2021
dkato 0:ee40da884cfc 2022 /* init the CRC */
dkato 0:ee40da884cfc 2023 frame_crc = 0;
dkato 0:ee40da884cfc 2024 frame_crc = FLAC__CRC16_UPDATE(decoder->private_->header_warmup[0], frame_crc);
dkato 0:ee40da884cfc 2025 frame_crc = FLAC__CRC16_UPDATE(decoder->private_->header_warmup[1], frame_crc);
dkato 0:ee40da884cfc 2026 FLAC__bitreader_reset_read_crc16(decoder->private_->input, (FLAC__uint16)frame_crc);
dkato 0:ee40da884cfc 2027
dkato 0:ee40da884cfc 2028 if(!read_frame_header_(decoder))
dkato 0:ee40da884cfc 2029 return false;
dkato 0:ee40da884cfc 2030 if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means we didn't sync on a valid header */
dkato 0:ee40da884cfc 2031 return true;
dkato 0:ee40da884cfc 2032 if(!allocate_output_(decoder, decoder->private_->frame.header.blocksize, decoder->private_->frame.header.channels))
dkato 0:ee40da884cfc 2033 return false;
dkato 0:ee40da884cfc 2034 for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) {
dkato 0:ee40da884cfc 2035 /*
dkato 0:ee40da884cfc 2036 * first figure the correct bits-per-sample of the subframe
dkato 0:ee40da884cfc 2037 */
dkato 0:ee40da884cfc 2038 unsigned bps = decoder->private_->frame.header.bits_per_sample;
dkato 0:ee40da884cfc 2039 switch(decoder->private_->frame.header.channel_assignment) {
dkato 0:ee40da884cfc 2040 case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
dkato 0:ee40da884cfc 2041 /* no adjustment needed */
dkato 0:ee40da884cfc 2042 break;
dkato 0:ee40da884cfc 2043 case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
dkato 0:ee40da884cfc 2044 FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
dkato 0:ee40da884cfc 2045 if(channel == 1)
dkato 0:ee40da884cfc 2046 bps++;
dkato 0:ee40da884cfc 2047 break;
dkato 0:ee40da884cfc 2048 case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
dkato 0:ee40da884cfc 2049 FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
dkato 0:ee40da884cfc 2050 if(channel == 0)
dkato 0:ee40da884cfc 2051 bps++;
dkato 0:ee40da884cfc 2052 break;
dkato 0:ee40da884cfc 2053 case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
dkato 0:ee40da884cfc 2054 FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
dkato 0:ee40da884cfc 2055 if(channel == 1)
dkato 0:ee40da884cfc 2056 bps++;
dkato 0:ee40da884cfc 2057 break;
dkato 0:ee40da884cfc 2058 default:
dkato 0:ee40da884cfc 2059 FLAC__ASSERT(0);
dkato 0:ee40da884cfc 2060 }
dkato 0:ee40da884cfc 2061 /*
dkato 0:ee40da884cfc 2062 * now read it
dkato 0:ee40da884cfc 2063 */
dkato 0:ee40da884cfc 2064 if(!read_subframe_(decoder, channel, bps, do_full_decode))
dkato 0:ee40da884cfc 2065 return false;
dkato 0:ee40da884cfc 2066 if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption */
dkato 0:ee40da884cfc 2067 return true;
dkato 0:ee40da884cfc 2068 }
dkato 0:ee40da884cfc 2069 if(!read_zero_padding_(decoder))
dkato 0:ee40da884cfc 2070 return false;
dkato 0:ee40da884cfc 2071 if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption (i.e. "zero bits" were not all zeroes) */
dkato 0:ee40da884cfc 2072 return true;
dkato 0:ee40da884cfc 2073
dkato 0:ee40da884cfc 2074 /*
dkato 0:ee40da884cfc 2075 * Read the frame CRC-16 from the footer and check
dkato 0:ee40da884cfc 2076 */
dkato 0:ee40da884cfc 2077 frame_crc = FLAC__bitreader_get_read_crc16(decoder->private_->input);
dkato 0:ee40da884cfc 2078 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__FRAME_FOOTER_CRC_LEN))
dkato 0:ee40da884cfc 2079 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2080 if(frame_crc == x) {
dkato 0:ee40da884cfc 2081 if(do_full_decode) {
dkato 0:ee40da884cfc 2082 /* Undo any special channel coding */
dkato 0:ee40da884cfc 2083 switch(decoder->private_->frame.header.channel_assignment) {
dkato 0:ee40da884cfc 2084 case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
dkato 0:ee40da884cfc 2085 /* do nothing */
dkato 0:ee40da884cfc 2086 break;
dkato 0:ee40da884cfc 2087 case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
dkato 0:ee40da884cfc 2088 FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
dkato 0:ee40da884cfc 2089 for(i = 0; i < decoder->private_->frame.header.blocksize; i++)
dkato 0:ee40da884cfc 2090 decoder->private_->output[1][i] = decoder->private_->output[0][i] - decoder->private_->output[1][i];
dkato 0:ee40da884cfc 2091 break;
dkato 0:ee40da884cfc 2092 case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
dkato 0:ee40da884cfc 2093 FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
dkato 0:ee40da884cfc 2094 for(i = 0; i < decoder->private_->frame.header.blocksize; i++)
dkato 0:ee40da884cfc 2095 decoder->private_->output[0][i] += decoder->private_->output[1][i];
dkato 0:ee40da884cfc 2096 break;
dkato 0:ee40da884cfc 2097 case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
dkato 0:ee40da884cfc 2098 FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
dkato 0:ee40da884cfc 2099 for(i = 0; i < decoder->private_->frame.header.blocksize; i++) {
dkato 0:ee40da884cfc 2100 #if 1
dkato 0:ee40da884cfc 2101 mid = decoder->private_->output[0][i];
dkato 0:ee40da884cfc 2102 side = decoder->private_->output[1][i];
dkato 0:ee40da884cfc 2103 mid <<= 1;
dkato 0:ee40da884cfc 2104 mid |= (side & 1); /* i.e. if 'side' is odd... */
dkato 0:ee40da884cfc 2105 decoder->private_->output[0][i] = (mid + side) >> 1;
dkato 0:ee40da884cfc 2106 decoder->private_->output[1][i] = (mid - side) >> 1;
dkato 0:ee40da884cfc 2107 #else
dkato 0:ee40da884cfc 2108 /* OPT: without 'side' temp variable */
dkato 0:ee40da884cfc 2109 mid = (decoder->private_->output[0][i] << 1) | (decoder->private_->output[1][i] & 1); /* i.e. if 'side' is odd... */
dkato 0:ee40da884cfc 2110 decoder->private_->output[0][i] = (mid + decoder->private_->output[1][i]) >> 1;
dkato 0:ee40da884cfc 2111 decoder->private_->output[1][i] = (mid - decoder->private_->output[1][i]) >> 1;
dkato 0:ee40da884cfc 2112 #endif
dkato 0:ee40da884cfc 2113 }
dkato 0:ee40da884cfc 2114 break;
dkato 0:ee40da884cfc 2115 default:
dkato 0:ee40da884cfc 2116 FLAC__ASSERT(0);
dkato 0:ee40da884cfc 2117 break;
dkato 0:ee40da884cfc 2118 }
dkato 0:ee40da884cfc 2119 }
dkato 0:ee40da884cfc 2120 }
dkato 0:ee40da884cfc 2121 else {
dkato 0:ee40da884cfc 2122 /* Bad frame, emit error and zero the output signal */
dkato 0:ee40da884cfc 2123 send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH);
dkato 0:ee40da884cfc 2124 if(do_full_decode) {
dkato 0:ee40da884cfc 2125 for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) {
dkato 0:ee40da884cfc 2126 memset(decoder->private_->output[channel], 0, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize);
dkato 0:ee40da884cfc 2127 }
dkato 0:ee40da884cfc 2128 }
dkato 0:ee40da884cfc 2129 }
dkato 0:ee40da884cfc 2130
dkato 0:ee40da884cfc 2131 *got_a_frame = true;
dkato 0:ee40da884cfc 2132
dkato 0:ee40da884cfc 2133 /* we wait to update fixed_block_size until here, when we're sure we've got a proper frame and hence a correct blocksize */
dkato 0:ee40da884cfc 2134 if(decoder->private_->next_fixed_block_size)
dkato 0:ee40da884cfc 2135 decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size;
dkato 0:ee40da884cfc 2136
dkato 0:ee40da884cfc 2137 /* put the latest values into the public section of the decoder instance */
dkato 0:ee40da884cfc 2138 decoder->protected_->channels = decoder->private_->frame.header.channels;
dkato 0:ee40da884cfc 2139 decoder->protected_->channel_assignment = decoder->private_->frame.header.channel_assignment;
dkato 0:ee40da884cfc 2140 decoder->protected_->bits_per_sample = decoder->private_->frame.header.bits_per_sample;
dkato 0:ee40da884cfc 2141 decoder->protected_->sample_rate = decoder->private_->frame.header.sample_rate;
dkato 0:ee40da884cfc 2142 decoder->protected_->blocksize = decoder->private_->frame.header.blocksize;
dkato 0:ee40da884cfc 2143
dkato 0:ee40da884cfc 2144 FLAC__ASSERT(decoder->private_->frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
dkato 0:ee40da884cfc 2145 decoder->private_->samples_decoded = decoder->private_->frame.header.number.sample_number + decoder->private_->frame.header.blocksize;
dkato 0:ee40da884cfc 2146
dkato 0:ee40da884cfc 2147 /* write it */
dkato 0:ee40da884cfc 2148 if(do_full_decode) {
dkato 0:ee40da884cfc 2149 if(write_audio_frame_to_client_(decoder, &decoder->private_->frame, (const FLAC__int32 * const *)decoder->private_->output) != FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE)
dkato 0:ee40da884cfc 2150 return false;
dkato 0:ee40da884cfc 2151 }
dkato 0:ee40da884cfc 2152
dkato 0:ee40da884cfc 2153 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
dkato 0:ee40da884cfc 2154 return true;
dkato 0:ee40da884cfc 2155 }
dkato 0:ee40da884cfc 2156
dkato 0:ee40da884cfc 2157 FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 2158 {
dkato 0:ee40da884cfc 2159 FLAC__uint32 x;
dkato 0:ee40da884cfc 2160 FLAC__uint64 xx;
dkato 0:ee40da884cfc 2161 unsigned i, blocksize_hint = 0, sample_rate_hint = 0;
dkato 0:ee40da884cfc 2162 FLAC__byte crc8, raw_header[16]; /* MAGIC NUMBER based on the maximum frame header size, including CRC */
dkato 0:ee40da884cfc 2163 unsigned raw_header_len;
dkato 0:ee40da884cfc 2164 FLAC__bool is_unparseable = false;
dkato 0:ee40da884cfc 2165
dkato 0:ee40da884cfc 2166 FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
dkato 0:ee40da884cfc 2167
dkato 0:ee40da884cfc 2168 /* init the raw header with the saved bits from synchronization */
dkato 0:ee40da884cfc 2169 raw_header[0] = decoder->private_->header_warmup[0];
dkato 0:ee40da884cfc 2170 raw_header[1] = decoder->private_->header_warmup[1];
dkato 0:ee40da884cfc 2171 raw_header_len = 2;
dkato 0:ee40da884cfc 2172
dkato 0:ee40da884cfc 2173 /* check to make sure that reserved bit is 0 */
dkato 0:ee40da884cfc 2174 if(raw_header[1] & 0x02) /* MAGIC NUMBER */
dkato 0:ee40da884cfc 2175 is_unparseable = true;
dkato 0:ee40da884cfc 2176
dkato 0:ee40da884cfc 2177 /*
dkato 0:ee40da884cfc 2178 * Note that along the way as we read the header, we look for a sync
dkato 0:ee40da884cfc 2179 * code inside. If we find one it would indicate that our original
dkato 0:ee40da884cfc 2180 * sync was bad since there cannot be a sync code in a valid header.
dkato 0:ee40da884cfc 2181 *
dkato 0:ee40da884cfc 2182 * Three kinds of things can go wrong when reading the frame header:
dkato 0:ee40da884cfc 2183 * 1) We may have sync'ed incorrectly and not landed on a frame header.
dkato 0:ee40da884cfc 2184 * If we don't find a sync code, it can end up looking like we read
dkato 0:ee40da884cfc 2185 * a valid but unparseable header, until getting to the frame header
dkato 0:ee40da884cfc 2186 * CRC. Even then we could get a false positive on the CRC.
dkato 0:ee40da884cfc 2187 * 2) We may have sync'ed correctly but on an unparseable frame (from a
dkato 0:ee40da884cfc 2188 * future encoder).
dkato 0:ee40da884cfc 2189 * 3) We may be on a damaged frame which appears valid but unparseable.
dkato 0:ee40da884cfc 2190 *
dkato 0:ee40da884cfc 2191 * For all these reasons, we try and read a complete frame header as
dkato 0:ee40da884cfc 2192 * long as it seems valid, even if unparseable, up until the frame
dkato 0:ee40da884cfc 2193 * header CRC.
dkato 0:ee40da884cfc 2194 */
dkato 0:ee40da884cfc 2195
dkato 0:ee40da884cfc 2196 /*
dkato 0:ee40da884cfc 2197 * read in the raw header as bytes so we can CRC it, and parse it on the way
dkato 0:ee40da884cfc 2198 */
dkato 0:ee40da884cfc 2199 for(i = 0; i < 2; i++) {
dkato 0:ee40da884cfc 2200 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8))
dkato 0:ee40da884cfc 2201 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2202 if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
dkato 0:ee40da884cfc 2203 /* if we get here it means our original sync was erroneous since the sync code cannot appear in the header */
dkato 0:ee40da884cfc 2204 decoder->private_->lookahead = (FLAC__byte)x;
dkato 0:ee40da884cfc 2205 decoder->private_->cached = true;
dkato 0:ee40da884cfc 2206 send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER);
dkato 0:ee40da884cfc 2207 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
dkato 0:ee40da884cfc 2208 return true;
dkato 0:ee40da884cfc 2209 }
dkato 0:ee40da884cfc 2210 raw_header[raw_header_len++] = (FLAC__byte)x;
dkato 0:ee40da884cfc 2211 }
dkato 0:ee40da884cfc 2212
dkato 0:ee40da884cfc 2213 switch(x = raw_header[2] >> 4) {
dkato 0:ee40da884cfc 2214 case 0:
dkato 0:ee40da884cfc 2215 is_unparseable = true;
dkato 0:ee40da884cfc 2216 break;
dkato 0:ee40da884cfc 2217 case 1:
dkato 0:ee40da884cfc 2218 decoder->private_->frame.header.blocksize = 192;
dkato 0:ee40da884cfc 2219 break;
dkato 0:ee40da884cfc 2220 case 2:
dkato 0:ee40da884cfc 2221 case 3:
dkato 0:ee40da884cfc 2222 case 4:
dkato 0:ee40da884cfc 2223 case 5:
dkato 0:ee40da884cfc 2224 decoder->private_->frame.header.blocksize = 576 << (x-2);
dkato 0:ee40da884cfc 2225 break;
dkato 0:ee40da884cfc 2226 case 6:
dkato 0:ee40da884cfc 2227 case 7:
dkato 0:ee40da884cfc 2228 blocksize_hint = x;
dkato 0:ee40da884cfc 2229 break;
dkato 0:ee40da884cfc 2230 case 8:
dkato 0:ee40da884cfc 2231 case 9:
dkato 0:ee40da884cfc 2232 case 10:
dkato 0:ee40da884cfc 2233 case 11:
dkato 0:ee40da884cfc 2234 case 12:
dkato 0:ee40da884cfc 2235 case 13:
dkato 0:ee40da884cfc 2236 case 14:
dkato 0:ee40da884cfc 2237 case 15:
dkato 0:ee40da884cfc 2238 decoder->private_->frame.header.blocksize = 256 << (x-8);
dkato 0:ee40da884cfc 2239 break;
dkato 0:ee40da884cfc 2240 default:
dkato 0:ee40da884cfc 2241 FLAC__ASSERT(0);
dkato 0:ee40da884cfc 2242 break;
dkato 0:ee40da884cfc 2243 }
dkato 0:ee40da884cfc 2244
dkato 0:ee40da884cfc 2245 switch(x = raw_header[2] & 0x0f) {
dkato 0:ee40da884cfc 2246 case 0:
dkato 0:ee40da884cfc 2247 if(decoder->private_->has_stream_info)
dkato 0:ee40da884cfc 2248 decoder->private_->frame.header.sample_rate = decoder->private_->stream_info.data.stream_info.sample_rate;
dkato 0:ee40da884cfc 2249 else
dkato 0:ee40da884cfc 2250 is_unparseable = true;
dkato 0:ee40da884cfc 2251 break;
dkato 0:ee40da884cfc 2252 case 1:
dkato 0:ee40da884cfc 2253 decoder->private_->frame.header.sample_rate = 88200;
dkato 0:ee40da884cfc 2254 break;
dkato 0:ee40da884cfc 2255 case 2:
dkato 0:ee40da884cfc 2256 decoder->private_->frame.header.sample_rate = 176400;
dkato 0:ee40da884cfc 2257 break;
dkato 0:ee40da884cfc 2258 case 3:
dkato 0:ee40da884cfc 2259 decoder->private_->frame.header.sample_rate = 192000;
dkato 0:ee40da884cfc 2260 break;
dkato 0:ee40da884cfc 2261 case 4:
dkato 0:ee40da884cfc 2262 decoder->private_->frame.header.sample_rate = 8000;
dkato 0:ee40da884cfc 2263 break;
dkato 0:ee40da884cfc 2264 case 5:
dkato 0:ee40da884cfc 2265 decoder->private_->frame.header.sample_rate = 16000;
dkato 0:ee40da884cfc 2266 break;
dkato 0:ee40da884cfc 2267 case 6:
dkato 0:ee40da884cfc 2268 decoder->private_->frame.header.sample_rate = 22050;
dkato 0:ee40da884cfc 2269 break;
dkato 0:ee40da884cfc 2270 case 7:
dkato 0:ee40da884cfc 2271 decoder->private_->frame.header.sample_rate = 24000;
dkato 0:ee40da884cfc 2272 break;
dkato 0:ee40da884cfc 2273 case 8:
dkato 0:ee40da884cfc 2274 decoder->private_->frame.header.sample_rate = 32000;
dkato 0:ee40da884cfc 2275 break;
dkato 0:ee40da884cfc 2276 case 9:
dkato 0:ee40da884cfc 2277 decoder->private_->frame.header.sample_rate = 44100;
dkato 0:ee40da884cfc 2278 break;
dkato 0:ee40da884cfc 2279 case 10:
dkato 0:ee40da884cfc 2280 decoder->private_->frame.header.sample_rate = 48000;
dkato 0:ee40da884cfc 2281 break;
dkato 0:ee40da884cfc 2282 case 11:
dkato 0:ee40da884cfc 2283 decoder->private_->frame.header.sample_rate = 96000;
dkato 0:ee40da884cfc 2284 break;
dkato 0:ee40da884cfc 2285 case 12:
dkato 0:ee40da884cfc 2286 case 13:
dkato 0:ee40da884cfc 2287 case 14:
dkato 0:ee40da884cfc 2288 sample_rate_hint = x;
dkato 0:ee40da884cfc 2289 break;
dkato 0:ee40da884cfc 2290 case 15:
dkato 0:ee40da884cfc 2291 send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER);
dkato 0:ee40da884cfc 2292 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
dkato 0:ee40da884cfc 2293 return true;
dkato 0:ee40da884cfc 2294 default:
dkato 0:ee40da884cfc 2295 FLAC__ASSERT(0);
dkato 0:ee40da884cfc 2296 }
dkato 0:ee40da884cfc 2297
dkato 0:ee40da884cfc 2298 x = (unsigned)(raw_header[3] >> 4);
dkato 0:ee40da884cfc 2299 if(x & 8) {
dkato 0:ee40da884cfc 2300 decoder->private_->frame.header.channels = 2;
dkato 0:ee40da884cfc 2301 switch(x & 7) {
dkato 0:ee40da884cfc 2302 case 0:
dkato 0:ee40da884cfc 2303 decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE;
dkato 0:ee40da884cfc 2304 break;
dkato 0:ee40da884cfc 2305 case 1:
dkato 0:ee40da884cfc 2306 decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE;
dkato 0:ee40da884cfc 2307 break;
dkato 0:ee40da884cfc 2308 case 2:
dkato 0:ee40da884cfc 2309 decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_MID_SIDE;
dkato 0:ee40da884cfc 2310 break;
dkato 0:ee40da884cfc 2311 default:
dkato 0:ee40da884cfc 2312 is_unparseable = true;
dkato 0:ee40da884cfc 2313 break;
dkato 0:ee40da884cfc 2314 }
dkato 0:ee40da884cfc 2315 }
dkato 0:ee40da884cfc 2316 else {
dkato 0:ee40da884cfc 2317 decoder->private_->frame.header.channels = (unsigned)x + 1;
dkato 0:ee40da884cfc 2318 decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT;
dkato 0:ee40da884cfc 2319 }
dkato 0:ee40da884cfc 2320
dkato 0:ee40da884cfc 2321 switch(x = (unsigned)(raw_header[3] & 0x0e) >> 1) {
dkato 0:ee40da884cfc 2322 case 0:
dkato 0:ee40da884cfc 2323 if(decoder->private_->has_stream_info)
dkato 0:ee40da884cfc 2324 decoder->private_->frame.header.bits_per_sample = decoder->private_->stream_info.data.stream_info.bits_per_sample;
dkato 0:ee40da884cfc 2325 else
dkato 0:ee40da884cfc 2326 is_unparseable = true;
dkato 0:ee40da884cfc 2327 break;
dkato 0:ee40da884cfc 2328 case 1:
dkato 0:ee40da884cfc 2329 decoder->private_->frame.header.bits_per_sample = 8;
dkato 0:ee40da884cfc 2330 break;
dkato 0:ee40da884cfc 2331 case 2:
dkato 0:ee40da884cfc 2332 decoder->private_->frame.header.bits_per_sample = 12;
dkato 0:ee40da884cfc 2333 break;
dkato 0:ee40da884cfc 2334 case 4:
dkato 0:ee40da884cfc 2335 decoder->private_->frame.header.bits_per_sample = 16;
dkato 0:ee40da884cfc 2336 break;
dkato 0:ee40da884cfc 2337 case 5:
dkato 0:ee40da884cfc 2338 decoder->private_->frame.header.bits_per_sample = 20;
dkato 0:ee40da884cfc 2339 break;
dkato 0:ee40da884cfc 2340 case 6:
dkato 0:ee40da884cfc 2341 decoder->private_->frame.header.bits_per_sample = 24;
dkato 0:ee40da884cfc 2342 break;
dkato 0:ee40da884cfc 2343 case 3:
dkato 0:ee40da884cfc 2344 case 7:
dkato 0:ee40da884cfc 2345 is_unparseable = true;
dkato 0:ee40da884cfc 2346 break;
dkato 0:ee40da884cfc 2347 default:
dkato 0:ee40da884cfc 2348 FLAC__ASSERT(0);
dkato 0:ee40da884cfc 2349 break;
dkato 0:ee40da884cfc 2350 }
dkato 0:ee40da884cfc 2351
dkato 0:ee40da884cfc 2352 /* check to make sure that reserved bit is 0 */
dkato 0:ee40da884cfc 2353 if(raw_header[3] & 0x01) /* MAGIC NUMBER */
dkato 0:ee40da884cfc 2354 is_unparseable = true;
dkato 0:ee40da884cfc 2355
dkato 0:ee40da884cfc 2356 /* read the frame's starting sample number (or frame number as the case may be) */
dkato 0:ee40da884cfc 2357 if(
dkato 0:ee40da884cfc 2358 raw_header[1] & 0x01 ||
dkato 0:ee40da884cfc 2359 /*@@@ this clause is a concession to the old way of doing variable blocksize; the only known implementation is flake and can probably be removed without inconveniencing anyone */
dkato 0:ee40da884cfc 2360 (decoder->private_->has_stream_info && decoder->private_->stream_info.data.stream_info.min_blocksize != decoder->private_->stream_info.data.stream_info.max_blocksize)
dkato 0:ee40da884cfc 2361 ) { /* variable blocksize */
dkato 0:ee40da884cfc 2362 if(!FLAC__bitreader_read_utf8_uint64(decoder->private_->input, &xx, raw_header, &raw_header_len))
dkato 0:ee40da884cfc 2363 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2364 if(xx == FLAC__U64L(0xffffffffffffffff)) { /* i.e. non-UTF8 code... */
dkato 0:ee40da884cfc 2365 decoder->private_->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */
dkato 0:ee40da884cfc 2366 decoder->private_->cached = true;
dkato 0:ee40da884cfc 2367 send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER);
dkato 0:ee40da884cfc 2368 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
dkato 0:ee40da884cfc 2369 return true;
dkato 0:ee40da884cfc 2370 }
dkato 0:ee40da884cfc 2371 decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER;
dkato 0:ee40da884cfc 2372 decoder->private_->frame.header.number.sample_number = xx;
dkato 0:ee40da884cfc 2373 }
dkato 0:ee40da884cfc 2374 else { /* fixed blocksize */
dkato 0:ee40da884cfc 2375 if(!FLAC__bitreader_read_utf8_uint32(decoder->private_->input, &x, raw_header, &raw_header_len))
dkato 0:ee40da884cfc 2376 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2377 if(x == 0xffffffff) { /* i.e. non-UTF8 code... */
dkato 0:ee40da884cfc 2378 decoder->private_->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */
dkato 0:ee40da884cfc 2379 decoder->private_->cached = true;
dkato 0:ee40da884cfc 2380 send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER);
dkato 0:ee40da884cfc 2381 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
dkato 0:ee40da884cfc 2382 return true;
dkato 0:ee40da884cfc 2383 }
dkato 0:ee40da884cfc 2384 decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER;
dkato 0:ee40da884cfc 2385 decoder->private_->frame.header.number.frame_number = x;
dkato 0:ee40da884cfc 2386 }
dkato 0:ee40da884cfc 2387
dkato 0:ee40da884cfc 2388 if(blocksize_hint) {
dkato 0:ee40da884cfc 2389 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8))
dkato 0:ee40da884cfc 2390 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2391 raw_header[raw_header_len++] = (FLAC__byte)x;
dkato 0:ee40da884cfc 2392 if(blocksize_hint == 7) {
dkato 0:ee40da884cfc 2393 FLAC__uint32 _x;
dkato 0:ee40da884cfc 2394 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &_x, 8))
dkato 0:ee40da884cfc 2395 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2396 raw_header[raw_header_len++] = (FLAC__byte)_x;
dkato 0:ee40da884cfc 2397 x = (x << 8) | _x;
dkato 0:ee40da884cfc 2398 }
dkato 0:ee40da884cfc 2399 decoder->private_->frame.header.blocksize = x+1;
dkato 0:ee40da884cfc 2400 }
dkato 0:ee40da884cfc 2401
dkato 0:ee40da884cfc 2402 if(sample_rate_hint) {
dkato 0:ee40da884cfc 2403 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8))
dkato 0:ee40da884cfc 2404 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2405 raw_header[raw_header_len++] = (FLAC__byte)x;
dkato 0:ee40da884cfc 2406 if(sample_rate_hint != 12) {
dkato 0:ee40da884cfc 2407 FLAC__uint32 _x;
dkato 0:ee40da884cfc 2408 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &_x, 8))
dkato 0:ee40da884cfc 2409 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2410 raw_header[raw_header_len++] = (FLAC__byte)_x;
dkato 0:ee40da884cfc 2411 x = (x << 8) | _x;
dkato 0:ee40da884cfc 2412 }
dkato 0:ee40da884cfc 2413 if(sample_rate_hint == 12)
dkato 0:ee40da884cfc 2414 decoder->private_->frame.header.sample_rate = x*1000;
dkato 0:ee40da884cfc 2415 else if(sample_rate_hint == 13)
dkato 0:ee40da884cfc 2416 decoder->private_->frame.header.sample_rate = x;
dkato 0:ee40da884cfc 2417 else
dkato 0:ee40da884cfc 2418 decoder->private_->frame.header.sample_rate = x*10;
dkato 0:ee40da884cfc 2419 }
dkato 0:ee40da884cfc 2420
dkato 0:ee40da884cfc 2421 /* read the CRC-8 byte */
dkato 0:ee40da884cfc 2422 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8))
dkato 0:ee40da884cfc 2423 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2424 crc8 = (FLAC__byte)x;
dkato 0:ee40da884cfc 2425
dkato 0:ee40da884cfc 2426 if(FLAC__crc8(raw_header, raw_header_len) != crc8) {
dkato 0:ee40da884cfc 2427 send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER);
dkato 0:ee40da884cfc 2428 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
dkato 0:ee40da884cfc 2429 return true;
dkato 0:ee40da884cfc 2430 }
dkato 0:ee40da884cfc 2431
dkato 0:ee40da884cfc 2432 /* calculate the sample number from the frame number if needed */
dkato 0:ee40da884cfc 2433 decoder->private_->next_fixed_block_size = 0;
dkato 0:ee40da884cfc 2434 if(decoder->private_->frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER) {
dkato 0:ee40da884cfc 2435 x = decoder->private_->frame.header.number.frame_number;
dkato 0:ee40da884cfc 2436 decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER;
dkato 0:ee40da884cfc 2437 if(decoder->private_->fixed_block_size)
dkato 0:ee40da884cfc 2438 decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->fixed_block_size * (FLAC__uint64)x;
dkato 0:ee40da884cfc 2439 else if(decoder->private_->has_stream_info) {
dkato 0:ee40da884cfc 2440 if(decoder->private_->stream_info.data.stream_info.min_blocksize == decoder->private_->stream_info.data.stream_info.max_blocksize) {
dkato 0:ee40da884cfc 2441 decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->stream_info.data.stream_info.min_blocksize * (FLAC__uint64)x;
dkato 0:ee40da884cfc 2442 decoder->private_->next_fixed_block_size = decoder->private_->stream_info.data.stream_info.max_blocksize;
dkato 0:ee40da884cfc 2443 }
dkato 0:ee40da884cfc 2444 else
dkato 0:ee40da884cfc 2445 is_unparseable = true;
dkato 0:ee40da884cfc 2446 }
dkato 0:ee40da884cfc 2447 else if(x == 0) {
dkato 0:ee40da884cfc 2448 decoder->private_->frame.header.number.sample_number = 0;
dkato 0:ee40da884cfc 2449 decoder->private_->next_fixed_block_size = decoder->private_->frame.header.blocksize;
dkato 0:ee40da884cfc 2450 }
dkato 0:ee40da884cfc 2451 else {
dkato 0:ee40da884cfc 2452 /* can only get here if the stream has invalid frame numbering and no STREAMINFO, so assume it's not the last (possibly short) frame */
dkato 0:ee40da884cfc 2453 decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->frame.header.blocksize * (FLAC__uint64)x;
dkato 0:ee40da884cfc 2454 }
dkato 0:ee40da884cfc 2455 }
dkato 0:ee40da884cfc 2456
dkato 0:ee40da884cfc 2457 if(is_unparseable) {
dkato 0:ee40da884cfc 2458 send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM);
dkato 0:ee40da884cfc 2459 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
dkato 0:ee40da884cfc 2460 return true;
dkato 0:ee40da884cfc 2461 }
dkato 0:ee40da884cfc 2462
dkato 0:ee40da884cfc 2463 return true;
dkato 0:ee40da884cfc 2464 }
dkato 0:ee40da884cfc 2465
dkato 0:ee40da884cfc 2466 FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode)
dkato 0:ee40da884cfc 2467 {
dkato 0:ee40da884cfc 2468 FLAC__uint32 x;
dkato 0:ee40da884cfc 2469 FLAC__bool wasted_bits;
dkato 0:ee40da884cfc 2470 unsigned i;
dkato 0:ee40da884cfc 2471
dkato 0:ee40da884cfc 2472 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) /* MAGIC NUMBER */
dkato 0:ee40da884cfc 2473 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2474
dkato 0:ee40da884cfc 2475 wasted_bits = (x & 1);
dkato 0:ee40da884cfc 2476 x &= 0xfe;
dkato 0:ee40da884cfc 2477
dkato 0:ee40da884cfc 2478 if(wasted_bits) {
dkato 0:ee40da884cfc 2479 unsigned u;
dkato 0:ee40da884cfc 2480 if(!FLAC__bitreader_read_unary_unsigned(decoder->private_->input, &u))
dkato 0:ee40da884cfc 2481 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2482 decoder->private_->frame.subframes[channel].wasted_bits = u+1;
dkato 0:ee40da884cfc 2483 bps -= decoder->private_->frame.subframes[channel].wasted_bits;
dkato 0:ee40da884cfc 2484 }
dkato 0:ee40da884cfc 2485 else
dkato 0:ee40da884cfc 2486 decoder->private_->frame.subframes[channel].wasted_bits = 0;
dkato 0:ee40da884cfc 2487
dkato 0:ee40da884cfc 2488 /*
dkato 0:ee40da884cfc 2489 * Lots of magic numbers here
dkato 0:ee40da884cfc 2490 */
dkato 0:ee40da884cfc 2491 if(x & 0x80) {
dkato 0:ee40da884cfc 2492 send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
dkato 0:ee40da884cfc 2493 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
dkato 0:ee40da884cfc 2494 return true;
dkato 0:ee40da884cfc 2495 }
dkato 0:ee40da884cfc 2496 else if(x == 0) {
dkato 0:ee40da884cfc 2497 if(!read_subframe_constant_(decoder, channel, bps, do_full_decode))
dkato 0:ee40da884cfc 2498 return false;
dkato 0:ee40da884cfc 2499 }
dkato 0:ee40da884cfc 2500 else if(x == 2) {
dkato 0:ee40da884cfc 2501 if(!read_subframe_verbatim_(decoder, channel, bps, do_full_decode))
dkato 0:ee40da884cfc 2502 return false;
dkato 0:ee40da884cfc 2503 }
dkato 0:ee40da884cfc 2504 else if(x < 16) {
dkato 0:ee40da884cfc 2505 send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM);
dkato 0:ee40da884cfc 2506 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
dkato 0:ee40da884cfc 2507 return true;
dkato 0:ee40da884cfc 2508 }
dkato 0:ee40da884cfc 2509 else if(x <= 24) {
dkato 0:ee40da884cfc 2510 if(!read_subframe_fixed_(decoder, channel, bps, (x>>1)&7, do_full_decode))
dkato 0:ee40da884cfc 2511 return false;
dkato 0:ee40da884cfc 2512 if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption */
dkato 0:ee40da884cfc 2513 return true;
dkato 0:ee40da884cfc 2514 }
dkato 0:ee40da884cfc 2515 else if(x < 64) {
dkato 0:ee40da884cfc 2516 send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM);
dkato 0:ee40da884cfc 2517 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
dkato 0:ee40da884cfc 2518 return true;
dkato 0:ee40da884cfc 2519 }
dkato 0:ee40da884cfc 2520 else {
dkato 0:ee40da884cfc 2521 if(!read_subframe_lpc_(decoder, channel, bps, ((x>>1)&31)+1, do_full_decode))
dkato 0:ee40da884cfc 2522 return false;
dkato 0:ee40da884cfc 2523 if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption */
dkato 0:ee40da884cfc 2524 return true;
dkato 0:ee40da884cfc 2525 }
dkato 0:ee40da884cfc 2526
dkato 0:ee40da884cfc 2527 if(wasted_bits && do_full_decode) {
dkato 0:ee40da884cfc 2528 x = decoder->private_->frame.subframes[channel].wasted_bits;
dkato 0:ee40da884cfc 2529 for(i = 0; i < decoder->private_->frame.header.blocksize; i++)
dkato 0:ee40da884cfc 2530 decoder->private_->output[channel][i] <<= x;
dkato 0:ee40da884cfc 2531 }
dkato 0:ee40da884cfc 2532
dkato 0:ee40da884cfc 2533 return true;
dkato 0:ee40da884cfc 2534 }
dkato 0:ee40da884cfc 2535
dkato 0:ee40da884cfc 2536 FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode)
dkato 0:ee40da884cfc 2537 {
dkato 0:ee40da884cfc 2538 FLAC__Subframe_Constant *subframe = &decoder->private_->frame.subframes[channel].data.constant;
dkato 0:ee40da884cfc 2539 FLAC__int32 x;
dkato 0:ee40da884cfc 2540 unsigned i;
dkato 0:ee40da884cfc 2541 FLAC__int32 *output = decoder->private_->output[channel];
dkato 0:ee40da884cfc 2542
dkato 0:ee40da884cfc 2543 decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_CONSTANT;
dkato 0:ee40da884cfc 2544
dkato 0:ee40da884cfc 2545 if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &x, bps))
dkato 0:ee40da884cfc 2546 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2547
dkato 0:ee40da884cfc 2548 subframe->value = x;
dkato 0:ee40da884cfc 2549
dkato 0:ee40da884cfc 2550 /* decode the subframe */
dkato 0:ee40da884cfc 2551 if(do_full_decode) {
dkato 0:ee40da884cfc 2552 for(i = 0; i < decoder->private_->frame.header.blocksize; i++)
dkato 0:ee40da884cfc 2553 output[i] = x;
dkato 0:ee40da884cfc 2554 }
dkato 0:ee40da884cfc 2555
dkato 0:ee40da884cfc 2556 return true;
dkato 0:ee40da884cfc 2557 }
dkato 0:ee40da884cfc 2558
dkato 0:ee40da884cfc 2559 FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode)
dkato 0:ee40da884cfc 2560 {
dkato 0:ee40da884cfc 2561 FLAC__Subframe_Fixed *subframe = &decoder->private_->frame.subframes[channel].data.fixed;
dkato 0:ee40da884cfc 2562 FLAC__int32 i32;
dkato 0:ee40da884cfc 2563 FLAC__uint32 u32;
dkato 0:ee40da884cfc 2564 unsigned u;
dkato 0:ee40da884cfc 2565
dkato 0:ee40da884cfc 2566 decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_FIXED;
dkato 0:ee40da884cfc 2567
dkato 0:ee40da884cfc 2568 subframe->residual = decoder->private_->residual[channel];
dkato 0:ee40da884cfc 2569 subframe->order = order;
dkato 0:ee40da884cfc 2570
dkato 0:ee40da884cfc 2571 /* read warm-up samples */
dkato 0:ee40da884cfc 2572 for(u = 0; u < order; u++) {
dkato 0:ee40da884cfc 2573 if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, bps))
dkato 0:ee40da884cfc 2574 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2575 subframe->warmup[u] = i32;
dkato 0:ee40da884cfc 2576 }
dkato 0:ee40da884cfc 2577
dkato 0:ee40da884cfc 2578 /* read entropy coding method info */
dkato 0:ee40da884cfc 2579 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN))
dkato 0:ee40da884cfc 2580 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2581 subframe->entropy_coding_method.type = (FLAC__EntropyCodingMethodType)u32;
dkato 0:ee40da884cfc 2582 switch(subframe->entropy_coding_method.type) {
dkato 0:ee40da884cfc 2583 case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
dkato 0:ee40da884cfc 2584 case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
dkato 0:ee40da884cfc 2585 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN))
dkato 0:ee40da884cfc 2586 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2587 subframe->entropy_coding_method.data.partitioned_rice.order = u32;
dkato 0:ee40da884cfc 2588 subframe->entropy_coding_method.data.partitioned_rice.contents = &decoder->private_->partitioned_rice_contents[channel];
dkato 0:ee40da884cfc 2589 break;
dkato 0:ee40da884cfc 2590 default:
dkato 0:ee40da884cfc 2591 send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM);
dkato 0:ee40da884cfc 2592 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
dkato 0:ee40da884cfc 2593 return true;
dkato 0:ee40da884cfc 2594 }
dkato 0:ee40da884cfc 2595
dkato 0:ee40da884cfc 2596 /* read residual */
dkato 0:ee40da884cfc 2597 switch(subframe->entropy_coding_method.type) {
dkato 0:ee40da884cfc 2598 case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
dkato 0:ee40da884cfc 2599 case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
dkato 0:ee40da884cfc 2600 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], /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2))
dkato 0:ee40da884cfc 2601 return false;
dkato 0:ee40da884cfc 2602 break;
dkato 0:ee40da884cfc 2603 default:
dkato 0:ee40da884cfc 2604 FLAC__ASSERT(0);
dkato 0:ee40da884cfc 2605 }
dkato 0:ee40da884cfc 2606
dkato 0:ee40da884cfc 2607 /* decode the subframe */
dkato 0:ee40da884cfc 2608 if(do_full_decode) {
dkato 0:ee40da884cfc 2609 memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order);
dkato 0:ee40da884cfc 2610 FLAC__fixed_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, order, decoder->private_->output[channel]+order);
dkato 0:ee40da884cfc 2611 }
dkato 0:ee40da884cfc 2612
dkato 0:ee40da884cfc 2613 return true;
dkato 0:ee40da884cfc 2614 }
dkato 0:ee40da884cfc 2615
dkato 0:ee40da884cfc 2616 FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode)
dkato 0:ee40da884cfc 2617 {
dkato 0:ee40da884cfc 2618 FLAC__Subframe_LPC *subframe = &decoder->private_->frame.subframes[channel].data.lpc;
dkato 0:ee40da884cfc 2619 FLAC__int32 i32;
dkato 0:ee40da884cfc 2620 FLAC__uint32 u32;
dkato 0:ee40da884cfc 2621 unsigned u;
dkato 0:ee40da884cfc 2622
dkato 0:ee40da884cfc 2623 decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_LPC;
dkato 0:ee40da884cfc 2624
dkato 0:ee40da884cfc 2625 subframe->residual = decoder->private_->residual[channel];
dkato 0:ee40da884cfc 2626 subframe->order = order;
dkato 0:ee40da884cfc 2627
dkato 0:ee40da884cfc 2628 /* read warm-up samples */
dkato 0:ee40da884cfc 2629 for(u = 0; u < order; u++) {
dkato 0:ee40da884cfc 2630 if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, bps))
dkato 0:ee40da884cfc 2631 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2632 subframe->warmup[u] = i32;
dkato 0:ee40da884cfc 2633 }
dkato 0:ee40da884cfc 2634
dkato 0:ee40da884cfc 2635 /* read qlp coeff precision */
dkato 0:ee40da884cfc 2636 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN))
dkato 0:ee40da884cfc 2637 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2638 if(u32 == (1u << FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN) - 1) {
dkato 0:ee40da884cfc 2639 send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
dkato 0:ee40da884cfc 2640 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
dkato 0:ee40da884cfc 2641 return true;
dkato 0:ee40da884cfc 2642 }
dkato 0:ee40da884cfc 2643 subframe->qlp_coeff_precision = u32+1;
dkato 0:ee40da884cfc 2644
dkato 0:ee40da884cfc 2645 /* read qlp shift */
dkato 0:ee40da884cfc 2646 if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN))
dkato 0:ee40da884cfc 2647 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2648 subframe->quantization_level = i32;
dkato 0:ee40da884cfc 2649
dkato 0:ee40da884cfc 2650 /* read quantized lp coefficiencts */
dkato 0:ee40da884cfc 2651 for(u = 0; u < order; u++) {
dkato 0:ee40da884cfc 2652 if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, subframe->qlp_coeff_precision))
dkato 0:ee40da884cfc 2653 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2654 subframe->qlp_coeff[u] = i32;
dkato 0:ee40da884cfc 2655 }
dkato 0:ee40da884cfc 2656
dkato 0:ee40da884cfc 2657 /* read entropy coding method info */
dkato 0:ee40da884cfc 2658 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN))
dkato 0:ee40da884cfc 2659 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2660 subframe->entropy_coding_method.type = (FLAC__EntropyCodingMethodType)u32;
dkato 0:ee40da884cfc 2661 switch(subframe->entropy_coding_method.type) {
dkato 0:ee40da884cfc 2662 case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
dkato 0:ee40da884cfc 2663 case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
dkato 0:ee40da884cfc 2664 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN))
dkato 0:ee40da884cfc 2665 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2666 subframe->entropy_coding_method.data.partitioned_rice.order = u32;
dkato 0:ee40da884cfc 2667 subframe->entropy_coding_method.data.partitioned_rice.contents = &decoder->private_->partitioned_rice_contents[channel];
dkato 0:ee40da884cfc 2668 break;
dkato 0:ee40da884cfc 2669 default:
dkato 0:ee40da884cfc 2670 send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM);
dkato 0:ee40da884cfc 2671 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
dkato 0:ee40da884cfc 2672 return true;
dkato 0:ee40da884cfc 2673 }
dkato 0:ee40da884cfc 2674
dkato 0:ee40da884cfc 2675 /* read residual */
dkato 0:ee40da884cfc 2676 switch(subframe->entropy_coding_method.type) {
dkato 0:ee40da884cfc 2677 case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
dkato 0:ee40da884cfc 2678 case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
dkato 0:ee40da884cfc 2679 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], /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2))
dkato 0:ee40da884cfc 2680 return false;
dkato 0:ee40da884cfc 2681 break;
dkato 0:ee40da884cfc 2682 default:
dkato 0:ee40da884cfc 2683 FLAC__ASSERT(0);
dkato 0:ee40da884cfc 2684 }
dkato 0:ee40da884cfc 2685
dkato 0:ee40da884cfc 2686 /* decode the subframe */
dkato 0:ee40da884cfc 2687 if(do_full_decode) {
dkato 0:ee40da884cfc 2688 memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order);
dkato 0:ee40da884cfc 2689 /*@@@@@@ technically not pessimistic enough, should be more like
dkato 0:ee40da884cfc 2690 if( (FLAC__uint64)order * ((((FLAC__uint64)1)<<bps)-1) * ((1<<subframe->qlp_coeff_precision)-1) < (((FLAC__uint64)-1) << 32) )
dkato 0:ee40da884cfc 2691 */
dkato 0:ee40da884cfc 2692 if(bps + subframe->qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32)
dkato 0:ee40da884cfc 2693 if(bps <= 16 && subframe->qlp_coeff_precision <= 16)
dkato 0:ee40da884cfc 2694 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);
dkato 0:ee40da884cfc 2695 else
dkato 0:ee40da884cfc 2696 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);
dkato 0:ee40da884cfc 2697 else
dkato 0:ee40da884cfc 2698 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);
dkato 0:ee40da884cfc 2699 }
dkato 0:ee40da884cfc 2700
dkato 0:ee40da884cfc 2701 return true;
dkato 0:ee40da884cfc 2702 }
dkato 0:ee40da884cfc 2703
dkato 0:ee40da884cfc 2704 FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode)
dkato 0:ee40da884cfc 2705 {
dkato 0:ee40da884cfc 2706 FLAC__Subframe_Verbatim *subframe = &decoder->private_->frame.subframes[channel].data.verbatim;
dkato 0:ee40da884cfc 2707 FLAC__int32 x, *residual = decoder->private_->residual[channel];
dkato 0:ee40da884cfc 2708 unsigned i;
dkato 0:ee40da884cfc 2709
dkato 0:ee40da884cfc 2710 decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_VERBATIM;
dkato 0:ee40da884cfc 2711
dkato 0:ee40da884cfc 2712 subframe->data = residual;
dkato 0:ee40da884cfc 2713
dkato 0:ee40da884cfc 2714 for(i = 0; i < decoder->private_->frame.header.blocksize; i++) {
dkato 0:ee40da884cfc 2715 if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &x, bps))
dkato 0:ee40da884cfc 2716 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2717 residual[i] = x;
dkato 0:ee40da884cfc 2718 }
dkato 0:ee40da884cfc 2719
dkato 0:ee40da884cfc 2720 /* decode the subframe */
dkato 0:ee40da884cfc 2721 if(do_full_decode)
dkato 0:ee40da884cfc 2722 memcpy(decoder->private_->output[channel], subframe->data, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize);
dkato 0:ee40da884cfc 2723
dkato 0:ee40da884cfc 2724 return true;
dkato 0:ee40da884cfc 2725 }
dkato 0:ee40da884cfc 2726
dkato 0:ee40da884cfc 2727 FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigned predictor_order, unsigned partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, FLAC__int32 *residual, FLAC__bool is_extended)
dkato 0:ee40da884cfc 2728 {
dkato 0:ee40da884cfc 2729 FLAC__uint32 rice_parameter;
dkato 0:ee40da884cfc 2730 int i;
dkato 0:ee40da884cfc 2731 unsigned partition, sample, u;
dkato 0:ee40da884cfc 2732 const unsigned partitions = 1u << partition_order;
dkato 0:ee40da884cfc 2733 const unsigned partition_samples = partition_order > 0? decoder->private_->frame.header.blocksize >> partition_order : decoder->private_->frame.header.blocksize - predictor_order;
dkato 0:ee40da884cfc 2734 const unsigned plen = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN;
dkato 0:ee40da884cfc 2735 const unsigned pesc = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER;
dkato 0:ee40da884cfc 2736
dkato 0:ee40da884cfc 2737 /* sanity checks */
dkato 0:ee40da884cfc 2738 if(partition_order == 0) {
dkato 0:ee40da884cfc 2739 if(decoder->private_->frame.header.blocksize < predictor_order) {
dkato 0:ee40da884cfc 2740 send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
dkato 0:ee40da884cfc 2741 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
dkato 0:ee40da884cfc 2742 /* We have received a potentially malicious bit stream. All we can do is error out to avoid a heap overflow. */
dkato 0:ee40da884cfc 2743 return false;
dkato 0:ee40da884cfc 2744 }
dkato 0:ee40da884cfc 2745 }
dkato 0:ee40da884cfc 2746 else {
dkato 0:ee40da884cfc 2747 if(partition_samples < predictor_order) {
dkato 0:ee40da884cfc 2748 send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
dkato 0:ee40da884cfc 2749 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
dkato 0:ee40da884cfc 2750 /* We have received a potentially malicious bit stream. All we can do is error out to avoid a heap overflow. */
dkato 0:ee40da884cfc 2751 return false;
dkato 0:ee40da884cfc 2752 }
dkato 0:ee40da884cfc 2753 }
dkato 0:ee40da884cfc 2754
dkato 0:ee40da884cfc 2755 if(!FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, flac_max(6u, partition_order))) {
dkato 0:ee40da884cfc 2756 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
dkato 0:ee40da884cfc 2757 return false;
dkato 0:ee40da884cfc 2758 }
dkato 0:ee40da884cfc 2759
dkato 0:ee40da884cfc 2760 sample = 0;
dkato 0:ee40da884cfc 2761 for(partition = 0; partition < partitions; partition++) {
dkato 0:ee40da884cfc 2762 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &rice_parameter, plen))
dkato 0:ee40da884cfc 2763 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2764 partitioned_rice_contents->parameters[partition] = rice_parameter;
dkato 0:ee40da884cfc 2765 if(rice_parameter < pesc) {
dkato 0:ee40da884cfc 2766 partitioned_rice_contents->raw_bits[partition] = 0;
dkato 0:ee40da884cfc 2767 u = (partition_order == 0 || partition > 0)? partition_samples : partition_samples - predictor_order;
dkato 0:ee40da884cfc 2768 if(!FLAC__bitreader_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter))
dkato 0:ee40da884cfc 2769 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2770 sample += u;
dkato 0:ee40da884cfc 2771 }
dkato 0:ee40da884cfc 2772 else {
dkato 0:ee40da884cfc 2773 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN))
dkato 0:ee40da884cfc 2774 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2775 partitioned_rice_contents->raw_bits[partition] = rice_parameter;
dkato 0:ee40da884cfc 2776 for(u = (partition_order == 0 || partition > 0)? 0 : predictor_order; u < partition_samples; u++, sample++) {
dkato 0:ee40da884cfc 2777 if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i, rice_parameter))
dkato 0:ee40da884cfc 2778 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2779 residual[sample] = i;
dkato 0:ee40da884cfc 2780 }
dkato 0:ee40da884cfc 2781 }
dkato 0:ee40da884cfc 2782 }
dkato 0:ee40da884cfc 2783
dkato 0:ee40da884cfc 2784 return true;
dkato 0:ee40da884cfc 2785 }
dkato 0:ee40da884cfc 2786
dkato 0:ee40da884cfc 2787 FLAC__bool read_zero_padding_(FLAC__StreamDecoder *decoder)
dkato 0:ee40da884cfc 2788 {
dkato 0:ee40da884cfc 2789 if(!FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)) {
dkato 0:ee40da884cfc 2790 FLAC__uint32 zero = 0;
dkato 0:ee40da884cfc 2791 if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &zero, FLAC__bitreader_bits_left_for_byte_alignment(decoder->private_->input)))
dkato 0:ee40da884cfc 2792 return false; /* read_callback_ sets the state for us */
dkato 0:ee40da884cfc 2793 if(zero != 0) {
dkato 0:ee40da884cfc 2794 send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
dkato 0:ee40da884cfc 2795 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
dkato 0:ee40da884cfc 2796 }
dkato 0:ee40da884cfc 2797 }
dkato 0:ee40da884cfc 2798 return true;
dkato 0:ee40da884cfc 2799 }
dkato 0:ee40da884cfc 2800
dkato 0:ee40da884cfc 2801 FLAC__bool read_callback_(FLAC__byte buffer[], size_t *bytes, void *client_data)
dkato 0:ee40da884cfc 2802 {
dkato 0:ee40da884cfc 2803 FLAC__StreamDecoder *decoder = (FLAC__StreamDecoder *)client_data;
dkato 0:ee40da884cfc 2804
dkato 0:ee40da884cfc 2805 if(
dkato 0:ee40da884cfc 2806 #if FLAC__HAS_OGG
dkato 0:ee40da884cfc 2807 /* see [1] HACK NOTE below for why we don't call the eof_callback when decoding Ogg FLAC */
dkato 0:ee40da884cfc 2808 !decoder->private_->is_ogg &&
dkato 0:ee40da884cfc 2809 #endif
dkato 0:ee40da884cfc 2810 decoder->private_->eof_callback && decoder->private_->eof_callback(decoder, decoder->private_->client_data)
dkato 0:ee40da884cfc 2811 ) {
dkato 0:ee40da884cfc 2812 *bytes = 0;
dkato 0:ee40da884cfc 2813 decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM;
dkato 0:ee40da884cfc 2814 return false;
dkato 0:ee40da884cfc 2815 }
dkato 0:ee40da884cfc 2816 else if(*bytes > 0) {
dkato 0:ee40da884cfc 2817 /* While seeking, it is possible for our seek to land in the
dkato 0:ee40da884cfc 2818 * middle of audio data that looks exactly like a frame header
dkato 0:ee40da884cfc 2819 * from a future version of an encoder. When that happens, our
dkato 0:ee40da884cfc 2820 * error callback will get an
dkato 0:ee40da884cfc 2821 * FLAC__STREAM_DECODER_UNPARSEABLE_STREAM and increment its
dkato 0:ee40da884cfc 2822 * unparseable_frame_count. But there is a remote possibility
dkato 0:ee40da884cfc 2823 * that it is properly synced at such a "future-codec frame",
dkato 0:ee40da884cfc 2824 * so to make sure, we wait to see many "unparseable" errors in
dkato 0:ee40da884cfc 2825 * a row before bailing out.
dkato 0:ee40da884cfc 2826 */
dkato 0:ee40da884cfc 2827 if(decoder->private_->is_seeking && decoder->private_->unparseable_frame_count > 20) {
dkato 0:ee40da884cfc 2828 decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED;
dkato 0:ee40da884cfc 2829 return false;
dkato 0:ee40da884cfc 2830 }
dkato 0:ee40da884cfc 2831 else {
dkato 0:ee40da884cfc 2832 const FLAC__StreamDecoderReadStatus status =
dkato 0:ee40da884cfc 2833 #if FLAC__HAS_OGG
dkato 0:ee40da884cfc 2834 decoder->private_->is_ogg?
dkato 0:ee40da884cfc 2835 read_callback_ogg_aspect_(decoder, buffer, bytes) :
dkato 0:ee40da884cfc 2836 #endif
dkato 0:ee40da884cfc 2837 decoder->private_->read_callback(decoder, buffer, bytes, decoder->private_->client_data)
dkato 0:ee40da884cfc 2838 ;
dkato 0:ee40da884cfc 2839 if(status == FLAC__STREAM_DECODER_READ_STATUS_ABORT) {
dkato 0:ee40da884cfc 2840 decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED;
dkato 0:ee40da884cfc 2841 return false;
dkato 0:ee40da884cfc 2842 }
dkato 0:ee40da884cfc 2843 else if(*bytes == 0) {
dkato 0:ee40da884cfc 2844 if(
dkato 0:ee40da884cfc 2845 status == FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM ||
dkato 0:ee40da884cfc 2846 (
dkato 0:ee40da884cfc 2847 #if FLAC__HAS_OGG
dkato 0:ee40da884cfc 2848 /* see [1] HACK NOTE below for why we don't call the eof_callback when decoding Ogg FLAC */
dkato 0:ee40da884cfc 2849 !decoder->private_->is_ogg &&
dkato 0:ee40da884cfc 2850 #endif
dkato 0:ee40da884cfc 2851 decoder->private_->eof_callback && decoder->private_->eof_callback(decoder, decoder->private_->client_data)
dkato 0:ee40da884cfc 2852 )
dkato 0:ee40da884cfc 2853 ) {
dkato 0:ee40da884cfc 2854 decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM;
dkato 0:ee40da884cfc 2855 return false;
dkato 0:ee40da884cfc 2856 }
dkato 0:ee40da884cfc 2857 else
dkato 0:ee40da884cfc 2858 return true;
dkato 0:ee40da884cfc 2859 }
dkato 0:ee40da884cfc 2860 else
dkato 0:ee40da884cfc 2861 return true;
dkato 0:ee40da884cfc 2862 }
dkato 0:ee40da884cfc 2863 }
dkato 0:ee40da884cfc 2864 else {
dkato 0:ee40da884cfc 2865 /* abort to avoid a deadlock */
dkato 0:ee40da884cfc 2866 decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED;
dkato 0:ee40da884cfc 2867 return false;
dkato 0:ee40da884cfc 2868 }
dkato 0:ee40da884cfc 2869 /* [1] @@@ HACK NOTE: The end-of-stream checking has to be hacked around
dkato 0:ee40da884cfc 2870 * for Ogg FLAC. This is because the ogg decoder aspect can lose sync
dkato 0:ee40da884cfc 2871 * and at the same time hit the end of the stream (for example, seeking
dkato 0:ee40da884cfc 2872 * to a point that is after the beginning of the last Ogg page). There
dkato 0:ee40da884cfc 2873 * is no way to report an Ogg sync loss through the callbacks (see note
dkato 0:ee40da884cfc 2874 * in read_callback_ogg_aspect_()) so it returns CONTINUE with *bytes==0.
dkato 0:ee40da884cfc 2875 * So to keep the decoder from stopping at this point we gate the call
dkato 0:ee40da884cfc 2876 * to the eof_callback and let the Ogg decoder aspect set the
dkato 0:ee40da884cfc 2877 * end-of-stream state when it is needed.
dkato 0:ee40da884cfc 2878 */
dkato 0:ee40da884cfc 2879 }
dkato 0:ee40da884cfc 2880
dkato 0:ee40da884cfc 2881 #if FLAC__HAS_OGG
dkato 0:ee40da884cfc 2882 FLAC__StreamDecoderReadStatus read_callback_ogg_aspect_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes)
dkato 0:ee40da884cfc 2883 {
dkato 0:ee40da884cfc 2884 switch(FLAC__ogg_decoder_aspect_read_callback_wrapper(&decoder->protected_->ogg_decoder_aspect, buffer, bytes, read_callback_proxy_, decoder, decoder->private_->client_data)) {
dkato 0:ee40da884cfc 2885 case FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK:
dkato 0:ee40da884cfc 2886 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
dkato 0:ee40da884cfc 2887 /* we don't really have a way to handle lost sync via read
dkato 0:ee40da884cfc 2888 * callback so we'll let it pass and let the underlying
dkato 0:ee40da884cfc 2889 * FLAC decoder catch the error
dkato 0:ee40da884cfc 2890 */
dkato 0:ee40da884cfc 2891 case FLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC:
dkato 0:ee40da884cfc 2892 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
dkato 0:ee40da884cfc 2893 case FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM:
dkato 0:ee40da884cfc 2894 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
dkato 0:ee40da884cfc 2895 case FLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC:
dkato 0:ee40da884cfc 2896 case FLAC__OGG_DECODER_ASPECT_READ_STATUS_UNSUPPORTED_MAPPING_VERSION:
dkato 0:ee40da884cfc 2897 case FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT:
dkato 0:ee40da884cfc 2898 case FLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR:
dkato 0:ee40da884cfc 2899 case FLAC__OGG_DECODER_ASPECT_READ_STATUS_MEMORY_ALLOCATION_ERROR:
dkato 0:ee40da884cfc 2900 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
dkato 0:ee40da884cfc 2901 default:
dkato 0:ee40da884cfc 2902 FLAC__ASSERT(0);
dkato 0:ee40da884cfc 2903 /* double protection */
dkato 0:ee40da884cfc 2904 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
dkato 0:ee40da884cfc 2905 }
dkato 0:ee40da884cfc 2906 }
dkato 0:ee40da884cfc 2907
dkato 0:ee40da884cfc 2908 FLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
dkato 0:ee40da884cfc 2909 {
dkato 0:ee40da884cfc 2910 FLAC__StreamDecoder *decoder = (FLAC__StreamDecoder*)void_decoder;
dkato 0:ee40da884cfc 2911
dkato 0:ee40da884cfc 2912 switch(decoder->private_->read_callback(decoder, buffer, bytes, client_data)) {
dkato 0:ee40da884cfc 2913 case FLAC__STREAM_DECODER_READ_STATUS_CONTINUE:
dkato 0:ee40da884cfc 2914 return FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK;
dkato 0:ee40da884cfc 2915 case FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM:
dkato 0:ee40da884cfc 2916 return FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM;
dkato 0:ee40da884cfc 2917 case FLAC__STREAM_DECODER_READ_STATUS_ABORT:
dkato 0:ee40da884cfc 2918 return FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT;
dkato 0:ee40da884cfc 2919 default:
dkato 0:ee40da884cfc 2920 /* double protection: */
dkato 0:ee40da884cfc 2921 FLAC__ASSERT(0);
dkato 0:ee40da884cfc 2922 return FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT;
dkato 0:ee40da884cfc 2923 }
dkato 0:ee40da884cfc 2924 }
dkato 0:ee40da884cfc 2925 #endif
dkato 0:ee40da884cfc 2926
dkato 0:ee40da884cfc 2927 FLAC__StreamDecoderWriteStatus write_audio_frame_to_client_(FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[])
dkato 0:ee40da884cfc 2928 {
dkato 0:ee40da884cfc 2929 if(decoder->private_->is_seeking) {
dkato 0:ee40da884cfc 2930 FLAC__uint64 this_frame_sample = frame->header.number.sample_number;
dkato 0:ee40da884cfc 2931 FLAC__uint64 next_frame_sample = this_frame_sample + (FLAC__uint64)frame->header.blocksize;
dkato 0:ee40da884cfc 2932 FLAC__uint64 target_sample = decoder->private_->target_sample;
dkato 0:ee40da884cfc 2933
dkato 0:ee40da884cfc 2934 FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
dkato 0:ee40da884cfc 2935
dkato 0:ee40da884cfc 2936 #if FLAC__HAS_OGG
dkato 0:ee40da884cfc 2937 decoder->private_->got_a_frame = true;
dkato 0:ee40da884cfc 2938 #endif
dkato 0:ee40da884cfc 2939 decoder->private_->last_frame = *frame; /* save the frame */
dkato 0:ee40da884cfc 2940 if(this_frame_sample <= target_sample && target_sample < next_frame_sample) { /* we hit our target frame */
dkato 0:ee40da884cfc 2941 unsigned delta = (unsigned)(target_sample - this_frame_sample);
dkato 0:ee40da884cfc 2942 /* kick out of seek mode */
dkato 0:ee40da884cfc 2943 decoder->private_->is_seeking = false;
dkato 0:ee40da884cfc 2944 /* shift out the samples before target_sample */
dkato 0:ee40da884cfc 2945 if(delta > 0) {
dkato 0:ee40da884cfc 2946 unsigned channel;
dkato 0:ee40da884cfc 2947 const FLAC__int32 *newbuffer[FLAC__MAX_CHANNELS];
dkato 0:ee40da884cfc 2948 for(channel = 0; channel < frame->header.channels; channel++)
dkato 0:ee40da884cfc 2949 newbuffer[channel] = buffer[channel] + delta;
dkato 0:ee40da884cfc 2950 decoder->private_->last_frame.header.blocksize -= delta;
dkato 0:ee40da884cfc 2951 decoder->private_->last_frame.header.number.sample_number += (FLAC__uint64)delta;
dkato 0:ee40da884cfc 2952 /* write the relevant samples */
dkato 0:ee40da884cfc 2953 return decoder->private_->write_callback(decoder, &decoder->private_->last_frame, newbuffer, decoder->private_->client_data);
dkato 0:ee40da884cfc 2954 }
dkato 0:ee40da884cfc 2955 else {
dkato 0:ee40da884cfc 2956 /* write the relevant samples */
dkato 0:ee40da884cfc 2957 return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data);
dkato 0:ee40da884cfc 2958 }
dkato 0:ee40da884cfc 2959 }
dkato 0:ee40da884cfc 2960 else {
dkato 0:ee40da884cfc 2961 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
dkato 0:ee40da884cfc 2962 }
dkato 0:ee40da884cfc 2963 }
dkato 0:ee40da884cfc 2964 else {
dkato 0:ee40da884cfc 2965 /*
dkato 0:ee40da884cfc 2966 * If we never got STREAMINFO, turn off MD5 checking to save
dkato 0:ee40da884cfc 2967 * cycles since we don't have a sum to compare to anyway
dkato 0:ee40da884cfc 2968 */
dkato 0:ee40da884cfc 2969 if(!decoder->private_->has_stream_info)
dkato 0:ee40da884cfc 2970 decoder->private_->do_md5_checking = false;
dkato 0:ee40da884cfc 2971 if(decoder->private_->do_md5_checking) {
dkato 0:ee40da884cfc 2972 if(!FLAC__MD5Accumulate(&decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8))
dkato 0:ee40da884cfc 2973 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
dkato 0:ee40da884cfc 2974 }
dkato 0:ee40da884cfc 2975 return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data);
dkato 0:ee40da884cfc 2976 }
dkato 0:ee40da884cfc 2977 }
dkato 0:ee40da884cfc 2978
dkato 0:ee40da884cfc 2979 void send_error_to_client_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status)
dkato 0:ee40da884cfc 2980 {
dkato 0:ee40da884cfc 2981 if(!decoder->private_->is_seeking)
dkato 0:ee40da884cfc 2982 decoder->private_->error_callback(decoder, status, decoder->private_->client_data);
dkato 0:ee40da884cfc 2983 else if(status == FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM)
dkato 0:ee40da884cfc 2984 decoder->private_->unparseable_frame_count++;
dkato 0:ee40da884cfc 2985 }
dkato 0:ee40da884cfc 2986
dkato 0:ee40da884cfc 2987 FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample)
dkato 0:ee40da884cfc 2988 {
dkato 0:ee40da884cfc 2989 FLAC__uint64 first_frame_offset = decoder->private_->first_frame_offset, lower_bound, upper_bound, lower_bound_sample, upper_bound_sample, this_frame_sample;
dkato 0:ee40da884cfc 2990 FLAC__int64 pos = -1;
dkato 0:ee40da884cfc 2991 int i;
dkato 0:ee40da884cfc 2992 unsigned approx_bytes_per_frame;
dkato 0:ee40da884cfc 2993 FLAC__bool first_seek = true;
dkato 0:ee40da884cfc 2994 const FLAC__uint64 total_samples = FLAC__stream_decoder_get_total_samples(decoder);
dkato 0:ee40da884cfc 2995 const unsigned min_blocksize = decoder->private_->stream_info.data.stream_info.min_blocksize;
dkato 0:ee40da884cfc 2996 const unsigned max_blocksize = decoder->private_->stream_info.data.stream_info.max_blocksize;
dkato 0:ee40da884cfc 2997 const unsigned max_framesize = decoder->private_->stream_info.data.stream_info.max_framesize;
dkato 0:ee40da884cfc 2998 const unsigned min_framesize = decoder->private_->stream_info.data.stream_info.min_framesize;
dkato 0:ee40da884cfc 2999 /* take these from the current frame in case they've changed mid-stream */
dkato 0:ee40da884cfc 3000 unsigned channels = FLAC__stream_decoder_get_channels(decoder);
dkato 0:ee40da884cfc 3001 unsigned bps = FLAC__stream_decoder_get_bits_per_sample(decoder);
dkato 0:ee40da884cfc 3002 const FLAC__StreamMetadata_SeekTable *seek_table = decoder->private_->has_seek_table? &decoder->private_->seek_table.data.seek_table : 0;
dkato 0:ee40da884cfc 3003
dkato 0:ee40da884cfc 3004 /* use values from stream info if we didn't decode a frame */
dkato 0:ee40da884cfc 3005 if(channels == 0)
dkato 0:ee40da884cfc 3006 channels = decoder->private_->stream_info.data.stream_info.channels;
dkato 0:ee40da884cfc 3007 if(bps == 0)
dkato 0:ee40da884cfc 3008 bps = decoder->private_->stream_info.data.stream_info.bits_per_sample;
dkato 0:ee40da884cfc 3009
dkato 0:ee40da884cfc 3010 /* we are just guessing here */
dkato 0:ee40da884cfc 3011 if(max_framesize > 0)
dkato 0:ee40da884cfc 3012 approx_bytes_per_frame = (max_framesize + min_framesize) / 2 + 1;
dkato 0:ee40da884cfc 3013 /*
dkato 0:ee40da884cfc 3014 * Check if it's a known fixed-blocksize stream. Note that though
dkato 0:ee40da884cfc 3015 * the spec doesn't allow zeroes in the STREAMINFO block, we may
dkato 0:ee40da884cfc 3016 * never get a STREAMINFO block when decoding so the value of
dkato 0:ee40da884cfc 3017 * min_blocksize might be zero.
dkato 0:ee40da884cfc 3018 */
dkato 0:ee40da884cfc 3019 else if(min_blocksize == max_blocksize && min_blocksize > 0) {
dkato 0:ee40da884cfc 3020 /* note there are no () around 'bps/8' to keep precision up since it's an integer calulation */
dkato 0:ee40da884cfc 3021 approx_bytes_per_frame = min_blocksize * channels * bps/8 + 64;
dkato 0:ee40da884cfc 3022 }
dkato 0:ee40da884cfc 3023 else
dkato 0:ee40da884cfc 3024 approx_bytes_per_frame = 4096 * channels * bps/8 + 64;
dkato 0:ee40da884cfc 3025
dkato 0:ee40da884cfc 3026 /*
dkato 0:ee40da884cfc 3027 * First, we set an upper and lower bound on where in the
dkato 0:ee40da884cfc 3028 * stream we will search. For now we assume the worst case
dkato 0:ee40da884cfc 3029 * scenario, which is our best guess at the beginning of
dkato 0:ee40da884cfc 3030 * the first frame and end of the stream.
dkato 0:ee40da884cfc 3031 */
dkato 0:ee40da884cfc 3032 lower_bound = first_frame_offset;
dkato 0:ee40da884cfc 3033 lower_bound_sample = 0;
dkato 0:ee40da884cfc 3034 upper_bound = stream_length;
dkato 0:ee40da884cfc 3035 upper_bound_sample = total_samples > 0 ? total_samples : target_sample /*estimate it*/;
dkato 0:ee40da884cfc 3036
dkato 0:ee40da884cfc 3037 /*
dkato 0:ee40da884cfc 3038 * Now we refine the bounds if we have a seektable with
dkato 0:ee40da884cfc 3039 * suitable points. Note that according to the spec they
dkato 0:ee40da884cfc 3040 * must be ordered by ascending sample number.
dkato 0:ee40da884cfc 3041 *
dkato 0:ee40da884cfc 3042 * Note: to protect against invalid seek tables we will ignore points
dkato 0:ee40da884cfc 3043 * that have frame_samples==0 or sample_number>=total_samples
dkato 0:ee40da884cfc 3044 */
dkato 0:ee40da884cfc 3045 if(seek_table) {
dkato 0:ee40da884cfc 3046 FLAC__uint64 new_lower_bound = lower_bound;
dkato 0:ee40da884cfc 3047 FLAC__uint64 new_upper_bound = upper_bound;
dkato 0:ee40da884cfc 3048 FLAC__uint64 new_lower_bound_sample = lower_bound_sample;
dkato 0:ee40da884cfc 3049 FLAC__uint64 new_upper_bound_sample = upper_bound_sample;
dkato 0:ee40da884cfc 3050
dkato 0:ee40da884cfc 3051 /* find the closest seek point <= target_sample, if it exists */
dkato 0:ee40da884cfc 3052 for(i = (int)seek_table->num_points - 1; i >= 0; i--) {
dkato 0:ee40da884cfc 3053 if(
dkato 0:ee40da884cfc 3054 seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER &&
dkato 0:ee40da884cfc 3055 seek_table->points[i].frame_samples > 0 && /* defense against bad seekpoints */
dkato 0:ee40da884cfc 3056 (total_samples <= 0 || seek_table->points[i].sample_number < total_samples) && /* defense against bad seekpoints */
dkato 0:ee40da884cfc 3057 seek_table->points[i].sample_number <= target_sample
dkato 0:ee40da884cfc 3058 )
dkato 0:ee40da884cfc 3059 break;
dkato 0:ee40da884cfc 3060 }
dkato 0:ee40da884cfc 3061 if(i >= 0) { /* i.e. we found a suitable seek point... */
dkato 0:ee40da884cfc 3062 new_lower_bound = first_frame_offset + seek_table->points[i].stream_offset;
dkato 0:ee40da884cfc 3063 new_lower_bound_sample = seek_table->points[i].sample_number;
dkato 0:ee40da884cfc 3064 }
dkato 0:ee40da884cfc 3065
dkato 0:ee40da884cfc 3066 /* find the closest seek point > target_sample, if it exists */
dkato 0:ee40da884cfc 3067 for(i = 0; i < (int)seek_table->num_points; i++) {
dkato 0:ee40da884cfc 3068 if(
dkato 0:ee40da884cfc 3069 seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER &&
dkato 0:ee40da884cfc 3070 seek_table->points[i].frame_samples > 0 && /* defense against bad seekpoints */
dkato 0:ee40da884cfc 3071 (total_samples <= 0 || seek_table->points[i].sample_number < total_samples) && /* defense against bad seekpoints */
dkato 0:ee40da884cfc 3072 seek_table->points[i].sample_number > target_sample
dkato 0:ee40da884cfc 3073 )
dkato 0:ee40da884cfc 3074 break;
dkato 0:ee40da884cfc 3075 }
dkato 0:ee40da884cfc 3076 if(i < (int)seek_table->num_points) { /* i.e. we found a suitable seek point... */
dkato 0:ee40da884cfc 3077 new_upper_bound = first_frame_offset + seek_table->points[i].stream_offset;
dkato 0:ee40da884cfc 3078 new_upper_bound_sample = seek_table->points[i].sample_number;
dkato 0:ee40da884cfc 3079 }
dkato 0:ee40da884cfc 3080 /* final protection against unsorted seek tables; keep original values if bogus */
dkato 0:ee40da884cfc 3081 if(new_upper_bound >= new_lower_bound) {
dkato 0:ee40da884cfc 3082 lower_bound = new_lower_bound;
dkato 0:ee40da884cfc 3083 upper_bound = new_upper_bound;
dkato 0:ee40da884cfc 3084 lower_bound_sample = new_lower_bound_sample;
dkato 0:ee40da884cfc 3085 upper_bound_sample = new_upper_bound_sample;
dkato 0:ee40da884cfc 3086 }
dkato 0:ee40da884cfc 3087 }
dkato 0:ee40da884cfc 3088
dkato 0:ee40da884cfc 3089 FLAC__ASSERT(upper_bound_sample >= lower_bound_sample);
dkato 0:ee40da884cfc 3090 /* there are 2 insidious ways that the following equality occurs, which
dkato 0:ee40da884cfc 3091 * we need to fix:
dkato 0:ee40da884cfc 3092 * 1) total_samples is 0 (unknown) and target_sample is 0
dkato 0:ee40da884cfc 3093 * 2) total_samples is 0 (unknown) and target_sample happens to be
dkato 0:ee40da884cfc 3094 * exactly equal to the last seek point in the seek table; this
dkato 0:ee40da884cfc 3095 * means there is no seek point above it, and upper_bound_samples
dkato 0:ee40da884cfc 3096 * remains equal to the estimate (of target_samples) we made above
dkato 0:ee40da884cfc 3097 * in either case it does not hurt to move upper_bound_sample up by 1
dkato 0:ee40da884cfc 3098 */
dkato 0:ee40da884cfc 3099 if(upper_bound_sample == lower_bound_sample)
dkato 0:ee40da884cfc 3100 upper_bound_sample++;
dkato 0:ee40da884cfc 3101
dkato 0:ee40da884cfc 3102 decoder->private_->target_sample = target_sample;
dkato 0:ee40da884cfc 3103 while(1) {
dkato 0:ee40da884cfc 3104 /* check if the bounds are still ok */
dkato 0:ee40da884cfc 3105 if (lower_bound_sample >= upper_bound_sample || lower_bound > upper_bound) {
dkato 0:ee40da884cfc 3106 decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
dkato 0:ee40da884cfc 3107 return false;
dkato 0:ee40da884cfc 3108 }
dkato 0:ee40da884cfc 3109 #ifndef FLAC__INTEGER_ONLY_LIBRARY
dkato 0:ee40da884cfc 3110 pos = (FLAC__int64)lower_bound + (FLAC__int64)((FLAC__double)(target_sample - lower_bound_sample) / (FLAC__double)(upper_bound_sample - lower_bound_sample) * (FLAC__double)(upper_bound - lower_bound)) - approx_bytes_per_frame;
dkato 0:ee40da884cfc 3111 #else
dkato 0:ee40da884cfc 3112 /* a little less accurate: */
dkato 0:ee40da884cfc 3113 if(upper_bound - lower_bound < 0xffffffff)
dkato 0:ee40da884cfc 3114 pos = (FLAC__int64)lower_bound + (FLAC__int64)(((target_sample - lower_bound_sample) * (upper_bound - lower_bound)) / (upper_bound_sample - lower_bound_sample)) - approx_bytes_per_frame;
dkato 0:ee40da884cfc 3115 else /* @@@ WATCHOUT, ~2TB limit */
dkato 0:ee40da884cfc 3116 pos = (FLAC__int64)lower_bound + (FLAC__int64)((((target_sample - lower_bound_sample)>>8) * ((upper_bound - lower_bound)>>8)) / ((upper_bound_sample - lower_bound_sample)>>16)) - approx_bytes_per_frame;
dkato 0:ee40da884cfc 3117 #endif
dkato 0:ee40da884cfc 3118 if(pos >= (FLAC__int64)upper_bound)
dkato 0:ee40da884cfc 3119 pos = (FLAC__int64)upper_bound - 1;
dkato 0:ee40da884cfc 3120 if(pos < (FLAC__int64)lower_bound)
dkato 0:ee40da884cfc 3121 pos = (FLAC__int64)lower_bound;
dkato 0:ee40da884cfc 3122 if(decoder->private_->seek_callback(decoder, (FLAC__uint64)pos, decoder->private_->client_data) != FLAC__STREAM_DECODER_SEEK_STATUS_OK) {
dkato 0:ee40da884cfc 3123 decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
dkato 0:ee40da884cfc 3124 return false;
dkato 0:ee40da884cfc 3125 }
dkato 0:ee40da884cfc 3126 if(!FLAC__stream_decoder_flush(decoder)) {
dkato 0:ee40da884cfc 3127 /* above call sets the state for us */
dkato 0:ee40da884cfc 3128 return false;
dkato 0:ee40da884cfc 3129 }
dkato 0:ee40da884cfc 3130 /* Now we need to get a frame. First we need to reset our
dkato 0:ee40da884cfc 3131 * unparseable_frame_count; if we get too many unparseable
dkato 0:ee40da884cfc 3132 * frames in a row, the read callback will return
dkato 0:ee40da884cfc 3133 * FLAC__STREAM_DECODER_READ_STATUS_ABORT, causing
dkato 0:ee40da884cfc 3134 * FLAC__stream_decoder_process_single() to return false.
dkato 0:ee40da884cfc 3135 */
dkato 0:ee40da884cfc 3136 decoder->private_->unparseable_frame_count = 0;
dkato 0:ee40da884cfc 3137 if(!FLAC__stream_decoder_process_single(decoder)) {
dkato 0:ee40da884cfc 3138 decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
dkato 0:ee40da884cfc 3139 return false;
dkato 0:ee40da884cfc 3140 }
dkato 0:ee40da884cfc 3141 /* our write callback will change the state when it gets to the target frame */
dkato 0:ee40da884cfc 3142 /* 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 */
dkato 0:ee40da884cfc 3143 #if 0
dkato 0:ee40da884cfc 3144 /*@@@@@@ used to be the following; not clear if the check for end of stream is needed anymore */
dkato 0:ee40da884cfc 3145 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING && decoder->protected_->state != FLAC__STREAM_DECODER_END_OF_STREAM)
dkato 0:ee40da884cfc 3146 break;
dkato 0:ee40da884cfc 3147 #endif
dkato 0:ee40da884cfc 3148 if(!decoder->private_->is_seeking)
dkato 0:ee40da884cfc 3149 break;
dkato 0:ee40da884cfc 3150
dkato 0:ee40da884cfc 3151 FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
dkato 0:ee40da884cfc 3152 this_frame_sample = decoder->private_->last_frame.header.number.sample_number;
dkato 0:ee40da884cfc 3153
dkato 0:ee40da884cfc 3154 if (0 == decoder->private_->samples_decoded || (this_frame_sample + decoder->private_->last_frame.header.blocksize >= upper_bound_sample && !first_seek)) {
dkato 0:ee40da884cfc 3155 if (pos == (FLAC__int64)lower_bound) {
dkato 0:ee40da884cfc 3156 /* can't move back any more than the first frame, something is fatally wrong */
dkato 0:ee40da884cfc 3157 decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
dkato 0:ee40da884cfc 3158 return false;
dkato 0:ee40da884cfc 3159 }
dkato 0:ee40da884cfc 3160 /* our last move backwards wasn't big enough, try again */
dkato 0:ee40da884cfc 3161 approx_bytes_per_frame = approx_bytes_per_frame? approx_bytes_per_frame * 2 : 16;
dkato 0:ee40da884cfc 3162 continue;
dkato 0:ee40da884cfc 3163 }
dkato 0:ee40da884cfc 3164 /* allow one seek over upper bound, so we can get a correct upper_bound_sample for streams with unknown total_samples */
dkato 0:ee40da884cfc 3165 first_seek = false;
dkato 0:ee40da884cfc 3166
dkato 0:ee40da884cfc 3167 /* make sure we are not seeking in corrupted stream */
dkato 0:ee40da884cfc 3168 if (this_frame_sample < lower_bound_sample) {
dkato 0:ee40da884cfc 3169 decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
dkato 0:ee40da884cfc 3170 return false;
dkato 0:ee40da884cfc 3171 }
dkato 0:ee40da884cfc 3172
dkato 0:ee40da884cfc 3173 /* we need to narrow the search */
dkato 0:ee40da884cfc 3174 if(target_sample < this_frame_sample) {
dkato 0:ee40da884cfc 3175 upper_bound_sample = this_frame_sample + decoder->private_->last_frame.header.blocksize;
dkato 0:ee40da884cfc 3176 /*@@@@@@ what will decode position be if at end of stream? */
dkato 0:ee40da884cfc 3177 if(!FLAC__stream_decoder_get_decode_position(decoder, &upper_bound)) {
dkato 0:ee40da884cfc 3178 decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
dkato 0:ee40da884cfc 3179 return false;
dkato 0:ee40da884cfc 3180 }
dkato 0:ee40da884cfc 3181 approx_bytes_per_frame = (unsigned)(2 * (upper_bound - pos) / 3 + 16);
dkato 0:ee40da884cfc 3182 }
dkato 0:ee40da884cfc 3183 else { /* target_sample >= this_frame_sample + this frame's blocksize */
dkato 0:ee40da884cfc 3184 lower_bound_sample = this_frame_sample + decoder->private_->last_frame.header.blocksize;
dkato 0:ee40da884cfc 3185 if(!FLAC__stream_decoder_get_decode_position(decoder, &lower_bound)) {
dkato 0:ee40da884cfc 3186 decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
dkato 0:ee40da884cfc 3187 return false;
dkato 0:ee40da884cfc 3188 }
dkato 0:ee40da884cfc 3189 approx_bytes_per_frame = (unsigned)(2 * (lower_bound - pos) / 3 + 16);
dkato 0:ee40da884cfc 3190 }
dkato 0:ee40da884cfc 3191 }
dkato 0:ee40da884cfc 3192
dkato 0:ee40da884cfc 3193 return true;
dkato 0:ee40da884cfc 3194 }
dkato 0:ee40da884cfc 3195
dkato 0:ee40da884cfc 3196 #if FLAC__HAS_OGG
dkato 0:ee40da884cfc 3197 FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample)
dkato 0:ee40da884cfc 3198 {
dkato 0:ee40da884cfc 3199 FLAC__uint64 left_pos = 0, right_pos = stream_length;
dkato 0:ee40da884cfc 3200 FLAC__uint64 left_sample = 0, right_sample = FLAC__stream_decoder_get_total_samples(decoder);
dkato 0:ee40da884cfc 3201 FLAC__uint64 this_frame_sample = (FLAC__uint64)0 - 1;
dkato 0:ee40da884cfc 3202 FLAC__uint64 pos = 0; /* only initialized to avoid compiler warning */
dkato 0:ee40da884cfc 3203 FLAC__bool did_a_seek;
dkato 0:ee40da884cfc 3204 unsigned iteration = 0;
dkato 0:ee40da884cfc 3205
dkato 0:ee40da884cfc 3206 /* In the first iterations, we will calculate the target byte position
dkato 0:ee40da884cfc 3207 * by the distance from the target sample to left_sample and
dkato 0:ee40da884cfc 3208 * right_sample (let's call it "proportional search"). After that, we
dkato 0:ee40da884cfc 3209 * will switch to binary search.
dkato 0:ee40da884cfc 3210 */
dkato 0:ee40da884cfc 3211 unsigned BINARY_SEARCH_AFTER_ITERATION = 2;
dkato 0:ee40da884cfc 3212
dkato 0:ee40da884cfc 3213 /* We will switch to a linear search once our current sample is less
dkato 0:ee40da884cfc 3214 * than this number of samples ahead of the target sample
dkato 0:ee40da884cfc 3215 */
dkato 0:ee40da884cfc 3216 static const FLAC__uint64 LINEAR_SEARCH_WITHIN_SAMPLES = FLAC__MAX_BLOCK_SIZE * 2;
dkato 0:ee40da884cfc 3217
dkato 0:ee40da884cfc 3218 /* If the total number of samples is unknown, use a large value, and
dkato 0:ee40da884cfc 3219 * force binary search immediately.
dkato 0:ee40da884cfc 3220 */
dkato 0:ee40da884cfc 3221 if(right_sample == 0) {
dkato 0:ee40da884cfc 3222 right_sample = (FLAC__uint64)(-1);
dkato 0:ee40da884cfc 3223 BINARY_SEARCH_AFTER_ITERATION = 0;
dkato 0:ee40da884cfc 3224 }
dkato 0:ee40da884cfc 3225
dkato 0:ee40da884cfc 3226 decoder->private_->target_sample = target_sample;
dkato 0:ee40da884cfc 3227 for( ; ; iteration++) {
dkato 0:ee40da884cfc 3228 if (iteration == 0 || this_frame_sample > target_sample || target_sample - this_frame_sample > LINEAR_SEARCH_WITHIN_SAMPLES) {
dkato 0:ee40da884cfc 3229 if (iteration >= BINARY_SEARCH_AFTER_ITERATION) {
dkato 0:ee40da884cfc 3230 pos = (right_pos + left_pos) / 2;
dkato 0:ee40da884cfc 3231 }
dkato 0:ee40da884cfc 3232 else {
dkato 0:ee40da884cfc 3233 #ifndef FLAC__INTEGER_ONLY_LIBRARY
dkato 0:ee40da884cfc 3234 pos = (FLAC__uint64)((FLAC__double)(target_sample - left_sample) / (FLAC__double)(right_sample - left_sample) * (FLAC__double)(right_pos - left_pos));
dkato 0:ee40da884cfc 3235 #else
dkato 0:ee40da884cfc 3236 /* a little less accurate: */
dkato 0:ee40da884cfc 3237 if ((target_sample-left_sample <= 0xffffffff) && (right_pos-left_pos <= 0xffffffff))
dkato 0:ee40da884cfc 3238 pos = (FLAC__int64)(((target_sample-left_sample) * (right_pos-left_pos)) / (right_sample-left_sample));
dkato 0:ee40da884cfc 3239 else /* @@@ WATCHOUT, ~2TB limit */
dkato 0:ee40da884cfc 3240 pos = (FLAC__int64)((((target_sample-left_sample)>>8) * ((right_pos-left_pos)>>8)) / ((right_sample-left_sample)>>16));
dkato 0:ee40da884cfc 3241 #endif
dkato 0:ee40da884cfc 3242 /* @@@ TODO: might want to limit pos to some distance
dkato 0:ee40da884cfc 3243 * before EOF, to make sure we land before the last frame,
dkato 0:ee40da884cfc 3244 * thereby getting a this_frame_sample and so having a better
dkato 0:ee40da884cfc 3245 * estimate.
dkato 0:ee40da884cfc 3246 */
dkato 0:ee40da884cfc 3247 }
dkato 0:ee40da884cfc 3248
dkato 0:ee40da884cfc 3249 /* physical seek */
dkato 0:ee40da884cfc 3250 if(decoder->private_->seek_callback((FLAC__StreamDecoder*)decoder, (FLAC__uint64)pos, decoder->private_->client_data) != FLAC__STREAM_DECODER_SEEK_STATUS_OK) {
dkato 0:ee40da884cfc 3251 decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
dkato 0:ee40da884cfc 3252 return false;
dkato 0:ee40da884cfc 3253 }
dkato 0:ee40da884cfc 3254 if(!FLAC__stream_decoder_flush(decoder)) {
dkato 0:ee40da884cfc 3255 /* above call sets the state for us */
dkato 0:ee40da884cfc 3256 return false;
dkato 0:ee40da884cfc 3257 }
dkato 0:ee40da884cfc 3258 did_a_seek = true;
dkato 0:ee40da884cfc 3259 }
dkato 0:ee40da884cfc 3260 else
dkato 0:ee40da884cfc 3261 did_a_seek = false;
dkato 0:ee40da884cfc 3262
dkato 0:ee40da884cfc 3263 decoder->private_->got_a_frame = false;
dkato 0:ee40da884cfc 3264 if(!FLAC__stream_decoder_process_single(decoder)) {
dkato 0:ee40da884cfc 3265 decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
dkato 0:ee40da884cfc 3266 return false;
dkato 0:ee40da884cfc 3267 }
dkato 0:ee40da884cfc 3268 if(!decoder->private_->got_a_frame) {
dkato 0:ee40da884cfc 3269 if(did_a_seek) {
dkato 0:ee40da884cfc 3270 /* this can happen if we seek to a point after the last frame; we drop
dkato 0:ee40da884cfc 3271 * to binary search right away in this case to avoid any wasted
dkato 0:ee40da884cfc 3272 * iterations of proportional search.
dkato 0:ee40da884cfc 3273 */
dkato 0:ee40da884cfc 3274 right_pos = pos;
dkato 0:ee40da884cfc 3275 BINARY_SEARCH_AFTER_ITERATION = 0;
dkato 0:ee40da884cfc 3276 }
dkato 0:ee40da884cfc 3277 else {
dkato 0:ee40da884cfc 3278 /* this can probably only happen if total_samples is unknown and the
dkato 0:ee40da884cfc 3279 * target_sample is past the end of the stream
dkato 0:ee40da884cfc 3280 */
dkato 0:ee40da884cfc 3281 decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
dkato 0:ee40da884cfc 3282 return false;
dkato 0:ee40da884cfc 3283 }
dkato 0:ee40da884cfc 3284 }
dkato 0:ee40da884cfc 3285 /* our write callback will change the state when it gets to the target frame */
dkato 0:ee40da884cfc 3286 else if(!decoder->private_->is_seeking) {
dkato 0:ee40da884cfc 3287 break;
dkato 0:ee40da884cfc 3288 }
dkato 0:ee40da884cfc 3289 else {
dkato 0:ee40da884cfc 3290 this_frame_sample = decoder->private_->last_frame.header.number.sample_number;
dkato 0:ee40da884cfc 3291 FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
dkato 0:ee40da884cfc 3292
dkato 0:ee40da884cfc 3293 if (did_a_seek) {
dkato 0:ee40da884cfc 3294 if (this_frame_sample <= target_sample) {
dkato 0:ee40da884cfc 3295 /* The 'equal' case should not happen, since
dkato 0:ee40da884cfc 3296 * FLAC__stream_decoder_process_single()
dkato 0:ee40da884cfc 3297 * should recognize that it has hit the
dkato 0:ee40da884cfc 3298 * target sample and we would exit through
dkato 0:ee40da884cfc 3299 * the 'break' above.
dkato 0:ee40da884cfc 3300 */
dkato 0:ee40da884cfc 3301 FLAC__ASSERT(this_frame_sample != target_sample);
dkato 0:ee40da884cfc 3302
dkato 0:ee40da884cfc 3303 left_sample = this_frame_sample;
dkato 0:ee40da884cfc 3304 /* sanity check to avoid infinite loop */
dkato 0:ee40da884cfc 3305 if (left_pos == pos) {
dkato 0:ee40da884cfc 3306 decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
dkato 0:ee40da884cfc 3307 return false;
dkato 0:ee40da884cfc 3308 }
dkato 0:ee40da884cfc 3309 left_pos = pos;
dkato 0:ee40da884cfc 3310 }
dkato 0:ee40da884cfc 3311 else if(this_frame_sample > target_sample) {
dkato 0:ee40da884cfc 3312 right_sample = this_frame_sample;
dkato 0:ee40da884cfc 3313 /* sanity check to avoid infinite loop */
dkato 0:ee40da884cfc 3314 if (right_pos == pos) {
dkato 0:ee40da884cfc 3315 decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
dkato 0:ee40da884cfc 3316 return false;
dkato 0:ee40da884cfc 3317 }
dkato 0:ee40da884cfc 3318 right_pos = pos;
dkato 0:ee40da884cfc 3319 }
dkato 0:ee40da884cfc 3320 }
dkato 0:ee40da884cfc 3321 }
dkato 0:ee40da884cfc 3322 }
dkato 0:ee40da884cfc 3323
dkato 0:ee40da884cfc 3324 return true;
dkato 0:ee40da884cfc 3325 }
dkato 0:ee40da884cfc 3326 #endif
dkato 0:ee40da884cfc 3327
dkato 0:ee40da884cfc 3328 FLAC__StreamDecoderReadStatus file_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
dkato 0:ee40da884cfc 3329 {
dkato 0:ee40da884cfc 3330 (void)client_data;
dkato 0:ee40da884cfc 3331
dkato 0:ee40da884cfc 3332 if(*bytes > 0) {
dkato 0:ee40da884cfc 3333 *bytes = fread(buffer, sizeof(FLAC__byte), *bytes, decoder->private_->file);
dkato 0:ee40da884cfc 3334 if(ferror(decoder->private_->file))
dkato 0:ee40da884cfc 3335 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
dkato 0:ee40da884cfc 3336 else if(*bytes == 0)
dkato 0:ee40da884cfc 3337 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
dkato 0:ee40da884cfc 3338 else
dkato 0:ee40da884cfc 3339 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
dkato 0:ee40da884cfc 3340 }
dkato 0:ee40da884cfc 3341 else
dkato 0:ee40da884cfc 3342 return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */
dkato 0:ee40da884cfc 3343 }
dkato 0:ee40da884cfc 3344
dkato 0:ee40da884cfc 3345 FLAC__StreamDecoderSeekStatus file_seek_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
dkato 0:ee40da884cfc 3346 {
dkato 0:ee40da884cfc 3347 #if(1) /* mbed */
dkato 0:ee40da884cfc 3348 return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED;
dkato 0:ee40da884cfc 3349 #else /* not mbed */
dkato 0:ee40da884cfc 3350 (void)client_data;
dkato 0:ee40da884cfc 3351
dkato 0:ee40da884cfc 3352 if(decoder->private_->file == stdin)
dkato 0:ee40da884cfc 3353 return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED;
dkato 0:ee40da884cfc 3354 else if(fseeko(decoder->private_->file, (FLAC__off_t)absolute_byte_offset, SEEK_SET) < 0)
dkato 0:ee40da884cfc 3355 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
dkato 0:ee40da884cfc 3356 else
dkato 0:ee40da884cfc 3357 return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
dkato 0:ee40da884cfc 3358 #endif /* end mbed */
dkato 0:ee40da884cfc 3359 }
dkato 0:ee40da884cfc 3360
dkato 0:ee40da884cfc 3361 FLAC__StreamDecoderTellStatus file_tell_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
dkato 0:ee40da884cfc 3362 {
dkato 0:ee40da884cfc 3363 #if(1) /* mbed */
dkato 0:ee40da884cfc 3364 return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED;
dkato 0:ee40da884cfc 3365 #else /* not mbed */
dkato 0:ee40da884cfc 3366 FLAC__off_t pos;
dkato 0:ee40da884cfc 3367 (void)client_data;
dkato 0:ee40da884cfc 3368
dkato 0:ee40da884cfc 3369 if(decoder->private_->file == stdin)
dkato 0:ee40da884cfc 3370 return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED;
dkato 0:ee40da884cfc 3371 else if((pos = ftello(decoder->private_->file)) < 0)
dkato 0:ee40da884cfc 3372 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
dkato 0:ee40da884cfc 3373 else {
dkato 0:ee40da884cfc 3374 *absolute_byte_offset = (FLAC__uint64)pos;
dkato 0:ee40da884cfc 3375 return FLAC__STREAM_DECODER_TELL_STATUS_OK;
dkato 0:ee40da884cfc 3376 }
dkato 0:ee40da884cfc 3377 #endif /* end mbed */
dkato 0:ee40da884cfc 3378 }
dkato 0:ee40da884cfc 3379
dkato 0:ee40da884cfc 3380 FLAC__StreamDecoderLengthStatus file_length_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
dkato 0:ee40da884cfc 3381 {
dkato 0:ee40da884cfc 3382 #if(1) /* mbed */
dkato 0:ee40da884cfc 3383 return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
dkato 0:ee40da884cfc 3384 #else /* not mbed */
dkato 0:ee40da884cfc 3385 struct flac_stat_s filestats;
dkato 0:ee40da884cfc 3386 (void)client_data;
dkato 0:ee40da884cfc 3387
dkato 0:ee40da884cfc 3388 if(decoder->private_->file == stdin)
dkato 0:ee40da884cfc 3389 return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
dkato 0:ee40da884cfc 3390 else if(flac_fstat(fileno(decoder->private_->file), &filestats) != 0)
dkato 0:ee40da884cfc 3391 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
dkato 0:ee40da884cfc 3392 else {
dkato 0:ee40da884cfc 3393 *stream_length = (FLAC__uint64)filestats.st_size;
dkato 0:ee40da884cfc 3394 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
dkato 0:ee40da884cfc 3395 }
dkato 0:ee40da884cfc 3396 #endif /* end mbed */
dkato 0:ee40da884cfc 3397 }
dkato 0:ee40da884cfc 3398
dkato 0:ee40da884cfc 3399 FLAC__bool file_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_data)
dkato 0:ee40da884cfc 3400 {
dkato 0:ee40da884cfc 3401 (void)client_data;
dkato 0:ee40da884cfc 3402
dkato 0:ee40da884cfc 3403 return feof(decoder->private_->file)? true : false;
dkato 0:ee40da884cfc 3404 }