stream_decoder.c 48.8 KB
Newer Older
1
/* libFLAC - Free Lossless Audio Codec library
Josh Coalson's avatar
Josh Coalson committed
2
 * Copyright (C) 2000,2001  Josh Coalson
Josh Coalson's avatar
Josh Coalson committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA  02111-1307, USA.
 */

#include <assert.h>
#include <stdio.h>
#include <stdlib.h> /* for malloc() */
Josh Coalson's avatar
Josh Coalson committed
23
#include <string.h> /* for memset/memcpy() */
Josh Coalson's avatar
Josh Coalson committed
24
25
26
27
28
29
30
31
#include "FLAC/stream_decoder.h"
#include "private/bitbuffer.h"
#include "private/crc.h"
#include "private/fixed.h"
#include "private/lpc.h"

typedef struct FLAC__StreamDecoderPrivate {
	FLAC__StreamDecoderReadStatus (*read_callback)(const FLAC__StreamDecoder *decoder, byte buffer[], unsigned *bytes, void *client_data);
32
	FLAC__StreamDecoderWriteStatus (*write_callback)(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const int32 *buffer[], void *client_data);
Josh Coalson's avatar
Josh Coalson committed
33
34
35
36
37
	void (*metadata_callback)(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data);
	void (*error_callback)(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
	void *client_data;
	FLAC__BitBuffer input;
	int32 *output[FLAC__MAX_CHANNELS];
38
	int32 *residual[FLAC__MAX_CHANNELS];
39
	unsigned output_capacity, output_channels;
Josh Coalson's avatar
Josh Coalson committed
40
41
	uint32 last_frame_number;
	uint64 samples_decoded;
42
43
44
	bool has_stream_info, has_seek_table;
	FLAC__StreamMetaData stream_info;
	FLAC__StreamMetaData seek_table;
45
	FLAC__Frame frame;
46
47
48
	byte header_warmup[2]; /* contains the sync code and reserved bits */
	byte lookahead; /* temp storage when we need to look ahead one byte in the stream */
	bool cached; /* true if there is a byte in lookahead */
Josh Coalson's avatar
Josh Coalson committed
49
50
51
52
} FLAC__StreamDecoderPrivate;

static byte ID3V2_TAG_[3] = { 'I', 'D', '3' };

53
static bool stream_decoder_allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigned channels);
Josh Coalson's avatar
Josh Coalson committed
54
55
56
57
58
59
static bool stream_decoder_find_metadata_(FLAC__StreamDecoder *decoder);
static bool stream_decoder_read_metadata_(FLAC__StreamDecoder *decoder);
static bool stream_decoder_skip_id3v2_tag_(FLAC__StreamDecoder *decoder);
static bool stream_decoder_frame_sync_(FLAC__StreamDecoder *decoder);
static bool stream_decoder_read_frame_(FLAC__StreamDecoder *decoder, bool *got_a_frame);
static bool stream_decoder_read_frame_header_(FLAC__StreamDecoder *decoder);
60
61
62
63
64
static bool stream_decoder_read_subframe_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps);
static bool stream_decoder_read_subframe_constant_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps);
static bool stream_decoder_read_subframe_fixed_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order);
static bool stream_decoder_read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order);
static bool stream_decoder_read_subframe_verbatim_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps);
65
static bool stream_decoder_read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigned predictor_order, unsigned partition_order, int32 *residual);
Josh Coalson's avatar
Josh Coalson committed
66
67
68
static bool stream_decoder_read_zero_padding_(FLAC__StreamDecoder *decoder);
static bool read_callback_(byte buffer[], unsigned *bytes, void *client_data);

Josh Coalson's avatar
Josh Coalson committed
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
const char *FLAC__StreamDecoderStateString[] = {
	"FLAC__STREAM_DECODER_SEARCH_FOR_METADATA",
	"FLAC__STREAM_DECODER_READ_METADATA",
	"FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC",
	"FLAC__STREAM_DECODER_READ_FRAME",
	"FLAC__STREAM_DECODER_END_OF_STREAM",
	"FLAC__STREAM_DECODER_ABORTED",
	"FLAC__STREAM_DECODER_UNPARSEABLE_STREAM",
	"FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR",
	"FLAC__STREAM_DECODER_UNINITIALIZED"
};

const char *FLAC__StreamDecoderReadStatusString[] = {
	"FLAC__STREAM_DECODER_READ_CONTINUE",
	"FLAC__STREAM_DECODER_READ_END_OF_STREAM",
	"FLAC__STREAM_DECODER_READ_ABORT"
};

const char *FLAC__StreamDecoderWriteStatusString[] = {
	"FLAC__STREAM_DECODER_WRITE_CONTINUE",
	"FLAC__STREAM_DECODER_WRITE_ABORT"
};

const char *FLAC__StreamDecoderErrorStatusString[] = {
93
94
95
	"FLAC__STREAM_DECODER_ERROR_LOST_SYNC",
	"FLAC__STREAM_DECODER_ERROR_BAD_HEADER",
	"FLAC__STREAM_DECODER_ERROR_FRAME_CRC_MISMATCH"
Josh Coalson's avatar
Josh Coalson committed
96
97
};

Josh Coalson's avatar
Josh Coalson committed
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
FLAC__StreamDecoder *FLAC__stream_decoder_get_new_instance()
{
	FLAC__StreamDecoder *decoder = (FLAC__StreamDecoder*)malloc(sizeof(FLAC__StreamDecoder));
	if(decoder != 0) {
		decoder->state = FLAC__STREAM_DECODER_UNINITIALIZED;
		decoder->guts = 0;
	}
	return decoder;
}

void FLAC__stream_decoder_free_instance(FLAC__StreamDecoder *decoder)
{
	free(decoder);
}

FLAC__StreamDecoderState FLAC__stream_decoder_init(
	FLAC__StreamDecoder *decoder,
	FLAC__StreamDecoderReadStatus (*read_callback)(const FLAC__StreamDecoder *decoder, byte buffer[], unsigned *bytes, void *client_data),
116
	FLAC__StreamDecoderWriteStatus (*write_callback)(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const int32 *buffer[], void *client_data),
Josh Coalson's avatar
Josh Coalson committed
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
	void (*metadata_callback)(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data),
	void (*error_callback)(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data),
	void *client_data
)
{
	unsigned i;

	assert(sizeof(int) >= 4); /* we want to die right away if this is not true */
	assert(decoder != 0);
	assert(read_callback != 0);
	assert(write_callback != 0);
	assert(metadata_callback != 0);
	assert(error_callback != 0);
	assert(decoder->state == FLAC__STREAM_DECODER_UNINITIALIZED);
	assert(decoder->guts == 0);

	decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_METADATA;

	decoder->guts = (FLAC__StreamDecoderPrivate*)malloc(sizeof(FLAC__StreamDecoderPrivate));
	if(decoder->guts == 0)
		return decoder->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;

	decoder->guts->read_callback = read_callback;
	decoder->guts->write_callback = write_callback;
	decoder->guts->metadata_callback = metadata_callback;
	decoder->guts->error_callback = error_callback;
	decoder->guts->client_data = client_data;

	FLAC__bitbuffer_init(&decoder->guts->input);

147
	for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
Josh Coalson's avatar
Josh Coalson committed
148
		decoder->guts->output[i] = 0;
149
150
		decoder->guts->residual[i] = 0;
	}
