1 /* libFLAC - Free Lossless Audio Codec library
2 * Copyright (C) 2000,2001 Josh Coalson
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.
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.
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.
22 #include <stdlib.h> /* for malloc() */
23 #include <string.h> /* for strcmp() */
24 #include <sys/stat.h> /* for stat() */
25 #include "FLAC/file_decoder.h"
26 #include "protected/stream_decoder.h"
27 #include "private/md5.h"
29 typedef struct FLAC__FileDecoderPrivate {
30 FLAC__StreamDecoderWriteStatus (*write_callback)(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const int32 *buffer[], void *client_data);
31 void (*metadata_callback)(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data);
32 void (*error_callback)(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
35 char *filename; /* == NULL if stdin */
36 FLAC__StreamDecoder *stream;
37 struct MD5Context md5context;
38 byte stored_md5sum[16]; /* this is what is stored in the metadata */
39 byte computed_md5sum[16]; /* this is the sum we computed from the decoded data */
40 /* the rest of these are only used for seeking: */
41 FLAC__StreamMetaData_StreamInfo stream_info; /* we keep this around so we can figure out how to seek quickly */
42 const FLAC__StreamMetaData_SeekTable *seek_table; /* we hold a pointer to the stream decoder's seek table for the same reason */
43 FLAC__Frame last_frame; /* holds the info of the last frame we seeked to */
45 } FLAC__FileDecoderPrivate;
47 static FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *decoder, byte buffer[], unsigned *bytes, void *client_data);
48 static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const int32 *buffer[], void *client_data);
49 static void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data);
50 static void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
51 static bool seek_to_absolute_sample_(FLAC__FileDecoder *decoder, long filesize, uint64 target_sample);
53 const char *FLAC__FileDecoderStateString[] = {
54 "FLAC__FILE_DECODER_OK",
55 "FLAC__FILE_DECODER_SEEKING",
56 "FLAC__FILE_DECODER_END_OF_FILE",
57 "FLAC__FILE_DECODER_ERROR_OPENING_FILE",
58 "FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR",
59 "FLAC__FILE_DECODER_SEEK_ERROR",
60 "FLAC__FILE_DECODER_STREAM_ERROR",
61 "FLAC__FILE_DECODER_UNINITIALIZED"
64 FLAC__FileDecoder *FLAC__file_decoder_get_new_instance()
66 FLAC__FileDecoder *decoder = (FLAC__FileDecoder*)malloc(sizeof(FLAC__FileDecoder));
68 decoder->state = FLAC__FILE_DECODER_UNINITIALIZED;
74 void FLAC__file_decoder_free_instance(FLAC__FileDecoder *decoder)
79 FLAC__FileDecoderState FLAC__file_decoder_init(
80 FLAC__FileDecoder *decoder,
82 FLAC__StreamDecoderWriteStatus (*write_callback)(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const int32 *buffer[], void *client_data),
83 void (*metadata_callback)(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data),
84 void (*error_callback)(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data),
88 assert(sizeof(int) >= 4); /* we want to die right away if this is not true */
90 assert(write_callback != 0);
91 assert(metadata_callback != 0);
92 assert(error_callback != 0);
93 assert(decoder->state == FLAC__FILE_DECODER_UNINITIALIZED);
94 assert(decoder->guts == 0);
96 decoder->state = FLAC__FILE_DECODER_OK;
98 decoder->guts = (FLAC__FileDecoderPrivate*)malloc(sizeof(FLAC__FileDecoderPrivate));
99 if(decoder->guts == 0)
100 return decoder->state = FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR;
102 decoder->guts->write_callback = write_callback;
103 decoder->guts->metadata_callback = metadata_callback;
104 decoder->guts->error_callback = error_callback;
105 decoder->guts->client_data = client_data;
106 decoder->guts->stream = 0;
107 decoder->guts->file = 0;
108 decoder->guts->filename = 0;
109 decoder->guts->seek_table = 0;
111 if(0 == strcmp(filename, "-")) {
112 decoder->guts->file = stdin;
115 if(0 == (decoder->guts->filename = (char*)malloc(strlen(filename)+1)))
116 return decoder->state = FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR;
117 strcpy(decoder->guts->filename, filename);
118 decoder->guts->file = fopen(filename, "rb");
121 if(decoder->guts->file == 0)
122 return decoder->state = FLAC__FILE_DECODER_ERROR_OPENING_FILE;
124 /* We initialize the MD5Context even though we may never use it. This is
125 * because check_md5 may be turned on to start and then turned off if a
126 * seek occurs. So we always init the context here and finalize it in
127 * FLAC__file_decoder_finish() to make sure things are always cleaned up
130 MD5Init(&decoder->guts->md5context);
132 decoder->guts->stream = FLAC__stream_decoder_get_new_instance();
133 if(FLAC__stream_decoder_init(decoder->guts->stream, read_callback_, write_callback_, metadata_callback_, error_callback_, decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA)
134 return decoder->state = FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR; /* this is based on internal knowledge of FLAC__stream_decoder_init() */
136 return decoder->state;
139 bool FLAC__file_decoder_finish(FLAC__FileDecoder *decoder)
141 bool md5_failed = false;
143 assert(decoder != 0);
144 if(decoder->state == FLAC__FILE_DECODER_UNINITIALIZED)
146 if(decoder->guts != 0) {
147 if(decoder->guts->file != 0 && decoder->guts->file != stdin)
148 fclose(decoder->guts->file);
149 if(0 != decoder->guts->filename)
150 free(decoder->guts->filename);
151 /* see the comment in FLAC__file_decoder_init() as to why we always
154 MD5Final(decoder->guts->computed_md5sum, &decoder->guts->md5context);
155 if(decoder->guts->stream != 0) {
156 FLAC__stream_decoder_finish(decoder->guts->stream);
157 FLAC__stream_decoder_free_instance(decoder->guts->stream);
159 if(decoder->check_md5) {
160 if(memcmp(decoder->guts->stored_md5sum, decoder->guts->computed_md5sum, 16))
166 decoder->state = FLAC__FILE_DECODER_UNINITIALIZED;
170 bool FLAC__file_decoder_process_whole_file(FLAC__FileDecoder *decoder)
173 assert(decoder != 0);
175 if(decoder->guts->stream->state == FLAC__STREAM_DECODER_END_OF_STREAM)
176 decoder->state = FLAC__FILE_DECODER_END_OF_FILE;
178 if(decoder->state == FLAC__FILE_DECODER_END_OF_FILE)
181 assert(decoder->state == FLAC__FILE_DECODER_OK);
183 ret = FLAC__stream_decoder_process_whole_stream(decoder->guts->stream);
185 decoder->state = FLAC__FILE_DECODER_STREAM_ERROR;
190 bool FLAC__file_decoder_process_metadata(FLAC__FileDecoder *decoder)
193 assert(decoder != 0);
195 if(decoder->guts->stream->state == FLAC__STREAM_DECODER_END_OF_STREAM)
196 decoder->state = FLAC__FILE_DECODER_END_OF_FILE;
198 if(decoder->state == FLAC__FILE_DECODER_END_OF_FILE)
201 assert(decoder->state == FLAC__FILE_DECODER_OK);
203 ret = FLAC__stream_decoder_process_metadata(decoder->guts->stream);
205 decoder->state = FLAC__FILE_DECODER_STREAM_ERROR;
210 bool FLAC__file_decoder_process_one_frame(FLAC__FileDecoder *decoder)
213 assert(decoder != 0);
215 if(decoder->guts->stream->state == FLAC__STREAM_DECODER_END_OF_STREAM)
216 decoder->state = FLAC__FILE_DECODER_END_OF_FILE;
218 if(decoder->state == FLAC__FILE_DECODER_END_OF_FILE)
221 assert(decoder->state == FLAC__FILE_DECODER_OK);
223 ret = FLAC__stream_decoder_process_one_frame(decoder->guts->stream);
225 decoder->state = FLAC__FILE_DECODER_STREAM_ERROR;
230 bool FLAC__file_decoder_process_remaining_frames(FLAC__FileDecoder *decoder)
233 assert(decoder != 0);
235 if(decoder->guts->stream->state == FLAC__STREAM_DECODER_END_OF_STREAM)
236 decoder->state = FLAC__FILE_DECODER_END_OF_FILE;
238 if(decoder->state == FLAC__FILE_DECODER_END_OF_FILE)
241 assert(decoder->state == FLAC__FILE_DECODER_OK);
243 ret = FLAC__stream_decoder_process_remaining_frames(decoder->guts->stream);
245 decoder->state = FLAC__FILE_DECODER_STREAM_ERROR;
250 bool FLAC__file_decoder_seek_absolute(FLAC__FileDecoder *decoder, uint64 sample)
253 struct stat filestats;
255 assert(decoder != 0);
256 assert(decoder->state == FLAC__FILE_DECODER_OK);
258 if(decoder->guts->filename == 0) { /* means the file is stdin... */
259 decoder->state = FLAC__FILE_DECODER_SEEK_ERROR;
263 decoder->state = FLAC__FILE_DECODER_SEEKING;
265 /* turn off md5 checking if a seek is attempted */
266 decoder->check_md5 = false;
268 if(!FLAC__stream_decoder_reset(decoder->guts->stream)) {
269 decoder->state = FLAC__FILE_DECODER_STREAM_ERROR;
272 /* get the file length */
273 if(stat(decoder->guts->filename, &filestats) != 0) {
274 decoder->state = FLAC__FILE_DECODER_SEEK_ERROR;
277 filesize = filestats.st_size;
279 if(0 != fseek(decoder->guts->file, 0, SEEK_SET)) {
280 decoder->state = FLAC__FILE_DECODER_SEEK_ERROR;
283 if(!FLAC__stream_decoder_process_metadata(decoder->guts->stream)) {
284 decoder->state = FLAC__FILE_DECODER_STREAM_ERROR;
287 if(sample > decoder->guts->stream_info.total_samples) {
288 decoder->state = FLAC__FILE_DECODER_SEEK_ERROR;
292 return seek_to_absolute_sample_(decoder, filesize, sample);
295 FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *decoder, byte buffer[], unsigned *bytes, void *client_data)
297 FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
299 if(feof(file_decoder->guts->file)) {
300 file_decoder->state = FLAC__FILE_DECODER_END_OF_FILE;
301 return FLAC__STREAM_DECODER_READ_END_OF_STREAM;
303 else if(*bytes > 0) {
304 size_t bytes_read = fread(buffer, sizeof(byte), *bytes, file_decoder->guts->file);
305 if(bytes_read == 0) {
306 if(feof(file_decoder->guts->file)) {
307 file_decoder->state = FLAC__FILE_DECODER_END_OF_FILE;
308 return FLAC__STREAM_DECODER_READ_END_OF_STREAM;
311 return FLAC__STREAM_DECODER_READ_ABORT;
314 *bytes = (unsigned)bytes_read;
315 return FLAC__STREAM_DECODER_READ_CONTINUE;
319 return FLAC__STREAM_DECODER_READ_ABORT; /* abort to avoid a deadlock */
322 FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const int32 *buffer[], void *client_data)
324 FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
327 if(file_decoder->state == FLAC__FILE_DECODER_SEEKING) {
328 uint64 this_frame_sample = frame->header.number.sample_number;
329 uint64 next_frame_sample = this_frame_sample + (uint64)frame->header.blocksize;
330 uint64 target_sample = file_decoder->guts->target_sample;
332 file_decoder->guts->last_frame = *frame; /* save the frame in the guts */
333 if(this_frame_sample <= target_sample && target_sample < next_frame_sample) { /* we hit our target frame */
334 unsigned delta = (unsigned)(target_sample - this_frame_sample);
335 /* kick out of seek mode */
336 file_decoder->state = FLAC__FILE_DECODER_OK;
337 /* shift out the samples before target_sample */
340 const int32 *newbuffer[FLAC__MAX_CHANNELS];
341 for(channel = 0; channel < frame->header.channels; channel++)
342 newbuffer[channel] = buffer[channel] + delta;
343 file_decoder->guts->last_frame.header.blocksize -= delta;
344 file_decoder->guts->last_frame.header.number.sample_number += (uint64)delta;
345 /* write the relevant samples */
346 return file_decoder->guts->write_callback(file_decoder, &file_decoder->guts->last_frame, newbuffer, file_decoder->guts->client_data);
349 /* write the relevant samples */
350 return file_decoder->guts->write_callback(file_decoder, frame, buffer, file_decoder->guts->client_data);
354 return FLAC__STREAM_DECODER_WRITE_CONTINUE;
358 if(file_decoder->check_md5) {
359 if(!FLAC__MD5Accumulate(&file_decoder->guts->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8))
360 return FLAC__STREAM_DECODER_WRITE_ABORT;
362 return file_decoder->guts->write_callback(file_decoder, frame, buffer, file_decoder->guts->client_data);
366 void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data)
368 FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
371 if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
372 file_decoder->guts->stream_info = metadata->data.stream_info;
373 /* save the MD5 signature for comparison later */
374 memcpy(file_decoder->guts->stored_md5sum, metadata->data.stream_info.md5sum, 16);
375 if(0 == memcmp(file_decoder->guts->stored_md5sum, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16))
376 file_decoder->check_md5 = false;
378 else if(metadata->type == FLAC__METADATA_TYPE_SEEKTABLE) {
379 file_decoder->guts->seek_table = &metadata->data.seek_table;
381 if(file_decoder->state != FLAC__FILE_DECODER_SEEKING)
382 file_decoder->guts->metadata_callback(file_decoder, metadata, file_decoder->guts->client_data);
385 void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
387 FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
390 if(file_decoder->state != FLAC__FILE_DECODER_SEEKING)
391 file_decoder->guts->error_callback(file_decoder, status, file_decoder->guts->client_data);
394 bool seek_to_absolute_sample_(FLAC__FileDecoder *decoder, long filesize, uint64 target_sample)
396 long lower_bound, upper_bound, pos, last_pos = -1;
397 unsigned approx_bytes_per_frame;
398 uint64 last_frame_sample = 0xffffffffffffffff;
400 const bool is_variable_blocksize_stream = (decoder->guts->stream_info.min_blocksize != decoder->guts->stream_info.max_blocksize);
402 /* we are just guessing here, but we want to guess high, not low */
403 if(decoder->guts->stream_info.max_framesize > 0) {
404 approx_bytes_per_frame = decoder->guts->stream_info.max_framesize;
406 else if(!is_variable_blocksize_stream) {
407 /* note there are no () around 'decoder->guts->stream_info.bits_per_sample/8' to keep precision up since it's an integer calulation */
408 approx_bytes_per_frame = decoder->guts->stream_info.min_blocksize * decoder->guts->stream_info.channels * decoder->guts->stream_info.bits_per_sample/8 + 64;
411 approx_bytes_per_frame = 1152 * decoder->guts->stream_info.channels * decoder->guts->stream_info.bits_per_sample/8 + 64;
413 /* The file pointer is currently at the first frame plus any read
414 ahead data, so first we get the file pointer, then subtract
415 uncomsumed bytes to get the position (lower_bound) of the first frame
417 if(-1 == (lower_bound = ftell(decoder->guts->file))) {
418 decoder->state = FLAC__FILE_DECODER_SEEK_ERROR;
421 lower_bound -= FLAC__stream_decoder_input_bytes_unconsumed(decoder->guts->stream);
425 /* calc the upper_bound, beyond which we never want to seek */
426 if(decoder->guts->stream_info.max_framesize > 0)
427 upper_bound = filesize - (decoder->guts->stream_info.max_framesize + 128 + 2); /* 128 for a possible ID3V1 tag, 2 for indexing differences */
429 upper_bound = filesize - ((decoder->guts->stream_info.channels * decoder->guts->stream_info.bits_per_sample * FLAC__MAX_BLOCK_SIZE) / 8 + 128 + 2);
431 /* Now we need to use the metadata and the filelength to search to the frame with the correct sample */
433 /* with VC++ you have to spoon feed it the casting */
434 pos = lower_bound + (long)((double)(int64)target_sample / (double)(int64)decoder->guts->stream_info.total_samples * (double)(filesize-lower_bound-1)) - approx_bytes_per_frame;
436 pos = lower_bound + (long)((double)target_sample / (double)decoder->guts->stream_info.total_samples * (double)(filesize-lower_bound-1)) - approx_bytes_per_frame;
439 /* clip the position to the bounds, lower bound takes precedence */
440 if(pos >= upper_bound)
442 if(pos < lower_bound)
446 decoder->guts->target_sample = target_sample;
449 if(-1 == fseek(decoder->guts->file, pos, SEEK_SET)) {
450 decoder->state = FLAC__FILE_DECODER_SEEK_ERROR;
453 if(!FLAC__stream_decoder_flush(decoder->guts->stream)) {
454 decoder->state = FLAC__FILE_DECODER_STREAM_ERROR;
458 if(!FLAC__stream_decoder_process_one_frame(decoder->guts->stream)) {
459 decoder->state = FLAC__FILE_DECODER_SEEK_ERROR;
462 /* our write callback will change the state when it gets to the target frame */
463 if(decoder->state != FLAC__FILE_DECODER_SEEKING) {
466 else { /* we need to narrow the search */
467 uint64 this_frame_sample = decoder->guts->last_frame.header.number.sample_number;
468 if(this_frame_sample == last_frame_sample) {
469 /* our last move backwards wasn't big enough */
470 pos -= (last_pos - pos);
474 if(target_sample < this_frame_sample) {
476 approx_bytes_per_frame = decoder->guts->last_frame.header.blocksize * decoder->guts->last_frame.header.channels * decoder->guts->last_frame.header.bits_per_sample/8 + 64;
477 pos -= approx_bytes_per_frame;
480 else { /* target_sample >= this_frame_sample + this frame's blocksize */
482 if(-1 == (pos = ftell(decoder->guts->file))) {
483 decoder->state = FLAC__FILE_DECODER_SEEK_ERROR;
486 pos -= FLAC__stream_decoder_input_bytes_unconsumed(decoder->guts->stream);
490 if(pos < lower_bound)
492 last_frame_sample = this_frame_sample;