~ubuntu-branches/ubuntu/raring/flac/raring

« back to all changes in this revision

Viewing changes to src/libOggFLAC/file_decoder.c

  • Committer: Bazaar Package Importer
  • Author(s): Joshua Kwan
  • Date: 2007-05-29 22:56:36 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070529225636-ljeff8xxip09qaap
Tags: 1.1.4-1
* New upstream release. closes: #405167, #411311
  - libOggFLAC and libOggFLAC++ have been merged into libFLAC, so
    remove their corresponding packages.
  - Because of the API changes required to effect the above, there has
    been yet another soname bump. libflac7 -> libflac8 and
    libflac++5 -> libflac++6. Emails have been dispatched to the
    maintainers of dependent packages.
* Some notes on patches that were removed:
  - 02_stdin_stdout, 06_manpage_mention_utf8_convert: merged upstream
  - 08_manpage_warnings: Upstream has changed the manpage so it defintely
    can't fit in in 80 cols, so just forget about it. We'll live.
  - 05_eof_warnings_are_errors: Upstream decided to add a -w option to
    flac to treat all warnings as errors. I am going to defer to that
    for now, but if people think it's stupid let me know and I'll port
    the patch forward.
  - 04_stack_smasher: was a backport from 1.1.3, so it's obsolete.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* libOggFLAC - Free Lossless Audio Codec + Ogg library
2
 
 * Copyright (C) 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_(OggFLAC__FileDecoder *decoder);
54
 
static FILE *get_binary_stdin_();
55
 
static OggFLAC__SeekableStreamDecoderReadStatus read_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
56
 
static OggFLAC__SeekableStreamDecoderSeekStatus seek_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
57
 
static OggFLAC__SeekableStreamDecoderTellStatus tell_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
58
 
static OggFLAC__SeekableStreamDecoderLengthStatus length_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
59
 
static FLAC__bool eof_callback_(const OggFLAC__SeekableStreamDecoder *decoder, void *client_data);
60
 