Josh Coalson's avatar
Josh Coalson committed
151
152

	decoder->guts->output_capacity = 0;
153
	decoder->guts->output_channels = 0;
Josh Coalson's avatar
Josh Coalson committed
154
155
	decoder->guts->last_frame_number = 0;
	decoder->guts->samples_decoded = 0;
156
157
	decoder->guts->has_stream_info = false;
	decoder->guts->has_seek_table = false;
158
	decoder->guts->cached = false;
Josh Coalson's avatar
Josh Coalson committed
159
160
161
162
163
164
165
166
167
168
169

	return decoder->state;
}

void FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder)
{
	unsigned i;
	assert(decoder != 0);
	if(decoder->state == FLAC__STREAM_DECODER_UNINITIALIZED)
		return;
	if(decoder->guts != 0) {
170
171
172
173
		if(decoder->guts->has_seek_table) {
			free(decoder->guts->seek_table.data.seek_table.points);
			decoder->guts->seek_table.data.seek_table.points = 0;
		}
Josh Coalson's avatar
Josh Coalson committed
174
175
176
177
178
179
		FLAC__bitbuffer_free(&decoder->guts->input);
		for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
			if(decoder->guts->output[i] != 0) {
				free(decoder->guts->output[i]);
				decoder->guts->output[i] = 0;
			}
180
181
182
183
			if(decoder->guts->residual[i] != 0) {
				free(decoder->guts->residual[i]);
				decoder->guts->residual[i] = 0;
			}
Josh Coalson's avatar
Josh Coalson committed
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
		}
		free(decoder->guts);
		decoder->guts = 0;
	}
	decoder->state = FLAC__STREAM_DECODER_UNINITIALIZED;
}

bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder)
{
	assert(decoder != 0);

	if(!FLAC__bitbuffer_clear(&decoder->guts->input)) {
		decoder->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
		return false;
	}

	return true;
}

bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder)
{
	assert(decoder != 0);

	if(!FLAC__stream_decoder_flush(decoder)) {
		decoder->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
		return false;
	}
	decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_METADATA;

Josh Coalson's avatar
Josh Coalson committed
213
214
	decoder->guts->samples_decoded = 0;

Josh Coalson's avatar
Josh Coalson committed
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
	return true;
}

bool FLAC__stream_decoder_process_whole_stream(FLAC__StreamDecoder *decoder)
{
	bool dummy;
	assert(decoder != 0);

	if(decoder->state == FLAC__STREAM_DECODER_END_OF_STREAM)
		return true;

	assert(decoder->state == FLAC__STREAM_DECODER_SEARCH_FOR_METADATA);

	if(!FLAC__stream_decoder_reset(decoder)) {
		decoder->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
		return false;
	}

	while(1) {
		switch(decoder->state) {
			case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
				if(!stream_decoder_find_metadata_(decoder))
					return false; /* above function sets the status for us */
				break;
			case FLAC__STREAM_DECODER_READ_METADATA:
				if(!stream_decoder_read_metadata_(decoder))
					return false; /* above function sets the status for us */
				break;
			case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
				if(!stream_decoder_frame_sync_(decoder))
					return true; /* above function sets the status for us */
				break;
			case FLAC__STREAM_DECODER_READ_FRAME:
				if(!stream_decoder_read_frame_(decoder, &dummy))
					return false; /* above function sets the status for us */
				break;
			case FLAC__STREAM_DECODER_END_OF_STREAM:
				return true;
			default:
				assert(0);
		}
	}
}

bool FLAC__stream_decoder_process_metadata(FLAC__StreamDecoder *decoder)
{
	assert(decoder != 0);

	if(decoder->state == FLAC__STREAM_DECODER_END_OF_STREAM)
		return true;

	assert(decoder->state == FLAC__STREAM_DECODER_SEARCH_FOR_METADATA);

	if(!FLAC__stream_decoder_reset(decoder)) {
		decoder->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
		return false;
	}

	while(1) {
		switch(decoder->state) {
			case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
				if(!stream_decoder_find_metadata_(decoder))
					return false; /* above function sets the status for us */
				break;
			case FLAC__STREAM_DECODER_READ_METADATA:
				if(!stream_decoder_read_metadata_(decoder))
					return false; /* above function sets the status for us */
				break;
			case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
				return true;
				break;
			case FLAC__STREAM_DECODER_END_OF_STREAM:
				return true;
			default:
				assert(0);
		}
	}
}

bool FLAC__stream_decoder_process_one_frame(FLAC__StreamDecoder *decoder)
{
	bool got_a_frame;
	assert(decoder != 0);

	if(decoder->state == FLAC__STREAM_DECODER_END_OF_STREAM)
		return true;

	assert(decoder->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC);

	while(1) {
		switch(decoder->state) {
			case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
				if(!stream_decoder_frame_sync_(decoder))
					return true; /* above function sets the status for us */
				break;
			case FLAC__STREAM_DECODER_READ_FRAME:
				if(!stream_decoder_read_frame_(decoder, &got_a_frame))
					return false; /* above function sets the status for us */
				if(got_a_frame)
					return true; /* above function sets the status for us */
				break;
			case FLAC__STREAM_DECODER_END_OF_STREAM:
				return true;
			default:
				assert(0);
		}
	}
}

bool FLAC__stream_decoder_process_remaining_frames(FLAC__StreamDecoder *decoder)
{
	bool dummy;
	assert(decoder != 0);

	if(decoder->state == FLAC__STREAM_DECODER_END_OF_STREAM)
		return true;

	assert(decoder->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC);

	while(1) {
		switch(decoder->state) {
			case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
				if(!stream_decoder_frame_sync_(decoder))
					return true; /* above function sets the status for us */
				break;
			case FLAC__STREAM_DECODER_READ_FRAME:
				if(!stream_decoder_read_frame_(decoder, &dummy))
					return false; /* above function sets the status for us */
				break;
			case FLAC__STREAM_DECODER_END_OF_STREAM:
				return true;
			default:
				assert(0);
		}
	}
}

unsigned FLAC__stream_decoder_input_bytes_unconsumed(FLAC__StreamDecoder *decoder)
{
	assert(decoder != 0);
	return decoder->guts->input.bytes - decoder->guts->input.consumed_bytes;
}

358
bool stream_decoder_allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigned channels)
Josh Coalson's avatar
Josh Coalson committed
359
360
361
362
{
	unsigned i;
	int32 *tmp;

363
	if(size <= decoder->guts->output_capacity && channels <= decoder->guts->output_channels)
Josh Coalson's avatar
Josh Coalson committed
364
365
		return true;

366
367
	/* @@@ should change to use realloc() */

Josh Coalson's avatar
Josh Coalson committed
368
369
370
371
372
	for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
		if(decoder->guts->output[i] != 0) {
			free(decoder->guts->output[i]);
			decoder->guts->output[i] = 0;
		}
373
374
375
376
		if(decoder->guts->residual[i] != 0) {
			free(decoder->guts->residual[i]);
			decoder->guts->residual[i] = 0;
		}
Josh Coalson's avatar
Josh Coalson committed
377
378
	}

