bump version number to 1.1.3
[flac.git] / src / libFLAC / seekable_stream_decoder.c
1 /* libFLAC - Free Lossless Audio Codec library
2  * Copyright (C) 2000,2001,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 #if HAVE_CONFIG_H
33 #  include <config.h>
34 #endif
35
36 #include <stdio.h>
37 #include <stdlib.h> /* for calloc() */
38 #include <string.h> /* for memcpy()/memcmp() */
39 #include "FLAC/assert.h"
40 #include "protected/seekable_stream_decoder.h"
41 #include "protected/stream_decoder.h"
42 #include "private/float.h" /* for FLAC__double */
43 #include "private/md5.h"
44
45 /* adjust for compilers that can't understand using LLU suffix for uint64_t literals */
46 #ifdef _MSC_VER
47 #define FLAC__U64L(x) x
48 #else
49 #define FLAC__U64L(x) x##LLU
50 #endif
51
52 /***********************************************************************
53  *
54  * Private class method prototypes
55  *
56  ***********************************************************************/
57
58 static void set_defaults_(FLAC__SeekableStreamDecoder *decoder);
59 static FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
60 static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
61 static void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
62 static void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
63 static FLAC__bool seek_to_absolute_sample_(FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample);
64
65 /***********************************************************************
66  *
67  * Private class data
68  *
69  ***********************************************************************/
70
71 typedef struct FLAC__SeekableStreamDecoderPrivate {
72         FLAC__SeekableStreamDecoderReadCallback read_callback;
73         FLAC__SeekableStreamDecoderSeekCallback seek_callback;
74         FLAC__SeekableStreamDecoderTellCallback tell_callback;
75         FLAC__SeekableStreamDecoderLengthCallback length_callback;
76         FLAC__SeekableStreamDecoderEofCallback eof_callback;
77         FLAC__SeekableStreamDecoderWriteCallback write_callback;
78         FLAC__SeekableStreamDecoderMetadataCallback metadata_callback;
79         FLAC__SeekableStreamDecoderErrorCallback error_callback;
80         void *client_data;
81         FLAC__StreamDecoder *stream_decoder;
82         FLAC__bool do_md5_checking; /* initially gets protected_->md5_checking but is turned off after a seek or if the metadata has a zero MD5 */
83         struct FLAC__MD5Context md5context;
84         FLAC__byte computed_md5sum[16]; /* this is the sum we computed from the decoded data */
85         FLAC__StreamMetadata_StreamInfo stream_info; /* we keep this around for the md5sum comparison and also so we can figure out how to seek quickly */
86         FLAC__bool got_stream_info;
87         /* the rest of these are only used for seeking: */
88         const FLAC__StreamMetadata_SeekTable *seek_table; /* we hold a pointer to the stream decoder's seek table for the same reason */
89         /* Since we always want to see the STREAMINFO and SEEK_TABLE blocks at this level, we need some extra flags to keep track of whether they should be passed on up through the metadata_callback */
90         FLAC__bool ignore_stream_info_block;
91         FLAC__bool ignore_seek_table_block;
92         FLAC__Frame last_frame; /* holds the info of the last frame we seeked to */
93         FLAC__uint64 target_sample;
94         unsigned unparseable_frame_count; /* used to tell whether we're decoding a future version of FLAC or just got a bad sync */
95 } FLAC__SeekableStreamDecoderPrivate;
96
97 /***********************************************************************
98  *
99  * Public static class data
100  *
101  ***********************************************************************/
102
103 FLAC_API const char * const FLAC__SeekableStreamDecoderStateString[] = {
104         "FLAC__SEEKABLE_STREAM_DECODER_OK",
105         "FLAC__SEEKABLE_STREAM_DECODER_SEEKING",
106         "FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM",
107         "FLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR",
108         "FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR",
109         "FLAC__SEEKABLE_STREAM_DECODER_READ_ERROR",
110         "FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR",
111         "FLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED",
112         "FLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK",
113         "FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED"
114 };
115
116 FLAC_API const char * const FLAC__SeekableStreamDecoderReadStatusString[] = {
117         "FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK",
118         "FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR"
119 };
120
121 FLAC_API const char * const FLAC__SeekableStreamDecoderSeekStatusString[] = {
122         "FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK",
123         "FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR"
124 };
125
126 FLAC_API const char * const FLAC__SeekableStreamDecoderTellStatusString[] = {
127         "FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK",
128         "FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR"
129 };
130
131 FLAC_API const char * const FLAC__SeekableStreamDecoderLengthStatusString[] = {
132         "FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK",
133         "FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR"
134 };
135
136
137 /***********************************************************************
138  *
139  * Class constructor/destructor
140  *
141  ***********************************************************************/
142
143 FLAC_API FLAC__SeekableStreamDecoder *FLAC__seekable_stream_decoder_new()
144 {
145         FLAC__SeekableStreamDecoder *decoder;
146
147         FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
148
149         decoder = (FLAC__SeekableStreamDecoder*)calloc(1, sizeof(FLAC__SeekableStreamDecoder));
150         if(decoder == 0) {
151                 return 0;
152         }
153
154         decoder->protected_ = (FLAC__SeekableStreamDecoderProtected*)calloc(1, sizeof(FLAC__SeekableStreamDecoderProtected));
155         if(decoder->protected_ == 0) {
156                 free(decoder);
157                 return 0;
158         }
159
160         decoder->private_ = (FLAC__SeekableStreamDecoderPrivate*)calloc(1, sizeof(FLAC__SeekableStreamDecoderPrivate));
161         if(decoder->private_ == 0) {
162                 free(decoder->protected_);
163                 free(decoder);
164                 return 0;
165         }
166
167         decoder->private_->stream_decoder = FLAC__stream_decoder_new();
168         if(0 == decoder->private_->stream_decoder) {
169                 free(decoder->private_);
170                 free(decoder->protected_);
171                 free(decoder);
172                 return 0;
173         }
174
175         set_defaults_(decoder);
176
177         decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED;
178
179         return decoder;
180 }
181
182 FLAC_API void FLAC__seekable_stream_decoder_delete(FLAC__SeekableStreamDecoder *decoder)
183 {
184         FLAC__ASSERT(0 != decoder);
185         FLAC__ASSERT(0 != decoder->protected_);
186         FLAC__ASSERT(0 != decoder->private_);
187         FLAC__ASSERT(0 != decoder->private_->stream_decoder);
188
189         (void)FLAC__seekable_stream_decoder_finish(decoder);
190
191         FLAC__stream_decoder_delete(decoder->private_->stream_decoder);
192
193         free(decoder->private_);
194         free(decoder->protected_);
195         free(decoder);
196 }
197
198 /***********************************************************************
199  *
200  * Public class methods
201  *
202  ***********************************************************************/
203
204 FLAC_API FLAC__SeekableStreamDecoderState FLAC__seekable_stream_decoder_init(FLAC__SeekableStreamDecoder *decoder)
205 {
206         FLAC__ASSERT(0 != decoder);
207
208         if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
209                 return decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED;
210
211         if(0 == decoder->private_->read_callback || 0 == decoder->private_->seek_callback || 0 == decoder->private_->tell_callback || 0 == decoder->private_->length_callback || 0 == decoder->private_->eof_callback)
212                 return decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK;
213
214         if(0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
215                 return decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK;
216
217         decoder->private_->seek_table = 0;
218
219         decoder->private_->do_md5_checking = decoder->protected_->md5_checking;
220         decoder->private_->got_stream_info = false;
221         decoder->private_->unparseable_frame_count = 0;
222
223         /* We initialize the FLAC__MD5Context even though we may never use it.  This
224          * is because md5 checking may be turned on to start and then turned off if
225          * a seek occurs.  So we always init the context here and finalize it in
226          * FLAC__seekable_stream_decoder_finish() to make sure things are always
227          * cleaned up properly.
228          */
229         FLAC__MD5Init(&decoder->private_->md5context);
230
231         FLAC__stream_decoder_set_read_callback(decoder->private_->stream_decoder, read_callback_);
232         FLAC__stream_decoder_set_write_callback(decoder->private_->stream_decoder, write_callback_);
233         FLAC__stream_decoder_set_metadata_callback(decoder->private_->stream_decoder, metadata_callback_);
234         FLAC__stream_decoder_set_error_callback(decoder->private_->stream_decoder, error_callback_);
235         FLAC__stream_decoder_set_client_data(decoder->private_->stream_decoder, decoder);
236
237         /* We always want to see these blocks.  Whether or not we pass them up
238          * through the metadata callback will be determined by flags set in our
239          * implementation of ..._set_metadata_respond/ignore...()
240          */
241         FLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_STREAMINFO);
242         FLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_SEEKTABLE);
243
244         if(FLAC__stream_decoder_init(decoder->private_->stream_decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA)
245                 return decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
246
247         return decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_OK;
248 }
249
250 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_finish(FLAC__SeekableStreamDecoder *decoder)
251 {
252         FLAC__bool md5_failed = false;
253
254         FLAC__ASSERT(0 != decoder);
255         FLAC__ASSERT(0 != decoder->private_);
256         FLAC__ASSERT(0 != decoder->protected_);
257
258         if(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
259                 return true;
260
261         FLAC__ASSERT(0 != decoder->private_->stream_decoder);
262
263         /* see the comment in FLAC__seekable_stream_decoder_init() as to why we
264          * always call FLAC__MD5Final()
265          */
266         FLAC__MD5Final(decoder->private_->computed_md5sum, &decoder->private_->md5context);
267
268         FLAC__stream_decoder_finish(decoder->private_->stream_decoder);
269
270         if(decoder->private_->do_md5_checking) {
271                 if(memcmp(decoder->private_->stream_info.md5sum, decoder->private_->computed_md5sum, 16))
272                         md5_failed = true;
273         }
274
275         set_defaults_(decoder);
276
277         decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED;
278
279         return !md5_failed;
280 }
281
282 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_md5_checking(FLAC__SeekableStreamDecoder *decoder, FLAC__bool value)
283 {
284         FLAC__ASSERT(0 != decoder);
285         FLAC__ASSERT(0 != decoder->protected_);
286         if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
287                 return false;
288         decoder->protected_->md5_checking = value;
289         return true;
290 }
291
292 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_read_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderReadCallback value)
293 {
294         FLAC__ASSERT(0 != decoder);
295         FLAC__ASSERT(0 != decoder->private_);
296         FLAC__ASSERT(0 != decoder->protected_);
297         if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
298                 return false;
299         decoder->private_->read_callback = value;
300         return true;
301 }
302
303 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_seek_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderSeekCallback value)
304 {
305         FLAC__ASSERT(0 != decoder);
306         FLAC__ASSERT(0 != decoder->private_);
307         FLAC__ASSERT(0 != decoder->protected_);
308         if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
309                 return false;
310         decoder->private_->seek_callback = value;
311         return true;
312 }
313
314 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_tell_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderTellCallback value)
315 {
316         FLAC__ASSERT(0 != decoder);
317         FLAC__ASSERT(0 != decoder->private_);
318         FLAC__ASSERT(0 != decoder->protected_);
319         if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
320                 return false;
321         decoder->private_->tell_callback = value;
322         return true;
323 }
324
325 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_length_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderLengthCallback value)
326 {
327         FLAC__ASSERT(0 != decoder);
328         FLAC__ASSERT(0 != decoder->private_);
329         FLAC__ASSERT(0 != decoder->protected_);
330         if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
331                 return false;
332         decoder->private_->length_callback = value;
333         return true;
334 }
335
336 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_eof_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderEofCallback value)
337 {
338         FLAC__ASSERT(0 != decoder);
339         FLAC__ASSERT(0 != decoder->private_);
340         FLAC__ASSERT(0 != decoder->protected_);
341         if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
342                 return false;
343         decoder->private_->eof_callback = value;
344         return true;
345 }
346
347 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_write_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderWriteCallback value)
348 {
349         FLAC__ASSERT(0 != decoder);
350         FLAC__ASSERT(0 != decoder->private_);
351         FLAC__ASSERT(0 != decoder->protected_);
352         if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
353                 return false;
354         decoder->private_->write_callback = value;
355         return true;
356 }
357
358 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderMetadataCallback value)
359 {
360         FLAC__ASSERT(0 != decoder);
361         FLAC__ASSERT(0 != decoder->private_);
362         FLAC__ASSERT(0 != decoder->protected_);
363         if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
364                 return false;
365         decoder->private_->metadata_callback = value;
366         return true;
367 }
368
369 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_error_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderErrorCallback value)
370 {
371         FLAC__ASSERT(0 != decoder);
372         FLAC__ASSERT(0 != decoder->private_);
373         FLAC__ASSERT(0 != decoder->protected_);
374         if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
375                 return false;
376         decoder->private_->error_callback = value;
377         return true;
378 }
379
380 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_client_data(FLAC__SeekableStreamDecoder *decoder, void *value)
381 {
382         FLAC__ASSERT(0 != decoder);
383         FLAC__ASSERT(0 != decoder->private_);
384         FLAC__ASSERT(0 != decoder->protected_);
385         if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
386                 return false;
387         decoder->private_->client_data = value;
388         return true;
389 }
390
391 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_respond(FLAC__SeekableStreamDecoder *decoder, FLAC__MetadataType type)
392 {
393         FLAC__ASSERT(0 != decoder);
394         FLAC__ASSERT(0 != decoder->private_);
395         FLAC__ASSERT(0 != decoder->protected_);
396         FLAC__ASSERT(0 != decoder->private_->stream_decoder);
397         if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
398                 return false;
399         if(type == FLAC__METADATA_TYPE_STREAMINFO)
400                 decoder->private_->ignore_stream_info_block = false;
401         else if(type == FLAC__METADATA_TYPE_SEEKTABLE)
402                 decoder->private_->ignore_seek_table_block = false;
403         return FLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, type);
404 }
405
406 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_respond_application(FLAC__SeekableStreamDecoder *decoder, const FLAC__byte id[4])
407 {
408         FLAC__ASSERT(0 != decoder);
409         FLAC__ASSERT(0 != decoder->private_);
410         FLAC__ASSERT(0 != decoder->protected_);
411         FLAC__ASSERT(0 != decoder->private_->stream_decoder);
412         if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
413                 return false;
414         return FLAC__stream_decoder_set_metadata_respond_application(decoder->private_->stream_decoder, id);
415 }
416
417 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_respond_all(FLAC__SeekableStreamDecoder *decoder)
418 {
419         FLAC__ASSERT(0 != decoder);
420         FLAC__ASSERT(0 != decoder->private_);
421         FLAC__ASSERT(0 != decoder->protected_);
422         FLAC__ASSERT(0 != decoder->private_->stream_decoder);
423         if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
424                 return false;
425         decoder->private_->ignore_stream_info_block = false;
426         decoder->private_->ignore_seek_table_block = false;
427         return FLAC__stream_decoder_set_metadata_respond_all(decoder->private_->stream_decoder);
428 }
429
430 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_ignore(FLAC__SeekableStreamDecoder *decoder, FLAC__MetadataType type)
431 {
432         FLAC__ASSERT(0 != decoder);
433         FLAC__ASSERT(0 != decoder->private_);
434         FLAC__ASSERT(0 != decoder->protected_);
435         FLAC__ASSERT(0 != decoder->private_->stream_decoder);
436         if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
437                 return false;
438         if(type == FLAC__METADATA_TYPE_STREAMINFO) {
439                 decoder->private_->ignore_stream_info_block = true;
440                 return true;
441         }
442         else if(type == FLAC__METADATA_TYPE_SEEKTABLE) {
443                 decoder->private_->ignore_seek_table_block = true;
444                 return true;
445         }
446         else
447                 return FLAC__stream_decoder_set_metadata_ignore(decoder->private_->stream_decoder, type);
448 }
449
450 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_ignore_application(FLAC__SeekableStreamDecoder *decoder, const FLAC__byte id[4])
451 {
452         FLAC__ASSERT(0 != decoder);
453         FLAC__ASSERT(0 != decoder->private_);
454         FLAC__ASSERT(0 != decoder->protected_);
455         FLAC__ASSERT(0 != decoder->private_->stream_decoder);
456         if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
457                 return false;
458         return FLAC__stream_decoder_set_metadata_ignore_application(decoder->private_->stream_decoder, id);
459 }
460
461 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_ignore_all(FLAC__SeekableStreamDecoder *decoder)
462 {
463         FLAC__ASSERT(0 != decoder);
464         FLAC__ASSERT(0 != decoder->private_);
465         FLAC__ASSERT(0 != decoder->protected_);
466         FLAC__ASSERT(0 != decoder->private_->stream_decoder);
467         if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
468                 return false;
469         decoder->private_->ignore_stream_info_block = true;
470         decoder->private_->ignore_seek_table_block = true;
471         return
472                 FLAC__stream_decoder_set_metadata_ignore_all(decoder->private_->stream_decoder) &&
473                 FLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_STREAMINFO) &&
474                 FLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_SEEKTABLE);
475 }
476
477 FLAC_API FLAC__SeekableStreamDecoderState FLAC__seekable_stream_decoder_get_state(const FLAC__SeekableStreamDecoder *decoder)
478 {
479         FLAC__ASSERT(0 != decoder);
480         FLAC__ASSERT(0 != decoder->protected_);
481         return decoder->protected_->state;
482 }
483
484 FLAC_API FLAC__StreamDecoderState FLAC__seekable_stream_decoder_get_stream_decoder_state(const FLAC__SeekableStreamDecoder *decoder)
485 {
486         FLAC__ASSERT(0 != decoder);
487         FLAC__ASSERT(0 != decoder->private_);
488         return FLAC__stream_decoder_get_state(decoder->private_->stream_decoder);
489 }
490
491 FLAC_API const char *FLAC__seekable_stream_decoder_get_resolved_state_string(const FLAC__SeekableStreamDecoder *decoder)
492 {
493         if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR)
494                 return FLAC__SeekableStreamDecoderStateString[decoder->protected_->state];
495         else
496                 return FLAC__stream_decoder_get_resolved_state_string(decoder->private_->stream_decoder);
497 }
498
499 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_get_md5_checking(const FLAC__SeekableStreamDecoder *decoder)
500 {
501         FLAC__ASSERT(0 != decoder);
502         FLAC__ASSERT(0 != decoder->protected_);
503         return decoder->protected_->md5_checking;
504 }
505
506 FLAC_API unsigned FLAC__seekable_stream_decoder_get_channels(const FLAC__SeekableStreamDecoder *decoder)
507 {
508         FLAC__ASSERT(0 != decoder);
509         FLAC__ASSERT(0 != decoder->private_);
510         return FLAC__stream_decoder_get_channels(decoder->private_->stream_decoder);
511 }
512
513 FLAC_API FLAC__ChannelAssignment FLAC__seekable_stream_decoder_get_channel_assignment(const FLAC__SeekableStreamDecoder *decoder)
514 {
515         FLAC__ASSERT(0 != decoder);
516         FLAC__ASSERT(0 != decoder->private_);
517         return FLAC__stream_decoder_get_channel_assignment(decoder->private_->stream_decoder);
518 }
519
520 FLAC_API unsigned FLAC__seekable_stream_decoder_get_bits_per_sample(const FLAC__SeekableStreamDecoder *decoder)
521 {
522         FLAC__ASSERT(0 != decoder);
523         FLAC__ASSERT(0 != decoder->private_);
524         return FLAC__stream_decoder_get_bits_per_sample(decoder->private_->stream_decoder);
525 }
526
527 FLAC_API unsigned FLAC__seekable_stream_decoder_get_sample_rate(const FLAC__SeekableStreamDecoder *decoder)
528 {
529         FLAC__ASSERT(0 != decoder);
530         FLAC__ASSERT(0 != decoder->private_);
531         return FLAC__stream_decoder_get_sample_rate(decoder->private_->stream_decoder);
532 }
533
534 FLAC_API unsigned FLAC__seekable_stream_decoder_get_blocksize(const FLAC__SeekableStreamDecoder *decoder)
535 {
536         FLAC__ASSERT(0 != decoder);
537         FLAC__ASSERT(0 != decoder->private_);
538         return FLAC__stream_decoder_get_blocksize(decoder->private_->stream_decoder);
539 }
540
541 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_get_decode_position(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *position)
542 {
543         FLAC__ASSERT(0 != decoder);
544         FLAC__ASSERT(0 != decoder->private_);
545         FLAC__ASSERT(0 != position);
546
547         if(decoder->private_->tell_callback(decoder, position, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK)
548                 return false;
549         FLAC__ASSERT(*position >= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder->private_->stream_decoder));
550         *position -= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder->private_->stream_decoder);
551         return true;
552 }
553
554 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_flush(FLAC__SeekableStreamDecoder *decoder)
555 {
556         FLAC__ASSERT(0 != decoder);
557         FLAC__ASSERT(0 != decoder->private_);
558         FLAC__ASSERT(0 != decoder->protected_);
559
560         decoder->private_->do_md5_checking = false;
561
562         if(!FLAC__stream_decoder_flush(decoder->private_->stream_decoder)) {
563                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
564                 return false;
565         }
566
567         decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_OK;
568
569         return true;
570 }
571
572 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_reset(FLAC__SeekableStreamDecoder *decoder)
573 {
574         FLAC__ASSERT(0 != decoder);
575         FLAC__ASSERT(0 != decoder->private_);
576         FLAC__ASSERT(0 != decoder->protected_);
577
578         if(!FLAC__seekable_stream_decoder_flush(decoder)) {
579                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
580                 return false;
581         }
582
583         if(!FLAC__stream_decoder_reset(decoder->private_->stream_decoder)) {
584                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
585                 return false;
586         }
587
588         decoder->private_->seek_table = 0;
589
590         decoder->private_->do_md5_checking = decoder->protected_->md5_checking;
591
592         /* We initialize the FLAC__MD5Context even though we may never use it.  This
593          * is because md5 checking may be turned on to start and then turned off if
594          * a seek occurs.  So we always init the context here and finalize it in
595          * FLAC__seekable_stream_decoder_finish() to make sure things are always
596          * cleaned up properly.
597          */
598         FLAC__MD5Init(&decoder->private_->md5context);
599
600         decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_OK;
601
602         return true;
603 }
604
605 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_process_single(FLAC__SeekableStreamDecoder *decoder)
606 {
607         FLAC__bool ret;
608         FLAC__ASSERT(0 != decoder);
609
610         if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_END_OF_STREAM)
611                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
612
613         if(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
614                 return true;
615
616         FLAC__ASSERT(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_OK);
617
618         ret = FLAC__stream_decoder_process_single(decoder->private_->stream_decoder);
619         if(!ret)
620                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
621
622         return ret;
623 }
624
625 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_process_until_end_of_metadata(FLAC__SeekableStreamDecoder *decoder)
626 {
627         FLAC__bool ret;
628         FLAC__ASSERT(0 != decoder);
629
630         if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_END_OF_STREAM)
631                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
632
633         if(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
634                 return true;
635
636         FLAC__ASSERT(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_OK);
637
638         ret = FLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->stream_decoder);
639         if(!ret)
640                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
641
642         return ret;
643 }
644
645 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_process_until_end_of_stream(FLAC__SeekableStreamDecoder *decoder)
646 {
647         FLAC__bool ret;
648         FLAC__ASSERT(0 != decoder);
649
650         if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_END_OF_STREAM)
651                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
652
653         if(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
654                 return true;
655
656         FLAC__ASSERT(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_OK);
657
658         ret = FLAC__stream_decoder_process_until_end_of_stream(decoder->private_->stream_decoder);
659         if(!ret)
660                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
661
662         return ret;
663 }
664
665 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_skip_single_frame(FLAC__SeekableStreamDecoder *decoder)
666 {
667         FLAC__bool ret;
668         FLAC__ASSERT(0 != decoder);
669
670         if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_END_OF_STREAM)
671                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
672
673         if(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
674                 return true;
675
676         FLAC__ASSERT(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_OK);
677
678         ret = FLAC__stream_decoder_skip_single_frame(decoder->private_->stream_decoder);
679         if(!ret)
680                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
681
682         return ret;
683 }
684
685 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_seek_absolute(FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 sample)
686 {
687         FLAC__uint64 length;
688
689         FLAC__ASSERT(0 != decoder);
690         FLAC__ASSERT(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_OK || decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM);
691
692         decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEKING;
693
694         /* turn off md5 checking if a seek is attempted */
695         decoder->private_->do_md5_checking = false;
696
697         if(!FLAC__stream_decoder_reset(decoder->private_->stream_decoder)) {
698                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
699                 return false;
700         }
701         /* get the file length */
702         if(decoder->private_->length_callback(decoder, &length, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK) {
703                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
704                 return false;
705         }
706         /* rewind */
707         if(decoder->private_->seek_callback(decoder, 0, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK) {
708                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
709                 return false;
710         }
711         if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->stream_decoder)) {
712                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
713                 return false;
714         }
715         if(decoder->private_->stream_info.total_samples > 0 && sample >= decoder->private_->stream_info.total_samples) {
716                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
717                 return false;
718         }
719
720         return seek_to_absolute_sample_(decoder, length, sample);
721 }
722
723 /***********************************************************************
724  *
725  * Private class methods
726  *
727  ***********************************************************************/
728
729 void set_defaults_(FLAC__SeekableStreamDecoder *decoder)
730 {
731         decoder->private_->read_callback = 0;
732         decoder->private_->seek_callback = 0;
733         decoder->private_->tell_callback = 0;
734         decoder->private_->length_callback = 0;
735         decoder->private_->eof_callback = 0;
736         decoder->private_->write_callback = 0;
737         decoder->private_->metadata_callback = 0;
738         decoder->private_->error_callback = 0;
739         decoder->private_->client_data = 0;
740         /* WATCHOUT: these should match the default behavior of FLAC__StreamDecoder */
741         decoder->private_->ignore_stream_info_block = false;
742         decoder->private_->ignore_seek_table_block = true;
743
744         decoder->protected_->md5_checking = false;
745 }
746
747 FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
748 {
749         FLAC__SeekableStreamDecoder *seekable_stream_decoder = (FLAC__SeekableStreamDecoder *)client_data;
750         (void)decoder;
751         if(seekable_stream_decoder->private_->eof_callback(seekable_stream_decoder, seekable_stream_decoder->private_->client_data)) {
752                 *bytes = 0;
753 #if 0
754                 /*@@@@@@ verify that this is not needed */
755                 seekable_stream_decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
756 #endif
757                 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
758         }
759         else if(*bytes > 0) {
760                 /* While seeking, it is possible for our seek to land in the
761                  * middle of audio data that looks exactly like a frame header
762                  * from a future version of an encoder.  When that happens, our
763                  * error callback will get an
764                  * FLAC__STREAM_DECODER_UNPARSEABLE_STREAM and increment its
765                  * unparseable_frame_count.  But there is a remote possibility
766                  * that it is properly synced at such a "future-codec frame",
767                  * so to make sure, we wait to see many "unparseable" errors in
768                  * a row before bailing out.
769                  */
770                 if(seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_SEEKING && seekable_stream_decoder->private_->unparseable_frame_count > 20)
771                         return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
772                 if(seekable_stream_decoder->private_->read_callback(seekable_stream_decoder, buffer, bytes, seekable_stream_decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK) {
773                         seekable_stream_decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_READ_ERROR;
774                         return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
775                 }
776                 if(*bytes == 0) {
777                         if(seekable_stream_decoder->private_->eof_callback(seekable_stream_decoder, seekable_stream_decoder->private_->client_data)) {
778 #if 0
779                                 /*@@@@@@ verify that this is not needed */
780                                 seekable_stream_decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
781 #endif
782                                 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
783                         }
784                         else
785                                 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
786                 }
787                 else {
788                         return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
789                 }
790         }
791         else
792                 return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */
793 }
794
795 FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
796 {
797         FLAC__SeekableStreamDecoder *seekable_stream_decoder = (FLAC__SeekableStreamDecoder *)client_data;
798         (void)decoder;
799
800         if(seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_SEEKING) {
801                 FLAC__uint64 this_frame_sample = frame->header.number.sample_number;
802                 FLAC__uint64 next_frame_sample = this_frame_sample + (FLAC__uint64)frame->header.blocksize;
803                 FLAC__uint64 target_sample = seekable_stream_decoder->private_->target_sample;
804
805                 FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
806
807                 seekable_stream_decoder->private_->last_frame = *frame; /* save the frame */
808                 if(this_frame_sample <= target_sample && target_sample < next_frame_sample) { /* we hit our target frame */
809                         unsigned delta = (unsigned)(target_sample - this_frame_sample);
810                         /* kick out of seek mode */
811                         seekable_stream_decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_OK;
812                         /* shift out the samples before target_sample */
813                         if(delta > 0) {
814                                 unsigned channel;
815                                 const FLAC__int32 *newbuffer[FLAC__MAX_CHANNELS];
816                                 for(channel = 0; channel < frame->header.channels; channel++)
817                                         newbuffer[channel] = buffer[channel] + delta;
818                                 seekable_stream_decoder->private_->last_frame.header.blocksize -= delta;
819                                 seekable_stream_decoder->private_->last_frame.header.number.sample_number += (FLAC__uint64)delta;
820                                 /* write the relevant samples */
821                                 return seekable_stream_decoder->private_->write_callback(seekable_stream_decoder, &seekable_stream_decoder->private_->last_frame, newbuffer, seekable_stream_decoder->private_->client_data);
822                         }
823                         else {
824                                 /* write the relevant samples */
825                                 return seekable_stream_decoder->private_->write_callback(seekable_stream_decoder, frame, buffer, seekable_stream_decoder->private_->client_data);
826                         }
827                 }
828                 else {
829                         return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
830                 }
831         }
832         else {
833                 if(!seekable_stream_decoder->private_->got_stream_info)
834                         seekable_stream_decoder->private_->do_md5_checking = false;
835                 if(seekable_stream_decoder->private_->do_md5_checking) {
836                         if(!FLAC__MD5Accumulate(&seekable_stream_decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8))
837                                 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
838                 }
839                 return seekable_stream_decoder->private_->write_callback(seekable_stream_decoder, frame, buffer, seekable_stream_decoder->private_->client_data);
840         }
841 }
842
843 void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
844 {
845         FLAC__SeekableStreamDecoder *seekable_stream_decoder = (FLAC__SeekableStreamDecoder *)client_data;
846         (void)decoder;
847
848         if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
849                 seekable_stream_decoder->private_->stream_info = metadata->data.stream_info;
850                 seekable_stream_decoder->private_->got_stream_info = true;
851                 if(0 == memcmp(seekable_stream_decoder->private_->stream_info.md5sum, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16))
852                         seekable_stream_decoder->private_->do_md5_checking = false;
853         }
854         else if(metadata->type == FLAC__METADATA_TYPE_SEEKTABLE) {
855                 seekable_stream_decoder->private_->seek_table = &metadata->data.seek_table;
856         }
857
858         if(seekable_stream_decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING) {
859                 FLAC__bool ignore_block = false;
860                 if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO && seekable_stream_decoder->private_->ignore_stream_info_block)
861                         ignore_block = true;
862                 else if(metadata->type == FLAC__METADATA_TYPE_SEEKTABLE && seekable_stream_decoder->private_->ignore_seek_table_block)
863                         ignore_block = true;
864                 if(!ignore_block)
865                         seekable_stream_decoder->private_->metadata_callback(seekable_stream_decoder, metadata, seekable_stream_decoder->private_->client_data);
866         }
867 }
868
869 void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
870 {
871         FLAC__SeekableStreamDecoder *seekable_stream_decoder = (FLAC__SeekableStreamDecoder *)client_data;
872         (void)decoder;
873
874         if(seekable_stream_decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING)
875                 seekable_stream_decoder->private_->error_callback(seekable_stream_decoder, status, seekable_stream_decoder->private_->client_data);
876         else if(status == FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM)
877                 seekable_stream_decoder->private_->unparseable_frame_count++;
878 }
879
880 FLAC__bool seek_to_absolute_sample_(FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample)
881 {
882         FLAC__uint64 first_frame_offset, lower_bound, upper_bound;
883         FLAC__int64 pos = -1, last_pos = -1;
884         int i, lower_seek_point = -1, upper_seek_point = -1;
885         unsigned approx_bytes_per_frame;
886         FLAC__uint64 last_frame_sample = FLAC__U64L(0xffffffffffffffff);
887         FLAC__bool needs_seek;
888         const FLAC__uint64 total_samples = decoder->private_->stream_info.total_samples;
889         const unsigned min_blocksize = decoder->private_->stream_info.min_blocksize;
890         const unsigned max_blocksize = decoder->private_->stream_info.max_blocksize;
891         const unsigned max_framesize = decoder->private_->stream_info.max_framesize;
892         const unsigned channels = FLAC__seekable_stream_decoder_get_channels(decoder);
893         const unsigned bps = FLAC__seekable_stream_decoder_get_bits_per_sample(decoder);
894
895         /* we are just guessing here, but we want to guess high, not low */
896         if(max_framesize > 0) {
897                 approx_bytes_per_frame = max_framesize;
898         }
899         /*
900          * Check if it's a known fixed-blocksize stream.  Note that though
901          * the spec doesn't allow zeroes in the STREAMINFO block, we may
902          * never get a STREAMINFO block when decoding so the value of
903          * min_blocksize might be zero.
904          */
905         else if(min_blocksize == max_blocksize && min_blocksize > 0) {
906                 /* note there are no () around 'bps/8' to keep precision up since it's an integer calulation */
907                 approx_bytes_per_frame = min_blocksize * channels * bps/8 + 64;
908         }
909         else
910                 approx_bytes_per_frame = 4608 * channels * bps/8 + 64;
911
912         /*
913          * The decode position is currently at the first frame since we
914          * rewound and processed metadata.
915          */
916         if(!FLAC__seekable_stream_decoder_get_decode_position(decoder, &first_frame_offset)) {
917                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
918                 return false;
919         }
920
921         /*
922          * First, we set an upper and lower bound on where in the
923          * stream we will search.  For now we assume the worst case
924          * scenario, which is our best guess at the beginning of
925          * the first and last frames.
926          */
927         lower_bound = first_frame_offset;
928
929         /* calc the upper_bound, beyond which we never want to seek */
930         if(max_framesize > 0)
931                 upper_bound = stream_length - (max_framesize + 128 + 2); /* 128 for a possible ID3V1 tag, 2 for indexing differences */
932         else
933                 upper_bound = stream_length - ((channels * bps * FLAC__MAX_BLOCK_SIZE) / 8 + 128 + 2);
934
935         /*
936          * Now we refine the bounds if we have a seektable with
937          * suitable points.  Note that according to the spec they
938          * must be ordered by ascending sample number.
939          */
940         if(0 != decoder->private_->seek_table) {
941                 /* find the closest seek point <= target_sample, if it exists */
942                 for(i = (int)decoder->private_->seek_table->num_points - 1; i >= 0; i--) {
943                         if(decoder->private_->seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && decoder->private_->seek_table->points[i].sample_number <= target_sample)
944                                 break;
945                 }
946                 if(i >= 0) { /* i.e. we found a suitable seek point... */
947                         lower_bound = first_frame_offset + decoder->private_->seek_table->points[i].stream_offset;
948                         lower_seek_point = i;
949                 }
950
951                 /* find the closest seek point > target_sample, if it exists */
952                 for(i = 0; i < (int)decoder->private_->seek_table->num_points; i++) {
953                         if(decoder->private_->seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && decoder->private_->seek_table->points[i].sample_number > target_sample)
954                                 break;
955                 }
956                 if(i < (int)decoder->private_->seek_table->num_points) { /* i.e. we found a suitable seek point... */
957                         upper_bound = first_frame_offset + decoder->private_->seek_table->points[i].stream_offset;
958                         upper_seek_point = i;
959                 }
960         }
961
962         /*
963          * Now guess at where within those bounds our target
964          * sample will be.
965          */
966         if(lower_seek_point >= 0) {
967                 /* first see if our sample is within a few frames of the lower seekpoint */
968                 if(decoder->private_->seek_table->points[lower_seek_point].sample_number <= target_sample && target_sample < decoder->private_->seek_table->points[lower_seek_point].sample_number + (decoder->private_->seek_table->points[lower_seek_point].frame_samples * 4)) {
969                         pos = (FLAC__int64)lower_bound;
970                 }
971                 else if(upper_seek_point >= 0) {
972                         const FLAC__uint64 target_offset = target_sample - decoder->private_->seek_table->points[lower_seek_point].sample_number;
973                         const FLAC__uint64 range_samples = decoder->private_->seek_table->points[upper_seek_point].sample_number - decoder->private_->seek_table->points[lower_seek_point].sample_number;
974                         const FLAC__uint64 range_bytes = (upper_bound>lower_bound? upper_bound - lower_bound - 1 : 0);
975 #ifndef FLAC__INTEGER_ONLY_LIBRARY
976 #if defined _MSC_VER || defined __MINGW32__
977                         /* with MSVC you have to spoon feed it the casting */
978                         pos = (FLAC__int64)lower_bound + (FLAC__int64)(((FLAC__double)(FLAC__int64)target_offset / (FLAC__double)(FLAC__int64)range_samples) * (FLAC__double)(FLAC__int64)(range_bytes-1)) - approx_bytes_per_frame;
979 #else
980                         pos = (FLAC__int64)lower_bound + (FLAC__int64)(((FLAC__double)target_offset / (FLAC__double)range_samples) * (FLAC__double)range_bytes) - approx_bytes_per_frame;
981 #endif
982 #else
983                         /* a little less accurate: */
984                         if (range_bytes <= 0xffffffff)
985                                 pos = (FLAC__int64)lower_bound + (FLAC__int64)((target_offset * range_bytes) / range_samples) - approx_bytes_per_frame;
986                         else /* @@@ WATCHOUT, ~2TB limit */
987                                 pos = (FLAC__int64)lower_bound + (FLAC__int64)(((target_offset>>8) * (range_bytes>>8)) / (range_samples>>16)) - approx_bytes_per_frame;
988 #endif
989                 }
990         }
991
992         /*
993          * If there's no seek table, we need to use the metadata (if we
994          * have it) and the filelength to estimate the position of the
995          * frame with the correct sample.
996          */
997         if(pos < 0 && total_samples > 0) {
998                 /*
999                  * For max accuracy we should be using
1000                  * (stream_length-first_frame_offset-1) in the divisor, but the
1001                  * difference is trivial and (stream_length-first_frame_offset)
1002                  * has no chance of underflow.
1003                  */
1004 #ifndef FLAC__INTEGER_ONLY_LIBRARY
1005 #if defined _MSC_VER || defined __MINGW32__
1006                 /* with VC++ you have to spoon feed it the casting */
1007                 pos = (FLAC__int64)first_frame_offset + (FLAC__int64)(((FLAC__double)(FLAC__int64)target_sample / (FLAC__double)(FLAC__int64)total_samples) * (FLAC__double)(FLAC__int64)(stream_length-first_frame_offset)) - approx_bytes_per_frame;
1008 #else
1009                 pos = (FLAC__int64)first_frame_offset + (FLAC__int64)(((FLAC__double)target_sample / (FLAC__double)total_samples) * (FLAC__double)(stream_length-first_frame_offset)) - approx_bytes_per_frame;
1010 #endif
1011 #else
1012                 /* a little less accurate: */
1013                 if (stream_length < 0xffffffff)
1014                         pos = (FLAC__int64)first_frame_offset + (FLAC__int64)((target_sample * (stream_length-first_frame_offset)) / total_samples) - approx_bytes_per_frame;
1015                 else /* @@@ WATCHOUT, ~2TB limit */
1016                         pos = (FLAC__int64)first_frame_offset + (FLAC__int64)(((target_sample>>8) * ((stream_length-first_frame_offset)>>8)) / (total_samples>>16)) - approx_bytes_per_frame;
1017 #endif
1018         }
1019
1020         /*
1021          * If there's no seek table and total_samples is unknown, we
1022          * don't even bother trying to figure out a target, we just use
1023          * our current position.
1024          */
1025         if(pos < 0) {
1026                 FLAC__uint64 upos;
1027                 if(decoder->private_->tell_callback(decoder, &upos, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK) {
1028                         decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
1029                         return false;
1030                 }
1031                 pos = (FLAC__int64)upos;
1032                 needs_seek = false;
1033         }
1034         else
1035                 needs_seek = true;
1036
1037         /* clip the position to the bounds, lower bound takes precedence */
1038         if(pos >= (FLAC__int64)upper_bound) {
1039                 pos = (FLAC__int64)upper_bound-1;
1040                 needs_seek = true;
1041         }
1042         if(pos < (FLAC__int64)lower_bound) {
1043                 pos = (FLAC__int64)lower_bound;
1044                 needs_seek = true;
1045         }
1046
1047         decoder->private_->target_sample = target_sample;
1048         while(1) {
1049                 if(needs_seek) {
1050                         if(decoder->private_->seek_callback(decoder, (FLAC__uint64)pos, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK) {
1051                                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
1052                                 return false;
1053                         }
1054                         if(!FLAC__stream_decoder_flush(decoder->private_->stream_decoder)) {
1055                                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
1056                                 return false;
1057                         }
1058                 }
1059                 /* Now we need to get a frame.  First we need to reset our
1060                  * unparseable_frame_count; if we get too many unparseable
1061                  * frames in a row, the read callback will return
1062                  * FLAC__STREAM_DECODER_READ_STATUS_ABORT, causing
1063                  * FLAC__stream_decoder_process_single() to return false.
1064                  */
1065                 decoder->private_->unparseable_frame_count = 0;
1066                 if(!FLAC__stream_decoder_process_single(decoder->private_->stream_decoder)) {
1067                         decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
1068                         return false;
1069                 }
1070                 /* our write callback will change the state when it gets to the target frame */
1071                 /* actually, we could have got_a_frame if our decoder is at FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM so we need to check for that also */
1072                 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING && decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) {
1073                         break;
1074                 }
1075                 else { /* we need to narrow the search */
1076                         const FLAC__uint64 this_frame_sample = decoder->private_->last_frame.header.number.sample_number;
1077                         FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
1078                         if(this_frame_sample == last_frame_sample && pos < last_pos) {
1079                                 /* our last move backwards wasn't big enough, double it */
1080                                 pos -= (last_pos - pos);
1081                                 needs_seek = true;
1082                         }
1083                         else {
1084                                 if(target_sample < this_frame_sample) {
1085                                         last_pos = pos;
1086                                         approx_bytes_per_frame = decoder->private_->last_frame.header.blocksize * channels * bps/8 + 64;
1087                                         pos -= approx_bytes_per_frame;
1088                                         needs_seek = true;
1089                                 }
1090                                 else { /* target_sample >= this_frame_sample + this frame's blocksize */
1091                                         FLAC__uint64 upos;
1092                                         if(decoder->private_->tell_callback(decoder, &upos, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK) {
1093                                                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
1094                                                 return false;
1095                                         }
1096                                         last_pos = pos;
1097                                         pos = (FLAC__int64)upos;
1098                                         pos -= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder->private_->stream_decoder);
1099                                         needs_seek = false;
1100                                         /*
1101                                          * if we haven't hit the target frame yet and our position hasn't changed,
1102                                          * it means we're at the end of the stream and the seek target does not exist.
1103                                          */
1104                                         if(last_pos == pos) {
1105                                                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
1106                                                 return false;
1107                                         }
1108                                 }
1109                         }
1110                         if(pos < (FLAC__int64)lower_bound)
1111                                 pos = (FLAC__int64)lower_bound;
1112                         last_frame_sample = this_frame_sample;
1113                 }
1114         }
1115
1116         return true;
1117 }