1 /* libFLAC - Free Lossless Audio Codec library
2 * Copyright (C) 2000,2001,2002 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.
21 #include <stdlib.h> /* for malloc() */
22 #include <string.h> /* for strcmp() */
23 #include <sys/stat.h> /* for stat() */
24 #include "FLAC/assert.h"
25 #include "protected/file_decoder.h"
26 #include "protected/seekable_stream_decoder.h"
27 #include "private/md5.h"
29 /***********************************************************************
31 * Private class method prototypes
33 ***********************************************************************/
35 static FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
36 static FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
37 static FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
38 static FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
39 static FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data);
40 static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data);
41 static void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data);
42 static void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
44 /***********************************************************************
48 ***********************************************************************/
50 typedef struct FLAC__FileDecoderPrivate {
51 FLAC__StreamDecoderWriteStatus (*write_callback)(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data);
52 void (*metadata_callback)(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data);
53 void (*error_callback)(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
56 char *filename; /* == NULL if stdin */
57 FLAC__SeekableStreamDecoder *seekable_stream_decoder;
59 FLAC__bool md5_checking;
60 } init_values_for_superclass;
61 } FLAC__FileDecoderPrivate;
63 /***********************************************************************
65 * Public static class data
67 ***********************************************************************/
69 const char *FLAC__FileDecoderStateString[] = {
70 "FLAC__FILE_DECODER_OK",
71 "FLAC__FILE_DECODER_SEEKING",
72 "FLAC__FILE_DECODER_END_OF_FILE",
73 "FLAC__FILE_DECODER_ERROR_OPENING_FILE",
74 "FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR",
75 "FLAC__FILE_DECODER_SEEK_ERROR",
76 "FLAC__FILE_DECODER_STREAM_ERROR",
77 "FLAC__FILE_DECODER_STREAM_DECODER_ERROR",
78 "FLAC__FILE_DECODER_ALREADY_INITIALIZED",
79 "FLAC__FILE_DECODER_INVALID_CALLBACK",
80 "FLAC__FILE_DECODER_UNINITIALIZED"
83 /***********************************************************************
85 * Class constructor/destructor
87 ***********************************************************************/
89 FLAC__FileDecoder *FLAC__file_decoder_new()
91 FLAC__FileDecoder *decoder;
93 FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
95 decoder = (FLAC__FileDecoder*)malloc(sizeof(FLAC__FileDecoder));
99 decoder->protected_ = (FLAC__FileDecoderProtected*)malloc(sizeof(FLAC__FileDecoderProtected));
100 if(decoder->protected_ == 0) {
104 decoder->private_ = (FLAC__FileDecoderPrivate*)malloc(sizeof(FLAC__FileDecoderPrivate));
105 if(decoder->private_ == 0) {
106 free(decoder->protected_);
111 decoder->protected_->state = FLAC__FILE_DECODER_UNINITIALIZED;
113 decoder->private_->filename = 0;
114 decoder->private_->write_callback = 0;
115 decoder->private_->metadata_callback = 0;
116 decoder->private_->error_callback = 0;
117 decoder->private_->client_data = 0;
118 decoder->private_->init_values_for_superclass.md5_checking = false;
123 void FLAC__file_decoder_delete(FLAC__FileDecoder *decoder)
125 FLAC__ASSERT(decoder != 0);
126 FLAC__ASSERT(decoder->protected_ != 0);
127 FLAC__ASSERT(decoder->private_ != 0);
129 free(decoder->private_);
130 free(decoder->protected_);
134 /***********************************************************************
136 * Public class methods
138 ***********************************************************************/
140 FLAC__FileDecoderState FLAC__file_decoder_init(FLAC__FileDecoder *decoder)
142 FLAC__ASSERT(decoder != 0);
144 if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
145 return decoder->protected_->state = FLAC__FILE_DECODER_ALREADY_INITIALIZED;
147 decoder->protected_->state = FLAC__FILE_DECODER_OK;
149 if(0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
150 return decoder->protected_->state = FLAC__FILE_DECODER_INVALID_CALLBACK;
152 decoder->private_->file = 0;
153 decoder->private_->seekable_stream_decoder = 0;
155 if(0 == decoder->private_->filename)
156 decoder->private_->file = stdin;
158 decoder->private_->file = fopen(decoder->private_->filename, "rb");
160 if(decoder->private_->file == 0)
161 return decoder->protected_->state = FLAC__FILE_DECODER_ERROR_OPENING_FILE;
163 decoder->private_->seekable_stream_decoder = FLAC__seekable_stream_decoder_new();
165 if(0 == decoder->private_->seekable_stream_decoder)
166 return decoder->protected_->state = FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR;
168 FLAC__seekable_stream_decoder_set_read_callback(decoder->private_->seekable_stream_decoder, read_callback_);
169 FLAC__seekable_stream_decoder_set_seek_callback(decoder->private_->seekable_stream_decoder, seek_callback_);
170 FLAC__seekable_stream_decoder_set_tell_callback(decoder->private_->seekable_stream_decoder, tell_callback_);
171 FLAC__seekable_stream_decoder_set_length_callback(decoder->private_->seekable_stream_decoder, length_callback_);
172 FLAC__seekable_stream_decoder_set_eof_callback(decoder->private_->seekable_stream_decoder, eof_callback_);
173 FLAC__seekable_stream_decoder_set_write_callback(decoder->private_->seekable_stream_decoder, write_callback_);
174 FLAC__seekable_stream_decoder_set_metadata_callback(decoder->private_->seekable_stream_decoder, metadata_callback_);
175 FLAC__seekable_stream_decoder_set_error_callback(decoder->private_->seekable_stream_decoder, error_callback_);
176 FLAC__seekable_stream_decoder_set_client_data(decoder->private_->seekable_stream_decoder, decoder);
179 * Unfortunately, because of the "_new() ... _set_() ... _init()" order of
180 * decoder initialization, settings that are 'inherited' from the superclass
181 * have to be passed up this way, because the superclass has not even been
182 * created yet when the value is set in the subclass.
184 (void)FLAC__seekable_stream_decoder_set_md5_checking(decoder->private_->seekable_stream_decoder, decoder->private_->init_values_for_superclass.md5_checking);
186 if(FLAC__seekable_stream_decoder_init(decoder->private_->seekable_stream_decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK)
187 return decoder->protected_->state = FLAC__FILE_DECODER_STREAM_DECODER_ERROR; /*@@@ change this to FLAC__FILE_DECODER_SEEKABLE_STREAM_ERROR in next minor-revision */
189 return decoder->protected_->state;
192 FLAC__bool FLAC__file_decoder_finish(FLAC__FileDecoder *decoder)
194 FLAC__bool ok = true;
196 FLAC__ASSERT(decoder != 0);
197 if(decoder->protected_->state == FLAC__FILE_DECODER_UNINITIALIZED)
199 if(decoder->private_->file != 0 && decoder->private_->file != stdin)
200 fclose(decoder->private_->file);
201 if(0 != decoder->private_->filename) {
202 free(decoder->private_->filename);
203 decoder->private_->filename = 0;
205 if(decoder->private_->seekable_stream_decoder != 0) {
206 ok = FLAC__seekable_stream_decoder_finish(decoder->private_->seekable_stream_decoder);
207 FLAC__seekable_stream_decoder_delete(decoder->private_->seekable_stream_decoder);
209 decoder->protected_->state = FLAC__FILE_DECODER_UNINITIALIZED;
213 FLAC__bool FLAC__file_decoder_set_md5_checking(const FLAC__FileDecoder *decoder, FLAC__bool value)
215 if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
217 decoder->private_->init_values_for_superclass.md5_checking = value;
221 FLAC__bool FLAC__file_decoder_set_filename(const FLAC__FileDecoder *decoder, const char *value)
223 FLAC__ASSERT(value != 0);
224 if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
226 if(0 != decoder->private_->filename) {
227 free(decoder->private_->filename);
228 decoder->private_->filename = 0;
230 if(0 != strcmp(value, "-")) {
231 if(0 == (decoder->private_->filename = (char*)malloc(strlen(value)+1))) {
232 decoder->protected_->state = FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR;
235 strcpy(decoder->private_->filename, value);
240 FLAC__bool FLAC__file_decoder_set_write_callback(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderWriteStatus (*value)(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data))
242 if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
244 decoder->private_->write_callback = value;
248 FLAC__bool FLAC__file_decoder_set_metadata_callback(const FLAC__FileDecoder *decoder, void (*value)(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data))
250 if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
252 decoder->private_->metadata_callback = value;
256 FLAC__bool FLAC__file_decoder_set_error_callback(const FLAC__FileDecoder *decoder, void (*value)(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data))
258 if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
260 decoder->private_->error_callback = value;
264 FLAC__bool FLAC__file_decoder_set_client_data(const FLAC__FileDecoder *decoder, void *value)
266 if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
268 decoder->private_->client_data = value;
272 FLAC__FileDecoderState FLAC__file_decoder_get_state(const FLAC__FileDecoder *decoder)
274 return decoder->protected_->state;
277 FLAC__bool FLAC__file_decoder_get_md5_checking(const FLAC__FileDecoder *decoder)
279 return FLAC__seekable_stream_decoder_get_md5_checking(decoder->private_->seekable_stream_decoder);
282 FLAC__bool FLAC__file_decoder_process_whole_file(FLAC__FileDecoder *decoder)
285 FLAC__ASSERT(decoder != 0);
287 if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
288 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
290 if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
293 FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
295 ret = FLAC__seekable_stream_decoder_process_whole_stream(decoder->private_->seekable_stream_decoder);
297 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_ERROR;
302 FLAC__bool FLAC__file_decoder_process_metadata(FLAC__FileDecoder *decoder)
305 FLAC__ASSERT(decoder != 0);
307 if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
308 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
310 if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
313 FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
315 ret = FLAC__seekable_stream_decoder_process_metadata(decoder->private_->seekable_stream_decoder);
317 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_ERROR;
322 FLAC__bool FLAC__file_decoder_process_one_frame(FLAC__FileDecoder *decoder)
325 FLAC__ASSERT(decoder != 0);
327 if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
328 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
330 if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
333 FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
335 ret = FLAC__seekable_stream_decoder_process_one_frame(decoder->private_->seekable_stream_decoder);
337 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_ERROR;
342 FLAC__bool FLAC__file_decoder_process_remaining_frames(FLAC__FileDecoder *decoder)
345 FLAC__ASSERT(decoder != 0);
347 if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
348 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
350 if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
353 FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
355 ret = FLAC__seekable_stream_decoder_process_remaining_frames(decoder->private_->seekable_stream_decoder);
357 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_ERROR;
362 /***********************************************************************
364 * Private class methods
366 ***********************************************************************/
368 FLAC__bool FLAC__file_decoder_seek_absolute(FLAC__FileDecoder *decoder, FLAC__uint64 sample)
370 FLAC__ASSERT(decoder != 0);
371 FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
373 if(decoder->private_->filename == 0) { /* means the file is stdin... */
374 decoder->protected_->state = FLAC__FILE_DECODER_SEEK_ERROR;
378 if(!FLAC__seekable_stream_decoder_seek_absolute(decoder->private_->seekable_stream_decoder, sample)) {
379 decoder->protected_->state = FLAC__FILE_DECODER_SEEK_ERROR;
386 FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
388 FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
392 size_t bytes_read = fread(buffer, sizeof(FLAC__byte), *bytes, file_decoder->private_->file);
393 if(bytes_read == 0 && !feof(file_decoder->private_->file)) {
394 return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
397 *bytes = (unsigned)bytes_read;
398 return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
402 return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; /* abort to avoid a deadlock */
405 FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
407 FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
410 if(fseek(file_decoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0)
411 return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
413 return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
416 FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
418 FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
422 if((pos = ftell(file_decoder->private_->file)) < 0)
423 return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
425 *absolute_byte_offset = (FLAC__uint64)pos;
426 return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
430 FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
432 FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
433 struct stat filestats;
436 if(0 == file_decoder->private_->filename || stat(file_decoder->private_->filename, &filestats) != 0)
437 return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
439 *stream_length = (FLAC__uint64)filestats.st_size;
440 return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
444 FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data)
446 FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
449 return feof(file_decoder->private_->file);
452 FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data)
454 FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
457 return file_decoder->private_->write_callback(file_decoder, frame, buffer, file_decoder->private_->client_data);
460 void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data)
462 FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
465 file_decoder->private_->metadata_callback(file_decoder, metadata, file_decoder->private_->client_data);
468 void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
470 FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
473 file_decoder->private_->error_callback(file_decoder, status, file_decoder->private_->client_data);