add 2206 to copyright notice
[platform/upstream/flac.git] / src / libOggFLAC / stream_decoder.c
1 /* libOggFLAC - Free Lossless Audio Codec + Ogg library
2  * Copyright (C) 2002,2003,2004,2005,2006  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 }