379
	for(i = 0; i < channels; i++) {
Josh Coalson's avatar
Josh Coalson committed
380
381
382
383
384
385
		tmp = (int32*)malloc(sizeof(int32)*size);
		if(tmp == 0) {
			decoder->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
			return false;
		}
		decoder->guts->output[i] = tmp;
386
387
388
389
390
391
392

		tmp = (int32*)malloc(sizeof(int32)*size);
		if(tmp == 0) {
			decoder->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
			return false;
		}
		decoder->guts->residual[i] = tmp;
Josh Coalson's avatar
Josh Coalson committed
393
394
395
	}

	decoder->guts->output_capacity = size;
396
	decoder->guts->output_channels = channels;
Josh Coalson's avatar
Josh Coalson committed
397
398
399
400
401
402
403
404

	return true;
}

bool stream_decoder_find_metadata_(FLAC__StreamDecoder *decoder)
{
	uint32 x;
	unsigned i, id;
405
	bool first = true;
Josh Coalson's avatar
Josh Coalson committed
406
407
408
409

	assert(decoder->guts->input.consumed_bits == 0); /* make sure we're byte aligned */

	for(i = id = 0; i < 4; ) {
410
411
412
413
414
415
416
417
		if(decoder->guts->cached) {
			x = (uint32)decoder->guts->lookahead;
			decoder->guts->cached = false;
		}
		else {
			if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
				return false; /* the read_callback_ sets the state for us */
		}
Josh Coalson's avatar
Josh Coalson committed
418
		if(x == FLAC__STREAM_SYNC_STRING[i]) {
419
			first = true;
Josh Coalson's avatar
Josh Coalson committed
420
421
422
423
424
425
426
427
428
429
430
431
432
433
			i++;
			id = 0;
			continue;
		}
		if(x == ID3V2_TAG_[id]) {
			id++;
			i = 0;
			if(id == 3) {
				if(!stream_decoder_skip_id3v2_tag_(decoder))
					return false; /* the read_callback_ sets the state for us */
			}
			continue;
		}
		if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
434
435
			decoder->guts->header_warmup[0] = (byte)x;
			if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
Josh Coalson's avatar
Josh Coalson committed
436
				return false; /* the read_callback_ sets the state for us */
437
438
439
440
441
442
443
444
445

			/* we have to check if we just read two 0xff's in a row; the second may actually be the beginning of the sync code */
			/* else we have to check if the second byte is the end of a sync code */
			if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
				decoder->guts->lookahead = (byte)x;
				decoder->guts->cached = true;
			}
			else if(x >> 2 == 0x3e) { /* MAGIC NUMBER for the last 6 sync bits */
				decoder->guts->header_warmup[1] = (byte)x;
Josh Coalson's avatar
Josh Coalson committed
446
447
448
449
450
451
452
				decoder->state = FLAC__STREAM_DECODER_READ_FRAME;
				return true;
			}
		}
		i = 0;
		if(first) {
			decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
453
			first = false;
Josh Coalson's avatar
Josh Coalson committed
454
455
456
457
458
459
460
461
462
463
		}
	}

	decoder->state = FLAC__STREAM_DECODER_READ_METADATA;
	return true;
}

bool stream_decoder_read_metadata_(FLAC__StreamDecoder *decoder)
{
	uint32 i, x, last_block, type, length;
464
	uint64 xx;
Josh Coalson's avatar
Josh Coalson committed
465
466
467
468
469
470
471
472
473

	assert(decoder->guts->input.consumed_bits == 0); /* make sure we're byte aligned */

	if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &last_block, FLAC__STREAM_METADATA_IS_LAST_LEN, read_callback_, decoder))
		return false; /* the read_callback_ sets the state for us */
	if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &type, FLAC__STREAM_METADATA_TYPE_LEN, read_callback_, decoder))
		return false; /* the read_callback_ sets the state for us */
	if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &length, FLAC__STREAM_METADATA_LENGTH_LEN, read_callback_, decoder))
		return false; /* the read_callback_ sets the state for us */
Josh Coalson's avatar
Josh Coalson committed
474
	if(type == FLAC__METADATA_TYPE_STREAMINFO) {
475
		unsigned used_bits = 0;
476
477
478
		decoder->guts->stream_info.type = type;
		decoder->guts->stream_info.is_last = last_block;
		decoder->guts->stream_info.length = length;
479

Josh Coalson's avatar
Josh Coalson committed
480
		if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN, read_callback_, decoder))
Josh Coalson's avatar
Josh Coalson committed
481
			return false; /* the read_callback_ sets the state for us */
482
		decoder->guts->stream_info.data.stream_info.min_blocksize = x;
Josh Coalson's avatar
Josh Coalson committed
483
		used_bits += FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN;
484

Josh Coalson's avatar
Josh Coalson committed
485
		if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN, read_callback_, decoder))
Josh Coalson's avatar
Josh Coalson committed
486
			return false; /* the read_callback_ sets the state for us */
487
		decoder->guts->stream_info.data.stream_info.max_blocksize = x;
Josh Coalson's avatar
Josh Coalson committed
488
		used_bits += FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN;
489

Josh Coalson's avatar
Josh Coalson committed
490
		if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN, read_callback_, decoder))
Josh Coalson's avatar
Josh Coalson committed
491
			return false; /* the read_callback_ sets the state for us */
492
		decoder->guts->stream_info.data.stream_info.min_framesize = x;
Josh Coalson's avatar
Josh Coalson committed
493
		used_bits += FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN;
494

Josh Coalson's avatar
Josh Coalson committed
495
		if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN, read_callback_, decoder))
Josh Coalson's avatar
Josh Coalson committed
496
			return false; /* the read_callback_ sets the state for us */
497
		decoder->guts->stream_info.data.stream_info.max_framesize = x;
Josh Coalson's avatar
Josh Coalson committed
498
		used_bits += FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN;
499

Josh Coalson's avatar
Josh Coalson committed
500
		if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN, read_callback_, decoder))
Josh Coalson's avatar
Josh Coalson committed
501
			return false; /* the read_callback_ sets the state for us */
502
		decoder->guts->stream_info.data.stream_info.sample_rate = x;
Josh Coalson's avatar
Josh Coalson committed
503
		used_bits += FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN;
504

Josh Coalson's avatar
Josh Coalson committed
505
		if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN, read_callback_, decoder))
Josh Coalson's avatar
Josh Coalson committed
506
			return false; /* the read_callback_ sets the state for us */
507
		decoder->guts->stream_info.data.stream_info.channels = x+1;
Josh Coalson's avatar
Josh Coalson committed
508
		used_bits += FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN;
509

Josh Coalson's avatar
Josh Coalson committed
510
		if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN, read_callback_, decoder))
Josh Coalson's avatar
Josh Coalson committed
511
			return false; /* the read_callback_ sets the state for us */
512
		decoder->guts->stream_info.data.stream_info.bits_per_sample = x+1;
Josh Coalson's avatar
Josh Coalson committed
513
		used_bits += FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN;
514

515
		if(!FLAC__bitbuffer_read_raw_uint64(&decoder->guts->input, &decoder->guts->stream_info.data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN, read_callback_, decoder))
Josh Coalson's avatar
Josh Coalson committed
516
			return false; /* the read_callback_ sets the state for us */
Josh Coalson's avatar
Josh Coalson committed
517
		used_bits += FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN;
518

