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