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