vx32

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

decode.c (47353B)


      1 /* flac - Command-line FLAC encoder/decoder
      2  * Copyright (C) 2000,2001,2002,2003,2004,2005  Josh Coalson
      3  *
      4  * This program is free software; you can redistribute it and/or
      5  * modify it under the terms of the GNU General Public License
      6  * as published by the Free Software Foundation; either version 2
      7  * of the License, or (at your option) any later version.
      8  *
      9  * This program 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
     12  * GNU General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU General Public License
     15  * along with this program; if not, write to the Free Software
     16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17  */
     18 
     19 #ifdef HAVE_CONFIG_H
     20 #include <config.h>
     21 #endif
     22 
     23 #if defined _WIN32 && !defined __CYGWIN__
     24 /* where MSVC puts unlink() */
     25 # include <io.h>
     26 #else
     27 # include <unistd.h>
     28 #endif
     29 #include <errno.h>
     30 #include <math.h> /* for floor() */
     31 #include <stdio.h> /* for FILE et al. */
     32 #include <string.h> /* for strcmp() */
     33 #include "FLAC/all.h"
     34 #include "share/grabbag.h"
     35 #include "share/replaygain_synthesis.h"
     36 #include "decode.h"
     37 
     38 #ifdef FLAC__HAS_OGG
     39 #include "OggFLAC/file_decoder.h"
     40 #endif
     41 
     42 typedef struct {
     43 #ifdef FLAC__HAS_OGG
     44 	FLAC__bool is_ogg;
     45 #endif
     46 
     47 	FLAC__bool is_aiff_out;
     48 	FLAC__bool is_wave_out;
     49 	FLAC__bool continue_through_decode_errors;
     50 
     51 	struct {
     52 		replaygain_synthesis_spec_t spec;
     53 		FLAC__bool apply; /* 'spec.apply' is just a request; this 'apply' means we actually parsed the RG tags and are ready to go */
     54 		double scale;
     55 		DitherContext dither_context;
     56 	} replaygain;
     57 
     58 	FLAC__bool test_only;
     59 	FLAC__bool analysis_mode;
     60 	analysis_options aopts;
     61 	utils__SkipUntilSpecification *skip_specification;
     62 	utils__SkipUntilSpecification *until_specification; /* a canonicalized value of 0 mean end-of-stream (i.e. --until=-0) */
     63 	utils__CueSpecification *cue_specification;
     64 
     65 	const char *inbasefilename;
     66 	const char *outfilename;
     67 
     68 	FLAC__uint64 samples_processed;
     69 	unsigned frame_counter;
     70 	FLAC__bool abort_flag;
     71 	FLAC__bool aborting_due_to_until; /* true if we intentionally abort decoding prematurely because we hit the --until point */
     72 
     73 	struct {
     74 		FLAC__bool needs_fixup;
     75 		unsigned riff_offset; /* or FORM offset for AIFF */
     76 		unsigned data_offset; /* or SSND offset for AIFF */
     77 		unsigned frames_offset; /* AIFF only */
     78 	} wave_chunk_size_fixup;
     79 
     80 	FLAC__bool is_big_endian;
     81 	FLAC__bool is_unsigned_samples;
     82 	FLAC__uint64 total_samples;
     83 	unsigned bps;
     84 	unsigned channels;
     85 	unsigned sample_rate;
     86 
     87 	union {
     88 		union {
     89 			FLAC__FileDecoder *file;
     90 		} flac;
     91 #ifdef FLAC__HAS_OGG
     92 		union {
     93 			OggFLAC__FileDecoder *file;
     94 		} ogg;
     95 #endif
     96 	} decoder;
     97 
     98 	FILE *fout;
     99 } DecoderSession;
    100 
    101 
    102 static FLAC__bool is_big_endian_host_;
    103 
    104 
    105 /*
    106  * local routines
    107  */
    108 static FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__bool is_aiff_out, FLAC__bool is_wave_out, FLAC__bool continue_through_decode_errors, replaygain_synthesis_spec_t replaygain_synthesis_spec, FLAC__bool analysis_mode, analysis_options aopts, utils__SkipUntilSpecification *skip_specification, utils__SkipUntilSpecification *until_specification, utils__CueSpecification *cue_specification, const char *infilename, const char *outfilename);
    109 static void DecoderSession_destroy(DecoderSession *d, FLAC__bool error_occurred);
    110 static FLAC__bool DecoderSession_init_decoder(DecoderSession *d, decode_options_t decode_options, const char *infilename);
    111 static FLAC__bool DecoderSession_process(DecoderSession *d);
    112 static int DecoderSession_finish_ok(DecoderSession *d);
    113 static int DecoderSession_finish_error(DecoderSession *d);
    114 static FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input);
    115 static FLAC__bool write_necessary_headers(DecoderSession *decoder_session);
    116 static FLAC__bool write_little_endian_uint16(FILE *f, FLAC__uint16 val);
    117 static FLAC__bool write_little_endian_uint32(FILE *f, FLAC__uint32 val);
    118 static FLAC__bool write_big_endian_uint16(FILE *f, FLAC__uint16 val);
    119 static FLAC__bool write_big_endian_uint32(FILE *f, FLAC__uint32 val);
    120 static FLAC__bool write_sane_extended(FILE *f, unsigned val);
    121 static FLAC__bool fixup_wave_chunk_size(const char *outfilename, FLAC__bool is_wave_out, unsigned riff_offset, unsigned data_offset, unsigned frames_offset, FLAC__uint32 total_samples, unsigned channels, unsigned bps);
    122 /*
    123  * We use 'void *' so that we can use the same callbacks for the
    124  * FLAC__StreamDecoder and FLAC__FileDecoder.  The 'decoder' argument is
    125  * actually never used in the callbacks.
    126  */
    127 static FLAC__StreamDecoderWriteStatus write_callback(const void *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
    128 static void metadata_callback(const void *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
    129 static void error_callback(const void *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
    130 static void print_error_with_state(const DecoderSession *d, const char *message);
    131 static void print_stats(const DecoderSession *decoder_session);
    132 
    133 
    134 /*
    135  * public routines
    136  */
    137 int flac__decode_aiff(const char *infilename, const char *outfilename, FLAC__bool analysis_mode, analysis_options aopts, wav_decode_options_t options)
    138 {
    139 	DecoderSession decoder_session;
    140 
    141 	if(!
    142 		DecoderSession_construct(
    143 			&decoder_session,
    144 #ifdef FLAC__HAS_OGG
    145 			options.common.is_ogg,
    146 #else
    147 			/*is_ogg=*/false,
    148 #endif
    149 			/*is_aiff_out=*/true,
    150 			/*is_wave_out=*/false,
    151 			options.common.continue_through_decode_errors,
    152 			options.common.replaygain_synthesis_spec,
    153 			analysis_mode,
    154 			aopts,
    155 			&options.common.skip_specification,
    156 			&options.common.until_specification,
    157 			options.common.has_cue_specification? &options.common.cue_specification : 0,
    158 			infilename,
    159 			outfilename
    160 		)
    161 	)
    162 		return 1;
    163 
    164 	if(!DecoderSession_init_decoder(&decoder_session, options.common, infilename))
    165 		return DecoderSession_finish_error(&decoder_session);
    166 
    167 	if(!DecoderSession_process(&decoder_session))
    168 		return DecoderSession_finish_error(&decoder_session);
    169 
    170 	return DecoderSession_finish_ok(&decoder_session);
    171 }
    172 
    173 int flac__decode_wav(const char *infilename, const char *outfilename, FLAC__bool analysis_mode, analysis_options aopts, wav_decode_options_t options)
    174 {
    175 	DecoderSession decoder_session;
    176 
    177 	if(!
    178 		DecoderSession_construct(
    179 			&decoder_session,
    180 #ifdef FLAC__HAS_OGG
    181 			options.common.is_ogg,
    182 #else
    183 			/*is_ogg=*/false,
    184 #endif
    185 			/*is_aiff_out=*/false,
    186 			/*is_wave_out=*/true,
    187 			options.common.continue_through_decode_errors,
    188 			options.common.replaygain_synthesis_spec,
    189 			analysis_mode,
    190 			aopts,
    191 			&options.common.skip_specification,
    192 			&options.common.until_specification,
    193 			options.common.has_cue_specification? &options.common.cue_specification : 0,
    194 			infilename,
    195 			outfilename
    196 		)
    197 	)
    198 		return 1;
    199 
    200 	if(!DecoderSession_init_decoder(&decoder_session, options.common, infilename))
    201 		return DecoderSession_finish_error(&decoder_session);
    202 
    203 	if(!DecoderSession_process(&decoder_session))
    204 		return DecoderSession_finish_error(&decoder_session);
    205 
    206 	return DecoderSession_finish_ok(&decoder_session);
    207 }
    208 
    209 int flac__decode_raw(const char *infilename, const char *outfilename, FLAC__bool analysis_mode, analysis_options aopts, raw_decode_options_t options)
    210 {
    211 	DecoderSession decoder_session;
    212 
    213 	decoder_session.is_big_endian = options.is_big_endian;
    214 	decoder_session.is_unsigned_samples = options.is_unsigned_samples;
    215 
    216 	if(!
    217 		DecoderSession_construct(
    218 			&decoder_session,
    219 #ifdef FLAC__HAS_OGG
    220 			options.common.is_ogg,
    221 #else
    222 			/*is_ogg=*/false,
    223 #endif
    224 			/*is_aiff_out=*/false,
    225 			/*is_wave_out=*/false,
    226 			options.common.continue_through_decode_errors,
    227 			options.common.replaygain_synthesis_spec,
    228 			analysis_mode,
    229 			aopts,
    230 			&options.common.skip_specification,
    231 			&options.common.until_specification,
    232 			options.common.has_cue_specification? &options.common.cue_specification : 0,
    233 			infilename,
    234 			outfilename
    235 		)
    236 	)
    237 		return 1;
    238 
    239 	if(!DecoderSession_init_decoder(&decoder_session, options.common, infilename))
    240 		return DecoderSession_finish_error(&decoder_session);
    241 
    242 	if(!DecoderSession_process(&decoder_session))
    243 		return DecoderSession_finish_error(&decoder_session);
    244 
    245 	return DecoderSession_finish_ok(&decoder_session);
    246 }
    247 
    248 FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__bool is_aiff_out, FLAC__bool is_wave_out, FLAC__bool continue_through_decode_errors, replaygain_synthesis_spec_t replaygain_synthesis_spec, FLAC__bool analysis_mode, analysis_options aopts, utils__SkipUntilSpecification *skip_specification, utils__SkipUntilSpecification *until_specification, utils__CueSpecification *cue_specification, const char *infilename, const char *outfilename)
    249 {
    250 #ifdef FLAC__HAS_OGG
    251 	d->is_ogg = is_ogg;
    252 #else
    253 	(void)is_ogg;
    254 #endif
    255 
    256 	d->is_aiff_out = is_aiff_out;
    257 	d->is_wave_out = is_wave_out;
    258 	d->continue_through_decode_errors = continue_through_decode_errors;
    259 	d->replaygain.spec = replaygain_synthesis_spec;
    260 	d->replaygain.apply = false;
    261 	d->replaygain.scale = 0.0;
    262 	/* d->replaygain.dither_context gets initialized later once we know the sample resolution */
    263 	d->test_only = (0 == outfilename);
    264 	d->analysis_mode = analysis_mode;
    265 	d->aopts = aopts;
    266 	d->skip_specification = skip_specification;
    267 	d->until_specification = until_specification;
    268 	d->cue_specification = cue_specification;
    269 
    270 	d->inbasefilename = grabbag__file_get_basename(infilename);
    271 	d->outfilename = outfilename;
    272 
    273 	d->samples_processed = 0;
    274 	d->frame_counter = 0;
    275 	d->abort_flag = false;
    276 	d->aborting_due_to_until = false;
    277 
    278 	d->wave_chunk_size_fixup.needs_fixup = false;
    279 
    280 	d->decoder.flac.file = 0;
    281 #ifdef FLAC__HAS_OGG
    282 	d->decoder.ogg.file = 0;
    283 #endif
    284 
    285 	d->fout = 0; /* initialized with an open file later if necessary */
    286 
    287 	FLAC__ASSERT(!(d->test_only && d->analysis_mode));
    288 
    289 	if(!d->test_only) {
    290 		if(0 == strcmp(outfilename, "-")) {
    291 			d->fout = grabbag__file_get_binary_stdout();
    292 		}
    293 		else {
    294 			if(0 == (d->fout = fopen(outfilename, "wb"))) {
    295 				flac__utils_printf(stderr, 1, "%s: ERROR: can't open output file %s\n", d->inbasefilename, outfilename);
    296 				DecoderSession_destroy(d, /*error_occurred=*/true);
    297 				return false;
    298 			}
    299 		}
    300 	}
    301 
    302 	if(analysis_mode)
    303 		flac__analyze_init(aopts);
    304 
    305 	return true;
    306 }
    307 
    308 void DecoderSession_destroy(DecoderSession *d, FLAC__bool error_occurred)
    309 {
    310 	if(0 != d->fout && d->fout != stdout) {
    311 		fclose(d->fout);
    312 		if(error_occurred)
    313 			unlink(d->outfilename);
    314 	}
    315 }
    316 
    317 FLAC__bool DecoderSession_init_decoder(DecoderSession *decoder_session, decode_options_t decode_options, const char *infilename)
    318 {
    319 	FLAC__uint32 test = 1;
    320 
    321 	is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true;
    322 
    323 #ifdef FLAC__HAS_OGG
    324 	if(decoder_session->is_ogg) {
    325 		decoder_session->decoder.ogg.file = OggFLAC__file_decoder_new();
    326 
    327 		if(0 == decoder_session->decoder.ogg.file) {
    328 			flac__utils_printf(stderr, 1, "%s: ERROR creating the decoder instance\n", decoder_session->inbasefilename);
    329 			return false;
    330 		}
    331 
    332 		OggFLAC__file_decoder_set_md5_checking(decoder_session->decoder.ogg.file, true);
    333 		OggFLAC__file_decoder_set_filename(decoder_session->decoder.ogg.file, infilename);
    334 		if(!decode_options.use_first_serial_number)
    335 			OggFLAC__file_decoder_set_serial_number(decoder_session->decoder.ogg.file, decode_options.serial_number);
    336 		if (0 != decoder_session->cue_specification)
    337 			OggFLAC__file_decoder_set_metadata_respond(decoder_session->decoder.ogg.file, FLAC__METADATA_TYPE_CUESHEET);
    338 		if (decoder_session->replaygain.spec.apply)
    339 			OggFLAC__file_decoder_set_metadata_respond(decoder_session->decoder.ogg.file, FLAC__METADATA_TYPE_VORBIS_COMMENT);
    340 
    341 		/*
    342 		 * The three ugly casts here are to 'downcast' the 'void *' argument of
    343 		 * the callback down to 'OggFLAC__FileDecoder *'.  In C++ this would be
    344 		 * unnecessary but here the cast makes the C compiler happy.
    345 		 */
    346 		OggFLAC__file_decoder_set_write_callback(decoder_session->decoder.ogg.file, (FLAC__StreamDecoderWriteStatus (*)(const OggFLAC__FileDecoder *, const FLAC__Frame *, const FLAC__int32 * const [], void *))write_callback);
    347 		OggFLAC__file_decoder_set_metadata_callback(decoder_session->decoder.ogg.file, (void (*)(const OggFLAC__FileDecoder *, const FLAC__StreamMetadata *, void *))metadata_callback);
    348 		OggFLAC__file_decoder_set_error_callback(decoder_session->decoder.ogg.file, (void (*)(const OggFLAC__FileDecoder *, FLAC__StreamDecoderErrorStatus, void *))error_callback);
    349 		OggFLAC__file_decoder_set_client_data(decoder_session->decoder.ogg.file, decoder_session);
    350 
    351 		if(OggFLAC__file_decoder_init(decoder_session->decoder.ogg.file) != OggFLAC__FILE_DECODER_OK) {
    352 			print_error_with_state(decoder_session, "ERROR initializing decoder");
    353 			return false;
    354 		}
    355 	}
    356 	else
    357 #else
    358 	(void)decode_options;
    359 #endif
    360 	{
    361 		decoder_session->decoder.flac.file = FLAC__file_decoder_new();
    362 
    363 		if(0 == decoder_session->decoder.flac.file) {
    364 			flac__utils_printf(stderr, 1, "%s: ERROR creating the decoder instance\n", decoder_session->inbasefilename);
    365 			return false;
    366 		}
    367 
    368 		FLAC__file_decoder_set_md5_checking(decoder_session->decoder.flac.file, true);
    369 		FLAC__file_decoder_set_filename(decoder_session->decoder.flac.file, infilename);
    370 		if (0 != decoder_session->cue_specification)
    371 			FLAC__file_decoder_set_metadata_respond(decoder_session->decoder.flac.file, FLAC__METADATA_TYPE_CUESHEET);
    372 		if (decoder_session->replaygain.spec.apply)
    373 			FLAC__file_decoder_set_metadata_respond(decoder_session->decoder.flac.file, FLAC__METADATA_TYPE_VORBIS_COMMENT);
    374 		/*
    375 		 * The three ugly casts here are to 'downcast' the 'void *' argument of
    376 		 * the callback down to 'FLAC__FileDecoder *'.
    377 		 */
    378 		FLAC__file_decoder_set_write_callback(decoder_session->decoder.flac.file, (FLAC__StreamDecoderWriteStatus (*)(const FLAC__FileDecoder *, const FLAC__Frame *, const FLAC__int32 * const [], void *))write_callback);
    379 		FLAC__file_decoder_set_metadata_callback(decoder_session->decoder.flac.file, (void (*)(const FLAC__FileDecoder *, const FLAC__StreamMetadata *, void *))metadata_callback);
    380 		FLAC__file_decoder_set_error_callback(decoder_session->decoder.flac.file, (void (*)(const FLAC__FileDecoder *, FLAC__StreamDecoderErrorStatus, void *))error_callback);
    381 		FLAC__file_decoder_set_client_data(decoder_session->decoder.flac.file, decoder_session);
    382 
    383 		if(FLAC__file_decoder_init(decoder_session->decoder.flac.file) != FLAC__FILE_DECODER_OK) {
    384 			print_error_with_state(decoder_session, "ERROR initializing decoder");
    385 			return false;
    386 		}
    387 	}
    388 
    389 	return true;
    390 }
    391 
    392 FLAC__bool DecoderSession_process(DecoderSession *d)
    393 {
    394 #ifdef FLAC__HAS_OGG
    395 	if(d->is_ogg) {
    396 		if(!OggFLAC__file_decoder_process_until_end_of_metadata(d->decoder.ogg.file)) {
    397 			flac__utils_printf(stderr, 2, "\n");
    398 			print_error_with_state(d, "ERROR while decoding metadata");
    399 			return false;
    400 		}
    401 		if(OggFLAC__file_decoder_get_state(d->decoder.ogg.file) != OggFLAC__FILE_DECODER_OK && OggFLAC__file_decoder_get_state(d->decoder.ogg.file) != OggFLAC__FILE_DECODER_END_OF_FILE) {
    402 			flac__utils_printf(stderr, 2, "\n");
    403 			print_error_with_state(d, "ERROR during metadata decoding");
    404 			return false;
    405 		}
    406 	}
    407 	else
    408 #endif
    409 	{
    410 		if(!FLAC__file_decoder_process_until_end_of_metadata(d->decoder.flac.file)) {
    411 			flac__utils_printf(stderr, 2, "\n");
    412 			print_error_with_state(d, "ERROR while decoding metadata");
    413 			return false;
    414 		}
    415 		if(FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_OK && FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_END_OF_FILE) {
    416 			flac__utils_printf(stderr, 2, "\n");
    417 			print_error_with_state(d, "ERROR during metadata decoding");
    418 			return false;
    419 		}
    420 	}
    421 	if(d->abort_flag)
    422 		return false;
    423 
    424 	/* write the WAVE/AIFF headers if necessary */
    425 	if(!write_necessary_headers(d)) {
    426 		d->abort_flag = true;
    427 		return false;
    428 	}
    429 
    430 	if(d->skip_specification->value.samples > 0) {
    431 		const FLAC__uint64 skip = (FLAC__uint64)d->skip_specification->value.samples;
    432 
    433 #ifdef FLAC__HAS_OGG
    434 		if(d->is_ogg) {
    435 			if(!OggFLAC__file_decoder_seek_absolute(d->decoder.ogg.file, skip)) {
    436 				print_error_with_state(d, "ERROR seeking while skipping bytes");
    437 				return false;
    438 			}
    439 			if(!OggFLAC__file_decoder_process_until_end_of_file(d->decoder.ogg.file) && !d->aborting_due_to_until) {
    440 				flac__utils_printf(stderr, 2, "\n");
    441 				print_error_with_state(d, "ERROR while decoding frames");
    442 				return false;
    443 			}
    444 			if(OggFLAC__file_decoder_get_state(d->decoder.ogg.file) != OggFLAC__FILE_DECODER_OK && OggFLAC__file_decoder_get_state(d->decoder.ogg.file) != OggFLAC__FILE_DECODER_END_OF_FILE && !d->aborting_due_to_until) {
    445 				flac__utils_printf(stderr, 2, "\n");
    446 				print_error_with_state(d, "ERROR during decoding");
    447 				return false;
    448 			}
    449 		}
    450 		else
    451 #endif
    452 		{
    453 			if(!FLAC__file_decoder_seek_absolute(d->decoder.flac.file, skip)) {
    454 				print_error_with_state(d, "ERROR seeking while skipping bytes");
    455 				return false;
    456 			}
    457 			if(!FLAC__file_decoder_process_until_end_of_file(d->decoder.flac.file) && !d->aborting_due_to_until) {
    458 				flac__utils_printf(stderr, 2, "\n");
    459 				print_error_with_state(d, "ERROR while decoding frames");
    460 				return false;
    461 			}
    462 			if(FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_OK && FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_END_OF_FILE && !d->aborting_due_to_until) {
    463 				flac__utils_printf(stderr, 2, "\n");
    464 				print_error_with_state(d, "ERROR during decoding");
    465 				return false;
    466 			}
    467 		}
    468 	}
    469 	else {
    470 #ifdef FLAC__HAS_OGG
    471 		if(d->is_ogg) {
    472 			if(!OggFLAC__file_decoder_process_until_end_of_file(d->decoder.ogg.file) && !d->aborting_due_to_until) {
    473 				flac__utils_printf(stderr, 2, "\n");
    474 				print_error_with_state(d, "ERROR while decoding data");
    475 				return false;
    476 			}
    477 			if(OggFLAC__file_decoder_get_state(d->decoder.ogg.file) != OggFLAC__FILE_DECODER_OK && OggFLAC__file_decoder_get_state(d->decoder.ogg.file) != OggFLAC__FILE_DECODER_END_OF_FILE && !d->aborting_due_to_until) {
    478 				flac__utils_printf(stderr, 2, "\n");
    479 				print_error_with_state(d, "ERROR during decoding");
    480 				return false;
    481 			}
    482 		}
    483 		else
    484 #endif
    485 		{
    486 			if(!FLAC__file_decoder_process_until_end_of_file(d->decoder.flac.file) && !d->aborting_due_to_until) {
    487 				flac__utils_printf(stderr, 2, "\n");
    488 				print_error_with_state(d, "ERROR while decoding data");
    489 				return false;
    490 			}
    491 			if(FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_OK && FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_END_OF_FILE && !d->aborting_due_to_until) {
    492 				flac__utils_printf(stderr, 2, "\n");
    493 				print_error_with_state(d, "ERROR during decoding");
    494 				return false;
    495 			}
    496 		}
    497 	}
    498 
    499 	if((d->is_wave_out || d->is_aiff_out) && ((d->total_samples * d->channels * ((d->bps+7)/8)) & 1)) {
    500 		if(flac__utils_fwrite("\000", 1, 1, d->fout) != 1) {
    501 			print_error_with_state(d, d->is_wave_out?
    502 				"ERROR writing pad byte to WAVE data chunk" :
    503 				"ERROR writing pad byte to AIFF SSND chunk"
    504 			);
    505 			return false;
    506 		}
    507 	}
    508 
    509 	return true;
    510 }
    511 
    512 int DecoderSession_finish_ok(DecoderSession *d)
    513 {
    514 	FLAC__bool md5_failure = false;
    515 
    516 #ifdef FLAC__HAS_OGG
    517 	if(d->is_ogg) {
    518 		if(d->decoder.ogg.file) {
    519 			md5_failure = !OggFLAC__file_decoder_finish(d->decoder.ogg.file) && !d->aborting_due_to_until;
    520 			print_stats(d);
    521 			OggFLAC__file_decoder_delete(d->decoder.ogg.file);
    522 		}
    523 	}
    524 	else
    525 #endif
    526 	{
    527 		if(d->decoder.flac.file) {
    528 			md5_failure = !FLAC__file_decoder_finish(d->decoder.flac.file) && !d->aborting_due_to_until;
    529 			print_stats(d);
    530 			FLAC__file_decoder_delete(d->decoder.flac.file);
    531 		}
    532 	}
    533 	if(d->analysis_mode)
    534 		flac__analyze_finish(d->aopts);
    535 	if(md5_failure) {
    536 		flac__utils_printf(stderr, 1, "\r%s: WARNING, MD5 signature mismatch\n", d->inbasefilename);
    537 	}
    538 	else {
    539 		flac__utils_printf(stderr, 2, "\r%s: %s         \n", d->inbasefilename, d->test_only? "ok           ":d->analysis_mode?"done           ":"done");
    540 	}
    541 	DecoderSession_destroy(d, /*error_occurred=*/false);
    542 	if((d->is_wave_out || d->is_aiff_out) && d->wave_chunk_size_fixup.needs_fixup)
    543 		if(!fixup_wave_chunk_size(d->outfilename, d->is_wave_out, d->wave_chunk_size_fixup.riff_offset, d->wave_chunk_size_fixup.data_offset, d->wave_chunk_size_fixup.frames_offset, (FLAC__uint32)d->samples_processed, d->channels, d->bps))
    544 			return 1;
    545 	return 0;
    546 }
    547 
    548 int DecoderSession_finish_error(DecoderSession *d)
    549 {
    550 #ifdef FLAC__HAS_OGG
    551 	if(d->is_ogg) {
    552 		if(d->decoder.ogg.file) {
    553 			OggFLAC__file_decoder_finish(d->decoder.ogg.file);
    554 			OggFLAC__file_decoder_delete(d->decoder.ogg.file);
    555 		}
    556 	}
    557 	else
    558 #endif
    559 	{
    560 		if(d->decoder.flac.file) {
    561 			FLAC__file_decoder_finish(d->decoder.flac.file);
    562 			FLAC__file_decoder_delete(d->decoder.flac.file);
    563 		}
    564 	}
    565 	if(d->analysis_mode)
    566 		flac__analyze_finish(d->aopts);
    567 	DecoderSession_destroy(d, /*error_occurred=*/true);
    568 	return 1;
    569 }
    570 
    571 FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input)
    572 {
    573 	/* convert from mm:ss.sss to sample number if necessary */
    574 	flac__utils_canonicalize_skip_until_specification(spec, sample_rate);
    575 
    576 	/* special case: if "--until=-0", use the special value '0' to mean "end-of-stream" */
    577 	if(spec->is_relative && spec->value.samples == 0) {
    578 		spec->is_relative = false;
    579 		return true;
    580 	}
    581 
    582 	/* in any other case the total samples in the input must be known */
    583 	if(total_samples_in_input == 0) {
    584 		flac__utils_printf(stderr, 1, "%s: ERROR, cannot use --until when FLAC metadata has total sample count of 0\n", inbasefilename);
    585 		return false;
    586 	}
    587 
    588 	FLAC__ASSERT(spec->value_is_samples);
    589 
    590 	/* convert relative specifications to absolute */
    591 	if(spec->is_relative) {
    592 		if(spec->value.samples <= 0)
    593 			spec->value.samples += (FLAC__int64)total_samples_in_input;
    594 		else
    595 			spec->value.samples += skip;
    596 		spec->is_relative = false;
    597 	}
    598 
    599 	/* error check */
    600 	if(spec->value.samples < 0) {
    601 		flac__utils_printf(stderr, 1, "%s: ERROR, --until value is before beginning of input\n", inbasefilename);
    602 		return false;
    603 	}
    604 	if((FLAC__uint64)spec->value.samples <= skip) {
    605 		flac__utils_printf(stderr, 1, "%s: ERROR, --until value is before --skip point\n", inbasefilename);
    606 		return false;
    607 	}
    608 	if((FLAC__uint64)spec->value.samples > total_samples_in_input) {
    609 		flac__utils_printf(stderr, 1, "%s: ERROR, --until value is after end of input\n", inbasefilename);
    610 		return false;
    611 	}
    612 
    613 	return true;
    614 }
    615 
    616 FLAC__bool write_necessary_headers(DecoderSession *decoder_session)
    617 {
    618 	/* write the WAVE/AIFF headers if necessary */
    619 	if(!decoder_session->analysis_mode && !decoder_session->test_only && (decoder_session->is_wave_out || decoder_session->is_aiff_out)) {
    620 		const char *fmt_desc = decoder_session->is_wave_out? "WAVE" : "AIFF";
    621 		FLAC__uint64 data_size = decoder_session->total_samples * decoder_session->channels * ((decoder_session->bps+7)/8);
    622 		const FLAC__uint32 aligned_data_size = (FLAC__uint32)((data_size+1) & (~1U)); /* we'll check for overflow later */
    623 		if(decoder_session->total_samples == 0) {
    624 			if(decoder_session->fout == stdout) {
    625 				flac__utils_printf(stderr, 1, "%s: WARNING, don't have accurate sample count available for %s header.\n", decoder_session->inbasefilename, fmt_desc);
    626 				flac__utils_printf(stderr, 1, "             Generated %s file will have a data chunk size of 0.  Try\n", fmt_desc);
    627 				flac__utils_printf(stderr, 1, "             decoding directly to a file instead.\n");
    628 			}
    629 			else {
    630 				decoder_session->wave_chunk_size_fixup.needs_fixup = true;
    631 			}
    632 		}
    633 		if(data_size >= 0xFFFFFFDC) {
    634 			flac__utils_printf(stderr, 1, "%s: ERROR: stream is too big to fit in a single %s file chunk\n", decoder_session->inbasefilename, fmt_desc);
    635 			return false;
    636 		}
    637 		if(decoder_session->is_wave_out) {
    638 			if(flac__utils_fwrite("RIFF", 1, 4, decoder_session->fout) != 4)
    639 				return false;
    640 
    641 			if(decoder_session->wave_chunk_size_fixup.needs_fixup)
    642 				decoder_session->wave_chunk_size_fixup.riff_offset = ftell(decoder_session->fout);
    643 
    644 			if(!write_little_endian_uint32(decoder_session->fout, aligned_data_size+36)) /* filesize-8 */
    645 				return false;
    646 
    647 			if(flac__utils_fwrite("WAVEfmt ", 1, 8, decoder_session->fout) != 8)
    648 				return false;
    649 
    650 			if(flac__utils_fwrite("\020\000\000\000", 1, 4, decoder_session->fout) != 4) /* chunk size = 16 */
    651 				return false;
    652 
    653 			if(flac__utils_fwrite("\001\000", 1, 2, decoder_session->fout) != 2) /* compression code == 1 */
    654 				return false;
    655 
    656 			if(!write_little_endian_uint16(decoder_session->fout, (FLAC__uint16)(decoder_session->channels)))
    657 				return false;
    658 
    659 			if(!write_little_endian_uint32(decoder_session->fout, decoder_session->sample_rate))
    660 				return false;
    661 
    662 			if(!write_little_endian_uint32(decoder_session->fout, decoder_session->sample_rate * decoder_session->channels * ((decoder_session->bps+7) / 8))) /* @@@ or is it (sample_rate*channels*bps) / 8 ??? */
    663 				return false;
    664 
    665 			if(!write_little_endian_uint16(decoder_session->fout, (FLAC__uint16)(decoder_session->channels * ((decoder_session->bps+7) / 8)))) /* block align */
    666 				return false;
    667 
    668 			if(!write_little_endian_uint16(decoder_session->fout, (FLAC__uint16)(decoder_session->bps))) /* bits per sample */
    669 				return false;
    670 
    671 			if(flac__utils_fwrite("data", 1, 4, decoder_session->fout) != 4)
    672 				return false;
    673 
    674 			if(decoder_session->wave_chunk_size_fixup.needs_fixup)
    675 				decoder_session->wave_chunk_size_fixup.data_offset = ftell(decoder_session->fout);
    676 
    677 			if(!write_little_endian_uint32(decoder_session->fout, (FLAC__uint32)data_size)) /* data size */
    678 				return false;
    679 		}
    680 		else {
    681 			if(flac__utils_fwrite("FORM", 1, 4, decoder_session->fout) != 4)
    682 				return false;
    683 
    684 			if(decoder_session->wave_chunk_size_fixup.needs_fixup)
    685 				decoder_session->wave_chunk_size_fixup.riff_offset = ftell(decoder_session->fout);
    686 
    687 			if(!write_big_endian_uint32(decoder_session->fout, aligned_data_size+46)) /* filesize-8 */
    688 				return false;
    689 
    690 			if(flac__utils_fwrite("AIFFCOMM", 1, 8, decoder_session->fout) != 8)
    691 				return false;
    692 
    693 			if(flac__utils_fwrite("\000\000\000\022", 1, 4, decoder_session->fout) != 4) /* chunk size = 18 */
    694 				return false;
    695 
    696 			if(!write_big_endian_uint16(decoder_session->fout, (FLAC__uint16)(decoder_session->channels)))
    697 				return false;
    698 
    699 			if(decoder_session->wave_chunk_size_fixup.needs_fixup)
    700 				decoder_session->wave_chunk_size_fixup.frames_offset = ftell(decoder_session->fout);
    701 
    702 			if(!write_big_endian_uint32(decoder_session->fout, (FLAC__uint32)decoder_session->total_samples))
    703 				return false;
    704 
    705 			if(!write_big_endian_uint16(decoder_session->fout, (FLAC__uint16)(decoder_session->bps)))
    706 				return false;
    707 
    708 			if(!write_sane_extended(decoder_session->fout, decoder_session->sample_rate))
    709 				return false;
    710 
    711 			if(flac__utils_fwrite("SSND", 1, 4, decoder_session->fout) != 4)
    712 				return false;
    713 
    714 			if(decoder_session->wave_chunk_size_fixup.needs_fixup)
    715 				decoder_session->wave_chunk_size_fixup.data_offset = ftell(decoder_session->fout);
    716 
    717 			if(!write_big_endian_uint32(decoder_session->fout, (FLAC__uint32)data_size+8)) /* data size */
    718 				return false;
    719 
    720 			if(!write_big_endian_uint32(decoder_session->fout, 0/*offset*/))
    721 				return false;
    722 
    723 			if(!write_big_endian_uint32(decoder_session->fout, 0/*block_size*/))
    724 				return false;
    725 		}
    726 	}
    727 
    728 	return true;
    729 }
    730 
    731 FLAC__bool write_little_endian_uint16(FILE *f, FLAC__uint16 val)
    732 {
    733 	FLAC__byte *b = (FLAC__byte*)(&val);
    734 	if(is_big_endian_host_) {
    735 		FLAC__byte tmp;
    736 		tmp = b[1]; b[1] = b[0]; b[0] = tmp;
    737 	}
    738 	return flac__utils_fwrite(b, 1, 2, f) == 2;
    739 }
    740 
    741 FLAC__bool write_little_endian_uint32(FILE *f, FLAC__uint32 val)
    742 {
    743 	FLAC__byte *b = (FLAC__byte*)(&val);
    744 	if(is_big_endian_host_) {
    745 		FLAC__byte tmp;
    746 		tmp = b[3]; b[3] = b[0]; b[0] = tmp;
    747 		tmp = b[2]; b[2] = b[1]; b[1] = tmp;
    748 	}
    749 	return flac__utils_fwrite(b, 1, 4, f) == 4;
    750 }
    751 
    752 FLAC__bool write_big_endian_uint16(FILE *f, FLAC__uint16 val)
    753 {
    754 	FLAC__byte *b = (FLAC__byte*)(&val);
    755 	if(!is_big_endian_host_) {
    756 		FLAC__byte tmp;
    757 		tmp = b[1]; b[1] = b[0]; b[0] = tmp;
    758 	}
    759 	return flac__utils_fwrite(b, 1, 2, f) == 2;
    760 }
    761 
    762 FLAC__bool write_big_endian_uint32(FILE *f, FLAC__uint32 val)
    763 {
    764 	FLAC__byte *b = (FLAC__byte*)(&val);
    765 	if(!is_big_endian_host_) {
    766 		FLAC__byte tmp;
    767 		tmp = b[3]; b[3] = b[0]; b[0] = tmp;
    768 		tmp = b[2]; b[2] = b[1]; b[1] = tmp;
    769 	}
    770 	return flac__utils_fwrite(b, 1, 4, f) == 4;
    771 }
    772 
    773 FLAC__bool write_sane_extended(FILE *f, unsigned val)
    774 	/* Write to 'f' a SANE extended representation of 'val'.  Return false if
    775 	* the write succeeds; return true otherwise.
    776 	*
    777 	* SANE extended is an 80-bit IEEE-754 representation with sign bit, 15 bits
    778 	* of exponent, and 64 bits of significand (mantissa).  Unlike most IEEE-754
    779 	* representations, it does not imply a 1 above the MSB of the significand.
    780 	*
    781 	* Preconditions:
    782 	*  val!=0U
    783 	*/
    784 {
    785 	unsigned int shift, exponent;
    786 
    787 	FLAC__ASSERT(val!=0U); /* handling 0 would require a special case */
    788 
    789 	for(shift= 0U; (val>>(31-shift))==0U; ++shift)
    790 		;
    791 	val<<= shift;
    792 	exponent= 63U-(shift+32U); /* add 32 for unused second word */
    793 
    794 	if(!write_big_endian_uint16(f, (FLAC__uint16)(exponent+0x3FFF)))
    795 		return false;
    796 	if(!write_big_endian_uint32(f, val))
    797 		return false;
    798 	if(!write_big_endian_uint32(f, 0)) /* unused second word */
    799 		return false;
    800 
    801 	return true;
    802 }
    803 
    804 FLAC__bool fixup_wave_chunk_size(const char *outfilename, FLAC__bool is_wave_out, unsigned riff_offset, unsigned data_offset, unsigned frames_offset, FLAC__uint32 total_samples, unsigned channels, unsigned bps)
    805 {
    806 	const char *fmt_desc = (is_wave_out? "WAVE" : "AIFF");
    807 	FLAC__bool (*write_it)(FILE *, FLAC__uint32) = (is_wave_out? write_little_endian_uint32 : write_big_endian_uint32);
    808 	FILE *f = fopen(outfilename, "r+b");
    809 	FLAC__uint32 data_size, aligned_data_size;
    810 
    811 	if(0 == f) {
    812 		flac__utils_printf(stderr, 1, "ERROR, couldn't open file %s while fixing up %s chunk size\n", outfilename, fmt_desc);
    813 		return false;
    814 	}
    815 
    816 	data_size = aligned_data_size = total_samples * channels * ((bps+7)/8);
    817 	if(aligned_data_size & 1)
    818 		aligned_data_size++;
    819 
    820 	if(fseek(f, riff_offset, SEEK_SET) < 0) {
    821 		flac__utils_printf(stderr, 1, "ERROR, couldn't seek in file %s while fixing up %s chunk size\n", outfilename, fmt_desc);
    822 		fclose(f);
    823 		return false;
    824 	}
    825 	if(!write_it(f, aligned_data_size + (is_wave_out? 36 : 46))) {
    826 		flac__utils_printf(stderr, 1, "ERROR, couldn't write size in file %s while fixing up %s chunk size\n", outfilename, fmt_desc);
    827 		fclose(f);
    828 		return false;
    829 	}
    830 	if(!is_wave_out) {
    831 		if(fseek(f, frames_offset, SEEK_SET) < 0) {
    832 			flac__utils_printf(stderr, 1, "ERROR, couldn't seek in file %s while fixing up %s chunk size\n", outfilename, fmt_desc);
    833 			fclose(f);
    834 			return false;
    835 		}
    836 		if(!write_it(f, total_samples)) {
    837 			flac__utils_printf(stderr, 1, "ERROR, couldn't write size in file %s while fixing up %s chunk size\n", outfilename, fmt_desc);
    838 			fclose(f);
    839 			return false;
    840 		}
    841 	}
    842 	if(fseek(f, data_offset, SEEK_SET) < 0) {
    843 		flac__utils_printf(stderr, 1, "ERROR, couldn't seek in file %s while fixing up %s chunk size\n", outfilename, fmt_desc);
    844 		fclose(f);
    845 		return false;
    846 	}
    847 	if(!write_it(f, data_size + (is_wave_out? 0 : 8))) {
    848 		flac__utils_printf(stderr, 1, "ERROR, couldn't write size in file %s while fixing up %s chunk size\n", outfilename, fmt_desc);
    849 		fclose(f);
    850 		return false;
    851 	}
    852 	fclose(f);
    853 	return true;
    854 }
    855 
    856 FLAC__StreamDecoderWriteStatus write_callback(const void *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
    857 {
    858 	DecoderSession *decoder_session = (DecoderSession*)client_data;
    859 	FILE *fout = decoder_session->fout;
    860 	const unsigned bps = frame->header.bits_per_sample, channels = frame->header.channels;
    861 	FLAC__bool is_big_endian = (decoder_session->is_aiff_out? true : (decoder_session->is_wave_out? false : decoder_session->is_big_endian));
    862 	FLAC__bool is_unsigned_samples = (decoder_session->is_aiff_out? false : (decoder_session->is_wave_out? bps<=8 : decoder_session->is_unsigned_samples));
    863 	unsigned wide_samples = frame->header.blocksize, wide_sample, sample, channel, byte;
    864 	static FLAC__int8 s8buffer[FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS * sizeof(FLAC__int32)]; /* WATCHOUT: can be up to 2 megs */
    865 	FLAC__uint8  *u8buffer  = (FLAC__uint8  *)s8buffer;
    866 	FLAC__int16  *s16buffer = (FLAC__int16  *)s8buffer;
    867 	FLAC__uint16 *u16buffer = (FLAC__uint16 *)s8buffer;
    868 	FLAC__int32  *s32buffer = (FLAC__int32  *)s8buffer;
    869 	FLAC__uint32 *u32buffer = (FLAC__uint32 *)s8buffer;
    870 	size_t bytes_to_write = 0;
    871 
    872 	(void)decoder;
    873 
    874 	if(decoder_session->abort_flag)
    875 		return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
    876 
    877 	if(bps != decoder_session->bps) {
    878 		flac__utils_printf(stderr, 1, "%s: ERROR, bits-per-sample is %u in frame but %u in STREAMINFO\n", decoder_session->inbasefilename, bps, decoder_session->bps);
    879 		return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
    880 	}
    881 	if(channels != decoder_session->channels) {
    882 		flac__utils_printf(stderr, 1, "%s: ERROR, channels is %u in frame but %u in STREAMINFO\n", decoder_session->inbasefilename, channels, decoder_session->channels);
    883 		return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
    884 	}
    885 	if(frame->header.sample_rate != decoder_session->sample_rate) {
    886 		flac__utils_printf(stderr, 1, "%s: ERROR, sample rate is %u in frame but %u in STREAMINFO\n", decoder_session->inbasefilename, frame->header.sample_rate, decoder_session->sample_rate);
    887 		return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
    888 	}
    889 
    890 	/*
    891 	 * limit the number of samples to accept based on --until
    892 	 */
    893 	FLAC__ASSERT(!decoder_session->skip_specification->is_relative);
    894 	FLAC__ASSERT(decoder_session->skip_specification->value.samples >= 0);
    895 	FLAC__ASSERT(!decoder_session->until_specification->is_relative);
    896 	FLAC__ASSERT(decoder_session->until_specification->value.samples >= 0);
    897 	if(decoder_session->until_specification->value.samples > 0) {
    898 		const FLAC__uint64 skip = (FLAC__uint64)decoder_session->skip_specification->value.samples;
    899 		const FLAC__uint64 until = (FLAC__uint64)decoder_session->until_specification->value.samples;
    900 		const FLAC__uint64 input_samples_passed = skip + decoder_session->samples_processed;
    901 		FLAC__ASSERT(until >= input_samples_passed);
    902 		if(input_samples_passed + wide_samples > until)
    903 			wide_samples = (unsigned)(until - input_samples_passed);
    904 		if (wide_samples == 0) {
    905 			decoder_session->abort_flag = true;
    906 			decoder_session->aborting_due_to_until = true;
    907 			return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
    908 		}
    909 	}
    910 
    911 	if(wide_samples > 0) {
    912 		decoder_session->samples_processed += wide_samples;
    913 		decoder_session->frame_counter++;
    914 
    915 		if(!(decoder_session->frame_counter & 0x3f))
    916 			print_stats(decoder_session);
    917 
    918 		if(decoder_session->analysis_mode) {
    919 			flac__analyze_frame(frame, decoder_session->frame_counter-1, decoder_session->aopts, fout);
    920 		}
    921 		else if(!decoder_session->test_only) {
    922 			if (decoder_session->replaygain.apply) {
    923 				bytes_to_write = FLAC__replaygain_synthesis__apply_gain(
    924 					u8buffer,
    925 					!is_big_endian,
    926 					is_unsigned_samples,
    927 					buffer,
    928 					wide_samples,
    929 					channels,
    930 					bps, /* source_bps */
    931 					bps, /* target_bps */
    932 					decoder_session->replaygain.scale,
    933 					decoder_session->replaygain.spec.limiter == RGSS_LIMIT__HARD, /* hard_limit */
    934 					decoder_session->replaygain.spec.noise_shaping != NOISE_SHAPING_NONE, /* do_dithering */
    935 					&decoder_session->replaygain.dither_context
    936 				);
    937 			}
    938 			else if(bps == 8) {
    939 				if(is_unsigned_samples) {
    940 					for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
    941 						for(channel = 0; channel < channels; channel++, sample++)
    942 							u8buffer[sample] = (FLAC__uint8)(buffer[channel][wide_sample] + 0x80);
    943 				}
    944 				else {
    945 					for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
    946 						for(channel = 0; channel < channels; channel++, sample++)
    947 							s8buffer[sample] = (FLAC__int8)(buffer[channel][wide_sample]);
    948 				}
    949 				bytes_to_write = sample;
    950 			}
    951 			else if(bps == 16) {
    952 				if(is_unsigned_samples) {
    953 					for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
    954 						for(channel = 0; channel < channels; channel++, sample++)
    955 							u16buffer[sample] = (FLAC__uint16)(buffer[channel][wide_sample] + 0x8000);
    956 				}
    957 				else {
    958 					for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
    959 						for(channel = 0; channel < channels; channel++, sample++)
    960 							s16buffer[sample] = (FLAC__int16)(buffer[channel][wide_sample]);
    961 				}
    962 				if(is_big_endian != is_big_endian_host_) {
    963 					unsigned char tmp;
    964 					const unsigned bytes = sample * 2;
    965 					for(byte = 0; byte < bytes; byte += 2) {
    966 						tmp = u8buffer[byte];
    967 						u8buffer[byte] = u8buffer[byte+1];
    968 						u8buffer[byte+1] = tmp;
    969 					}
    970 				}
    971 				bytes_to_write = 2 * sample;
    972 			}
    973 			else if(bps == 24) {
    974 				if(is_unsigned_samples) {
    975 					for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
    976 						for(channel = 0; channel < channels; channel++, sample++)
    977 							u32buffer[sample] = buffer[channel][wide_sample] + 0x800000;
    978 				}
    979 				else {
    980 					for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
    981 						for(channel = 0; channel < channels; channel++, sample++)
    982 							s32buffer[sample] = buffer[channel][wide_sample];
    983 				}
    984 				if(is_big_endian != is_big_endian_host_) {
    985 					unsigned char tmp;
    986 					const unsigned bytes = sample * 4;
    987 					for(byte = 0; byte < bytes; byte += 4) {
    988 						tmp = u8buffer[byte];
    989 						u8buffer[byte] = u8buffer[byte+3];
    990 						u8buffer[byte+3] = tmp;
    991 						tmp = u8buffer[byte+1];
    992 						u8buffer[byte+1] = u8buffer[byte+2];
    993 						u8buffer[byte+2] = tmp;
    994 					}
    995 				}
    996 				if(is_big_endian) {
    997 					unsigned lbyte;
    998 					const unsigned bytes = sample * 4;
    999 					for(lbyte = byte = 0; byte < bytes; ) {
   1000 						byte++;
   1001 						u8buffer[lbyte++] = u8buffer[byte++];
   1002 						u8buffer[lbyte++] = u8buffer[byte++];
   1003 						u8buffer[lbyte++] = u8buffer[byte++];
   1004 					}
   1005 				}
   1006 				else {
   1007 					unsigned lbyte;
   1008 					const unsigned bytes = sample * 4;
   1009 					for(lbyte = byte = 0; byte < bytes; ) {
   1010 						u8buffer[lbyte++] = u8buffer[byte++];
   1011 						u8buffer[lbyte++] = u8buffer[byte++];
   1012 						u8buffer[lbyte++] = u8buffer[byte++];
   1013 						byte++;
   1014 					}
   1015 				}
   1016 				bytes_to_write = 3 * sample;
   1017 			}
   1018 			else {
   1019 				FLAC__ASSERT(0);
   1020 			}
   1021 		}
   1022 	}
   1023 	if(bytes_to_write > 0) {
   1024 		if(flac__utils_fwrite(u8buffer, 1, bytes_to_write, fout) != bytes_to_write) {
   1025 			/* if a pipe closed when writing to stdout, we let it go without an error message */
   1026 			if(errno == EPIPE && decoder_session->fout == stdout)
   1027 				decoder_session->aborting_due_to_until = true;
   1028 			decoder_session->abort_flag = true;
   1029 			return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
   1030 		}
   1031 	}
   1032 	return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
   1033 }
   1034 
   1035 void metadata_callback(const void *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
   1036 {
   1037 	DecoderSession *decoder_session = (DecoderSession*)client_data;
   1038 	(void)decoder;
   1039 	if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
   1040 		FLAC__uint64 skip, until;
   1041 		decoder_session->bps = metadata->data.stream_info.bits_per_sample;
   1042 		decoder_session->channels = metadata->data.stream_info.channels;
   1043 		decoder_session->sample_rate = metadata->data.stream_info.sample_rate;
   1044 
   1045 		flac__utils_canonicalize_skip_until_specification(decoder_session->skip_specification, decoder_session->sample_rate);
   1046 		FLAC__ASSERT(decoder_session->skip_specification->value.samples >= 0);
   1047 		skip = (FLAC__uint64)decoder_session->skip_specification->value.samples;
   1048 
   1049 		/* remember, metadata->data.stream_info.total_samples can be 0, meaning 'unknown' */
   1050 		if(metadata->data.stream_info.total_samples > 0 && skip >= metadata->data.stream_info.total_samples) {
   1051 			flac__utils_printf(stderr, 1, "%s: ERROR trying to --skip more samples than in stream\n", decoder_session->inbasefilename);
   1052 			decoder_session->abort_flag = true;
   1053 			return;
   1054 		}
   1055 		else if(metadata->data.stream_info.total_samples == 0 && skip > 0) {
   1056 			flac__utils_printf(stderr, 1, "%s: ERROR, can't --skip when FLAC metadata has total sample count of 0\n", decoder_session->inbasefilename);
   1057 			decoder_session->abort_flag = true;
   1058 			return;
   1059 		}
   1060 		FLAC__ASSERT(skip == 0 || 0 == decoder_session->cue_specification);
   1061 		decoder_session->total_samples = metadata->data.stream_info.total_samples - skip;
   1062 
   1063 		/* note that we use metadata->data.stream_info.total_samples instead of decoder_session->total_samples */
   1064 		if(!canonicalize_until_specification(decoder_session->until_specification, decoder_session->inbasefilename, decoder_session->sample_rate, skip, metadata->data.stream_info.total_samples)) {
   1065 			decoder_session->abort_flag = true;
   1066 			return;
   1067 		}
   1068 		FLAC__ASSERT(decoder_session->until_specification->value.samples >= 0);
   1069 		until = (FLAC__uint64)decoder_session->until_specification->value.samples;
   1070 
   1071 		if(until > 0) {
   1072 			FLAC__ASSERT(decoder_session->total_samples != 0);
   1073 			FLAC__ASSERT(0 == decoder_session->cue_specification);
   1074 			decoder_session->total_samples -= (metadata->data.stream_info.total_samples - until);
   1075 		}
   1076 
   1077 		if(decoder_session->bps != 8 && decoder_session->bps != 16 && decoder_session->bps != 24) {
   1078 			flac__utils_printf(stderr, 1, "%s: ERROR: bits per sample is not 8/16/24\n", decoder_session->inbasefilename);
   1079 			decoder_session->abort_flag = true;
   1080 			return;
   1081 		}
   1082 	}
   1083 	else if(metadata->type == FLAC__METADATA_TYPE_CUESHEET) {
   1084 		/* remember, at this point, decoder_session->total_samples can be 0, meaning 'unknown' */
   1085 		if(decoder_session->total_samples == 0) {
   1086 			flac__utils_printf(stderr, 1, "%s: ERROR can't use --cue when FLAC metadata has total sample count of 0\n", decoder_session->inbasefilename);
   1087 			decoder_session->abort_flag = true;
   1088 			return;
   1089 		}
   1090 
   1091 		flac__utils_canonicalize_cue_specification(decoder_session->cue_specification, &metadata->data.cue_sheet, decoder_session->total_samples, decoder_session->skip_specification, decoder_session->until_specification);
   1092 
   1093 		FLAC__ASSERT(!decoder_session->skip_specification->is_relative);
   1094 		FLAC__ASSERT(decoder_session->skip_specification->value_is_samples);
   1095 
   1096 		FLAC__ASSERT(!decoder_session->until_specification->is_relative);
   1097 		FLAC__ASSERT(decoder_session->until_specification->value_is_samples);
   1098 
   1099 		FLAC__ASSERT(decoder_session->skip_specification->value.samples >= 0);
   1100 		FLAC__ASSERT(decoder_session->until_specification->value.samples >= 0);
   1101 		FLAC__ASSERT((FLAC__uint64)decoder_session->until_specification->value.samples <= decoder_session->total_samples);
   1102 		FLAC__ASSERT(decoder_session->skip_specification->value.samples <= decoder_session->until_specification->value.samples);
   1103 
   1104 		decoder_session->total_samples = decoder_session->until_specification->value.samples - decoder_session->skip_specification->value.samples;
   1105 	}
   1106 	else if(metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
   1107 		if (decoder_session->replaygain.spec.apply) {
   1108 			double gain, peak;
   1109 			if (!(decoder_session->replaygain.apply = grabbag__replaygain_load_from_vorbiscomment(metadata, decoder_session->replaygain.spec.use_album_gain, &gain, &peak))) {
   1110 				flac__utils_printf(stderr, 1, "%s: WARNING: can't get %s ReplayGain tag\n", decoder_session->inbasefilename, decoder_session->replaygain.spec.use_album_gain? "album":"track");
   1111 			}
   1112 			else {
   1113 				const char *ls[] = { "no", "peak", "hard" };
   1114 				const char *ns[] = { "no", "low", "medium", "high" };
   1115 				decoder_session->replaygain.scale = grabbag__replaygain_compute_scale_factor(peak, gain, decoder_session->replaygain.spec.preamp, decoder_session->replaygain.spec.limiter == RGSS_LIMIT__PEAK);
   1116 				FLAC__ASSERT(decoder_session->bps > 0 && decoder_session->bps <= 32);
   1117 				FLAC__replaygain_synthesis__init_dither_context(&decoder_session->replaygain.dither_context, decoder_session->bps, decoder_session->replaygain.spec.noise_shaping);
   1118 				flac__utils_printf(stderr, 1, "%s: INFO: applying %s ReplayGain (gain=%0.2fdB+preamp=%0.1fdB, %s noise shaping, %s limiting) to output\n", decoder_session->inbasefilename, decoder_session->replaygain.spec.use_album_gain? "album":"track", gain, decoder_session->replaygain.spec.preamp, ns[decoder_session->replaygain.spec.noise_shaping], ls[decoder_session->replaygain.spec.limiter]);
   1119 				flac__utils_printf(stderr, 1, "%s: WARNING: applying ReplayGain is not lossless\n", decoder_session->inbasefilename);
   1120 			}
   1121 		}
   1122 	}
   1123 }
   1124 
   1125 void error_callback(const void *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
   1126 {
   1127 	DecoderSession *decoder_session = (DecoderSession*)client_data;
   1128 	(void)decoder;
   1129 	flac__utils_printf(stderr, 1, "%s: *** Got error code %d:%s\n", decoder_session->inbasefilename, status, FLAC__StreamDecoderErrorStatusString[status]);
   1130 	if(!decoder_session->continue_through_decode_errors)
   1131 		decoder_session->abort_flag = true;
   1132 }
   1133 
   1134 void print_error_with_state(const DecoderSession *d, const char *message)
   1135 {
   1136 	const int ilen = strlen(d->inbasefilename) + 1;
   1137 	const char *state_string;
   1138 
   1139 	flac__utils_printf(stderr, 1, "\n%s: %s\n", d->inbasefilename, message);
   1140 
   1141 #ifdef FLAC__HAS_OGG
   1142 	if(d->is_ogg) {
   1143 		state_string = OggFLAC__file_decoder_get_resolved_state_string(d->decoder.ogg.file);
   1144 	}
   1145 	else
   1146 #endif
   1147 	{
   1148 		state_string = FLAC__file_decoder_get_resolved_state_string(d->decoder.flac.file);
   1149 	}
   1150 
   1151 	flac__utils_printf(stderr, 1, "%*s state = %s\n", ilen, "", state_string);
   1152 
   1153 	/* print out some more info for some errors: */
   1154 	if (0 == strcmp(state_string, FLAC__StreamDecoderStateString[FLAC__STREAM_DECODER_UNPARSEABLE_STREAM])) {
   1155 		flac__utils_printf(stderr, 1,
   1156 			"\n"
   1157 			"The FLAC stream may have been created by a more advanced encoder.  Try\n"
   1158 			"  metaflac --show-vendor-tag %s\n"
   1159 			"If the version number is greater than %s, this decoder is probably\n"
   1160 			"not able to decode the file.  If the version number is not, the file\n"
   1161 			"may be corrupted, or you may have found a bug.  In this case please\n"
   1162 			"submit a bug report to\n"
   1163 			"    http://sourceforge.net/bugs/?func=addbug&group_id=13478\n"
   1164 			"Make sure to include an email contact in the comment and/or use the\n"
   1165 			"\"Monitor\" feature to monitor the bug status.\n",
   1166 			d->inbasefilename, FLAC__VERSION_STRING
   1167 		);
   1168 	}
   1169 	else if (
   1170 		0 == strcmp(state_string, FLAC__FileDecoderStateString[FLAC__FILE_DECODER_ERROR_OPENING_FILE])
   1171 #ifdef FLAC__HAS_OGG
   1172 		|| 0 == strcmp(state_string, OggFLAC__FileDecoderStateString[OggFLAC__FILE_DECODER_ERROR_OPENING_FILE])
   1173 #endif
   1174 	) {
   1175 		flac__utils_printf(stderr, 1,
   1176 			"\n"
   1177 			"An error occurred opening the input file; it is likely that it does not exist\n"
   1178 			"or is not readable.\n"
   1179 		);
   1180 	}
   1181 }
   1182 
   1183 void print_stats(const DecoderSession *decoder_session)
   1184 {
   1185 	if(flac__utils_verbosity_ >= 2) {
   1186 #if defined _MSC_VER || defined __MINGW32__
   1187 		/* with MSVC you have to spoon feed it the casting */
   1188 		const double progress = (double)(FLAC__int64)decoder_session->samples_processed / (double)(FLAC__int64)decoder_session->total_samples * 100.0;
   1189 #else
   1190 		const double progress = (double)decoder_session->samples_processed / (double)decoder_session->total_samples * 100.0;
   1191 #endif
   1192 		if(decoder_session->total_samples > 0) {
   1193 			fprintf(stderr, "\r%s: %s%u%% complete",
   1194 				decoder_session->inbasefilename,
   1195 				decoder_session->test_only? "testing, " : decoder_session->analysis_mode? "analyzing, " : "",
   1196 				(unsigned)floor(progress + 0.5)
   1197 			);
   1198 		}
   1199 		else {
   1200 			fprintf(stderr, "\r%s: %s %u samples",
   1201 				decoder_session->inbasefilename,
   1202 				decoder_session->test_only? "tested" : decoder_session->analysis_mode? "analyzed" : "wrote",
   1203 				(unsigned)decoder_session->samples_processed
   1204 			);
   1205 		}
   1206 	}
   1207 }