Josh Coalson's avatar
Josh Coalson committed
519
520
521
		for(i = 0; i < 16; i++) {
			if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
				return false; /* the read_callback_ sets the state for us */
522
			decoder->guts->stream_info.data.stream_info.md5sum[i] = (byte)x;
Josh Coalson's avatar
Josh Coalson committed
523
		}
524
		used_bits += i*8;
Josh Coalson's avatar
Josh Coalson committed
525

526
527
528
529
530
531
532
533
		/* skip the rest of the block */
		assert(used_bits % 8 == 0);
		length -= (used_bits / 8);
		for(i = 0; i < length; i++) {
			if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
				return false; /* the read_callback_ sets the state for us */
		}

534
535
536
537
		decoder->guts->has_stream_info = true;
		decoder->guts->metadata_callback(decoder, &decoder->guts->stream_info, decoder->guts->client_data);
	}
	else if(type == FLAC__METADATA_TYPE_SEEKTABLE) {
Josh Coalson's avatar
Josh Coalson committed
538
539
		unsigned real_points;

540
541
542
543
544
545
546
547
548
549
		decoder->guts->seek_table.type = type;
		decoder->guts->seek_table.is_last = last_block;
		decoder->guts->seek_table.length = length;

		decoder->guts->seek_table.data.seek_table.num_points = length / FLAC__STREAM_METADATA_SEEKPOINT_LEN;

		if(0 == (decoder->guts->seek_table.data.seek_table.points = (FLAC__StreamMetaData_SeekPoint*)malloc(decoder->guts->seek_table.data.seek_table.num_points * sizeof(FLAC__StreamMetaData_SeekPoint)))) {
			decoder->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
			return false;
		}
Josh Coalson's avatar
Josh Coalson committed
550
		for(i = real_points = 0; i < decoder->guts->seek_table.data.seek_table.num_points; i++) {
551
552
			if(!FLAC__bitbuffer_read_raw_uint64(&decoder->guts->input, &xx, FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN, read_callback_, decoder))
				return false; /* the read_callback_ sets the state for us */
Josh Coalson's avatar
Josh Coalson committed
553
			decoder->guts->seek_table.data.seek_table.points[real_points].sample_number = xx;
554
555
556

			if(!FLAC__bitbuffer_read_raw_uint64(&decoder->guts->input, &xx, FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN, read_callback_, decoder))
				return false; /* the read_callback_ sets the state for us */
Josh Coalson's avatar
Josh Coalson committed
557
			decoder->guts->seek_table.data.seek_table.points[real_points].stream_offset = xx;
558

Josh Coalson's avatar
Josh Coalson committed
559
			if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN, read_callback_, decoder))
560
				return false; /* the read_callback_ sets the state for us */
Josh Coalson's avatar
Josh Coalson committed
561
562
563
564
			decoder->guts->seek_table.data.seek_table.points[real_points].frame_samples = x;

			if(decoder->guts->seek_table.data.seek_table.points[real_points].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER)
				real_points++;
565
		}
Josh Coalson's avatar
Josh Coalson committed
566
		decoder->guts->seek_table.data.seek_table.num_points = real_points;
567
568
569

		decoder->guts->has_seek_table = true;
		decoder->guts->metadata_callback(decoder, &decoder->guts->seek_table, decoder->guts->client_data);
Josh Coalson's avatar
Josh Coalson committed
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
	}
	else {
		/* skip other metadata blocks */
		for(i = 0; i < length; i++) {
			if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
				return false; /* the read_callback_ sets the state for us */
		}
	}

	if(last_block)
		decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;

	return true;
}

bool stream_decoder_skip_id3v2_tag_(FLAC__StreamDecoder *decoder)
{
	uint32 x;
	unsigned i, skip;

	/* skip the version and flags bytes */
	if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 24, read_callback_, decoder))
		return false; /* the read_callback_ sets the state for us */
	/* get the size (in bytes) to skip */
	skip = 0;
	for(i = 0; i < 4; i++) {
		if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
			return false; /* the read_callback_ sets the state for us */
		skip <<= 7;
		skip |= (x & 0x7f);
	}
	/* skip the rest of the tag */
	for(i = 0; i < skip; i++) {
		if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
			return false; /* the read_callback_ sets the state for us */
	}
	return true;
}

bool stream_decoder_frame_sync_(FLAC__StreamDecoder *decoder)
{
	uint32 x;
612
	bool first = true;
Josh Coalson's avatar
Josh Coalson committed
613
614
615

	/* If we know the total number of samples in the stream, stop if we've read that many. */
	/* This will stop us, for example, from wasting time trying to sync on an ID3V1 tag. */
616
617
	if(decoder->guts->has_stream_info && decoder->guts->stream_info.data.stream_info.total_samples) {
		if(decoder->guts->samples_decoded >= decoder->guts->stream_info.data.stream_info.total_samples) {
Josh Coalson's avatar
Josh Coalson committed
618
619
620
621
622
623
624
625
626
627
628
629
			decoder->state = FLAC__STREAM_DECODER_END_OF_STREAM;
			return true;
		}
	}

	/* make sure we're byte aligned */
	if(decoder->guts->input.consumed_bits != 0) {
		if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8-decoder->guts->input.consumed_bits, read_callback_, decoder))
			return false; /* the read_callback_ sets the state for us */
	}

	while(1) {
630
631
632
633
634
635
636
637
		if(decoder->guts->cached) {
			x = (uint32)decoder->guts->lookahead;
			decoder->guts->cached = false;
		}
		else {
			if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
				return false; /* the read_callback_ sets the state for us */
		}
Josh Coalson's avatar
Josh Coalson committed
638
		if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
639
640
			decoder->guts->header_warmup[0] = (byte)x;
			if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
Josh Coalson's avatar
Josh Coalson committed
641
				return false; /* the read_callback_ sets the state for us */
642
643
644
645
646
647
648
649
650

			/* we have to check if we just read two 0xff's in a row; the second may actually be the beginning of the sync code */
			/* else we have to check if the second byte is the end of a sync code */
			if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
				decoder->guts->lookahead = (byte)x;
				decoder->guts->cached = true;
			}
			else if(x >> 2 == 0x3e) { /* MAGIC NUMBER for the last 6 sync bits */
				decoder->guts->header_warmup[1] = (byte)x;
Josh Coalson's avatar
Josh Coalson committed
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
				decoder->state = FLAC__STREAM_DECODER_READ_FRAME;
				return true;
			}
		}
		if(first) {
			decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
			first = 0;
		}
	}

	return true;
}

