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