static FLAC__StreamDecoderWriteStatus write_callback_(const OggFLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
61
 
static void metadata_callback_(const OggFLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
62
 
static void error_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
63
 
 
64
 
/***********************************************************************
65
 
 *
66
 
 * Private class data
67
 
 *
68
 
 ***********************************************************************/
69
 
 
70
 
typedef struct OggFLAC__FileDecoderPrivate {
71
 
        OggFLAC__FileDecoderWriteCallback write_callback;
72
 
        OggFLAC__FileDecoderMetadataCallback metadata_callback;
73
 
        OggFLAC__FileDecoderErrorCallback error_callback;
74
 
        void *client_data;
75
 
        FILE *file;
76
 
        char *filename; /* == NULL if stdin */
77
 
        OggFLAC__SeekableStreamDecoder *seekable_stream_decoder;
78
 
} OggFLAC__FileDecoderPrivate;
79
 
 
80
 
/***********************************************************************
81
 
 *
82
 
 * Public static class data
83
 
 *
84
 
 ***********************************************************************/
85
 
 
86
 
OggFLAC_API const char * const OggFLAC__FileDecoderStateString[] = {
87
 
        "OggFLAC__FILE_DECODER_OK",
88
 
        "OggFLAC__FILE_DECODER_END_OF_FILE",
89
 
        "OggFLAC__FILE_DECODER_ERROR_OPENING_FILE",
90
 
        "OggFLAC__FILE_DECODER_SEEK_ERROR",
91
 
        "OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR",
92
 
        "OggFLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR",
93
 
        "OggFLAC__FILE_DECODER_ALREADY_INITIALIZED",
94
 
        "OggFLAC__FILE_DECODER_INVALID_CALLBACK",
95
 
        "OggFLAC__FILE_DECODER_UNINITIALIZED"
96
 
};
97
 
 
98
 
/***********************************************************************
99
 
 *
100
 
 * Class constructor/destructor
101
 
 *
102
 
 ***********************************************************************/
103
 
 
104
 
OggFLAC_API OggFLAC__FileDecoder *OggFLAC__file_decoder_new()
105
 
{
106
 
        OggFLAC__FileDecoder *decoder;
107
 
 
108
 
        FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
109
 
 
110
 
        decoder = (OggFLAC__FileDecoder*)calloc(1, sizeof(OggFLAC__FileDecoder));
111
 
        if(decoder == 0) {
112
 
                return 0;
113
 
        }
114
 
 
115
 
        decoder->protected_ = (OggFLAC__FileDecoderProtected*)calloc(1, sizeof(OggFLAC__FileDecoderProtected));
116
 
        if(decoder->protected_ == 0) {
117
 
                free(decoder);
118
 
                return 0;
119
 
        }
120
 
 
121
 
        decoder->private_ = (OggFLAC__FileDecoderPrivate*)calloc(1, sizeof(OggFLAC__FileDecoderPrivate));
122
 
        if(decoder->private_ == 0) {
123
 
                free(decoder->protected_);
124
 
                free(decoder);
125
 
                return 0;
126
 
        }
127
 
 
128
 
        decoder->private_->seekable_stream_decoder = OggFLAC__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 = OggFLAC__FILE_DECODER_UNINITIALIZED;
141
 
 
142
 
        return decoder;
143
 
}
144
 
 
145
 
OggFLAC_API void OggFLAC__file_decoder_delete(OggFLAC__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)OggFLAC__file_decoder_finish(decoder);
153
 
 
154
 
        OggFLAC__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
 
OggFLAC_API OggFLAC__FileDecoderState OggFLAC__file_decoder_init(OggFLAC__FileDecoder *decoder)
168
 
{
169
 
        FLAC__ASSERT(0 != decoder);
170
 
 
171
 
        if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
172
 
                return decoder->protected_->state = OggFLAC__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 = OggFLAC__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 = OggFLAC__FILE_DECODER_ERROR_OPENING_FILE;
184
 
 
185
 
        OggFLAC__seekable_stream_decoder_set_read_callback(decoder->private_->seekable_stream_decoder, read_callback_);
186
 
        OggFLAC__seekable_stream_decoder_set_seek_callback(decoder->private_->seekable_stream_decoder, seek_callback_);
187
 
        OggFLAC__seekable_stream_decoder_set_tell_callback(decoder->private_->seekable_stream_decoder, tell_callback_);
188
 
        OggFLAC__seekable_stream_decoder_set_length_callback(decoder->private_->seekable_stream_decoder, length_callback_);
189
 
        OggFLAC__seekable_stream_decoder_set_eof_callback(decoder->private_->seekable_stream_decoder, eof_callback_);
190
 
        OggFLAC__seekable_stream_decoder_set_write_callback(decoder->private_->seekable_stream_decoder, write_callback_);
191
 
        OggFLAC__seekable_stream_decoder_set_metadata_callback(decoder->private_->seekable_stream_decoder, metadata_callback_);
192
 
        OggFLAC__seekable_stream_decoder_set_error_callback(decoder->private_->seekable_stream_decoder, error_callback_);
193
 
        OggFLAC__seekable_stream_decoder_set_client_data(decoder->private_->seekable_stream_decoder, decoder);
194
 
 
195
 
        if(OggFLAC__seekable_stream_decoder_init(decoder->private_->seekable_stream_decoder) != OggFLAC__SEEKABLE_STREAM_DECODER_OK)
196
 
                return decoder->protected_->state = OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
197
 
 
198
 
        return decoder->protected_->state = OggFLAC__FILE_DECODER_OK;
199
 
}
200
 
 
201
 
OggFLAC_API FLAC__bool OggFLAC__file_decoder_finish(OggFLAC__FileDecoder *decoder)
202
 
{
203
 
        FLAC__ASSERT(0 != decoder);
204
 
 
205
 
        if(decoder->protected_->state == OggFLAC__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 = OggFLAC__FILE_DECODER_UNINITIALIZED;
223
 
 
224
 
        return OggFLAC__seekable_stream_decoder_finish(decoder->private_->seekable_stream_decoder);
225
 
}
226
 
 
227
 
OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_md5_checking(OggFLAC__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 != OggFLAC__FILE_DECODER_UNINITIALIZED)
234
 
                return false;
235
 
        return OggFLAC__seekable_stream_decoder_set_md5_checking(decoder->private_->seekable_stream_decoder, value);
236
 
}
237
 
 
238
 
OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_filename(OggFLAC__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 != OggFLAC__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 = OggFLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR;
253
 
                        return false;
254
 
                }
255
 
                strcpy(decoder->private_->filename, value);
256
 
        }
257
 
        return true;
258
 
}
259
 
 
260
 
OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_write_callback(OggFLAC__FileDecoder *decoder, OggFLAC__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 != OggFLAC__FILE_DECODER_UNINITIALIZED)
266
 
                return false;