bool stream_decoder_read_frame_(FLAC__StreamDecoder *decoder, bool *got_a_frame)
{
	unsigned channel;
	unsigned i;
	int32 mid, side, left, right;
669
670
	uint16 frame_crc; /* the one we calculate from the input stream */
	uint32 x;
Josh Coalson's avatar
Josh Coalson committed
671
672
673

	*got_a_frame = false;

674
675
676
677
678
679
	/* init the CRC */
	frame_crc = 0;
	FLAC__CRC16_UPDATE(decoder->guts->header_warmup[0], frame_crc);
	FLAC__CRC16_UPDATE(decoder->guts->header_warmup[1], frame_crc);
	FLAC__bitbuffer_init_read_crc16(&decoder->guts->input, frame_crc);

Josh Coalson's avatar
Josh Coalson committed
680
681
	if(!stream_decoder_read_frame_header_(decoder))
		return false;
682
	if(decoder->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC)
Josh Coalson's avatar
Josh Coalson committed
683
		return true;
684
	if(!stream_decoder_allocate_output_(decoder, decoder->guts->frame.header.blocksize, decoder->guts->frame.header.channels))
Josh Coalson's avatar
Josh Coalson committed
685
		return false;
686
	for(channel = 0; channel < decoder->guts->frame.header.channels; channel++) {
687
688
689
690
691
692
693
694
695
		/*
		 * first figure the correct bits-per-sample of the subframe
		 */
		unsigned bps = decoder->guts->frame.header.bits_per_sample;
		switch(decoder->guts->frame.header.channel_assignment) {
			case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
				/* no adjustment needed */
				break;
			case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
Josh Coalson's avatar
Josh Coalson committed
696
				assert(decoder->guts->frame.header.channels == 2);
697
698
699
700
				if(channel == 1)
					bps++;
				break;
			case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
Josh Coalson's avatar
Josh Coalson committed
701
				assert(decoder->guts->frame.header.channels == 2);
702
703
704
705
				if(channel == 0)
					bps++;
				break;
			case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
Josh Coalson's avatar
Josh Coalson committed
706
				assert(decoder->guts->frame.header.channels == 2);
707
708
709
710
711
712
713
714
715
716
				if(channel == 1)
					bps++;
				break;
			default:
				assert(0);
		}
		/*
		 * now read it
		 */
		if(!stream_decoder_read_subframe_(decoder, channel, bps))
Josh Coalson's avatar
Josh Coalson committed
717
718
719
720
721
722
723
724
725
			return false;
		if(decoder->state != FLAC__STREAM_DECODER_READ_FRAME) {
			decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
			return true;
		}
	}
	if(!stream_decoder_read_zero_padding_(decoder))
		return false;

726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
	/*
	 * Read the frame CRC-16 from the footer and check
	 */
	frame_crc = decoder->guts->input.read_crc16;
	if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, FLAC__FRAME_FOOTER_CRC_LEN, read_callback_, decoder))
		return false; /* the read_callback_ sets the state for us */
	if(frame_crc == (uint16)x) {
		/* Undo any special channel coding */
		switch(decoder->guts->frame.header.channel_assignment) {
			case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
				/* do nothing */
				break;
			case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
				assert(decoder->guts->frame.header.channels == 2);
				for(i = 0; i < decoder->guts->frame.header.blocksize; i++)
					decoder->guts->output[1][i] = decoder->guts->output[0][i] - decoder->guts->output[1][i];
				break;
			case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
				assert(decoder->guts->frame.header.channels == 2);
				for(i = 0; i < decoder->guts->frame.header.blocksize; i++)
					decoder->guts->output[0][i] += decoder->guts->output[1][i];
				break;
			case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
				assert(decoder->guts->frame.header.channels == 2);
				for(i = 0; i < decoder->guts->frame.header.blocksize; i++) {
					mid = decoder->guts->output[0][i];
					side = decoder->guts->output[1][i];
					mid <<= 1;
					if(side & 1) /* i.e. if 'side' is odd... */
						mid++;
					left = mid + side;
					right = mid - side;
					decoder->guts->output[0][i] = left >> 1;
					decoder->guts->output[1][i] = right >> 1;
				}
				break;
			default:
				assert(0);
				break;
		}
	}
	else {
		/* Bad frame, emit error and zero the output signal */
		decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_FRAME_CRC_MISMATCH, decoder->guts->client_data);
		for(channel = 0; channel < decoder->guts->frame.header.channels; channel++) {
			memset(decoder->guts->output[channel], 0, sizeof(int32) * decoder->guts->frame.header.blocksize);
		}
Josh Coalson's avatar
Josh Coalson committed
773
774
775
776
777
	}

	*got_a_frame = true;

	/* put the latest values into the public section of the decoder instance */
778
779
780
781
782
	decoder->channels = decoder->guts->frame.header.channels;
	decoder->channel_assignment = decoder->guts->frame.header.channel_assignment;
	decoder->bits_per_sample = decoder->guts->frame.header.bits_per_sample;
	decoder->sample_rate = decoder->guts->frame.header.sample_rate;
	decoder->blocksize = decoder->guts->frame.header.blocksize;
Josh Coalson's avatar
Josh Coalson committed
783

Josh Coalson's avatar
Josh Coalson committed
784
	decoder->guts->samples_decoded = decoder->guts->frame.header.number.sample_number + decoder->guts->frame.header.blocksize;
Josh Coalson's avatar
Josh Coalson committed
785
786

	/* write it */
787
	/* NOTE: some versions of GCC can't figure out const-ness right and will give you an 'incompatible pointer type' warning on arg 3 here: */
788
	if(decoder->guts->write_callback(decoder, &decoder->guts->frame, decoder->guts->output, decoder->guts->client_data) != FLAC__STREAM_DECODER_WRITE_CONTINUE)
Josh Coalson's avatar
Josh Coalson committed
789
790
791
792
793
794
795
796
797
798
799
		return false;

	decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
	return true;
}

bool stream_decoder_read_frame_header_(FLAC__StreamDecoder *decoder)
{
	uint32 x;
	uint64 xx;
	unsigned i, blocksize_hint = 0, sample_rate_hint = 0;
800
	byte crc8, raw_header[16]; /* MAGIC NUMBER based on the maximum frame header size, including CRC */
Josh Coalson's avatar
Josh Coalson committed
801
802
	unsigned raw_header_len;
	bool is_unparseable = false;
803
804
	const bool is_known_variable_blocksize_stream = (decoder->guts->has_stream_info && decoder->guts->stream_info.data.stream_info.min_blocksize != decoder->guts->stream_info.data.stream_info.max_blocksize);
	const bool is_known_fixed_blocksize_stream = (decoder->guts->has_stream_info && decoder->guts->stream_info.data.stream_info.min_blocksize == decoder->guts->stream_info.data.stream_info.max_blocksize);
Josh Coalson's avatar
Josh Coalson committed
805
806
807

	assert(decoder->guts->input.consumed_bits == 0); /* make sure we're byte aligned */

808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
	/* init the raw header with the saved bits from synchronization */
	raw_header[0] = decoder->guts->header_warmup[0];
	raw_header[1] = decoder->guts->header_warmup[1];
	raw_header_len = 2;

	/*
	 * check to make sure that the reserved bits are 0
	 */
	if(raw_header[1] & 0x03) { /* MAGIC NUMBER */
		is_unparseable = true;
	}

	/*
	 * Note that along the way as we read the header, we look for a sync
	 * code inside.  If we find one it would indicate that our original
	 * sync was bad since there cannot be a sync code in a valid header.
	 */
Josh Coalson's avatar
Josh Coalson committed
825
826
827
828
829
830
831

	/*
	 * read in the raw header as bytes so we can CRC it, and parse it on the way
	 */
	for(i = 0; i < 2; i++) {
		if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
			return false; /* the read_callback_ sets the state for us */
832
		if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
Josh Coalson's avatar
Josh Coalson committed
833
			/* if we get here it means our original sync was erroneous since the sync code cannot appear in the header */
834
835
836
837
838
			decoder->guts->lookahead = (byte)x;
			decoder->guts->cached = true;
			decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_BAD_HEADER, decoder->guts->client_data);
			decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
			return true;
Josh Coalson's avatar
Josh Coalson committed
839
840
841
842
		}
		raw_header[raw_header_len++] = (byte)x;
	}

