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