2bba6afc7fc523d23b6b959db78890c1a2109909
[platform/upstream/flac.git] / src / libOggFLAC / stream_decoder.c
1 /* libOggFLAC - Free Lossless Audio Codec + Ogg library
2  * Copyright (C) 2002,2003  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_INVALID_CALLBACK",
78         "OggFLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR",
79         "OggFLAC__STREAM_DECODER_ALREADY_INITIALIZED",
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         if(!FLAC__stream_decoder_reset(decoder->private_->FLAC_stream_decoder)) {
406                 decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
407                 return false;
408         }
409
410         decoder->protected_->state = OggFLAC__STREAM_DECODER_OK;
411
412         return true;
413 }
414
415 OggFLAC_API FLAC__bool OggFLAC__stream_decoder_process_single(OggFLAC__StreamDecoder *decoder)
416 {
417         FLAC__bool ret;
418         FLAC__ASSERT(0 != decoder);
419
420         if(FLAC__stream_decoder_get_state(decoder->private_->FLAC_stream_decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
421                 decoder->protected_->state = OggFLAC__STREAM_DECODER_END_OF_STREAM;
422
423         if(decoder->protected_->state == OggFLAC__STREAM_DECODER_END_OF_STREAM)
424                 return true;
425
426         FLAC__ASSERT(decoder->protected_->state == OggFLAC__STREAM_DECODER_OK);
427
428         ret = FLAC__stream_decoder_process_single(decoder->private_->FLAC_stream_decoder);
429         if(!ret)
430                 decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
431
432         return ret;
433 }
434
435 OggFLAC_API FLAC__bool OggFLAC__stream_decoder_process_until_end_of_metadata(OggFLAC__StreamDecoder *decoder)
436 {
437         FLAC__bool ret;
438         FLAC__ASSERT(0 != decoder);
439
440         if(FLAC__stream_decoder_get_state(decoder->private_->FLAC_stream_decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
441                 decoder->protected_->state = OggFLAC__STREAM_DECODER_END_OF_STREAM;
442
443         if(decoder->protected_->state == OggFLAC__STREAM_DECODER_END_OF_STREAM)
444                 return true;
445
446         FLAC__ASSERT(decoder->protected_->state == OggFLAC__STREAM_DECODER_OK);
447
448         ret = FLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->FLAC_stream_decoder);
449         if(!ret)
450                 decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
451
452         return ret;
453 }
454
455 OggFLAC_API FLAC__bool OggFLAC__stream_decoder_process_until_end_of_stream(OggFLAC__StreamDecoder *decoder)
456 {
457         FLAC__bool ret;
458         FLAC__ASSERT(0 != decoder);
459
460         if(FLAC__stream_decoder_get_state(decoder->private_->FLAC_stream_decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
461                 decoder->protected_->state = OggFLAC__STREAM_DECODER_END_OF_STREAM;
462
463         if(decoder->protected_->state == OggFLAC__STREAM_DECODER_END_OF_STREAM)
464                 return true;
465
466         FLAC__ASSERT(decoder->protected_->state == OggFLAC__STREAM_DECODER_OK);
467
468         ret = FLAC__stream_decoder_process_until_end_of_stream(decoder->private_->FLAC_stream_decoder);
469         if(!ret)
470                 decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
471
472         return ret;
473 }
474
475
476 /***********************************************************************
477  *
478  * Private class methods
479  *
480  ***********************************************************************/
481
482 void set_defaults_(OggFLAC__StreamDecoder *decoder)
483 {
484         decoder->private_->read_callback = 0;
485         decoder->private_->write_callback = 0;
486         decoder->private_->metadata_callback = 0;
487         decoder->private_->error_callback = 0;
488         decoder->private_->client_data = 0;
489         OggFLAC__ogg_decoder_aspect_set_defaults(&decoder->protected_->ogg_decoder_aspect);
490 }
491
492 FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *unused, FLAC__byte buffer[], unsigned *bytes, void *client_data)
493 {
494         OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
495
496         (void)unused;
497
498         switch(OggFLAC__ogg_decoder_aspect_read_callback_wrapper(&decoder->protected_->ogg_decoder_aspect, buffer, bytes, read_callback_proxy_, decoder, decoder->private_->client_data)) {
499                 case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_OK:
500                         return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
501                 /* we don't really have a way to handle lost sync via read
502                  * callback so we'll let it pass and let the underlying
503                  * FLAC decoder catch the error
504                  */
505                 case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC:
506                         return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
507                 case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM:
508                         return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
509                 case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT:
510                 case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR:
511                         decoder->protected_->state = OggFLAC__STREAM_DECODER_READ_ERROR;
512                         return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
513                 case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_MEMORY_ALLOCATION_ERROR:
514                         decoder->protected_->state = OggFLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
515                         return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
516                 default:
517                         FLAC__ASSERT(0);
518                         /* double protection */
519                         return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
520         }
521 }
522
523 FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *unused, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
524 {
525         OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
526         (void)unused;
527         return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data);
528 }
529
530 void metadata_callback_(const FLAC__StreamDecoder *unused, const FLAC__StreamMetadata *metadata, void *client_data)
531 {
532         OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
533         (void)unused;
534         decoder->private_->metadata_callback(decoder, metadata, decoder->private_->client_data);
535 }
536
537 void error_callback_(const FLAC__StreamDecoder *unused, FLAC__StreamDecoderErrorStatus status, void *client_data)
538 {
539         OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
540         (void)unused;
541         decoder->private_->error_callback(decoder, status, decoder->private_->client_data);
542 }
543
544 OggFLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
545 {
546         OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)void_decoder;
547
548         switch(decoder->private_->read_callback(decoder, buffer, bytes, client_data)) {
549                 case FLAC__STREAM_DECODER_READ_STATUS_CONTINUE:
550                         return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_OK;
551                 case FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM:
552                         return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM;
553                 case FLAC__STREAM_DECODER_READ_STATUS_ABORT:
554                         return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT;
555                 default:
556                         /* double protection: */
557                         FLAC__ASSERT(0);
558                         return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT;
559         }
560 }