diff options
author | Dave Chapman <dave@dchapman.com> | 2005-02-16 19:33:19 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2005-02-16 19:33:19 +0000 |
commit | aa97e4d4981d61808a558c5ab36be6d3bcc2c4f6 (patch) | |
tree | a66b2fcd87f37b26e2d4f360e6c2a9db53eb1b5b /apps/codecs/libFLAC/file_decoder.c | |
parent | 9b32a1988f848145d96ba2be8cba86e837196df3 (diff) | |
download | rockbox-aa97e4d4981d61808a558c5ab36be6d3bcc2c4f6.tar.gz rockbox-aa97e4d4981d61808a558c5ab36be6d3bcc2c4f6.zip |
Initial import of libFLAC from flac-1.1.2.tar.gz
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5983 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libFLAC/file_decoder.c')
-rw-r--r-- | apps/codecs/libFLAC/file_decoder.c | 673 |
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 | |||
53 | static void set_defaults_(FLAC__FileDecoder *decoder); | ||
54 | static FILE *get_binary_stdin_(); | ||
55 | static FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data); | ||
56 | static FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data); | ||
57 | static FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data); | ||
58 | static FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data); | ||
59 | static FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data); | ||
60 | static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); | ||
61 | static void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); | ||
62 | static void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); | ||
63 | |||
64 | /*********************************************************************** | ||
65 | * | ||
66 | * Private class data | ||
67 | * | ||
68 | ***********************************************************************/ | ||
69 | |||
70 | typedef 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 | |||
86 | FLAC_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 | |||
104 | FLAC_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 | |||
145 | FLAC_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 | |||
167 | FLAC_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 | |||
201 | FLAC_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 | |||
227 | FLAC_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 | |||
238 | FLAC_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 | |||
260 | FLAC_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 | |||
271 | FLAC_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 | |||
282 | FLAC_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 | |||
293 | FLAC_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 | |||
304 | FLAC_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 | |||
315 | FLAC_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 | |||
326 | FLAC_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 | |||
337 | FLAC_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 | |||
348 | FLAC_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 | |||
359 | FLAC_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 | |||
370 | FLAC_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 | |||
377 | FLAC_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 | |||
384 | FLAC_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 | |||
391 | FLAC_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 | |||
399 | FLAC_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 | |||
406 | FLAC_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 | |||
413 | FLAC_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 | |||
420 | FLAC_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 | |||
427 | FLAC_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 | |||
434 | FLAC_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 | |||
441 | FLAC_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 | |||
448 | FLAC_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 | |||
468 | FLAC_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 | |||
488 | FLAC_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 | |||
508 | FLAC_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 | |||
528 | FLAC_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 | |||
555 | void 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 | */ | ||
570 | FILE *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 | |||
586 | FLAC__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 | |||
604 | FLAC__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 | |||
615 | FLAC__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 | |||
629 | FLAC__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 | |||
643 | FLAC__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 | |||
651 | FLAC__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 | |||
659 | void 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 | |||
667 | void 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 | } | ||