vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

seekable_stream_decoder.c (47027B)


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