94b6f58b5e0725adea9a8623858df3113899673e
[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         else if(type == FLAC__METADATA_TYPE_SEEKTABLE)
426                 decoder->private_->ignore_seek_table_block = true;
427         return FLAC__stream_decoder_set_metadata_ignore(decoder->private_->stream_decoder, type);
428 }
429
430 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_ignore_application(FLAC__SeekableStreamDecoder *decoder, const FLAC__byte id[4])
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         return FLAC__stream_decoder_set_metadata_ignore_application(decoder->private_->stream_decoder, id);
439 }
440
441 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_ignore_all(FLAC__SeekableStreamDecoder *decoder)
442 {
443         FLAC__ASSERT(0 != decoder);
444         FLAC__ASSERT(0 != decoder->private_);
445         FLAC__ASSERT(0 != decoder->protected_);
446         FLAC__ASSERT(0 != decoder->private_->stream_decoder);
447         if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
448                 return false;
449         decoder->private_->ignore_stream_info_block = true;
450         decoder->private_->ignore_seek_table_block = true;
451         return FLAC__stream_decoder_set_metadata_ignore_all(decoder->private_->stream_decoder);
452 }
453
454 FLAC_API FLAC__SeekableStreamDecoderState FLAC__seekable_stream_decoder_get_state(const FLAC__SeekableStreamDecoder *decoder)
455 {
456         FLAC__ASSERT(0 != decoder);
457         FLAC__ASSERT(0 != decoder->protected_);
458         return decoder->protected_->state;
459 }
460
461 FLAC_API FLAC__StreamDecoderState FLAC__seekable_stream_decoder_get_stream_decoder_state(const FLAC__SeekableStreamDecoder *decoder)
462 {
463         FLAC__ASSERT(0 != decoder);
464         FLAC__ASSERT(0 != decoder->private_);
465         return FLAC__stream_decoder_get_state(decoder->private_->stream_decoder);
466 }
467
468 FLAC_API const char *FLAC__seekable_stream_decoder_get_resolved_state_string(const FLAC__SeekableStreamDecoder *decoder)
469 {
470         if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR)
471                 return FLAC__SeekableStreamDecoderStateString[decoder->protected_->state];
472         else
473                 return FLAC__stream_decoder_get_resolved_state_string(decoder->private_->stream_decoder);
474 }
475
476 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_get_md5_checking(const FLAC__SeekableStreamDecoder *decoder)
477 {
478         FLAC__ASSERT(0 != decoder);
479         FLAC__ASSERT(0 != decoder->protected_);
480         return decoder->protected_->md5_checking;
481 }
482
483 FLAC_API unsigned FLAC__seekable_stream_decoder_get_channels(const FLAC__SeekableStreamDecoder *decoder)
484 {
485         FLAC__ASSERT(0 != decoder);
486         FLAC__ASSERT(0 != decoder->private_);
487         return FLAC__stream_decoder_get_channels(decoder->private_->stream_decoder);
488 }
489
490 FLAC_API FLAC__ChannelAssignment FLAC__seekable_stream_decoder_get_channel_assignment(const FLAC__SeekableStreamDecoder *decoder)
491 {
492         FLAC__ASSERT(0 != decoder);
493         FLAC__ASSERT(0 != decoder->private_);
494         return FLAC__stream_decoder_get_channel_assignment(decoder->private_->stream_decoder);
495 }
496
497 FLAC_API unsigned FLAC__seekable_stream_decoder_get_bits_per_sample(const FLAC__SeekableStreamDecoder *decoder)
498 {
499         FLAC__ASSERT(0 != decoder);
500         FLAC__ASSERT(0 != decoder->private_);
501         return FLAC__stream_decoder_get_bits_per_sample(decoder->private_->stream_decoder);
502 }
503
504 FLAC_API unsigned FLAC__seekable_stream_decoder_get_sample_rate(const FLAC__SeekableStreamDecoder *decoder)
505 {
506         FLAC__ASSERT(0 != decoder);
507         FLAC__ASSERT(0 != decoder->private_);
508         return FLAC__stream_decoder_get_sample_rate(decoder->private_->stream_decoder);
509 }
510
511 FLAC_API unsigned FLAC__seekable_stream_decoder_get_blocksize(const FLAC__SeekableStreamDecoder *decoder)
512 {
513         FLAC__ASSERT(0 != decoder);
514         FLAC__ASSERT(0 != decoder->private_);
515         return FLAC__stream_decoder_get_blocksize(decoder->private_->stream_decoder);
516 }
517
518 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_get_decode_position(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *position)
519 {
520         FLAC__ASSERT(0 != decoder);
521         FLAC__ASSERT(0 != decoder->private_);
522         FLAC__ASSERT(0 != position);
523
524         if(decoder->private_->tell_callback(decoder, position, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK)
525                 return false;
526         FLAC__ASSERT(*position >= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder->private_->stream_decoder));
527         *position -= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder->private_->stream_decoder);
528         return true;
529 }
530
531 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_flush(FLAC__SeekableStreamDecoder *decoder)
532 {
533         FLAC__ASSERT(0 != decoder);
534         FLAC__ASSERT(0 != decoder->private_);
535         FLAC__ASSERT(0 != decoder->protected_);
536
537         decoder->private_->do_md5_checking = false;
538
539         if(!FLAC__stream_decoder_flush(decoder->private_->stream_decoder)) {
540                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
541                 return false;
542         }
543
544         decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_OK;
545
546         return true;
547 }
548
549 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_reset(FLAC__SeekableStreamDecoder *decoder)
550 {
551         FLAC__ASSERT(0 != decoder);
552         FLAC__ASSERT(0 != decoder->private_);
553         FLAC__ASSERT(0 != decoder->protected_);
554
555         if(!FLAC__seekable_stream_decoder_flush(decoder)) {
556                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
557                 return false;
558         }
559
560         if(!FLAC__stream_decoder_reset(decoder->private_->stream_decoder)) {
561                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
562                 return false;
563         }
564
565         decoder->private_->seek_table = 0;
566
567         decoder->private_->do_md5_checking = decoder->protected_->md5_checking;
568
569         /* We initialize the MD5Context even though we may never use it.  This is
570          * because md5 checking may be turned on to start and then turned off if a
571          * seek occurs.  So we always init the context here and finalize it in
572          * FLAC__seekable_stream_decoder_finish() to make sure things are always
573          * cleaned up properly.
574          */
575         MD5Init(&decoder->private_->md5context);
576
577         decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_OK;
578
579         return true;
580 }
581
582 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_process_single(FLAC__SeekableStreamDecoder *decoder)
583 {
584         FLAC__bool ret;
585         FLAC__ASSERT(0 != decoder);
586
587         if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_END_OF_STREAM)
588                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
589
590         if(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
591                 return true;
592
593         FLAC__ASSERT(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_OK);
594
595         ret = FLAC__stream_decoder_process_single(decoder->private_->stream_decoder);
596         if(!ret)
597                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
598
599         return ret;
600 }
601
602 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_process_until_end_of_metadata(FLAC__SeekableStreamDecoder *decoder)
603 {
604         FLAC__bool ret;
605         FLAC__ASSERT(0 != decoder);
606
607         if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_END_OF_STREAM)
608                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
609
610         if(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
611                 return true;
612
613         FLAC__ASSERT(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_OK);
614
615         ret = FLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->stream_decoder);
616         if(!ret)
617                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
618
619         return ret;
620 }
621
622 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_process_until_end_of_stream(FLAC__SeekableStreamDecoder *decoder)
623 {
624         FLAC__bool ret;
625         FLAC__ASSERT(0 != decoder);
626
627         if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_END_OF_STREAM)
628                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
629
630         if(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
631                 return true;
632
633         FLAC__ASSERT(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_OK);
634
635         ret = FLAC__stream_decoder_process_until_end_of_stream(decoder->private_->stream_decoder);
636         if(!ret)
637                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
638
639         return ret;
640 }
641
642 FLAC_API FLAC__bool FLAC__seekable_stream_decoder_seek_absolute(FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 sample)
643 {
644         FLAC__uint64 length;
645
646         FLAC__ASSERT(0 != decoder);
647         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*/);
648
649         decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEKING;
650
651         /* turn off md5 checking if a seek is attempted */
652         decoder->private_->do_md5_checking = false;
653
654         if(!FLAC__stream_decoder_reset(decoder->private_->stream_decoder)) {
655                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
656                 return false;
657         }
658         /* get the file length */
659         if(decoder->private_->length_callback(decoder, &length, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK) {
660                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
661                 return false;
662         }
663         /* rewind */
664         if(decoder->private_->seek_callback(decoder, 0, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK) {
665                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
666                 return false;
667         }
668         if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->stream_decoder)) {
669                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
670                 return false;
671         }
672         if(decoder->private_->stream_info.total_samples > 0 && sample >= decoder->private_->stream_info.total_samples) {
673                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
674                 return false;
675         }
676
677         return seek_to_absolute_sample_(decoder, length, sample);
678 }
679
680 /***********************************************************************
681  *
682  * Private class methods
683  *
684  ***********************************************************************/
685
686 void set_defaults_(FLAC__SeekableStreamDecoder *decoder)
687 {
688         decoder->private_->read_callback = 0;
689         decoder->private_->seek_callback = 0;
690         decoder->private_->tell_callback = 0;
691         decoder->private_->length_callback = 0;
692         decoder->private_->eof_callback = 0;
693         decoder->private_->write_callback = 0;
694         decoder->private_->metadata_callback = 0;
695         decoder->private_->error_callback = 0;
696         decoder->private_->client_data = 0;
697         /* WATCHOUT: these should match the default behavior of FLAC__StreamDecoder */
698         decoder->private_->ignore_stream_info_block = false;
699         decoder->private_->ignore_seek_table_block = true;
700
701         decoder->protected_->md5_checking = false;
702 }
703
704 FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
705 {
706         FLAC__SeekableStreamDecoder *seekable_stream_decoder = (FLAC__SeekableStreamDecoder *)client_data;
707         (void)decoder;
708         if(seekable_stream_decoder->private_->eof_callback(seekable_stream_decoder, seekable_stream_decoder->private_->client_data)) {
709                 *bytes = 0;
710                 seekable_stream_decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
711                 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
712         }
713         else if(*bytes > 0) {
714                 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) {
715                         seekable_stream_decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_READ_ERROR;
716                         return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
717                 }
718                 if(*bytes == 0) {
719                         if(seekable_stream_decoder->private_->eof_callback(seekable_stream_decoder, seekable_stream_decoder->private_->client_data)) {
720                                 seekable_stream_decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
721                                 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
722                         }
723                         else
724                                 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
725                 }
726                 else {
727                         return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
728                 }
729         }
730         else
731                 return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */
732 }
733
734 FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
735 {
736         FLAC__SeekableStreamDecoder *seekable_stream_decoder = (FLAC__SeekableStreamDecoder *)client_data;
737         (void)decoder;
738
739         if(seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_SEEKING) {
740                 FLAC__uint64 this_frame_sample = frame->header.number.sample_number;
741                 FLAC__uint64 next_frame_sample = this_frame_sample + (FLAC__uint64)frame->header.blocksize;
742                 FLAC__uint64 target_sample = seekable_stream_decoder->private_->target_sample;
743
744                 FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
745
746                 seekable_stream_decoder->private_->last_frame = *frame; /* save the frame */
747                 if(this_frame_sample <= target_sample && target_sample < next_frame_sample) { /* we hit our target frame */
748                         unsigned delta = (unsigned)(target_sample - this_frame_sample);
749                         /* kick out of seek mode */
750                         seekable_stream_decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_OK;
751                         /* shift out the samples before target_sample */
752                         if(delta > 0) {
753                                 unsigned channel;
754                                 const FLAC__int32 *newbuffer[FLAC__MAX_CHANNELS];
755                                 for(channel = 0; channel < frame->header.channels; channel++)
756                                         newbuffer[channel] = buffer[channel] + delta;
757                                 seekable_stream_decoder->private_->last_frame.header.blocksize -= delta;
758                                 seekable_stream_decoder->private_->last_frame.header.number.sample_number += (FLAC__uint64)delta;
759                                 /* write the relevant samples */
760                                 return seekable_stream_decoder->private_->write_callback(seekable_stream_decoder, &seekable_stream_decoder->private_->last_frame, newbuffer, seekable_stream_decoder->private_->client_data);
761                         }
762                         else {
763                                 /* write the relevant samples */
764                                 return seekable_stream_decoder->private_->write_callback(seekable_stream_decoder, frame, buffer, seekable_stream_decoder->private_->client_data);
765                         }
766                 }
767                 else {
768                         return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
769                 }
770         }
771         else {
772                 if(seekable_stream_decoder->private_->do_md5_checking) {
773                         if(!FLAC__MD5Accumulate(&seekable_stream_decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8))
774                                 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
775                 }
776                 return seekable_stream_decoder->private_->write_callback(seekable_stream_decoder, frame, buffer, seekable_stream_decoder->private_->client_data);
777         }
778 }
779
780 void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
781 {
782         FLAC__SeekableStreamDecoder *seekable_stream_decoder = (FLAC__SeekableStreamDecoder *)client_data;
783         (void)decoder;
784
785         if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
786                 seekable_stream_decoder->private_->stream_info = metadata->data.stream_info;
787                 /* save the MD5 signature for comparison later */
788                 memcpy(seekable_stream_decoder->private_->stored_md5sum, metadata->data.stream_info.md5sum, 16);
789                 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))
790                         seekable_stream_decoder->private_->do_md5_checking = false;
791         }
792         else if(metadata->type == FLAC__METADATA_TYPE_SEEKTABLE) {
793                 seekable_stream_decoder->private_->seek_table = &metadata->data.seek_table;
794         }
795
796         if(seekable_stream_decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING) {
797                 FLAC__bool ignore_block = false;
798                 if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO && seekable_stream_decoder->private_->ignore_stream_info_block)
799                         ignore_block = true;
800                 else if(metadata->type == FLAC__METADATA_TYPE_SEEKTABLE && seekable_stream_decoder->private_->ignore_seek_table_block)
801                         ignore_block = true;
802                 if(!ignore_block)
803                         seekable_stream_decoder->private_->metadata_callback(seekable_stream_decoder, metadata, seekable_stream_decoder->private_->client_data);
804         }
805 }
806
807 void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
808 {
809         FLAC__SeekableStreamDecoder *seekable_stream_decoder = (FLAC__SeekableStreamDecoder *)client_data;
810         (void)decoder;
811
812         if(seekable_stream_decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING)
813                 seekable_stream_decoder->private_->error_callback(seekable_stream_decoder, status, seekable_stream_decoder->private_->client_data);
814 }
815
816 FLAC__bool seek_to_absolute_sample_(FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample)
817 {
818         FLAC__uint64 first_frame_offset, lower_bound, upper_bound;
819         FLAC__int64 pos = -1, last_pos = -1;
820         int i, lower_seek_point = -1, upper_seek_point = -1;
821         unsigned approx_bytes_per_frame;
822         FLAC__uint64 last_frame_sample = 0xffffffffffffffff;
823         FLAC__bool needs_seek;
824         const FLAC__uint64 total_samples = decoder->private_->stream_info.total_samples;
825         const unsigned min_blocksize = decoder->private_->stream_info.min_blocksize;
826         const unsigned max_blocksize = decoder->private_->stream_info.max_blocksize;
827         const unsigned max_framesize = decoder->private_->stream_info.max_framesize;
828         const unsigned channels = FLAC__seekable_stream_decoder_get_channels(decoder);
829         const unsigned bps = FLAC__seekable_stream_decoder_get_bits_per_sample(decoder);
830
831         /* we are just guessing here, but we want to guess high, not low */
832         if(max_framesize > 0) {
833                 approx_bytes_per_frame = max_framesize;
834         }
835         /*
836          * Check if it's a known fixed-blocksize stream.  Note that though
837          * the spec doesn't allow zeroes in the STREAMINFO block, we may
838          * never get a STREAMINFO block when decoding so the value of
839          * min_blocksize might be zero.
840          */
841         else if(min_blocksize == max_blocksize && min_blocksize > 0) {
842                 /* note there are no () around 'bps/8' to keep precision up since it's an integer calulation */
843                 approx_bytes_per_frame = min_blocksize * channels * bps/8 + 64;
844         }
845         else
846                 approx_bytes_per_frame = 4608 * channels * bps/8 + 64;
847
848         /*
849          * The decode position is currently at the first frame since we
850          * rewound and processed metadata.
851          */
852         if(!FLAC__seekable_stream_decoder_get_decode_position(decoder, &first_frame_offset)) {
853                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
854                 return false;
855         }
856
857         /*
858          * First, we set an upper and lower bound on where in the
859          * stream we will search.  For now we assume the worst case
860          * scenario, which is our best guess at the beginning of
861          * the first and last frames.
862          */
863         lower_bound = first_frame_offset;
864
865         /* calc the upper_bound, beyond which we never want to seek */
866         if(max_framesize > 0)
867                 upper_bound = stream_length - (max_framesize + 128 + 2); /* 128 for a possible ID3V1 tag, 2 for indexing differences */
868         else
869                 upper_bound = stream_length - ((channels * bps * FLAC__MAX_BLOCK_SIZE) / 8 + 128 + 2);
870
871         /*
872          * Now we refine the bounds if we have a seektable with
873          * suitable points.  Note that according to the spec they
874          * must be ordered by ascending sample number.
875          */
876         if(0 != decoder->private_->seek_table) {
877                 /* find the closest seek point <= target_sample, if it exists */
878                 for(i = (int)decoder->private_->seek_table->num_points - 1; i >= 0; i--) {
879                         if(decoder->private_->seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && decoder->private_->seek_table->points[i].sample_number <= target_sample)
880                                 break;
881                 }
882                 if(i >= 0) { /* i.e. we found a suitable seek point... */
883                         lower_bound = first_frame_offset + decoder->private_->seek_table->points[i].stream_offset;
884                         lower_seek_point = i;
885                 }
886
887                 /* find the closest seek point > target_sample, if it exists */
888                 for(i = 0; i < (int)decoder->private_->seek_table->num_points; i++) {
889                         if(decoder->private_->seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && decoder->private_->seek_table->points[i].sample_number > target_sample)
890                                 break;
891                 }
892                 if(i < (int)decoder->private_->seek_table->num_points) { /* i.e. we found a suitable seek point... */
893                         upper_bound = first_frame_offset + decoder->private_->seek_table->points[i].stream_offset;
894                         upper_seek_point = i;
895                 }
896         }
897
898         /*
899          * Now guess at where within those bounds our target
900          * sample will be.
901          */
902         if(lower_seek_point >= 0) {
903                 /* first see if our sample is within a few frames of the lower seekpoint */
904                 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)) {
905                         pos = (FLAC__int64)lower_bound;
906                 }
907                 else if(upper_seek_point >= 0) {
908                         const FLAC__uint64 target_offset = target_sample - decoder->private_->seek_table->points[lower_seek_point].sample_number;
909                         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;
910                         const FLAC__uint64 range_bytes = upper_bound - lower_bound;
911 #if defined _MSC_VER || defined __MINGW32__
912                         /* with VC++ you have to spoon feed it the casting */
913                         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;
914 #else
915                         pos = (FLAC__int64)lower_bound + (FLAC__int64)((double)target_offset / (double)range_samples * (double)(range_bytes-1)) - approx_bytes_per_frame;
916 #endif
917                 }
918         }
919
920         /*
921          * If there's no seek table, we need to use the metadata (if we
922          * have it) and the filelength to estimate the position of the
923          * frame with the correct sample.
924          */
925         if(pos < 0 && total_samples > 0) {
926 #if defined _MSC_VER || defined __MINGW32__
927                 /* with VC++ you have to spoon feed it the casting */
928                 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;
929 #else
930                 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;
931 #endif
932         }
933
934         /*
935          * If there's no seek table and total_samples is unknown, we
936          * don't even bother trying to figure out a target, we just use
937          * our current position.
938          */
939         if(pos < 0) {
940                 FLAC__uint64 upos;
941                 if(decoder->private_->tell_callback(decoder, &upos, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK) {
942                         decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
943                         return false;
944                 }
945                 pos = (FLAC__int64)upos;
946                 needs_seek = false;
947         }
948         else
949                 needs_seek = true;
950
951         /* clip the position to the bounds, lower bound takes precedence */
952         if(pos >= (FLAC__int64)upper_bound) {
953                 pos = (FLAC__int64)upper_bound-1;
954                 needs_seek = true;
955         }
956         if(pos < (FLAC__int64)lower_bound) {
957                 pos = (FLAC__int64)lower_bound;
958                 needs_seek = true;
959         }
960
961         decoder->private_->target_sample = target_sample;
962         while(1) {
963                 if(needs_seek) {
964                         if(decoder->private_->seek_callback(decoder, (FLAC__uint64)pos, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK) {
965                                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
966                                 return false;
967                         }
968                         if(!FLAC__stream_decoder_flush(decoder->private_->stream_decoder)) {
969                                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
970                                 return false;
971                         }
972                 }
973                 /* Now we need to get a frame.  It is possible for our seek
974                  * to land in the middle of audio data that looks exactly like
975                  * a frame header from a future version of an encoder.  When
976                  * that happens, FLAC__stream_decoder_process_single() will
977                  * return false and the state will be
978                  * FLAC__STREAM_DECODER_UNPARSEABLE_STREAM.  But there is a
979                  * remote possibility that it is properly synced at such a
980                  * "future-codec frame", so to make sure, we wait to see
981                  * several "unparseable" errors in a row before bailing out.
982                  */
983                 {
984                         unsigned unparseable_count;
985                         FLAC__bool got_a_frame = false;
986                         for (unparseable_count = 0; !got_a_frame && unparseable_count < 10; unparseable_count++) {
987                                 if(FLAC__stream_decoder_process_single(decoder->private_->stream_decoder))
988                                         got_a_frame = true;
989                                 else if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_UNPARSEABLE_STREAM)
990                                         /* try again.  we don't want to flush the decoder since that clears the bitbuffer */
991                                         decoder->private_->stream_decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
992                                 else /* it's a real error */
993                                         break;
994                         }
995                         if (!got_a_frame) {
996                                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
997                                 return false;
998                         }
999                 }
1000                 /* our write callback will change the state when it gets to the target frame */
1001                 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING) {
1002                         break;
1003                 }
1004                 else { /* we need to narrow the search */
1005                         FLAC__uint64 this_frame_sample = decoder->private_->last_frame.header.number.sample_number;
1006                         FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
1007                         if(this_frame_sample == last_frame_sample && pos < last_pos) {
1008                                 /* our last move backwards wasn't big enough, double it */
1009                                 pos -= (last_pos - pos);
1010                                 needs_seek = true;
1011                         }
1012                         else {
1013                                 if(target_sample < this_frame_sample) {
1014                                         last_pos = pos;
1015                                         approx_bytes_per_frame = decoder->private_->last_frame.header.blocksize * channels * bps/8 + 64;
1016                                         pos -= approx_bytes_per_frame;
1017                                         needs_seek = true;
1018                                 }
1019                                 else { /* target_sample >= this_frame_sample + this frame's blocksize */
1020                                         FLAC__uint64 upos;
1021                                         if(decoder->private_->tell_callback(decoder, &upos, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK) {
1022                                                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
1023                                                 return false;
1024                                         }
1025                                         last_pos = pos;
1026                                         pos = (FLAC__int64)upos;
1027                                         pos -= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder->private_->stream_decoder);
1028                                         needs_seek = false;
1029                                         /*
1030                                          * if we haven't hit the target frame yet and our position hasn't changed,
1031                                          * it means we're at the end of the stream and the seek target does not exist.
1032                                          */
1033                                         if(last_pos == pos) {
1034                                                 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
1035                                                 return false;
1036                                         }
1037                                 }
1038                         }
1039                         if(pos < (FLAC__int64)lower_bound)
1040                                 pos = (FLAC__int64)lower_bound;
1041                         last_frame_sample = this_frame_sample;
1042                 }
1043         }
1044
1045         return true;
1046 }