267
 
        decoder->private_->write_callback = value;
268
 
        return true;
269
 
}
270
 
 
271
 
OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_metadata_callback(OggFLAC__FileDecoder *decoder, OggFLAC__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 != OggFLAC__FILE_DECODER_UNINITIALIZED)
277
 
                return false;
278
 
        decoder->private_->metadata_callback = value;
279
 
        return true;
280
 
}
281
 
 
282
 
OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_error_callback(OggFLAC__FileDecoder *decoder, OggFLAC__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 != OggFLAC__FILE_DECODER_UNINITIALIZED)
288
 
                return false;
289
 
        decoder->private_->error_callback = value;
290
 
        return true;
291
 
}
292
 
 
293
 
OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_client_data(OggFLAC__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 != OggFLAC__FILE_DECODER_UNINITIALIZED)
299
 
                return false;
300
 
        decoder->private_->client_data = value;
301
 
        return true;
302
 
}
303
 
 
304
 
OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_serial_number(OggFLAC__FileDecoder *decoder, long value)
305
 
{
306
 
        FLAC__ASSERT(0 != decoder);
307
 
        FLAC__ASSERT(0 != decoder->private_);
308
 
        FLAC__ASSERT(0 != decoder->protected_);
309
 
        if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
310
 
                return false;
311
 
        OggFLAC__seekable_stream_decoder_set_serial_number(decoder->private_->seekable_stream_decoder, value);
312
 
        return true;
313
 
}
314
 
 
315
 
OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_metadata_respond(OggFLAC__FileDecoder *decoder, FLAC__MetadataType type)
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 != OggFLAC__FILE_DECODER_UNINITIALIZED)
322
 
                return false;
323
 
        return OggFLAC__seekable_stream_decoder_set_metadata_respond(decoder->private_->seekable_stream_decoder, type);
324
 
}
325
 
 
326
 
OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_metadata_respond_application(OggFLAC__FileDecoder *decoder, const FLAC__byte id[4])
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 != OggFLAC__FILE_DECODER_UNINITIALIZED)
333
 
                return false;
334
 
        return OggFLAC__seekable_stream_decoder_set_metadata_respond_application(decoder->private_->seekable_stream_decoder, id);
335
 
}
336
 
 
337
 
OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_metadata_respond_all(OggFLAC__FileDecoder *decoder)
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 != OggFLAC__FILE_DECODER_UNINITIALIZED)
344
 
                return false;
345
 
        return OggFLAC__seekable_stream_decoder_set_metadata_respond_all(decoder->private_->seekable_stream_decoder);
346
 
}
347
 
 
348
 
OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_metadata_ignore(OggFLAC__FileDecoder *decoder, FLAC__MetadataType type)
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 != OggFLAC__FILE_DECODER_UNINITIALIZED)
355
 
                return false;
356
 
        return OggFLAC__seekable_stream_decoder_set_metadata_ignore(decoder->private_->seekable_stream_decoder, type);
357
 
}
358
 
 
359
 
OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_metadata_ignore_application(OggFLAC__FileDecoder *decoder, const FLAC__byte id[4])
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 != OggFLAC__FILE_DECODER_UNINITIALIZED)
366
 
                return false;
367
 
        return OggFLAC__seekable_stream_decoder_set_metadata_ignore_application(decoder->private_->seekable_stream_decoder, id);
368
 
}
369
 
 
370
 
OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_metadata_ignore_all(OggFLAC__FileDecoder *decoder)
371
 
{
372
 
        FLAC__ASSERT(0 != decoder);
373
 
        FLAC__ASSERT(0 != decoder->private_);
374
 
        FLAC__ASSERT(0 != decoder->protected_);
375
 
        FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
376
 
        if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
377
 
                return false;
378
 
        return OggFLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder->private_->seekable_stream_decoder);
379
 
}
380
 
 
381
 
OggFLAC_API OggFLAC__FileDecoderState OggFLAC__file_decoder_get_state(const OggFLAC__FileDecoder *decoder)
382
 
{
383
 
        FLAC__ASSERT(0 != decoder);
384
 
        FLAC__ASSERT(0 != decoder->protected_);
385
 
        return decoder->protected_->state;
386
 
}
387
 
 
388
 
OggFLAC_API OggFLAC__SeekableStreamDecoderState OggFLAC__file_decoder_get_seekable_stream_decoder_state(const OggFLAC__FileDecoder *decoder)
389
 
