blob: 53520667f85996eb39301824c0ff0074ec0d95b5 [file] [log] [blame]
Josh Coalson26560dd2001-02-08 00:38:41 +00001/* libFLAC - Free Lossless Audio Codec library
Josh Coalson305ae2e2002-01-26 17:36:39 +00002 * Copyright (C) 2000,2001,2002 Josh Coalson
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00003 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
Josh Coalsonbb7f6b92000-12-10 04:09:52 +000020#include <stdio.h>
21#include <stdlib.h> /* for malloc() */
Josh Coalsonec1af652001-04-01 05:34:16 +000022#include <string.h> /* for memset/memcpy() */
Josh Coalson1b689822001-05-31 20:11:02 +000023#include "FLAC/assert.h"
Josh Coalson0a15c142001-06-13 17:59:57 +000024#include "protected/stream_decoder.h"
Josh Coalsonbb7f6b92000-12-10 04:09:52 +000025#include "private/bitbuffer.h"
Josh Coalsonb985bbc2001-05-23 21:59:52 +000026#include "private/cpu.h"
Josh Coalsonbb7f6b92000-12-10 04:09:52 +000027#include "private/crc.h"
28#include "private/fixed.h"
Josh Coalsonb7023aa2002-08-17 15:23:43 +000029#include "private/format.h"
Josh Coalsonbb7f6b92000-12-10 04:09:52 +000030#include "private/lpc.h"
31
Josh Coalsonb7023aa2002-08-17 15:23:43 +000032#ifdef max
33#undef max
34#endif
35#define max(a,b) ((a)>(b)?(a):(b))
36
Josh Coalson0a15c142001-06-13 17:59:57 +000037/***********************************************************************
38 *
39 * Private static data
40 *
41 ***********************************************************************/
42
Josh Coalson77e3f312001-06-23 03:03:24 +000043static FLAC__byte ID3V2_TAG_[3] = { 'I', 'D', '3' };
Josh Coalson0a15c142001-06-13 17:59:57 +000044
45/***********************************************************************
46 *
47 * Private class method prototypes
48 *
49 ***********************************************************************/
50
Josh Coalson570db862002-07-31 06:58:16 +000051static void set_defaults_(FLAC__StreamDecoder *decoder);
52static FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigned channels);
53static FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id);
54static FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder);
55static FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder);
56static FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder);
57static FLAC__bool frame_sync_(FLAC__StreamDecoder *decoder);
58static FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame);
59static FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder);
60static FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps);
61static FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps);
62static FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order);
63static FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order);
64static FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps);
Josh Coalsona37ba462002-08-19 21:36:39 +000065static FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigned predictor_order, unsigned partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, FLAC__int32 *residual);
Josh Coalson570db862002-07-31 06:58:16 +000066static FLAC__bool read_zero_padding_(FLAC__StreamDecoder *decoder);
Josh Coalson77e3f312001-06-23 03:03:24 +000067static FLAC__bool read_callback_(FLAC__byte buffer[], unsigned *bytes, void *client_data);
Josh Coalson0a15c142001-06-13 17:59:57 +000068
69/***********************************************************************
70 *
71 * Private class data
72 *
73 ***********************************************************************/
74
Josh Coalsonbb7f6b92000-12-10 04:09:52 +000075typedef struct FLAC__StreamDecoderPrivate {
Josh Coalson681c2932002-08-01 08:19:37 +000076 FLAC__StreamDecoderReadCallback read_callback;
77 FLAC__StreamDecoderWriteCallback write_callback;
78 FLAC__StreamDecoderMetadataCallback metadata_callback;
79 FLAC__StreamDecoderErrorCallback error_callback;
Josh Coalson77e3f312001-06-23 03:03:24 +000080 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[]);
Josh Coalsonb6a32192002-10-04 05:27:49 +000081 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[]);
Josh Coalson77e3f312001-06-23 03:03:24 +000082 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[]);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +000083 void *client_data;
Josh Coalsonaec256b2002-03-12 16:19:54 +000084 FLAC__BitBuffer *input;
Josh Coalson77e3f312001-06-23 03:03:24 +000085 FLAC__int32 *output[FLAC__MAX_CHANNELS];
86 FLAC__int32 *residual[FLAC__MAX_CHANNELS];
Josh Coalsona37ba462002-08-19 21:36:39 +000087 FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents[FLAC__MAX_CHANNELS];
Josh Coalson1e1509f2001-03-23 20:20:43 +000088 unsigned output_capacity, output_channels;
Josh Coalson77e3f312001-06-23 03:03:24 +000089 FLAC__uint32 last_frame_number;
90 FLAC__uint64 samples_decoded;
91 FLAC__bool has_stream_info, has_seek_table;
Josh Coalsoncc682512002-06-08 04:53:42 +000092 FLAC__StreamMetadata stream_info;
93 FLAC__StreamMetadata seek_table;
Josh Coalsonbf9325f2002-05-07 05:30:27 +000094 FLAC__bool metadata_filter[FLAC__METADATA_TYPE_VORBIS_COMMENT+1];
95 FLAC__byte *metadata_filter_ids;
96 unsigned metadata_filter_ids_count, metadata_filter_ids_capacity; /* units for both are IDs, not bytes */
Josh Coalson6dcea512001-01-23 23:07:36 +000097 FLAC__Frame frame;
Josh Coalson77e3f312001-06-23 03:03:24 +000098 FLAC__bool cached; /* true if there is a byte in lookahead */
Josh Coalsonb985bbc2001-05-23 21:59:52 +000099 FLAC__CPUInfo cpuinfo;
Josh Coalson77e3f312001-06-23 03:03:24 +0000100 FLAC__byte header_warmup[2]; /* contains the sync code and reserved bits */
101 FLAC__byte lookahead; /* temp storage when we need to look ahead one byte in the stream */
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000102} FLAC__StreamDecoderPrivate;
103
Josh Coalson0a15c142001-06-13 17:59:57 +0000104/***********************************************************************
105 *
106 * Public static class data
107 *
108 ***********************************************************************/
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000109
Josh Coalson6afed9f2002-10-16 22:29:47 +0000110FLAC_API const char * const FLAC__StreamDecoderStateString[] = {
Josh Coalsoncbf595f2000-12-22 22:35:33 +0000111 "FLAC__STREAM_DECODER_SEARCH_FOR_METADATA",
112 "FLAC__STREAM_DECODER_READ_METADATA",
113 "FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC",
114 "FLAC__STREAM_DECODER_READ_FRAME",
Josh Coalsoncbf595f2000-12-22 22:35:33 +0000115 "FLAC__STREAM_DECODER_END_OF_STREAM",
116 "FLAC__STREAM_DECODER_ABORTED",
117 "FLAC__STREAM_DECODER_UNPARSEABLE_STREAM",
118 "FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR",
Josh Coalson0a15c142001-06-13 17:59:57 +0000119 "FLAC__STREAM_DECODER_ALREADY_INITIALIZED",
Josh Coalson00e53872001-06-16 07:32:25 +0000120 "FLAC__STREAM_DECODER_INVALID_CALLBACK",
Josh Coalsoncbf595f2000-12-22 22:35:33 +0000121 "FLAC__STREAM_DECODER_UNINITIALIZED"
122};
123
Josh Coalson6afed9f2002-10-16 22:29:47 +0000124FLAC_API const char * const FLAC__StreamDecoderReadStatusString[] = {
Josh Coalson090f8f72002-06-04 05:53:04 +0000125 "FLAC__STREAM_DECODER_READ_STATUS_CONTINUE",
126 "FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM",
127 "FLAC__STREAM_DECODER_READ_STATUS_ABORT"
Josh Coalsoncbf595f2000-12-22 22:35:33 +0000128};
129
Josh Coalson6afed9f2002-10-16 22:29:47 +0000130FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[] = {
Josh Coalson090f8f72002-06-04 05:53:04 +0000131 "FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE",
132 "FLAC__STREAM_DECODER_WRITE_STATUS_ABORT"
Josh Coalsoncbf595f2000-12-22 22:35:33 +0000133};
134
Josh Coalson6afed9f2002-10-16 22:29:47 +0000135FLAC_API const char * const FLAC__StreamDecoderErrorStatusString[] = {
Josh Coalson090f8f72002-06-04 05:53:04 +0000136 "FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC",
137 "FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER",
138 "FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH"
Josh Coalsoncbf595f2000-12-22 22:35:33 +0000139};
140
Josh Coalson0a15c142001-06-13 17:59:57 +0000141/***********************************************************************
142 *
143 * Class constructor/destructor
144 *
145 ***********************************************************************/
Josh Coalson6afed9f2002-10-16 22:29:47 +0000146FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new()
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000147{
Josh Coalson0a15c142001-06-13 17:59:57 +0000148 FLAC__StreamDecoder *decoder;
Josh Coalsonbc869502002-06-14 06:36:16 +0000149 unsigned i;
Josh Coalson0a15c142001-06-13 17:59:57 +0000150
151 FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
152
Josh Coalsonea7155f2002-10-18 05:49:19 +0000153 decoder = (FLAC__StreamDecoder*)calloc(1, sizeof(FLAC__StreamDecoder));
Josh Coalson0a15c142001-06-13 17:59:57 +0000154 if(decoder == 0) {
155 return 0;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000156 }
Josh Coalsona7e4fb22002-08-03 22:05:11 +0000157
Josh Coalsonea7155f2002-10-18 05:49:19 +0000158 decoder->protected_ = (FLAC__StreamDecoderProtected*)calloc(1, sizeof(FLAC__StreamDecoderProtected));
Josh Coalsonfa697a92001-08-16 20:07:29 +0000159 if(decoder->protected_ == 0) {
Josh Coalson0a15c142001-06-13 17:59:57 +0000160 free(decoder);
161 return 0;
162 }
Josh Coalsona7e4fb22002-08-03 22:05:11 +0000163
Josh Coalsonea7155f2002-10-18 05:49:19 +0000164 decoder->private_ = (FLAC__StreamDecoderPrivate*)calloc(1, sizeof(FLAC__StreamDecoderPrivate));
Josh Coalsonfa697a92001-08-16 20:07:29 +0000165 if(decoder->private_ == 0) {
166 free(decoder->protected_);
Josh Coalson0a15c142001-06-13 17:59:57 +0000167 free(decoder);
168 return 0;
169 }
Josh Coalsona7e4fb22002-08-03 22:05:11 +0000170
Josh Coalsonaec256b2002-03-12 16:19:54 +0000171 decoder->private_->input = FLAC__bitbuffer_new();
172 if(decoder->private_->input == 0) {
173 free(decoder->private_);
174 free(decoder->protected_);
175 free(decoder);
176 return 0;
177 }
Josh Coalson0a15c142001-06-13 17:59:57 +0000178
Josh Coalson6b02a752002-05-10 06:42:02 +0000179 decoder->private_->metadata_filter_ids_capacity = 16;
180 if(0 == (decoder->private_->metadata_filter_ids = malloc((FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) * decoder->private_->metadata_filter_ids_capacity))) {
181 FLAC__bitbuffer_delete(decoder->private_->input);
182 free(decoder->private_);
183 free(decoder->protected_);
184 free(decoder);
185 return 0;
186 }
Josh Coalson090f8f72002-06-04 05:53:04 +0000187
Josh Coalsonbc869502002-06-14 06:36:16 +0000188 for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
189 decoder->private_->output[i] = 0;
190 decoder->private_->residual[i] = 0;
191 }
192
193 decoder->private_->output_capacity = 0;
194 decoder->private_->output_channels = 0;
195 decoder->private_->has_seek_table = false;
Josh Coalsona37ba462002-08-19 21:36:39 +0000196
197 for(i = 0; i < FLAC__MAX_CHANNELS; i++)
198 FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&decoder->private_->partitioned_rice_contents[i]);
Josh Coalsonbc869502002-06-14 06:36:16 +0000199
Josh Coalson570db862002-07-31 06:58:16 +0000200 set_defaults_(decoder);
Josh Coalson6b02a752002-05-10 06:42:02 +0000201
Josh Coalsonbc869502002-06-14 06:36:16 +0000202 decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED;
203
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000204 return decoder;
205}
206
Josh Coalson6afed9f2002-10-16 22:29:47 +0000207FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000208{
Josh Coalsona37ba462002-08-19 21:36:39 +0000209 unsigned i;
210
Josh Coalson570db862002-07-31 06:58:16 +0000211 FLAC__ASSERT(0 != decoder);
212 FLAC__ASSERT(0 != decoder->protected_);
213 FLAC__ASSERT(0 != decoder->private_);
214 FLAC__ASSERT(0 != decoder->private_->input);
Josh Coalson0a15c142001-06-13 17:59:57 +0000215
Josh Coalsonbc869502002-06-14 06:36:16 +0000216 FLAC__stream_decoder_finish(decoder);
217
Josh Coalson570db862002-07-31 06:58:16 +0000218 if(0 != decoder->private_->metadata_filter_ids)
Josh Coalson090f8f72002-06-04 05:53:04 +0000219 free(decoder->private_->metadata_filter_ids);
220
Josh Coalsonaec256b2002-03-12 16:19:54 +0000221 FLAC__bitbuffer_delete(decoder->private_->input);
Josh Coalsonb7023aa2002-08-17 15:23:43 +0000222
Josh Coalsona37ba462002-08-19 21:36:39 +0000223 for(i = 0; i < FLAC__MAX_CHANNELS; i++)
224 FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&decoder->private_->partitioned_rice_contents[i]);
Josh Coalsonb7023aa2002-08-17 15:23:43 +0000225
Josh Coalsonfa697a92001-08-16 20:07:29 +0000226 free(decoder->private_);
227 free(decoder->protected_);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000228 free(decoder);
229}
230
Josh Coalson0a15c142001-06-13 17:59:57 +0000231/***********************************************************************
232 *
233 * Public class methods
234 *
235 ***********************************************************************/
236
Josh Coalson6afed9f2002-10-16 22:29:47 +0000237FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_init(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000238{
Josh Coalson570db862002-07-31 06:58:16 +0000239 FLAC__ASSERT(0 != decoder);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000240
Josh Coalsonfa697a92001-08-16 20:07:29 +0000241 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
242 return decoder->protected_->state = FLAC__STREAM_DECODER_ALREADY_INITIALIZED;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000243
Josh Coalsonfa697a92001-08-16 20:07:29 +0000244 if(0 == decoder->private_->read_callback || 0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
245 return decoder->protected_->state = FLAC__STREAM_DECODER_INVALID_CALLBACK;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000246
Josh Coalsonaec256b2002-03-12 16:19:54 +0000247 if(!FLAC__bitbuffer_init(decoder->private_->input))
248 return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000249
Josh Coalsonfa697a92001-08-16 20:07:29 +0000250 decoder->private_->last_frame_number = 0;
251 decoder->private_->samples_decoded = 0;
252 decoder->private_->has_stream_info = false;
Josh Coalsonfa697a92001-08-16 20:07:29 +0000253 decoder->private_->cached = false;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000254
Josh Coalsonb985bbc2001-05-23 21:59:52 +0000255 /*
256 * get the CPU info and set the function pointers
257 */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000258 FLAC__cpu_info(&decoder->private_->cpuinfo);
Josh Coalsonb985bbc2001-05-23 21:59:52 +0000259 /* first default to the non-asm routines */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000260 decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal;
Josh Coalsonb6a32192002-10-04 05:27:49 +0000261 decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide;
Josh Coalsonfa697a92001-08-16 20:07:29 +0000262 decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal;
Josh Coalsonb985bbc2001-05-23 21:59:52 +0000263 /* now override with asm where appropriate */
Josh Coalsona3f7c2c2001-05-25 00:04:45 +0000264#ifndef FLAC__NO_ASM
Josh Coalsonfa697a92001-08-16 20:07:29 +0000265 if(decoder->private_->cpuinfo.use_asm) {
Josh Coalsonb985bbc2001-05-23 21:59:52 +0000266#ifdef FLAC__CPU_IA32
Josh Coalsonfa697a92001-08-16 20:07:29 +0000267 FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32);
Josh Coalson034d38e2001-05-24 19:29:30 +0000268#ifdef FLAC__HAS_NASM
Josh Coalsonfa697a92001-08-16 20:07:29 +0000269 if(decoder->private_->cpuinfo.data.ia32.mmx) {
270 decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32;
271 decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32_mmx;
Josh Coalson021ad3b2001-07-18 00:25:52 +0000272 }
273 else {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000274 decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32;
275 decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32;
Josh Coalson021ad3b2001-07-18 00:25:52 +0000276 }
Josh Coalsonb985bbc2001-05-23 21:59:52 +0000277#endif
Josh Coalson034d38e2001-05-24 19:29:30 +0000278#endif
Josh Coalson021ad3b2001-07-18 00:25:52 +0000279 }
Josh Coalsona3f7c2c2001-05-25 00:04:45 +0000280#endif
Josh Coalsonb985bbc2001-05-23 21:59:52 +0000281
Josh Coalsoncfdfc822002-08-02 06:12:36 +0000282 if(!FLAC__stream_decoder_reset(decoder))
283 return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
284
285 return decoder->protected_->state;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000286}
287
Josh Coalson6afed9f2002-10-16 22:29:47 +0000288FLAC_API void FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000289{
290 unsigned i;
Josh Coalson570db862002-07-31 06:58:16 +0000291 FLAC__ASSERT(0 != decoder);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000292 if(decoder->protected_->state == FLAC__STREAM_DECODER_UNINITIALIZED)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000293 return;
Josh Coalsonfa697a92001-08-16 20:07:29 +0000294 if(decoder->private_->has_seek_table) {
Josh Coalson570db862002-07-31 06:58:16 +0000295 FLAC__ASSERT(0 != decoder->private_->seek_table.data.seek_table.points);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000296 free(decoder->private_->seek_table.data.seek_table.points);
297 decoder->private_->seek_table.data.seek_table.points = 0;
Josh Coalsonbc869502002-06-14 06:36:16 +0000298 decoder->private_->has_seek_table = false;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000299 }
Josh Coalsonaec256b2002-03-12 16:19:54 +0000300 FLAC__bitbuffer_free(decoder->private_->input);
Josh Coalson0a15c142001-06-13 17:59:57 +0000301 for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
Josh Coalsonb7023aa2002-08-17 15:23:43 +0000302 /* WATCHOUT:
303 * FLAC__lpc_restore_signal_asm_ia32_mmx() requires that the
304 * output arrays have a buffer of up to 3 zeroes in front
305 * (at negative indices) for alignment purposes; we use 4
306 * to keep the data well-aligned.
307 */
Josh Coalson570db862002-07-31 06:58:16 +0000308 if(0 != decoder->private_->output[i]) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000309 free(decoder->private_->output[i]-4);
310 decoder->private_->output[i] = 0;
Josh Coalson0a15c142001-06-13 17:59:57 +0000311 }
Josh Coalson570db862002-07-31 06:58:16 +0000312 if(0 != decoder->private_->residual[i]) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000313 free(decoder->private_->residual[i]);
314 decoder->private_->residual[i] = 0;
Josh Coalson0a15c142001-06-13 17:59:57 +0000315 }
316 }
Josh Coalsonfa697a92001-08-16 20:07:29 +0000317 decoder->private_->output_capacity = 0;
318 decoder->private_->output_channels = 0;
Josh Coalson090f8f72002-06-04 05:53:04 +0000319
Josh Coalson570db862002-07-31 06:58:16 +0000320 set_defaults_(decoder);
Josh Coalson090f8f72002-06-04 05:53:04 +0000321
Josh Coalsonfa697a92001-08-16 20:07:29 +0000322 decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED;
Josh Coalson0a15c142001-06-13 17:59:57 +0000323}
324
Josh Coalson6afed9f2002-10-16 22:29:47 +0000325FLAC_API FLAC__bool FLAC__stream_decoder_set_read_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderReadCallback value)
Josh Coalson00e53872001-06-16 07:32:25 +0000326{
Josh Coalson570db862002-07-31 06:58:16 +0000327 FLAC__ASSERT(0 != decoder);
328 FLAC__ASSERT(0 != decoder->private_);
329 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000330 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
Josh Coalson00e53872001-06-16 07:32:25 +0000331 return false;
Josh Coalsonfa697a92001-08-16 20:07:29 +0000332 decoder->private_->read_callback = value;
Josh Coalson00e53872001-06-16 07:32:25 +0000333 return true;
334}
335
Josh Coalson6afed9f2002-10-16 22:29:47 +0000336FLAC_API FLAC__bool FLAC__stream_decoder_set_write_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderWriteCallback value)
Josh Coalson00e53872001-06-16 07:32:25 +0000337{
Josh Coalson570db862002-07-31 06:58:16 +0000338 FLAC__ASSERT(0 != decoder);
339 FLAC__ASSERT(0 != decoder->private_);
340 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000341 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
Josh Coalson00e53872001-06-16 07:32:25 +0000342 return false;
Josh Coalsonfa697a92001-08-16 20:07:29 +0000343 decoder->private_->write_callback = value;
Josh Coalson00e53872001-06-16 07:32:25 +0000344 return true;
345}
346
Josh Coalson6afed9f2002-10-16 22:29:47 +0000347FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderMetadataCallback value)
Josh Coalson00e53872001-06-16 07:32:25 +0000348{
Josh Coalson570db862002-07-31 06:58:16 +0000349 FLAC__ASSERT(0 != decoder);
350 FLAC__ASSERT(0 != decoder->private_);
351 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000352 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
Josh Coalson00e53872001-06-16 07:32:25 +0000353 return false;
Josh Coalsonfa697a92001-08-16 20:07:29 +0000354 decoder->private_->metadata_callback = value;
Josh Coalson00e53872001-06-16 07:32:25 +0000355 return true;
356}
357
Josh Coalson6afed9f2002-10-16 22:29:47 +0000358FLAC_API FLAC__bool FLAC__stream_decoder_set_error_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorCallback value)
Josh Coalson00e53872001-06-16 07:32:25 +0000359{
Josh Coalson570db862002-07-31 06:58:16 +0000360 FLAC__ASSERT(0 != decoder);
361 FLAC__ASSERT(0 != decoder->private_);
362 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000363 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
Josh Coalson00e53872001-06-16 07:32:25 +0000364 return false;
Josh Coalsonfa697a92001-08-16 20:07:29 +0000365 decoder->private_->error_callback = value;
Josh Coalson00e53872001-06-16 07:32:25 +0000366 return true;
367}
368
Josh Coalson6afed9f2002-10-16 22:29:47 +0000369FLAC_API FLAC__bool FLAC__stream_decoder_set_client_data(FLAC__StreamDecoder *decoder, void *value)
Josh Coalson00e53872001-06-16 07:32:25 +0000370{
Josh Coalson570db862002-07-31 06:58:16 +0000371 FLAC__ASSERT(0 != decoder);
372 FLAC__ASSERT(0 != decoder->private_);
373 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000374 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
Josh Coalson00e53872001-06-16 07:32:25 +0000375 return false;
Josh Coalsonfa697a92001-08-16 20:07:29 +0000376 decoder->private_->client_data = value;
Josh Coalson00e53872001-06-16 07:32:25 +0000377 return true;
378}
379
Josh Coalson6afed9f2002-10-16 22:29:47 +0000380FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond(FLAC__StreamDecoder *decoder, FLAC__MetadataType type)
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000381{
Josh Coalson570db862002-07-31 06:58:16 +0000382 FLAC__ASSERT(0 != decoder);
383 FLAC__ASSERT(0 != decoder->private_);
384 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000385 FLAC__ASSERT(type <= FLAC__METADATA_TYPE_VORBIS_COMMENT);
386 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
387 return false;
388 decoder->private_->metadata_filter[type] = true;
389 if(type == FLAC__METADATA_TYPE_APPLICATION)
390 decoder->private_->metadata_filter_ids_count = 0;
391 return true;
392}
393
Josh Coalson6afed9f2002-10-16 22:29:47 +0000394FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4])
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000395{
Josh Coalson570db862002-07-31 06:58:16 +0000396 FLAC__ASSERT(0 != decoder);
397 FLAC__ASSERT(0 != decoder->private_);
398 FLAC__ASSERT(0 != decoder->protected_);
399 FLAC__ASSERT(0 != id);
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000400 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
401 return false;
402
403 if(decoder->private_->metadata_filter[FLAC__METADATA_TYPE_APPLICATION])
404 return true;
405
406 FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids);
407
408 if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) {
409 if(0 == (decoder->private_->metadata_filter_ids = realloc(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity * 2)))
410 return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
411 decoder->private_->metadata_filter_ids_capacity *= 2;
412 }
413
414 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));
415 decoder->private_->metadata_filter_ids_count++;
416
417 return true;
418}
419
Josh Coalson6afed9f2002-10-16 22:29:47 +0000420FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_all(FLAC__StreamDecoder *decoder)
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000421{
Josh Coalson090f8f72002-06-04 05:53:04 +0000422 unsigned i;
Josh Coalson570db862002-07-31 06:58:16 +0000423 FLAC__ASSERT(0 != decoder);
424 FLAC__ASSERT(0 != decoder->private_);
425 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000426 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
427 return false;
Josh Coalson090f8f72002-06-04 05:53:04 +0000428 for(i = 0; i < sizeof(decoder->private_->metadata_filter) / sizeof(decoder->private_->metadata_filter[0]); i++)
429 decoder->private_->metadata_filter[i] = true;
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000430 decoder->private_->metadata_filter_ids_count = 0;
431 return true;
432}
433
Josh Coalson6afed9f2002-10-16 22:29:47 +0000434FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore(FLAC__StreamDecoder *decoder, FLAC__MetadataType type)
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000435{
Josh Coalson570db862002-07-31 06:58:16 +0000436 FLAC__ASSERT(0 != decoder);
437 FLAC__ASSERT(0 != decoder->private_);
438 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000439 FLAC__ASSERT(type <= FLAC__METADATA_TYPE_VORBIS_COMMENT);
440 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
441 return false;
442 decoder->private_->metadata_filter[type] = false;
443 if(type == FLAC__METADATA_TYPE_APPLICATION)
444 decoder->private_->metadata_filter_ids_count = 0;
445 return true;
446}
447
Josh Coalson6afed9f2002-10-16 22:29:47 +0000448FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4])
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000449{
Josh Coalson570db862002-07-31 06:58:16 +0000450 FLAC__ASSERT(0 != decoder);
451 FLAC__ASSERT(0 != decoder->private_);
452 FLAC__ASSERT(0 != decoder->protected_);
453 FLAC__ASSERT(0 != id);
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000454 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
455 return false;
456
457 if(!decoder->private_->metadata_filter[FLAC__METADATA_TYPE_APPLICATION])
458 return true;
459
460 FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids);
461
462 if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) {
463 if(0 == (decoder->private_->metadata_filter_ids = realloc(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity * 2)))
464 return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
465 decoder->private_->metadata_filter_ids_capacity *= 2;
466 }
467
468 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));
469 decoder->private_->metadata_filter_ids_count++;
470
471 return true;
472}
473
Josh Coalson6afed9f2002-10-16 22:29:47 +0000474FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_all(FLAC__StreamDecoder *decoder)
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000475{
Josh Coalson570db862002-07-31 06:58:16 +0000476 FLAC__ASSERT(0 != decoder);
477 FLAC__ASSERT(0 != decoder->private_);
478 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000479 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
480 return false;
481 memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter));
482 decoder->private_->metadata_filter_ids_count = 0;
483 return true;
484}
485
Josh Coalson6afed9f2002-10-16 22:29:47 +0000486FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_get_state(const FLAC__StreamDecoder *decoder)
Josh Coalson0a15c142001-06-13 17:59:57 +0000487{
Josh Coalson570db862002-07-31 06:58:16 +0000488 FLAC__ASSERT(0 != decoder);
489 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000490 return decoder->protected_->state;
Josh Coalson0a15c142001-06-13 17:59:57 +0000491}
492
Josh Coalson6afed9f2002-10-16 22:29:47 +0000493FLAC_API unsigned FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder)
Josh Coalson0a15c142001-06-13 17:59:57 +0000494{
Josh Coalson570db862002-07-31 06:58:16 +0000495 FLAC__ASSERT(0 != decoder);
496 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000497 return decoder->protected_->channels;
Josh Coalson0a15c142001-06-13 17:59:57 +0000498}
499
Josh Coalson6afed9f2002-10-16 22:29:47 +0000500FLAC_API FLAC__ChannelAssignment FLAC__stream_decoder_get_channel_assignment(const FLAC__StreamDecoder *decoder)
Josh Coalson0a15c142001-06-13 17:59:57 +0000501{
Josh Coalson570db862002-07-31 06:58:16 +0000502 FLAC__ASSERT(0 != decoder);
503 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000504 return decoder->protected_->channel_assignment;
Josh Coalson0a15c142001-06-13 17:59:57 +0000505}
506
Josh Coalson6afed9f2002-10-16 22:29:47 +0000507FLAC_API unsigned FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder)
Josh Coalson0a15c142001-06-13 17:59:57 +0000508{
Josh Coalson570db862002-07-31 06:58:16 +0000509 FLAC__ASSERT(0 != decoder);
510 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000511 return decoder->protected_->bits_per_sample;
Josh Coalson0a15c142001-06-13 17:59:57 +0000512}
513
Josh Coalson6afed9f2002-10-16 22:29:47 +0000514FLAC_API unsigned FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder)
Josh Coalson0a15c142001-06-13 17:59:57 +0000515{
Josh Coalson570db862002-07-31 06:58:16 +0000516 FLAC__ASSERT(0 != decoder);
517 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000518 return decoder->protected_->sample_rate;
Josh Coalson0a15c142001-06-13 17:59:57 +0000519}
520
Josh Coalson6afed9f2002-10-16 22:29:47 +0000521FLAC_API unsigned FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder *decoder)
Josh Coalson0a15c142001-06-13 17:59:57 +0000522{
Josh Coalson570db862002-07-31 06:58:16 +0000523 FLAC__ASSERT(0 != decoder);
524 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000525 return decoder->protected_->blocksize;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000526}
527
Josh Coalson6afed9f2002-10-16 22:29:47 +0000528FLAC_API FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000529{
Josh Coalson570db862002-07-31 06:58:16 +0000530 FLAC__ASSERT(0 != decoder);
531 FLAC__ASSERT(0 != decoder->private_);
532 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000533
Josh Coalsonaec256b2002-03-12 16:19:54 +0000534 if(!FLAC__bitbuffer_clear(decoder->private_->input)) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000535 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000536 return false;
537 }
Josh Coalsonb312f282001-11-01 05:23:48 +0000538 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000539
540 return true;
541}
542
Josh Coalson6afed9f2002-10-16 22:29:47 +0000543FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000544{
Josh Coalson570db862002-07-31 06:58:16 +0000545 FLAC__ASSERT(0 != decoder);
546 FLAC__ASSERT(0 != decoder->private_);
547 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000548
549 if(!FLAC__stream_decoder_flush(decoder)) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000550 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000551 return false;
552 }
Josh Coalsonfa697a92001-08-16 20:07:29 +0000553 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_METADATA;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000554
Josh Coalsonfa697a92001-08-16 20:07:29 +0000555 decoder->private_->samples_decoded = 0;
Josh Coalson671fadb2001-04-17 17:32:01 +0000556
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000557 return true;
558}
559
Josh Coalson6afed9f2002-10-16 22:29:47 +0000560FLAC_API FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000561{
Josh Coalson77e3f312001-06-23 03:03:24 +0000562 FLAC__bool got_a_frame;
Josh Coalson570db862002-07-31 06:58:16 +0000563 FLAC__ASSERT(0 != decoder);
Josh Coalsoncfdfc822002-08-02 06:12:36 +0000564 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000565
566 while(1) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000567 switch(decoder->protected_->state) {
Josh Coalsoncfdfc822002-08-02 06:12:36 +0000568 case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
569 if(!find_metadata_(decoder))
570 return false; /* above function sets the status for us */
571 break;
572 case FLAC__STREAM_DECODER_READ_METADATA:
573 if(!read_metadata_(decoder))
574 return false; /* above function sets the status for us */
575 else
576 return true;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000577 case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
Josh Coalson570db862002-07-31 06:58:16 +0000578 if(!frame_sync_(decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000579 return true; /* above function sets the status for us */
580 break;
581 case FLAC__STREAM_DECODER_READ_FRAME:
Josh Coalson570db862002-07-31 06:58:16 +0000582 if(!read_frame_(decoder, &got_a_frame))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000583 return false; /* above function sets the status for us */
584 if(got_a_frame)
585 return true; /* above function sets the status for us */
586 break;
587 case FLAC__STREAM_DECODER_END_OF_STREAM:
Josh Coalson93df7e02002-07-24 06:08:37 +0000588 case FLAC__STREAM_DECODER_ABORTED:
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000589 return true;
590 default:
Josh Coalson1b689822001-05-31 20:11:02 +0000591 FLAC__ASSERT(0);
Josh Coalsoncfdfc822002-08-02 06:12:36 +0000592 return false;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000593 }
594 }
595}
596
Josh Coalson6afed9f2002-10-16 22:29:47 +0000597FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000598{
Josh Coalson570db862002-07-31 06:58:16 +0000599 FLAC__ASSERT(0 != decoder);
Josh Coalsoncfdfc822002-08-02 06:12:36 +0000600 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000601
602 while(1) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000603 switch(decoder->protected_->state) {
Josh Coalsoncfdfc822002-08-02 06:12:36 +0000604 case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
605 if(!find_metadata_(decoder))
606 return false; /* above function sets the status for us */
607 break;
608 case FLAC__STREAM_DECODER_READ_METADATA:
609 if(!read_metadata_(decoder))
610 return false; /* above function sets the status for us */
611 break;
612 case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
613 case FLAC__STREAM_DECODER_READ_FRAME:
614 case FLAC__STREAM_DECODER_END_OF_STREAM:
615 case FLAC__STREAM_DECODER_ABORTED:
616 return true;
617 default:
618 FLAC__ASSERT(0);
619 return false;
620 }
621 }
622}
623
Josh Coalson6afed9f2002-10-16 22:29:47 +0000624FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder)
Josh Coalsoncfdfc822002-08-02 06:12:36 +0000625{
626 FLAC__bool dummy;
627 FLAC__ASSERT(0 != decoder);
628 FLAC__ASSERT(0 != decoder->protected_);
629
630 while(1) {
631 switch(decoder->protected_->state) {
632 case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
633 if(!find_metadata_(decoder))
634 return false; /* above function sets the status for us */
635 break;
636 case FLAC__STREAM_DECODER_READ_METADATA:
637 if(!read_metadata_(decoder))
638 return false; /* above function sets the status for us */
639 break;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000640 case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
Josh Coalson570db862002-07-31 06:58:16 +0000641 if(!frame_sync_(decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000642 return true; /* above function sets the status for us */
643 break;
644 case FLAC__STREAM_DECODER_READ_FRAME:
Josh Coalson570db862002-07-31 06:58:16 +0000645 if(!read_frame_(decoder, &dummy))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000646 return false; /* above function sets the status for us */
647 break;
648 case FLAC__STREAM_DECODER_END_OF_STREAM:
Josh Coalson93df7e02002-07-24 06:08:37 +0000649 case FLAC__STREAM_DECODER_ABORTED:
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000650 return true;
651 default:
Josh Coalson1b689822001-05-31 20:11:02 +0000652 FLAC__ASSERT(0);
Josh Coalsoncfdfc822002-08-02 06:12:36 +0000653 return false;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000654 }
655 }
656}
657
Josh Coalson0a15c142001-06-13 17:59:57 +0000658/***********************************************************************
659 *
660 * Protected class methods
661 *
662 ***********************************************************************/
663
Josh Coalson00e53872001-06-16 07:32:25 +0000664unsigned FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000665{
Josh Coalson570db862002-07-31 06:58:16 +0000666 FLAC__ASSERT(0 != decoder);
Josh Coalsonaec256b2002-03-12 16:19:54 +0000667 return FLAC__bitbuffer_get_input_bytes_unconsumed(decoder->private_->input);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000668}
669
Josh Coalson0a15c142001-06-13 17:59:57 +0000670/***********************************************************************
671 *
672 * Private class methods
673 *
674 ***********************************************************************/
675
Josh Coalson570db862002-07-31 06:58:16 +0000676void set_defaults_(FLAC__StreamDecoder *decoder)
Josh Coalson090f8f72002-06-04 05:53:04 +0000677{
678 decoder->private_->read_callback = 0;
679 decoder->private_->write_callback = 0;
680 decoder->private_->metadata_callback = 0;
681 decoder->private_->error_callback = 0;
682 decoder->private_->client_data = 0;
683
684 memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter));
685 decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO] = true;
686 decoder->private_->metadata_filter_ids_count = 0;
687}
688
Josh Coalson570db862002-07-31 06:58:16 +0000689FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigned channels)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000690{
691 unsigned i;
Josh Coalson77e3f312001-06-23 03:03:24 +0000692 FLAC__int32 *tmp;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000693
Josh Coalsonfa697a92001-08-16 20:07:29 +0000694 if(size <= decoder->private_->output_capacity && channels <= decoder->private_->output_channels)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000695 return true;
696
Josh Coalson5dcb57d2002-09-04 07:59:02 +0000697 /* simply using realloc() is not practical because the number of channels may change mid-stream */
Josh Coalson6dcea512001-01-23 23:07:36 +0000698
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000699 for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
Josh Coalson570db862002-07-31 06:58:16 +0000700 if(0 != decoder->private_->output[i]) {
Josh Coalson2c718a22002-10-21 06:43:48 +0000701 free(decoder->private_->output[i]-4);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000702 decoder->private_->output[i] = 0;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000703 }
Josh Coalson570db862002-07-31 06:58:16 +0000704 if(0 != decoder->private_->residual[i]) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000705 free(decoder->private_->residual[i]);
706 decoder->private_->residual[i] = 0;
Josh Coalson6dcea512001-01-23 23:07:36 +0000707 }
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000708 }
709
Josh Coalson1e1509f2001-03-23 20:20:43 +0000710 for(i = 0; i < channels; i++) {
Josh Coalsonb7023aa2002-08-17 15:23:43 +0000711 /* WATCHOUT:
712 * FLAC__lpc_restore_signal_asm_ia32_mmx() requires that the
713 * output arrays have a buffer of up to 3 zeroes in front
714 * (at negative indices) for alignment purposes; we use 4
715 * to keep the data well-aligned.
716 */
Josh Coalson63d99572001-07-12 21:26:57 +0000717 tmp = (FLAC__int32*)malloc(sizeof(FLAC__int32)*(size+4));
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000718 if(tmp == 0) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000719 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000720 return false;
721 }
Josh Coalson63d99572001-07-12 21:26:57 +0000722 memset(tmp, 0, sizeof(FLAC__int32)*4);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000723 decoder->private_->output[i] = tmp + 4;
Josh Coalson6dcea512001-01-23 23:07:36 +0000724
Josh Coalson77e3f312001-06-23 03:03:24 +0000725 tmp = (FLAC__int32*)malloc(sizeof(FLAC__int32)*size);
Josh Coalson6dcea512001-01-23 23:07:36 +0000726 if(tmp == 0) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000727 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
Josh Coalson6dcea512001-01-23 23:07:36 +0000728 return false;
729 }
Josh Coalsonfa697a92001-08-16 20:07:29 +0000730 decoder->private_->residual[i] = tmp;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000731 }
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000732
Josh Coalsonfa697a92001-08-16 20:07:29 +0000733 decoder->private_->output_capacity = size;
734 decoder->private_->output_channels = channels;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000735
736 return true;
737}
738
Josh Coalson570db862002-07-31 06:58:16 +0000739FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id)
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000740{
741 unsigned i;
742
743 FLAC__ASSERT(0 != decoder);
744 FLAC__ASSERT(0 != decoder->private_);
745
746 for(i = 0; i < decoder->private_->metadata_filter_ids_count; i++)
747 if(0 == memcmp(decoder->private_->metadata_filter_ids + i * (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), id, (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8)))
748 return true;
749
750 return false;
751}
752
Josh Coalson570db862002-07-31 06:58:16 +0000753FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000754{
Josh Coalson77e3f312001-06-23 03:03:24 +0000755 FLAC__uint32 x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000756 unsigned i, id;
Josh Coalson77e3f312001-06-23 03:03:24 +0000757 FLAC__bool first = true;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000758
Josh Coalsonaec256b2002-03-12 16:19:54 +0000759 FLAC__ASSERT(FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input));
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000760
761 for(i = id = 0; i < 4; ) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000762 if(decoder->private_->cached) {
763 x = (FLAC__uint32)decoder->private_->lookahead;
764 decoder->private_->cached = false;
Josh Coalson215af572001-03-27 01:15:58 +0000765 }
766 else {
Josh Coalsonaec256b2002-03-12 16:19:54 +0000767 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder))
Josh Coalson215af572001-03-27 01:15:58 +0000768 return false; /* the read_callback_ sets the state for us */
769 }
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000770 if(x == FLAC__STREAM_SYNC_STRING[i]) {
Josh Coalson215af572001-03-27 01:15:58 +0000771 first = true;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000772 i++;
773 id = 0;
774 continue;
775 }
776 if(x == ID3V2_TAG_[id]) {
777 id++;
778 i = 0;
779 if(id == 3) {
Josh Coalson570db862002-07-31 06:58:16 +0000780 if(!skip_id3v2_tag_(decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000781 return false; /* the read_callback_ sets the state for us */
782 }
783 continue;
784 }
785 if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000786 decoder->private_->header_warmup[0] = (FLAC__byte)x;
Josh Coalsonaec256b2002-03-12 16:19:54 +0000787 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000788 return false; /* the read_callback_ sets the state for us */
Josh Coalson215af572001-03-27 01:15:58 +0000789
790 /* 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 */
791 /* else we have to check if the second byte is the end of a sync code */
792 if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000793 decoder->private_->lookahead = (FLAC__byte)x;
794 decoder->private_->cached = true;
Josh Coalson215af572001-03-27 01:15:58 +0000795 }
796 else if(x >> 2 == 0x3e) { /* MAGIC NUMBER for the last 6 sync bits */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000797 decoder->private_->header_warmup[1] = (FLAC__byte)x;
798 decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000799 return true;
800 }
801 }
802 i = 0;
803 if(first) {
Josh Coalson090f8f72002-06-04 05:53:04 +0000804 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, decoder->private_->client_data);
Josh Coalson215af572001-03-27 01:15:58 +0000805 first = false;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000806 }
807 }
808
Josh Coalsonfa697a92001-08-16 20:07:29 +0000809 decoder->protected_->state = FLAC__STREAM_DECODER_READ_METADATA;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000810 return true;
811}
812
Josh Coalson570db862002-07-31 06:58:16 +0000813FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000814{
Josh Coalson77e3f312001-06-23 03:03:24 +0000815 FLAC__uint32 i, x, last_block, type, length;
816 FLAC__uint64 xx;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000817
Josh Coalsonaec256b2002-03-12 16:19:54 +0000818 FLAC__ASSERT(FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input));
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000819
Josh Coalsonaec256b2002-03-12 16:19:54 +0000820 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &last_block, FLAC__STREAM_METADATA_IS_LAST_LEN, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000821 return false; /* the read_callback_ sets the state for us */
Josh Coalsonaec256b2002-03-12 16:19:54 +0000822 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &type, FLAC__STREAM_METADATA_TYPE_LEN, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000823 return false; /* the read_callback_ sets the state for us */
Josh Coalsonaec256b2002-03-12 16:19:54 +0000824 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &length, FLAC__STREAM_METADATA_LENGTH_LEN, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000825 return false; /* the read_callback_ sets the state for us */
Josh Coalson72983922001-02-23 21:03:21 +0000826 if(type == FLAC__METADATA_TYPE_STREAMINFO) {
Josh Coalson841e27e2001-01-03 00:26:42 +0000827 unsigned used_bits = 0;
Josh Coalsonfa697a92001-08-16 20:07:29 +0000828 decoder->private_->stream_info.type = type;
829 decoder->private_->stream_info.is_last = last_block;
830 decoder->private_->stream_info.length = length;
Josh Coalson841e27e2001-01-03 00:26:42 +0000831
Josh Coalsonaec256b2002-03-12 16:19:54 +0000832 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000833 return false; /* the read_callback_ sets the state for us */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000834 decoder->private_->stream_info.data.stream_info.min_blocksize = x;
Josh Coalson72983922001-02-23 21:03:21 +0000835 used_bits += FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN;
Josh Coalson841e27e2001-01-03 00:26:42 +0000836
Josh Coalsonaec256b2002-03-12 16:19:54 +0000837 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000838 return false; /* the read_callback_ sets the state for us */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000839 decoder->private_->stream_info.data.stream_info.max_blocksize = x;
Josh Coalson72983922001-02-23 21:03:21 +0000840 used_bits += FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN;
Josh Coalson841e27e2001-01-03 00:26:42 +0000841
Josh Coalsonaec256b2002-03-12 16:19:54 +0000842 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000843 return false; /* the read_callback_ sets the state for us */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000844 decoder->private_->stream_info.data.stream_info.min_framesize = x;
Josh Coalson72983922001-02-23 21:03:21 +0000845 used_bits += FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN;
Josh Coalson841e27e2001-01-03 00:26:42 +0000846
Josh Coalsonaec256b2002-03-12 16:19:54 +0000847 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000848 return false; /* the read_callback_ sets the state for us */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000849 decoder->private_->stream_info.data.stream_info.max_framesize = x;
Josh Coalson72983922001-02-23 21:03:21 +0000850 used_bits += FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN;
Josh Coalson841e27e2001-01-03 00:26:42 +0000851
Josh Coalsonaec256b2002-03-12 16:19:54 +0000852 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000853 return false; /* the read_callback_ sets the state for us */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000854 decoder->private_->stream_info.data.stream_info.sample_rate = x;
Josh Coalson72983922001-02-23 21:03:21 +0000855 used_bits += FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN;
Josh Coalson841e27e2001-01-03 00:26:42 +0000856
Josh Coalsonaec256b2002-03-12 16:19:54 +0000857 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000858 return false; /* the read_callback_ sets the state for us */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000859 decoder->private_->stream_info.data.stream_info.channels = x+1;
Josh Coalson72983922001-02-23 21:03:21 +0000860 used_bits += FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN;
Josh Coalson841e27e2001-01-03 00:26:42 +0000861
Josh Coalsonaec256b2002-03-12 16:19:54 +0000862 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000863 return false; /* the read_callback_ sets the state for us */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000864 decoder->private_->stream_info.data.stream_info.bits_per_sample = x+1;
Josh Coalson72983922001-02-23 21:03:21 +0000865 used_bits += FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN;
Josh Coalson841e27e2001-01-03 00:26:42 +0000866
Josh Coalsonaec256b2002-03-12 16:19:54 +0000867 if(!FLAC__bitbuffer_read_raw_uint64(decoder->private_->input, &decoder->private_->stream_info.data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000868 return false; /* the read_callback_ sets the state for us */
Josh Coalson72983922001-02-23 21:03:21 +0000869 used_bits += FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN;
Josh Coalson841e27e2001-01-03 00:26:42 +0000870
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000871 if(!FLAC__bitbuffer_read_byte_block_aligned(decoder->private_->input, decoder->private_->stream_info.data.stream_info.md5sum, 16, read_callback_, decoder))
872 return false; /* the read_callback_ sets the state for us */
873 used_bits += 16*8;
Josh Coalsonfa37f1c2001-01-12 23:55:11 +0000874
Josh Coalson841e27e2001-01-03 00:26:42 +0000875 /* skip the rest of the block */
Josh Coalson1b689822001-05-31 20:11:02 +0000876 FLAC__ASSERT(used_bits % 8 == 0);
Josh Coalson841e27e2001-01-03 00:26:42 +0000877 length -= (used_bits / 8);
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000878 if(!FLAC__bitbuffer_read_byte_block_aligned(decoder->private_->input, 0, length, read_callback_, decoder))
879 return false; /* the read_callback_ sets the state for us */
Josh Coalson841e27e2001-01-03 00:26:42 +0000880
Josh Coalsonfa697a92001-08-16 20:07:29 +0000881 decoder->private_->has_stream_info = true;
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000882 if(decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO])
883 decoder->private_->metadata_callback(decoder, &decoder->private_->stream_info, decoder->private_->client_data);
Josh Coalsonc076ba52001-04-05 21:32:54 +0000884 }
885 else if(type == FLAC__METADATA_TYPE_SEEKTABLE) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000886 decoder->private_->seek_table.type = type;
887 decoder->private_->seek_table.is_last = last_block;
888 decoder->private_->seek_table.length = length;
Josh Coalsonc076ba52001-04-05 21:32:54 +0000889
Josh Coalsonf145bbd2002-05-04 17:37:51 +0000890 decoder->private_->seek_table.data.seek_table.num_points = length / FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
Josh Coalsonc076ba52001-04-05 21:32:54 +0000891
Josh Coalsoncc682512002-06-08 04:53:42 +0000892 if(0 == (decoder->private_->seek_table.data.seek_table.points = (FLAC__StreamMetadata_SeekPoint*)malloc(decoder->private_->seek_table.data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint)))) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000893 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
Josh Coalsonc076ba52001-04-05 21:32:54 +0000894 return false;
895 }
Josh Coalson090f8f72002-06-04 05:53:04 +0000896 for(i = 0; i < decoder->private_->seek_table.data.seek_table.num_points; i++) {
Josh Coalsonaec256b2002-03-12 16:19:54 +0000897 if(!FLAC__bitbuffer_read_raw_uint64(decoder->private_->input, &xx, FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN, read_callback_, decoder))
Josh Coalsonc076ba52001-04-05 21:32:54 +0000898 return false; /* the read_callback_ sets the state for us */
Josh Coalson090f8f72002-06-04 05:53:04 +0000899 decoder->private_->seek_table.data.seek_table.points[i].sample_number = xx;
Josh Coalsonc076ba52001-04-05 21:32:54 +0000900
Josh Coalsonaec256b2002-03-12 16:19:54 +0000901 if(!FLAC__bitbuffer_read_raw_uint64(decoder->private_->input, &xx, FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN, read_callback_, decoder))
Josh Coalsonc076ba52001-04-05 21:32:54 +0000902 return false; /* the read_callback_ sets the state for us */
Josh Coalson090f8f72002-06-04 05:53:04 +0000903 decoder->private_->seek_table.data.seek_table.points[i].stream_offset = xx;
Josh Coalsonc076ba52001-04-05 21:32:54 +0000904
Josh Coalsonaec256b2002-03-12 16:19:54 +0000905 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN, read_callback_, decoder))
Josh Coalsonc076ba52001-04-05 21:32:54 +0000906 return false; /* the read_callback_ sets the state for us */
Josh Coalson090f8f72002-06-04 05:53:04 +0000907 decoder->private_->seek_table.data.seek_table.points[i].frame_samples = x;
Josh Coalsonc076ba52001-04-05 21:32:54 +0000908 }
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000909 length -= (decoder->private_->seek_table.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH);
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000910 /* if there is a partial point left, skip over it */
911 if(length > 0) {
912 /*@@@ do an error_callback() here? there's an argument for either way */
913 if(!FLAC__bitbuffer_read_byte_block_aligned(decoder->private_->input, 0, length, read_callback_, decoder))
914 return false; /* the read_callback_ sets the state for us */
915 }
916
Josh Coalsonfa697a92001-08-16 20:07:29 +0000917 decoder->private_->has_seek_table = true;
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000918 if(decoder->private_->metadata_filter[FLAC__METADATA_TYPE_SEEKTABLE])
919 decoder->private_->metadata_callback(decoder, &decoder->private_->seek_table, decoder->private_->client_data);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000920 }
921 else {
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000922 FLAC__bool skip_it = !decoder->private_->metadata_filter[type];
923 unsigned real_length = length;
Josh Coalsoncc682512002-06-08 04:53:42 +0000924 FLAC__StreamMetadata block;
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000925
926 block.is_last = last_block;
927 block.type = type;
928 block.length = length;
929
Josh Coalson8400e432002-05-09 05:41:35 +0000930 if(type == FLAC__METADATA_TYPE_APPLICATION) {
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000931 if(!FLAC__bitbuffer_read_byte_block_aligned(decoder->private_->input, block.data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000932 return false; /* the read_callback_ sets the state for us */
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000933
934 real_length -= FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8;
935
Josh Coalson570db862002-07-31 06:58:16 +0000936 if(decoder->private_->metadata_filter_ids_count > 0 && has_id_filtered_(decoder, block.data.application.id))
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000937 skip_it = !skip_it;
938 }
939
940 if(skip_it) {
941 if(!FLAC__bitbuffer_read_byte_block_aligned(decoder->private_->input, 0, real_length, read_callback_, decoder))
942 return false; /* the read_callback_ sets the state for us */
943 }
944 else {
945 switch(type) {
946 case FLAC__METADATA_TYPE_PADDING:
947 /* skip the padding bytes */
948 if(!FLAC__bitbuffer_read_byte_block_aligned(decoder->private_->input, 0, real_length, read_callback_, decoder))
949 return false; /* the read_callback_ sets the state for us */
950 break;
951 case FLAC__METADATA_TYPE_APPLICATION:
952 /* remember, we read the ID already */
Josh Coalsonbda92f22002-05-31 06:24:03 +0000953 if(real_length > 0) {
954 if(0 == (block.data.application.data = malloc(real_length))) {
955 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
956 return false;
957 }
958 if(!FLAC__bitbuffer_read_byte_block_aligned(decoder->private_->input, block.data.application.data, real_length, read_callback_, decoder))
959 return false; /* the read_callback_ sets the state for us */
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000960 }
Josh Coalsonbda92f22002-05-31 06:24:03 +0000961 else
962 block.data.application.data = 0;
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000963 break;
964 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
965 /* read vendor string */
Josh Coalson090f8f72002-06-04 05:53:04 +0000966 FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32);
967 if(!FLAC__bitbuffer_read_raw_uint32_little_endian(decoder->private_->input, &block.data.vorbis_comment.vendor_string.length, read_callback_, decoder))
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000968 return false; /* the read_callback_ sets the state for us */
969 if(block.data.vorbis_comment.vendor_string.length > 0) {
970 if(0 == (block.data.vorbis_comment.vendor_string.entry = malloc(block.data.vorbis_comment.vendor_string.length))) {
971 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
972 return false;
973 }
974 if(!FLAC__bitbuffer_read_byte_block_aligned(decoder->private_->input, block.data.vorbis_comment.vendor_string.entry, block.data.vorbis_comment.vendor_string.length, read_callback_, decoder))
975 return false; /* the read_callback_ sets the state for us */
976 }
977 else
978 block.data.vorbis_comment.vendor_string.entry = 0;
979
980 /* read num comments */
Josh Coalson090f8f72002-06-04 05:53:04 +0000981 FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN == 32);
982 if(!FLAC__bitbuffer_read_raw_uint32_little_endian(decoder->private_->input, &block.data.vorbis_comment.num_comments, read_callback_, decoder))
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000983 return false; /* the read_callback_ sets the state for us */
984
985 /* read comments */
986 if(block.data.vorbis_comment.num_comments > 0) {
Josh Coalsoncc682512002-06-08 04:53:42 +0000987 if(0 == (block.data.vorbis_comment.comments = malloc(block.data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) {
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000988 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
989 return false;
990 }
991 for(i = 0; i < block.data.vorbis_comment.num_comments; i++) {
Josh Coalson090f8f72002-06-04 05:53:04 +0000992 FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32);
993 if(!FLAC__bitbuffer_read_raw_uint32_little_endian(decoder->private_->input, &block.data.vorbis_comment.comments[i].length, read_callback_, decoder))
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000994 return false; /* the read_callback_ sets the state for us */
995 if(block.data.vorbis_comment.comments[i].length > 0) {
996 if(0 == (block.data.vorbis_comment.comments[i].entry = malloc(block.data.vorbis_comment.comments[i].length))) {
997 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
998 return false;
999 }
1000 if(!FLAC__bitbuffer_read_byte_block_aligned(decoder->private_->input, block.data.vorbis_comment.comments[i].entry, block.data.vorbis_comment.comments[i].length, read_callback_, decoder))
1001 return false; /* the read_callback_ sets the state for us */
1002 }
1003 else
1004 block.data.vorbis_comment.comments[i].entry = 0;
1005 }
1006 }
1007 else {
1008 block.data.vorbis_comment.comments = 0;
1009 }
1010 break;
1011 case FLAC__METADATA_TYPE_STREAMINFO:
1012 case FLAC__METADATA_TYPE_SEEKTABLE:
1013 default:
1014 FLAC__ASSERT(0);
1015 }
1016 decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data);
1017
1018 /* now we have to free any malloc'ed data in the block */
1019 switch(type) {
1020 case FLAC__METADATA_TYPE_PADDING:
1021 break;
1022 case FLAC__METADATA_TYPE_APPLICATION:
1023 if(0 != block.data.application.data)
1024 free(block.data.application.data);
1025 break;
1026 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
1027 if(0 != block.data.vorbis_comment.vendor_string.entry)
1028 free(block.data.vorbis_comment.vendor_string.entry);
1029 if(block.data.vorbis_comment.num_comments > 0)
1030 for(i = 0; i < block.data.vorbis_comment.num_comments; i++)
1031 if(0 != block.data.vorbis_comment.comments[i].entry)
1032 free(block.data.vorbis_comment.comments[i].entry);
1033 if(0 != block.data.vorbis_comment.comments)
1034 free(block.data.vorbis_comment.comments);
1035 break;
1036 case FLAC__METADATA_TYPE_STREAMINFO:
1037 case FLAC__METADATA_TYPE_SEEKTABLE:
1038 default:
1039 FLAC__ASSERT(0);
1040 }
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001041 }
1042 }
1043
1044 if(last_block)
Josh Coalsonfa697a92001-08-16 20:07:29 +00001045 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001046
1047 return true;
1048}
1049
Josh Coalson570db862002-07-31 06:58:16 +00001050FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001051{
Josh Coalson77e3f312001-06-23 03:03:24 +00001052 FLAC__uint32 x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001053 unsigned i, skip;
1054
1055 /* skip the version and flags bytes */
Josh Coalsonaec256b2002-03-12 16:19:54 +00001056 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 24, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001057 return false; /* the read_callback_ sets the state for us */
1058 /* get the size (in bytes) to skip */
1059 skip = 0;
1060 for(i = 0; i < 4; i++) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001061 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001062 return false; /* the read_callback_ sets the state for us */
1063 skip <<= 7;
1064 skip |= (x & 0x7f);
1065 }
1066 /* skip the rest of the tag */
Josh Coalsonbf9325f2002-05-07 05:30:27 +00001067 if(!FLAC__bitbuffer_read_byte_block_aligned(decoder->private_->input, 0, skip, read_callback_, decoder))
1068 return false; /* the read_callback_ sets the state for us */
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001069 return true;
1070}
1071
Josh Coalson570db862002-07-31 06:58:16 +00001072FLAC__bool frame_sync_(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001073{
Josh Coalson77e3f312001-06-23 03:03:24 +00001074 FLAC__uint32 x;
1075 FLAC__bool first = true;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001076
1077 /* If we know the total number of samples in the stream, stop if we've read that many. */
1078 /* This will stop us, for example, from wasting time trying to sync on an ID3V1 tag. */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001079 if(decoder->private_->has_stream_info && decoder->private_->stream_info.data.stream_info.total_samples) {
1080 if(decoder->private_->samples_decoded >= decoder->private_->stream_info.data.stream_info.total_samples) {
1081 decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001082 return true;
1083 }
1084 }
1085
1086 /* make sure we're byte aligned */
Josh Coalsonaec256b2002-03-12 16:19:54 +00001087 if(!FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input)) {
1088 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__bitbuffer_bits_left_for_byte_alignment(decoder->private_->input), read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001089 return false; /* the read_callback_ sets the state for us */
1090 }
1091
1092 while(1) {
Josh Coalsonfa697a92001-08-16 20:07:29 +00001093 if(decoder->private_->cached) {
1094 x = (FLAC__uint32)decoder->private_->lookahead;
1095 decoder->private_->cached = false;
Josh Coalson215af572001-03-27 01:15:58 +00001096 }
1097 else {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001098 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001099 return false; /* the read_callback_ sets the state for us */
Josh Coalson215af572001-03-27 01:15:58 +00001100 }
1101 if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001102 decoder->private_->header_warmup[0] = (FLAC__byte)x;
Josh Coalsonaec256b2002-03-12 16:19:54 +00001103 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder))
Josh Coalson215af572001-03-27 01:15:58 +00001104 return false; /* the read_callback_ sets the state for us */
1105
1106 /* 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 */
1107 /* else we have to check if the second byte is the end of a sync code */
1108 if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001109 decoder->private_->lookahead = (FLAC__byte)x;
1110 decoder->private_->cached = true;
Josh Coalson215af572001-03-27 01:15:58 +00001111 }
1112 else if(x >> 2 == 0x3e) { /* MAGIC NUMBER for the last 6 sync bits */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001113 decoder->private_->header_warmup[1] = (FLAC__byte)x;
1114 decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001115 return true;
1116 }
1117 }
1118 if(first) {
Josh Coalson090f8f72002-06-04 05:53:04 +00001119 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, decoder->private_->client_data);
Josh Coalson38c68542002-02-12 22:58:59 +00001120 first = false;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001121 }
1122 }
1123
1124 return true;
1125}
1126
Josh Coalson570db862002-07-31 06:58:16 +00001127FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001128{
1129 unsigned channel;
1130 unsigned i;
Josh Coalson77e3f312001-06-23 03:03:24 +00001131 FLAC__int32 mid, side, left, right;
1132 FLAC__uint16 frame_crc; /* the one we calculate from the input stream */
1133 FLAC__uint32 x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001134
1135 *got_a_frame = false;
1136
Josh Coalson215af572001-03-27 01:15:58 +00001137 /* init the CRC */
1138 frame_crc = 0;
Josh Coalsonfa697a92001-08-16 20:07:29 +00001139 FLAC__CRC16_UPDATE(decoder->private_->header_warmup[0], frame_crc);
1140 FLAC__CRC16_UPDATE(decoder->private_->header_warmup[1], frame_crc);
Josh Coalsonaec256b2002-03-12 16:19:54 +00001141 FLAC__bitbuffer_reset_read_crc16(decoder->private_->input, frame_crc);
Josh Coalson215af572001-03-27 01:15:58 +00001142
Josh Coalson570db862002-07-31 06:58:16 +00001143 if(!read_frame_header_(decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001144 return false;
Josh Coalsonfa697a92001-08-16 20:07:29 +00001145 if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001146 return true;
Josh Coalson570db862002-07-31 06:58:16 +00001147 if(!allocate_output_(decoder, decoder->private_->frame.header.blocksize, decoder->private_->frame.header.channels))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001148 return false;
Josh Coalsonfa697a92001-08-16 20:07:29 +00001149 for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) {
Josh Coalsonb5e60e52001-01-28 09:27:27 +00001150 /*
1151 * first figure the correct bits-per-sample of the subframe
1152 */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001153 unsigned bps = decoder->private_->frame.header.bits_per_sample;
1154 switch(decoder->private_->frame.header.channel_assignment) {
Josh Coalsonb5e60e52001-01-28 09:27:27 +00001155 case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
1156 /* no adjustment needed */
1157 break;
1158 case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001159 FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
Josh Coalsonb5e60e52001-01-28 09:27:27 +00001160 if(channel == 1)
1161 bps++;
1162 break;
1163 case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001164 FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
Josh Coalsonb5e60e52001-01-28 09:27:27 +00001165 if(channel == 0)
1166 bps++;
1167 break;
1168 case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001169 FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
Josh Coalsonb5e60e52001-01-28 09:27:27 +00001170 if(channel == 1)
1171 bps++;
1172 break;
1173 default:
Josh Coalson1b689822001-05-31 20:11:02 +00001174 FLAC__ASSERT(0);
Josh Coalsonb5e60e52001-01-28 09:27:27 +00001175 }
1176 /*
1177 * now read it
1178 */
Josh Coalson570db862002-07-31 06:58:16 +00001179 if(!read_subframe_(decoder, channel, bps))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001180 return false;
Josh Coalsonfa697a92001-08-16 20:07:29 +00001181 if(decoder->protected_->state != FLAC__STREAM_DECODER_READ_FRAME) {
1182 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001183 return true;
1184 }
1185 }
Josh Coalson570db862002-07-31 06:58:16 +00001186 if(!read_zero_padding_(decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001187 return false;
1188
Josh Coalson215af572001-03-27 01:15:58 +00001189 /*
1190 * Read the frame CRC-16 from the footer and check
1191 */
Josh Coalsonaec256b2002-03-12 16:19:54 +00001192 frame_crc = FLAC__bitbuffer_get_read_crc16(decoder->private_->input);
1193 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__FRAME_FOOTER_CRC_LEN, read_callback_, decoder))
Josh Coalson215af572001-03-27 01:15:58 +00001194 return false; /* the read_callback_ sets the state for us */
Josh Coalson77e3f312001-06-23 03:03:24 +00001195 if(frame_crc == (FLAC__uint16)x) {
Josh Coalson215af572001-03-27 01:15:58 +00001196 /* Undo any special channel coding */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001197 switch(decoder->private_->frame.header.channel_assignment) {
Josh Coalson215af572001-03-27 01:15:58 +00001198 case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
1199 /* do nothing */
1200 break;
1201 case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001202 FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
1203 for(i = 0; i < decoder->private_->frame.header.blocksize; i++)
1204 decoder->private_->output[1][i] = decoder->private_->output[0][i] - decoder->private_->output[1][i];
Josh Coalson215af572001-03-27 01:15:58 +00001205 break;
1206 case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001207 FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
1208 for(i = 0; i < decoder->private_->frame.header.blocksize; i++)
1209 decoder->private_->output[0][i] += decoder->private_->output[1][i];
Josh Coalson215af572001-03-27 01:15:58 +00001210 break;
1211 case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001212 FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
1213 for(i = 0; i < decoder->private_->frame.header.blocksize; i++) {
1214 mid = decoder->private_->output[0][i];
1215 side = decoder->private_->output[1][i];
Josh Coalson215af572001-03-27 01:15:58 +00001216 mid <<= 1;
1217 if(side & 1) /* i.e. if 'side' is odd... */
1218 mid++;
1219 left = mid + side;
1220 right = mid - side;
Josh Coalsonfa697a92001-08-16 20:07:29 +00001221 decoder->private_->output[0][i] = left >> 1;
1222 decoder->private_->output[1][i] = right >> 1;
Josh Coalson215af572001-03-27 01:15:58 +00001223 }
1224 break;
1225 default:
Josh Coalson1b689822001-05-31 20:11:02 +00001226 FLAC__ASSERT(0);
Josh Coalson215af572001-03-27 01:15:58 +00001227 break;
1228 }
1229 }
1230 else {
1231 /* Bad frame, emit error and zero the output signal */
Josh Coalson090f8f72002-06-04 05:53:04 +00001232 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH, decoder->private_->client_data);
Josh Coalsonfa697a92001-08-16 20:07:29 +00001233 for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) {
1234 memset(decoder->private_->output[channel], 0, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize);
Josh Coalson215af572001-03-27 01:15:58 +00001235 }
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001236 }
1237
1238 *got_a_frame = true;
1239
1240 /* put the latest values into the public section of the decoder instance */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001241 decoder->protected_->channels = decoder->private_->frame.header.channels;
1242 decoder->protected_->channel_assignment = decoder->private_->frame.header.channel_assignment;
1243 decoder->protected_->bits_per_sample = decoder->private_->frame.header.bits_per_sample;
1244 decoder->protected_->sample_rate = decoder->private_->frame.header.sample_rate;
1245 decoder->protected_->blocksize = decoder->private_->frame.header.blocksize;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001246
Josh Coalsonfa697a92001-08-16 20:07:29 +00001247 FLAC__ASSERT(decoder->private_->frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
1248 decoder->private_->samples_decoded = decoder->private_->frame.header.number.sample_number + decoder->private_->frame.header.blocksize;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001249
1250 /* write it */
Josh Coalson57ba6f42002-06-07 05:27:37 +00001251 if(decoder->private_->write_callback(decoder, &decoder->private_->frame, (const FLAC__int32 * const *)decoder->private_->output, decoder->private_->client_data) != FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001252 return false;
1253
Josh Coalsonfa697a92001-08-16 20:07:29 +00001254 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001255 return true;
1256}
1257
Josh Coalson570db862002-07-31 06:58:16 +00001258FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001259{
Josh Coalson77e3f312001-06-23 03:03:24 +00001260 FLAC__uint32 x;
1261 FLAC__uint64 xx;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001262 unsigned i, blocksize_hint = 0, sample_rate_hint = 0;
Josh Coalson77e3f312001-06-23 03:03:24 +00001263 FLAC__byte crc8, raw_header[16]; /* MAGIC NUMBER based on the maximum frame header size, including CRC */
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001264 unsigned raw_header_len;
Josh Coalson77e3f312001-06-23 03:03:24 +00001265 FLAC__bool is_unparseable = false;
Josh Coalsonfa697a92001-08-16 20:07:29 +00001266 const FLAC__bool is_known_variable_blocksize_stream = (decoder->private_->has_stream_info && decoder->private_->stream_info.data.stream_info.min_blocksize != decoder->private_->stream_info.data.stream_info.max_blocksize);
1267 const FLAC__bool is_known_fixed_blocksize_stream = (decoder->private_->has_stream_info && decoder->private_->stream_info.data.stream_info.min_blocksize == decoder->private_->stream_info.data.stream_info.max_blocksize);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001268
Josh Coalsonaec256b2002-03-12 16:19:54 +00001269 FLAC__ASSERT(FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input));
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001270
Josh Coalson215af572001-03-27 01:15:58 +00001271 /* init the raw header with the saved bits from synchronization */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001272 raw_header[0] = decoder->private_->header_warmup[0];
1273 raw_header[1] = decoder->private_->header_warmup[1];
Josh Coalson215af572001-03-27 01:15:58 +00001274 raw_header_len = 2;
1275
1276 /*
1277 * check to make sure that the reserved bits are 0
1278 */
1279 if(raw_header[1] & 0x03) { /* MAGIC NUMBER */
1280 is_unparseable = true;
1281 }
1282
1283 /*
1284 * Note that along the way as we read the header, we look for a sync
1285 * code inside. If we find one it would indicate that our original
1286 * sync was bad since there cannot be a sync code in a valid header.
1287 */
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001288
1289 /*
1290 * read in the raw header as bytes so we can CRC it, and parse it on the way
1291 */
1292 for(i = 0; i < 2; i++) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001293 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001294 return false; /* the read_callback_ sets the state for us */
Josh Coalson215af572001-03-27 01:15:58 +00001295 if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001296 /* if we get here it means our original sync was erroneous since the sync code cannot appear in the header */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001297 decoder->private_->lookahead = (FLAC__byte)x;
1298 decoder->private_->cached = true;
Josh Coalson090f8f72002-06-04 05:53:04 +00001299 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, decoder->private_->client_data);
Josh Coalsonfa697a92001-08-16 20:07:29 +00001300 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalson215af572001-03-27 01:15:58 +00001301 return true;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001302 }
Josh Coalson77e3f312001-06-23 03:03:24 +00001303 raw_header[raw_header_len++] = (FLAC__byte)x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001304 }
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001305
Josh Coalson215af572001-03-27 01:15:58 +00001306 switch(x = raw_header[2] >> 4) {
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001307 case 0:
Josh Coalson7531b002001-04-14 00:24:32 +00001308 if(is_known_fixed_blocksize_stream)
Josh Coalsonfa697a92001-08-16 20:07:29 +00001309 decoder->private_->frame.header.blocksize = decoder->private_->stream_info.data.stream_info.min_blocksize;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001310 else
1311 is_unparseable = true;
1312 break;
1313 case 1:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001314 decoder->private_->frame.header.blocksize = 192;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001315 break;
1316 case 2:
1317 case 3:
1318 case 4:
1319 case 5:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001320 decoder->private_->frame.header.blocksize = 576 << (x-2);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001321 break;
1322 case 6:
1323 case 7:
1324 blocksize_hint = x;
1325 break;
Josh Coalson215af572001-03-27 01:15:58 +00001326 case 8:
1327 case 9:
1328 case 10:
1329 case 11:
1330 case 12:
1331 case 13:
1332 case 14:
1333 case 15:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001334 decoder->private_->frame.header.blocksize = 256 << (x-8);
Josh Coalson215af572001-03-27 01:15:58 +00001335 break;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001336 default:
Josh Coalson1b689822001-05-31 20:11:02 +00001337 FLAC__ASSERT(0);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001338 break;
1339 }
1340
Josh Coalson215af572001-03-27 01:15:58 +00001341 switch(x = raw_header[2] & 0x0f) {
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001342 case 0:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001343 if(decoder->private_->has_stream_info)
1344 decoder->private_->frame.header.sample_rate = decoder->private_->stream_info.data.stream_info.sample_rate;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001345 else
1346 is_unparseable = true;
1347 break;
1348 case 1:
1349 case 2:
1350 case 3:
1351 is_unparseable = true;
1352 break;
1353 case 4:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001354 decoder->private_->frame.header.sample_rate = 8000;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001355 break;
1356 case 5:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001357 decoder->private_->frame.header.sample_rate = 16000;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001358 break;
1359 case 6:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001360 decoder->private_->frame.header.sample_rate = 22050;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001361 break;
1362 case 7:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001363 decoder->private_->frame.header.sample_rate = 24000;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001364 break;
1365 case 8:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001366 decoder->private_->frame.header.sample_rate = 32000;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001367 break;
1368 case 9:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001369 decoder->private_->frame.header.sample_rate = 44100;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001370 break;
1371 case 10:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001372 decoder->private_->frame.header.sample_rate = 48000;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001373 break;
1374 case 11:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001375 decoder->private_->frame.header.sample_rate = 96000;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001376 break;
1377 case 12:
1378 case 13:
1379 case 14:
1380 sample_rate_hint = x;
1381 break;
1382 case 15:
Josh Coalson090f8f72002-06-04 05:53:04 +00001383 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, decoder->private_->client_data);
Josh Coalsonfa697a92001-08-16 20:07:29 +00001384 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001385 return true;
1386 default:
Josh Coalson1b689822001-05-31 20:11:02 +00001387 FLAC__ASSERT(0);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001388 }
1389
Josh Coalson215af572001-03-27 01:15:58 +00001390 x = (unsigned)(raw_header[3] >> 4);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001391 if(x & 8) {
Josh Coalsonfa697a92001-08-16 20:07:29 +00001392 decoder->private_->frame.header.channels = 2;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001393 switch(x & 7) {
1394 case 0:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001395 decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001396 break;
1397 case 1:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001398 decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001399 break;
1400 case 2:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001401 decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_MID_SIDE;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001402 break;
1403 default:
1404 is_unparseable = true;
1405 break;
1406 }
1407 }
1408 else {
Josh Coalsonfa697a92001-08-16 20:07:29 +00001409 decoder->private_->frame.header.channels = (unsigned)x + 1;
1410 decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001411 }
1412
Josh Coalson215af572001-03-27 01:15:58 +00001413 switch(x = (unsigned)(raw_header[3] & 0x0e) >> 1) {
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001414 case 0:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001415 if(decoder->private_->has_stream_info)
1416 decoder->private_->frame.header.bits_per_sample = decoder->private_->stream_info.data.stream_info.bits_per_sample;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001417 else
1418 is_unparseable = true;
1419 break;
1420 case 1:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001421 decoder->private_->frame.header.bits_per_sample = 8;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001422 break;
1423 case 2:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001424 decoder->private_->frame.header.bits_per_sample = 12;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001425 break;
1426 case 4:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001427 decoder->private_->frame.header.bits_per_sample = 16;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001428 break;
1429 case 5:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001430 decoder->private_->frame.header.bits_per_sample = 20;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001431 break;
1432 case 6:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001433 decoder->private_->frame.header.bits_per_sample = 24;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001434 break;
1435 case 3:
1436 case 7:
1437 is_unparseable = true;
1438 break;
1439 default:
Josh Coalson1b689822001-05-31 20:11:02 +00001440 FLAC__ASSERT(0);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001441 break;
1442 }
1443
Josh Coalson215af572001-03-27 01:15:58 +00001444 if(raw_header[3] & 0x01) { /* this should be a zero padding bit */
Josh Coalson090f8f72002-06-04 05:53:04 +00001445 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, decoder->private_->client_data);
Josh Coalsonfa697a92001-08-16 20:07:29 +00001446 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001447 return true;
1448 }
1449
Josh Coalson7531b002001-04-14 00:24:32 +00001450 if(blocksize_hint && is_known_variable_blocksize_stream) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001451 if(!FLAC__bitbuffer_read_utf8_uint64(decoder->private_->input, &xx, read_callback_, decoder, raw_header, &raw_header_len))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001452 return false; /* the read_callback_ sets the state for us */
Josh Coalson215af572001-03-27 01:15:58 +00001453 if(xx == 0xffffffffffffffff) { /* i.e. non-UTF8 code... */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001454 decoder->private_->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */
1455 decoder->private_->cached = true;
Josh Coalson090f8f72002-06-04 05:53:04 +00001456 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, decoder->private_->client_data);
Josh Coalsonfa697a92001-08-16 20:07:29 +00001457 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalson215af572001-03-27 01:15:58 +00001458 return true;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001459 }
Josh Coalsonfa697a92001-08-16 20:07:29 +00001460 decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER;
1461 decoder->private_->frame.header.number.sample_number = xx;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001462 }
1463 else {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001464 if(!FLAC__bitbuffer_read_utf8_uint32(decoder->private_->input, &x, read_callback_, decoder, raw_header, &raw_header_len))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001465 return false; /* the read_callback_ sets the state for us */
Josh Coalson215af572001-03-27 01:15:58 +00001466 if(x == 0xffffffff) { /* i.e. non-UTF8 code... */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001467 decoder->private_->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */
1468 decoder->private_->cached = true;
Josh Coalson090f8f72002-06-04 05:53:04 +00001469 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, decoder->private_->client_data);
Josh Coalsonfa697a92001-08-16 20:07:29 +00001470 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalson215af572001-03-27 01:15:58 +00001471 return true;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001472 }
Josh Coalsonfa697a92001-08-16 20:07:29 +00001473 decoder->private_->last_frame_number = x;
1474 if(decoder->private_->has_stream_info) {
1475 decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER;
1476 decoder->private_->frame.header.number.sample_number = (FLAC__int64)decoder->private_->stream_info.data.stream_info.min_blocksize * (FLAC__int64)x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001477 }
1478 else {
1479 is_unparseable = true;
1480 }
1481 }
1482
1483 if(blocksize_hint) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001484 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001485 return false; /* the read_callback_ sets the state for us */
Josh Coalson77e3f312001-06-23 03:03:24 +00001486 raw_header[raw_header_len++] = (FLAC__byte)x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001487 if(blocksize_hint == 7) {
Josh Coalson77e3f312001-06-23 03:03:24 +00001488 FLAC__uint32 _x;
Josh Coalsonaec256b2002-03-12 16:19:54 +00001489 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &_x, 8, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001490 return false; /* the read_callback_ sets the state for us */
Josh Coalson77e3f312001-06-23 03:03:24 +00001491 raw_header[raw_header_len++] = (FLAC__byte)_x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001492 x = (x << 8) | _x;
1493 }
Josh Coalsonfa697a92001-08-16 20:07:29 +00001494 decoder->private_->frame.header.blocksize = x+1;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001495 }
1496
1497 if(sample_rate_hint) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001498 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001499 return false; /* the read_callback_ sets the state for us */
Josh Coalson77e3f312001-06-23 03:03:24 +00001500 raw_header[raw_header_len++] = (FLAC__byte)x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001501 if(sample_rate_hint != 12) {
Josh Coalson77e3f312001-06-23 03:03:24 +00001502 FLAC__uint32 _x;
Josh Coalsonaec256b2002-03-12 16:19:54 +00001503 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &_x, 8, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001504 return false; /* the read_callback_ sets the state for us */
Josh Coalson77e3f312001-06-23 03:03:24 +00001505 raw_header[raw_header_len++] = (FLAC__byte)_x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001506 x = (x << 8) | _x;
1507 }
1508 if(sample_rate_hint == 12)
Josh Coalsonfa697a92001-08-16 20:07:29 +00001509 decoder->private_->frame.header.sample_rate = x*1000;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001510 else if(sample_rate_hint == 13)
Josh Coalsonfa697a92001-08-16 20:07:29 +00001511 decoder->private_->frame.header.sample_rate = x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001512 else
Josh Coalsonfa697a92001-08-16 20:07:29 +00001513 decoder->private_->frame.header.sample_rate = x*10;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001514 }
1515
Josh Coalson215af572001-03-27 01:15:58 +00001516 /* read the CRC-8 byte */
Josh Coalsonaec256b2002-03-12 16:19:54 +00001517 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001518 return false; /* the read_callback_ sets the state for us */
Josh Coalson77e3f312001-06-23 03:03:24 +00001519 crc8 = (FLAC__byte)x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001520
Josh Coalson215af572001-03-27 01:15:58 +00001521 if(FLAC__crc8(raw_header, raw_header_len) != crc8) {
Josh Coalson090f8f72002-06-04 05:53:04 +00001522 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, decoder->private_->client_data);
Josh Coalsonfa697a92001-08-16 20:07:29 +00001523 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001524 return true;
1525 }
1526
1527 if(is_unparseable) {
Josh Coalsonfa697a92001-08-16 20:07:29 +00001528 decoder->protected_->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001529 return false;
1530 }
1531
1532 return true;
1533}
1534
Josh Coalson570db862002-07-31 06:58:16 +00001535FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001536{
Josh Coalson77e3f312001-06-23 03:03:24 +00001537 FLAC__uint32 x;
1538 FLAC__bool wasted_bits;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001539
Josh Coalsonaec256b2002-03-12 16:19:54 +00001540 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) /* MAGIC NUMBER */
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001541 return false; /* the read_callback_ sets the state for us */
Josh Coalson215af572001-03-27 01:15:58 +00001542
1543 wasted_bits = (x & 1);
1544 x &= 0xfe;
1545
1546 if(wasted_bits) {
1547 unsigned u;
Josh Coalsonaec256b2002-03-12 16:19:54 +00001548 if(!FLAC__bitbuffer_read_unary_unsigned(decoder->private_->input, &u, read_callback_, decoder))
Josh Coalson215af572001-03-27 01:15:58 +00001549 return false; /* the read_callback_ sets the state for us */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001550 decoder->private_->frame.subframes[channel].wasted_bits = u+1;
1551 bps -= decoder->private_->frame.subframes[channel].wasted_bits;
Josh Coalson215af572001-03-27 01:15:58 +00001552 }
1553 else
Josh Coalsonfa697a92001-08-16 20:07:29 +00001554 decoder->private_->frame.subframes[channel].wasted_bits = 0;
Josh Coalson215af572001-03-27 01:15:58 +00001555
Josh Coalson859bc542001-03-27 22:22:27 +00001556 /*
1557 * Lots of magic numbers here
1558 */
Josh Coalson215af572001-03-27 01:15:58 +00001559 if(x & 0x80) {
Josh Coalson090f8f72002-06-04 05:53:04 +00001560 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, decoder->private_->client_data);
Josh Coalsonfa697a92001-08-16 20:07:29 +00001561 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001562 return true;
1563 }
1564 else if(x == 0) {
Josh Coalson570db862002-07-31 06:58:16 +00001565 if(!read_subframe_constant_(decoder, channel, bps))
Josh Coalson215af572001-03-27 01:15:58 +00001566 return false;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001567 }
1568 else if(x == 2) {
Josh Coalson570db862002-07-31 06:58:16 +00001569 if(!read_subframe_verbatim_(decoder, channel, bps))
Josh Coalson215af572001-03-27 01:15:58 +00001570 return false;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001571 }
1572 else if(x < 16) {
Josh Coalsonfa697a92001-08-16 20:07:29 +00001573 decoder->protected_->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001574 return false;
1575 }
1576 else if(x <= 24) {
Josh Coalson570db862002-07-31 06:58:16 +00001577 if(!read_subframe_fixed_(decoder, channel, bps, (x>>1)&7))
Josh Coalson215af572001-03-27 01:15:58 +00001578 return false;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001579 }
1580 else if(x < 64) {
Josh Coalsonfa697a92001-08-16 20:07:29 +00001581 decoder->protected_->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001582 return false;
1583 }
1584 else {
Josh Coalson570db862002-07-31 06:58:16 +00001585 if(!read_subframe_lpc_(decoder, channel, bps, ((x>>1)&31)+1))
Josh Coalson215af572001-03-27 01:15:58 +00001586 return false;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001587 }
Josh Coalson215af572001-03-27 01:15:58 +00001588
1589 if(wasted_bits) {
Josh Coalson859bc542001-03-27 22:22:27 +00001590 unsigned i;
Josh Coalsonfa697a92001-08-16 20:07:29 +00001591 x = decoder->private_->frame.subframes[channel].wasted_bits;
1592 for(i = 0; i < decoder->private_->frame.header.blocksize; i++)
1593 decoder->private_->output[channel][i] <<= x;
Josh Coalson215af572001-03-27 01:15:58 +00001594 }
Josh Coalson859bc542001-03-27 22:22:27 +00001595
Josh Coalson215af572001-03-27 01:15:58 +00001596 return true;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001597}
1598
Josh Coalson570db862002-07-31 06:58:16 +00001599FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001600{
Josh Coalsonfa697a92001-08-16 20:07:29 +00001601 FLAC__Subframe_Constant *subframe = &decoder->private_->frame.subframes[channel].data.constant;
Josh Coalson77e3f312001-06-23 03:03:24 +00001602 FLAC__int32 x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001603 unsigned i;
Josh Coalsonfa697a92001-08-16 20:07:29 +00001604 FLAC__int32 *output = decoder->private_->output[channel];
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001605
Josh Coalsonfa697a92001-08-16 20:07:29 +00001606 decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_CONSTANT;
Josh Coalson6dcea512001-01-23 23:07:36 +00001607
Josh Coalsonaec256b2002-03-12 16:19:54 +00001608 if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &x, bps, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001609 return false; /* the read_callback_ sets the state for us */
1610
Josh Coalson6dcea512001-01-23 23:07:36 +00001611 subframe->value = x;
1612
1613 /* decode the subframe */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001614 for(i = 0; i < decoder->private_->frame.header.blocksize; i++)
Josh Coalson6dcea512001-01-23 23:07:36 +00001615 output[i] = x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001616
1617 return true;
1618}
1619
Josh Coalson570db862002-07-31 06:58:16 +00001620FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001621{
Josh Coalsonfa697a92001-08-16 20:07:29 +00001622 FLAC__Subframe_Fixed *subframe = &decoder->private_->frame.subframes[channel].data.fixed;
Josh Coalson77e3f312001-06-23 03:03:24 +00001623 FLAC__int32 i32;
1624 FLAC__uint32 u32;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001625 unsigned u;
1626
Josh Coalsonfa697a92001-08-16 20:07:29 +00001627 decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_FIXED;
Josh Coalson6dcea512001-01-23 23:07:36 +00001628
Josh Coalsonfa697a92001-08-16 20:07:29 +00001629 subframe->residual = decoder->private_->residual[channel];
Josh Coalson6dcea512001-01-23 23:07:36 +00001630 subframe->order = order;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001631
1632 /* read warm-up samples */
1633 for(u = 0; u < order; u++) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001634 if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &i32, bps, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001635 return false; /* the read_callback_ sets the state for us */
Josh Coalson6dcea512001-01-23 23:07:36 +00001636 subframe->warmup[u] = i32;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001637 }
1638
1639 /* read entropy coding method info */
Josh Coalsonaec256b2002-03-12 16:19:54 +00001640 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001641 return false; /* the read_callback_ sets the state for us */
Josh Coalson6dcea512001-01-23 23:07:36 +00001642 subframe->entropy_coding_method.type = u32;
1643 switch(subframe->entropy_coding_method.type) {
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001644 case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
Josh Coalsonaec256b2002-03-12 16:19:54 +00001645 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001646 return false; /* the read_callback_ sets the state for us */
Josh Coalson6dcea512001-01-23 23:07:36 +00001647 subframe->entropy_coding_method.data.partitioned_rice.order = u32;
Josh Coalsona37ba462002-08-19 21:36:39 +00001648 subframe->entropy_coding_method.data.partitioned_rice.contents = &decoder->private_->partitioned_rice_contents[channel];
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001649 break;
1650 default:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001651 decoder->protected_->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001652 return false;
1653 }
1654
1655 /* read residual */
Josh Coalson6dcea512001-01-23 23:07:36 +00001656 switch(subframe->entropy_coding_method.type) {
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001657 case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
Josh Coalsona37ba462002-08-19 21:36:39 +00001658 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]))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001659 return false;
1660 break;
1661 default:
Josh Coalson1b689822001-05-31 20:11:02 +00001662 FLAC__ASSERT(0);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001663 }
1664
1665 /* decode the subframe */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001666 memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order);
1667 FLAC__fixed_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, order, decoder->private_->output[channel]+order);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001668
1669 return true;
1670}
1671
Josh Coalson570db862002-07-31 06:58:16 +00001672FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001673{
Josh Coalsonfa697a92001-08-16 20:07:29 +00001674 FLAC__Subframe_LPC *subframe = &decoder->private_->frame.subframes[channel].data.lpc;
Josh Coalson77e3f312001-06-23 03:03:24 +00001675 FLAC__int32 i32;
1676 FLAC__uint32 u32;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001677 unsigned u;
1678
Josh Coalsonfa697a92001-08-16 20:07:29 +00001679 decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_LPC;
Josh Coalson6dcea512001-01-23 23:07:36 +00001680
Josh Coalsonfa697a92001-08-16 20:07:29 +00001681 subframe->residual = decoder->private_->residual[channel];
Josh Coalson6dcea512001-01-23 23:07:36 +00001682 subframe->order = order;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001683
1684 /* read warm-up samples */
1685 for(u = 0; u < order; u++) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001686 if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &i32, bps, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001687 return false; /* the read_callback_ sets the state for us */
Josh Coalson6dcea512001-01-23 23:07:36 +00001688 subframe->warmup[u] = i32;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001689 }
1690
1691 /* read qlp coeff precision */
Josh Coalsonaec256b2002-03-12 16:19:54 +00001692 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &u32, FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001693 return false; /* the read_callback_ sets the state for us */
Josh Coalson3372cc02001-04-13 18:44:46 +00001694 if(u32 == (1u << FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN) - 1) {
Josh Coalson090f8f72002-06-04 05:53:04 +00001695 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, decoder->private_->client_data);
Josh Coalsonfa697a92001-08-16 20:07:29 +00001696 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001697 return true;
1698 }
Josh Coalson6dcea512001-01-23 23:07:36 +00001699 subframe->qlp_coeff_precision = u32+1;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001700
1701 /* read qlp shift */
Josh Coalsonaec256b2002-03-12 16:19:54 +00001702 if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &i32, FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001703 return false; /* the read_callback_ sets the state for us */
Josh Coalson6dcea512001-01-23 23:07:36 +00001704 subframe->quantization_level = i32;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001705
1706 /* read quantized lp coefficiencts */
1707 for(u = 0; u < order; u++) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001708 if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &i32, subframe->qlp_coeff_precision, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001709 return false; /* the read_callback_ sets the state for us */
Josh Coalson6dcea512001-01-23 23:07:36 +00001710 subframe->qlp_coeff[u] = i32;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001711 }
1712
1713 /* read entropy coding method info */
Josh Coalsonaec256b2002-03-12 16:19:54 +00001714 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001715 return false; /* the read_callback_ sets the state for us */
Josh Coalson6dcea512001-01-23 23:07:36 +00001716 subframe->entropy_coding_method.type = u32;
1717 switch(subframe->entropy_coding_method.type) {
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001718 case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
Josh Coalsonaec256b2002-03-12 16:19:54 +00001719 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001720 return false; /* the read_callback_ sets the state for us */
Josh Coalson6dcea512001-01-23 23:07:36 +00001721 subframe->entropy_coding_method.data.partitioned_rice.order = u32;
Josh Coalsona37ba462002-08-19 21:36:39 +00001722 subframe->entropy_coding_method.data.partitioned_rice.contents = &decoder->private_->partitioned_rice_contents[channel];
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001723 break;
1724 default:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001725 decoder->protected_->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001726 return false;
1727 }
1728
1729 /* read residual */
Josh Coalson6dcea512001-01-23 23:07:36 +00001730 switch(subframe->entropy_coding_method.type) {
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001731 case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
Josh Coalsona37ba462002-08-19 21:36:39 +00001732 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]))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001733 return false;
1734 break;
1735 default:
Josh Coalson1b689822001-05-31 20:11:02 +00001736 FLAC__ASSERT(0);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001737 }
1738
1739 /* decode the subframe */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001740 memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order);
Josh Coalsonfb9d18f2002-10-21 07:04:07 +00001741 if(bps + subframe->qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32)
1742 if(bps <= 16 && subframe->qlp_coeff_precision <= 16)
1743 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);
1744 else
1745 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);
Josh Coalsonb6a32192002-10-04 05:27:49 +00001746 else
1747 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);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001748
1749 return true;
1750}
1751
Josh Coalson570db862002-07-31 06:58:16 +00001752FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001753{
Josh Coalsonfa697a92001-08-16 20:07:29 +00001754 FLAC__Subframe_Verbatim *subframe = &decoder->private_->frame.subframes[channel].data.verbatim;
1755 FLAC__int32 x, *residual = decoder->private_->residual[channel];
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001756 unsigned i;
1757
Josh Coalsonfa697a92001-08-16 20:07:29 +00001758 decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_VERBATIM;
Josh Coalson6dcea512001-01-23 23:07:36 +00001759
Josh Coalsonb5e60e52001-01-28 09:27:27 +00001760 subframe->data = residual;
Josh Coalson6dcea512001-01-23 23:07:36 +00001761
Josh Coalsonfa697a92001-08-16 20:07:29 +00001762 for(i = 0; i < decoder->private_->frame.header.blocksize; i++) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001763 if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &x, bps, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001764 return false; /* the read_callback_ sets the state for us */
Josh Coalsonb5e60e52001-01-28 09:27:27 +00001765 residual[i] = x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001766 }
1767
Josh Coalson6dcea512001-01-23 23:07:36 +00001768 /* decode the subframe */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001769 memcpy(decoder->private_->output[channel], subframe->data, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize);
Josh Coalson6dcea512001-01-23 23:07:36 +00001770
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001771 return true;
1772}
1773
Josh Coalsona37ba462002-08-19 21:36:39 +00001774FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigned predictor_order, unsigned partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, FLAC__int32 *residual)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001775{
Josh Coalson77e3f312001-06-23 03:03:24 +00001776 FLAC__uint32 rice_parameter;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001777 int i;
1778 unsigned partition, sample, u;
1779 const unsigned partitions = 1u << partition_order;
Josh Coalsonfa697a92001-08-16 20:07:29 +00001780 const unsigned partition_samples = partition_order > 0? decoder->private_->frame.header.blocksize >> partition_order : decoder->private_->frame.header.blocksize - predictor_order;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001781
Josh Coalsona37ba462002-08-19 21:36:39 +00001782 if(!FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, max(6, partition_order))) {
Josh Coalsonb7023aa2002-08-17 15:23:43 +00001783 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
1784 return false;
1785 }
Josh Coalsonb7023aa2002-08-17 15:23:43 +00001786
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001787 sample = 0;
1788 for(partition = 0; partition < partitions; partition++) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001789 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001790 return false; /* the read_callback_ sets the state for us */
Josh Coalsona37ba462002-08-19 21:36:39 +00001791 partitioned_rice_contents->parameters[partition] = rice_parameter;
Josh Coalson2051dd42001-04-12 22:22:34 +00001792 if(rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) {
Josh Coalsonbb6712e2001-04-24 22:54:07 +00001793#ifdef FLAC__SYMMETRIC_RICE
Josh Coalsonb28559a2002-04-25 05:21:09 +00001794 for(u = (partition_order == 0 || partition > 0)? 0 : predictor_order; u < partition_samples; u++, sample++) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001795 if(!FLAC__bitbuffer_read_symmetric_rice_signed(decoder->private_->input, &i, rice_parameter, read_callback_, decoder))
Josh Coalson2051dd42001-04-12 22:22:34 +00001796 return false; /* the read_callback_ sets the state for us */
Josh Coalson2051dd42001-04-12 22:22:34 +00001797 residual[sample] = i;
1798 }
Josh Coalsonb28559a2002-04-25 05:21:09 +00001799#else
1800 u = (partition_order == 0 || partition > 0)? partition_samples : partition_samples - predictor_order;
1801 if(!FLAC__bitbuffer_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter, read_callback_, decoder))
1802 return false; /* the read_callback_ sets the state for us */
1803 sample += u;
1804#endif
Josh Coalson2051dd42001-04-12 22:22:34 +00001805 }
1806 else {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001807 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN, read_callback_, decoder))
Josh Coalson2051dd42001-04-12 22:22:34 +00001808 return false; /* the read_callback_ sets the state for us */
Josh Coalsona37ba462002-08-19 21:36:39 +00001809 partitioned_rice_contents->raw_bits[partition] = rice_parameter;
Josh Coalson2051dd42001-04-12 22:22:34 +00001810 for(u = (partition_order == 0 || partition > 0)? 0 : predictor_order; u < partition_samples; u++, sample++) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001811 if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &i, rice_parameter, read_callback_, decoder))
Josh Coalson2051dd42001-04-12 22:22:34 +00001812 return false; /* the read_callback_ sets the state for us */
1813 residual[sample] = i;
1814 }
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001815 }
1816 }
1817
1818 return true;
1819}
1820
Josh Coalson570db862002-07-31 06:58:16 +00001821FLAC__bool read_zero_padding_(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001822{
Josh Coalsonaec256b2002-03-12 16:19:54 +00001823 if(!FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input)) {
Josh Coalson77e3f312001-06-23 03:03:24 +00001824 FLAC__uint32 zero = 0;
Josh Coalsonaec256b2002-03-12 16:19:54 +00001825 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &zero, FLAC__bitbuffer_bits_left_for_byte_alignment(decoder->private_->input), read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001826 return false; /* the read_callback_ sets the state for us */
1827 if(zero != 0) {
Josh Coalson090f8f72002-06-04 05:53:04 +00001828 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, decoder->private_->client_data);
Josh Coalsonfa697a92001-08-16 20:07:29 +00001829 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001830 }
1831 }
1832 return true;
1833}
1834
Josh Coalson77e3f312001-06-23 03:03:24 +00001835FLAC__bool read_callback_(FLAC__byte buffer[], unsigned *bytes, void *client_data)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001836{
1837 FLAC__StreamDecoder *decoder = (FLAC__StreamDecoder *)client_data;
1838 FLAC__StreamDecoderReadStatus status;
Josh Coalsonaec256b2002-03-12 16:19:54 +00001839
Josh Coalsonfa697a92001-08-16 20:07:29 +00001840 status = decoder->private_->read_callback(decoder, buffer, bytes, decoder->private_->client_data);
Josh Coalson090f8f72002-06-04 05:53:04 +00001841 if(status == FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM)
Josh Coalsonfa697a92001-08-16 20:07:29 +00001842 decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM;
Josh Coalson090f8f72002-06-04 05:53:04 +00001843 else if(status == FLAC__STREAM_DECODER_READ_STATUS_ABORT)
Josh Coalsonfa697a92001-08-16 20:07:29 +00001844 decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED;
Josh Coalson090f8f72002-06-04 05:53:04 +00001845 return status == FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001846}