843
	switch(x = raw_header[2] >> 4) {
Josh Coalson's avatar
Josh Coalson committed
844
		case 0:
845
			if(is_known_fixed_blocksize_stream)
846
				decoder->guts->frame.header.blocksize = decoder->guts->stream_info.data.stream_info.min_blocksize;
Josh Coalson's avatar
Josh Coalson committed
847
848
849
850
			else
				is_unparseable = true;
			break;
		case 1:
851
			decoder->guts->frame.header.blocksize = 192;
Josh Coalson's avatar
Josh Coalson committed
852
853
854
855
856
			break;
		case 2:
		case 3:
		case 4:
		case 5:
857
			decoder->guts->frame.header.blocksize = 576 << (x-2);
Josh Coalson's avatar
Josh Coalson committed
858
859
860
861
862
			break;
		case 6:
		case 7:
			blocksize_hint = x;
			break;
863
864
865
866
867
868
869
870
871
872
		case 8:
		case 9:
		case 10:
		case 11:
		case 12:
		case 13:
		case 14:
		case 15:
			decoder->guts->frame.header.blocksize = 256 << (x-8);
			break;
Josh Coalson's avatar
Josh Coalson committed
873
874
875
876
877
		default:
			assert(0);
			break;
	}

878
	switch(x = raw_header[2] & 0x0f) {
Josh Coalson's avatar
Josh Coalson committed
879
		case 0:
880
881
			if(decoder->guts->has_stream_info)
				decoder->guts->frame.header.sample_rate = decoder->guts->stream_info.data.stream_info.sample_rate;
Josh Coalson's avatar
Josh Coalson committed
882
883
884
885
886
887
888
889
890
			else
				is_unparseable = true;
			break;
		case 1:
		case 2:
		case 3:
			is_unparseable = true;
			break;
		case 4:
891
			decoder->guts->frame.header.sample_rate = 8000;
Josh Coalson's avatar
Josh Coalson committed
892
893
			break;
		case 5:
894
			decoder->guts->frame.header.sample_rate = 16000;
Josh Coalson's avatar
Josh Coalson committed
895
896
			break;
		case 6:
897
			decoder->guts->frame.header.sample_rate = 22050;
Josh Coalson's avatar
Josh Coalson committed
898
899
			break;
		case 7:
900
			decoder->guts->frame.header.sample_rate = 24000;
Josh Coalson's avatar
Josh Coalson committed
901
902
			break;
		case 8:
903
			decoder->guts->frame.header.sample_rate = 32000;
Josh Coalson's avatar
Josh Coalson committed
904
905
			break;
		case 9:
906
			decoder->guts->frame.header.sample_rate = 44100;
Josh Coalson's avatar
Josh Coalson committed
907
908
			break;
		case 10:
909
			decoder->guts->frame.header.sample_rate = 48000;
Josh Coalson's avatar
Josh Coalson committed
910
911
			break;
		case 11:
912
			decoder->guts->frame.header.sample_rate = 96000;
Josh Coalson's avatar
Josh Coalson committed
913
914
915
916
917
918
919
			break;
		case 12:
		case 13:
		case 14:
			sample_rate_hint = x;
			break;
		case 15:
920
			decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_BAD_HEADER, decoder->guts->client_data);
Josh Coalson's avatar
Josh Coalson committed
921
922
923
924
925
926
			decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
			return true;
		default:
			assert(0);
	}

927
	x = (unsigned)(raw_header[3] >> 4);
Josh Coalson's avatar
Josh Coalson committed
928
	if(x & 8) {
929
		decoder->guts->frame.header.channels = 2;
Josh Coalson's avatar
Josh Coalson committed
930
931
		switch(x & 7) {
			case 0:
932
				decoder->guts->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE;
Josh Coalson's avatar
Josh Coalson committed
933
934
				break;
			case 1:
935
				decoder->guts->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE;
Josh Coalson's avatar
Josh Coalson committed
936
937
				break;
			case 2:
938
				decoder->guts->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_MID_SIDE;
Josh Coalson's avatar
Josh Coalson committed
939
940
941
942
943
944
945
				break;
			default:
				is_unparseable = true;
				break;
		}
	}
	else {
946
947
		decoder->guts->frame.header.channels = (unsigned)x + 1;
		decoder->guts->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT;
Josh Coalson's avatar
Josh Coalson committed
948
949
	}

950
	switch(x = (unsigned)(raw_header[3] & 0x0e) >> 1) {
Josh Coalson's avatar
Josh Coalson committed
951
		case 0:
952
953
			if(decoder->guts->has_stream_info)
				decoder->guts->frame.header.bits_per_sample = decoder->guts->stream_info.data.stream_info.bits_per_sample;
Josh Coalson's avatar
Josh Coalson committed
954
955
956
957
			else
				is_unparseable = true;
			break;
		case 1:
958
			decoder->guts->frame.header.bits_per_sample = 8;
Josh Coalson's avatar
Josh Coalson committed
959
960
			break;
		case 2:
961
			decoder->guts->frame.header.bits_per_sample = 12;
Josh Coalson's avatar
Josh Coalson committed
962
963
			break;
		case 4:
964
			decoder->guts->frame.header.bits_per_sample = 16;
Josh Coalson's avatar
Josh Coalson committed
965
966
			break;
		case 5:
967
			decoder->guts->frame.header.bits_per_sample = 20;
Josh Coalson's avatar
Josh Coalson committed
968
969
			break;
		case 6:
970
			decoder->guts->frame.header.bits_per_sample = 24;
Josh Coalson's avatar
Josh Coalson committed
971
972
973
974
975
976
977
978
979
980
			break;
		case 3:
		case 7:
			is_unparseable = true;
			break;
		default:
			assert(0);
			break;
	}

981
982
	if(raw_header[3] & 0x01) { /* this should be a zero padding bit */
		decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_BAD_HEADER, decoder->guts->client_data);
Josh Coalson's avatar
Josh Coalson committed
983
984
985
986
		decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
		return true;
	}

987
	if(blocksize_hint && is_known_variable_blocksize_stream) {
Josh Coalson's avatar
Josh Coalson committed
988
989
		if(!FLAC__bitbuffer_read_utf8_uint64(&decoder->guts->input, &xx, read_callback_, decoder, raw_header, &raw_header_len))
			return false; /* the read_callback_ sets the state for us */
990
991
992
993
994
995
		if(xx == 0xffffffffffffffff) { /* i.e. non-UTF8 code... */
			decoder->guts->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */
			decoder->guts->cached = true;
			decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_BAD_HEADER, decoder->guts->client_data);
			decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
			return true;
Josh Coalson's avatar
Josh Coalson committed
996
		}
997
		decoder->guts->frame.header.number.sample_number = xx;
