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