vx32

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

file_decoder.c (25636B)


      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 malloc() */
     34 #include <string.h> /* for strcmp() */
     35 #include <sys/stat.h> /* for stat() */
     36 #if defined _MSC_VER || defined __MINGW32__
     37 #include <io.h> /* for _setmode() */
     38 #include <fcntl.h> /* for _O_BINARY */
     39 #elif defined __CYGWIN__
     40 #include <io.h> /* for setmode(), O_BINARY */
     41 #include <fcntl.h> /* for _O_BINARY */
     42 #endif
     43 #include "FLAC/assert.h"
     44 #include "protected/file_decoder.h"
     45 #include "protected/seekable_stream_decoder.h"
     46 
     47 /***********************************************************************
     48  *
     49  * Private class method prototypes
     50  *
     51  ***********************************************************************/
     52 
     53 static void set_defaults_(FLAC__FileDecoder *decoder);
     54 static FILE *get_binary_stdin_();
     55 static FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
     56 static FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
     57 static FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
     58 static FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
     59 static FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data);
     60 static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
     61 static void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
     62 static void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
     63 
     64 /***********************************************************************
     65  *
     66  * Private class data
     67  *
     68  ***********************************************************************/
     69 
     70 typedef struct FLAC__FileDecoderPrivate {
     71 	FLAC__FileDecoderWriteCallback write_callback;
     72 	FLAC__FileDecoderMetadataCallback metadata_callback;
     73 	FLAC__FileDecoderErrorCallback error_callback;
     74 	void *client_data;
     75 	FILE *file;
     76 	char *filename; /* == NULL if stdin */
     77 	FLAC__SeekableStreamDecoder *seekable_stream_decoder;
     78 } FLAC__FileDecoderPrivate;
     79 
     80 /***********************************************************************
     81  *
     82  * Public static class data
     83  *
     84  ***********************************************************************/
     85 
     86 FLAC_API const char * const FLAC__FileDecoderStateString[] = {
     87 	"FLAC__FILE_DECODER_OK",
     88 	"FLAC__FILE_DECODER_END_OF_FILE",
     89 	"FLAC__FILE_DECODER_ERROR_OPENING_FILE",
     90 	"FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR",
     91 	"FLAC__FILE_DECODER_SEEK_ERROR",
     92 	"FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR",
     93 	"FLAC__FILE_DECODER_ALREADY_INITIALIZED",
     94 	"FLAC__FILE_DECODER_INVALID_CALLBACK",
     95 	"FLAC__FILE_DECODER_UNINITIALIZED"
     96 };
     97 
     98 /***********************************************************************
     99  *
    100  * Class constructor/destructor
    101  *
    102  ***********************************************************************/
    103 
    104 FLAC_API FLAC__FileDecoder *FLAC__file_decoder_new()
    105 {
    106 	FLAC__FileDecoder *decoder;
    107 
    108 	FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
    109 
    110 	decoder = (FLAC__FileDecoder*)calloc(1, sizeof(FLAC__FileDecoder));
    111 	if(decoder == 0) {
    112 		return 0;
    113 	}
    114 
    115 	decoder->protected_ = (FLAC__FileDecoderProtected*)calloc(1, sizeof(FLAC__FileDecoderProtected));
    116 	if(decoder->protected_ == 0) {
    117 		free(decoder);
    118 		return 0;
    119 	}
    120 
    121 	decoder->private_ = (FLAC__FileDecoderPrivate*)calloc(1, sizeof(FLAC__FileDecoderPrivate));
    122 	if(decoder->private_ == 0) {
    123 		free(decoder->protected_);
    124 		free(decoder);
    125 		return 0;
    126 	}
    127 
    128 	decoder->private_->seekable_stream_decoder = FLAC__seekable_stream_decoder_new();
    129 	if(0 == decoder->private_->seekable_stream_decoder) {
    130 		free(decoder->private_);
    131 		free(decoder->protected_);
    132 		free(decoder);
    133 		return 0;
    134 	}
    135 
    136 	decoder->private_->file = 0;
    137 
    138 	set_defaults_(decoder);
    139 
    140 	decoder->protected_->state = FLAC__FILE_DECODER_UNINITIALIZED;
    141 
    142 	return decoder;
    143 }
    144 
    145 FLAC_API void FLAC__file_decoder_delete(FLAC__FileDecoder *decoder)
    146 {
    147 	FLAC__ASSERT(0 != decoder);
    148 	FLAC__ASSERT(0 != decoder->protected_);
    149 	FLAC__ASSERT(0 != decoder->private_);
    150 	FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
    151 
    152 	(void)FLAC__file_decoder_finish(decoder);
    153 
    154 	FLAC__seekable_stream_decoder_delete(decoder->private_->seekable_stream_decoder);
    155 
    156 	free(decoder->private_);
    157 	free(decoder->protected_);
    158 	free(decoder);
    159 }
    160 
    161 /***********************************************************************
    162  *
    163  * Public class methods
    164  *
    165  ***********************************************************************/
    166 
    167 FLAC_API FLAC__FileDecoderState FLAC__file_decoder_init(FLAC__FileDecoder *decoder)
    168 {
    169 	FLAC__ASSERT(0 != decoder);
    170 
    171 	if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
    172 		return decoder->protected_->state = FLAC__FILE_DECODER_ALREADY_INITIALIZED;
    173 
    174 	if(0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
    175 		return decoder->protected_->state = FLAC__FILE_DECODER_INVALID_CALLBACK;
    176 
    177 	if(0 == decoder->private_->filename)
    178 		decoder->private_->file = get_binary_stdin_();
    179 	else
    180 		decoder->private_->file = fopen(decoder->private_->filename, "rb");
    181 
    182 	if(decoder->private_->file == 0)
    183 		return decoder->protected_->state = FLAC__FILE_DECODER_ERROR_OPENING_FILE;
    184 
    185 	FLAC__seekable_stream_decoder_set_read_callback(decoder->private_->seekable_stream_decoder, read_callback_);
    186 	FLAC__seekable_stream_decoder_set_seek_callback(decoder->private_->seekable_stream_decoder, seek_callback_);
    187 	FLAC__seekable_stream_decoder_set_tell_callback(decoder->private_->seekable_stream_decoder, tell_callback_);
    188 	FLAC__seekable_stream_decoder_set_length_callback(decoder->private_->seekable_stream_decoder, length_callback_);
    189 	FLAC__seekable_stream_decoder_set_eof_callback(decoder->private_->seekable_stream_decoder, eof_callback_);
    190 	FLAC__seekable_stream_decoder_set_write_callback(decoder->private_->seekable_stream_decoder, write_callback_);
    191 	FLAC__seekable_stream_decoder_set_metadata_callback(decoder->private_->seekable_stream_decoder, metadata_callback_);
    192 	FLAC__seekable_stream_decoder_set_error_callback(decoder->private_->seekable_stream_decoder, error_callback_);
    193 	FLAC__seekable_stream_decoder_set_client_data(decoder->private_->seekable_stream_decoder, decoder);
    194 
    195 	if(FLAC__seekable_stream_decoder_init(decoder->private_->seekable_stream_decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK)
    196 		return decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
    197 
    198 	return decoder->protected_->state = FLAC__FILE_DECODER_OK;
    199 }
    200 
    201 FLAC_API FLAC__bool FLAC__file_decoder_finish(FLAC__FileDecoder *decoder)
    202 {
    203 	FLAC__ASSERT(0 != decoder);
    204 
    205 	if(decoder->protected_->state == FLAC__FILE_DECODER_UNINITIALIZED)
    206 		return true;
    207 
    208 	FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
    209 
    210 	if(0 != decoder->private_->file && decoder->private_->file != stdin) {
    211 		fclose(decoder->private_->file);
    212 		decoder->private_->file = 0;
    213 	}
    214 
    215 	if(0 != decoder->private_->filename) {
    216 		free(decoder->private_->filename);
    217 		decoder->private_->filename = 0;
    218 	}
    219 
    220 	set_defaults_(decoder);
    221 
    222 	decoder->protected_->state = FLAC__FILE_DECODER_UNINITIALIZED;
    223 
    224 	return FLAC__seekable_stream_decoder_finish(decoder->private_->seekable_stream_decoder);
    225 }
    226 
    227 FLAC_API FLAC__bool FLAC__file_decoder_set_md5_checking(FLAC__FileDecoder *decoder, FLAC__bool value)
    228 {
    229 	FLAC__ASSERT(0 != decoder);
    230 	FLAC__ASSERT(0 != decoder->private_);
    231 	FLAC__ASSERT(0 != decoder->protected_);
    232 	FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
    233 	if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
    234 		return false;
    235 	return FLAC__seekable_stream_decoder_set_md5_checking(decoder->private_->seekable_stream_decoder, value);
    236 }
    237 
    238 FLAC_API FLAC__bool FLAC__file_decoder_set_filename(FLAC__FileDecoder *decoder, const char *value)
    239 {
    240 	FLAC__ASSERT(0 != decoder);
    241 	FLAC__ASSERT(0 != decoder->private_);
    242 	FLAC__ASSERT(0 != decoder->protected_);
    243 	FLAC__ASSERT(0 != value);
    244 	if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
    245 		return false;
    246 	if(0 != decoder->private_->filename) {
    247 		free(decoder->private_->filename);
    248 		decoder->private_->filename = 0;
    249 	}
    250 	if(0 != strcmp(value, "-")) {
    251 		if(0 == (decoder->private_->filename = (char*)malloc(strlen(value)+1))) {
    252 			decoder->protected_->state = FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR;
    253 			return false;
    254 		}
    255 		strcpy(decoder->private_->filename, value);
    256 	}
    257 	return true;
    258 }
    259 
    260 FLAC_API FLAC__bool FLAC__file_decoder_set_write_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderWriteCallback value)
    261 {
    262 	FLAC__ASSERT(0 != decoder);
    263 	FLAC__ASSERT(0 != decoder->private_);
    264 	FLAC__ASSERT(0 != decoder->protected_);
    265 	if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
    266 		return false;
    267 	decoder->private_->write_callback = value;
    268 	return true;
    269 }
    270 
    271 FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderMetadataCallback value)
    272 {
    273 	FLAC__ASSERT(0 != decoder);
    274 	FLAC__ASSERT(0 != decoder->private_);
    275 	FLAC__ASSERT(0 != decoder->protected_);
    276 	if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
    277 		return false;
    278 	decoder->private_->metadata_callback = value;
    279 	return true;
    280 }
    281 
    282 FLAC_API FLAC__bool FLAC__file_decoder_set_error_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderErrorCallback value)
    283 {
    284 	FLAC__ASSERT(0 != decoder);
    285 	FLAC__ASSERT(0 != decoder->private_);
    286 	FLAC__ASSERT(0 != decoder->protected_);
    287 	if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
    288 		return false;
    289 	decoder->private_->error_callback = value;
    290 	return true;
    291 }
    292 
    293 FLAC_API FLAC__bool FLAC__file_decoder_set_client_data(FLAC__FileDecoder *decoder, void *value)
    294 {
    295 	FLAC__ASSERT(0 != decoder);
    296 	FLAC__ASSERT(0 != decoder->private_);
    297 	FLAC__ASSERT(0 != decoder->protected_);
    298 	if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
    299 		return false;
    300 	decoder->private_->client_data = value;
    301 	return true;
    302 }
    303 
    304 FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_respond(FLAC__FileDecoder *decoder, FLAC__MetadataType type)
    305 {
    306 	FLAC__ASSERT(0 != decoder);
    307 	FLAC__ASSERT(0 != decoder->private_);
    308 	FLAC__ASSERT(0 != decoder->protected_);
    309 	FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
    310 	if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
    311 		return false;
    312 	return FLAC__seekable_stream_decoder_set_metadata_respond(decoder->private_->seekable_stream_decoder, type);
    313 }
    314 
    315 FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_respond_application(FLAC__FileDecoder *decoder, const FLAC__byte id[4])
    316 {
    317 	FLAC__ASSERT(0 != decoder);
    318 	FLAC__ASSERT(0 != decoder->private_);
    319 	FLAC__ASSERT(0 != decoder->protected_);
    320 	FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
    321 	if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
    322 		return false;
    323 	return FLAC__seekable_stream_decoder_set_metadata_respond_application(decoder->private_->seekable_stream_decoder, id);
    324 }
    325 
    326 FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_respond_all(FLAC__FileDecoder *decoder)
    327 {
    328 	FLAC__ASSERT(0 != decoder);
    329 	FLAC__ASSERT(0 != decoder->private_);
    330 	FLAC__ASSERT(0 != decoder->protected_);
    331 	FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
    332 	if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
    333 		return false;
    334 	return FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder->private_->seekable_stream_decoder);
    335 }
    336 
    337 FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_ignore(FLAC__FileDecoder *decoder, FLAC__MetadataType type)
    338 {
    339 	FLAC__ASSERT(0 != decoder);
    340 	FLAC__ASSERT(0 != decoder->private_);
    341 	FLAC__ASSERT(0 != decoder->protected_);
    342 	FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
    343 	if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
    344 		return false;
    345 	return FLAC__seekable_stream_decoder_set_metadata_ignore(decoder->private_->seekable_stream_decoder, type);
    346 }
    347 
    348 FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_ignore_application(FLAC__FileDecoder *decoder, const FLAC__byte id[4])
    349 {
    350 	FLAC__ASSERT(0 != decoder);
    351 	FLAC__ASSERT(0 != decoder->private_);
    352 	FLAC__ASSERT(0 != decoder->protected_);
    353 	FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
    354 	if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
    355 		return false;
    356 	return FLAC__seekable_stream_decoder_set_metadata_ignore_application(decoder->private_->seekable_stream_decoder, id);
    357 }
    358 
    359 FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_ignore_all(FLAC__FileDecoder *decoder)
    360 {
    361 	FLAC__ASSERT(0 != decoder);
    362 	FLAC__ASSERT(0 != decoder->private_);
    363 	FLAC__ASSERT(0 != decoder->protected_);
    364 	FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
    365 	if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED)
    366 		return false;
    367 	return FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder->private_->seekable_stream_decoder);
    368 }
    369 
    370 FLAC_API FLAC__FileDecoderState FLAC__file_decoder_get_state(const FLAC__FileDecoder *decoder)
    371 {
    372 	FLAC__ASSERT(0 != decoder);
    373 	FLAC__ASSERT(0 != decoder->protected_);
    374 	return decoder->protected_->state;
    375 }
    376 
    377 FLAC_API FLAC__SeekableStreamDecoderState FLAC__file_decoder_get_seekable_stream_decoder_state(const FLAC__FileDecoder *decoder)
    378 {
    379 	FLAC__ASSERT(0 != decoder);
    380 	FLAC__ASSERT(0 != decoder->private_);
    381 	return FLAC__seekable_stream_decoder_get_state(decoder->private_->seekable_stream_decoder);
    382 }
    383 
    384 FLAC_API FLAC__StreamDecoderState FLAC__file_decoder_get_stream_decoder_state(const FLAC__FileDecoder *decoder)
    385 {
    386 	FLAC__ASSERT(0 != decoder);
    387 	FLAC__ASSERT(0 != decoder->private_);
    388 	return FLAC__seekable_stream_decoder_get_stream_decoder_state(decoder->private_->seekable_stream_decoder);
    389 }
    390 
    391 FLAC_API const char *FLAC__file_decoder_get_resolved_state_string(const FLAC__FileDecoder *decoder)
    392 {
    393 	if(decoder->protected_->state != FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR)
    394 		return FLAC__FileDecoderStateString[decoder->protected_->state];
    395 	else
    396 		return FLAC__seekable_stream_decoder_get_resolved_state_string(decoder->private_->seekable_stream_decoder);
    397 }
    398 
    399 FLAC_API FLAC__bool FLAC__file_decoder_get_md5_checking(const FLAC__FileDecoder *decoder)
    400 {
    401 	FLAC__ASSERT(0 != decoder);
    402 	FLAC__ASSERT(0 != decoder->private_);
    403 	return FLAC__seekable_stream_decoder_get_md5_checking(decoder->private_->seekable_stream_decoder);
    404 }
    405 
    406 FLAC_API unsigned FLAC__file_decoder_get_channels(const FLAC__FileDecoder *decoder)
    407 {
    408 	FLAC__ASSERT(0 != decoder);
    409 	FLAC__ASSERT(0 != decoder->private_);
    410 	return FLAC__seekable_stream_decoder_get_channels(decoder->private_->seekable_stream_decoder);
    411 }
    412 
    413 FLAC_API FLAC__ChannelAssignment FLAC__file_decoder_get_channel_assignment(const FLAC__FileDecoder *decoder)
    414 {
    415 	FLAC__ASSERT(0 != decoder);
    416 	FLAC__ASSERT(0 != decoder->private_);
    417 	return FLAC__seekable_stream_decoder_get_channel_assignment(decoder->private_->seekable_stream_decoder);
    418 }
    419 
    420 FLAC_API unsigned FLAC__file_decoder_get_bits_per_sample(const FLAC__FileDecoder *decoder)
    421 {
    422 	FLAC__ASSERT(0 != decoder);
    423 	FLAC__ASSERT(0 != decoder->private_);
    424 	return FLAC__seekable_stream_decoder_get_bits_per_sample(decoder->private_->seekable_stream_decoder);
    425 }
    426 
    427 FLAC_API unsigned FLAC__file_decoder_get_sample_rate(const FLAC__FileDecoder *decoder)
    428 {
    429 	FLAC__ASSERT(0 != decoder);
    430 	FLAC__ASSERT(0 != decoder->private_);
    431 	return FLAC__seekable_stream_decoder_get_sample_rate(decoder->private_->seekable_stream_decoder);
    432 }
    433 
    434 FLAC_API unsigned FLAC__file_decoder_get_blocksize(const FLAC__FileDecoder *decoder)
    435 {
    436 	FLAC__ASSERT(0 != decoder);
    437 	FLAC__ASSERT(0 != decoder->private_);
    438 	return FLAC__seekable_stream_decoder_get_blocksize(decoder->private_->seekable_stream_decoder);
    439 }
    440 
    441 FLAC_API FLAC__bool FLAC__file_decoder_get_decode_position(const FLAC__FileDecoder *decoder, FLAC__uint64 *position)
    442 {
    443 	FLAC__ASSERT(0 != decoder);
    444 	FLAC__ASSERT(0 != decoder->private_);
    445 	return FLAC__seekable_stream_decoder_get_decode_position(decoder->private_->seekable_stream_decoder, position);
    446 }
    447 
    448 FLAC_API FLAC__bool FLAC__file_decoder_process_single(FLAC__FileDecoder *decoder)
    449 {
    450 	FLAC__bool ret;
    451 	FLAC__ASSERT(0 != decoder);
    452 
    453 	if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
    454 		decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
    455 
    456 	if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
    457 		return true;
    458 
    459 	FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
    460 
    461 	ret = FLAC__seekable_stream_decoder_process_single(decoder->private_->seekable_stream_decoder);
    462 	if(!ret)
    463 		decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
    464 
    465 	return ret;
    466 }
    467 
    468 FLAC_API FLAC__bool FLAC__file_decoder_process_until_end_of_metadata(FLAC__FileDecoder *decoder)
    469 {
    470 	FLAC__bool ret;
    471 	FLAC__ASSERT(0 != decoder);
    472 
    473 	if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
    474 		decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
    475 
    476 	if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
    477 		return true;
    478 
    479 	FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
    480 
    481 	ret = FLAC__seekable_stream_decoder_process_until_end_of_metadata(decoder->private_->seekable_stream_decoder);
    482 	if(!ret)
    483 		decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
    484 
    485 	return ret;
    486 }
    487 
    488 FLAC_API FLAC__bool FLAC__file_decoder_process_until_end_of_file(FLAC__FileDecoder *decoder)
    489 {
    490 	FLAC__bool ret;
    491 	FLAC__ASSERT(0 != decoder);
    492 
    493 	if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
    494 		decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
    495 
    496 	if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
    497 		return true;
    498 
    499 	FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
    500 
    501 	ret = FLAC__seekable_stream_decoder_process_until_end_of_stream(decoder->private_->seekable_stream_decoder);
    502 	if(!ret)
    503 		decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
    504 
    505 	return ret;
    506 }
    507 
    508 FLAC_API FLAC__bool FLAC__file_decoder_skip_single_frame(FLAC__FileDecoder *decoder)
    509 {
    510 	FLAC__bool ret;
    511 	FLAC__ASSERT(0 != decoder);
    512 
    513 	if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
    514 		decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE;
    515 
    516 	if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE)
    517 		return true;
    518 
    519 	FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK);
    520 
    521 	ret = FLAC__seekable_stream_decoder_skip_single_frame(decoder->private_->seekable_stream_decoder);
    522 	if(!ret)
    523 		decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
    524 
    525 	return ret;
    526 }
    527 
    528 FLAC_API FLAC__bool FLAC__file_decoder_seek_absolute(FLAC__FileDecoder *decoder, FLAC__uint64 sample)
    529 {
    530 	FLAC__ASSERT(0 != decoder);
    531 	FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK || decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE);
    532 
    533 	if(decoder->private_->filename == 0) { /* means the file is stdin... */
    534 		decoder->protected_->state = FLAC__FILE_DECODER_SEEK_ERROR;
    535 		return false;
    536 	}
    537 
    538 	if(!FLAC__seekable_stream_decoder_seek_absolute(decoder->private_->seekable_stream_decoder, sample)) {
    539 		decoder->protected_->state = FLAC__FILE_DECODER_SEEK_ERROR;
    540 		return false;
    541 	}
    542 	else {
    543 		decoder->protected_->state = FLAC__FILE_DECODER_OK;
    544 		return true;
    545 	}
    546 }
    547 
    548 
    549 /***********************************************************************
    550  *
    551  * Private class methods
    552  *
    553  ***********************************************************************/
    554 
    555 void set_defaults_(FLAC__FileDecoder *decoder)
    556 {
    557 	FLAC__ASSERT(0 != decoder);
    558 	FLAC__ASSERT(0 != decoder->private_);
    559 
    560 	decoder->private_->filename = 0;
    561 	decoder->private_->write_callback = 0;
    562 	decoder->private_->metadata_callback = 0;
    563 	decoder->private_->error_callback = 0;
    564 	decoder->private_->client_data = 0;
    565 }
    566 
    567 /*
    568  * This will forcibly set stdin to binary mode (for OSes that require it)
    569  */
    570 FILE *get_binary_stdin_()
    571 {
    572 	/* if something breaks here it is probably due to the presence or
    573 	 * absence of an underscore before the identifiers 'setmode',
    574 	 * 'fileno', and/or 'O_BINARY'; check your system header files.
    575 	 */
    576 #if defined _MSC_VER || defined __MINGW32__
    577 	_setmode(_fileno(stdin), _O_BINARY);
    578 #elif defined __CYGWIN__
    579 	/* almost certainly not needed for any modern Cygwin, but let's be safe... */
    580 	setmode(_fileno(stdin), _O_BINARY);
    581 #endif
    582 
    583 	return stdin;
    584 }
    585 
    586 FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
    587 {
    588 	FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
    589 	(void)decoder;
    590 
    591 	if(*bytes > 0) {
    592 		*bytes = (unsigned)fread(buffer, sizeof(FLAC__byte), *bytes, file_decoder->private_->file);
    593 		if(ferror(file_decoder->private_->file)) {
    594 			return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
    595 		}
    596 		else {
    597 			return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
    598 		}
    599 	}
    600 	else
    601 		return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; /* abort to avoid a deadlock */
    602 }
    603 
    604 FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
    605 {
    606 	FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
    607 	(void)decoder;
    608 
    609 	if(fseek(file_decoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0)
    610 		return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
    611 	else
    612 		return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
    613 }
    614 
    615 FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
    616 {
    617 	FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
    618 	long pos;
    619 	(void)decoder;
    620 
    621 	if((pos = ftell(file_decoder->private_->file)) < 0)
    622 		return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
    623 	else {
    624 		*absolute_byte_offset = (FLAC__uint64)pos;
    625 		return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
    626 	}
    627 }
    628 
    629 FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
    630 {
    631 	FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
    632 	struct stat filestats;
    633 	(void)decoder;
    634 
    635 	if(0 == file_decoder->private_->filename || stat(file_decoder->private_->filename, &filestats) != 0)
    636 		return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
    637 	else {
    638 		*stream_length = (FLAC__uint64)filestats.st_size;
    639 		return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
    640 	}
    641 }
    642 
    643 FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data)
    644 {
    645 	FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
    646 	(void)decoder;
    647 
    648 	return feof(file_decoder->private_->file)? true : false;
    649 }
    650 
    651 FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
    652 {
    653 	FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
    654 	(void)decoder;
    655 
    656 	return file_decoder->private_->write_callback(file_decoder, frame, buffer, file_decoder->private_->client_data);
    657 }
    658 
    659 void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
    660 {
    661 	FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
    662 	(void)decoder;
    663 
    664 	file_decoder->private_->metadata_callback(file_decoder, metadata, file_decoder->private_->client_data);
    665 }
    666 
    667 void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
    668 {
    669 	FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
    670 	(void)decoder;
    671 
    672 	file_decoder->private_->error_callback(file_decoder, status, file_decoder->private_->client_data);
    673 }