fix state enums
[flac.git] / src / libFLAC / file_decoder.c
1 /* libFLAC - Free Lossless Audio Codec library
2  * Copyright (C) 2000,2001,2002  Josh Coalson
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA  02111-1307, USA.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h> /* for malloc() */
22 #include <string.h> /* for strcmp() */
23 #include <sys/stat.h> /* for stat() */
24 #if defined _MSC_VER || defined __MINGW32__
25 #include <io.h> /* for _setmode() */
26 #include <fcntl.h> /* for _O_BINARY */
27 #elif defined __CYGWIN__
28 #include <io.h> /* for _setmode(), O_BINARY */
29 #endif
30 #include "FLAC/assert.h"
31 #include "protected/file_decoder.h"
32 #include "protected/seekable_stream_decoder.h"
33 #include "private/md5.h"
34
35 /***********************************************************************
36  *
37  * Private class method prototypes
38  *
39  ***********************************************************************/
40
41 static FILE *get_binary_stdin_();
42 static FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
43 static FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
44 static FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
45 static FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
46 static FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data);
47 static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data);
48 static void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data);
49 static void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
50
51 /***********************************************************************
52  *
53  * Private class data
54  *
55  ***********************************************************************/
56
57 typedef struct FLAC__FileDecoderPrivate {
58         FLAC__StreamDecoderWriteStatus (*write_callback)(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data);
59         void (*metadata_callback)(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data);
60         void (*error_callback)(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
61         void *client_data;
62         FILE *file;
63         char *filename; /* == NULL if stdin */
64         FLAC__SeekableStreamDecoder *seekable_stream_decoder;
65 } FLAC__FileDecoderPrivate;
66
67 /***********************************************************************
68  *
69  * Public static class data
70  *
71  ***********************************************************************/
72
73 const char *FLAC__FileDecoderStateString[] = {
74         "FLAC__FILE_DECODER_OK",
75         "FLAC__FILE_DECODER_END_OF_FILE",
76         "FLAC__FILE_DECODER_ERROR_OPENING_FILE",
77         "FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR",
78         "FLAC__FILE_DECODER_SEEK_ERROR",
79         "FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_DECODER_ERROR",
80         "FLAC__FILE_DECODER_ALREADY_INITIALIZED",
81         "FLAC__FILE_DECODER_INVALID_CALLBACK",
82         "FLAC__FILE_DECODER_UNINITIALIZED"
83 };
84
85 /***********************************************************************
86  *
87  * Class constructor/destructor
88  *
89  ***********************************************************************/
90
91 FLAC__FileDecoder *FLAC__file_decoder_new()
92 {
93         FLAC__FileDecoder *decoder;
94
95         FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
96
97         decoder = (FLAC__FileDecoder*)malloc(sizeof(FLAC__FileDecoder));
98         if(decoder == 0) {
99                 return 0;
100         }
101         decoder->protected_ = (FLAC__FileDecoderProtected*)malloc(sizeof(FLAC__FileDecoderProtected));
102         if(decoder->protected_ == 0) {
103                 free(decoder);
104                 return 0;
105         }
106         decoder->private_ = (FLAC__FileDecoderPrivate*)malloc(sizeof(FLAC__FileDecoderPrivate));
107         if(decoder->private_ == 0) {
108                 free(decoder->protected_);
109                 free(decoder);
110                 return 0;
111         }
112
113         decoder->private_->seekable_stream_decoder = FLAC__seekable_stream_decoder_new();
114
115         if(0 == decoder->private_->seekable_stream_decoder) {
116                 free(decoder->private_);
117                 free(decoder->protected_);
118                 free(decoder);
119                 return 0;
120         }
121
122         decoder->protected_->state = FLAC__FILE_DECODER_UNINITIALIZED;
123
124         decoder->private_->filename = 0;
125         decoder->private_->write_callback = 0;
126         decoder->private_->metadata_callback = 0;
127         decoder->private_->error_callback = 0;
128         decoder->private_->client_data = 0;
129
130         return decoder;
131 }
132
133 void FLAC__file_decoder_delete(FLAC__FileDecoder *decoder)
134 {
135         FLAC__ASSERT(decoder != 0);
136         FLAC__ASSERT(decoder->protected_ != 0);
137         FLAC__ASSERT(decoder->private_ != 0);
138
139         if(decoder->private_->filename != 0)
140                 free(decoder->private_->filename);
141
142         if(decoder->private_->seekable_stream_decoder != 0)
143                 FLAC__seekable_stream_decoder_delete(decoder->private_->seekable_stream_decoder);
144
145         free(decoder->private_);
146         free(decoder->protected_);
147         free(decoder);
148 }
149
150 /***********************************************************************
151  *
152  * Public class methods
153  *
154  ***********************************************************************/
155
156 FLAC__FileDecoderState FLAC__file_decoder_init(FLAC__FileDecoder *decoder)
157 {
158         FLAC__ASSERT(decoder != 0);
159
160         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
161                 return decoder->protected_->state = FLAC__FILE_DECODER_ALREADY_INITIALIZED;
162
163         decoder->protected_->state = FLAC__FILE_DECODER_OK;
164
165         if(0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
166                 return decoder->protected_->state = FLAC__FILE_DECODER_INVALID_CALLBACK;
167
168         decoder->private_->file = 0;
169
170         if(0 == decoder->private_->filename)
171                 decoder->private_->file = get_binary_stdin_();
172         else
173                 decoder->private_->file = fopen(decoder->private_->filename, "rb");
174
175         if(decoder->private_->file == 0)
176                 return decoder->protected_->state = FLAC__FILE_DECODER_ERROR_OPENING_FILE;
177
178         FLAC__seekable_stream_decoder_set_read_callback(decoder->private_->seekable_stream_decoder, read_callback_);
179         FLAC__seekable_stream_decoder_set_seek_callback(decoder->private_->seekable_stream_decoder, seek_callback_);
180         FLAC__seekable_stream_decoder_set_tell_callback(decoder->private_->seekable_stream_decoder, tell_callback_);
181         FLAC__seekable_stream_decoder_set_length_callback(decoder->private_->seekable_stream_decoder, length_callback_);
182         FLAC__seekable_stream_decoder_set_eof_callback(decoder->private_->seekable_stream_decoder, eof_callback_);
183         FLAC__seekable_stream_decoder_set_write_callback(decoder->private_->seekable_stream_decoder, write_callback_);
184         FLAC__seekable_stream_decoder_set_metadata_callback(decoder->private_->seekable_stream_decoder, metadata_callback_);
185         FLAC__seekable_stream_decoder_set_error_callback(decoder->private_->seekable_stream_decoder, error_callback_);
186         FLAC__seekable_stream_decoder_set_client_data(decoder->private_->seekable_stream_decoder, decoder);
187
188         if(FLAC__seekable_stream_decoder_init(decoder->private_->seekable_stream_decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK)
189                 return decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
190
191         return decoder->protected_->state;
192 }
193
194 FLAC__bool FLAC__file_decoder_finish(FLAC__FileDecoder *decoder)
195 {
196         FLAC__ASSERT(decoder != 0);
197
198         if(decoder->protected_->state == FLAC__FILE_DECODER_UNINITIALIZED)
199                 return true;
200
201         FLAC__ASSERT(decoder->private_->seekable_stream_decoder != 0);
202
203         if(decoder->private_->file != 0 && decoder->private_->file != stdin)
204                 fclose(decoder->private_->file);
205
206         if(decoder->private_->filename != 0) {
207                 free(decoder->private_->filename);
208                 decoder->private_->filename = 0;
209         }
210
211         decoder->protected_->state = FLAC__FILE_DECODER_UNINITIALIZED;
212
213         return FLAC__seekable_stream_decoder_finish(decoder->private_->seekable_stream_decoder);
214 }
215
216 FLAC__bool FLAC__file_decoder_set_md5_checking(FLAC__FileDecoder *decoder, FLAC__bool value)
217 {
218         FLAC__ASSERT(decoder != 0);
219         FLAC__ASSERT(decoder->private_ != 0);
220         FLAC__ASSERT(decoder->protected_ != 0);
221         FLAC__ASSERT(decoder->private_->seekable_stream_decoder != 0);
222         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
223                 return false;
224         return FLAC__seekable_stream_decoder_set_md5_checking(decoder->private_->seekable_stream_decoder, value);
225 }
226
227 FLAC__bool FLAC__file_decoder_set_filename(FLAC__FileDecoder *decoder, const char *value)
228 {
229         FLAC__ASSERT(decoder != 0);
230         FLAC__ASSERT(decoder->private_ != 0);
231         FLAC__ASSERT(decoder->protected_ != 0);
232         FLAC__ASSERT(value != 0);
233         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
234                 return false;
235         if(0 != decoder->private_->filename) {
236                 free(decoder->private_->filename);
237                 decoder->private_->filename = 0;
238         }
239         if(0 != strcmp(value, "-")) {
240                 if(0 == (decoder->private_->filename = (char*)malloc(strlen(value)+1))) {
241                         decoder->protected_->state = FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR;
242                         return false;
243                 }
244                 strcpy(decoder->private_->filename, value);
245         }
246         return true;
247 }
248
249 FLAC__bool FLAC__file_decoder_set_write_callback(FLAC__FileDecoder *decoder, FLAC__StreamDecoderWriteStatus (*value)(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data))
250 {
251         FLAC__ASSERT(decoder != 0);
252         FLAC__ASSERT(decoder->private_ != 0);
253         FLAC__ASSERT(decoder->protected_ != 0);
254         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
255                 return false;
256         decoder->private_->write_callback = value;
257         return true;
258 }
259
260 FLAC__bool FLAC__file_decoder_set_metadata_callback(FLAC__FileDecoder *decoder, void (*value)(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data))
261 {
262         FLAC__ASSERT(decoder != 0);
263         FLAC__ASSERT(decoder->private_ != 0);
264         FLAC__ASSERT(decoder->protected_ != 0);
265         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
266                 return false;
267         decoder->private_->metadata_callback = value;
268         return true;
269 }
270
271 FLAC__bool FLAC__file_decoder_set_error_callback(FLAC__FileDecoder *decoder, void (*value)(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data))
272 {
273         FLAC__ASSERT(decoder != 0);
274         FLAC__ASSERT(decoder->private_ != 0);
275         FLAC__ASSERT(decoder->protected_ != 0);
276         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
277                 return false;
278         decoder->private_->error_callback = value;
279         return true;
280 }
281
282 FLAC__bool FLAC__file_decoder_set_client_data(FLAC__FileDecoder *decoder, void *value)
283 {
284         FLAC__ASSERT(decoder != 0);
285         FLAC__ASSERT(decoder->private_ != 0);
286         FLAC__ASSERT(decoder->protected_ != 0);
287         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
288                 return false;
289         decoder->private_->client_data = value;
290         return true;
291 }
292
293 FLAC__bool FLAC__file_decoder_set_metadata_respond(FLAC__FileDecoder *decoder, FLAC__MetaDataType type)
294 {
295         FLAC__ASSERT(decoder != 0);
296         FLAC__ASSERT(decoder->private_ != 0);
297         FLAC__ASSERT(decoder->protected_ != 0);
298         FLAC__ASSERT(decoder->private_->seekable_stream_decoder != 0);
299         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
300                 return false;
301         return FLAC__seekable_stream_decoder_set_metadata_respond(decoder->private_->seekable_stream_decoder, type);
302 }
303
304 FLAC__bool FLAC__file_decoder_set_metadata_respond_application(FLAC__FileDecoder *decoder, const FLAC__byte id[4])
305 {
306         FLAC__ASSERT(decoder != 0);
307         FLAC__ASSERT(decoder->private_ != 0);
308         FLAC__ASSERT(decoder->protected_ != 0);
309         FLAC__ASSERT(decoder->private_->seekable_stream_decoder != 0);
310         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
311                 return false;
312         return FLAC__seekable_stream_decoder_set_metadata_respond_application(decoder->private_->seekable_stream_decoder, id);
313 }
314
315 FLAC__bool FLAC__file_decoder_set_metadata_respond_all(FLAC__FileDecoder *decoder)
316 {
317         FLAC__ASSERT(decoder != 0);
318         FLAC__ASSERT(decoder->private_ != 0);
319         FLAC__ASSERT(decoder->protected_ != 0);
320         FLAC__ASSERT(decoder->private_->seekable_stream_decoder != 0);
321         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
322                 return false;
323         return FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder->private_->seekable_stream_decoder);
324 }
325
326 FLAC__bool FLAC__file_decoder_set_metadata_ignore(FLAC__FileDecoder *decoder, FLAC__MetaDataType type)
327 {
328         FLAC__ASSERT(decoder != 0);
329         FLAC__ASSERT(decoder->private_ != 0);
330         FLAC__ASSERT(decoder->protected_ != 0);
331         FLAC__ASSERT(decoder->private_->seekable_stream_decoder != 0);
332         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
333                 return false;
334         return FLAC__seekable_stream_decoder_set_metadata_ignore(decoder->private_->seekable_stream_decoder, type);
335 }
336
337 FLAC__bool FLAC__file_decoder_set_metadata_ignore_application(FLAC__FileDecoder *decoder, const FLAC__byte id[4])
338 {
339         FLAC__ASSERT(decoder != 0);
340         FLAC__ASSERT(decoder->private_ != 0);
341         FLAC__ASSERT(decoder->protected_ != 0);
342         FLAC__ASSERT(decoder->private_->seekable_stream_decoder != 0);
343         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
344                 return false;
345         return FLAC__seekable_stream_decoder_set_metadata_ignore_application(decoder->private_->seekable_stream_decoder, id);
346 }
347
348 FLAC__bool FLAC__file_decoder_set_metadata_ignore_all(FLAC__FileDecoder *decoder)
349 {
350         FLAC__ASSERT(decoder != 0);
351         FLAC__ASSERT(decoder->private_ != 0);
352         FLAC__ASSERT(decoder->protected_ != 0);
353         FLAC__ASSERT(decoder->private_->seekable_stream_decoder != 0);
354         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
355                 return false;
356         return FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder->private_->seekable_stream_decoder);
357 }
358
359
360 FLAC__FileDecoderState FLAC__file_decoder_get_state(const FLAC__FileDecoder *decoder)
361 {
362         FLAC__ASSERT(decoder != 0);
363         FLAC__ASSERT(decoder->protected_ != 0);
364         return decoder->protected_->state;
365 }
366
367 FLAC__bool FLAC__file_decoder_get_md5_checking(const FLAC__FileDecoder *decoder)
368 {
369         FLAC__ASSERT(decoder != 0);
370         FLAC__ASSERT(decoder->private_ != 0);
371         return FLAC__seekable_stream_decoder_get_md5_checking(decoder->private_->seekable_stream_decoder);
372 }
373
374 FLAC__bool FLAC__file_decoder_process_whole_file(FLAC__FileDecoder *decoder)
375 {
376         FLAC__bool ret;
377         FLAC__ASSERT(decoder != 0);
378
379         if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
380                 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
381
382         if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
383                 return true;
384
385         FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
386
387         ret = FLAC__seekable_stream_decoder_process_whole_stream(decoder->private_->seekable_stream_decoder);
388         if(!ret)
389                 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
390
391         return ret;
392 }
393
394 FLAC__bool FLAC__file_decoder_process_metadata(FLAC__FileDecoder *decoder)
395 {
396         FLAC__bool ret;
397         FLAC__ASSERT(decoder != 0);
398
399         if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
400                 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
401
402         if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
403                 return true;
404
405         FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
406
407         ret = FLAC__seekable_stream_decoder_process_metadata(decoder->private_->seekable_stream_decoder);
408         if(!ret)
409                 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
410
411         return ret;
412 }
413
414 FLAC__bool FLAC__file_decoder_process_one_frame(FLAC__FileDecoder *decoder)
415 {
416         FLAC__bool ret;
417         FLAC__ASSERT(decoder != 0);
418
419         if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
420                 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
421
422         if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
423                 return true;
424
425         FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
426
427         ret = FLAC__seekable_stream_decoder_process_one_frame(decoder->private_->seekable_stream_decoder);
428         if(!ret)
429                 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
430
431         return ret;
432 }
433
434 FLAC__bool FLAC__file_decoder_process_remaining_frames(FLAC__FileDecoder *decoder)
435 {
436         FLAC__bool ret;
437         FLAC__ASSERT(decoder != 0);
438
439         if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
440                 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
441
442         if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
443                 return true;
444
445         FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
446
447         ret = FLAC__seekable_stream_decoder_process_remaining_frames(decoder->private_->seekable_stream_decoder);
448         if(!ret)
449                 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
450
451         return ret;
452 }
453
454 FLAC__bool FLAC__file_decoder_seek_absolute(FLAC__FileDecoder *decoder, FLAC__uint64 sample)
455 {
456         FLAC__ASSERT(decoder != 0);
457         FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK || decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE);
458
459         if(decoder->private_->filename == 0) { /* means the file is stdin... */
460                 decoder->protected_->state = FLAC__FILE_DECODER_SEEK_ERROR;
461                 return false;
462         }
463
464         if(!FLAC__seekable_stream_decoder_seek_absolute(decoder->private_->seekable_stream_decoder, sample)) {
465                 decoder->protected_->state = FLAC__FILE_DECODER_SEEK_ERROR;
466                 return false;
467         }
468         else {
469                 decoder->protected_->state = FLAC__FILE_DECODER_OK;
470                 return true;
471         }
472 }
473
474 /***********************************************************************
475  *
476  * Private class methods
477  *
478  ***********************************************************************/
479
480 /*
481  * This will forcibly set stdin to binary mode (for OSes that require it)
482  */
483 FILE *get_binary_stdin_()
484 {
485         /* if something breaks here it is probably due to the presence or
486          * absence of an underscore before the identifiers 'setmode',
487          * 'fileno', and/or 'O_BINARY'; check your system header files.
488          */
489 #if defined _MSC_VER || defined __MINGW32__
490         _setmode(_fileno(stdin), _O_BINARY);
491 #elif defined __CYGWIN__
492         /* almost certainly not needed for any modern Cygwin, but let's be safe... */
493         setmode(_fileno(stdin), _O_BINARY);
494 #endif
495
496         return stdin;
497 }
498
499 FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
500 {
501         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
502         (void)decoder;
503
504         if(*bytes > 0) {
505                 size_t bytes_read = fread(buffer, sizeof(FLAC__byte), *bytes, file_decoder->private_->file);
506                 if(bytes_read == 0 && !feof(file_decoder->private_->file)) {
507                         return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
508                 }
509                 else {
510                         *bytes = (unsigned)bytes_read;
511                         return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
512                 }
513         }
514         else
515                 return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; /* abort to avoid a deadlock */
516 }
517
518 FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
519 {
520         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
521         (void)decoder;
522
523         if(fseek(file_decoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0)
524                 return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
525         else
526                 return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
527 }
528
529 FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
530 {
531         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
532         long pos;
533         (void)decoder;
534
535         if((pos = ftell(file_decoder->private_->file)) < 0)
536                 return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
537         else {
538                 *absolute_byte_offset = (FLAC__uint64)pos;
539                 return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
540         }
541 }
542
543 FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
544 {
545         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
546         struct stat filestats;
547         (void)decoder;
548
549         if(0 == file_decoder->private_->filename || stat(file_decoder->private_->filename, &filestats) != 0)
550                 return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
551         else {
552                 *stream_length = (FLAC__uint64)filestats.st_size;
553                 return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
554         }
555 }
556
557 FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data)
558 {
559         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
560         (void)decoder;
561
562         return feof(file_decoder->private_->file);
563 }
564
565 FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data)
566 {
567         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
568         (void)decoder;
569
570         return file_decoder->private_->write_callback(file_decoder, frame, buffer, file_decoder->private_->client_data);
571 }
572
573 void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data)
574 {
575         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
576         (void)decoder;
577
578         file_decoder->private_->metadata_callback(file_decoder, metadata, file_decoder->private_->client_data);
579 }
580
581 void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
582 {
583         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
584         (void)decoder;
585
586         file_decoder->private_->error_callback(file_decoder, status, file_decoder->private_->client_data);
587 }