remove reference to obsolete Makefile.vc
[platform/upstream/flac.git] / src / libFLAC / file_decoder.c
1 /* libFLAC - Free Lossless Audio Codec library
2  * Copyright (C) 2000,2001,2002,2003  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 #include <fcntl.h> /* for _O_BINARY */
30 #endif
31 #include "FLAC/assert.h"
32 #include "protected/file_decoder.h"
33 #include "protected/seekable_stream_decoder.h"
34 #include "private/md5.h"
35
36 /***********************************************************************
37  *
38  * Private class method prototypes
39  *
40  ***********************************************************************/
41
42 static void set_defaults_(FLAC__FileDecoder *decoder);
43 static FILE *get_binary_stdin_();
44 static FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
45 static FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
46 static FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
47 static FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
48 static FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data);
49 static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
50 static void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
51 static void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
52
53 /***********************************************************************
54  *
55  * Private class data
56  *
57  ***********************************************************************/
58
59 typedef struct FLAC__FileDecoderPrivate {
60         FLAC__FileDecoderWriteCallback write_callback;
61         FLAC__FileDecoderMetadataCallback metadata_callback;
62         FLAC__FileDecoderErrorCallback error_callback;
63         void *client_data;
64         FILE *file;
65         char *filename; /* == NULL if stdin */
66         FLAC__SeekableStreamDecoder *seekable_stream_decoder;
67 } FLAC__FileDecoderPrivate;
68
69 /***********************************************************************
70  *
71  * Public static class data
72  *
73  ***********************************************************************/
74
75 FLAC_API const char * const FLAC__FileDecoderStateString[] = {
76         "FLAC__FILE_DECODER_OK",
77         "FLAC__FILE_DECODER_END_OF_FILE",
78         "FLAC__FILE_DECODER_ERROR_OPENING_FILE",
79         "FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR",
80         "FLAC__FILE_DECODER_SEEK_ERROR",
81         "FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR",
82         "FLAC__FILE_DECODER_ALREADY_INITIALIZED",
83         "FLAC__FILE_DECODER_INVALID_CALLBACK",
84         "FLAC__FILE_DECODER_UNINITIALIZED"
85 };
86
87 /***********************************************************************
88  *
89  * Class constructor/destructor
90  *
91  ***********************************************************************/
92
93 FLAC_API FLAC__FileDecoder *FLAC__file_decoder_new()
94 {
95         FLAC__FileDecoder *decoder;
96
97         FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
98
99         decoder = (FLAC__FileDecoder*)calloc(1, sizeof(FLAC__FileDecoder));
100         if(decoder == 0) {
101                 return 0;
102         }
103
104         decoder->protected_ = (FLAC__FileDecoderProtected*)calloc(1, sizeof(FLAC__FileDecoderProtected));
105         if(decoder->protected_ == 0) {
106                 free(decoder);
107                 return 0;
108         }
109
110         decoder->private_ = (FLAC__FileDecoderPrivate*)calloc(1, sizeof(FLAC__FileDecoderPrivate));
111         if(decoder->private_ == 0) {
112                 free(decoder->protected_);
113                 free(decoder);
114                 return 0;
115         }
116
117         decoder->private_->seekable_stream_decoder = FLAC__seekable_stream_decoder_new();
118         if(0 == decoder->private_->seekable_stream_decoder) {
119                 free(decoder->private_);
120                 free(decoder->protected_);
121                 free(decoder);
122                 return 0;
123         }
124
125         decoder->private_->file = 0;
126
127         set_defaults_(decoder);
128
129         decoder->protected_->state = FLAC__FILE_DECODER_UNINITIALIZED;
130
131         return decoder;
132 }
133
134 FLAC_API void FLAC__file_decoder_delete(FLAC__FileDecoder *decoder)
135 {
136         FLAC__ASSERT(0 != decoder);
137         FLAC__ASSERT(0 != decoder->protected_);
138         FLAC__ASSERT(0 != decoder->private_);
139         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
140
141         (void)FLAC__file_decoder_finish(decoder);
142
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_API FLAC__FileDecoderState FLAC__file_decoder_init(FLAC__FileDecoder *decoder)
157 {
158         FLAC__ASSERT(0 != decoder);
159
160         if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
161                 return decoder->protected_->state = FLAC__FILE_DECODER_ALREADY_INITIALIZED;
162
163         if(0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
164                 return decoder->protected_->state = FLAC__FILE_DECODER_INVALID_CALLBACK;
165
166         if(0 == decoder->private_->filename)
167                 decoder->private_->file = get_binary_stdin_();
168         else
169                 decoder->private_->file = fopen(decoder->private_->filename, "rb");
170
171         if(decoder->private_->file == 0)
172                 return decoder->protected_->state = FLAC__FILE_DECODER_ERROR_OPENING_FILE;
173
174         FLAC__seekable_stream_decoder_set_read_callback(decoder->private_->seekable_stream_decoder, read_callback_);
175         FLAC__seekable_stream_decoder_set_seek_callback(decoder->private_->seekable_stream_decoder, seek_callback_);
176         FLAC__seekable_stream_decoder_set_tell_callback(decoder->private_->seekable_stream_decoder, tell_callback_);
177         FLAC__seekable_stream_decoder_set_length_callback(decoder->private_->seekable_stream_decoder, length_callback_);
178         FLAC__seekable_stream_decoder_set_eof_callback(decoder->private_->seekable_stream_decoder, eof_callback_);
179         FLAC__seekable_stream_decoder_set_write_callback(decoder->private_->seekable_stream_decoder, write_callback_);
180         FLAC__seekable_stream_decoder_set_metadata_callback(decoder->private_->seekable_stream_decoder, metadata_callback_);
181         FLAC__seekable_stream_decoder_set_error_callback(decoder->private_->seekable_stream_decoder, error_callback_);
182         FLAC__seekable_stream_decoder_set_client_data(decoder->private_->seekable_stream_decoder, decoder);
183
184         if(FLAC__seekable_stream_decoder_init(decoder->private_->seekable_stream_decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK)
185                 return decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
186
187         return decoder->protected_->state = FLAC__FILE_DECODER_OK;
188 }
189
190 FLAC_API FLAC__bool FLAC__file_decoder_finish(FLAC__FileDecoder *decoder)
191 {
192         FLAC__ASSERT(0 != decoder);
193
194         if(decoder->protected_->state == FLAC__FILE_DECODER_UNINITIALIZED)
195                 return true;
196
197         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
198
199         if(0 != decoder->private_->file && decoder->private_->file != stdin) {
200                 fclose(decoder->private_->file);
201                 decoder->private_->file = 0;
202         }
203
204         if(0 != decoder->private_->filename) {
205                 free(decoder->private_->filename);
206                 decoder->private_->filename = 0;
207         }
208
209         set_defaults_(decoder);
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_API FLAC__bool FLAC__file_decoder_set_md5_checking(FLAC__FileDecoder *decoder, FLAC__bool value)
217 {
218         FLAC__ASSERT(0 != decoder);
219         FLAC__ASSERT(0 != decoder->private_);
220         FLAC__ASSERT(0 != decoder->protected_);
221         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
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_API FLAC__bool FLAC__file_decoder_set_filename(FLAC__FileDecoder *decoder, const char *value)
228 {
229         FLAC__ASSERT(0 != decoder);
230         FLAC__ASSERT(0 != decoder->private_);
231         FLAC__ASSERT(0 != decoder->protected_);
232         FLAC__ASSERT(0 != value);
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_API FLAC__bool FLAC__file_decoder_set_write_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderWriteCallback value)
250 {
251         FLAC__ASSERT(0 != decoder);
252         FLAC__ASSERT(0 != decoder->private_);
253         FLAC__ASSERT(0 != decoder->protected_);
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_API FLAC__bool FLAC__file_decoder_set_metadata_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderMetadataCallback value)
261 {
262         FLAC__ASSERT(0 != decoder);
263         FLAC__ASSERT(0 != decoder->private_);
264         FLAC__ASSERT(0 != decoder->protected_);
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_API FLAC__bool FLAC__file_decoder_set_error_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderErrorCallback value)
272 {
273         FLAC__ASSERT(0 != decoder);
274         FLAC__ASSERT(0 != decoder->private_);
275         FLAC__ASSERT(0 != decoder->protected_);
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_API FLAC__bool FLAC__file_decoder_set_client_data(FLAC__FileDecoder *decoder, void *value)
283 {
284         FLAC__ASSERT(0 != decoder);
285         FLAC__ASSERT(0 != decoder->private_);
286         FLAC__ASSERT(0 != decoder->protected_);
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_API FLAC__bool FLAC__file_decoder_set_metadata_respond(FLAC__FileDecoder *decoder, FLAC__MetadataType type)
294 {
295         FLAC__ASSERT(0 != decoder);
296         FLAC__ASSERT(0 != decoder->private_);
297         FLAC__ASSERT(0 != decoder->protected_);
298         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
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_API FLAC__bool FLAC__file_decoder_set_metadata_respond_application(FLAC__FileDecoder *decoder, const FLAC__byte id[4])
305 {
306         FLAC__ASSERT(0 != decoder);
307         FLAC__ASSERT(0 != decoder->private_);
308         FLAC__ASSERT(0 != decoder->protected_);
309         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
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_API FLAC__bool FLAC__file_decoder_set_metadata_respond_all(FLAC__FileDecoder *decoder)
316 {
317         FLAC__ASSERT(0 != decoder);
318         FLAC__ASSERT(0 != decoder->private_);
319         FLAC__ASSERT(0 != decoder->protected_);
320         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
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_API FLAC__bool FLAC__file_decoder_set_metadata_ignore(FLAC__FileDecoder *decoder, FLAC__MetadataType type)
327 {
328         FLAC__ASSERT(0 != decoder);
329         FLAC__ASSERT(0 != decoder->private_);
330         FLAC__ASSERT(0 != decoder->protected_);
331         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
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_API FLAC__bool FLAC__file_decoder_set_metadata_ignore_application(FLAC__FileDecoder *decoder, const FLAC__byte id[4])
338 {
339         FLAC__ASSERT(0 != decoder);
340         FLAC__ASSERT(0 != decoder->private_);
341         FLAC__ASSERT(0 != decoder->protected_);
342         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
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_API FLAC__bool FLAC__file_decoder_set_metadata_ignore_all(FLAC__FileDecoder *decoder)
349 {
350         FLAC__ASSERT(0 != decoder);
351         FLAC__ASSERT(0 != decoder->private_);
352         FLAC__ASSERT(0 != decoder->protected_);
353         FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
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 FLAC_API FLAC__FileDecoderState FLAC__file_decoder_get_state(const FLAC__FileDecoder *decoder)
360 {
361         FLAC__ASSERT(0 != decoder);
362         FLAC__ASSERT(0 != decoder->protected_);
363         return decoder->protected_->state;
364 }
365
366 FLAC_API FLAC__SeekableStreamDecoderState FLAC__file_decoder_get_seekable_stream_decoder_state(const FLAC__FileDecoder *decoder)
367 {
368         FLAC__ASSERT(0 != decoder);
369         FLAC__ASSERT(0 != decoder->private_);
370         return FLAC__seekable_stream_decoder_get_state(decoder->private_->seekable_stream_decoder);
371 }
372
373 FLAC_API FLAC__StreamDecoderState FLAC__file_decoder_get_stream_decoder_state(const FLAC__FileDecoder *decoder)
374 {
375         FLAC__ASSERT(0 != decoder);
376         FLAC__ASSERT(0 != decoder->private_);
377         return FLAC__seekable_stream_decoder_get_stream_decoder_state(decoder->private_->seekable_stream_decoder);
378 }
379
380 FLAC_API const char *FLAC__file_decoder_get_resolved_state_string(const FLAC__FileDecoder *decoder)
381 {
382         if(decoder->protected_->state != FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR)
383                 return FLAC__FileDecoderStateString[decoder->protected_->state];
384         else
385                 return FLAC__seekable_stream_decoder_get_resolved_state_string(decoder->private_->seekable_stream_decoder);
386 }
387
388 FLAC_API FLAC__bool FLAC__file_decoder_get_md5_checking(const FLAC__FileDecoder *decoder)
389 {
390         FLAC__ASSERT(0 != decoder);
391         FLAC__ASSERT(0 != decoder->private_);
392         return FLAC__seekable_stream_decoder_get_md5_checking(decoder->private_->seekable_stream_decoder);
393 }
394
395 FLAC_API unsigned FLAC__file_decoder_get_channels(const FLAC__FileDecoder *decoder)
396 {
397         FLAC__ASSERT(0 != decoder);
398         FLAC__ASSERT(0 != decoder->private_);
399         return FLAC__seekable_stream_decoder_get_channels(decoder->private_->seekable_stream_decoder);
400 }
401
402 FLAC_API FLAC__ChannelAssignment FLAC__file_decoder_get_channel_assignment(const FLAC__FileDecoder *decoder)
403 {
404         FLAC__ASSERT(0 != decoder);
405         FLAC__ASSERT(0 != decoder->private_);
406         return FLAC__seekable_stream_decoder_get_channel_assignment(decoder->private_->seekable_stream_decoder);
407 }
408
409 FLAC_API unsigned FLAC__file_decoder_get_bits_per_sample(const FLAC__FileDecoder *decoder)
410 {
411         FLAC__ASSERT(0 != decoder);
412         FLAC__ASSERT(0 != decoder->private_);
413         return FLAC__seekable_stream_decoder_get_bits_per_sample(decoder->private_->seekable_stream_decoder);
414 }
415
416 FLAC_API unsigned FLAC__file_decoder_get_sample_rate(const FLAC__FileDecoder *decoder)
417 {
418         FLAC__ASSERT(0 != decoder);
419         FLAC__ASSERT(0 != decoder->private_);
420         return FLAC__seekable_stream_decoder_get_sample_rate(decoder->private_->seekable_stream_decoder);
421 }
422
423 FLAC_API unsigned FLAC__file_decoder_get_blocksize(const FLAC__FileDecoder *decoder)
424 {
425         FLAC__ASSERT(0 != decoder);
426         FLAC__ASSERT(0 != decoder->private_);
427         return FLAC__seekable_stream_decoder_get_blocksize(decoder->private_->seekable_stream_decoder);
428 }
429
430 FLAC_API FLAC__bool FLAC__file_decoder_get_decode_position(const FLAC__FileDecoder *decoder, FLAC__uint64 *position)
431 {
432         FLAC__ASSERT(0 != decoder);
433         FLAC__ASSERT(0 != decoder->private_);
434         return FLAC__seekable_stream_decoder_get_decode_position(decoder->private_->seekable_stream_decoder, position);
435 }
436
437 FLAC_API FLAC__bool FLAC__file_decoder_process_single(FLAC__FileDecoder *decoder)
438 {
439         FLAC__bool ret;
440         FLAC__ASSERT(0 != decoder);
441
442         if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
443                 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
444
445         if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
446                 return true;
447
448         FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
449
450         ret = FLAC__seekable_stream_decoder_process_single(decoder->private_->seekable_stream_decoder);
451         if(!ret)
452                 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
453
454         return ret;
455 }
456
457 FLAC_API FLAC__bool FLAC__file_decoder_process_until_end_of_metadata(FLAC__FileDecoder *decoder)
458 {
459         FLAC__bool ret;
460         FLAC__ASSERT(0 != decoder);
461
462         if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
463                 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
464
465         if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
466                 return true;
467
468         FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
469
470         ret = FLAC__seekable_stream_decoder_process_until_end_of_metadata(decoder->private_->seekable_stream_decoder);
471         if(!ret)
472                 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
473
474         return ret;
475 }
476
477 FLAC_API FLAC__bool FLAC__file_decoder_process_until_end_of_file(FLAC__FileDecoder *decoder)
478 {
479         FLAC__bool ret;
480         FLAC__ASSERT(0 != decoder);
481
482         if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
483                 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
484
485         if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
486                 return true;
487
488         FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
489
490         ret = FLAC__seekable_stream_decoder_process_until_end_of_stream(decoder->private_->seekable_stream_decoder);
491         if(!ret)
492                 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
493
494         return ret;
495 }
496
497 FLAC_API FLAC__bool FLAC__file_decoder_seek_absolute(FLAC__FileDecoder *decoder, FLAC__uint64 sample)
498 {
499         FLAC__ASSERT(0 != decoder);
500         FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK || decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE);
501
502         if(decoder->private_->filename == 0) { /* means the file is stdin... */
503                 decoder->protected_->state = FLAC__FILE_DECODER_SEEK_ERROR;
504                 return false;
505         }
506
507         if(!FLAC__seekable_stream_decoder_seek_absolute(decoder->private_->seekable_stream_decoder, sample)) {
508                 decoder->protected_->state = FLAC__FILE_DECODER_SEEK_ERROR;
509                 return false;
510         }
511         else {
512                 decoder->protected_->state = FLAC__FILE_DECODER_OK;
513                 return true;
514         }
515 }
516
517
518 /***********************************************************************
519  *
520  * Private class methods
521  *
522  ***********************************************************************/
523
524 void set_defaults_(FLAC__FileDecoder *decoder)
525 {
526         FLAC__ASSERT(0 != decoder);
527         FLAC__ASSERT(0 != decoder->private_);
528
529         decoder->private_->filename = 0;
530         decoder->private_->write_callback = 0;
531         decoder->private_->metadata_callback = 0;
532         decoder->private_->error_callback = 0;
533         decoder->private_->client_data = 0;
534 }
535
536 /*
537  * This will forcibly set stdin to binary mode (for OSes that require it)
538  */
539 FILE *get_binary_stdin_()
540 {
541         /* if something breaks here it is probably due to the presence or
542          * absence of an underscore before the identifiers 'setmode',
543          * 'fileno', and/or 'O_BINARY'; check your system header files.
544          */
545 #if defined _MSC_VER || defined __MINGW32__
546         _setmode(_fileno(stdin), _O_BINARY);
547 #elif defined __CYGWIN__
548         /* almost certainly not needed for any modern Cygwin, but let's be safe... */
549         setmode(_fileno(stdin), _O_BINARY);
550 #endif
551
552         return stdin;
553 }
554
555 FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
556 {
557         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
558         (void)decoder;
559
560         if(*bytes > 0) {
561                 size_t bytes_read = fread(buffer, sizeof(FLAC__byte), *bytes, file_decoder->private_->file);
562                 if(bytes_read == 0 && !feof(file_decoder->private_->file)) {
563                         return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
564                 }
565                 else {
566                         *bytes = (unsigned)bytes_read;
567                         return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
568                 }
569         }
570         else
571                 return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; /* abort to avoid a deadlock */
572 }
573
574 FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
575 {
576         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
577         (void)decoder;
578
579         if(fseek(file_decoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0)
580                 return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
581         else
582                 return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
583 }
584
585 FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
586 {
587         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
588         long pos;
589         (void)decoder;
590
591         if((pos = ftell(file_decoder->private_->file)) < 0)
592                 return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
593         else {
594                 *absolute_byte_offset = (FLAC__uint64)pos;
595                 return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
596         }
597 }
598
599 FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
600 {
601         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
602         struct stat filestats;
603         (void)decoder;
604
605         if(0 == file_decoder->private_->filename || stat(file_decoder->private_->filename, &filestats) != 0)
606                 return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
607         else {
608                 *stream_length = (FLAC__uint64)filestats.st_size;
609                 return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
610         }
611 }
612
613 FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data)
614 {
615         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
616         (void)decoder;
617
618         return feof(file_decoder->private_->file);
619 }
620
621 FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
622 {
623         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
624         (void)decoder;
625
626         return file_decoder->private_->write_callback(file_decoder, frame, buffer, file_decoder->private_->client_data);
627 }
628
629 void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
630 {
631         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
632         (void)decoder;
633
634         file_decoder->private_->metadata_callback(file_decoder, metadata, file_decoder->private_->client_data);
635 }
636
637 void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
638 {
639         FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
640         (void)decoder;
641
642         file_decoder->private_->error_callback(file_decoder, status, file_decoder->private_->client_data);
643 }