{
390
 
        FLAC__ASSERT(0 != decoder);
391
 
        FLAC__ASSERT(0 != decoder->private_);
392
 
        return OggFLAC__seekable_stream_decoder_get_state(decoder->private_->seekable_stream_decoder);
393
 
}
394
 
 
395
 
OggFLAC_API OggFLAC__StreamDecoderState OggFLAC__file_decoder_get_stream_decoder_state(const OggFLAC__FileDecoder *decoder)
396
 
{
397
 
        FLAC__ASSERT(0 != decoder);
398
 
        FLAC__ASSERT(0 != decoder->private_);
399
 
        return OggFLAC__seekable_stream_decoder_get_stream_decoder_state(decoder->private_->seekable_stream_decoder);
400
 
}
401
 
 
402
 
OggFLAC_API FLAC__StreamDecoderState OggFLAC__file_decoder_get_FLAC_stream_decoder_state(const OggFLAC__FileDecoder *decoder)
403
 
{
404
 
        FLAC__ASSERT(0 != decoder);
405
 
        FLAC__ASSERT(0 != decoder->private_);
406
 
        return OggFLAC__seekable_stream_decoder_get_FLAC_stream_decoder_state(decoder->private_->seekable_stream_decoder);
407
 
}
408
 
 
409
 
OggFLAC_API const char *OggFLAC__file_decoder_get_resolved_state_string(const OggFLAC__FileDecoder *decoder)
410
 
{
411
 
        if(decoder->protected_->state != OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR)
412
 
                return OggFLAC__FileDecoderStateString[decoder->protected_->state];
413
 
        else
414
 
                return OggFLAC__seekable_stream_decoder_get_resolved_state_string(decoder->private_->seekable_stream_decoder);
415
 
}
416
 
 
417
 
OggFLAC_API FLAC__bool OggFLAC__file_decoder_get_md5_checking(const OggFLAC__FileDecoder *decoder)
418
 
{
419
 
        FLAC__ASSERT(0 != decoder);
420
 
        FLAC__ASSERT(0 != decoder->private_);
421
 
        return OggFLAC__seekable_stream_decoder_get_md5_checking(decoder->private_->seekable_stream_decoder);
422
 
}
423
 
 
424
 
OggFLAC_API unsigned OggFLAC__file_decoder_get_channels(const OggFLAC__FileDecoder *decoder)
425
 
{
426
 
        FLAC__ASSERT(0 != decoder);
427
 
        FLAC__ASSERT(0 != decoder->private_);
428
 
        return OggFLAC__seekable_stream_decoder_get_channels(decoder->private_->seekable_stream_decoder);
429
 
}
430
 
 
431
 
OggFLAC_API FLAC__ChannelAssignment OggFLAC__file_decoder_get_channel_assignment(const OggFLAC__FileDecoder *decoder)
432
 
{
433
 
        FLAC__ASSERT(0 != decoder);
434
 
        FLAC__ASSERT(0 != decoder->private_);
435
 
        return OggFLAC__seekable_stream_decoder_get_channel_assignment(decoder->private_->seekable_stream_decoder);
436
 
}
437
 
 
438
 
OggFLAC_API unsigned OggFLAC__file_decoder_get_bits_per_sample(const OggFLAC__FileDecoder *decoder)
439
 
{
440
 
        FLAC__ASSERT(0 != decoder);
441
 
        FLAC__ASSERT(0 != decoder->private_);
442
 
        return OggFLAC__seekable_stream_decoder_get_bits_per_sample(decoder->private_->seekable_stream_decoder);
443
 
}
444
 
 
445
 
OggFLAC_API unsigned OggFLAC__file_decoder_get_sample_rate(const OggFLAC__FileDecoder *decoder)
446
 
{
447
 
        FLAC__ASSERT(0 != decoder);
448
 
        FLAC__ASSERT(0 != decoder->private_);
449
 
        return OggFLAC__seekable_stream_decoder_get_sample_rate(decoder->private_->seekable_stream_decoder);
450
 
}
451
 
 
452
 
OggFLAC_API unsigned OggFLAC__file_decoder_get_blocksize(const OggFLAC__FileDecoder *decoder)
453
 
{
454
 
        FLAC__ASSERT(0 != decoder);
455
 
        FLAC__ASSERT(0 != decoder->private_);
456
 
        return OggFLAC__seekable_stream_decoder_get_blocksize(decoder->private_->seekable_stream_decoder);
457
 
}
458
 
 
459
 