Josh Coalson's avatar
Josh Coalson committed
998
999
1000
1001
	}
	else {
		if(!FLAC__bitbuffer_read_utf8_uint32(&decoder->guts->input, &x, read_callback_, decoder, raw_header, &raw_header_len))
			return false; /* the read_callback_ sets the state for us */
1002
1003
1004
1005
1006
1007
		if(x == 0xffffffff) { /* i.e. non-UTF8 code... */
			decoder->guts->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */
			decoder->guts->cached = true;
			decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_BAD_HEADER, decoder->guts->client_data);
			decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
			return true;
Josh Coalson's avatar
Josh Coalson committed
1008
1009
		}
		decoder->guts->last_frame_number = x;
1010
1011
		if(decoder->guts->has_stream_info) {
			decoder->guts->frame.header.number.sample_number = (int64)decoder->guts->stream_info.data.stream_info.min_blocksize * (int64)x;
Josh Coalson's avatar
Josh Coalson committed
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
		}
		else {
			is_unparseable = true;
		}
	}

	if(blocksize_hint) {
		if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
			return false; /* the read_callback_ sets the state for us */
		raw_header[raw_header_len++] = (byte)x;
		if(blocksize_hint == 7) {
			uint32 _x;
			if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &_x, 8, read_callback_, decoder))
				return false; /* the read_callback_ sets the state for us */
			raw_header[raw_header_len++] = (byte)_x;
			x = (x << 8) | _x;
		}
1029
		decoder->guts->frame.header.blocksize = x+1;
Josh Coalson's avatar
Josh Coalson committed
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
	}

	if(sample_rate_hint) {
		if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
			return false; /* the read_callback_ sets the state for us */
		raw_header[raw_header_len++] = (byte)x;
		if(sample_rate_hint != 12) {
			uint32 _x;
			if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &_x, 8, read_callback_, decoder))
				return false; /* the read_callback_ sets the state for us */
			raw_header[raw_header_len++] = (byte)_x;
			x = (x << 8) | _x;
		}
		if(sample_rate_hint == 12)
1044
			decoder->guts->frame.header.sample_rate = x*1000;
Josh Coalson's avatar
Josh Coalson committed
1045
		else if(sample_rate_hint == 13)
1046
			decoder->guts->frame.header.sample_rate = x;
Josh Coalson's avatar
Josh Coalson committed
1047
		else
1048
			decoder->guts->frame.header.sample_rate = x*10;
Josh Coalson's avatar
Josh Coalson committed
1049
1050
	}

1051
	/* read the CRC-8 byte */
Josh Coalson's avatar
Josh Coalson committed
1052
1053
	if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
		return false; /* the read_callback_ sets the state for us */
1054
	crc8 = (byte)x;
Josh Coalson's avatar
Josh Coalson committed
1055

1056
1057
	if(FLAC__crc8(raw_header, raw_header_len) != crc8) {
		decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_BAD_HEADER, decoder->guts->client_data);
Josh Coalson's avatar
Josh Coalson committed
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
		decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
		return true;
	}

	if(is_unparseable) {
		decoder->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
		return false;
	}

	return true;
}

1070
bool stream_decoder_read_subframe_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps)
Josh Coalson's avatar
Josh Coalson committed
1071
1072
{
	uint32 x;
1073
	bool wasted_bits;
Josh Coalson's avatar
Josh Coalson committed
1074

1075
	if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder)) /* MAGIC NUMBER */
Josh Coalson's avatar
Josh Coalson committed
1076
		return false; /* the read_callback_ sets the state for us */
1077
1078
1079
1080
1081
1082
1083
1084
1085

	wasted_bits = (x & 1);
	x &= 0xfe;

	if(wasted_bits) {
		unsigned u;
		if(!FLAC__bitbuffer_read_unary_unsigned(&decoder->guts->input, &u, read_callback_, decoder))
			return false; /* the read_callback_ sets the state for us */
		decoder->guts->frame.subframes[channel].wasted_bits = u+1;
1086
		bps -= decoder->guts->frame.subframes[channel].wasted_bits;
1087
1088
1089
1090
	}
	else
		decoder->guts->frame.subframes[channel].wasted_bits = 0;

1091
1092
1093
	/*
	 * Lots of magic numbers here
	 */
1094
	if(x & 0x80) {
Josh Coalson's avatar
Josh Coalson committed
1095
1096
1097
1098
1099
		decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
		decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
		return true;
	}
	else if(x == 0) {
1100
1101
		if(!stream_decoder_read_subframe_constant_(decoder, channel, bps))
			return false;
Josh Coalson's avatar
Josh Coalson committed
1102
1103
	}
	else if(x == 2) {
1104
1105
		if(!stream_decoder_read_subframe_verbatim_(decoder, channel, bps))
			return false;
Josh Coalson's avatar
Josh Coalson committed
1106
1107
1108
1109
1110
1111
	}
	else if(x < 16) {
		decoder->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
		return false;
	}
	else if(x <= 24) {
1112
1113
		if(!stream_decoder_read_subframe_fixed_(decoder, channel, bps, (x>>1)&7))
			return false;
Josh Coalson's avatar
Josh Coalson committed
1114
1115
1116
1117
1118
1119
	}
	else if(x < 64) {
		decoder->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
		return false;
	}
	else {
1120
1121
		if(!stream_decoder_read_subframe_lpc_(decoder, channel, bps, ((x>>1)&31)+1))
			return false;
Josh Coalson's avatar
Josh Coalson committed
1122
	}
1123
1124

	if(wasted_bits) {
1125
1126
1127
1128
		unsigned i;
		x = decoder->guts->frame.subframes[channel].wasted_bits;
		for(i = 0; i < decoder->guts->frame.header.blocksize; i++)
			decoder->guts->output[channel][i] <<= x;
1129
	}
1130

1131
	return true;
Josh Coalson's avatar
Josh Coalson committed
1132
1133
}

1134
bool stream_decoder_read_subframe_constant_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps)
Josh Coalson's avatar
Josh Coalson committed
1135
{
1136
	FLAC__Subframe_Constant *subframe = &decoder->guts->frame.subframes[channel].data.constant;
Josh Coalson's avatar
Josh Coalson committed
1137
1138
	int32 x;
	unsigned i;
1139
	int32 *output = decoder->guts->output[channel];
Josh Coalson's avatar
Josh Coalson committed
1140

1141
1142
	decoder->guts->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_CONSTANT;

1143
	if(!FLAC__bitbuffer_read_raw_int32(&decoder->guts->input, &x, bps, read_callback_, decoder))
Josh Coalson's avatar
Josh Coalson committed
1144
1145
		return false; /* the read_callback_ sets the state for us */

1146
1147
1148
1149
1150
	subframe->value = x;

	/* decode the subframe */
	for(i = 0; i < decoder->guts->frame.header.blocksize; i++)
		output[i] = x;
Josh Coalson's avatar
Josh Coalson committed
1151
1152
1153
1154

	return true;
}

