revamp decoder process calls
[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 void set_defaults_(FLAC__FileDecoder *decoder);
42 static FILE *get_binary_stdin_();
43 static FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
44 static FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
45 static FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
46 static FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
47 static FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data);
48 static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
49 static void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
50 static void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
51
52 /***********************************************************************
53  *
54  * Private class data
55  *
56  ***********************************************************************/
57
58 typedef struct FLAC__FileDecoderPrivate {
59         FLAC__FileDecoderWriteCallback write_callback;
60         FLAC__FileDecoderMetadataCallback metadata_callback;
61         FLAC__FileDecoderErrorCallback error_callback;
62         void *client_data;
63         FILE *file;
64         char *filename; /* == NULL if stdin */
65         FLAC__SeekableStreamDecoder *seekable_stream_decoder;
66 } FLAC__FileDecoderPrivate;
67
68 /***********************************************************************
69  *
70  * Public static class data
71  *
72  ***********************************************************************/
73
74 const char * const FLAC__FileDecoderStateString[] = {
75         "FLAC__FILE_DECODER_OK",
76         "FLAC__FILE_DECODER_END_OF_FILE",
77         "FLAC__FILE_DECODER_ERROR_OPENING_FILE",
78         "FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR",
79         "FLAC__FILE_DECODER_SEEK_ERROR",
80         "FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_DECODER_ERROR",
81         "FLAC__FILE_DECODER_ALREADY_INITIALIZED",
82         "FLAC__FILE_DECODER_INVALID_CALLBACK",
83         "FLAC__FILE_DECODER_UNINITIALIZED"
84 };
85
86 /***********************************************************************
87  *
88  * Class constructor/destructor
89  *
90  ***********************************************************************/
91
92 FLAC__FileDecoder *FLAC__file_decoder_new()
93 {
94         FLAC__FileDecoder *decoder;
95
96         FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
97
98         decoder = (FLAC__FileDecoder*)malloc(sizeof(FLAC__FileDecoder));
99         if(decoder == 0) {
100                 return 0;
101         }
102         decoder->protected_ = (FLAC__FileDecoderProtected*)malloc(sizeof(FLAC__FileDecoderProtected));
103         if(decoder->protected_ == 0) {
104                 free(decoder);
105                 return 0;
106         }
107         decoder->private_ = (FLAC__FileDecoderPrivate*)malloc(sizeof(FLAC__FileDecoderPrivate));
108         if(decoder->private_ == 0) {
109                 free(decoder->protected_);
110                 free(decoder);
111                 return 0;
112         }
113
114         decoder->private_->seekable_stream_decoder = FLAC__seekable_stream_decoder_new();
115
116         if(0 == decoder->private_->seekable_stream_decoder) {
117                 free(decoder->private_);
118                 free(decoder->protected_);
119                 free(decoder);
120                 return 0;
121         }
122
123         decoder->private_->file = 0;
124
125         set_defaults_(decoder);
126
127         decoder->protected_->state = FLAC__FILE_DECODER_UNINITIALIZED;
128
129         return decoder;
130 }
131
132 void FLAC__file_decoder_delete(FLAC__FileDecoder *decoder)
133 {
134         FLAC__ASSERT(0 != decoder);
135         FLAC__ASSERT(0 != decoder->protected_);
136         FLAC__ASSERT(0 != decoder->private_);
137         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
138
139         (void)FLAC__file_decoder_finish(decoder);
140
141         FLAC__seekable_stream_decoder_delete(decoder->private_->seekable_stream_decoder);
142
143         free(decoder->private_);
144         free(decoder->protected_);
145         free(decoder);
146 }
147
148 /***********************************************************************
149  *
150  * Public class methods
151  *
152  ***********************************************************************/
153
154 FLAC__FileDecoderState FLAC__file_decoder_init(FLAC__FileDecoder *decoder)
155 {
156         FLAC__ASSERT(0 != decoder);
157
158         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
159                 return decoder->protected_->state = FLAC__FILE_DECODER_ALREADY_INITIALIZED;
160
161         if(0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
162                 return decoder->protected_->state = FLAC__FILE_DECODER_INVALID_CALLBACK;
163
164         if(0 == decoder->private_->filename)
165                 decoder->private_->file = get_binary_stdin_();
166         else
167                 decoder->private_->file = fopen(decoder->private_->filename, "rb");
168
169         if(decoder->private_->file == 0)
170                 return decoder->protected_->state = FLAC__FILE_DECODER_ERROR_OPENING_FILE;
171
172         FLAC__seekable_stream_decoder_set_read_callback(decoder->private_->seekable_stream_decoder, read_callback_);
173         FLAC__seekable_stream_decoder_set_seek_callback(decoder->private_->seekable_stream_decoder, seek_callback_);
174         FLAC__seekable_stream_decoder_set_tell_callback(decoder->private_->seekable_stream_decoder, tell_callback_);
175         FLAC__seekable_stream_decoder_set_length_callback(decoder->private_->seekable_stream_decoder, length_callback_);
176         FLAC__seekable_stream_decoder_set_eof_callback(decoder->private_->seekable_stream_decoder, eof_callback_);
177         FLAC__seekable_stream_decoder_set_write_callback(decoder->private_->seekable_stream_decoder, write_callback_);
178         FLAC__seekable_stream_decoder_set_metadata_callback(decoder->private_->seekable_stream_decoder, metadata_callback_);
179         FLAC__seekable_stream_decoder_set_error_callback(decoder->private_->seekable_stream_decoder, error_callback_);
180         FLAC__seekable_stream_decoder_set_client_data(decoder->private_->seekable_stream_decoder, decoder);
181
182         if(FLAC__seekable_stream_decoder_init(decoder->private_->seekable_stream_decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK)
183                 return decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
184
185         return decoder->protected_->state = FLAC__FILE_DECODER_OK;
186 }
187
188 FLAC__bool FLAC__file_decoder_finish(FLAC__FileDecoder *decoder)
189 {
190         FLAC__ASSERT(0 != decoder);
191
192         if(decoder->protected_->state == FLAC__FILE_DECODER_UNINITIALIZED)
193                 return true;
194
195         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
196
197         if(0 != decoder->private_->file && decoder->private_->file != stdin) {
198                 fclose(decoder->private_->file);
199                 decoder->private_->file = 0;
200         }
201
202         if(0 != decoder->private_->filename) {
203                 free(decoder->private_->filename);
204                 decoder->private_->filename = 0;
205         }
206
207         set_defaults_(decoder);
208
209         decoder->protected_->state = FLAC__FILE_DECODER_UNINITIALIZED;
210
211         return FLAC__seekable_stream_decoder_finish(decoder->private_->seekable_stream_decoder);
212 }
213
214 FLAC__bool FLAC__file_decoder_set_md5_checking(FLAC__FileDecoder *decoder, FLAC__bool value)
215 {
216         FLAC__ASSERT(0 != decoder);
217         FLAC__ASSERT(0 != decoder->private_);
218         FLAC__ASSERT(0 != decoder->protected_);
219         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
220         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
221                 return false;
222         return FLAC__seekable_stream_decoder_set_md5_checking(decoder->private_->seekable_stream_decoder, value);
223 }
224
225 FLAC__bool FLAC__file_decoder_set_filename(FLAC__FileDecoder *decoder, const char *value)
226 {
227         FLAC__ASSERT(0 != decoder);
228         FLAC__ASSERT(0 != decoder->private_);
229         FLAC__ASSERT(0 != decoder->protected_);
230         FLAC__ASSERT(0 != value);
231         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
232                 return false;
233         if(0 != decoder->private_->filename) {
234                 free(decoder->private_->filename);
235                 decoder->private_->filename = 0;
236         }
237         if(0 != strcmp(value, "-")) {
238                 if(0 == (decoder->private_->filename = (char*)malloc(strlen(value)+1))) {
239                         decoder->protected_->state = FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR;
240                         return false;
241                 }
242                 strcpy(decoder->private_->filename, value);
243         }
244         return true;
245 }
246
247 FLAC__bool FLAC__file_decoder_set_write_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderWriteCallback value)
248 {
249         FLAC__ASSERT(0 != decoder);
250         FLAC__ASSERT(0 != decoder->private_);
251         FLAC__ASSERT(0 != decoder->protected_);
252         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
253                 return false;
254         decoder->private_->write_callback = value;
255         return true;
256 }
257
258 FLAC__bool FLAC__file_decoder_set_metadata_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderMetadataCallback value)
259 {
260         FLAC__ASSERT(0 != decoder);
261         FLAC__ASSERT(0 != decoder->private_);
262         FLAC__ASSERT(0 != decoder->protected_);
263         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
264                 return false;
265         decoder->private_->metadata_callback = value;
266         return true;
267 }
268
269 FLAC__bool FLAC__file_decoder_set_error_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderErrorCallback value)
270 {
271         FLAC__ASSERT(0 != decoder);
272         FLAC__ASSERT(0 != decoder->private_);
273         FLAC__ASSERT(0 != decoder->protected_);
274         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
275                 return false;
276         decoder->private_->error_callback = value;
277         return true;
278 }
279
280 FLAC__bool FLAC__file_decoder_set_client_data(FLAC__FileDecoder *decoder, void *value)
281 {
282         FLAC__ASSERT(0 != decoder);
283         FLAC__ASSERT(0 != decoder->private_);
284         FLAC__ASSERT(0 != decoder->protected_);
285         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
286                 return false;
287         decoder->private_->client_data = value;
288         return true;
289 }
290
291 FLAC__bool FLAC__file_decoder_set_metadata_respond(FLAC__FileDecoder *decoder, FLAC__MetadataType type)
292 {
293         FLAC__ASSERT(0 != decoder);
294         FLAC__ASSERT(0 != decoder->private_);
295         FLAC__ASSERT(0 != decoder->protected_);
296         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
297         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
298                 return false;
299         return FLAC__seekable_stream_decoder_set_metadata_respond(decoder->private_->seekable_stream_decoder, type);
300 }
301
302 FLAC__bool FLAC__file_decoder_set_metadata_respond_application(FLAC__FileDecoder *decoder, const FLAC__byte id[4])
303 {
304         FLAC__ASSERT(0 != decoder);
305         FLAC__ASSERT(0 != decoder->private_);
306         FLAC__ASSERT(0 != decoder->protected_);
307         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
308         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
309                 return false;
310         return FLAC__seekable_stream_decoder_set_metadata_respond_application(decoder->private_->seekable_stream_decoder, id);
311 }
312
313 FLAC__bool FLAC__file_decoder_set_metadata_respond_all(FLAC__FileDecoder *decoder)
314 {
315         FLAC__ASSERT(0 != decoder);
316         FLAC__ASSERT(0 != decoder->private_);
317         FLAC__ASSERT(0 != decoder->protected_);
318         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
319         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
320                 return false;
321         return FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder->private_->seekable_stream_decoder);
322 }
323
324 FLAC__bool FLAC__file_decoder_set_metadata_ignore(FLAC__FileDecoder *decoder, FLAC__MetadataType type)
325 {
326         FLAC__ASSERT(0 != decoder);
327         FLAC__ASSERT(0 != decoder->private_);
328         FLAC__ASSERT(0 != decoder->protected_);
329         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
330         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
331                 return false;
332         return FLAC__seekable_stream_decoder_set_metadata_ignore(decoder->private_->seekable_stream_decoder, type);
333 }
334
335 FLAC__bool FLAC__file_decoder_set_metadata_ignore_application(FLAC__FileDecoder *decoder, const FLAC__byte id[4])
336 {
337         FLAC__ASSERT(0 != decoder);
338         FLAC__ASSERT(0 != decoder->private_);
339         FLAC__ASSERT(0 != decoder->protected_);
340         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
341         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
342                 return false;
343         return FLAC__seekable_stream_decoder_set_metadata_ignore_application(decoder->private_->seekable_stream_decoder, id);
344 }
345
346 FLAC__bool FLAC__file_decoder_set_metadata_ignore_all(FLAC__FileDecoder *decoder)
347 {
348         FLAC__ASSERT(0 != decoder);
349         FLAC__ASSERT(0 != decoder->private_);
350         FLAC__ASSERT(0 != decoder->protected_);
351         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
352         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
353                 return false;
354         return FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder->private_->seekable_stream_decoder);
355 }
356
357
358 FLAC__FileDecoderState FLAC__file_decoder_get_state(const FLAC__FileDecoder *decoder)
359 {
360         FLAC__ASSERT(0 != decoder);
361         FLAC__ASSERT(0 != decoder->protected_);
362         return decoder->protected_->state;
363 }
364
365 FLAC__SeekableStreamDecoderState FLAC__file_decoder_get_seekable_stream_decoder_state(const FLAC__FileDecoder *decoder)
366 {
367         FLAC__ASSERT(0 != decoder);
368         FLAC__ASSERT(0 != decoder->private_);
369         return FLAC__seekable_stream_decoder_get_state(decoder->private_->seekable_stream_decoder);
370 }
371
372 FLAC__StreamDecoderState FLAC__file_decoder_get_stream_decoder_state(const FLAC__FileDecoder *decoder)
373 {
374         FLAC__ASSERT(0 != decoder);
375         FLAC__ASSERT(0 != decoder->private_);
376         return FLAC__seekable_stream_decoder_get_stream_decoder_state(decoder->private_->seekable_stream_decoder);
377 }
378
379 FLAC__bool FLAC__file_decoder_get_md5_checking(const FLAC__FileDecoder *decoder)
380 {
381         FLAC__ASSERT(0 != decoder);
382         FLAC__ASSERT(0 != decoder->private_);
383         return FLAC__seekable_stream_decoder_get_md5_checking(decoder->private_->seekable_stream_decoder);
384 }
385
386 unsigned FLAC__file_decoder_get_channels(const FLAC__FileDecoder *decoder)
387 {
388         FLAC__ASSERT(0 != decoder);
389         FLAC__ASSERT(0 != decoder->private_);
390         return FLAC__seekable_stream_decoder_get_channels(decoder->private_->seekable_stream_decoder);
391 }
392
393 FLAC__ChannelAssignment FLAC__file_decoder_get_channel_assignment(const FLAC__FileDecoder *decoder)
394 {
395         FLAC__ASSERT(0 != decoder);
396         FLAC__ASSERT(0 != decoder->private_);
397         return FLAC__seekable_stream_decoder_get_channel_assignment(decoder->private_->seekable_stream_decoder);
398 }
399
400 unsigned FLAC__file_decoder_get_bits_per_sample(const FLAC__FileDecoder *decoder)
401 {
402         FLAC__ASSERT(0 != decoder);
403         FLAC__ASSERT(0 != decoder->private_);
404         return FLAC__seekable_stream_decoder_get_bits_per_sample(decoder->private_->seekable_stream_decoder);
405 }
406
407 unsigned FLAC__file_decoder_get_sample_rate(const FLAC__FileDecoder *decoder)
408 {
409         FLAC__ASSERT(0 != decoder);
410         FLAC__ASSERT(0 != decoder->private_);
411         return FLAC__seekable_stream_decoder_get_sample_rate(decoder->private_->seekable_stream_decoder);
412 }
413
414 unsigned FLAC__file_decoder_get_blocksize(const FLAC__FileDecoder *decoder)
415 {
416         FLAC__ASSERT(0 != decoder);
417         FLAC__ASSERT(0 != decoder->private_);
418         return FLAC__seekable_stream_decoder_get_blocksize(decoder->private_->seekable_stream_decoder);
419 }
420
421 FLAC__bool FLAC__file_decoder_process_single(FLAC__FileDecoder *decoder)
422 {
423         FLAC__bool ret;
424         FLAC__ASSERT(0 != decoder);
425
426         if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
427                 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
428
429         if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
430                 return true;
431
432         FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
433
434         ret = FLAC__seekable_stream_decoder_process_single(decoder->private_->seekable_stream_decoder);
435         if(!ret)
436                 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
437
438         return ret;
439 }
440
441 FLAC__bool FLAC__file_decoder_process_until_end_of_metadata(FLAC__FileDecoder *decoder)
442 {
443         FLAC__bool ret;
444         FLAC__ASSERT(0 != decoder);
445
446         if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
447                 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
448
449         if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
450                 return true;
451
452         FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
453
454         ret = FLAC__seekable_stream_decoder_process_until_end_of_metadata(decoder->private_->seekable_stream_decoder);
455         if(!ret)
456                 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
457
458         return ret;
459 }
460
461 FLAC__bool FLAC__file_decoder_process_until_end_of_file(FLAC__FileDecoder *decoder)
462 {
463         FLAC__bool ret;
464         FLAC__ASSERT(0 != decoder);
465
466         if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
467                 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
468
469         if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
470                 return true;
471
472         FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
473
474         ret = FLAC__seekable_stream_decoder_process_until_end_of_stream(decoder->private_->seekable_stream_decoder);
475         if(!ret)
476                 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
477
478         return ret;
479 }
480
481 FLAC__bool FLAC__file_decoder_seek_absolute(FLAC__FileDecoder *decoder, FLAC__uint64 sample)
482 {
483         FLAC__ASSERT(0 != decoder);
484         FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK || decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE);
485
486         if(decoder->private_->filename == 0) { /* means the file is stdin... */
487                 decoder->protected_->state = FLAC__FILE_DECODER_SEEK_ERROR;
488                 return false;
489         }
490
491         if(!FLAC__seekable_stream_decoder_seek_absolute(decoder->private_->seekable_stream_decoder, sample)) {
492                 decoder->protected_->state = FLAC__FILE_DECODER_SEEK_ERROR;
493                 return false;
494         }
495         else {
496                 decoder->protected_->state = FLAC__FILE_DECODER_OK;
497                 return true;
498         }
499 }
500
501
502 /***********************************************************************
503  *
504  * Private class methods
505  *
506  ***********************************************************************/
507
508 void set_defaults_(FLAC__FileDecoder *decoder)
509 {
510         FLAC__ASSERT(0 != decoder);
511         FLAC__ASSERT(0 != decoder->private_);
512
513         decoder->private_->filename = 0;
514         decoder->private_->write_callback = 0;
515         decoder->private_->metadata_callback = 0;
516         decoder->private_->error_callback = 0;
517         decoder->private_->client_data = 0;
518 }
519
520 /*
521  * This will forcibly set stdin to binary mode (for OSes that require it)
522  */
523 FILE *get_binary_stdin_()
524 {
525         /* if something breaks here it is probably due to the presence or
526          * absence of an underscore before the identifiers 'setmode',
527          * 'fileno', and/or 'O_BINARY'; check your system header files.
528          */
529 #if defined _MSC_VER || defined __MINGW32__
530         _setmode(_fileno(stdin), _O_BINARY);
531 #elif defined __CYGWIN__
532         /* almost certainly not needed for any modern Cygwin, but let's be safe... */
533         setmode(_fileno(stdin), _O_BINARY);
534 #endif
535
536         return stdin;
537 }
538
539 FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
540 {
541         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
542         (void)decoder;
543
544         if(*bytes > 0) {
545                 size_t bytes_read = fread(buffer, sizeof(FLAC__byte), *bytes, file_decoder->private_->file);
546                 if(bytes_read == 0 && !feof(file_decoder->private_->file)) {
547                         return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
548                 }
549                 else {
550                         *bytes = (unsigned)bytes_read;
551                         return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
552                 }
553         }
554         else
555                 return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; /* abort to avoid a deadlock */
556 }
557
558 FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
559 {
560         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
561         (void)decoder;
562
563         if(fseek(file_decoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0)
564                 return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
565         else
566                 return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
567 }
568
569 FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
570 {
571         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
572         long pos;
573         (void)decoder;
574
575         if((pos = ftell(file_decoder->private_->file)) < 0)
576                 return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
577         else {
578                 *absolute_byte_offset = (FLAC__uint64)pos;
579                 return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
580         }
581 }
582
583 FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
584 {
585         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
586         struct stat filestats;
587         (void)decoder;
588
589         if(0 == file_decoder->private_->filename || stat(file_decoder->private_->filename, &filestats) != 0)
590                 return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
591         else {
592                 *stream_length = (FLAC__uint64)filestats.st_size;
593                 return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
594         }
595 }
596
597 FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data)
598 {
599         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
600         (void)decoder;
601
602         return feof(file_decoder->private_->file);
603 }
604
605 FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
606 {
607         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
608         (void)decoder;
609
610         return file_decoder->private_->write_callback(file_decoder, frame, buffer, file_decoder->private_->client_data);
611 }
612
613 void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
614 {
615         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
616         (void)decoder;
617
618         file_decoder->private_->metadata_callback(file_decoder, metadata, file_decoder->private_->client_data);
619 }
620
621 void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
622 {
623         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
624         (void)decoder;
625
626         file_decoder->private_->error_callback(file_decoder, status, file_decoder->private_->client_data);
627 }