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