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

« back to all changes in this revision

Viewing changes to src/libOggFLAC/stream_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 <stdlib.h> /* for calloc() */
33
 
#include "FLAC/assert.h"
34
 
#include "protected/stream_decoder.h"
35
 
 
36
 
/***********************************************************************
37
 
 *
38
 
 * Private class method prototypes
39
 
 *
40
 
 ***********************************************************************/
41
 
 
42
 
static void set_defaults_(OggFLAC__StreamDecoder *decoder);
43
 
static FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
44
 
static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
45
 
static void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
46
 
static void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
47
 
static OggFLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
48
 
 
49
 
 
50
 
/***********************************************************************
51
 
 *
52
 
 * Private class data
53
 
 *
54
 
 ***********************************************************************/
55
 
 
56
 
typedef struct OggFLAC__StreamDecoderPrivate {
57
 
        OggFLAC__StreamDecoderReadCallback read_callback;
58
 
        OggFLAC__StreamDecoderWriteCallback write_callback;
59
 
        OggFLAC__StreamDecoderMetadataCallback metadata_callback;
60
 
        OggFLAC__StreamDecoderErrorCallback error_callback;
61
 
        void *client_data;
62
 
        FLAC__StreamDecoder *FLAC_stream_decoder;
63
 
} OggFLAC__StreamDecoderPrivate;
64
 
 
65
 
/***********************************************************************
66
 
 *
67
 
 * Public static class data
68
 
 *
69
 
 ***********************************************************************/
70
 
 
71
 
OggFLAC_API const char * const OggFLAC__StreamDecoderStateString[] = {
72
 
        "OggFLAC__STREAM_DECODER_OK",
73
 
        "OggFLAC__STREAM_DECODER_END_OF_STREAM",
74
 
        "OggFLAC__STREAM_DECODER_OGG_ERROR",
75
 
        "OggFLAC__STREAM_DECODER_READ_ERROR",
76
 
        "OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR",
77
 
        "OggFLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR",
78
 
        "OggFLAC__STREAM_DECODER_ALREADY_INITIALIZED",
79
 
        "OggFLAC__STREAM_DECODER_INVALID_CALLBACK",
80
 
        "OggFLAC__STREAM_DECODER_UNINITIALIZED"
81
 
};
82
 
 
83
 
 
84
 
/***********************************************************************
85
 
 *
86
 
 * Class constructor/destructor
87
 
 *
88
 
 ***********************************************************************/
89
 
OggFLAC_API OggFLAC__StreamDecoder *OggFLAC__stream_decoder_new()
90
 
{
91
 
        OggFLAC__StreamDecoder *decoder;
92
 
 
93
 
        decoder = (OggFLAC__StreamDecoder*)calloc(1, sizeof(OggFLAC__StreamDecoder));
94
 
        if(decoder == 0) {
95
 
                return 0;
96
 
        }
97
 
 
98
 
        decoder->protected_ = (OggFLAC__StreamDecoderProtected*)calloc(1, sizeof(OggFLAC__StreamDecoderProtected));
99
 
        if(decoder->protected_ == 0) {
100
 
                free(decoder);
101
 
                return 0;
102
 
        }
103
 
 
104
 
        decoder->private_ = (OggFLAC__StreamDecoderPrivate*)calloc(1, sizeof(OggFLAC__StreamDecoderPrivate));
105
 
        if(decoder->private_ == 0) {
106
 
                free(decoder->protected_);
107
 
                free(decoder);
108
 
                return 0;
109
 
        }
110
 
 
111
 
        decoder->private_->FLAC_stream_decoder = FLAC__stream_decoder_new();
112
 
        if(0 == decoder->private_->FLAC_stream_decoder) {
113
 
                free(decoder->private_);
114
 
                free(decoder->protected_);
115
 
                free(decoder);
116
 
                return 0;
117
 
        }
118
 
 
119
 
        set_defaults_(decoder);
120
 
 
121
 
        decoder->protected_->state = OggFLAC__STREAM_DECODER_UNINITIALIZED;
122
 
 
123
 
        return decoder;
124
 
}
125
 
 
126
 
OggFLAC_API void OggFLAC__stream_decoder_delete(OggFLAC__StreamDecoder *decoder)
127
 