1155
bool stream_decoder_read_subframe_fixed_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order)
Josh Coalson's avatar
Josh Coalson committed
1156
{
1157
	FLAC__Subframe_Fixed *subframe = &decoder->guts->frame.subframes[channel].data.fixed;
Josh Coalson's avatar
Josh Coalson committed
1158
1159
1160
1161
	int32 i32;
	uint32 u32;
	unsigned u;

1162
1163
1164
1165
	decoder->guts->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_FIXED;

	subframe->residual = decoder->guts->residual[channel];
	subframe->order = order;
Josh Coalson's avatar
Josh Coalson committed
1166
1167
1168

	/* read warm-up samples */
	for(u = 0; u < order; u++) {
1169
		if(!FLAC__bitbuffer_read_raw_int32(&decoder->guts->input, &i32, bps, read_callback_, decoder))
Josh Coalson's avatar
Josh Coalson committed
1170
			return false; /* the read_callback_ sets the state for us */
1171
		subframe->warmup[u] = i32;
Josh Coalson's avatar
Josh Coalson committed
1172
1173
1174
1175
1176
	}

	/* read entropy coding method info */
	if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN, read_callback_, decoder))
		return false; /* the read_callback_ sets the state for us */
1177
1178
	subframe->entropy_coding_method.type = u32;
	switch(subframe->entropy_coding_method.type) {
Josh Coalson's avatar
Josh Coalson committed
1179
1180
1181
		case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
			if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN, read_callback_, decoder))
				return false; /* the read_callback_ sets the state for us */
1182
			subframe->entropy_coding_method.data.partitioned_rice.order = u32;
Josh Coalson's avatar
Josh Coalson committed
1183
1184
1185
1186
1187
1188
1189
			break;
		default:
			decoder->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
			return false;
	}

	/* read residual */
1190
	switch(subframe->entropy_coding_method.type) {
Josh Coalson's avatar
Josh Coalson committed
1191
		case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
1192
			if(!stream_decoder_read_residual_partitioned_rice_(decoder, order, subframe->entropy_coding_method.data.partitioned_rice.order, decoder->guts->residual[channel]))
Josh Coalson's avatar
Josh Coalson committed
1193
1194
1195
1196
1197
1198
1199
				return false;
			break;
		default:
			assert(0);
	}

	/* decode the subframe */
1200
1201
	memcpy(decoder->guts->output[channel], subframe->warmup, sizeof(int32) * order);
	FLAC__fixed_restore_signal(decoder->guts->residual[channel], decoder->guts->frame.header.blocksize-order, order, decoder->guts->output[channel]+order);
Josh Coalson's avatar
Josh Coalson committed
1202
1203
1204
1205

	return true;
}

1206
bool stream_decoder_read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order)
Josh Coalson's avatar
Josh Coalson committed
1207
{
1208
	FLAC__Subframe_LPC *subframe = &decoder->guts->frame.subframes[channel].data.lpc;
Josh Coalson's avatar
Josh Coalson committed
1209
1210
1211
1212
	int32 i32;
	uint32 u32;
	unsigned u;

1213
1214
1215
1216
	decoder->guts->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_LPC;

	subframe->residual = decoder->guts->residual[channel];
	subframe->order = order;
Josh Coalson's avatar
Josh Coalson committed
1217
1218
1219

	/* read warm-up samples */
	for(u = 0; u < order; u++) {
1220
		if(!FLAC__bitbuffer_read_raw_int32(&decoder->guts->input, &i32, bps, read_callback_, decoder))
Josh Coalson's avatar
Josh Coalson committed
1221
			return false; /* the read_callback_ sets the state for us */
1222
		subframe->warmup[u] = i32;
Josh Coalson's avatar
Josh Coalson committed
1223
1224
1225
	}

	/* read qlp coeff precision */
1226
	if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &u32, FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN, read_callback_, decoder))
Josh Coalson's avatar
Josh Coalson committed
1227
		return false; /* the read_callback_ sets the state for us */
Josh Coalson's avatar
Josh Coalson committed
1228
	if(u32 == (1u << FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN) - 1) {
Josh Coalson's avatar
Josh Coalson committed
1229
1230
1231
1232
		decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
		decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
		return true;
	}
1233
	subframe->qlp_coeff_precision = u32+1;
Josh Coalson's avatar
Josh Coalson committed
1234
1235

	/* read qlp shift */
1236
	if(!FLAC__bitbuffer_read_raw_int32(&decoder->guts->input, &i32, FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN, read_callback_, decoder))
Josh Coalson's avatar
Josh Coalson committed
1237
		return false; /* the read_callback_ sets the state for us */
1238
	subframe->quantization_level = i32;
Josh Coalson's avatar
Josh Coalson committed
1239
1240
1241

	/* read quantized lp coefficiencts */
	for(u = 0; u < order; u++) {
1242
		if(!FLAC__bitbuffer_read_raw_int32(&decoder->guts->input, &i32, subframe->qlp_coeff_precision, read_callback_, decoder))
Josh Coalson's avatar
Josh Coalson committed
1243
			return false; /* the read_callback_ sets the state for us */
1244
		subframe->qlp_coeff[u] = i32;
Josh Coalson's avatar
Josh Coalson committed
1245
1246
1247
1248
1249
	}

	/* read entropy coding method info */
	if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN, read_callback_, decoder))
		return false; /* the read_callback_ sets the state for us */
1250
1251
	subframe->entropy_coding_method.type = u32;
	switch(subframe->entropy_coding_method.type) {
Josh Coalson's avatar
Josh Coalson committed
1252
1253
1254
		case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
			if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN, read_callback_, decoder))
				return false; /* the read_callback_ sets the state for us */
1255
			subframe->entropy_coding_method.data.partitioned_rice.order = u32;
Josh Coalson's avatar
Josh Coalson committed
1256
1257
1258
1259
1260
1261
1262
			break;
		default:
			decoder->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
			return false;
	}

	/* read residual */
1263
	switch(subframe->entropy_coding_method.type) {
Josh Coalson's avatar
Josh Coalson committed
1264
		case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
1265
			if(!stream_decoder_read_residual_partitioned_rice_(decoder, order, subframe->entropy_coding_method.data.partitioned_rice.order, decoder->guts->residual[channel]))
Josh Coalson's avatar
Josh Coalson committed
1266
1267
1268
1269
1270
1271
1272
				return false;
			break;
		default:
			assert(0);
	}

	/* decode the subframe */
1273
1274
	memcpy(decoder->guts->output[channel], subframe->warmup, sizeof(int32) * order);
	FLAC__lpc_restore_signal(decoder->guts->residual[channel], decoder->guts->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->guts->output[channel]+order);
Josh Coalson's avatar
Josh Coalson committed
1275
1276
1277
1278

	return true;
}

1279
bool stream_decoder_read_subframe_verbatim_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps)
Josh Coalson's avatar
Josh Coalson committed
1280
{
1281
	FLAC__Subframe_Verbatim *subframe = &decoder->guts->frame.subframes[channel].data.verbatim;
1282
	int32 x, *residual = decoder->guts->residual[channel];
Josh Coalson's avatar
Josh Coalson committed
1283
1284
	unsigned i;

1285
1286
	decoder->guts->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_VERBATIM;

1287
	subframe->data = residual;
1288
1289

	for(i = 0; i < decoder->guts->frame.header.blocksize; i++) {
1290
		if(!FLAC__bitbuffer_read_raw_int32(&decoder->guts->input, &x, bps, read_callback_, decoder))
Josh Coalson's avatar
Josh Coalson committed
1291
			return false; /* the read_callback_ sets the state for us */
1292
		residual[i] = x;
Josh Coalson's avatar
Josh Coalson committed
1293
1294
	}

1295
1296
1297
	/* decode the subframe */
	memcpy(decoder->guts->output[channel], subframe->data, <