OggFLAC_API FLAC__bool OggFLAC__file_decoder_process_single(OggFLAC__FileDecoder *decoder)
460
 
{
461
 
        FLAC__bool ret;
462
 
        FLAC__ASSERT(0 != decoder);
463
 
 
464
 
        if(decoder->private_->seekable_stream_decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
465
 
                decoder->protected_->state = OggFLAC__FILE_DECODER_END_OF_FILE;
466
 
 
467
 
        if(decoder->protected_->state == OggFLAC__FILE_DECODER_END_OF_FILE)
468
 
                return true;
469
 
 
470
 
        FLAC__ASSERT(decoder->protected_->state == OggFLAC__FILE_DECODER_OK);
471
 
 
472
 
        ret = OggFLAC__seekable_stream_decoder_process_single(decoder->private_->seekable_stream_decoder);
473
 
        if(!ret)
474
 
                decoder->protected_->state = OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
475
 
 
476
 
        return ret;
477
 
}
478
 
 
479
 
OggFLAC_API FLAC__bool OggFLAC__file_decoder_process_until_end_of_metadata(OggFLAC__FileDecoder *decoder)
480
 
{
481
 
        FLAC__bool ret;
482
 
        FLAC__ASSERT(0 != decoder);
483
 
 
484
 
        if(decoder->private_->seekable_stream_decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
485
 
                decoder->protected_->state = OggFLAC__FILE_DECODER_END_OF_FILE;
486
 
 
487
 
        if(decoder->protected_->state == OggFLAC__FILE_DECODER_END_OF_FILE)
488
 
                return true;
489
 
 
490
 
        FLAC__ASSERT(decoder->protected_->state == OggFLAC__FILE_DECODER_OK);
491
 
 
492
 
        ret = OggFLAC__seekable_stream_decoder_process_until_end_of_metadata(decoder->private_->seekable_stream_decoder);
493
 
        if(!ret)
494
 
                decoder->protected_->state = OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
495
 
 
496
 
        return ret;
497
 
}
498
 
 
499
 
OggFLAC_API FLAC__bool OggFLAC__file_decoder_process_until_end_of_file(OggFLAC__FileDecoder *decoder)
500
 
{
501
 
        FLAC__bool ret;
502
 
        FLAC__ASSERT(0 != decoder);
503
 
 
504
 
        if(decoder->private_->seekable_stream_decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
505
 
                decoder->protected_->state = OggFLAC__FILE_DECODER_END_OF_FILE;
506
 
 
507
 
        if(decoder->protected_->state == OggFLAC__FILE_DECODER_END_OF_FILE)
508
 
                return true;
509
 
 
510
 
        FLAC__ASSERT(decoder->protected_->state == OggFLAC__FILE_DECODER_OK);
511
 
 
512
 
        ret = OggFLAC__seekable_stream_decoder_process_until_end_of_stream(decoder->private_->seekable_stream_decoder);
513
 
        if(!ret)
514
 
                decoder->protected_->state = OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
515
 
 
516
 
        return ret;
517
 
}
518
 
 
519
 
OggFLAC_API FLAC__bool OggFLAC__file_decoder_seek_absolute(OggFLAC__FileDecoder *decoder, FLAC__uint64 sample)
520
 
{
521
 
        FLAC__ASSERT(0 != decoder);
522
 
        FLAC__ASSERT(decoder->protected_->state == OggFLAC__FILE_DECODER_OK || decoder->protected_->state == OggFLAC__FILE_DECODER_END_OF_FILE);
523
 
 
524
 
        if(decoder->private_->filename == 0) { /* means the file is stdin... */
525
 
                decoder->protected_->state = OggFLAC__FILE_DECODER_SEEK_ERROR;
526
 
                return false;
527
 
        }
528
 
 
529
 
        if(!OggFLAC__seekable_stream_decoder_seek_absolute(decoder->private_->seekable_stream_decoder, sample)) {
530
 
                decoder->protected_->state = OggFLAC__FILE_DECODER_SEEK_ERROR;
531
 
                return false;
532
 
        }
533
 
        else {
534
 
                decoder->protected_->state = OggFLAC__FILE_DECODER_OK;
535
 
                return true;
536
 
        }
537
 
}
538
 
 
539
 
 
540
 
/***********************************************************************
541
 
 *
542
 
 * Private class methods
543
 
 *
544
 
 ***********************************************************************/
545
 
 
546
 
void set_defaults_(OggFLAC__FileDecoder *decoder)
547
 
{
548
 
        FLAC__ASSERT(0 != decoder);
549
 
        FLAC__ASSERT(0 != decoder->private_);
550
 
 
551
 
        decoder->private_->filename = 0;
552
 
        decoder->private_->write_callback = 0;
553
 
        decoder->private_->metadata_callback = 0;
554
 
        decoder->private_->error_callback = 0;
555
 
        decoder->private_->client_data = 0;
556
 
}
557
 
 
558
 
/*
559
 
 * This will forcibly set stdin to binary mode (for OSes that require it)
560
 
 */
561
 
FILE *get_binary_stdin_()
562
 
{
563
 
        /* if something breaks here it is probably due to the presence or
564
 
         * absence of an underscore before the identifiers 'setmode',
565
 
         * 'fileno', and/or 'O_BINARY'; check your system header files.
566
 
         */
567
 
#if defined _MSC_VER || defined __MINGW32__
568
 
        _setmode(_fileno(stdin), _O_BINARY);
569
 
#elif defined __CYGWIN__
570
 
        /* almost certainly not needed for any modern Cygwin, but let's be safe... */
571
 
        setmode(_fileno(stdin), _O_BINARY);
572
 
#endif
573
 
 
574
 
        return stdin;
575
 
}
576
 
 
577
 
OggFLAC__SeekableStreamDecoderReadStatus read_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
578
 
{
579
 
        OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
580
 
        (void)decoder;
581
 
 
582
 
        if(*bytes > 0) {
583
 
                *bytes = (unsigned)fread(buffer, sizeof(FLAC__byte), *bytes, file_decoder->private_->file);
584
 
                if(ferror(file_decoder->private_->file)) {
585
 
                        return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
586
 
                }
587
 
                else {
588
 
                        return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
589
 
                }
590
 
        }
591
 
        else
592
 
                return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; /* abort to avoid a deadlock */
593
 
}
594
 
 
595
 
OggFLAC__SeekableStreamDecoderSeekStatus seek_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
596
 
{
597
 
        OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
598
 
        (void)decoder;
599
 
 
600
 
        if(fseek(file_decoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0)
601
 
                return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
602
 
        else
603
 
                return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
604
 
}
605
 
 
606
 
OggFLAC__SeekableStreamDecoderTellStatus tell_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
607
 
{
608
 
        OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
609
 
        long pos;
610
 
        (void)decoder;
611
 
 
612
 
        if((pos = ftell(file_decoder->private_->file)) < 0)
613
 
                return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
614
 
        else {
615
 
                *absolute_byte_offset = (FLAC__uint64)pos;
616
 
                return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
617
 
        }
618
 
}
619
 
 
620
 
OggFLAC__SeekableStreamDecoderLengthStatus length_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
621
 
{
622
 
        OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
623
 
        struct stat filestats;
624
 
        (void)decoder;
625
 
 
626
 
        if(0 == file_decoder->private_->filename || stat(file_decoder->private_->filename, &filestats) != 0)
627
 
                return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
628
 
        else {
629
 
                *stream_length = (FLAC__uint64)filestats.st_size;
630
 
                return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
631
 
        }
632
 
}
633
 
 
634
 
FLAC__bool eof_callback_(const OggFLAC__SeekableStreamDecoder *decoder, void *client_data)
635
 
{
636
 
        OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
637
 
        (void)decoder;
638
 
 
639
 
        return feof(file_decoder->private_->file)? true : false;
640
 
}
641
 
 
642
 
FLAC__StreamDecoderWriteStatus write_callback_(const OggFLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
643
 
{
644
 
        OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
645
 
        (void)decoder;
646
 
 
647
 
        return file_decoder->private_->write_callback(file_decoder, frame, buffer, file_decoder->private_->client_data);
648
 
}
649
 
 
650
 
void metadata_callback_(const OggFLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
651
 
{
652
 
        OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
653
 
        (void)decoder;
654
 
 
655
 
        file_decoder->private_->metadata_callback(file_decoder, metadata, file_decoder->private_->client_data);
656
 
}
657
 
 
658
 
void error_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
659
 
{
660
 
        OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
661
 
        (void)decoder;
662
 
 
663
 
        file_decoder->private_->error_callback(file_decoder, status, file_decoder->private_->client_data);
664
 
}