{
128
 
        FLAC__ASSERT(0 != decoder);
129
 
        FLAC__ASSERT(0 != decoder->protected_);
130
 
        FLAC__ASSERT(0 != decoder->private_);
131
 
        FLAC__ASSERT(0 != decoder->private_->FLAC_stream_decoder);
132
 
 
133
 
        OggFLAC__stream_decoder_finish(decoder);
134
 
 
135
 
        FLAC__stream_decoder_delete(decoder->private_->FLAC_stream_decoder);
136
 
 
137
 
        free(decoder->private_);
138
 
        free(decoder->protected_);
139
 
        free(decoder);
140
 
}
141
 
 
142
 
/***********************************************************************
143
 
 *
144
 
 * Public class methods
145
 
 *
146
 
 ***********************************************************************/
147
 
 
148
 
OggFLAC_API OggFLAC__StreamDecoderState OggFLAC__stream_decoder_init(OggFLAC__StreamDecoder *decoder)
149
 
{
150
 
        FLAC__ASSERT(0 != decoder);
151
 
 
152
 
        if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
153
 
                return decoder->protected_->state = OggFLAC__STREAM_DECODER_ALREADY_INITIALIZED;
154
 
 
155
 
        if(0 == decoder->private_->read_callback || 0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
156
 
                return decoder->protected_->state = OggFLAC__STREAM_DECODER_INVALID_CALLBACK;
157
 
 
158
 
        if(!OggFLAC__ogg_decoder_aspect_init(&decoder->protected_->ogg_decoder_aspect))
159
 
                return decoder->protected_->state = OggFLAC__STREAM_DECODER_OGG_ERROR;
160
 
 
161
 
        FLAC__stream_decoder_set_read_callback(decoder->private_->FLAC_stream_decoder, read_callback_);
162
 
        FLAC__stream_decoder_set_write_callback(decoder->private_->FLAC_stream_decoder, write_callback_);
163
 
        FLAC__stream_decoder_set_metadata_callback(decoder->private_->FLAC_stream_decoder, metadata_callback_);
164
 
        FLAC__stream_decoder_set_error_callback(decoder->private_->FLAC_stream_decoder, error_callback_);
165
 
        FLAC__stream_decoder_set_client_data(decoder->private_->FLAC_stream_decoder, decoder);
166
 
 
167
 
        if(FLAC__stream_decoder_init(decoder->private_->FLAC_stream_decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA)
168
 
                return decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
169
 
 
170
 
        return decoder->protected_->state = OggFLAC__STREAM_DECODER_OK;
171
 
}
172
 
 
173
 
OggFLAC_API void OggFLAC__stream_decoder_finish(OggFLAC__StreamDecoder *decoder)
174
 
{
175
 
        FLAC__ASSERT(0 != decoder);
176
 
        FLAC__ASSERT(0 != decoder->private_);
177
 
        FLAC__ASSERT(0 != decoder->protected_);
178
 
 
179
 
        if(decoder->protected_->state == OggFLAC__STREAM_DECODER_UNINITIALIZED)
180
 
                return;
181
 
 
182
 
        FLAC__ASSERT(0 != decoder->private_->FLAC_stream_decoder);
183
 
 
184
 
        FLAC__stream_decoder_finish(decoder->private_->FLAC_stream_decoder);
185
 
 
186
 
        OggFLAC__ogg_decoder_aspect_finish(&decoder->protected_->ogg_decoder_aspect);
187
 
 
188
 
        set_defaults_(decoder);
189
 
 
190
 
        decoder->protected_->state = OggFLAC__STREAM_DECODER_UNINITIALIZED;
191
 
}
192
 
 
193
 
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_read_callback(OggFLAC__StreamDecoder *decoder, OggFLAC__StreamDecoderReadCallback value)
194
 
{
195
 
        FLAC__ASSERT(0 != decoder);
196
 
        FLAC__ASSERT(0 != decoder->private_);
197
 
        FLAC__ASSERT(0 != decoder->protected_);
198
 
        if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
199
 
                return false;
200
 
        decoder->private_->read_callback = value;
201
 
        return true;
202
 
}
203
 
 
204
 
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_write_callback(OggFLAC__StreamDecoder *decoder, OggFLAC__StreamDecoderWriteCallback value)
205
 
{
206
 
        FLAC__ASSERT(0 != decoder);
207
 
        FLAC__ASSERT(0 != decoder->private_);
208
 
        FLAC__ASSERT(0 != decoder->protected_);
209
 
        if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
210
 
                return false;
211
 
        decoder->private_->write_callback = value;
212
 
        return true;
213
 
}
214
 
 
215
 
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_metadata_callback(OggFLAC__StreamDecoder *decoder, OggFLAC__StreamDecoderMetadataCallback value)
216
 
{
217
 
        FLAC__ASSERT(0 != decoder);
218
 
        FLAC__ASSERT(0 != decoder->private_);
219
 
        FLAC__ASSERT(0 != decoder->protected_);
220
 
        if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
221
 
                return false;
222
 
        decoder->private_->metadata_callback = value;
223
 
        return true;
224
 
}
225
 
 
226
 
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_error_callback(OggFLAC__StreamDecoder *decoder, OggFLAC__StreamDecoderErrorCallback value)
227
 
{
228
 
        FLAC__ASSERT(0 != decoder);
229
 
        FLAC__ASSERT(0 != decoder->private_);
230
 
        FLAC__ASSERT(0 != decoder->protected_);
231
 
        if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
232
 
                return false;
233
 
        decoder->private_->error_callback = value;
234
 
        return true;
235
 
}
236
 
 
237
 
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_client_data(OggFLAC__StreamDecoder *decoder, void *value)
238
 
{
239
 
        FLAC__ASSERT(0 != decoder);
240
 
        FLAC__ASSERT(0 != decoder->private_);
241
 
        FLAC__ASSERT(0 != decoder->protected_);
242
 
        if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
243
 
                return false;
244
 
        decoder->private_->client_data = value;
245
 
        return true;
246
 
}
247
 
 
248
 
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_serial_number(OggFLAC__StreamDecoder *decoder, long value)
249
 
{
250
 
        FLAC__ASSERT(0 != decoder);
251
 
        FLAC__ASSERT(0 != decoder->private_);
252
 
        FLAC__ASSERT(0 != decoder->protected_);
253
 
        if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
254
 
                return false;
255
 
        OggFLAC__ogg_decoder_aspect_set_serial_number(&decoder->protected_->ogg_decoder_aspect, value);
256
 
        return true;
257
 
}
258
 
 
259
 
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_metadata_respond(OggFLAC__StreamDecoder *decoder, FLAC__MetadataType type)
260
 
{
261
 
        FLAC__ASSERT(0 != decoder);
262
 
        FLAC__ASSERT(0 != decoder->private_);
263
 
        FLAC__ASSERT(0 != decoder->protected_);
264
 
        if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
265
 
                return false;
266
 
        return FLAC__stream_decoder_set_metadata_respond(decoder->private_->FLAC_stream_decoder, type);
267
 
}
268
 
 
269
 
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_metadata_respond_application(OggFLAC__StreamDecoder *decoder, const FLAC__byte id[4])
270
 
{
271
 
        FLAC__ASSERT(0 != decoder);
272
 
        FLAC__ASSERT(0 != decoder->private_);
273
 
        FLAC__ASSERT(0 != decoder->protected_);
274
 
        if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
275
 
                return false;
276
 
        return FLAC__stream_decoder_set_metadata_respond_application(decoder->private_->FLAC_stream_decoder, id);
277
 
}
278
 
 
279
 
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_metadata_respond_all(OggFLAC__StreamDecoder *decoder)
280
 
{
281
 
        FLAC__ASSERT(0 != decoder);
282
 
        FLAC__ASSERT(0 != decoder->private_);
283
 
        FLAC__ASSERT(0 != decoder->protected_);
284
 
        if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
285
 
                return false;
286
 
        return FLAC__stream_decoder_set_metadata_respond_all(decoder->private_->FLAC_stream_decoder);
287
 
}
288
 
 
289
 
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_metadata_ignore(OggFLAC__StreamDecoder *decoder, FLAC__MetadataType type)
290
 
{
291
 
        FLAC__ASSERT(0 != decoder);
292
 
        FLAC__ASSERT(0 != decoder->private_);
293
 
        FLAC__ASSERT(0 != decoder->protected_);
294
 
        if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
295
 
                return false;
296
 
        return FLAC__stream_decoder_set_metadata_ignore(decoder->private_->FLAC_stream_decoder, type);
297
 
}
298
 
 
299
 
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_metadata_ignore_application(OggFLAC__StreamDecoder *decoder, const FLAC__byte id[4])
300
 
{
301
 
        FLAC__ASSERT(0 != decoder);
302
 
        FLAC__ASSERT(0 != decoder->private_);
303
 
        FLAC__ASSERT(0 != decoder->protected_);
304
 
        if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
305
 
                return false;
306
 
        return FLAC__stream_decoder_set_metadata_ignore_application(decoder->private_->FLAC_stream_decoder, id);
307
 
}
308
 
 
309
 
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_metadata_ignore_all(OggFLAC__StreamDecoder *decoder)
310
 
{
311
 
        FLAC__ASSERT(0 != decoder);
312
 
        FLAC__ASSERT(0 != decoder->private_);
313
 
        FLAC__ASSERT(0 != decoder->protected_);
314
 
        if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
315
 
                return false;
316
 
        return FLAC__stream_decoder_set_metadata_ignore_all(decoder->private_->FLAC_stream_decoder);
317
 
}
318
 
 
319
 
OggFLAC_API OggFLAC__StreamDecoderState OggFLAC__stream_decoder_get_state(const OggFLAC__StreamDecoder *decoder)
320
 
{
321
 
        FLAC__ASSERT(0 != decoder);
322
 
        FLAC__ASSERT(0 != decoder->protected_);
323
 
        return decoder->protected_->state;
324
 
}
325
 
 
326
 
OggFLAC_API FLAC__StreamDecoderState OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(const OggFLAC__StreamDecoder *decoder)
327
 
{
328
 
        FLAC__ASSERT(0 != decoder);
329
 
        FLAC__ASSERT(0 != decoder->private_);
330
 
        return FLAC__stream_decoder_get_state(decoder->private_->FLAC_stream_decoder);
331
 
}
332
 
 
333
 
OggFLAC_API const char *OggFLAC__stream_decoder_get_resolved_state_string(const OggFLAC__StreamDecoder *decoder)
334
 
{
335
 
        if(decoder->protected_->state != OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR)
336
 
                return OggFLAC__StreamDecoderStateString[decoder->protected_->state];
337
 
        else
338
 
                return FLAC__stream_decoder_get_resolved_state_string(decoder->private_->FLAC_stream_decoder);
339
 
}
340
 
 
341
 
OggFLAC_API unsigned OggFLAC__stream_decoder_get_channels(const OggFLAC__StreamDecoder *decoder)
342
 
{
343
 
        FLAC__ASSERT(0 != decoder);
344
 
        FLAC__ASSERT(0 != decoder->private_);
345
 
        return FLAC__stream_decoder_get_channels(decoder->private_->FLAC_stream_decoder);
346
 
}
347
 
 
348
 
OggFLAC_API FLAC__ChannelAssignment OggFLAC__stream_decoder_get_channel_assignment(const OggFLAC__StreamDecoder *decoder)
349
 
{
350
 
        FLAC__ASSERT(0 != decoder);
351
 
        FLAC__ASSERT(0 != decoder->private_);
352
 
        return FLAC__stream_decoder_get_channel_assignment(decoder->private_->FLAC_stream_decoder);
353
 
}
354
 
 
355
 
OggFLAC_API unsigned OggFLAC__stream_decoder_get_bits_per_sample(const OggFLAC__StreamDecoder *decoder)
356
 
{
357
 
        FLAC__ASSERT(0 != decoder);
358
 
        FLAC__ASSERT(0 != decoder->private_);
359
 
        return FLAC__stream_decoder_get_bits_per_sample(decoder->private_->FLAC_stream_decoder);
360
 
}
361
 
 
362
 
OggFLAC_API unsigned OggFLAC__stream_decoder_get_sample_rate(const OggFLAC__StreamDecoder *decoder)
363
 
{
364
 
        FLAC__ASSERT(0 != decoder);
365
 
        FLAC__ASSERT(0 != decoder->private_);
366
 
        return FLAC__stream_decoder_get_sample_rate(decoder->private_->FLAC_stream_decoder);
367
 
}
368
 
 
369
 
OggFLAC_API unsigned OggFLAC__stream_decoder_get_blocksize(const OggFLAC__StreamDecoder *decoder)
370
 
{
371
 
        FLAC__ASSERT(0 != decoder);
372
 
        FLAC__ASSERT(0 != decoder->private_);
373
 
        return FLAC__stream_decoder_get_blocksize(decoder->private_->FLAC_stream_decoder);
374
 
}
375
 
 
376
 
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_flush(OggFLAC__StreamDecoder *decoder)
377
 
{
378
 
        FLAC__ASSERT(0 != decoder);
379
 
        FLAC__ASSERT(0 != decoder->private_);
380
 
        FLAC__ASSERT(0 != decoder->protected_);
381
 
 
382
 
        OggFLAC__ogg_decoder_aspect_flush(&decoder->protected_->ogg_decoder_aspect);
383
 
 
384
 
        if(!FLAC__stream_decoder_flush(decoder->private_->FLAC_stream_decoder)) {
385
 
                decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
386
 
                return false;
387
 
        }
388
 
 
389
 
        decoder->protected_->state = OggFLAC__STREAM_DECODER_OK;
390
 
 
391
 
        return true;
392
 
}
393
 
 
394
 
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_reset(OggFLAC__StreamDecoder *decoder)
395
 
{
396
 
        FLAC__ASSERT(0 != decoder);
397
 
        FLAC__ASSERT(0 != decoder->private_);
398
 
        FLAC__ASSERT(0 != decoder->protected_);
399
 
 
400
 
        if(!OggFLAC__stream_decoder_flush(decoder)) {
401
 
                decoder->protected_->state = OggFLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
402
 
                return false;
403
 
        }
404
 
 
405
 
        OggFLAC__ogg_decoder_aspect_reset(&decoder->protected_->ogg_decoder_aspect);
406
 
 
407
 
        if(!FLAC__stream_decoder_reset(decoder->private_->FLAC_stream_decoder)) {
408
 
                decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
409
 
                return false;
410
 
        }
411
 
 
412
 
        decoder->protected_->state = OggFLAC__STREAM_DECODER_OK;
413
 
 
414
 
        return true;
415
 
}
416
 
 
417
 
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_process_single(OggFLAC__StreamDecoder *decoder)
418
 
{
419
 
        FLAC__bool ret;
420
 
        FLAC__ASSERT(0 != decoder);
421
 
 
422
 
        if(FLAC__stream_decoder_get_state(decoder->private_->FLAC_stream_decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
423
 
                decoder->protected_->state = OggFLAC__STREAM_DECODER_END_OF_STREAM;
424
 
 
425
 
        if(decoder->protected_->state == OggFLAC__STREAM_DECODER_END_OF_STREAM)
426
 
                return true;
427
 
 
428
 
        FLAC__ASSERT(decoder->protected_->state == OggFLAC__STREAM_DECODER_OK);
429
 
 
430
 
        ret = FLAC__stream_decoder_process_single(decoder->private_->FLAC_stream_decoder);
431
 
        if(!ret)
432
 
                decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
433
 
 
434
 
        return ret;
435
 
}
436
 
 
437
 
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_process_until_end_of_metadata(OggFLAC__StreamDecoder *decoder)
438
 
{
439
 
        FLAC__bool ret;
440
 
        FLAC__ASSERT(0 != decoder);
441
 
 
442
 
        if(FLAC__stream_decoder_get_state(decoder->private_->FLAC_stream_decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
443
 
                decoder->protected_->state = OggFLAC__STREAM_DECODER_END_OF_STREAM;
444
 
 
445
 
        if(decoder->protected_->state == OggFLAC__STREAM_DECODER_END_OF_STREAM)
446
 
                return true;
447
 
 
448
 
        FLAC__ASSERT(decoder->protected_->state == OggFLAC__STREAM_DECODER_OK);
449
 
 
450
 
        ret = FLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->FLAC_stream_decoder);
451
 
        if(!ret)
452
 
                decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
453
 
 
454
 
        return ret;
455
 
}
456
 
 
457
 
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_process_until_end_of_stream(OggFLAC__StreamDecoder *decoder)
458
 
{
459
 
        FLAC__bool ret;
460
 
        FLAC__ASSERT(0 != decoder);
461
 
 
462
 
        if(FLAC__stream_decoder_get_state(decoder->private_->FLAC_stream_decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
463
 
                decoder->protected_->state = OggFLAC__STREAM_DECODER_END_OF_STREAM;
464
 
 
465
 
        if(decoder->protected_->state == OggFLAC__STREAM_DECODER_END_OF_STREAM)
466
 
                return true;
467
 
 
468
 
        FLAC__ASSERT(decoder->protected_->state == OggFLAC__STREAM_DECODER_OK);
469
 
 
470
 
        ret = FLAC__stream_decoder_process_until_end_of_stream(decoder->private_->FLAC_stream_decoder);
471
 
        if(!ret)
472
 
                decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
473
 
 
474
 
        return ret;
475
 
}
476
 
 
477
 
 
478
 
/***********************************************************************
479
 
 *
480
 
 * Private class methods
481
 
 *
482
 
 ***********************************************************************/
483
 
 
484
 
void set_defaults_(OggFLAC__StreamDecoder *decoder)
485
 
{
486
 
        decoder->private_->read_callback = 0;
487
 
        decoder->private_->write_callback = 0;
488
 
        decoder->private_->metadata_callback = 0;
489
 
        decoder->private_->error_callback = 0;
490
 
        decoder->private_->client_data = 0;
491
 
        OggFLAC__ogg_decoder_aspect_set_defaults(&decoder->protected_->ogg_decoder_aspect);
492
 
}
493
 
 
494
 
FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *unused, FLAC__byte buffer[], unsigned *bytes, void *client_data)
495
 
{
496
 
        OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
497
 
 
498
 
        (void)unused;
499
 
 
500
 
        switch(OggFLAC__ogg_decoder_aspect_read_callback_wrapper(&decoder->protected_->ogg_decoder_aspect, buffer, bytes, read_callback_proxy_, decoder, decoder->private_->client_data)) {
501
 
                case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_OK:
502
 
                        return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
503
 
                /* we don't really have a way to handle lost sync via read
504
 
                 * callback so we'll let it pass and let the underlying
505
 
                 * FLAC decoder catch the error
506
 
                 */
507
 
                case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC:
508
 
                        return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
509
 
                case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM:
510
 
                        return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
511
 
                case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC:
512
 
                case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_UNSUPPORTED_MAPPING_VERSION:
513
 
                case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT:
514
 
                case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR:
515
 
                        decoder->protected_->state = OggFLAC__STREAM_DECODER_READ_ERROR;
516
 
                        return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
517
 
                case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_MEMORY_ALLOCATION_ERROR:
518
 
                        decoder->protected_->state = OggFLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
519
 
                        return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
520
 
                default:
521
 
                        FLAC__ASSERT(0);
522
 
                        /* double protection */
523
 
                        return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
524
 
        }
525
 
}
526
 
 
527
 
FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *unused, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
528
 
{
529
 
        OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
530
 
        (void)unused;
531
 
        return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data);
532
 
}
533
 
 
534
 
void metadata_callback_(const FLAC__StreamDecoder *unused, const FLAC__StreamMetadata *metadata, void *client_data)
535
 
{
536
 
        OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
537
 
        (void)unused;
538
 
        decoder->private_->metadata_callback(decoder, metadata, decoder->private_->client_data);
539
 
}
540
 
 
541
 
void error_callback_(const FLAC__StreamDecoder *unused, FLAC__StreamDecoderErrorStatus status, void *client_data)
542
 
{
543
 
        OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
544
 
        (void)unused;
545
 
        decoder->private_->error_callback(decoder, status, decoder->private_->client_data);
546
 
}
547
 
 
548
 
OggFLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
549
 
{
550
 
        OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)void_decoder;
551
 
 
552
 
        switch(decoder->private_->read_callback(decoder, buffer, bytes, client_data)) {
553
 
                case FLAC__STREAM_DECODER_READ_STATUS_CONTINUE:
554
 
                        return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_OK;
555
 
                case FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM:
556
 
                        return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM;
557
 
                case FLAC__STREAM_DECODER_READ_STATUS_ABORT:
558
 
                        return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT;
559
 
                default:
560
 
                        /* double protection: */
561
 
                        FLAC__ASSERT(0);
562
 
                        return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT;
563
 
        }
564
 
}