massive changes to command line parsing to act like gzip

This commit is contained in:
Josh Coalson
2001-05-01 23:47:02 +00:00
parent b472e26067
commit bae9ce56f1
3 changed files with 333 additions and 229 deletions

View File

@@ -111,24 +111,24 @@ int decode_wav(const char *infile, const char *outfile, bool analysis_mode, anal
goto wav_abort_;
}
if(!FLAC__file_decoder_process_remaining_frames(decoder)) {
if(verbose) { printf("\n"); fflush(stdout); }
if(verbose) fprintf(stderr, "\n");
fprintf(stderr, "%s: ERROR while decoding frames, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
goto wav_abort_;
}
if(decoder->state != FLAC__FILE_DECODER_OK && decoder->state != FLAC__FILE_DECODER_END_OF_FILE) {
if(verbose) { printf("\n"); fflush(stdout); }
if(verbose) fprintf(stderr, "\n");
fprintf(stderr, "%s: ERROR during decoding, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
goto wav_abort_;
}
}
else {
if(!FLAC__file_decoder_process_whole_file(decoder)) {
if(verbose) { printf("\n"); fflush(stdout); }
if(verbose) fprintf(stderr, "\n");
fprintf(stderr, "%s: ERROR while decoding data, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
goto wav_abort_;
}
if(decoder->state != FLAC__FILE_DECODER_OK && decoder->state != FLAC__FILE_DECODER_END_OF_FILE) {
if(verbose) { printf("\n"); fflush(stdout); }
if(verbose) fprintf(stderr, "\n");
fprintf(stderr, "%s: ERROR during decoding, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
goto wav_abort_;
}
@@ -143,8 +143,7 @@ int decode_wav(const char *infile, const char *outfile, bool analysis_mode, anal
if(!stream_info.test_only)
fclose(stream_info.fout);
if(verbose)
printf("\n");
fflush(stdout);
fprintf(stderr, "\n");
if(analysis_mode)
analyze_finish(aopts);
if(md5_failure) {
@@ -153,7 +152,7 @@ int decode_wav(const char *infile, const char *outfile, bool analysis_mode, anal
}
else {
if(stream_info.test_only)
printf("%s: ok\n", infile);
fprintf(stderr, "%s: ok\n", infile);
}
return 0;
wav_abort_:
@@ -224,24 +223,24 @@ int decode_raw(const char *infile, const char *outfile, bool analysis_mode, anal
goto raw_abort_;
}
if(!FLAC__file_decoder_process_remaining_frames(decoder)) {
if(verbose) { printf("\n"); fflush(stdout); }
if(verbose) fprintf(stderr, "\n");
fprintf(stderr, "%s: ERROR while decoding frames, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
goto raw_abort_;
}
if(decoder->state != FLAC__FILE_DECODER_OK && decoder->state != FLAC__FILE_DECODER_END_OF_FILE) {
if(verbose) { printf("\n"); fflush(stdout); }
if(verbose) fprintf(stderr, "\n");
fprintf(stderr, "%s: ERROR during decoding, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
goto raw_abort_;
}
}
else {
if(!FLAC__file_decoder_process_whole_file(decoder)) {
if(verbose) { printf("\n"); fflush(stdout); }
if(verbose) fprintf(stderr, "\n");
fprintf(stderr, "%s: ERROR while decoding data, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
goto raw_abort_;
}
if(decoder->state != FLAC__FILE_DECODER_OK && decoder->state != FLAC__FILE_DECODER_END_OF_FILE) {
if(verbose) { printf("\n"); fflush(stdout); }
if(verbose) fprintf(stderr, "\n");
fprintf(stderr, "%s: ERROR during decoding, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
goto raw_abort_;
}
@@ -256,8 +255,7 @@ int decode_raw(const char *infile, const char *outfile, bool analysis_mode, anal
if(!stream_info.test_only)
fclose(stream_info.fout);
if(verbose)
printf("\n");
fflush(stdout);
fprintf(stderr, "\n");
if(analysis_mode)
analyze_finish(aopts);
if(md5_failure) {
@@ -266,7 +264,7 @@ int decode_raw(const char *infile, const char *outfile, bool analysis_mode, anal
}
else {
if(stream_info.test_only)
printf("%s: ok\n", infile);
fprintf(stderr, "%s: ok\n", infile);
}
return 0;
raw_abort_:
@@ -504,17 +502,24 @@ void error_callback(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorSt
void print_stats(const stream_info_struct *stream_info)
{
if(stream_info->verbose) {
printf("\r%s %u of %u samples, %6.2f%% complete",
stream_info->test_only? "tested" : stream_info->analysis_mode? "analyzed" : "wrote",
(unsigned)stream_info->samples_processed,
(unsigned)stream_info->total_samples,
if(stream_info->total_samples > 0) {
fprintf(stderr, "\r%s %u of %u samples, %6.2f%% complete",
stream_info->test_only? "tested" : stream_info->analysis_mode? "analyzed" : "wrote",
(unsigned)stream_info->samples_processed,
(unsigned)stream_info->total_samples,
#ifdef _MSC_VER
/* with VC++ you have to spoon feed it the casting */
(double)(int64)stream_info->samples_processed / (double)(int64)stream_info->total_samples * 100.0
/* with VC++ you have to spoon feed it the casting */
(double)(int64)stream_info->samples_processed / (double)(int64)stream_info->total_samples * 100.0
#else
(double)stream_info->samples_processed / (double)stream_info->total_samples * 100.0
(double)stream_info->samples_processed / (double)stream_info->total_samples * 100.0
#endif
);
fflush(stdout);
);
}
else {
fprintf(stderr, "\r%s %u of ? samples, ?%% complete",
stream_info->test_only? "tested" : stream_info->analysis_mode? "analyzed" : "wrote",
(unsigned)stream_info->samples_processed
);
}
}
}

View File

@@ -296,17 +296,17 @@ wav_end_:
}
if(encoder_wrapper.verbose && encoder_wrapper.total_samples_to_encode > 0) {
print_stats(&encoder_wrapper);
printf("\n");
fprintf(stderr, "\n");
}
if(0 != encoder_wrapper.seek_table.points)
free(encoder_wrapper.seek_table.points);
if(verify) {
if(encoder_wrapper.verify_fifo.result != FLAC__VERIFY_OK) {
fprintf(stderr, "Verify FAILED! (%s) Do not use %s\n", verify_code_string[encoder_wrapper.verify_fifo.result], outfilename);
fprintf(stderr, "%s: Verify FAILED! (%s) Do not use %s\n", infilename, verify_code_string[encoder_wrapper.verify_fifo.result], outfilename);
return 1;
}
else {
fprintf(stderr, "Verify succeeded\n");
else if(encoder_wrapper.verbose) {
fprintf(stderr, "%s: Verify succeeded\n", infilename);
}
}
if(infile != stdin)
@@ -314,7 +314,7 @@ wav_end_:
return 0;
wav_abort_:
if(encoder_wrapper.verbose && encoder_wrapper.total_samples_to_encode > 0)
printf("\n");
fprintf(stderr, "\n");
if(encoder_wrapper.encoder) {
if(encoder_wrapper.encoder->state == FLAC__ENCODER_OK)
FLAC__encoder_finish(encoder_wrapper.encoder);
@@ -324,11 +324,11 @@ wav_abort_:
free(encoder_wrapper.seek_table.points);
if(verify) {
if(encoder_wrapper.verify_fifo.result != FLAC__VERIFY_OK) {
fprintf(stderr, "Verify FAILED! (%s) Do not use %s\n", verify_code_string[encoder_wrapper.verify_fifo.result], outfilename);
fprintf(stderr, "%s: Verify FAILED! (%s) Do not use %s\n", infilename, verify_code_string[encoder_wrapper.verify_fifo.result], outfilename);
return 1;
}
else {
fprintf(stderr, "Verify succeeded\n");
else if(encoder_wrapper.verbose) {
fprintf(stderr, "%s: Verify succeeded\n", infilename);
}
}
if(infile != stdin)
@@ -383,7 +383,7 @@ int encode_raw(FILE *infile, const char *infilename, const char *outfilename, bo
}
if(encoder_wrapper.verbose && encoder_wrapper.total_samples_to_encode <= 0)
printf("(No runtime statistics possible; please wait for encoding to finish...)\n");
fprintf(stderr, "(No runtime statistics possible; please wait for encoding to finish...)\n");
if(skip > 0) {
if(infile != stdin) {
@@ -444,17 +444,17 @@ int encode_raw(FILE *infile, const char *infilename, const char *outfilename, bo
}
if(encoder_wrapper.verbose && encoder_wrapper.total_samples_to_encode > 0) {
print_stats(&encoder_wrapper);
printf("\n");
fprintf(stderr, "\n");
}
if(0 != encoder_wrapper.seek_table.points)
free(encoder_wrapper.seek_table.points);
if(verify) {
if(encoder_wrapper.verify_fifo.result != FLAC__VERIFY_OK) {
fprintf(stderr, "Verify FAILED! (%s) Do not use %s\n", verify_code_string[encoder_wrapper.verify_fifo.result], outfilename);
fprintf(stderr, "%s: Verify FAILED! (%s) Do not use %s\n", infilename, verify_code_string[encoder_wrapper.verify_fifo.result], outfilename);
return 1;
}
else {
fprintf(stderr, "Verify succeeded\n");
else if(encoder_wrapper.verbose) {
fprintf(stderr, "%s: Verify succeeded\n", infilename);
}
}
if(infile != stdin)
@@ -462,7 +462,7 @@ int encode_raw(FILE *infile, const char *infilename, const char *outfilename, bo
return 0;
raw_abort_:
if(encoder_wrapper.verbose && encoder_wrapper.total_samples_to_encode > 0)
printf("\n");
fprintf(stderr, "\n");
if(encoder_wrapper.encoder) {
if(encoder_wrapper.encoder->state == FLAC__ENCODER_OK)
FLAC__encoder_finish(encoder_wrapper.encoder);
@@ -472,11 +472,11 @@ raw_abort_:
free(encoder_wrapper.seek_table.points);
if(verify) {
if(encoder_wrapper.verify_fifo.result != FLAC__VERIFY_OK) {
fprintf(stderr, "Verify FAILED! (%s) Do not use %s\n", verify_code_string[encoder_wrapper.verify_fifo.result], outfilename);
fprintf(stderr, "%s: Verify FAILED! (%s) Do not use %s\n", infilename, verify_code_string[encoder_wrapper.verify_fifo.result], outfilename);
return 1;
}
else {
fprintf(stderr, "Verify succeeded\n");
else if(encoder_wrapper.verbose) {
fprintf(stderr, "%s: Verify succeeded\n", infilename);
}
}
if(infile != stdin)
@@ -979,7 +979,7 @@ void print_stats(const encoder_wrapper_struct *encoder_wrapper)
#else
double progress = (double)encoder_wrapper->samples_written / (double)encoder_wrapper->total_samples_to_encode;
#endif
printf("\r%0.2f%% complete: frame %u, wrote %u bytes, %u of %u samples, ratio = %5.3f",
fprintf(stderr, "\r%0.2f%% complete: frame %u, wrote %u bytes, %u of %u samples, ratio = %5.3f",
progress * 100.0, encoder_wrapper->current_frame,
(unsigned)encoder_wrapper->bytes_written, (unsigned)encoder_wrapper->samples_written, (unsigned)encoder_wrapper->total_samples_to_encode,
#ifdef _MSC_VER
@@ -989,7 +989,6 @@ void print_stats(const encoder_wrapper_struct *encoder_wrapper)
(double)encoder_wrapper->bytes_written / ((double)encoder_wrapper->unencoded_size * progress)
#endif
);
fflush(stdout);
}
bool read_little_endian_uint16(FILE *f, uint16 *val, bool eof_ok)

View File

@@ -28,23 +28,27 @@
#include "encode.h"
static int usage(const char *message, ...);
static int encode_file(const char *infilename, const char *forced_outfilename);
static int decode_file(const char *infilename, const char *forced_outfilename);
bool verify = false, verbose = true, lax = false, test_only = false, analyze = false;
bool do_mid_side = true, loose_mid_side = false, do_exhaustive_model_search = false, do_qlp_coeff_prec_search = false;
bool force_to_stdout = false;
analysis_options aopts = { false, false };
unsigned padding = 0;
unsigned max_lpc_order = 8;
unsigned qlp_coeff_precision = 0;
uint64 skip = 0;
int format_is_wave = -1, format_is_big_endian = -1, format_is_unsigned_samples = false;
int format_channels = -1, format_bps = -1, format_sample_rate = -1;
int blocksize = -1, min_residual_partition_order = -1, max_residual_partition_order = -1, rice_parameter_search_dist = -1;
char requested_seek_points[50000]; /* @@@ bad MAGIC NUMBER */
int num_requested_seek_points = -1; /* -1 => no -S options were given, 0 => -S- was given */
int main(int argc, char *argv[])
{
int i;
bool verify = false, verbose = true, lax = false, mode_decode = false, test_only = false, analyze = false;
bool do_mid_side = true, loose_mid_side = false, do_exhaustive_model_search = false, do_qlp_coeff_prec_search = false;
analysis_options aopts = { false, false };
unsigned padding = 0;
unsigned max_lpc_order = 8;
unsigned qlp_coeff_precision = 0;
uint64 skip = 0;
int format_is_wave = -1, format_is_big_endian = -1, format_is_unsigned_samples = false;
int format_channels = -1, format_bps = -1, format_sample_rate = -1;
int blocksize = -1, min_residual_partition_order = -1, max_residual_partition_order = -1, rice_parameter_search_dist = -1;
char requested_seek_points[50000]; /* @@@ bad MAGIC NUMBER */
int num_requested_seek_points = -1; /* -1 => no -S options were given, 0 => -S- was given */
FILE *encode_infile = 0;
int i, retval = 0;
bool mode_decode = false;
if(argc <= 1)
return usage(0);
@@ -63,6 +67,8 @@ int main(int argc, char *argv[])
mode_decode = true;
test_only = true;
}
else if(0 == strcmp(argv[i], "-c"))
force_to_stdout = true;
else if(0 == strcmp(argv[i], "-s"))
verbose = false;
else if(0 == strcmp(argv[i], "-s-"))
@@ -226,50 +232,9 @@ int main(int argc, char *argv[])
return usage("ERROR: invalid option '%s'\n", argv[i]);
}
}
if(i + (test_only? 1:2) != argc)
return usage("ERROR: invalid arguments (more/less than %d filename%s?)\n", (test_only? 1:2), (test_only? "":"s"));
/* tweak options based on the filenames; validate the values */
/* tweak options; validate the values */
if(!mode_decode) {
if(0 == strcmp(argv[i], "-")) {
encode_infile = stdin;
}
else {
if(0 == (encode_infile = fopen(argv[i], "rb"))) {
fprintf(stderr, "ERROR: can't open input file %s\n", argv[i]);
return 1;
}
}
if(format_is_wave < 0) {
/* lamely attempt to guess the file type based on the first 4 bytes (which is all ungetc will guarantee us) */
char head[4];
int h, n;
/* first set format based on name */
if(strstr(argv[i], ".wav") == argv[i] + (strlen(argv[i]) - strlen(".wav")))
format_is_wave = true;
else
format_is_wave = false;
if((n = fread(head, 1, 4, encode_infile)) < 4) {
if(format_is_wave)
fprintf(stderr, "WARNING: %s is not a WAVE file, treating as a raw file\n", argv[i]);
format_is_wave = false;
}
else {
if(strncmp(head, "RIFF", 4)) {
if(format_is_wave)
fprintf(stderr, "WARNING: %s is not a WAVE file, treating as a raw file\n", argv[i]);
format_is_wave = false;
}
else
format_is_wave = true;
}
for(h = n-1; h >= 0; h--)
ungetc(head[h], encode_infile);
}
if(!format_is_wave) {
if(format_is_big_endian < 0 || format_channels < 0 || format_bps < 0 || format_sample_rate < 0)
return usage("ERROR: for encoding a raw file you must specify { -fb or -fl }, -fc, -fp, and -fs\n");
}
if(blocksize < 0) {
if(max_lpc_order == 0)
blocksize = 1152;
@@ -292,21 +257,9 @@ int main(int argc, char *argv[])
}
}
else {
if(test_only) {
if(test_only || analyze) {
if(skip > 0)
return usage("ERROR: --skip is not allowed in test mode\n");
}
else if(!analyze) {
if(format_is_wave < 0) {
if(strstr(argv[i+1], ".wav") == argv[i+1] + (strlen(argv[i+1]) - strlen(".wav")))
format_is_wave = true;
else
format_is_wave = false;
}
if(!format_is_wave) {
if(format_is_big_endian < 0)
return usage("ERROR: for decoding to a raw file you must specify -fb or -fl\n");
}
return usage("ERROR: --skip is not allowed in %s mode\n", test_only? "test":"analysis");
}
}
@@ -331,18 +284,14 @@ int main(int argc, char *argv[])
return usage("ERROR: invalid value for -q '%u', must be 0 or >= %u\n", qlp_coeff_precision, FLAC__MIN_QLP_COEFF_PRECISION);
}
/* turn off verbosity if the output stream is going to stdout */
if(!test_only && 0 == strcmp(argv[i+1], "-"))
verbose = false;
if(verbose) {
printf("\n");
printf("flac %s, Copyright (C) 2000,2001 Josh Coalson\n", FLAC__VERSION_STRING);
printf("flac comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n");
printf("welcome to redistribute it under certain conditions. Type `flac' for details.\n\n");
fprintf(stderr, "\n");
fprintf(stderr, "flac %s, Copyright (C) 2000,2001 Josh Coalson\n", FLAC__VERSION_STRING);
fprintf(stderr, "flac comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n");
fprintf(stderr, "welcome to redistribute it under certain conditions. Type `flac' for details.\n\n");
if(!mode_decode) {
printf("options:%s -P %u -b %u%s -l %u%s%s -q %u -r %u,%u -R %u%s\n",
fprintf(stderr, "options:%s -P %u -b %u%s -l %u%s%s -q %u -r %u,%u -R %u%s\n",
lax?" --lax":"", padding, (unsigned)blocksize, loose_mid_side?" -M":do_mid_side?" -m":"", max_lpc_order,
do_exhaustive_model_search?" -e":"", do_qlp_coeff_prec_search?" -p":"",
qlp_coeff_precision,
@@ -352,18 +301,46 @@ int main(int argc, char *argv[])
}
}
if(mode_decode)
if(format_is_wave)
return decode_wav(argv[i], test_only? 0 : argv[i+1], analyze, aopts, verbose, skip);
else
return decode_raw(argv[i], test_only? 0 : argv[i+1], analyze, aopts, verbose, skip, format_is_big_endian, format_is_unsigned_samples);
else
if(format_is_wave)
return encode_wav(encode_infile, argv[i], argv[i+1], verbose, skip, verify, lax, do_mid_side, loose_mid_side, do_exhaustive_model_search, do_qlp_coeff_prec_search, min_residual_partition_order, max_residual_partition_order, rice_parameter_search_dist, max_lpc_order, (unsigned)blocksize, qlp_coeff_precision, padding, requested_seek_points, num_requested_seek_points);
else
return encode_raw(encode_infile, argv[i], argv[i+1], verbose, skip, verify, lax, do_mid_side, loose_mid_side, do_exhaustive_model_search, do_qlp_coeff_prec_search, min_residual_partition_order, max_residual_partition_order, rice_parameter_search_dist, max_lpc_order, (unsigned)blocksize, qlp_coeff_precision, padding, requested_seek_points, num_requested_seek_points, format_is_big_endian, format_is_unsigned_samples, format_channels, format_bps, format_sample_rate);
if(mode_decode) {
bool first = true;
int save_format;
return 0;
if(i == argc)
retval = decode_file("-", 0);
else if(i + 2 == argc && 0 == strcmp(argv[i], "-"))
retval = decode_file("-", argv[i+1]);
else {
for(retval = 0; i < argc && retval == 0; i++) {
if(0 == strcmp(argv[i], "-") && !first)
continue;
save_format = format_is_wave;
retval = decode_file(argv[i], 0);
format_is_wave = save_format;
first = false;
}
}
}
else { /* encode */
bool first = true;
int save_format;
if(i == argc)
retval = encode_file("-", 0);
else if(i + 2 == argc && 0 == strcmp(argv[i], "-"))
retval = encode_file("-", argv[i+1]);
else {
for(retval = 0; i < argc && retval == 0; i++) {
if(0 == strcmp(argv[i], "-") && !first)
continue;
save_format = format_is_wave;
retval = encode_file(argv[i], 0);
format_is_wave = save_format;
first = false;
}
}
}
return retval;
}
int usage(const char *message, ...)
@@ -378,102 +355,225 @@ int usage(const char *message, ...)
va_end(args);
}
printf("==============================================================================\n");
printf("flac - Command-line FLAC encoder/decoder version %s\n", FLAC__VERSION_STRING);
printf("Copyright (C) 2000,2001 Josh Coalson\n");
printf("\n");
printf("This program is free software; you can redistribute it and/or\n");
printf("modify it under the terms of the GNU General Public License\n");
printf("as published by the Free Software Foundation; either version 2\n");
printf("of the License, or (at your option) any later version.\n");
printf("\n");
printf("This program is distributed in the hope that it will be useful,\n");
printf("but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");
printf("GNU General Public License for more details.\n");
printf("\n");
printf("You should have received a copy of the GNU General Public License\n");
printf("along with this program; if not, write to the Free Software\n");
printf("Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n");
printf("==============================================================================\n");
printf("Usage:\n");
printf(" flac [options] infile outfile\n");
printf("\n");
printf("For encoding:\n");
printf(" infile may be a PCM RIFF WAVE file or raw samples\n");
printf(" outfile will be in FLAC format\n");
printf("For decoding, the reverse is be true\n");
printf("\n");
printf("infile may be - for stdin, outfile may be - for stdout\n");
printf("\n");
printf("If the unencoded filename ends with '.wav' or -fw is used, it's assumed to be\n");
printf("RIFF WAVE. Otherwise, it's assumed to be raw samples and you have to specify\n");
printf("all the format options. You can force a .wav file to be treated as a raw file\n");
printf("using -fr.\n");
printf("\n");
printf("generic options:\n");
printf(" -d : decode (default behavior is encode)\n");
printf(" -t : test (same as -d except no decoded file is written)\n");
printf(" -a : analyze (same as -d except an analysis file is written)\n");
printf(" -s : silent (do not write runtime encode/decode statistics to stdout)\n");
printf(" --skip samples : can be used both for encoding and decoding\n");
printf("analyze options:\n");
printf(" --a-rtext : include residual signal in text output\n");
printf(" --a-rgp : generate gnuplot files of residual distribution of each subframe\n");
printf("encoding options:\n");
printf(" --lax : allow encoder to generate non-Subset files\n");
printf(" -S { # | X | #x } : include a point or points in a SEEKTABLE\n");
printf(" # : a specific sample number for a seek point\n");
printf(" X : a placeholder point (always goes at the end of the SEEKTABLE)\n");
printf(" #x : # evenly spaced seekpoints, the first being at sample 0\n");
printf(" You may use many -S options; the resulting SEEKTABLE will be the unique-\n");
printf(" ified union of all such values.\n");
printf(" With no -S options, flac defaults to '-S 100x'. Use -S- for no SEEKTABLE.\n");
printf(" Note: -S #x will not work if the encoder can't determine the input size\n");
printf(" before starting.\n");
printf(" Note: if you use -S # and # is >= samples in the input, there will be\n");
printf(" either no seek point entered (if the input size is determinable\n");
printf(" before encoding starts) or a placeholder point (if input size is not\n");
printf(" determinable)\n");
printf(" -P # : write a PADDING block of # bytes (goes after SEEKTABLE)\n");
printf(" (0 => no PADDING block, default is -P 0)\n");
printf(" -b # : specify blocksize in samples; default is 1152 for -l 0, else 4608;\n");
printf(" must be 192/576/1152/2304/4608/256/512/1024/2048/4096/8192/16384/32768\n");
printf(" (unless --lax is used)\n");
printf(" -m : try mid-side coding for each frame (stereo input only)\n");
printf(" -M : loose mid-side coding for all frames (stereo input only)\n");
printf(" -0 .. -9 : fastest compression .. highest compression, default is -6\n");
printf(" these are synonyms for other options:\n");
printf(" -0 : synonymous with -l 0 -b 1152\n");
printf(" -1 : synonymous with -l 0 -b 1152 -M\n");
printf(" -2 : synonymous with -l 0 -b 1152 -m -r 4\n");
printf(" -3 : reserved\n");
printf(" -4 : synonymous with -l 8 -b 4608 \n");
printf(" -5 : synonymous with -l 8 -b 4608 -M\n");
printf(" -6 : synonymous with -l 8 -b 4608 -m -r 4\n");
printf(" -7 : reserved\n");
printf(" -8 : synonymous with -l 32 -b 4608 -m -r 4\n");
printf(" -9 : synonymous with -l 32 -m -e -r 16 -R 32 -p (very slow!)\n");
printf(" -e : do exhaustive model search (expensive!)\n");
printf(" -l # : specify max LPC order; 0 => use only fixed predictors\n");
printf(" -p : do exhaustive search of LP coefficient quantization (expensive!);\n");
printf(" overrides -q, does nothing if using -l 0\n");
printf(" -q # : specify precision in bits of quantized linear-predictor coefficients;\n");
printf(" 0 => let encoder decide (min is %u, default is -q 0)\n", FLAC__MIN_QLP_COEFF_PRECISION);
printf(" -r [#,]# : [min,]max residual partition order (# is 0..16; min defaults to 0;\n");
printf(" default is -r 0; above 4 doesn't usually help much)\n");
printf(" -R # : Rice parameter search distance (# is 0..32; above 2 doesn't help much\n");
printf(" -V : verify a correct encoding by decoding the output in parallel and\n");
printf(" comparing to the original\n");
printf(" -S-, -m-, -M-, -e-, -p-, -V-, --lax- can all be used to turn off a particular\n");
printf(" option\n");
printf("format options:\n");
printf(" -fb | -fl : big-endian | little-endian byte order\n");
printf(" -fc channels\n");
printf(" -fp bits_per_sample\n");
printf(" -fs sample_rate : in Hz\n");
printf(" -fu : unsigned samples (default is signed)\n");
printf(" -fr : force to raw format (even if filename ends in .wav)\n");
printf(" -fw : force to RIFF WAVE\n");
fprintf(stderr, "===============================================================================\n");
fprintf(stderr, "flac - Command-line FLAC encoder/decoder version %s\n", FLAC__VERSION_STRING);
fprintf(stderr, "Copyright (C) 2000,2001 Josh Coalson\n");
fprintf(stderr, "\n");
fprintf(stderr, "This program is free software; you can redistribute it and/or\n");
fprintf(stderr, "modify it under the terms of the GNU General Public License\n");
fprintf(stderr, "as published by the Free Software Foundation; either version 2\n");
fprintf(stderr, "of the License, or (at your option) any later version.\n");
fprintf(stderr, "\n");
fprintf(stderr, "This program is distributed in the hope that it will be useful,\n");
fprintf(stderr, "but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
fprintf(stderr, "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");
fprintf(stderr, "GNU General Public License for more details.\n");
fprintf(stderr, "\n");
fprintf(stderr, "You should have received a copy of the GNU General Public License\n");
fprintf(stderr, "along with this program; if not, write to the Free Software\n");
fprintf(stderr, "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n");
fprintf(stderr, "===============================================================================\n");
fprintf(stderr, "Usage:\n");
fprintf(stderr, " flac [options] [infile [...]]\n");
fprintf(stderr, "\n");
fprintf(stderr, "For encoding:\n");
fprintf(stderr, " the input file(s) may be a PCM RIFF WAVE file or raw samples\n");
fprintf(stderr, " the output file(s) will be in FLAC format\n");
fprintf(stderr, "For decoding, the reverse is true\n");
fprintf(stderr, "\n");
fprintf(stderr, "A single 'infile' may be - for stdin. No 'infile' implies stdin. Use of\n");
fprintf(stderr, "stdin implies -c (write to stdout). However, flac allows the special\n");
fprintf(stderr, "encoding/decoding forms:\n");
fprintf(stderr, " flac [options] - outfilename or flac -d [options] - outfilename\n");
fprintf(stderr, "which is better than:\n");
fprintf(stderr, " flac [options] > outfilename or flac -d [options] > outfilename\n");
fprintf(stderr, "since the former allows flac to seek backwards to write the STREAMINFO or\n");
fprintf(stderr, "RIFF WAVE header contents when necessary.\n");
fprintf(stderr, "\n");
fprintf(stderr, "If the unencoded filename ends with '.wav' or -fw is used, it's assumed to be\n");
fprintf(stderr, "RIFF WAVE. Otherwise, flac will check for the presence of a RIFF header. If\n");
fprintf(stderr, "any infile is raw you must specify the format options {-fb|fl} -fc -fp and -fs,\n");
fprintf(stderr, "which will apply to all raw files. You can force a .wav file to be treated as\n");
fprintf(stderr, "a raw file using -fr.\n");
fprintf(stderr, "\n");
fprintf(stderr, "generic options:\n");
fprintf(stderr, " -d : decode (default behavior is encode)\n");
fprintf(stderr, " -t : test (same as -d except no decoded file is written)\n");
fprintf(stderr, " -a : analyze (same as -d except an analysis file is written)\n");
fprintf(stderr, " -c : write output to stdout\n");
fprintf(stderr, " -s : silent (do not write runtime encode/decode statistics)\n");
fprintf(stderr, " --skip samples : can be used both for encoding and decoding\n");
fprintf(stderr, "analyze options:\n");
fprintf(stderr, " --a-rtext : include residual signal in text output\n");
fprintf(stderr, " --a-rgp : generate gnuplot files of residual distribution of each subframe\n");
fprintf(stderr, "encoding options:\n");
fprintf(stderr, " --lax : allow encoder to generate non-Subset files\n");
fprintf(stderr, " -S { # | X | #x } : include a point or points in a SEEKTABLE\n");
fprintf(stderr, " # : a specific sample number for a seek point\n");
fprintf(stderr, " X : a placeholder point (always goes at the end of the SEEKTABLE)\n");
fprintf(stderr, " #x : # evenly spaced seekpoints, the first being at sample 0\n");
fprintf(stderr, " You may use many -S options; the resulting SEEKTABLE will be the unique-\n");
fprintf(stderr, " ified union of all such values.\n");
fprintf(stderr, " With no -S options, flac defaults to '-S 100x'. Use -S- for no SEEKTABLE.\n");
fprintf(stderr, " Note: -S #x will not work if the encoder can't determine the input size\n");
fprintf(stderr, " before starting.\n");
fprintf(stderr, " Note: if you use -S # and # is >= samples in the input, there will be\n");
fprintf(stderr, " either no seek point entered (if the input size is determinable\n");
fprintf(stderr, " before encoding starts) or a placeholder point (if input size is not\n");
fprintf(stderr, " determinable)\n");
fprintf(stderr, " -P # : write a PADDING block of # bytes (goes after SEEKTABLE)\n");
fprintf(stderr, " (0 => no PADDING block, default is -P 0)\n");
fprintf(stderr, " -b # : specify blocksize in samples; default is 1152 for -l 0, else 4608;\n");
fprintf(stderr, " must be 192/576/1152/2304/4608/256/512/1024/2048/4096/8192/16384/32768\n");
fprintf(stderr, " (unless --lax is used)\n");
fprintf(stderr, " -m : try mid-side coding for each frame (stereo input only)\n");
fprintf(stderr, " -M : loose mid-side coding for all frames (stereo input only)\n");
fprintf(stderr, " -0 .. -9 : fastest compression .. highest compression, default is -6\n");
fprintf(stderr, " these are synonyms for other options:\n");
fprintf(stderr, " -0 : synonymous with -l 0 -b 1152\n");
fprintf(stderr, " -1 : synonymous with -l 0 -b 1152 -M\n");
fprintf(stderr, " -2 : synonymous with -l 0 -b 1152 -m -r 4\n");
fprintf(stderr, " -3 : reserved\n");
fprintf(stderr, " -4 : synonymous with -l 8 -b 4608 \n");
fprintf(stderr, " -5 : synonymous with -l 8 -b 4608 -M\n");
fprintf(stderr, " -6 : synonymous with -l 8 -b 4608 -m -r 4\n");
fprintf(stderr, " -7 : reserved\n");
fprintf(stderr, " -8 : synonymous with -l 32 -b 4608 -m -r 4\n");
fprintf(stderr, " -9 : synonymous with -l 32 -m -e -r 16 -R 32 -p (very slow!)\n");
fprintf(stderr, " -e : do exhaustive model search (expensive!)\n");
fprintf(stderr, " -l # : specify max LPC order; 0 => use only fixed predictors\n");
fprintf(stderr, " -p : do exhaustive search of LP coefficient quantization (expensive!);\n");
fprintf(stderr, " overrides -q, does nothing if using -l 0\n");
fprintf(stderr, " -q # : specify precision in bits of quantized linear-predictor coefficients;\n");
fprintf(stderr, " 0 => let encoder decide (min is %u, default is -q 0)\n", FLAC__MIN_QLP_COEFF_PRECISION);
fprintf(stderr, " -r [#,]# : [min,]max residual partition order (# is 0..16; min defaults to 0;\n");
fprintf(stderr, " default is -r 0; above 4 doesn't usually help much)\n");
fprintf(stderr, " -R # : Rice parameter search distance (# is 0..32; above 2 doesn't help much\n");
fprintf(stderr, " -V : verify a correct encoding by decoding the output in parallel and\n");
fprintf(stderr, " comparing to the original\n");
fprintf(stderr, " -S-, -m-, -M-, -e-, -p-, -V-, --lax- can all be used to turn off a particular\n");
fprintf(stderr, " option\n");
fprintf(stderr, "format options:\n");
fprintf(stderr, " -fb | -fl : big-endian | little-endian byte order\n");
fprintf(stderr, " -fc channels\n");
fprintf(stderr, " -fp bits_per_sample\n");
fprintf(stderr, " -fs sample_rate : in Hz\n");
fprintf(stderr, " -fu : unsigned samples (default is signed)\n");
fprintf(stderr, " -fr : force to raw format (even if filename ends in .wav)\n");
fprintf(stderr, " -fw : force to RIFF WAVE\n");
return 1;
}
int encode_file(const char *infilename, const char *forced_outfilename)
{
FILE *encode_infile;
char outfilename[4096]; /* @@@ bad MAGIC NUMBER */
char *p;
if(0 == strcmp(infilename, "-")) {
encode_infile = stdin;
}
else {
if(0 == (encode_infile = fopen(infilename, "rb"))) {
fprintf(stderr, "ERROR: can't open input file %s\n", infilename);
return 1;
}
}
if(verbose)
fprintf(stderr, "%s:\n", infilename);
if(format_is_wave < 0) {
/* lamely attempt to guess the file type based on the first 4 bytes (which is all ungetc will guarantee us) */
char head[4];
int h, n;
/* first set format based on name */
if(strstr(infilename, ".wav") == infilename + (strlen(infilename) - strlen(".wav")))
format_is_wave = true;
else
format_is_wave = false;
if((n = fread(head, 1, 4, encode_infile)) < 4) {
if(format_is_wave)
fprintf(stderr, "WARNING: %s is not a WAVE file, treating as a raw file\n", infilename);
format_is_wave = false;
}
else {
if(strncmp(head, "RIFF", 4)) {
if(format_is_wave)
fprintf(stderr, "WARNING: %s is not a WAVE file, treating as a raw file\n", infilename);
format_is_wave = false;
}
else
format_is_wave = true;
}
for(h = n-1; h >= 0; h--)
ungetc(head[h], encode_infile);
}
if(!format_is_wave) {
if(format_is_big_endian < 0 || format_channels < 0 || format_bps < 0 || format_sample_rate < 0)
return usage("ERROR: for encoding a raw file you must specify { -fb or -fl }, -fc, -fp, and -fs\n");
}
if(encode_infile == stdin || force_to_stdout)
strcpy(outfilename, "-");
else {
strcpy(outfilename, infilename);
if(0 == (p = strrchr(outfilename, '.')))
strcat(outfilename, ".flac");
else {
if(0 == strcmp(p, ".flac"))
strcpy(p, "_new.flac");
else
strcpy(p, ".flac");
}
}
if(0 == forced_outfilename)
forced_outfilename = outfilename;
if(format_is_wave)
return encode_wav(encode_infile, infilename, forced_outfilename, verbose, skip, verify, lax, do_mid_side, loose_mid_side, do_exhaustive_model_search, do_qlp_coeff_prec_search, min_residual_partition_order, max_residual_partition_order, rice_parameter_search_dist, max_lpc_order, (unsigned)blocksize, qlp_coeff_precision, padding, requested_seek_points, num_requested_seek_points);
else
return encode_raw(encode_infile, infilename, forced_outfilename, verbose, skip, verify, lax, do_mid_side, loose_mid_side, do_exhaustive_model_search, do_qlp_coeff_prec_search, min_residual_partition_order, max_residual_partition_order, rice_parameter_search_dist, max_lpc_order, (unsigned)blocksize, qlp_coeff_precision, padding, requested_seek_points, num_requested_seek_points, format_is_big_endian, format_is_unsigned_samples, format_channels, format_bps, format_sample_rate);
}
int decode_file(const char *infilename, const char *forced_outfilename)
{
static const char *suffixes[] = { ".wav", ".raw" };
char outfilename[4096]; /* @@@ bad MAGIC NUMBER */
char *p;
if(!test_only && !analyze) {
if(format_is_wave < 0) {
format_is_wave = true;
}
if(!format_is_wave) {
if(format_is_big_endian < 0)
return usage("ERROR: for decoding to a raw file you must specify -fb or -fl\n");
}
}
if(0 == strcmp(infilename, "-") || force_to_stdout)
strcpy(outfilename, "-");
else {
const char *suffix = suffixes[format_is_wave? 0:1];
strcpy(outfilename, infilename);
if(0 == (p = strrchr(outfilename, '.')))
strcat(outfilename, suffix);
else {
if(0 == strcmp(p, suffix)) {
strcpy(p, "_new");
strcat(p, suffix);
}
else
strcpy(p, suffix);
}
}
if(0 == forced_outfilename)
forced_outfilename = outfilename;
if(format_is_wave)
return decode_wav(infilename, test_only? 0 : forced_outfilename, analyze, aopts, verbose, skip);
else
return decode_raw(infilename, test_only? 0 : forced_outfilename, analyze, aopts, verbose, skip, format_is_big_endian, format_is_unsigned_samples);
}