blob: 9a1672e292aa42d281407a0a668aed2b5d903ffd [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[]);
81 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 +000082 void *client_data;
Josh Coalsonaec256b2002-03-12 16:19:54 +000083 FLAC__BitBuffer *input;
Josh Coalson77e3f312001-06-23 03:03:24 +000084 FLAC__int32 *output[FLAC__MAX_CHANNELS];
85 FLAC__int32 *residual[FLAC__MAX_CHANNELS];
Josh Coalsona37ba462002-08-19 21:36:39 +000086 FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents[FLAC__MAX_CHANNELS];
Josh Coalson1e1509f2001-03-23 20:20:43 +000087 unsigned output_capacity, output_channels;
Josh Coalson77e3f312001-06-23 03:03:24 +000088 FLAC__uint32 last_frame_number;
89 FLAC__uint64 samples_decoded;
90 FLAC__bool has_stream_info, has_seek_table;
Josh Coalsoncc682512002-06-08 04:53:42 +000091 FLAC__StreamMetadata stream_info;
92 FLAC__StreamMetadata seek_table;
Josh Coalsonbf9325f2002-05-07 05:30:27 +000093 FLAC__bool metadata_filter[FLAC__METADATA_TYPE_VORBIS_COMMENT+1];
94 FLAC__byte *metadata_filter_ids;
95 unsigned metadata_filter_ids_count, metadata_filter_ids_capacity; /* units for both are IDs, not bytes */
Josh Coalson6dcea512001-01-23 23:07:36 +000096 FLAC__Frame frame;
Josh Coalson77e3f312001-06-23 03:03:24 +000097 FLAC__bool cached; /* true if there is a byte in lookahead */
Josh Coalsonb985bbc2001-05-23 21:59:52 +000098 FLAC__CPUInfo cpuinfo;
Josh Coalson77e3f312001-06-23 03:03:24 +000099 FLAC__byte header_warmup[2]; /* contains the sync code and reserved bits */
100 FLAC__byte lookahead; /* temp storage when we need to look ahead one byte in the stream */
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000101} FLAC__StreamDecoderPrivate;
102
Josh Coalson0a15c142001-06-13 17:59:57 +0000103/***********************************************************************
104 *
105 * Public static class data
106 *
107 ***********************************************************************/
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000108
Josh Coalson57ba6f42002-06-07 05:27:37 +0000109const char * const FLAC__StreamDecoderStateString[] = {
Josh Coalsoncbf595f2000-12-22 22:35:33 +0000110 "FLAC__STREAM_DECODER_SEARCH_FOR_METADATA",
111 "FLAC__STREAM_DECODER_READ_METADATA",
112 "FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC",
113 "FLAC__STREAM_DECODER_READ_FRAME",
Josh Coalsoncbf595f2000-12-22 22:35:33 +0000114 "FLAC__STREAM_DECODER_END_OF_STREAM",
115 "FLAC__STREAM_DECODER_ABORTED",
116 "FLAC__STREAM_DECODER_UNPARSEABLE_STREAM",
117 "FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR",
Josh Coalson0a15c142001-06-13 17:59:57 +0000118 "FLAC__STREAM_DECODER_ALREADY_INITIALIZED",
Josh Coalson00e53872001-06-16 07:32:25 +0000119 "FLAC__STREAM_DECODER_INVALID_CALLBACK",
Josh Coalsoncbf595f2000-12-22 22:35:33 +0000120 "FLAC__STREAM_DECODER_UNINITIALIZED"
121};
122
Josh Coalson57ba6f42002-06-07 05:27:37 +0000123const char * const FLAC__StreamDecoderReadStatusString[] = {
Josh Coalson090f8f72002-06-04 05:53:04 +0000124 "FLAC__STREAM_DECODER_READ_STATUS_CONTINUE",
125 "FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM",
126 "FLAC__STREAM_DECODER_READ_STATUS_ABORT"
Josh Coalsoncbf595f2000-12-22 22:35:33 +0000127};
128
Josh Coalson57ba6f42002-06-07 05:27:37 +0000129const char * const FLAC__StreamDecoderWriteStatusString[] = {
Josh Coalson090f8f72002-06-04 05:53:04 +0000130 "FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE",
131 "FLAC__STREAM_DECODER_WRITE_STATUS_ABORT"
Josh Coalsoncbf595f2000-12-22 22:35:33 +0000132};
133
Josh Coalson57ba6f42002-06-07 05:27:37 +0000134const char * const FLAC__StreamDecoderErrorStatusString[] = {
Josh Coalson090f8f72002-06-04 05:53:04 +0000135 "FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC",
136 "FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER",
137 "FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH"
Josh Coalsoncbf595f2000-12-22 22:35:33 +0000138};
139
Josh Coalson0a15c142001-06-13 17:59:57 +0000140/***********************************************************************
141 *
142 * Class constructor/destructor
143 *
144 ***********************************************************************/
145FLAC__StreamDecoder *FLAC__stream_decoder_new()
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000146{
Josh Coalson0a15c142001-06-13 17:59:57 +0000147 FLAC__StreamDecoder *decoder;
Josh Coalsonbc869502002-06-14 06:36:16 +0000148 unsigned i;
Josh Coalson0a15c142001-06-13 17:59:57 +0000149
150 FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
151
152 decoder = (FLAC__StreamDecoder*)malloc(sizeof(FLAC__StreamDecoder));
153 if(decoder == 0) {
154 return 0;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000155 }
Josh Coalsona7e4fb22002-08-03 22:05:11 +0000156 memset(decoder, 0, sizeof(FLAC__StreamDecoder));
157
Josh Coalsonfa697a92001-08-16 20:07:29 +0000158 decoder->protected_ = (FLAC__StreamDecoderProtected*)malloc(sizeof(FLAC__StreamDecoderProtected));
159 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 memset(decoder->protected_, 0, sizeof(FLAC__StreamDecoderProtected));
164
Josh Coalsonfa697a92001-08-16 20:07:29 +0000165 decoder->private_ = (FLAC__StreamDecoderPrivate*)malloc(sizeof(FLAC__StreamDecoderPrivate));
166 if(decoder->private_ == 0) {
167 free(decoder->protected_);
Josh Coalson0a15c142001-06-13 17:59:57 +0000168 free(decoder);
169 return 0;
170 }
Josh Coalsona7e4fb22002-08-03 22:05:11 +0000171 memset(decoder->private_, 0, sizeof(FLAC__StreamDecoderPrivate));
172
Josh Coalsonaec256b2002-03-12 16:19:54 +0000173 decoder->private_->input = FLAC__bitbuffer_new();
174 if(decoder->private_->input == 0) {
175 free(decoder->private_);
176 free(decoder->protected_);
177 free(decoder);
178 return 0;
179 }
Josh Coalson0a15c142001-06-13 17:59:57 +0000180
Josh Coalson6b02a752002-05-10 06:42:02 +0000181 decoder->private_->metadata_filter_ids_capacity = 16;
182 if(0 == (decoder->private_->metadata_filter_ids = malloc((FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) * decoder->private_->metadata_filter_ids_capacity))) {
183 FLAC__bitbuffer_delete(decoder->private_->input);
184 free(decoder->private_);
185 free(decoder->protected_);
186 free(decoder);
187 return 0;
188 }
Josh Coalson090f8f72002-06-04 05:53:04 +0000189
Josh Coalsonbc869502002-06-14 06:36:16 +0000190 for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
191 decoder->private_->output[i] = 0;
192 decoder->private_->residual[i] = 0;
193 }
194
195 decoder->private_->output_capacity = 0;
196 decoder->private_->output_channels = 0;
197 decoder->private_->has_seek_table = false;
Josh Coalsona37ba462002-08-19 21:36:39 +0000198
199 for(i = 0; i < FLAC__MAX_CHANNELS; i++)
200 FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&decoder->private_->partitioned_rice_contents[i]);
Josh Coalsonbc869502002-06-14 06:36:16 +0000201
Josh Coalson570db862002-07-31 06:58:16 +0000202 set_defaults_(decoder);
Josh Coalson6b02a752002-05-10 06:42:02 +0000203
Josh Coalsonbc869502002-06-14 06:36:16 +0000204 decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED;
205
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000206 return decoder;
207}
208
Josh Coalson0a15c142001-06-13 17:59:57 +0000209void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000210{
Josh Coalsona37ba462002-08-19 21:36:39 +0000211 unsigned i;
212
Josh Coalson570db862002-07-31 06:58:16 +0000213 FLAC__ASSERT(0 != decoder);
214 FLAC__ASSERT(0 != decoder->protected_);
215 FLAC__ASSERT(0 != decoder->private_);
216 FLAC__ASSERT(0 != decoder->private_->input);
Josh Coalson0a15c142001-06-13 17:59:57 +0000217
Josh Coalsonbc869502002-06-14 06:36:16 +0000218 FLAC__stream_decoder_finish(decoder);
219
Josh Coalson570db862002-07-31 06:58:16 +0000220 if(0 != decoder->private_->metadata_filter_ids)
Josh Coalson090f8f72002-06-04 05:53:04 +0000221 free(decoder->private_->metadata_filter_ids);
222
Josh Coalsonaec256b2002-03-12 16:19:54 +0000223 FLAC__bitbuffer_delete(decoder->private_->input);
Josh Coalsonb7023aa2002-08-17 15:23:43 +0000224
Josh Coalsona37ba462002-08-19 21:36:39 +0000225 for(i = 0; i < FLAC__MAX_CHANNELS; i++)
226 FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&decoder->private_->partitioned_rice_contents[i]);
Josh Coalsonb7023aa2002-08-17 15:23:43 +0000227
Josh Coalsonfa697a92001-08-16 20:07:29 +0000228 free(decoder->private_);
229 free(decoder->protected_);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000230 free(decoder);
231}
232
Josh Coalson0a15c142001-06-13 17:59:57 +0000233/***********************************************************************
234 *
235 * Public class methods
236 *
237 ***********************************************************************/
238
Josh Coalson00e53872001-06-16 07:32:25 +0000239FLAC__StreamDecoderState FLAC__stream_decoder_init(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000240{
Josh Coalson570db862002-07-31 06:58:16 +0000241 FLAC__ASSERT(0 != decoder);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000242
Josh Coalsonfa697a92001-08-16 20:07:29 +0000243 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
244 return decoder->protected_->state = FLAC__STREAM_DECODER_ALREADY_INITIALIZED;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000245
Josh Coalsonfa697a92001-08-16 20:07:29 +0000246 if(0 == decoder->private_->read_callback || 0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
247 return decoder->protected_->state = FLAC__STREAM_DECODER_INVALID_CALLBACK;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000248
Josh Coalsonaec256b2002-03-12 16:19:54 +0000249 if(!FLAC__bitbuffer_init(decoder->private_->input))
250 return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000251
Josh Coalsonfa697a92001-08-16 20:07:29 +0000252 decoder->private_->last_frame_number = 0;
253 decoder->private_->samples_decoded = 0;
254 decoder->private_->has_stream_info = false;
Josh Coalsonfa697a92001-08-16 20:07:29 +0000255 decoder->private_->cached = false;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000256
Josh Coalsonb985bbc2001-05-23 21:59:52 +0000257 /*
258 * get the CPU info and set the function pointers
259 */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000260 FLAC__cpu_info(&decoder->private_->cpuinfo);
Josh Coalsonb985bbc2001-05-23 21:59:52 +0000261 /* first default to the non-asm routines */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000262 decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal;
263 decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal;
Josh Coalsonb985bbc2001-05-23 21:59:52 +0000264 /* now override with asm where appropriate */
Josh Coalsona3f7c2c2001-05-25 00:04:45 +0000265#ifndef FLAC__NO_ASM
Josh Coalsonfa697a92001-08-16 20:07:29 +0000266 if(decoder->private_->cpuinfo.use_asm) {
Josh Coalsonb985bbc2001-05-23 21:59:52 +0000267#ifdef FLAC__CPU_IA32
Josh Coalsonfa697a92001-08-16 20:07:29 +0000268 FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32);
Josh Coalson034d38e2001-05-24 19:29:30 +0000269#ifdef FLAC__HAS_NASM
Josh Coalsonfa697a92001-08-16 20:07:29 +0000270 if(decoder->private_->cpuinfo.data.ia32.mmx) {
271 decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32;
272 decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32_mmx;
Josh Coalson021ad3b2001-07-18 00:25:52 +0000273 }
274 else {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000275 decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32;
276 decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32;
Josh Coalson021ad3b2001-07-18 00:25:52 +0000277 }
Josh Coalsonb985bbc2001-05-23 21:59:52 +0000278#endif
Josh Coalson034d38e2001-05-24 19:29:30 +0000279#endif
Josh Coalson021ad3b2001-07-18 00:25:52 +0000280 }
Josh Coalsona3f7c2c2001-05-25 00:04:45 +0000281#endif
Josh Coalsonb985bbc2001-05-23 21:59:52 +0000282
Josh Coalsoncfdfc822002-08-02 06:12:36 +0000283 if(!FLAC__stream_decoder_reset(decoder))
284 return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
285
286 return decoder->protected_->state;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000287}
288
289void FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder)
290{
291 unsigned i;
Josh Coalson570db862002-07-31 06:58:16 +0000292 FLAC__ASSERT(0 != decoder);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000293 if(decoder->protected_->state == FLAC__STREAM_DECODER_UNINITIALIZED)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000294 return;
Josh Coalsonfa697a92001-08-16 20:07:29 +0000295 if(decoder->private_->has_seek_table) {
Josh Coalson570db862002-07-31 06:58:16 +0000296 FLAC__ASSERT(0 != decoder->private_->seek_table.data.seek_table.points);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000297 free(decoder->private_->seek_table.data.seek_table.points);
298 decoder->private_->seek_table.data.seek_table.points = 0;
Josh Coalsonbc869502002-06-14 06:36:16 +0000299 decoder->private_->has_seek_table = false;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000300 }
Josh Coalsonaec256b2002-03-12 16:19:54 +0000301 FLAC__bitbuffer_free(decoder->private_->input);
Josh Coalson0a15c142001-06-13 17:59:57 +0000302 for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
Josh Coalsonb7023aa2002-08-17 15:23:43 +0000303 /* WATCHOUT:
304 * FLAC__lpc_restore_signal_asm_ia32_mmx() requires that the
305 * output arrays have a buffer of up to 3 zeroes in front
306 * (at negative indices) for alignment purposes; we use 4
307 * to keep the data well-aligned.
308 */
Josh Coalson570db862002-07-31 06:58:16 +0000309 if(0 != decoder->private_->output[i]) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000310 free(decoder->private_->output[i]-4);
311 decoder->private_->output[i] = 0;
Josh Coalson0a15c142001-06-13 17:59:57 +0000312 }
Josh Coalson570db862002-07-31 06:58:16 +0000313 if(0 != decoder->private_->residual[i]) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000314 free(decoder->private_->residual[i]);
315 decoder->private_->residual[i] = 0;
Josh Coalson0a15c142001-06-13 17:59:57 +0000316 }
317 }
Josh Coalsonfa697a92001-08-16 20:07:29 +0000318 decoder->private_->output_capacity = 0;
319 decoder->private_->output_channels = 0;
Josh Coalson090f8f72002-06-04 05:53:04 +0000320
Josh Coalson570db862002-07-31 06:58:16 +0000321 set_defaults_(decoder);
Josh Coalson090f8f72002-06-04 05:53:04 +0000322
Josh Coalsonfa697a92001-08-16 20:07:29 +0000323 decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED;
Josh Coalson0a15c142001-06-13 17:59:57 +0000324}
325
Josh Coalson681c2932002-08-01 08:19:37 +0000326FLAC__bool FLAC__stream_decoder_set_read_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderReadCallback value)
Josh Coalson00e53872001-06-16 07:32:25 +0000327{
Josh Coalson570db862002-07-31 06:58:16 +0000328 FLAC__ASSERT(0 != decoder);
329 FLAC__ASSERT(0 != decoder->private_);
330 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000331 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
Josh Coalson00e53872001-06-16 07:32:25 +0000332 return false;
Josh Coalsonfa697a92001-08-16 20:07:29 +0000333 decoder->private_->read_callback = value;
Josh Coalson00e53872001-06-16 07:32:25 +0000334 return true;
335}
336
Josh Coalson681c2932002-08-01 08:19:37 +0000337FLAC__bool FLAC__stream_decoder_set_write_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderWriteCallback value)
Josh Coalson00e53872001-06-16 07:32:25 +0000338{
Josh Coalson570db862002-07-31 06:58:16 +0000339 FLAC__ASSERT(0 != decoder);
340 FLAC__ASSERT(0 != decoder->private_);
341 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000342 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
Josh Coalson00e53872001-06-16 07:32:25 +0000343 return false;
Josh Coalsonfa697a92001-08-16 20:07:29 +0000344 decoder->private_->write_callback = value;
Josh Coalson00e53872001-06-16 07:32:25 +0000345 return true;
346}
347
Josh Coalson681c2932002-08-01 08:19:37 +0000348FLAC__bool FLAC__stream_decoder_set_metadata_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderMetadataCallback value)
Josh Coalson00e53872001-06-16 07:32:25 +0000349{
Josh Coalson570db862002-07-31 06:58:16 +0000350 FLAC__ASSERT(0 != decoder);
351 FLAC__ASSERT(0 != decoder->private_);
352 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000353 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
Josh Coalson00e53872001-06-16 07:32:25 +0000354 return false;
Josh Coalsonfa697a92001-08-16 20:07:29 +0000355 decoder->private_->metadata_callback = value;
Josh Coalson00e53872001-06-16 07:32:25 +0000356 return true;
357}
358
Josh Coalson681c2932002-08-01 08:19:37 +0000359FLAC__bool FLAC__stream_decoder_set_error_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorCallback value)
Josh Coalson00e53872001-06-16 07:32:25 +0000360{
Josh Coalson570db862002-07-31 06:58:16 +0000361 FLAC__ASSERT(0 != decoder);
362 FLAC__ASSERT(0 != decoder->private_);
363 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000364 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
Josh Coalson00e53872001-06-16 07:32:25 +0000365 return false;
Josh Coalsonfa697a92001-08-16 20:07:29 +0000366 decoder->private_->error_callback = value;
Josh Coalson00e53872001-06-16 07:32:25 +0000367 return true;
368}
369
Josh Coalson16556042002-05-29 05:51:24 +0000370FLAC__bool FLAC__stream_decoder_set_client_data(FLAC__StreamDecoder *decoder, void *value)
Josh Coalson00e53872001-06-16 07:32:25 +0000371{
Josh Coalson570db862002-07-31 06:58:16 +0000372 FLAC__ASSERT(0 != decoder);
373 FLAC__ASSERT(0 != decoder->private_);
374 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000375 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
Josh Coalson00e53872001-06-16 07:32:25 +0000376 return false;
Josh Coalsonfa697a92001-08-16 20:07:29 +0000377 decoder->private_->client_data = value;
Josh Coalson00e53872001-06-16 07:32:25 +0000378 return true;
379}
380
Josh Coalsoncc682512002-06-08 04:53:42 +0000381FLAC__bool FLAC__stream_decoder_set_metadata_respond(FLAC__StreamDecoder *decoder, FLAC__MetadataType type)
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000382{
Josh Coalson570db862002-07-31 06:58:16 +0000383 FLAC__ASSERT(0 != decoder);
384 FLAC__ASSERT(0 != decoder->private_);
385 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000386 FLAC__ASSERT(type <= FLAC__METADATA_TYPE_VORBIS_COMMENT);
387 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
388 return false;
389 decoder->private_->metadata_filter[type] = true;
390 if(type == FLAC__METADATA_TYPE_APPLICATION)
391 decoder->private_->metadata_filter_ids_count = 0;
392 return true;
393}
394
Josh Coalson16556042002-05-29 05:51:24 +0000395FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4])
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000396{
Josh Coalson570db862002-07-31 06:58:16 +0000397 FLAC__ASSERT(0 != decoder);
398 FLAC__ASSERT(0 != decoder->private_);
399 FLAC__ASSERT(0 != decoder->protected_);
400 FLAC__ASSERT(0 != id);
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000401 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
402 return false;
403
404 if(decoder->private_->metadata_filter[FLAC__METADATA_TYPE_APPLICATION])
405 return true;
406
407 FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids);
408
409 if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) {
410 if(0 == (decoder->private_->metadata_filter_ids = realloc(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity * 2)))
411 return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
412 decoder->private_->metadata_filter_ids_capacity *= 2;
413 }
414
415 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));
416 decoder->private_->metadata_filter_ids_count++;
417
418 return true;
419}
420
Josh Coalson16556042002-05-29 05:51:24 +0000421FLAC__bool FLAC__stream_decoder_set_metadata_respond_all(FLAC__StreamDecoder *decoder)
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000422{
Josh Coalson090f8f72002-06-04 05:53:04 +0000423 unsigned i;
Josh Coalson570db862002-07-31 06:58:16 +0000424 FLAC__ASSERT(0 != decoder);
425 FLAC__ASSERT(0 != decoder->private_);
426 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000427 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
428 return false;
Josh Coalson090f8f72002-06-04 05:53:04 +0000429 for(i = 0; i < sizeof(decoder->private_->metadata_filter) / sizeof(decoder->private_->metadata_filter[0]); i++)
430 decoder->private_->metadata_filter[i] = true;
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000431 decoder->private_->metadata_filter_ids_count = 0;
432 return true;
433}
434
Josh Coalsoncc682512002-06-08 04:53:42 +0000435FLAC__bool FLAC__stream_decoder_set_metadata_ignore(FLAC__StreamDecoder *decoder, FLAC__MetadataType type)
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000436{
Josh Coalson570db862002-07-31 06:58:16 +0000437 FLAC__ASSERT(0 != decoder);
438 FLAC__ASSERT(0 != decoder->private_);
439 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000440 FLAC__ASSERT(type <= FLAC__METADATA_TYPE_VORBIS_COMMENT);
441 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
442 return false;
443 decoder->private_->metadata_filter[type] = false;
444 if(type == FLAC__METADATA_TYPE_APPLICATION)
445 decoder->private_->metadata_filter_ids_count = 0;
446 return true;
447}
448
Josh Coalson16556042002-05-29 05:51:24 +0000449FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4])
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000450{
Josh Coalson570db862002-07-31 06:58:16 +0000451 FLAC__ASSERT(0 != decoder);
452 FLAC__ASSERT(0 != decoder->private_);
453 FLAC__ASSERT(0 != decoder->protected_);
454 FLAC__ASSERT(0 != id);
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000455 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
456 return false;
457
458 if(!decoder->private_->metadata_filter[FLAC__METADATA_TYPE_APPLICATION])
459 return true;
460
461 FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids);
462
463 if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) {
464 if(0 == (decoder->private_->metadata_filter_ids = realloc(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity * 2)))
465 return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
466 decoder->private_->metadata_filter_ids_capacity *= 2;
467 }
468
469 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));
470 decoder->private_->metadata_filter_ids_count++;
471
472 return true;
473}
474
Josh Coalson16556042002-05-29 05:51:24 +0000475FLAC__bool FLAC__stream_decoder_set_metadata_ignore_all(FLAC__StreamDecoder *decoder)
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000476{
Josh Coalson570db862002-07-31 06:58:16 +0000477 FLAC__ASSERT(0 != decoder);
478 FLAC__ASSERT(0 != decoder->private_);
479 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000480 if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED)
481 return false;
482 memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter));
483 decoder->private_->metadata_filter_ids_count = 0;
484 return true;
485}
486
Josh Coalson00e53872001-06-16 07:32:25 +0000487FLAC__StreamDecoderState FLAC__stream_decoder_get_state(const FLAC__StreamDecoder *decoder)
Josh Coalson0a15c142001-06-13 17:59:57 +0000488{
Josh Coalson570db862002-07-31 06:58:16 +0000489 FLAC__ASSERT(0 != decoder);
490 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000491 return decoder->protected_->state;
Josh Coalson0a15c142001-06-13 17:59:57 +0000492}
493
Josh Coalson00e53872001-06-16 07:32:25 +0000494unsigned FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder)
Josh Coalson0a15c142001-06-13 17:59:57 +0000495{
Josh Coalson570db862002-07-31 06:58:16 +0000496 FLAC__ASSERT(0 != decoder);
497 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000498 return decoder->protected_->channels;
Josh Coalson0a15c142001-06-13 17:59:57 +0000499}
500
Josh Coalson00e53872001-06-16 07:32:25 +0000501FLAC__ChannelAssignment FLAC__stream_decoder_get_channel_assignment(const FLAC__StreamDecoder *decoder)
Josh Coalson0a15c142001-06-13 17:59:57 +0000502{
Josh Coalson570db862002-07-31 06:58:16 +0000503 FLAC__ASSERT(0 != decoder);
504 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000505 return decoder->protected_->channel_assignment;
Josh Coalson0a15c142001-06-13 17:59:57 +0000506}
507
Josh Coalson00e53872001-06-16 07:32:25 +0000508unsigned FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder)
Josh Coalson0a15c142001-06-13 17:59:57 +0000509{
Josh Coalson570db862002-07-31 06:58:16 +0000510 FLAC__ASSERT(0 != decoder);
511 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000512 return decoder->protected_->bits_per_sample;
Josh Coalson0a15c142001-06-13 17:59:57 +0000513}
514
Josh Coalson00e53872001-06-16 07:32:25 +0000515unsigned FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder)
Josh Coalson0a15c142001-06-13 17:59:57 +0000516{
Josh Coalson570db862002-07-31 06:58:16 +0000517 FLAC__ASSERT(0 != decoder);
518 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000519 return decoder->protected_->sample_rate;
Josh Coalson0a15c142001-06-13 17:59:57 +0000520}
521
Josh Coalson00e53872001-06-16 07:32:25 +0000522unsigned FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder *decoder)
Josh Coalson0a15c142001-06-13 17:59:57 +0000523{
Josh Coalson570db862002-07-31 06:58:16 +0000524 FLAC__ASSERT(0 != decoder);
525 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000526 return decoder->protected_->blocksize;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000527}
528
Josh Coalson77e3f312001-06-23 03:03:24 +0000529FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000530{
Josh Coalson570db862002-07-31 06:58:16 +0000531 FLAC__ASSERT(0 != decoder);
532 FLAC__ASSERT(0 != decoder->private_);
533 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000534
Josh Coalsonaec256b2002-03-12 16:19:54 +0000535 if(!FLAC__bitbuffer_clear(decoder->private_->input)) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000536 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000537 return false;
538 }
Josh Coalsonb312f282001-11-01 05:23:48 +0000539 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000540
541 return true;
542}
543
Josh Coalson77e3f312001-06-23 03:03:24 +0000544FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000545{
Josh Coalson570db862002-07-31 06:58:16 +0000546 FLAC__ASSERT(0 != decoder);
547 FLAC__ASSERT(0 != decoder->private_);
548 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000549
550 if(!FLAC__stream_decoder_flush(decoder)) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000551 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000552 return false;
553 }
Josh Coalsonfa697a92001-08-16 20:07:29 +0000554 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_METADATA;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000555
Josh Coalsonfa697a92001-08-16 20:07:29 +0000556 decoder->private_->samples_decoded = 0;
Josh Coalson671fadb2001-04-17 17:32:01 +0000557
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000558 return true;
559}
560
Josh Coalsoncfdfc822002-08-02 06:12:36 +0000561FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000562{
Josh Coalson77e3f312001-06-23 03:03:24 +0000563 FLAC__bool got_a_frame;
Josh Coalson570db862002-07-31 06:58:16 +0000564 FLAC__ASSERT(0 != decoder);
Josh Coalsoncfdfc822002-08-02 06:12:36 +0000565 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000566
567 while(1) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000568 switch(decoder->protected_->state) {
Josh Coalsoncfdfc822002-08-02 06:12:36 +0000569 case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
570 if(!find_metadata_(decoder))
571 return false; /* above function sets the status for us */
572 break;
573 case FLAC__STREAM_DECODER_READ_METADATA:
574 if(!read_metadata_(decoder))
575 return false; /* above function sets the status for us */
576 else
577 return true;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000578 case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
Josh Coalson570db862002-07-31 06:58:16 +0000579 if(!frame_sync_(decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000580 return true; /* above function sets the status for us */
581 break;
582 case FLAC__STREAM_DECODER_READ_FRAME:
Josh Coalson570db862002-07-31 06:58:16 +0000583 if(!read_frame_(decoder, &got_a_frame))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000584 return false; /* above function sets the status for us */
585 if(got_a_frame)
586 return true; /* above function sets the status for us */
587 break;
588 case FLAC__STREAM_DECODER_END_OF_STREAM:
Josh Coalson93df7e02002-07-24 06:08:37 +0000589 case FLAC__STREAM_DECODER_ABORTED:
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000590 return true;
591 default:
Josh Coalson1b689822001-05-31 20:11:02 +0000592 FLAC__ASSERT(0);
Josh Coalsoncfdfc822002-08-02 06:12:36 +0000593 return false;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000594 }
595 }
596}
597
Josh Coalsoncfdfc822002-08-02 06:12:36 +0000598FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000599{
Josh Coalson570db862002-07-31 06:58:16 +0000600 FLAC__ASSERT(0 != decoder);
Josh Coalsoncfdfc822002-08-02 06:12:36 +0000601 FLAC__ASSERT(0 != decoder->protected_);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000602
603 while(1) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000604 switch(decoder->protected_->state) {
Josh Coalsoncfdfc822002-08-02 06:12:36 +0000605 case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
606 if(!find_metadata_(decoder))
607 return false; /* above function sets the status for us */
608 break;
609 case FLAC__STREAM_DECODER_READ_METADATA:
610 if(!read_metadata_(decoder))
611 return false; /* above function sets the status for us */
612 break;
613 case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
614 case FLAC__STREAM_DECODER_READ_FRAME:
615 case FLAC__STREAM_DECODER_END_OF_STREAM:
616 case FLAC__STREAM_DECODER_ABORTED:
617 return true;
618 default:
619 FLAC__ASSERT(0);
620 return false;
621 }
622 }
623}
624
625FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder)
626{
627 FLAC__bool dummy;
628 FLAC__ASSERT(0 != decoder);
629 FLAC__ASSERT(0 != decoder->protected_);
630
631 while(1) {
632 switch(decoder->protected_->state) {
633 case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
634 if(!find_metadata_(decoder))
635 return false; /* above function sets the status for us */
636 break;
637 case FLAC__STREAM_DECODER_READ_METADATA:
638 if(!read_metadata_(decoder))
639 return false; /* above function sets the status for us */
640 break;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000641 case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
Josh Coalson570db862002-07-31 06:58:16 +0000642 if(!frame_sync_(decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000643 return true; /* above function sets the status for us */
644 break;
645 case FLAC__STREAM_DECODER_READ_FRAME:
Josh Coalson570db862002-07-31 06:58:16 +0000646 if(!read_frame_(decoder, &dummy))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000647 return false; /* above function sets the status for us */
648 break;
649 case FLAC__STREAM_DECODER_END_OF_STREAM:
Josh Coalson93df7e02002-07-24 06:08:37 +0000650 case FLAC__STREAM_DECODER_ABORTED:
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000651 return true;
652 default:
Josh Coalson1b689822001-05-31 20:11:02 +0000653 FLAC__ASSERT(0);
Josh Coalsoncfdfc822002-08-02 06:12:36 +0000654 return false;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000655 }
656 }
657}
658
Josh Coalson0a15c142001-06-13 17:59:57 +0000659/***********************************************************************
660 *
661 * Protected class methods
662 *
663 ***********************************************************************/
664
Josh Coalson00e53872001-06-16 07:32:25 +0000665unsigned FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000666{
Josh Coalson570db862002-07-31 06:58:16 +0000667 FLAC__ASSERT(0 != decoder);
Josh Coalsonaec256b2002-03-12 16:19:54 +0000668 return FLAC__bitbuffer_get_input_bytes_unconsumed(decoder->private_->input);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000669}
670
Josh Coalson0a15c142001-06-13 17:59:57 +0000671/***********************************************************************
672 *
673 * Private class methods
674 *
675 ***********************************************************************/
676
Josh Coalson570db862002-07-31 06:58:16 +0000677void set_defaults_(FLAC__StreamDecoder *decoder)
Josh Coalson090f8f72002-06-04 05:53:04 +0000678{
679 decoder->private_->read_callback = 0;
680 decoder->private_->write_callback = 0;
681 decoder->private_->metadata_callback = 0;
682 decoder->private_->error_callback = 0;
683 decoder->private_->client_data = 0;
684
685 memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter));
686 decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO] = true;
687 decoder->private_->metadata_filter_ids_count = 0;
688}
689
Josh Coalson570db862002-07-31 06:58:16 +0000690FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigned channels)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000691{
692 unsigned i;
Josh Coalson77e3f312001-06-23 03:03:24 +0000693 FLAC__int32 *tmp;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000694
Josh Coalsonfa697a92001-08-16 20:07:29 +0000695 if(size <= decoder->private_->output_capacity && channels <= decoder->private_->output_channels)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000696 return true;
697
Josh Coalson5dcb57d2002-09-04 07:59:02 +0000698 /* simply using realloc() is not practical because the number of channels may change mid-stream */
Josh Coalson6dcea512001-01-23 23:07:36 +0000699
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000700 for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
Josh Coalson570db862002-07-31 06:58:16 +0000701 if(0 != decoder->private_->output[i]) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000702 free(decoder->private_->output[i]);
703 decoder->private_->output[i] = 0;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000704 }
Josh Coalson570db862002-07-31 06:58:16 +0000705 if(0 != decoder->private_->residual[i]) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000706 free(decoder->private_->residual[i]);
707 decoder->private_->residual[i] = 0;
Josh Coalson6dcea512001-01-23 23:07:36 +0000708 }
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000709 }
710
Josh Coalson1e1509f2001-03-23 20:20:43 +0000711 for(i = 0; i < channels; i++) {
Josh Coalsonb7023aa2002-08-17 15:23:43 +0000712 /* WATCHOUT:
713 * FLAC__lpc_restore_signal_asm_ia32_mmx() requires that the
714 * output arrays have a buffer of up to 3 zeroes in front
715 * (at negative indices) for alignment purposes; we use 4
716 * to keep the data well-aligned.
717 */
Josh Coalson63d99572001-07-12 21:26:57 +0000718 tmp = (FLAC__int32*)malloc(sizeof(FLAC__int32)*(size+4));
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000719 if(tmp == 0) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000720 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000721 return false;
722 }
Josh Coalson63d99572001-07-12 21:26:57 +0000723 memset(tmp, 0, sizeof(FLAC__int32)*4);
Josh Coalsonfa697a92001-08-16 20:07:29 +0000724 decoder->private_->output[i] = tmp + 4;
Josh Coalson6dcea512001-01-23 23:07:36 +0000725
Josh Coalson77e3f312001-06-23 03:03:24 +0000726 tmp = (FLAC__int32*)malloc(sizeof(FLAC__int32)*size);
Josh Coalson6dcea512001-01-23 23:07:36 +0000727 if(tmp == 0) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000728 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
Josh Coalson6dcea512001-01-23 23:07:36 +0000729 return false;
730 }
Josh Coalsonfa697a92001-08-16 20:07:29 +0000731 decoder->private_->residual[i] = tmp;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000732 }
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000733
Josh Coalsonfa697a92001-08-16 20:07:29 +0000734 decoder->private_->output_capacity = size;
735 decoder->private_->output_channels = channels;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000736
737 return true;
738}
739
Josh Coalson570db862002-07-31 06:58:16 +0000740FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id)
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000741{
742 unsigned i;
743
744 FLAC__ASSERT(0 != decoder);
745 FLAC__ASSERT(0 != decoder->private_);
746
747 for(i = 0; i < decoder->private_->metadata_filter_ids_count; i++)
748 if(0 == memcmp(decoder->private_->metadata_filter_ids + i * (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), id, (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8)))
749 return true;
750
751 return false;
752}
753
Josh Coalson570db862002-07-31 06:58:16 +0000754FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000755{
Josh Coalson77e3f312001-06-23 03:03:24 +0000756 FLAC__uint32 x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000757 unsigned i, id;
Josh Coalson77e3f312001-06-23 03:03:24 +0000758 FLAC__bool first = true;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000759
Josh Coalsonaec256b2002-03-12 16:19:54 +0000760 FLAC__ASSERT(FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input));
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000761
762 for(i = id = 0; i < 4; ) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000763 if(decoder->private_->cached) {
764 x = (FLAC__uint32)decoder->private_->lookahead;
765 decoder->private_->cached = false;
Josh Coalson215af572001-03-27 01:15:58 +0000766 }
767 else {
Josh Coalsonaec256b2002-03-12 16:19:54 +0000768 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder))
Josh Coalson215af572001-03-27 01:15:58 +0000769 return false; /* the read_callback_ sets the state for us */
770 }
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000771 if(x == FLAC__STREAM_SYNC_STRING[i]) {
Josh Coalson215af572001-03-27 01:15:58 +0000772 first = true;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000773 i++;
774 id = 0;
775 continue;
776 }
777 if(x == ID3V2_TAG_[id]) {
778 id++;
779 i = 0;
780 if(id == 3) {
Josh Coalson570db862002-07-31 06:58:16 +0000781 if(!skip_id3v2_tag_(decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000782 return false; /* the read_callback_ sets the state for us */
783 }
784 continue;
785 }
786 if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000787 decoder->private_->header_warmup[0] = (FLAC__byte)x;
Josh Coalsonaec256b2002-03-12 16:19:54 +0000788 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000789 return false; /* the read_callback_ sets the state for us */
Josh Coalson215af572001-03-27 01:15:58 +0000790
791 /* 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 */
792 /* else we have to check if the second byte is the end of a sync code */
793 if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000794 decoder->private_->lookahead = (FLAC__byte)x;
795 decoder->private_->cached = true;
Josh Coalson215af572001-03-27 01:15:58 +0000796 }
797 else if(x >> 2 == 0x3e) { /* MAGIC NUMBER for the last 6 sync bits */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000798 decoder->private_->header_warmup[1] = (FLAC__byte)x;
799 decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000800 return true;
801 }
802 }
803 i = 0;
804 if(first) {
Josh Coalson090f8f72002-06-04 05:53:04 +0000805 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, decoder->private_->client_data);
Josh Coalson215af572001-03-27 01:15:58 +0000806 first = false;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000807 }
808 }
809
Josh Coalsonfa697a92001-08-16 20:07:29 +0000810 decoder->protected_->state = FLAC__STREAM_DECODER_READ_METADATA;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000811 return true;
812}
813
Josh Coalson570db862002-07-31 06:58:16 +0000814FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000815{
Josh Coalson77e3f312001-06-23 03:03:24 +0000816 FLAC__uint32 i, x, last_block, type, length;
817 FLAC__uint64 xx;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000818
Josh Coalsonaec256b2002-03-12 16:19:54 +0000819 FLAC__ASSERT(FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input));
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000820
Josh Coalsonaec256b2002-03-12 16:19:54 +0000821 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 +0000822 return false; /* the read_callback_ sets the state for us */
Josh Coalsonaec256b2002-03-12 16:19:54 +0000823 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 +0000824 return false; /* the read_callback_ sets the state for us */
Josh Coalsonaec256b2002-03-12 16:19:54 +0000825 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 +0000826 return false; /* the read_callback_ sets the state for us */
Josh Coalson72983922001-02-23 21:03:21 +0000827 if(type == FLAC__METADATA_TYPE_STREAMINFO) {
Josh Coalson841e27e2001-01-03 00:26:42 +0000828 unsigned used_bits = 0;
Josh Coalsonfa697a92001-08-16 20:07:29 +0000829 decoder->private_->stream_info.type = type;
830 decoder->private_->stream_info.is_last = last_block;
831 decoder->private_->stream_info.length = length;
Josh Coalson841e27e2001-01-03 00:26:42 +0000832
Josh Coalsonaec256b2002-03-12 16:19:54 +0000833 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 +0000834 return false; /* the read_callback_ sets the state for us */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000835 decoder->private_->stream_info.data.stream_info.min_blocksize = x;
Josh Coalson72983922001-02-23 21:03:21 +0000836 used_bits += FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN;
Josh Coalson841e27e2001-01-03 00:26:42 +0000837
Josh Coalsonaec256b2002-03-12 16:19:54 +0000838 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 +0000839 return false; /* the read_callback_ sets the state for us */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000840 decoder->private_->stream_info.data.stream_info.max_blocksize = x;
Josh Coalson72983922001-02-23 21:03:21 +0000841 used_bits += FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN;
Josh Coalson841e27e2001-01-03 00:26:42 +0000842
Josh Coalsonaec256b2002-03-12 16:19:54 +0000843 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 +0000844 return false; /* the read_callback_ sets the state for us */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000845 decoder->private_->stream_info.data.stream_info.min_framesize = x;
Josh Coalson72983922001-02-23 21:03:21 +0000846 used_bits += FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN;
Josh Coalson841e27e2001-01-03 00:26:42 +0000847
Josh Coalsonaec256b2002-03-12 16:19:54 +0000848 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 +0000849 return false; /* the read_callback_ sets the state for us */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000850 decoder->private_->stream_info.data.stream_info.max_framesize = x;
Josh Coalson72983922001-02-23 21:03:21 +0000851 used_bits += FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN;
Josh Coalson841e27e2001-01-03 00:26:42 +0000852
Josh Coalsonaec256b2002-03-12 16:19:54 +0000853 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 +0000854 return false; /* the read_callback_ sets the state for us */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000855 decoder->private_->stream_info.data.stream_info.sample_rate = x;
Josh Coalson72983922001-02-23 21:03:21 +0000856 used_bits += FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN;
Josh Coalson841e27e2001-01-03 00:26:42 +0000857
Josh Coalsonaec256b2002-03-12 16:19:54 +0000858 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 +0000859 return false; /* the read_callback_ sets the state for us */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000860 decoder->private_->stream_info.data.stream_info.channels = x+1;
Josh Coalson72983922001-02-23 21:03:21 +0000861 used_bits += FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN;
Josh Coalson841e27e2001-01-03 00:26:42 +0000862
Josh Coalsonaec256b2002-03-12 16:19:54 +0000863 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 +0000864 return false; /* the read_callback_ sets the state for us */
Josh Coalsonfa697a92001-08-16 20:07:29 +0000865 decoder->private_->stream_info.data.stream_info.bits_per_sample = x+1;
Josh Coalson72983922001-02-23 21:03:21 +0000866 used_bits += FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN;
Josh Coalson841e27e2001-01-03 00:26:42 +0000867
Josh Coalsonaec256b2002-03-12 16:19:54 +0000868 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 +0000869 return false; /* the read_callback_ sets the state for us */
Josh Coalson72983922001-02-23 21:03:21 +0000870 used_bits += FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN;
Josh Coalson841e27e2001-01-03 00:26:42 +0000871
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000872 if(!FLAC__bitbuffer_read_byte_block_aligned(decoder->private_->input, decoder->private_->stream_info.data.stream_info.md5sum, 16, read_callback_, decoder))
873 return false; /* the read_callback_ sets the state for us */
874 used_bits += 16*8;
Josh Coalsonfa37f1c2001-01-12 23:55:11 +0000875
Josh Coalson841e27e2001-01-03 00:26:42 +0000876 /* skip the rest of the block */
Josh Coalson1b689822001-05-31 20:11:02 +0000877 FLAC__ASSERT(used_bits % 8 == 0);
Josh Coalson841e27e2001-01-03 00:26:42 +0000878 length -= (used_bits / 8);
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000879 if(!FLAC__bitbuffer_read_byte_block_aligned(decoder->private_->input, 0, length, read_callback_, decoder))
880 return false; /* the read_callback_ sets the state for us */
Josh Coalson841e27e2001-01-03 00:26:42 +0000881
Josh Coalsonfa697a92001-08-16 20:07:29 +0000882 decoder->private_->has_stream_info = true;
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000883 if(decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO])
884 decoder->private_->metadata_callback(decoder, &decoder->private_->stream_info, decoder->private_->client_data);
Josh Coalsonc076ba52001-04-05 21:32:54 +0000885 }
886 else if(type == FLAC__METADATA_TYPE_SEEKTABLE) {
Josh Coalsonfa697a92001-08-16 20:07:29 +0000887 decoder->private_->seek_table.type = type;
888 decoder->private_->seek_table.is_last = last_block;
889 decoder->private_->seek_table.length = length;
Josh Coalsonc076ba52001-04-05 21:32:54 +0000890
Josh Coalsonf145bbd2002-05-04 17:37:51 +0000891 decoder->private_->seek_table.data.seek_table.num_points = length / FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
Josh Coalsonc076ba52001-04-05 21:32:54 +0000892
Josh Coalsoncc682512002-06-08 04:53:42 +0000893 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 +0000894 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
Josh Coalsonc076ba52001-04-05 21:32:54 +0000895 return false;
896 }
Josh Coalson090f8f72002-06-04 05:53:04 +0000897 for(i = 0; i < decoder->private_->seek_table.data.seek_table.num_points; i++) {
Josh Coalsonaec256b2002-03-12 16:19:54 +0000898 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 +0000899 return false; /* the read_callback_ sets the state for us */
Josh Coalson090f8f72002-06-04 05:53:04 +0000900 decoder->private_->seek_table.data.seek_table.points[i].sample_number = xx;
Josh Coalsonc076ba52001-04-05 21:32:54 +0000901
Josh Coalsonaec256b2002-03-12 16:19:54 +0000902 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 +0000903 return false; /* the read_callback_ sets the state for us */
Josh Coalson090f8f72002-06-04 05:53:04 +0000904 decoder->private_->seek_table.data.seek_table.points[i].stream_offset = xx;
Josh Coalsonc076ba52001-04-05 21:32:54 +0000905
Josh Coalsonaec256b2002-03-12 16:19:54 +0000906 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 +0000907 return false; /* the read_callback_ sets the state for us */
Josh Coalson090f8f72002-06-04 05:53:04 +0000908 decoder->private_->seek_table.data.seek_table.points[i].frame_samples = x;
Josh Coalsonc076ba52001-04-05 21:32:54 +0000909 }
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000910 length -= (decoder->private_->seek_table.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH);
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000911 /* if there is a partial point left, skip over it */
912 if(length > 0) {
913 /*@@@ do an error_callback() here? there's an argument for either way */
914 if(!FLAC__bitbuffer_read_byte_block_aligned(decoder->private_->input, 0, length, read_callback_, decoder))
915 return false; /* the read_callback_ sets the state for us */
916 }
917
Josh Coalsonfa697a92001-08-16 20:07:29 +0000918 decoder->private_->has_seek_table = true;
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000919 if(decoder->private_->metadata_filter[FLAC__METADATA_TYPE_SEEKTABLE])
920 decoder->private_->metadata_callback(decoder, &decoder->private_->seek_table, decoder->private_->client_data);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +0000921 }
922 else {
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000923 FLAC__bool skip_it = !decoder->private_->metadata_filter[type];
924 unsigned real_length = length;
Josh Coalsoncc682512002-06-08 04:53:42 +0000925 FLAC__StreamMetadata block;
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000926
927 block.is_last = last_block;
928 block.type = type;
929 block.length = length;
930
Josh Coalson8400e432002-05-09 05:41:35 +0000931 if(type == FLAC__METADATA_TYPE_APPLICATION) {
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000932 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 +0000933 return false; /* the read_callback_ sets the state for us */
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000934
935 real_length -= FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8;
936
Josh Coalson570db862002-07-31 06:58:16 +0000937 if(decoder->private_->metadata_filter_ids_count > 0 && has_id_filtered_(decoder, block.data.application.id))
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000938 skip_it = !skip_it;
939 }
940
941 if(skip_it) {
942 if(!FLAC__bitbuffer_read_byte_block_aligned(decoder->private_->input, 0, real_length, read_callback_, decoder))
943 return false; /* the read_callback_ sets the state for us */
944 }
945 else {
946 switch(type) {
947 case FLAC__METADATA_TYPE_PADDING:
948 /* skip the padding bytes */
949 if(!FLAC__bitbuffer_read_byte_block_aligned(decoder->private_->input, 0, real_length, read_callback_, decoder))
950 return false; /* the read_callback_ sets the state for us */
951 break;
952 case FLAC__METADATA_TYPE_APPLICATION:
953 /* remember, we read the ID already */
Josh Coalsonbda92f22002-05-31 06:24:03 +0000954 if(real_length > 0) {
955 if(0 == (block.data.application.data = malloc(real_length))) {
956 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
957 return false;
958 }
959 if(!FLAC__bitbuffer_read_byte_block_aligned(decoder->private_->input, block.data.application.data, real_length, read_callback_, decoder))
960 return false; /* the read_callback_ sets the state for us */
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000961 }
Josh Coalsonbda92f22002-05-31 06:24:03 +0000962 else
963 block.data.application.data = 0;
Josh Coalsonbf9325f2002-05-07 05:30:27 +0000964 break;
965 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
966 /* read vendor string */
Josh Coalson090f8f72002-06-04 05:53:04 +0000967 FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32);
968 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 +0000969 return false; /* the read_callback_ sets the state for us */
970 if(block.data.vorbis_comment.vendor_string.length > 0) {
971 if(0 == (block.data.vorbis_comment.vendor_string.entry = malloc(block.data.vorbis_comment.vendor_string.length))) {
972 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
973 return false;
974 }
975 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))
976 return false; /* the read_callback_ sets the state for us */
977 }
978 else
979 block.data.vorbis_comment.vendor_string.entry = 0;
980
981 /* read num comments */
Josh Coalson090f8f72002-06-04 05:53:04 +0000982 FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN == 32);
983 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 +0000984 return false; /* the read_callback_ sets the state for us */
985
986 /* read comments */
987 if(block.data.vorbis_comment.num_comments > 0) {
Josh Coalsoncc682512002-06-08 04:53:42 +0000988 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 +0000989 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
990 return false;
991 }
992 for(i = 0; i < block.data.vorbis_comment.num_comments; i++) {
Josh Coalson090f8f72002-06-04 05:53:04 +0000993 FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32);
994 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 +0000995 return false; /* the read_callback_ sets the state for us */
996 if(block.data.vorbis_comment.comments[i].length > 0) {
997 if(0 == (block.data.vorbis_comment.comments[i].entry = malloc(block.data.vorbis_comment.comments[i].length))) {
998 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
999 return false;
1000 }
1001 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))
1002 return false; /* the read_callback_ sets the state for us */
1003 }
1004 else
1005 block.data.vorbis_comment.comments[i].entry = 0;
1006 }
1007 }
1008 else {
1009 block.data.vorbis_comment.comments = 0;
1010 }
1011 break;
1012 case FLAC__METADATA_TYPE_STREAMINFO:
1013 case FLAC__METADATA_TYPE_SEEKTABLE:
1014 default:
1015 FLAC__ASSERT(0);
1016 }
1017 decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data);
1018
1019 /* now we have to free any malloc'ed data in the block */
1020 switch(type) {
1021 case FLAC__METADATA_TYPE_PADDING:
1022 break;
1023 case FLAC__METADATA_TYPE_APPLICATION:
1024 if(0 != block.data.application.data)
1025 free(block.data.application.data);
1026 break;
1027 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
1028 if(0 != block.data.vorbis_comment.vendor_string.entry)
1029 free(block.data.vorbis_comment.vendor_string.entry);
1030 if(block.data.vorbis_comment.num_comments > 0)
1031 for(i = 0; i < block.data.vorbis_comment.num_comments; i++)
1032 if(0 != block.data.vorbis_comment.comments[i].entry)
1033 free(block.data.vorbis_comment.comments[i].entry);
1034 if(0 != block.data.vorbis_comment.comments)
1035 free(block.data.vorbis_comment.comments);
1036 break;
1037 case FLAC__METADATA_TYPE_STREAMINFO:
1038 case FLAC__METADATA_TYPE_SEEKTABLE:
1039 default:
1040 FLAC__ASSERT(0);
1041 }
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001042 }
1043 }
1044
1045 if(last_block)
Josh Coalsonfa697a92001-08-16 20:07:29 +00001046 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001047
1048 return true;
1049}
1050
Josh Coalson570db862002-07-31 06:58:16 +00001051FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001052{
Josh Coalson77e3f312001-06-23 03:03:24 +00001053 FLAC__uint32 x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001054 unsigned i, skip;
1055
1056 /* skip the version and flags bytes */
Josh Coalsonaec256b2002-03-12 16:19:54 +00001057 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 24, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001058 return false; /* the read_callback_ sets the state for us */
1059 /* get the size (in bytes) to skip */
1060 skip = 0;
1061 for(i = 0; i < 4; i++) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001062 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001063 return false; /* the read_callback_ sets the state for us */
1064 skip <<= 7;
1065 skip |= (x & 0x7f);
1066 }
1067 /* skip the rest of the tag */
Josh Coalsonbf9325f2002-05-07 05:30:27 +00001068 if(!FLAC__bitbuffer_read_byte_block_aligned(decoder->private_->input, 0, skip, read_callback_, decoder))
1069 return false; /* the read_callback_ sets the state for us */
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001070 return true;
1071}
1072
Josh Coalson570db862002-07-31 06:58:16 +00001073FLAC__bool frame_sync_(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001074{
Josh Coalson77e3f312001-06-23 03:03:24 +00001075 FLAC__uint32 x;
1076 FLAC__bool first = true;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001077
1078 /* If we know the total number of samples in the stream, stop if we've read that many. */
1079 /* This will stop us, for example, from wasting time trying to sync on an ID3V1 tag. */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001080 if(decoder->private_->has_stream_info && decoder->private_->stream_info.data.stream_info.total_samples) {
1081 if(decoder->private_->samples_decoded >= decoder->private_->stream_info.data.stream_info.total_samples) {
1082 decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001083 return true;
1084 }
1085 }
1086
1087 /* make sure we're byte aligned */
Josh Coalsonaec256b2002-03-12 16:19:54 +00001088 if(!FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input)) {
1089 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 +00001090 return false; /* the read_callback_ sets the state for us */
1091 }
1092
1093 while(1) {
Josh Coalsonfa697a92001-08-16 20:07:29 +00001094 if(decoder->private_->cached) {
1095 x = (FLAC__uint32)decoder->private_->lookahead;
1096 decoder->private_->cached = false;
Josh Coalson215af572001-03-27 01:15:58 +00001097 }
1098 else {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001099 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001100 return false; /* the read_callback_ sets the state for us */
Josh Coalson215af572001-03-27 01:15:58 +00001101 }
1102 if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001103 decoder->private_->header_warmup[0] = (FLAC__byte)x;
Josh Coalsonaec256b2002-03-12 16:19:54 +00001104 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder))
Josh Coalson215af572001-03-27 01:15:58 +00001105 return false; /* the read_callback_ sets the state for us */
1106
1107 /* 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 */
1108 /* else we have to check if the second byte is the end of a sync code */
1109 if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001110 decoder->private_->lookahead = (FLAC__byte)x;
1111 decoder->private_->cached = true;
Josh Coalson215af572001-03-27 01:15:58 +00001112 }
1113 else if(x >> 2 == 0x3e) { /* MAGIC NUMBER for the last 6 sync bits */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001114 decoder->private_->header_warmup[1] = (FLAC__byte)x;
1115 decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001116 return true;
1117 }
1118 }
1119 if(first) {
Josh Coalson090f8f72002-06-04 05:53:04 +00001120 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, decoder->private_->client_data);
Josh Coalson38c68542002-02-12 22:58:59 +00001121 first = false;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001122 }
1123 }
1124
1125 return true;
1126}
1127
Josh Coalson570db862002-07-31 06:58:16 +00001128FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001129{
1130 unsigned channel;
1131 unsigned i;
Josh Coalson77e3f312001-06-23 03:03:24 +00001132 FLAC__int32 mid, side, left, right;
1133 FLAC__uint16 frame_crc; /* the one we calculate from the input stream */
1134 FLAC__uint32 x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001135
1136 *got_a_frame = false;
1137
Josh Coalson215af572001-03-27 01:15:58 +00001138 /* init the CRC */
1139 frame_crc = 0;
Josh Coalsonfa697a92001-08-16 20:07:29 +00001140 FLAC__CRC16_UPDATE(decoder->private_->header_warmup[0], frame_crc);
1141 FLAC__CRC16_UPDATE(decoder->private_->header_warmup[1], frame_crc);
Josh Coalsonaec256b2002-03-12 16:19:54 +00001142 FLAC__bitbuffer_reset_read_crc16(decoder->private_->input, frame_crc);
Josh Coalson215af572001-03-27 01:15:58 +00001143
Josh Coalson570db862002-07-31 06:58:16 +00001144 if(!read_frame_header_(decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001145 return false;
Josh Coalsonfa697a92001-08-16 20:07:29 +00001146 if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001147 return true;
Josh Coalson570db862002-07-31 06:58:16 +00001148 if(!allocate_output_(decoder, decoder->private_->frame.header.blocksize, decoder->private_->frame.header.channels))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001149 return false;
Josh Coalsonfa697a92001-08-16 20:07:29 +00001150 for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) {
Josh Coalsonb5e60e52001-01-28 09:27:27 +00001151 /*
1152 * first figure the correct bits-per-sample of the subframe
1153 */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001154 unsigned bps = decoder->private_->frame.header.bits_per_sample;
1155 switch(decoder->private_->frame.header.channel_assignment) {
Josh Coalsonb5e60e52001-01-28 09:27:27 +00001156 case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
1157 /* no adjustment needed */
1158 break;
1159 case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001160 FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
Josh Coalsonb5e60e52001-01-28 09:27:27 +00001161 if(channel == 1)
1162 bps++;
1163 break;
1164 case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001165 FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
Josh Coalsonb5e60e52001-01-28 09:27:27 +00001166 if(channel == 0)
1167 bps++;
1168 break;
1169 case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001170 FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
Josh Coalsonb5e60e52001-01-28 09:27:27 +00001171 if(channel == 1)
1172 bps++;
1173 break;
1174 default:
Josh Coalson1b689822001-05-31 20:11:02 +00001175 FLAC__ASSERT(0);
Josh Coalsonb5e60e52001-01-28 09:27:27 +00001176 }
1177 /*
1178 * now read it
1179 */
Josh Coalson570db862002-07-31 06:58:16 +00001180 if(!read_subframe_(decoder, channel, bps))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001181 return false;
Josh Coalsonfa697a92001-08-16 20:07:29 +00001182 if(decoder->protected_->state != FLAC__STREAM_DECODER_READ_FRAME) {
1183 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001184 return true;
1185 }
1186 }
Josh Coalson570db862002-07-31 06:58:16 +00001187 if(!read_zero_padding_(decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001188 return false;
1189
Josh Coalson215af572001-03-27 01:15:58 +00001190 /*
1191 * Read the frame CRC-16 from the footer and check
1192 */
Josh Coalsonaec256b2002-03-12 16:19:54 +00001193 frame_crc = FLAC__bitbuffer_get_read_crc16(decoder->private_->input);
1194 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 +00001195 return false; /* the read_callback_ sets the state for us */
Josh Coalson77e3f312001-06-23 03:03:24 +00001196 if(frame_crc == (FLAC__uint16)x) {
Josh Coalson215af572001-03-27 01:15:58 +00001197 /* Undo any special channel coding */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001198 switch(decoder->private_->frame.header.channel_assignment) {
Josh Coalson215af572001-03-27 01:15:58 +00001199 case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
1200 /* do nothing */
1201 break;
1202 case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001203 FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
1204 for(i = 0; i < decoder->private_->frame.header.blocksize; i++)
1205 decoder->private_->output[1][i] = decoder->private_->output[0][i] - decoder->private_->output[1][i];
Josh Coalson215af572001-03-27 01:15:58 +00001206 break;
1207 case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001208 FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
1209 for(i = 0; i < decoder->private_->frame.header.blocksize; i++)
1210 decoder->private_->output[0][i] += decoder->private_->output[1][i];
Josh Coalson215af572001-03-27 01:15:58 +00001211 break;
1212 case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001213 FLAC__ASSERT(decoder->private_->frame.header.channels == 2);
1214 for(i = 0; i < decoder->private_->frame.header.blocksize; i++) {
1215 mid = decoder->private_->output[0][i];
1216 side = decoder->private_->output[1][i];
Josh Coalson215af572001-03-27 01:15:58 +00001217 mid <<= 1;
1218 if(side & 1) /* i.e. if 'side' is odd... */
1219 mid++;
1220 left = mid + side;
1221 right = mid - side;
Josh Coalsonfa697a92001-08-16 20:07:29 +00001222 decoder->private_->output[0][i] = left >> 1;
1223 decoder->private_->output[1][i] = right >> 1;
Josh Coalson215af572001-03-27 01:15:58 +00001224 }
1225 break;
1226 default:
Josh Coalson1b689822001-05-31 20:11:02 +00001227 FLAC__ASSERT(0);
Josh Coalson215af572001-03-27 01:15:58 +00001228 break;
1229 }
1230 }
1231 else {
1232 /* Bad frame, emit error and zero the output signal */
Josh Coalson090f8f72002-06-04 05:53:04 +00001233 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH, decoder->private_->client_data);
Josh Coalsonfa697a92001-08-16 20:07:29 +00001234 for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) {
1235 memset(decoder->private_->output[channel], 0, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize);
Josh Coalson215af572001-03-27 01:15:58 +00001236 }
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001237 }
1238
1239 *got_a_frame = true;
1240
1241 /* put the latest values into the public section of the decoder instance */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001242 decoder->protected_->channels = decoder->private_->frame.header.channels;
1243 decoder->protected_->channel_assignment = decoder->private_->frame.header.channel_assignment;
1244 decoder->protected_->bits_per_sample = decoder->private_->frame.header.bits_per_sample;
1245 decoder->protected_->sample_rate = decoder->private_->frame.header.sample_rate;
1246 decoder->protected_->blocksize = decoder->private_->frame.header.blocksize;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001247
Josh Coalsonfa697a92001-08-16 20:07:29 +00001248 FLAC__ASSERT(decoder->private_->frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
1249 decoder->private_->samples_decoded = decoder->private_->frame.header.number.sample_number + decoder->private_->frame.header.blocksize;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001250
1251 /* write it */
Josh Coalson57ba6f42002-06-07 05:27:37 +00001252 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 +00001253 return false;
1254
Josh Coalsonfa697a92001-08-16 20:07:29 +00001255 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001256 return true;
1257}
1258
Josh Coalson570db862002-07-31 06:58:16 +00001259FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001260{
Josh Coalson77e3f312001-06-23 03:03:24 +00001261 FLAC__uint32 x;
1262 FLAC__uint64 xx;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001263 unsigned i, blocksize_hint = 0, sample_rate_hint = 0;
Josh Coalson77e3f312001-06-23 03:03:24 +00001264 FLAC__byte crc8, raw_header[16]; /* MAGIC NUMBER based on the maximum frame header size, including CRC */
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001265 unsigned raw_header_len;
Josh Coalson77e3f312001-06-23 03:03:24 +00001266 FLAC__bool is_unparseable = false;
Josh Coalsonfa697a92001-08-16 20:07:29 +00001267 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);
1268 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 +00001269
Josh Coalsonaec256b2002-03-12 16:19:54 +00001270 FLAC__ASSERT(FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input));
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001271
Josh Coalson215af572001-03-27 01:15:58 +00001272 /* init the raw header with the saved bits from synchronization */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001273 raw_header[0] = decoder->private_->header_warmup[0];
1274 raw_header[1] = decoder->private_->header_warmup[1];
Josh Coalson215af572001-03-27 01:15:58 +00001275 raw_header_len = 2;
1276
1277 /*
1278 * check to make sure that the reserved bits are 0
1279 */
1280 if(raw_header[1] & 0x03) { /* MAGIC NUMBER */
1281 is_unparseable = true;
1282 }
1283
1284 /*
1285 * Note that along the way as we read the header, we look for a sync
1286 * code inside. If we find one it would indicate that our original
1287 * sync was bad since there cannot be a sync code in a valid header.
1288 */
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001289
1290 /*
1291 * read in the raw header as bytes so we can CRC it, and parse it on the way
1292 */
1293 for(i = 0; i < 2; i++) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001294 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001295 return false; /* the read_callback_ sets the state for us */
Josh Coalson215af572001-03-27 01:15:58 +00001296 if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001297 /* 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 +00001298 decoder->private_->lookahead = (FLAC__byte)x;
1299 decoder->private_->cached = true;
Josh Coalson090f8f72002-06-04 05:53:04 +00001300 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, decoder->private_->client_data);
Josh Coalsonfa697a92001-08-16 20:07:29 +00001301 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalson215af572001-03-27 01:15:58 +00001302 return true;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001303 }
Josh Coalson77e3f312001-06-23 03:03:24 +00001304 raw_header[raw_header_len++] = (FLAC__byte)x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001305 }
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001306
Josh Coalson215af572001-03-27 01:15:58 +00001307 switch(x = raw_header[2] >> 4) {
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001308 case 0:
Josh Coalson7531b002001-04-14 00:24:32 +00001309 if(is_known_fixed_blocksize_stream)
Josh Coalsonfa697a92001-08-16 20:07:29 +00001310 decoder->private_->frame.header.blocksize = decoder->private_->stream_info.data.stream_info.min_blocksize;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001311 else
1312 is_unparseable = true;
1313 break;
1314 case 1:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001315 decoder->private_->frame.header.blocksize = 192;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001316 break;
1317 case 2:
1318 case 3:
1319 case 4:
1320 case 5:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001321 decoder->private_->frame.header.blocksize = 576 << (x-2);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001322 break;
1323 case 6:
1324 case 7:
1325 blocksize_hint = x;
1326 break;
Josh Coalson215af572001-03-27 01:15:58 +00001327 case 8:
1328 case 9:
1329 case 10:
1330 case 11:
1331 case 12:
1332 case 13:
1333 case 14:
1334 case 15:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001335 decoder->private_->frame.header.blocksize = 256 << (x-8);
Josh Coalson215af572001-03-27 01:15:58 +00001336 break;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001337 default:
Josh Coalson1b689822001-05-31 20:11:02 +00001338 FLAC__ASSERT(0);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001339 break;
1340 }
1341
Josh Coalson215af572001-03-27 01:15:58 +00001342 switch(x = raw_header[2] & 0x0f) {
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001343 case 0:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001344 if(decoder->private_->has_stream_info)
1345 decoder->private_->frame.header.sample_rate = decoder->private_->stream_info.data.stream_info.sample_rate;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001346 else
1347 is_unparseable = true;
1348 break;
1349 case 1:
1350 case 2:
1351 case 3:
1352 is_unparseable = true;
1353 break;
1354 case 4:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001355 decoder->private_->frame.header.sample_rate = 8000;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001356 break;
1357 case 5:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001358 decoder->private_->frame.header.sample_rate = 16000;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001359 break;
1360 case 6:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001361 decoder->private_->frame.header.sample_rate = 22050;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001362 break;
1363 case 7:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001364 decoder->private_->frame.header.sample_rate = 24000;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001365 break;
1366 case 8:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001367 decoder->private_->frame.header.sample_rate = 32000;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001368 break;
1369 case 9:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001370 decoder->private_->frame.header.sample_rate = 44100;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001371 break;
1372 case 10:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001373 decoder->private_->frame.header.sample_rate = 48000;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001374 break;
1375 case 11:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001376 decoder->private_->frame.header.sample_rate = 96000;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001377 break;
1378 case 12:
1379 case 13:
1380 case 14:
1381 sample_rate_hint = x;
1382 break;
1383 case 15:
Josh Coalson090f8f72002-06-04 05:53:04 +00001384 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, decoder->private_->client_data);
Josh Coalsonfa697a92001-08-16 20:07:29 +00001385 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001386 return true;
1387 default:
Josh Coalson1b689822001-05-31 20:11:02 +00001388 FLAC__ASSERT(0);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001389 }
1390
Josh Coalson215af572001-03-27 01:15:58 +00001391 x = (unsigned)(raw_header[3] >> 4);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001392 if(x & 8) {
Josh Coalsonfa697a92001-08-16 20:07:29 +00001393 decoder->private_->frame.header.channels = 2;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001394 switch(x & 7) {
1395 case 0:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001396 decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001397 break;
1398 case 1:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001399 decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001400 break;
1401 case 2:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001402 decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_MID_SIDE;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001403 break;
1404 default:
1405 is_unparseable = true;
1406 break;
1407 }
1408 }
1409 else {
Josh Coalsonfa697a92001-08-16 20:07:29 +00001410 decoder->private_->frame.header.channels = (unsigned)x + 1;
1411 decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001412 }
1413
Josh Coalson215af572001-03-27 01:15:58 +00001414 switch(x = (unsigned)(raw_header[3] & 0x0e) >> 1) {
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001415 case 0:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001416 if(decoder->private_->has_stream_info)
1417 decoder->private_->frame.header.bits_per_sample = decoder->private_->stream_info.data.stream_info.bits_per_sample;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001418 else
1419 is_unparseable = true;
1420 break;
1421 case 1:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001422 decoder->private_->frame.header.bits_per_sample = 8;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001423 break;
1424 case 2:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001425 decoder->private_->frame.header.bits_per_sample = 12;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001426 break;
1427 case 4:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001428 decoder->private_->frame.header.bits_per_sample = 16;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001429 break;
1430 case 5:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001431 decoder->private_->frame.header.bits_per_sample = 20;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001432 break;
1433 case 6:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001434 decoder->private_->frame.header.bits_per_sample = 24;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001435 break;
1436 case 3:
1437 case 7:
1438 is_unparseable = true;
1439 break;
1440 default:
Josh Coalson1b689822001-05-31 20:11:02 +00001441 FLAC__ASSERT(0);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001442 break;
1443 }
1444
Josh Coalson215af572001-03-27 01:15:58 +00001445 if(raw_header[3] & 0x01) { /* this should be a zero padding bit */
Josh Coalson090f8f72002-06-04 05:53:04 +00001446 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, decoder->private_->client_data);
Josh Coalsonfa697a92001-08-16 20:07:29 +00001447 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001448 return true;
1449 }
1450
Josh Coalson7531b002001-04-14 00:24:32 +00001451 if(blocksize_hint && is_known_variable_blocksize_stream) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001452 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 +00001453 return false; /* the read_callback_ sets the state for us */
Josh Coalson215af572001-03-27 01:15:58 +00001454 if(xx == 0xffffffffffffffff) { /* i.e. non-UTF8 code... */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001455 decoder->private_->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */
1456 decoder->private_->cached = true;
Josh Coalson090f8f72002-06-04 05:53:04 +00001457 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, decoder->private_->client_data);
Josh Coalsonfa697a92001-08-16 20:07:29 +00001458 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalson215af572001-03-27 01:15:58 +00001459 return true;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001460 }
Josh Coalsonfa697a92001-08-16 20:07:29 +00001461 decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER;
1462 decoder->private_->frame.header.number.sample_number = xx;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001463 }
1464 else {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001465 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 +00001466 return false; /* the read_callback_ sets the state for us */
Josh Coalson215af572001-03-27 01:15:58 +00001467 if(x == 0xffffffff) { /* i.e. non-UTF8 code... */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001468 decoder->private_->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */
1469 decoder->private_->cached = true;
Josh Coalson090f8f72002-06-04 05:53:04 +00001470 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, decoder->private_->client_data);
Josh Coalsonfa697a92001-08-16 20:07:29 +00001471 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalson215af572001-03-27 01:15:58 +00001472 return true;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001473 }
Josh Coalsonfa697a92001-08-16 20:07:29 +00001474 decoder->private_->last_frame_number = x;
1475 if(decoder->private_->has_stream_info) {
1476 decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER;
1477 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 +00001478 }
1479 else {
1480 is_unparseable = true;
1481 }
1482 }
1483
1484 if(blocksize_hint) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001485 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001486 return false; /* the read_callback_ sets the state for us */
Josh Coalson77e3f312001-06-23 03:03:24 +00001487 raw_header[raw_header_len++] = (FLAC__byte)x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001488 if(blocksize_hint == 7) {
Josh Coalson77e3f312001-06-23 03:03:24 +00001489 FLAC__uint32 _x;
Josh Coalsonaec256b2002-03-12 16:19:54 +00001490 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &_x, 8, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001491 return false; /* the read_callback_ sets the state for us */
Josh Coalson77e3f312001-06-23 03:03:24 +00001492 raw_header[raw_header_len++] = (FLAC__byte)_x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001493 x = (x << 8) | _x;
1494 }
Josh Coalsonfa697a92001-08-16 20:07:29 +00001495 decoder->private_->frame.header.blocksize = x+1;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001496 }
1497
1498 if(sample_rate_hint) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001499 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001500 return false; /* the read_callback_ sets the state for us */
Josh Coalson77e3f312001-06-23 03:03:24 +00001501 raw_header[raw_header_len++] = (FLAC__byte)x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001502 if(sample_rate_hint != 12) {
Josh Coalson77e3f312001-06-23 03:03:24 +00001503 FLAC__uint32 _x;
Josh Coalsonaec256b2002-03-12 16:19:54 +00001504 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &_x, 8, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001505 return false; /* the read_callback_ sets the state for us */
Josh Coalson77e3f312001-06-23 03:03:24 +00001506 raw_header[raw_header_len++] = (FLAC__byte)_x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001507 x = (x << 8) | _x;
1508 }
1509 if(sample_rate_hint == 12)
Josh Coalsonfa697a92001-08-16 20:07:29 +00001510 decoder->private_->frame.header.sample_rate = x*1000;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001511 else if(sample_rate_hint == 13)
Josh Coalsonfa697a92001-08-16 20:07:29 +00001512 decoder->private_->frame.header.sample_rate = x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001513 else
Josh Coalsonfa697a92001-08-16 20:07:29 +00001514 decoder->private_->frame.header.sample_rate = x*10;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001515 }
1516
Josh Coalson215af572001-03-27 01:15:58 +00001517 /* read the CRC-8 byte */
Josh Coalsonaec256b2002-03-12 16:19:54 +00001518 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001519 return false; /* the read_callback_ sets the state for us */
Josh Coalson77e3f312001-06-23 03:03:24 +00001520 crc8 = (FLAC__byte)x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001521
Josh Coalson215af572001-03-27 01:15:58 +00001522 if(FLAC__crc8(raw_header, raw_header_len) != crc8) {
Josh Coalson090f8f72002-06-04 05:53:04 +00001523 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, decoder->private_->client_data);
Josh Coalsonfa697a92001-08-16 20:07:29 +00001524 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001525 return true;
1526 }
1527
1528 if(is_unparseable) {
Josh Coalsonfa697a92001-08-16 20:07:29 +00001529 decoder->protected_->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001530 return false;
1531 }
1532
1533 return true;
1534}
1535
Josh Coalson570db862002-07-31 06:58:16 +00001536FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001537{
Josh Coalson77e3f312001-06-23 03:03:24 +00001538 FLAC__uint32 x;
1539 FLAC__bool wasted_bits;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001540
Josh Coalsonaec256b2002-03-12 16:19:54 +00001541 if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) /* MAGIC NUMBER */
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001542 return false; /* the read_callback_ sets the state for us */
Josh Coalson215af572001-03-27 01:15:58 +00001543
1544 wasted_bits = (x & 1);
1545 x &= 0xfe;
1546
1547 if(wasted_bits) {
1548 unsigned u;
Josh Coalsonaec256b2002-03-12 16:19:54 +00001549 if(!FLAC__bitbuffer_read_unary_unsigned(decoder->private_->input, &u, read_callback_, decoder))
Josh Coalson215af572001-03-27 01:15:58 +00001550 return false; /* the read_callback_ sets the state for us */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001551 decoder->private_->frame.subframes[channel].wasted_bits = u+1;
1552 bps -= decoder->private_->frame.subframes[channel].wasted_bits;
Josh Coalson215af572001-03-27 01:15:58 +00001553 }
1554 else
Josh Coalsonfa697a92001-08-16 20:07:29 +00001555 decoder->private_->frame.subframes[channel].wasted_bits = 0;
Josh Coalson215af572001-03-27 01:15:58 +00001556
Josh Coalson859bc542001-03-27 22:22:27 +00001557 /*
1558 * Lots of magic numbers here
1559 */
Josh Coalson215af572001-03-27 01:15:58 +00001560 if(x & 0x80) {
Josh Coalson090f8f72002-06-04 05:53:04 +00001561 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, decoder->private_->client_data);
Josh Coalsonfa697a92001-08-16 20:07:29 +00001562 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001563 return true;
1564 }
1565 else if(x == 0) {
Josh Coalson570db862002-07-31 06:58:16 +00001566 if(!read_subframe_constant_(decoder, channel, bps))
Josh Coalson215af572001-03-27 01:15:58 +00001567 return false;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001568 }
1569 else if(x == 2) {
Josh Coalson570db862002-07-31 06:58:16 +00001570 if(!read_subframe_verbatim_(decoder, channel, bps))
Josh Coalson215af572001-03-27 01:15:58 +00001571 return false;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001572 }
1573 else if(x < 16) {
Josh Coalsonfa697a92001-08-16 20:07:29 +00001574 decoder->protected_->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001575 return false;
1576 }
1577 else if(x <= 24) {
Josh Coalson570db862002-07-31 06:58:16 +00001578 if(!read_subframe_fixed_(decoder, channel, bps, (x>>1)&7))
Josh Coalson215af572001-03-27 01:15:58 +00001579 return false;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001580 }
1581 else if(x < 64) {
Josh Coalsonfa697a92001-08-16 20:07:29 +00001582 decoder->protected_->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001583 return false;
1584 }
1585 else {
Josh Coalson570db862002-07-31 06:58:16 +00001586 if(!read_subframe_lpc_(decoder, channel, bps, ((x>>1)&31)+1))
Josh Coalson215af572001-03-27 01:15:58 +00001587 return false;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001588 }
Josh Coalson215af572001-03-27 01:15:58 +00001589
1590 if(wasted_bits) {
Josh Coalson859bc542001-03-27 22:22:27 +00001591 unsigned i;
Josh Coalsonfa697a92001-08-16 20:07:29 +00001592 x = decoder->private_->frame.subframes[channel].wasted_bits;
1593 for(i = 0; i < decoder->private_->frame.header.blocksize; i++)
1594 decoder->private_->output[channel][i] <<= x;
Josh Coalson215af572001-03-27 01:15:58 +00001595 }
Josh Coalson859bc542001-03-27 22:22:27 +00001596
Josh Coalson215af572001-03-27 01:15:58 +00001597 return true;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001598}
1599
Josh Coalson570db862002-07-31 06:58:16 +00001600FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001601{
Josh Coalsonfa697a92001-08-16 20:07:29 +00001602 FLAC__Subframe_Constant *subframe = &decoder->private_->frame.subframes[channel].data.constant;
Josh Coalson77e3f312001-06-23 03:03:24 +00001603 FLAC__int32 x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001604 unsigned i;
Josh Coalsonfa697a92001-08-16 20:07:29 +00001605 FLAC__int32 *output = decoder->private_->output[channel];
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001606
Josh Coalsonfa697a92001-08-16 20:07:29 +00001607 decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_CONSTANT;
Josh Coalson6dcea512001-01-23 23:07:36 +00001608
Josh Coalsonaec256b2002-03-12 16:19:54 +00001609 if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &x, bps, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001610 return false; /* the read_callback_ sets the state for us */
1611
Josh Coalson6dcea512001-01-23 23:07:36 +00001612 subframe->value = x;
1613
1614 /* decode the subframe */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001615 for(i = 0; i < decoder->private_->frame.header.blocksize; i++)
Josh Coalson6dcea512001-01-23 23:07:36 +00001616 output[i] = x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001617
1618 return true;
1619}
1620
Josh Coalson570db862002-07-31 06:58:16 +00001621FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001622{
Josh Coalsonfa697a92001-08-16 20:07:29 +00001623 FLAC__Subframe_Fixed *subframe = &decoder->private_->frame.subframes[channel].data.fixed;
Josh Coalson77e3f312001-06-23 03:03:24 +00001624 FLAC__int32 i32;
1625 FLAC__uint32 u32;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001626 unsigned u;
1627
Josh Coalsonfa697a92001-08-16 20:07:29 +00001628 decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_FIXED;
Josh Coalson6dcea512001-01-23 23:07:36 +00001629
Josh Coalsonfa697a92001-08-16 20:07:29 +00001630 subframe->residual = decoder->private_->residual[channel];
Josh Coalson6dcea512001-01-23 23:07:36 +00001631 subframe->order = order;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001632
1633 /* read warm-up samples */
1634 for(u = 0; u < order; u++) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001635 if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &i32, bps, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001636 return false; /* the read_callback_ sets the state for us */
Josh Coalson6dcea512001-01-23 23:07:36 +00001637 subframe->warmup[u] = i32;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001638 }
1639
1640 /* read entropy coding method info */
Josh Coalsonaec256b2002-03-12 16:19:54 +00001641 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 +00001642 return false; /* the read_callback_ sets the state for us */
Josh Coalson6dcea512001-01-23 23:07:36 +00001643 subframe->entropy_coding_method.type = u32;
1644 switch(subframe->entropy_coding_method.type) {
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001645 case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
Josh Coalsonaec256b2002-03-12 16:19:54 +00001646 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 +00001647 return false; /* the read_callback_ sets the state for us */
Josh Coalson6dcea512001-01-23 23:07:36 +00001648 subframe->entropy_coding_method.data.partitioned_rice.order = u32;
Josh Coalsona37ba462002-08-19 21:36:39 +00001649 subframe->entropy_coding_method.data.partitioned_rice.contents = &decoder->private_->partitioned_rice_contents[channel];
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001650 break;
1651 default:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001652 decoder->protected_->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001653 return false;
1654 }
1655
1656 /* read residual */
Josh Coalson6dcea512001-01-23 23:07:36 +00001657 switch(subframe->entropy_coding_method.type) {
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001658 case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
Josh Coalsona37ba462002-08-19 21:36:39 +00001659 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 +00001660 return false;
1661 break;
1662 default:
Josh Coalson1b689822001-05-31 20:11:02 +00001663 FLAC__ASSERT(0);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001664 }
1665
1666 /* decode the subframe */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001667 memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order);
1668 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 +00001669
1670 return true;
1671}
1672
Josh Coalson570db862002-07-31 06:58:16 +00001673FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001674{
Josh Coalsonfa697a92001-08-16 20:07:29 +00001675 FLAC__Subframe_LPC *subframe = &decoder->private_->frame.subframes[channel].data.lpc;
Josh Coalson77e3f312001-06-23 03:03:24 +00001676 FLAC__int32 i32;
1677 FLAC__uint32 u32;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001678 unsigned u;
1679
Josh Coalsonfa697a92001-08-16 20:07:29 +00001680 decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_LPC;
Josh Coalson6dcea512001-01-23 23:07:36 +00001681
Josh Coalsonfa697a92001-08-16 20:07:29 +00001682 subframe->residual = decoder->private_->residual[channel];
Josh Coalson6dcea512001-01-23 23:07:36 +00001683 subframe->order = order;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001684
1685 /* read warm-up samples */
1686 for(u = 0; u < order; u++) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001687 if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &i32, bps, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001688 return false; /* the read_callback_ sets the state for us */
Josh Coalson6dcea512001-01-23 23:07:36 +00001689 subframe->warmup[u] = i32;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001690 }
1691
1692 /* read qlp coeff precision */
Josh Coalsonaec256b2002-03-12 16:19:54 +00001693 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 +00001694 return false; /* the read_callback_ sets the state for us */
Josh Coalson3372cc02001-04-13 18:44:46 +00001695 if(u32 == (1u << FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN) - 1) {
Josh Coalson090f8f72002-06-04 05:53:04 +00001696 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, decoder->private_->client_data);
Josh Coalsonfa697a92001-08-16 20:07:29 +00001697 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001698 return true;
1699 }
Josh Coalson6dcea512001-01-23 23:07:36 +00001700 subframe->qlp_coeff_precision = u32+1;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001701
1702 /* read qlp shift */
Josh Coalsonaec256b2002-03-12 16:19:54 +00001703 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 +00001704 return false; /* the read_callback_ sets the state for us */
Josh Coalson6dcea512001-01-23 23:07:36 +00001705 subframe->quantization_level = i32;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001706
1707 /* read quantized lp coefficiencts */
1708 for(u = 0; u < order; u++) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001709 if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &i32, subframe->qlp_coeff_precision, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001710 return false; /* the read_callback_ sets the state for us */
Josh Coalson6dcea512001-01-23 23:07:36 +00001711 subframe->qlp_coeff[u] = i32;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001712 }
1713
1714 /* read entropy coding method info */
Josh Coalsonaec256b2002-03-12 16:19:54 +00001715 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 +00001716 return false; /* the read_callback_ sets the state for us */
Josh Coalson6dcea512001-01-23 23:07:36 +00001717 subframe->entropy_coding_method.type = u32;
1718 switch(subframe->entropy_coding_method.type) {
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001719 case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
Josh Coalsonaec256b2002-03-12 16:19:54 +00001720 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 +00001721 return false; /* the read_callback_ sets the state for us */
Josh Coalson6dcea512001-01-23 23:07:36 +00001722 subframe->entropy_coding_method.data.partitioned_rice.order = u32;
Josh Coalsona37ba462002-08-19 21:36:39 +00001723 subframe->entropy_coding_method.data.partitioned_rice.contents = &decoder->private_->partitioned_rice_contents[channel];
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001724 break;
1725 default:
Josh Coalsonfa697a92001-08-16 20:07:29 +00001726 decoder->protected_->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001727 return false;
1728 }
1729
1730 /* read residual */
Josh Coalson6dcea512001-01-23 23:07:36 +00001731 switch(subframe->entropy_coding_method.type) {
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001732 case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
Josh Coalsona37ba462002-08-19 21:36:39 +00001733 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 +00001734 return false;
1735 break;
1736 default:
Josh Coalson1b689822001-05-31 20:11:02 +00001737 FLAC__ASSERT(0);
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001738 }
1739
1740 /* decode the subframe */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001741 memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order);
Josh Coalson92d42402001-05-31 20:53:19 +00001742 if(bps <= 16 && subframe->qlp_coeff_precision <= 16)
Josh Coalsonfa697a92001-08-16 20:07:29 +00001743 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);
Josh Coalson92d42402001-05-31 20:53:19 +00001744 else
Josh Coalsonfa697a92001-08-16 20:07:29 +00001745 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 Coalsonbb7f6b92000-12-10 04:09:52 +00001746
1747 return true;
1748}
1749
Josh Coalson570db862002-07-31 06:58:16 +00001750FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001751{
Josh Coalsonfa697a92001-08-16 20:07:29 +00001752 FLAC__Subframe_Verbatim *subframe = &decoder->private_->frame.subframes[channel].data.verbatim;
1753 FLAC__int32 x, *residual = decoder->private_->residual[channel];
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001754 unsigned i;
1755
Josh Coalsonfa697a92001-08-16 20:07:29 +00001756 decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_VERBATIM;
Josh Coalson6dcea512001-01-23 23:07:36 +00001757
Josh Coalsonb5e60e52001-01-28 09:27:27 +00001758 subframe->data = residual;
Josh Coalson6dcea512001-01-23 23:07:36 +00001759
Josh Coalsonfa697a92001-08-16 20:07:29 +00001760 for(i = 0; i < decoder->private_->frame.header.blocksize; i++) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001761 if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &x, bps, read_callback_, decoder))
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001762 return false; /* the read_callback_ sets the state for us */
Josh Coalsonb5e60e52001-01-28 09:27:27 +00001763 residual[i] = x;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001764 }
1765
Josh Coalson6dcea512001-01-23 23:07:36 +00001766 /* decode the subframe */
Josh Coalsonfa697a92001-08-16 20:07:29 +00001767 memcpy(decoder->private_->output[channel], subframe->data, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize);
Josh Coalson6dcea512001-01-23 23:07:36 +00001768
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001769 return true;
1770}
1771
Josh Coalsona37ba462002-08-19 21:36:39 +00001772FLAC__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 +00001773{
Josh Coalson77e3f312001-06-23 03:03:24 +00001774 FLAC__uint32 rice_parameter;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001775 int i;
1776 unsigned partition, sample, u;
1777 const unsigned partitions = 1u << partition_order;
Josh Coalsonfa697a92001-08-16 20:07:29 +00001778 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 +00001779
Josh Coalsona37ba462002-08-19 21:36:39 +00001780 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 +00001781 decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
1782 return false;
1783 }
Josh Coalsonb7023aa2002-08-17 15:23:43 +00001784
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001785 sample = 0;
1786 for(partition = 0; partition < partitions; partition++) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001787 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 +00001788 return false; /* the read_callback_ sets the state for us */
Josh Coalsona37ba462002-08-19 21:36:39 +00001789 partitioned_rice_contents->parameters[partition] = rice_parameter;
Josh Coalson2051dd42001-04-12 22:22:34 +00001790 if(rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) {
Josh Coalsonbb6712e2001-04-24 22:54:07 +00001791#ifdef FLAC__SYMMETRIC_RICE
Josh Coalsonb28559a2002-04-25 05:21:09 +00001792 for(u = (partition_order == 0 || partition > 0)? 0 : predictor_order; u < partition_samples; u++, sample++) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001793 if(!FLAC__bitbuffer_read_symmetric_rice_signed(decoder->private_->input, &i, rice_parameter, read_callback_, decoder))
Josh Coalson2051dd42001-04-12 22:22:34 +00001794 return false; /* the read_callback_ sets the state for us */
Josh Coalson2051dd42001-04-12 22:22:34 +00001795 residual[sample] = i;
1796 }
Josh Coalsonb28559a2002-04-25 05:21:09 +00001797#else
1798 u = (partition_order == 0 || partition > 0)? partition_samples : partition_samples - predictor_order;
1799 if(!FLAC__bitbuffer_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter, read_callback_, decoder))
1800 return false; /* the read_callback_ sets the state for us */
1801 sample += u;
1802#endif
Josh Coalson2051dd42001-04-12 22:22:34 +00001803 }
1804 else {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001805 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 +00001806 return false; /* the read_callback_ sets the state for us */
Josh Coalsona37ba462002-08-19 21:36:39 +00001807 partitioned_rice_contents->raw_bits[partition] = rice_parameter;
Josh Coalson2051dd42001-04-12 22:22:34 +00001808 for(u = (partition_order == 0 || partition > 0)? 0 : predictor_order; u < partition_samples; u++, sample++) {
Josh Coalsonaec256b2002-03-12 16:19:54 +00001809 if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &i, rice_parameter, read_callback_, decoder))
Josh Coalson2051dd42001-04-12 22:22:34 +00001810 return false; /* the read_callback_ sets the state for us */
1811 residual[sample] = i;
1812 }
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001813 }
1814 }
1815
1816 return true;
1817}
1818
Josh Coalson570db862002-07-31 06:58:16 +00001819FLAC__bool read_zero_padding_(FLAC__StreamDecoder *decoder)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001820{
Josh Coalsonaec256b2002-03-12 16:19:54 +00001821 if(!FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input)) {
Josh Coalson77e3f312001-06-23 03:03:24 +00001822 FLAC__uint32 zero = 0;
Josh Coalsonaec256b2002-03-12 16:19:54 +00001823 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 +00001824 return false; /* the read_callback_ sets the state for us */
1825 if(zero != 0) {
Josh Coalson090f8f72002-06-04 05:53:04 +00001826 decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, decoder->private_->client_data);
Josh Coalsonfa697a92001-08-16 20:07:29 +00001827 decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001828 }
1829 }
1830 return true;
1831}
1832
Josh Coalson77e3f312001-06-23 03:03:24 +00001833FLAC__bool read_callback_(FLAC__byte buffer[], unsigned *bytes, void *client_data)
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001834{
1835 FLAC__StreamDecoder *decoder = (FLAC__StreamDecoder *)client_data;
1836 FLAC__StreamDecoderReadStatus status;
Josh Coalsonaec256b2002-03-12 16:19:54 +00001837
Josh Coalsonfa697a92001-08-16 20:07:29 +00001838 status = decoder->private_->read_callback(decoder, buffer, bytes, decoder->private_->client_data);
Josh Coalson090f8f72002-06-04 05:53:04 +00001839 if(status == FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM)
Josh Coalsonfa697a92001-08-16 20:07:29 +00001840 decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM;
Josh Coalson090f8f72002-06-04 05:53:04 +00001841 else if(status == FLAC__STREAM_DECODER_READ_STATUS_ABORT)
Josh Coalsonfa697a92001-08-16 20:07:29 +00001842 decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED;
Josh Coalson090f8f72002-06-04 05:53:04 +00001843 return status == FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
Josh Coalsonbb7f6b92000-12-10 04:09:52 +00001844}