summaryrefslogtreecommitdiff
path: root/apps/codecs/libFLAC/file_decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libFLAC/file_decoder.c')
-rw-r--r--apps/codecs/libFLAC/file_decoder.c673
1 files changed, 673 insertions, 0 deletions
diff --git a/apps/codecs/libFLAC/file_decoder.c b/apps/codecs/libFLAC/file_decoder.c
new file mode 100644
index 0000000000..29d489587a
--- /dev/null
+++ b/apps/codecs/libFLAC/file_decoder.c
@@ -0,0 +1,673 @@
1/* libFLAC - Free Lossless Audio Codec library
2 * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * - Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * - Neither the name of the Xiph.org Foundation nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <stdio.h>
33#include <stdlib.h> /* for malloc() */
34#include <string.h> /* for strcmp() */
35#include <sys/stat.h> /* for stat() */
36#if defined _MSC_VER || defined __MINGW32__
37#include <io.h> /* for _setmode() */
38#include <fcntl.h> /* for _O_BINARY */
39#elif defined __CYGWIN__
40#include <io.h> /* for setmode(), O_BINARY */
41#include <fcntl.h> /* for _O_BINARY */
42#endif
43#include "FLAC/assert.h"
44#include "protected/file_decoder.h"
45#include "protected/seekable_stream_decoder.h"
46
47/***********************************************************************
48 *
49 * Private class method prototypes
50 *
51 ***********************************************************************/
52
53static void set_defaults_(FLAC__FileDecoder *decoder);
54static FILE *get_binary_stdin_();
55static FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
56static FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
57static FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
58static FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
59static FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data);
60static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
61static void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
62static void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
63
64/***********************************************************************
65 *
66 * Private class data
67 *
68 ***********************************************************************/
69
70typedef struct FLAC__FileDecoderPrivate {
71 FLAC__FileDecoderWriteCallback write_callback;
72 FLAC__FileDecoderMetadataCallback metadata_callback;
73 FLAC__FileDecoderErrorCallback error_callback;
74 void *client_data;
75 FILE *file;
76 char *filename; /* == NULL if stdin */
77 FLAC__SeekableStreamDecoder *seekable_stream_decoder;
78} FLAC__FileDecoderPrivate;
79
80/***********************************************************************
81 *
82 * Public static class data
83 *
84 ***********************************************************************/
85
86FLAC_API const char * const FLAC__FileDecoderStateString[] = {
87 "FLAC__FILE_DECODER_OK",
88 "FLAC__FILE_DECODER_END_OF_FILE",
89 "FLAC__FILE_DECODER_ERROR_OPENING_FILE",
90 "FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR",
91 "FLAC__FILE_DECODER_SEEK_ERROR",
92 "FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR",
93 "FLAC__FILE_DECODER_ALREADY_INITIALIZED",
94 "FLAC__FILE_DECODER_INVALID_CALLBACK",
95 "FLAC__FILE_DECODER_UNINITIALIZED"
96};
97
98/***********************************************************************
99 *
100 * Class constructor/destructor
101 *
102 ***********************************************************************/
103
104FLAC_API FLAC__FileDecoder *FLAC__file_decoder_new()
105{
106 FLAC__FileDecoder *decoder;
107
108 FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
109
110 decoder = (FLAC__FileDecoder*)calloc(1, sizeof(FLAC__FileDecoder));
111 if(decoder == 0) {
112 return 0;
113 }
114
115 decoder->protected_ = (FLAC__FileDecoderProtected*)calloc(1, sizeof(FLAC__FileDecoderProtected));
116 if(decoder->protected_ == 0) {
117 free(decoder);
118 return 0;
119 }
120
121 decoder->private_ = (FLAC__FileDecoderPrivate*)calloc(1, sizeof(FLAC__FileDecoderPrivate));
122 if(decoder->private_ == 0) {
123 free(decoder->protected_);
124 free(decoder);
125 return 0;
126 }
127
128 decoder->private_->seekable_stream_decoder = FLAC__seekable_stream_decoder_new();
129 if(0 == decoder->private_->seekable_stream_decoder) {
130 free(decoder->private_);
131 free(decoder->protected_);
132 free(decoder);
133 return 0;
134 }
135
136 decoder->private_->file = 0;
137
138 set_defaults_(decoder);
139
140 decoder->protected_->state = FLAC__FILE_DECODER_UNINITIALIZED;
141
142 return decoder;
143}
144
145FLAC_API void FLAC__file_decoder_delete(FLAC__FileDecoder *decoder)
146{
147 FLAC__ASSERT(0 != decoder);
148 FLAC__ASSERT(0 != decoder->protected_);
149 FLAC__ASSERT(0 != decoder->private_);
150 FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
151
152 (void)FLAC__file_decoder_finish(decoder);
153
154 FLAC__seekable_stream_decoder_delete(decoder->private_->seekable_stream_decoder);
155
156 free(decoder->private_);
157 free(decoder->protected_);
158 free(decoder);
159}
160
161/***********************************************************************
162 *
163 * Public class methods
164 *
165 ***********************************************************************/
166
167FLAC_API FLAC__FileDecoderState FLAC__file_decoder_init(FLAC__FileDecoder *decoder)
168{
169 FLAC__ASSERT(0 != decoder);
170
171 if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
172 return decoder->protected_->state = FLAC__FILE_DECODER_ALREADY_INITIALIZED;
173
174 if(0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
175 return decoder->protected_->state = FLAC__FILE_DECODER_INVALID_CALLBACK;
176
177 if(0 == decoder->private_->filename)
178 decoder->private_->file = get_binary_stdin_();
179 else
180 decoder->private_->file = fopen(decoder->private_->filename, "rb");
181
182 if(decoder->private_->file == 0)
183 return decoder->protected_->state = FLAC__FILE_DECODER_ERROR_OPENING_FILE;
184
185 FLAC__seekable_stream_decoder_set_read_callback(decoder->private_->seekable_stream_decoder, read_callback_);
186 FLAC__seekable_stream_decoder_set_seek_callback(decoder->private_->seekable_stream_decoder, seek_callback_);
187 FLAC__seekable_stream_decoder_set_tell_callback(decoder->private_->seekable_stream_decoder, tell_callback_);
188 FLAC__seekable_stream_decoder_set_length_callback(decoder->private_->seekable_stream_decoder, length_callback_);
189 FLAC__seekable_stream_decoder_set_eof_callback(decoder->private_->seekable_stream_decoder, eof_callback_);
190 FLAC__seekable_stream_decoder_set_write_callback(decoder->private_->seekable_stream_decoder, write_callback_);
191 FLAC__seekable_stream_decoder_set_metadata_callback(decoder->private_->seekable_stream_decoder, metadata_callback_);
192 FLAC__seekable_stream_decoder_set_error_callback(decoder->private_->seekable_stream_decoder, error_callback_);
193 FLAC__seekable_stream_decoder_set_client_data(decoder->private_->seekable_stream_decoder, decoder);
194
195 if(FLAC__seekable_stream_decoder_init(decoder->private_->seekable_stream_decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK)
196 return decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
197
198 return decoder->protected_->state = FLAC__FILE_DECODER_OK;
199}
200
201FLAC_API FLAC__bool FLAC__file_decoder_finish(FLAC__FileDecoder *decoder)
202{
203 FLAC__ASSERT(0 != decoder);
204
205 if(decoder->protected_->state == FLAC__FILE_DECODER_UNINITIALIZED)
206 return true;
207
208 FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
209
210 if(0 != decoder->private_->file && decoder->private_->file != stdin) {
211 fclose(decoder->private_->file);
212 decoder->private_->file = 0;
213 }
214
215 if(0 != decoder->private_->filename) {
216 free(decoder->private_->filename);
217 decoder->private_->filename = 0;
218 }
219
220 set_defaults_(decoder);
221
222 decoder->protected_->state = FLAC__FILE_DECODER_UNINITIALIZED;
223
224 return FLAC__seekable_stream_decoder_finish(decoder->private_->seekable_stream_decoder);
225}
226
227FLAC_API FLAC__bool FLAC__file_decoder_set_md5_checking(FLAC__FileDecoder *decoder, FLAC__bool value)
228{
229 FLAC__ASSERT(0 != decoder);
230 FLAC__ASSERT(0 != decoder->private_);
231 FLAC__ASSERT(0 != decoder->protected_);
232 FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
233 if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
234 return false;
235 return FLAC__seekable_stream_decoder_set_md5_checking(decoder->private_->seekable_stream_decoder, value);
236}
237
238FLAC_API FLAC__bool FLAC__file_decoder_set_filename(FLAC__FileDecoder *decoder, const char *value)
239{
240 FLAC__ASSERT(0 != decoder);
241 FLAC__ASSERT(0 != decoder->private_);
242 FLAC__ASSERT(0 != decoder->protected_);
243 FLAC__ASSERT(0 != value);
244 if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
245 return false;
246 if(0 != decoder->private_->filename) {
247 free(decoder->private_->filename);
248 decoder->private_->filename = 0;
249 }
250 if(0 != strcmp(value, "-")) {
251 if(0 == (decoder->private_->filename = (char*)malloc(strlen(value)+1))) {
252 decoder->protected_->state = FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR;
253 return false;
254 }
255 strcpy(decoder->private_->filename, value);
256 }
257 return true;
258}
259
260FLAC_API FLAC__bool FLAC__file_decoder_set_write_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderWriteCallback 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_->write_callback = value;
268 return true;
269}
270
271FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderMetadataCallback 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_->metadata_callback = value;
279 return true;
280}
281
282FLAC_API FLAC__bool FLAC__file_decoder_set_error_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderErrorCallback 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_->error_callback = value;
290 return true;
291}
292
293FLAC_API FLAC__bool FLAC__file_decoder_set_client_data(FLAC__FileDecoder *decoder, void *value)
294{
295 FLAC__ASSERT(0 != decoder);
296 FLAC__ASSERT(0 != decoder->private_);
297 FLAC__ASSERT(0 != decoder->protected_);
298 if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
299 return false;
300 decoder->private_->client_data = value;
301 return true;
302}
303
304FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_respond(FLAC__FileDecoder *decoder, FLAC__MetadataType type)
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(decoder->private_->seekable_stream_decoder, type);
313}
314
315FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_respond_application(FLAC__FileDecoder *decoder, const FLAC__byte id[4])
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_application(decoder->private_->seekable_stream_decoder, id);
324}
325
326FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_respond_all(FLAC__FileDecoder *decoder)
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_respond_all(decoder->private_->seekable_stream_decoder);
335}
336
337FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_ignore(FLAC__FileDecoder *decoder, FLAC__MetadataType type)
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(decoder->private_->seekable_stream_decoder, type);
346}
347
348FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_ignore_application(FLAC__FileDecoder *decoder, const FLAC__byte id[4])
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_application(decoder->private_->seekable_stream_decoder, id);
357}
358
359FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_ignore_all(FLAC__FileDecoder *decoder)
360{
361 FLAC__ASSERT(0 != decoder);
362 FLAC__ASSERT(0 != decoder->private_);
363 FLAC__ASSERT(0 != decoder->protected_);
364 FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
365 if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
366 return false;
367 return FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder->private_->seekable_stream_decoder);
368}
369
370FLAC_API FLAC__FileDecoderState FLAC__file_decoder_get_state(const FLAC__FileDecoder *decoder)
371{
372 FLAC__ASSERT(0 != decoder);
373 FLAC__ASSERT(0 != decoder->protected_);
374 return decoder->protected_->state;
375}
376
377FLAC_API FLAC__SeekableStreamDecoderState FLAC__file_decoder_get_seekable_stream_decoder_state(const FLAC__FileDecoder *decoder)
378{
379 FLAC__ASSERT(0 != decoder);
380 FLAC__ASSERT(0 != decoder->private_);
381 return FLAC__seekable_stream_decoder_get_state(decoder->private_->seekable_stream_decoder);
382}
383
384FLAC_API FLAC__StreamDecoderState FLAC__file_decoder_get_stream_decoder_state(const FLAC__FileDecoder *decoder)
385{
386 FLAC__ASSERT(0 != decoder);
387 FLAC__ASSERT(0 != decoder->private_);
388 return FLAC__seekable_stream_decoder_get_stream_decoder_state(decoder->private_->seekable_stream_decoder);
389}
390
391FLAC_API const char *FLAC__file_decoder_get_resolved_state_string(const FLAC__FileDecoder *decoder)
392{
393 if(decoder->protected_->state != FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR)
394 return FLAC__FileDecoderStateString[decoder->protected_->state];
395 else
396 return FLAC__seekable_stream_decoder_get_resolved_state_string(decoder->private_->seekable_stream_decoder);
397}
398
399FLAC_API FLAC__bool FLAC__file_decoder_get_md5_checking(const FLAC__FileDecoder *decoder)
400{
401 FLAC__ASSERT(0 != decoder);
402 FLAC__ASSERT(0 != decoder->private_);
403 return FLAC__seekable_stream_decoder_get_md5_checking(decoder->private_->seekable_stream_decoder);
404}
405
406FLAC_API unsigned FLAC__file_decoder_get_channels(const FLAC__FileDecoder *decoder)
407{
408 FLAC__ASSERT(0 != decoder);
409 FLAC__ASSERT(0 != decoder->private_);
410 return FLAC__seekable_stream_decoder_get_channels(decoder->private_->seekable_stream_decoder);
411}
412
413FLAC_API FLAC__ChannelAssignment FLAC__file_decoder_get_channel_assignment(const FLAC__FileDecoder *decoder)
414{
415 FLAC__ASSERT(0 != decoder);
416 FLAC__ASSERT(0 != decoder->private_);
417 return FLAC__seekable_stream_decoder_get_channel_assignment(decoder->private_->seekable_stream_decoder);
418}
419
420FLAC_API unsigned FLAC__file_decoder_get_bits_per_sample(const FLAC__FileDecoder *decoder)
421{
422 FLAC__ASSERT(0 != decoder);
423 FLAC__ASSERT(0 != decoder->private_);
424 return FLAC__seekable_stream_decoder_get_bits_per_sample(decoder->private_->seekable_stream_decoder);
425}
426
427FLAC_API unsigned FLAC__file_decoder_get_sample_rate(const FLAC__FileDecoder *decoder)
428{
429 FLAC__ASSERT(0 != decoder);
430 FLAC__ASSERT(0 != decoder->private_);
431 return FLAC__seekable_stream_decoder_get_sample_rate(decoder->private_->seekable_stream_decoder);
432}
433
434FLAC_API unsigned FLAC__file_decoder_get_blocksize(const FLAC__FileDecoder *decoder)
435{
436 FLAC__ASSERT(0 != decoder);
437 FLAC__ASSERT(0 != decoder->private_);
438 return FLAC__seekable_stream_decoder_get_blocksize(decoder->private_->seekable_stream_decoder);
439}
440
441FLAC_API FLAC__bool FLAC__file_decoder_get_decode_position(const FLAC__FileDecoder *decoder, FLAC__uint64 *position)
442{
443 FLAC__ASSERT(0 != decoder);
444 FLAC__ASSERT(0 != decoder->private_);
445 return FLAC__seekable_stream_decoder_get_decode_position(decoder->private_->seekable_stream_decoder, position);
446}
447
448FLAC_API FLAC__bool FLAC__file_decoder_process_single(FLAC__FileDecoder *decoder)
449{
450 FLAC__bool ret;
451 FLAC__ASSERT(0 != decoder);
452
453 if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
454 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
455
456 if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
457 return true;
458
459 FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
460
461 ret = FLAC__seekable_stream_decoder_process_single(decoder->private_->seekable_stream_decoder);
462 if(!ret)
463 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
464
465 return ret;
466}
467
468FLAC_API FLAC__bool FLAC__file_decoder_process_until_end_of_metadata(FLAC__FileDecoder *decoder)
469{
470 FLAC__bool ret;
471 FLAC__ASSERT(0 != decoder);
472
473 if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
474 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
475
476 if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
477 return true;
478
479 FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
480
481 ret = FLAC__seekable_stream_decoder_process_until_end_of_metadata(decoder->private_->seekable_stream_decoder);
482 if(!ret)
483 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
484
485 return ret;
486}
487
488FLAC_API FLAC__bool FLAC__file_decoder_process_until_end_of_file(FLAC__FileDecoder *decoder)
489{
490 FLAC__bool ret;
491 FLAC__ASSERT(0 != decoder);
492
493 if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
494 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
495
496 if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
497 return true;
498
499 FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
500
501 ret = FLAC__seekable_stream_decoder_process_until_end_of_stream(decoder->private_->seekable_stream_decoder);
502 if(!ret)
503 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
504
505 return ret;
506}
507
508FLAC_API FLAC__bool FLAC__file_decoder_skip_single_frame(FLAC__FileDecoder *decoder)
509{
510 FLAC__bool ret;
511 FLAC__ASSERT(0 != decoder);
512
513 if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
514 decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
515
516 if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
517 return true;
518
519 FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
520
521 ret = FLAC__seekable_stream_decoder_skip_single_frame(decoder->private_->seekable_stream_decoder);
522 if(!ret)
523 decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
524
525 return ret;
526}
527
528FLAC_API FLAC__bool FLAC__file_decoder_seek_absolute(FLAC__FileDecoder *decoder, FLAC__uint64 sample)
529{
530 FLAC__ASSERT(0 != decoder);
531 FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK || decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE);
532
533 if(decoder->private_->filename == 0) { /* means the file is stdin... */
534 decoder->protected_->state = FLAC__FILE_DECODER_SEEK_ERROR;
535 return false;
536 }
537
538 if(!FLAC__seekable_stream_decoder_seek_absolute(decoder->private_->seekable_stream_decoder, sample)) {
539 decoder->protected_->state = FLAC__FILE_DECODER_SEEK_ERROR;
540 return false;
541 }
542 else {
543 decoder->protected_->state = FLAC__FILE_DECODER_OK;
544 return true;
545 }
546}
547
548
549/***********************************************************************
550 *
551 * Private class methods
552 *
553 ***********************************************************************/
554
555void set_defaults_(FLAC__FileDecoder *decoder)
556{
557 FLAC__ASSERT(0 != decoder);
558 FLAC__ASSERT(0 != decoder->private_);
559
560 decoder->private_->filename = 0;
561 decoder->private_->write_callback = 0;
562 decoder->private_->metadata_callback = 0;
563 decoder->private_->error_callback = 0;
564 decoder->private_->client_data = 0;
565}
566
567/*
568 * This will forcibly set stdin to binary mode (for OSes that require it)
569 */
570FILE *get_binary_stdin_()
571{
572 /* if something breaks here it is probably due to the presence or
573 * absence of an underscore before the identifiers 'setmode',
574 * 'fileno', and/or 'O_BINARY'; check your system header files.
575 */
576#if defined _MSC_VER || defined __MINGW32__
577 _setmode(_fileno(stdin), _O_BINARY);
578#elif defined __CYGWIN__
579 /* almost certainly not needed for any modern Cygwin, but let's be safe... */
580 setmode(_fileno(stdin), _O_BINARY);
581#endif
582
583 return stdin;
584}
585
586FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
587{
588 FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
589 (void)decoder;
590
591 if(*bytes > 0) {
592 *bytes = (unsigned)fread(buffer, sizeof(FLAC__byte), *bytes, file_decoder->private_->file);
593 if(ferror(file_decoder->private_->file)) {
594 return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
595 }
596 else {
597 return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
598 }
599 }
600 else
601 return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; /* abort to avoid a deadlock */
602}
603
604FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
605{
606 FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
607 (void)decoder;
608
609 if(fseek(file_decoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0)
610 return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
611 else
612 return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
613}
614
615FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
616{
617 FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
618 long pos;
619 (void)decoder;
620
621 if((pos = ftell(file_decoder->private_->file)) < 0)
622 return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
623 else {
624 *absolute_byte_offset = (FLAC__uint64)pos;
625 return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
626 }
627}
628
629FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
630{
631 FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
632 struct stat filestats;
633 (void)decoder;
634
635 if(0 == file_decoder->private_->filename || stat(file_decoder->private_->filename, &filestats) != 0)
636 return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
637 else {
638 *stream_length = (FLAC__uint64)filestats.st_size;
639 return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
640 }
641}
642
643FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data)
644{
645 FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
646 (void)decoder;
647
648 return feof(file_decoder->private_->file)? true : false;
649}
650
651FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
652{
653 FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
654 (void)decoder;
655
656 return file_decoder->private_->write_callback(file_decoder, frame, buffer, file_decoder->private_->client_data);
657}
658
659void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
660{
661 FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
662 (void)decoder;
663
664 file_decoder->private_->metadata_callback(file_decoder, metadata, file_decoder->private_->client_data);
665}
666
667void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
668{
669 FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
670 (void)decoder;
671
672 file_decoder->private_->error_callback(file_decoder, status, file_decoder->private_->client_data);
673}