fixes based on Windows testing
[flac.git] / src / libOggFLAC / stream_decoder.c
1 /* libOggFLAC - Free Lossless Audio Codec + Ogg library
2  * Copyright (C) 2002  Josh Coalson
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA  02111-1307, USA.
18  */
19
20 #include <stdlib.h>
21 #include <string.h> /* for memset() */
22 #include "ogg/ogg.h"
23 #include "FLAC/assert.h"
24 #include "protected/stream_decoder.h"
25
26 #ifdef min
27 #undef min
28 #endif
29 #define min(x,y) ((x)<(y)?(x):(y))
30
31 /***********************************************************************
32  *
33  * Private class method prototypes
34  *
35  ***********************************************************************/
36
37 static void set_defaults_(OggFLAC__StreamDecoder *decoder);
38 static FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
39 static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
40 static void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
41 static void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
42
43
44 /***********************************************************************
45  *
46  * Private class data
47  *
48  ***********************************************************************/
49
50 typedef struct OggFLAC__StreamDecoderPrivate {
51         OggFLAC__StreamDecoderReadCallback read_callback;
52         OggFLAC__StreamDecoderWriteCallback write_callback;
53         OggFLAC__StreamDecoderMetadataCallback metadata_callback;
54         OggFLAC__StreamDecoderErrorCallback error_callback;
55         void *client_data;
56         FLAC__StreamDecoder *FLAC_stream_decoder;
57         struct {
58                 ogg_stream_state stream_state;
59                 ogg_sync_state sync_state;
60         } ogg;
61 } OggFLAC__StreamDecoderPrivate;
62
63 /***********************************************************************
64  *
65  * Public static class data
66  *
67  ***********************************************************************/
68
69 const char * const OggFLAC__StreamDecoderStateString[] = {
70         "OggFLAC__STREAM_DECODER_OK",
71         "OggFLAC__STREAM_DECODER_OGG_ERROR",
72         "OggFLAC__STREAM_DECODER_READ_ERROR",
73         "OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR",
74         "OggFLAC__STREAM_DECODER_INVALID_CALLBACK",
75         "OggFLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR",
76         "OggFLAC__STREAM_DECODER_ALREADY_INITIALIZED",
77         "OggFLAC__STREAM_DECODER_UNINITIALIZED"
78 };
79
80
81 /***********************************************************************
82  *
83  * Class constructor/destructor
84  *
85  ***********************************************************************/
86 OggFLAC__StreamDecoder *OggFLAC__stream_decoder_new()
87 {
88         OggFLAC__StreamDecoder *decoder;
89
90         decoder = (OggFLAC__StreamDecoder*)malloc(sizeof(OggFLAC__StreamDecoder));
91         if(decoder == 0) {
92                 return 0;
93         }
94         memset(decoder, 0, sizeof(OggFLAC__StreamDecoder));
95
96         decoder->protected_ = (OggFLAC__StreamDecoderProtected*)malloc(sizeof(OggFLAC__StreamDecoderProtected));
97         if(decoder->protected_ == 0) {
98                 free(decoder);
99                 return 0;
100         }
101         memset(decoder->protected_, 0, sizeof(OggFLAC__StreamDecoderProtected));
102
103         decoder->private_ = (OggFLAC__StreamDecoderPrivate*)malloc(sizeof(OggFLAC__StreamDecoderPrivate));
104         if(decoder->private_ == 0) {
105                 free(decoder->protected_);
106                 free(decoder);
107                 return 0;
108         }
109         memset(decoder->private_, 0, sizeof(OggFLAC__StreamDecoderPrivate));
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 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__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(ogg_stream_init(&decoder->private_->ogg.stream_state, 0) != 0)
159                 return decoder->protected_->state = OggFLAC__STREAM_DECODER_OGG_ERROR;
160
161         if(ogg_sync_init(&decoder->private_->ogg.sync_state) != 0)
162                 return decoder->protected_->state = OggFLAC__STREAM_DECODER_OGG_ERROR;
163
164     FLAC__stream_decoder_set_read_callback(decoder->private_->FLAC_stream_decoder, read_callback_);
165     FLAC__stream_decoder_set_write_callback(decoder->private_->FLAC_stream_decoder, write_callback_);
166     FLAC__stream_decoder_set_metadata_callback(decoder->private_->FLAC_stream_decoder, metadata_callback_);
167     FLAC__stream_decoder_set_error_callback(decoder->private_->FLAC_stream_decoder, error_callback_);
168     FLAC__stream_decoder_set_client_data(decoder->private_->FLAC_stream_decoder, decoder);
169
170     if(FLAC__stream_decoder_init(decoder->private_->FLAC_stream_decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA)
171         return decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
172
173         return decoder->protected_->state = OggFLAC__STREAM_DECODER_OK;
174 }
175
176 void OggFLAC__stream_decoder_finish(OggFLAC__StreamDecoder *decoder)
177 {
178         FLAC__ASSERT(0 != decoder);
179         FLAC__ASSERT(0 != decoder->private_);
180         FLAC__ASSERT(0 != decoder->protected_);
181
182         if(decoder->protected_->state == OggFLAC__STREAM_DECODER_UNINITIALIZED)
183                 return;
184
185         FLAC__ASSERT(0 != decoder->private_->FLAC_stream_decoder);
186
187         FLAC__stream_decoder_finish(decoder->private_->FLAC_stream_decoder);
188
189         (void)ogg_sync_clear(&decoder->private_->ogg.sync_state);
190         (void)ogg_stream_clear(&decoder->private_->ogg.stream_state);
191
192         set_defaults_(decoder);
193
194         decoder->protected_->state = OggFLAC__STREAM_DECODER_UNINITIALIZED;
195 }
196
197 FLAC__bool OggFLAC__stream_decoder_set_read_callback(OggFLAC__StreamDecoder *decoder, OggFLAC__StreamDecoderReadCallback value)
198 {
199         FLAC__ASSERT(0 != decoder);
200         FLAC__ASSERT(0 != decoder->private_);
201         FLAC__ASSERT(0 != decoder->protected_);
202         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
203                 return false;
204         decoder->private_->read_callback = value;
205         return true;
206 }
207
208 FLAC__bool OggFLAC__stream_decoder_set_write_callback(OggFLAC__StreamDecoder *decoder, OggFLAC__StreamDecoderWriteCallback value)
209 {
210         FLAC__ASSERT(0 != decoder);
211         FLAC__ASSERT(0 != decoder->private_);
212         FLAC__ASSERT(0 != decoder->protected_);
213         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
214                 return false;
215         decoder->private_->write_callback = value;
216         return true;
217 }
218
219 FLAC__bool OggFLAC__stream_decoder_set_metadata_callback(OggFLAC__StreamDecoder *decoder, OggFLAC__StreamDecoderMetadataCallback value)
220 {
221         FLAC__ASSERT(0 != decoder);
222         FLAC__ASSERT(0 != decoder->private_);
223         FLAC__ASSERT(0 != decoder->protected_);
224         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
225                 return false;
226         decoder->private_->metadata_callback = value;
227         return true;
228 }
229
230 FLAC__bool OggFLAC__stream_decoder_set_error_callback(OggFLAC__StreamDecoder *decoder, OggFLAC__StreamDecoderErrorCallback value)
231 {
232         FLAC__ASSERT(0 != decoder);
233         FLAC__ASSERT(0 != decoder->private_);
234         FLAC__ASSERT(0 != decoder->protected_);
235         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
236                 return false;
237         decoder->private_->error_callback = value;
238         return true;
239 }
240
241 FLAC__bool OggFLAC__stream_decoder_set_client_data(OggFLAC__StreamDecoder *decoder, void *value)
242 {
243         FLAC__ASSERT(0 != decoder);
244         FLAC__ASSERT(0 != decoder->private_);
245         FLAC__ASSERT(0 != decoder->protected_);
246         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
247                 return false;
248         decoder->private_->client_data = value;
249         return true;
250 }
251
252 FLAC__bool OggFLAC__stream_decoder_set_metadata_respond(OggFLAC__StreamDecoder *decoder, FLAC__MetadataType type)
253 {
254         FLAC__ASSERT(0 != decoder);
255         FLAC__ASSERT(0 != decoder->private_);
256         FLAC__ASSERT(0 != decoder->protected_);
257         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
258                 return false;
259         return FLAC__stream_decoder_set_metadata_respond(decoder->private_->FLAC_stream_decoder, type);
260 }
261
262 FLAC__bool OggFLAC__stream_decoder_set_metadata_respond_application(OggFLAC__StreamDecoder *decoder, const FLAC__byte id[4])
263 {
264         FLAC__ASSERT(0 != decoder);
265         FLAC__ASSERT(0 != decoder->private_);
266         FLAC__ASSERT(0 != decoder->protected_);
267         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
268                 return false;
269         return FLAC__stream_decoder_set_metadata_respond_application(decoder->private_->FLAC_stream_decoder, id);
270 }
271
272 FLAC__bool OggFLAC__stream_decoder_set_metadata_respond_all(OggFLAC__StreamDecoder *decoder)
273 {
274         FLAC__ASSERT(0 != decoder);
275         FLAC__ASSERT(0 != decoder->private_);
276         FLAC__ASSERT(0 != decoder->protected_);
277         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
278                 return false;
279         return FLAC__stream_decoder_set_metadata_respond_all(decoder->private_->FLAC_stream_decoder);
280 }
281
282 FLAC__bool OggFLAC__stream_decoder_set_metadata_ignore(OggFLAC__StreamDecoder *decoder, FLAC__MetadataType type)
283 {
284         FLAC__ASSERT(0 != decoder);
285         FLAC__ASSERT(0 != decoder->private_);
286         FLAC__ASSERT(0 != decoder->protected_);
287         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
288                 return false;
289         return FLAC__stream_decoder_set_metadata_ignore(decoder->private_->FLAC_stream_decoder, type);
290 }
291
292 FLAC__bool OggFLAC__stream_decoder_set_metadata_ignore_application(OggFLAC__StreamDecoder *decoder, const FLAC__byte id[4])
293 {
294         FLAC__ASSERT(0 != decoder);
295         FLAC__ASSERT(0 != decoder->private_);
296         FLAC__ASSERT(0 != decoder->protected_);
297         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
298                 return false;
299         return FLAC__stream_decoder_set_metadata_ignore_application(decoder->private_->FLAC_stream_decoder, id);
300 }
301
302 FLAC__bool OggFLAC__stream_decoder_set_metadata_ignore_all(OggFLAC__StreamDecoder *decoder)
303 {
304         FLAC__ASSERT(0 != decoder);
305         FLAC__ASSERT(0 != decoder->private_);
306         FLAC__ASSERT(0 != decoder->protected_);
307         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
308                 return false;
309         return FLAC__stream_decoder_set_metadata_ignore_all(decoder->private_->FLAC_stream_decoder);
310 }
311
312 OggFLAC__StreamDecoderState OggFLAC__stream_decoder_get_state(const OggFLAC__StreamDecoder *decoder)
313 {
314         FLAC__ASSERT(0 != decoder);
315         FLAC__ASSERT(0 != decoder->protected_);
316         return decoder->protected_->state;
317 }
318
319 FLAC__StreamDecoderState OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(const OggFLAC__StreamDecoder *decoder)
320 {
321         FLAC__ASSERT(0 != decoder);
322         FLAC__ASSERT(0 != decoder->private_);
323         return FLAC__stream_decoder_get_state(decoder->private_->FLAC_stream_decoder);
324 }
325
326 unsigned OggFLAC__stream_decoder_get_channels(const OggFLAC__StreamDecoder *decoder)
327 {
328         FLAC__ASSERT(0 != decoder);
329         FLAC__ASSERT(0 != decoder->private_);
330         return FLAC__stream_decoder_get_channels(decoder->private_->FLAC_stream_decoder);
331 }
332
333 FLAC__ChannelAssignment OggFLAC__stream_decoder_get_channel_assignment(const OggFLAC__StreamDecoder *decoder)
334 {
335         FLAC__ASSERT(0 != decoder);
336         FLAC__ASSERT(0 != decoder->private_);
337         return FLAC__stream_decoder_get_channel_assignment(decoder->private_->FLAC_stream_decoder);
338 }
339
340 unsigned OggFLAC__stream_decoder_get_bits_per_sample(const OggFLAC__StreamDecoder *decoder)
341 {
342         FLAC__ASSERT(0 != decoder);
343         FLAC__ASSERT(0 != decoder->private_);
344         return FLAC__stream_decoder_get_bits_per_sample(decoder->private_->FLAC_stream_decoder);
345 }
346
347 unsigned OggFLAC__stream_decoder_get_sample_rate(const OggFLAC__StreamDecoder *decoder)
348 {
349         FLAC__ASSERT(0 != decoder);
350         FLAC__ASSERT(0 != decoder->private_);
351         return FLAC__stream_decoder_get_sample_rate(decoder->private_->FLAC_stream_decoder);
352 }
353
354 unsigned OggFLAC__stream_decoder_get_blocksize(const OggFLAC__StreamDecoder *decoder)
355 {
356         FLAC__ASSERT(0 != decoder);
357         FLAC__ASSERT(0 != decoder->private_);
358         return FLAC__stream_decoder_get_blocksize(decoder->private_->FLAC_stream_decoder);
359 }
360
361 FLAC__bool OggFLAC__stream_decoder_flush(OggFLAC__StreamDecoder *decoder)
362 {
363         FLAC__ASSERT(0 != decoder);
364         FLAC__ASSERT(0 != decoder->private_);
365         FLAC__ASSERT(0 != decoder->protected_);
366
367         (void)ogg_sync_clear(&decoder->private_->ogg.sync_state);
368
369         if(!FLAC__stream_decoder_flush(decoder->private_->FLAC_stream_decoder)) {
370                 decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
371                 return false;
372         }
373
374         decoder->protected_->state = OggFLAC__STREAM_DECODER_OK;
375
376         return true;
377 }
378
379 FLAC__bool OggFLAC__stream_decoder_reset(OggFLAC__StreamDecoder *decoder)
380 {
381         FLAC__ASSERT(0 != decoder);
382         FLAC__ASSERT(0 != decoder->private_);
383         FLAC__ASSERT(0 != decoder->protected_);
384
385         if(!OggFLAC__stream_decoder_flush(decoder)) {
386                 decoder->protected_->state = OggFLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
387                 return false;
388         }
389
390         if(!FLAC__stream_decoder_reset(decoder->private_->FLAC_stream_decoder)) {
391                 decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
392                 return false;
393         }
394
395         decoder->protected_->state = OggFLAC__STREAM_DECODER_OK;
396
397         return true;
398 }
399
400 FLAC__bool OggFLAC__stream_decoder_process_single(OggFLAC__StreamDecoder *decoder)
401 {
402         FLAC__ASSERT(0 != decoder);
403         FLAC__ASSERT(0 != decoder->private_);
404         return FLAC__stream_decoder_process_single(decoder->private_->FLAC_stream_decoder);
405 }
406
407 FLAC__bool OggFLAC__stream_decoder_process_until_end_of_metadata(OggFLAC__StreamDecoder *decoder)
408 {
409         FLAC__ASSERT(0 != decoder);
410         FLAC__ASSERT(0 != decoder->private_);
411         return FLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->FLAC_stream_decoder);
412 }
413
414 FLAC__bool OggFLAC__stream_decoder_process_until_end_of_stream(OggFLAC__StreamDecoder *decoder)
415 {
416         FLAC__ASSERT(0 != decoder);
417         FLAC__ASSERT(0 != decoder->private_);
418         return FLAC__stream_decoder_process_until_end_of_stream(decoder->private_->FLAC_stream_decoder);
419 }
420
421
422 /***********************************************************************
423  *
424  * Private class methods
425  *
426  ***********************************************************************/
427
428 void set_defaults_(OggFLAC__StreamDecoder *decoder)
429 {
430         decoder->private_->read_callback = 0;
431         decoder->private_->write_callback = 0;
432         decoder->private_->metadata_callback = 0;
433         decoder->private_->error_callback = 0;
434         decoder->private_->client_data = 0;
435 }
436
437 FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *unused, FLAC__byte buffer[], unsigned *bytes, void *client_data)
438 {
439         static const unsigned OGG_BYTES_CHUNK = 8192;
440         OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
441         unsigned ogg_bytes_to_read, ogg_bytes_read;
442         ogg_page page;
443         char *oggbuf;
444
445         (void)unused;
446
447         /*
448          * We have to be careful not to read in more than the
449          * FLAC__StreamDecoder says it has room for.  We know
450          * that the size of the decoded data must be no more
451          * than the encoded data we will read.  
452          */
453         ogg_bytes_to_read = min(*bytes, OGG_BYTES_CHUNK);
454         oggbuf = ogg_sync_buffer(&decoder->private_->ogg.sync_state, ogg_bytes_to_read);
455
456         if(decoder->private_->read_callback(decoder, oggbuf, &ogg_bytes_to_read, decoder->private_->client_data) != FLAC__STREAM_DECODER_READ_STATUS_CONTINUE) {
457                 decoder->protected_->state = OggFLAC__STREAM_DECODER_READ_ERROR;
458                 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
459         }   
460         ogg_bytes_read = ogg_bytes_to_read;
461
462         if(ogg_sync_wrote(&decoder->private_->ogg.sync_state, ogg_bytes_read) < 0) {
463                 decoder->protected_->state = OggFLAC__STREAM_DECODER_READ_ERROR;
464                 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
465         }
466
467         *bytes = 0;
468         while(ogg_sync_pageout(&decoder->private_->ogg.sync_state, &page) == 1) {
469                 if(ogg_stream_pagein(&decoder->private_->ogg.stream_state, &page) == 0) {
470                         ogg_packet packet;
471
472                         while(ogg_stream_packetout(&decoder->private_->ogg.stream_state, &packet) == 1) {
473                                 memcpy(buffer, packet.packet, packet.bytes);
474                                 *bytes += packet.bytes;
475                                 buffer += packet.bytes;
476                         }
477                 } else {
478                         decoder->protected_->state = OggFLAC__STREAM_DECODER_READ_ERROR;
479                         return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
480                 }
481         }
482
483         return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
484 }
485
486 FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *unused, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
487 {
488         OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
489         (void)unused;
490         return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data);
491 }
492
493 void metadata_callback_(const FLAC__StreamDecoder *unused, const FLAC__StreamMetadata *metadata, void *client_data)
494 {
495         OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
496         (void)unused;
497         decoder->private_->metadata_callback(decoder, metadata, decoder->private_->client_data);
498 }
499
500 void error_callback_(const FLAC__StreamDecoder *unused, FLAC__StreamDecoderErrorStatus status, void *client_data)
501 {
502         OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
503         (void)unused;
504         decoder->private_->error_callback(decoder, status, decoder->private_->client_data);
505 }