redo option parsing using getopt_long
diff --git a/src/flac/main.c b/src/flac/main.c
index e6e18b5..8991244 100644
--- a/src/flac/main.c
+++ b/src/flac/main.c
@@ -33,443 +33,355 @@
#include "encode.h"
#include "file.h"
+#if 0
+/*[JEC] was:#if HAVE_GETOPT_LONG*/
+/*[JEC] see flac/include/share/getopt.h as to why the change */
+# include <getopt.h>
+#else
+# include "share/getopt.h"
+#endif
+
typedef enum { RAW, WAV, AIF } FileFormat;
-static int short_usage(const char *message, ...);
-static int long_usage(const char *message, ...);
+static int do_it();
+
+static void init_options();
+static int parse_options(int argc, char *argv[]);
+static int parse_option(int short_option, const char *long_option, const char *option_argument);
+static void free_options();
+
+static int usage_error(const char *message, ...);
+static void short_usage();
+static void long_usage();
static void format_mistake(const char *infilename, const char *wrong, const char *right);
static int encode_file(const char *infilename, const char *forced_outfilename, FLAC__bool is_last_file);
static int decode_file(const char *infilename, const char *forced_outfilename);
-FLAC__bool verify = false, verbose = true, continue_through_decode_errors = false, lax = false, test_only = false, analyze = false, use_ogg = false;
-FLAC__bool do_mid_side = true, loose_mid_side = false, do_exhaustive_model_search = false, do_escape_coding = false, do_qlp_coeff_prec_search = false;
-FLAC__bool force_to_stdout = false, force_raw_format = false, delete_input = false, sector_align = false;
-const char *cmdline_forced_outfilename = 0, *output_prefix = 0;
-analysis_options aopts = { false, false };
-int padding = -1;
-unsigned max_lpc_order = 8;
-unsigned qlp_coeff_precision = 0;
-FLAC__uint64 skip = 0;
-int 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 */
-FLAC__int32 align_reservoir_0[588], align_reservoir_1[588]; /* for carrying over samples from --sector-align */
-FLAC__int32 *align_reservoir[2] = { align_reservoir_0, align_reservoir_1 };
-unsigned align_reservoir_samples = 0; /* 0 .. 587 */
+static void die(const char *message);
+static char *local_strdup(const char *source);
+
+
+/*
+ * FLAC__share__getopt format struct; note that for long options with no
+ * short option equivalent we just set the 'val' field to 0.
+ */
+static struct FLAC__share__option long_options_[] = {
+ /*
+ * general options
+ */
+ { "--help", 0, 0, 'H' },
+ { "--decode", 0, 0, 'd' },
+ { "--analyze", 0, 0, 'a' },
+ { "--test", 0, 0, 't' },
+ { "--stdout", 0, 0, 'c' },
+ { "--silent", 0, 0, 's' },
+ { "--delete-input-file", 0, 0, 0 },
+ { "--output-prefix", 1, 0, 0 },
+ { "--output-name", 1, 0, 'o' },
+ { "--skip", 1, 0, 0 },
+
+ /*
+ * decoding options
+ */
+ { "--decode-through-errors", 0, 0, 'F' },
+
+ /*
+ * encoding options
+ */
+ { "--compression-level-0", 0, 0, '0' },
+ { "--compression-level-1", 0, 0, '1' },
+ { "--compression-level-2", 0, 0, '2' },
+ { "--compression-level-3", 0, 0, '3' },
+ { "--compression-level-4", 0, 0, '4' },
+ { "--compression-level-5", 0, 0, '5' },
+ { "--compression-level-6", 0, 0, '6' },
+ { "--compression-level-7", 0, 0, '7' },
+ { "--compression-level-8", 0, 0, '8' },
+ { "--compression-level-9", 0, 0, '9' },
+ { "--best", 0, 0, '8' },
+ { "--fast", 0, 0, '0' },
+ { "--super-secret-impractical-compression-level", 0, 0, 0 },
+ { "--verify", 0, 0, 'V' },
+ { "--force-raw-input", 0, 0, 0 },
+ { "--lax", 0, 0, 0 },
+ { "--sector-align", 0, 0, 0 },
+ { "--seekpoint", 1, 0, 'S' },
+ { "--padding", 1, 0, 'P' },
+#ifdef FLAC__HAS_OGG
+ { "--ogg", 0, 0, 0 },
+#endif
+ { "--blocksize", 1, 0, 'b' },
+ { "--exhaustive-model-search", 0, 0, 'e' },
+#if 0
+ /* @@@ deprecated: */
+ { "--escape-coding", 0, 0, 'E' },
+#endif
+ { "--max-lpc-order", 1, 0, 'l' },
+ { "--mid-side", 0, 0, 'm' },
+ { "--adaptive-mid-side", 0, 0, 'M' },
+ { "--qlp-coeff-precision-search", 0, 0, 'p' },
+ { "--qlp-coeff-precision", 1, 0, 'q' },
+ { "--rice-partition-order", 1, 0, 'r' },
+#if 0
+ /* @@@ deprecated: */
+ { "--rice-parameter-search-distance", 1, 0, 'R' },
+#endif
+ { "--endian", 1, 0, 0 },
+ { "--channels", 1, 0, 0 },
+ { "--bps", 1, 0, 0 },
+ { "--sample-rate", 1, 0, 0 },
+ { "--sign", 1, 0, 0 },
+
+ /*
+ * analysis options
+ */
+ { "--residual-gnu-plot", 0, 0, 0 },
+ { "--residual-text", 0, 0, 0 },
+
+ /*
+ * negatives
+ */
+ { "--no-decode-through-errors", 0, 0, 0 },
+ { "--no-silent", 0, 0, 0 },
+ { "--no-seektable", 0, 0, 0 },
+ { "--no-delete-input-file", 0, 0, 0 },
+ { "--no-sector-align", 0, 0, 0 },
+ { "--no-lax", 0, 0, 0 },
+#ifdef FLAC__HAS_OGG
+ { "--no-ogg", 0, 0, 0 },
+#endif
+ { "--no-exhaustive-model-search", 0, 0, 0 },
+#if 0
+ /* @@@ deprecated: */
+ { "--no-escape-coding", 0, 0, 0 },
+#endif
+ { "--no-mid-side", 0, 0, 0 },
+ { "--no-adaptive-mid-side", 0, 0, 0 },
+ { "--no-qlp-coeff-prec-search", 0, 0, 0 },
+ { "--no-padding", 0, 0, 0 },
+ { "--no-verify", 0, 0, 0 },
+ { "--no-residual-gnuplot", 0, 0, 0 },
+ { "--no-residual-text", 0, 0, 0 },
+
+ {0, 0, 0, 0}
+};
+
+
+/*
+ * global to hold command-line option values
+ */
+
+static struct {
+ FLAC__bool show_long_help;
+ FLAC__bool mode_decode;
+ FLAC__bool verify;
+ FLAC__bool verbose;
+ FLAC__bool continue_through_decode_errors;
+ FLAC__bool lax;
+ FLAC__bool test_only;
+ FLAC__bool analyze;
+ FLAC__bool use_ogg;
+ FLAC__bool do_mid_side;
+ FLAC__bool loose_mid_side;
+ FLAC__bool do_exhaustive_model_search;
+ FLAC__bool do_escape_coding;
+ FLAC__bool do_qlp_coeff_prec_search;
+ FLAC__bool force_to_stdout;
+ FLAC__bool force_raw_format;
+ FLAC__bool delete_input;
+ FLAC__bool sector_align;
+ const char *cmdline_forced_outfilename;
+ const char *output_prefix;
+ analysis_options aopts;
+ int padding;
+ unsigned max_lpc_order;
+ unsigned qlp_coeff_precision;
+ FLAC__uint64 skip;
+ int format_is_big_endian;
+ int format_is_unsigned_samples;
+ int format_channels;
+ int format_bps;
+ int format_sample_rate;
+ int blocksize;
+ int min_residual_partition_order;
+ int max_residual_partition_order;
+ int rice_parameter_search_dist;
+ char requested_seek_points[50000]; /* @@@ bad MAGIC NUMBER */
+ int num_requested_seek_points; /* -1 => no -S options were given, 0 => -S- was given */
+
+ unsigned num_files;
+ char **filenames;
+} option_values;
+
+
+/*
+ * miscellaneous globals
+ */
+
+static FLAC__int32 align_reservoir_0[588], align_reservoir_1[588]; /* for carrying over samples from --sector-align */
+static FLAC__int32 *align_reservoir[2] = { align_reservoir_0, align_reservoir_1 };
+static unsigned align_reservoir_samples = 0; /* 0 .. 587 */
static const char *flac_suffix = ".flac", *ogg_suffix = ".ogg";
+
int main(int argc, char *argv[])
{
- int i, retval = 0;
- FLAC__bool mode_decode = false;
+ int retval = 0;
- if(argc <= 1)
- return short_usage(0);
+ init_options();
- /* get the options */
- for(i = 1; i < argc; i++) {
- if(argv[i][0] != '-' || argv[i][1] == 0)
- break;
- if(0 == strcmp(argv[i], "-H") || 0 == strcmp(argv[i], "--help"))
- return long_usage(0);
- else if(0 == strcmp(argv[i], "-d"))
- mode_decode = true;
- else if(0 == strcmp(argv[i], "-a")) {
- mode_decode = true;
- analyze = true;
- }
- else if(0 == strcmp(argv[i], "-t")) {
- mode_decode = true;
- test_only = true;
- }
- else if(0 == strcmp(argv[i], "-c"))
- force_to_stdout = true;
- else if(0 == strcmp(argv[i], "-F"))
- continue_through_decode_errors = true;
- else if(0 == strcmp(argv[i], "-F-"))
- continue_through_decode_errors = false;
- else if(0 == strcmp(argv[i], "-s"))
- verbose = false;
- else if(0 == strcmp(argv[i], "-s-"))
- verbose = true;
- else if(0 == strcmp(argv[i], "-S")) {
- if(++i >= argc)
- return long_usage("ERROR: must specify a value with -S\n");
- if(num_requested_seek_points < 0)
- num_requested_seek_points = 0;
- num_requested_seek_points++;
- strcat(requested_seek_points, argv[i]);
- strcat(requested_seek_points, "<");
- }
- else if(0 == strcmp(argv[i], "-S-")) {
- num_requested_seek_points = 0;
- requested_seek_points[0] = '\0';
- }
- else if(0 == strcmp(argv[i], "--delete-input-file"))
- delete_input = true;
- else if(0 == strcmp(argv[i], "--delete-input-file-"))
- delete_input = false;
- else if(0 == strcmp(argv[i], "--output-prefix")) {
- if(++i >= argc)
- return long_usage("ERROR: must specify a value with --output-prefix\n");
- output_prefix = argv[i];
- }
- else if(0 == strcmp(argv[i], "--sector-align"))
- sector_align = true;
- else if(0 == strcmp(argv[i], "--sector-align-"))
- sector_align = false;
- else if(0 == strcmp(argv[i], "--skip")) {
- if(++i >= argc)
- return long_usage("ERROR: must specify a value with --skip\n");
- skip = (FLAC__uint64)atoi(argv[i]); /* @@@ takes a pretty damn big file to overflow atoi() here, but it could happen */
- }
- else if(0 == strcmp(argv[i], "--lax"))
- lax = true;
- else if(0 == strcmp(argv[i], "--lax-"))
- lax = false;
-#ifdef FLAC__HAS_OGG
- else if(0 == strcmp(argv[i], "--ogg"))
- use_ogg = true;
- else if(0 == strcmp(argv[i], "--ogg-"))
- use_ogg = false;
-#endif
- else if(0 == strcmp(argv[i], "-b")) {
- if(++i >= argc)
- return long_usage("ERROR: must specify a value with -b\n");
- blocksize = atoi(argv[i]);
- }
- else if(0 == strcmp(argv[i], "-e"))
- do_exhaustive_model_search = true;
- else if(0 == strcmp(argv[i], "-e-"))
- do_exhaustive_model_search = false;
- else if(0 == strcmp(argv[i], "-E"))
- do_escape_coding = true;
- else if(0 == strcmp(argv[i], "-E-"))
- do_escape_coding = false;
- else if(0 == strcmp(argv[i], "-l")) {
- if(++i >= argc)
- return long_usage("ERROR: must specify a value with -l\n");
- max_lpc_order = atoi(argv[i]);
- }
- else if(0 == strcmp(argv[i], "-m")) {
- do_mid_side = true;
- loose_mid_side = false;
- }
- else if(0 == strcmp(argv[i], "-m-"))
- do_mid_side = loose_mid_side = false;
- else if(0 == strcmp(argv[i], "-M"))
- loose_mid_side = do_mid_side = true;
- else if(0 == strcmp(argv[i], "-M-"))
- loose_mid_side = do_mid_side = false;
- else if(0 == strcmp(argv[i], "-o")) {
- if(++i >= argc)
- return long_usage("ERROR: must specify a value with -o\n");
- cmdline_forced_outfilename = argv[i];
- }
- else if(0 == strcmp(argv[i], "-p"))
- do_qlp_coeff_prec_search = true;
- else if(0 == strcmp(argv[i], "-p-"))
- do_qlp_coeff_prec_search = false;
- else if(0 == strcmp(argv[i], "-P")) {
- if(++i >= argc)
- return long_usage("ERROR: must specify a value with -P\n");
- padding = atoi(argv[i]);
- if(padding < 0)
- return long_usage("ERROR: argument to -P must be >= 0\n");
- }
- else if(0 == strcmp(argv[i], "-P-"))
- padding = -1;
- else if(0 == strcmp(argv[i], "-q")) {
- if(++i >= argc)
- return long_usage("ERROR: must specify a value with -q\n");
- qlp_coeff_precision = atoi(argv[i]);
- }
- else if(0 == strcmp(argv[i], "-r")) {
- char *p;
- if(++i >= argc)
- return long_usage("ERROR: must specify a value with -r\n");
- p = strchr(argv[i], ',');
- if(0 == p) {
- min_residual_partition_order = 0;
- max_residual_partition_order = atoi(argv[i]);
- }
- else {
- min_residual_partition_order = atoi(argv[i]);
- max_residual_partition_order = atoi(++p);
- }
- }
- else if(0 == strcmp(argv[i], "--old-unworking-do-not-use-R")) {
- if(++i >= argc)
- return long_usage("ERROR: must specify a value with -R\n");
- rice_parameter_search_dist = atoi(argv[i]);
- }
- else if(0 == strcmp(argv[i], "-V"))
- verify = true;
- else if(0 == strcmp(argv[i], "-V-"))
- verify = false;
- else if(0 == strcmp(argv[i], "-fb"))
- format_is_big_endian = true;
- else if(0 == strcmp(argv[i], "-fl"))
- format_is_big_endian = false;
- else if(0 == strcmp(argv[i], "-fc")) {
- if(++i >= argc)
- return long_usage("ERROR: must specify a value with -fc\n");
- format_channels = atoi(argv[i]);
- }
- else if(0 == strcmp(argv[i], "-fp")) {
- if(++i >= argc)
- return long_usage("ERROR: must specify a value with -fp\n");
- format_bps = atoi(argv[i]);
- }
- else if(0 == strcmp(argv[i], "-fs")) {
- if(++i >= argc)
- return long_usage("ERROR: must specify a value with -fs\n");
- format_sample_rate = atoi(argv[i]);
- }
- else if(0 == strcmp(argv[i], "-fu"))
- format_is_unsigned_samples = true;
- else if(0 == strcmp(argv[i], "-fr"))
- force_raw_format = true;
- else if(0 == strcmp(argv[i], "--a-rgp"))
- aopts.do_residual_gnuplot = true;
- else if(0 == strcmp(argv[i], "--a-rgp-"))
- aopts.do_residual_gnuplot = false;
- else if(0 == strcmp(argv[i], "--a-rtext"))
- aopts.do_residual_text = true;
- else if(0 == strcmp(argv[i], "--a-rtext-"))
- aopts.do_residual_text = false;
- else if(0 == strcmp(argv[i], "-0") || 0 == strcmp(argv[i], "--fast")) {
- do_exhaustive_model_search = false;
- do_escape_coding = false;
- do_mid_side = false;
- loose_mid_side = false;
- qlp_coeff_precision = 0;
- min_residual_partition_order = max_residual_partition_order = 2;
- rice_parameter_search_dist = 0;
- max_lpc_order = 0;
- }
- else if(0 == strcmp(argv[i], "-1")) {
- do_exhaustive_model_search = false;
- do_escape_coding = false;
- do_mid_side = true;
- loose_mid_side = true;
- qlp_coeff_precision = 0;
- min_residual_partition_order = max_residual_partition_order = 2;
- rice_parameter_search_dist = 0;
- max_lpc_order = 0;
- }
- else if(0 == strcmp(argv[i], "-2")) {
- do_exhaustive_model_search = false;
- do_escape_coding = false;
- do_mid_side = true;
- loose_mid_side = false;
- qlp_coeff_precision = 0;
- min_residual_partition_order = 0;
- max_residual_partition_order = 3;
- rice_parameter_search_dist = 0;
- max_lpc_order = 0;
- }
- else if(0 == strcmp(argv[i], "-3")) {
- do_exhaustive_model_search = false;
- do_escape_coding = false;
- do_mid_side = false;
- loose_mid_side = false;
- qlp_coeff_precision = 0;
- min_residual_partition_order = max_residual_partition_order = 3;
- rice_parameter_search_dist = 0;
- max_lpc_order = 6;
- }
- else if(0 == strcmp(argv[i], "-4")) {
- do_exhaustive_model_search = false;
- do_escape_coding = false;
- do_mid_side = true;
- loose_mid_side = true;
- qlp_coeff_precision = 0;
- min_residual_partition_order = max_residual_partition_order = 3;
- rice_parameter_search_dist = 0;
- max_lpc_order = 8;
- }
- else if(0 == strcmp(argv[i], "-5")) {
- do_exhaustive_model_search = false;
- do_escape_coding = false;
- do_mid_side = true;
- loose_mid_side = false;
- qlp_coeff_precision = 0;
- min_residual_partition_order = max_residual_partition_order = 3;
- rice_parameter_search_dist = 0;
- max_lpc_order = 8;
- }
- else if(0 == strcmp(argv[i], "-6")) {
- do_exhaustive_model_search = false;
- do_escape_coding = false;
- do_mid_side = true;
- loose_mid_side = false;
- qlp_coeff_precision = 0;
- min_residual_partition_order = 0;
- max_residual_partition_order = 4;
- rice_parameter_search_dist = 0;
- max_lpc_order = 8;
- }
- else if(0 == strcmp(argv[i], "-7")) {
- do_exhaustive_model_search = true;
- do_escape_coding = false;
- do_mid_side = true;
- loose_mid_side = false;
- qlp_coeff_precision = 0;
- min_residual_partition_order = 0;
- max_residual_partition_order = 6;
- rice_parameter_search_dist = 0;
- max_lpc_order = 8;
- }
- else if(0 == strcmp(argv[i], "-8") || 0 == strcmp(argv[i], "--best")) {
- do_exhaustive_model_search = true;
- do_escape_coding = false;
- do_mid_side = true;
- loose_mid_side = false;
- qlp_coeff_precision = 0;
- min_residual_partition_order = 0;
- max_residual_partition_order = 6;
- rice_parameter_search_dist = 0;
- max_lpc_order = 12;
- }
- else if(0 == strcmp(argv[i], "--super-secret-impractical-compression-level")) {
- do_exhaustive_model_search = true;
- do_escape_coding = true;
- do_mid_side = true;
- loose_mid_side = false;
- do_qlp_coeff_prec_search = true;
- min_residual_partition_order = 0;
- max_residual_partition_order = 16;
- rice_parameter_search_dist = 0;
- max_lpc_order = 32;
- }
- else if(isdigit((int)(argv[i][1]))) {
- return long_usage("ERROR: compression level '%s' is reserved\n", argv[i]);
- }
- else {
- return long_usage("ERROR: invalid option '%s'\n", argv[i]);
- }
- }
+ if((retval = parse_options(argc, argv)) == 0)
+ retval = do_it();
- /* tweak options; validate the values */
- if(!mode_decode) {
- if(blocksize < 0) {
- if(max_lpc_order == 0)
- blocksize = 1152;
- else
- blocksize = 4608;
- }
- if(max_residual_partition_order < 0) {
- if(blocksize <= 1152)
- max_residual_partition_order = 2;
- else if(blocksize <= 2304)
- max_residual_partition_order = 3;
- else if(blocksize <= 4608)
- max_residual_partition_order = 3;
- else
- max_residual_partition_order = 4;
- min_residual_partition_order = max_residual_partition_order;
- }
- if(rice_parameter_search_dist < 0) {
- rice_parameter_search_dist = 0;
- }
+ free_options();
+
+ return retval;
+}
+
+int do_it()
+{
+ int retval = 0;
+
+ if(option_values.show_long_help) {
+ long_usage();
+ return 0;
}
else {
- if(test_only) {
- if(skip > 0)
- return long_usage("ERROR: --skip is not allowed in test mode\n");
+ if(option_values.num_files == 0) {
+ short_usage();
+ return 0;
}
- }
- FLAC__ASSERT(blocksize >= 0 || mode_decode);
+ /*
+ * tweak options; validate the values
+ */
+ if(!option_values.mode_decode) {
+ if(option_values.blocksize < 0) {
+ if(option_values.max_lpc_order == 0)
+ option_values.blocksize = 1152;
+ else
+ option_values.blocksize = 4608;
+ }
+ if(option_values.max_residual_partition_order < 0) {
+ if(option_values.blocksize <= 1152)
+ option_values.max_residual_partition_order = 2;
+ else if(option_values.blocksize <= 2304)
+ option_values.max_residual_partition_order = 3;
+ else if(option_values.blocksize <= 4608)
+ option_values.max_residual_partition_order = 3;
+ else
+ option_values.max_residual_partition_order = 4;
+ option_values.min_residual_partition_order = option_values.max_residual_partition_order;
+ }
+ if(option_values.rice_parameter_search_dist < 0) {
+ option_values.rice_parameter_search_dist = 0;
+ }
+ }
+ else {
+ if(option_values.test_only) {
+ if(option_values.skip > 0)
+ return usage_error("ERROR: --skip is not allowed in test mode\n");
+ }
+ }
- if(format_channels >= 0) {
- if(format_channels == 0 || (unsigned)format_channels > FLAC__MAX_CHANNELS)
- return long_usage("ERROR: invalid number of channels '%u', must be > 0 and <= %u\n", format_channels, FLAC__MAX_CHANNELS);
- }
- if(format_bps >= 0) {
- if(format_bps != 8 && format_bps != 16 && format_bps != 24)
- return long_usage("ERROR: invalid bits per sample '%u' (must be 8/16/24)\n", format_bps);
- }
- if(format_sample_rate >= 0) {
- if(!FLAC__format_sample_rate_is_valid(format_sample_rate))
- return long_usage("ERROR: invalid sample rate '%u', must be > 0 and <= %u\n", format_sample_rate, FLAC__MAX_SAMPLE_RATE);
- }
- if(!mode_decode && ((unsigned)blocksize < FLAC__MIN_BLOCK_SIZE || (unsigned)blocksize > FLAC__MAX_BLOCK_SIZE)) {
- return long_usage("ERROR: invalid blocksize '%u', must be >= %u and <= %u\n", (unsigned)blocksize, FLAC__MIN_BLOCK_SIZE, FLAC__MAX_BLOCK_SIZE);
- }
- if(qlp_coeff_precision > 0 && qlp_coeff_precision < FLAC__MIN_QLP_COEFF_PRECISION) {
- return long_usage("ERROR: invalid value for -q '%u', must be 0 or >= %u\n", qlp_coeff_precision, FLAC__MIN_QLP_COEFF_PRECISION);
- }
+ FLAC__ASSERT(option_values.blocksize >= 0 || option_values.mode_decode);
- if(sector_align) {
- if(mode_decode)
- return long_usage("ERROR: --sector-align only allowed for encoding\n");
- else if(skip > 0)
- return long_usage("ERROR: --sector-align not allowed with --skip\n");
- else if(format_channels >= 0 && format_channels != 2)
- return long_usage("ERROR: --sector-align can only be done with stereo input\n");
- else if(format_bps >= 0 && format_bps != 16)
- return long_usage("ERROR: --sector-align can only be done with 16-bit samples\n");
- else if(format_sample_rate >= 0 && format_sample_rate != 44100)
- return long_usage("ERROR: --sector-align can only be done with a sample rate of 44100\n");
- }
- if(argc - i > 1 && cmdline_forced_outfilename) {
- return long_usage("ERROR: -o cannot be used with multiple files\n");
- }
- if(cmdline_forced_outfilename && output_prefix) {
- return long_usage("ERROR: --output-prefix conflicts with -o\n");
- }
+ if(option_values.format_channels >= 0) {
+ if(option_values.format_channels == 0 || (unsigned)option_values.format_channels > FLAC__MAX_CHANNELS)
+ return usage_error("ERROR: invalid number of channels '%u', must be > 0 and <= %u\n", option_values.format_channels, FLAC__MAX_CHANNELS);
+ }
+ if(option_values.format_bps >= 0) {
+ if(option_values.format_bps != 8 && option_values.format_bps != 16 && option_values.format_bps != 24)
+ return usage_error("ERROR: invalid bits per sample '%u' (must be 8/16/24)\n", option_values.format_bps);
+ }
+ if(option_values.format_sample_rate >= 0) {
+ if(!FLAC__format_sample_rate_is_valid(option_values.format_sample_rate))
+ return usage_error("ERROR: invalid sample rate '%u', must be > 0 and <= %u\n", option_values.format_sample_rate, FLAC__MAX_SAMPLE_RATE);
+ }
+ if(!option_values.mode_decode && ((unsigned)option_values.blocksize < FLAC__MIN_BLOCK_SIZE || (unsigned)option_values.blocksize > FLAC__MAX_BLOCK_SIZE)) {
+ return usage_error("ERROR: invalid blocksize '%u', must be >= %u and <= %u\n", (unsigned)option_values.blocksize, FLAC__MIN_BLOCK_SIZE, FLAC__MAX_BLOCK_SIZE);
+ }
+ if(option_values.qlp_coeff_precision > 0 && option_values.qlp_coeff_precision < FLAC__MIN_QLP_COEFF_PRECISION) {
+ return usage_error("ERROR: invalid value for -q '%u', must be 0 or >= %u\n", option_values.qlp_coeff_precision, FLAC__MIN_QLP_COEFF_PRECISION);
+ }
- if(verbose) {
+ if(option_values.sector_align) {
+ if(option_values.mode_decode)
+ return usage_error("ERROR: --sector-align only allowed for encoding\n");
+ else if(option_values.skip > 0)
+ return usage_error("ERROR: --sector-align not allowed with --skip\n");
+ else if(option_values.format_channels >= 0 && option_values.format_channels != 2)
+ return usage_error("ERROR: --sector-align can only be done with stereo input\n");
+ else if(option_values.format_bps >= 0 && option_values.format_bps != 16)
+ return usage_error("ERROR: --sector-align can only be done with 16-bit samples\n");
+ else if(option_values.format_sample_rate >= 0 && option_values.format_sample_rate != 44100)
+ return usage_error("ERROR: --sector-align can only be done with a sample rate of 44100\n");
+ }
+ if(option_values.num_files > 1 && option_values.cmdline_forced_outfilename) {
+ return usage_error("ERROR: -o cannot be used with multiple files\n");
+ }
+ if(option_values.cmdline_forced_outfilename && option_values.output_prefix) {
+ return usage_error("ERROR: --output-prefix conflicts with -o\n");
+ }
+
+ return 0;
+ }
+ if(option_values.verbose) {
fprintf(stderr, "\n");
fprintf(stderr, "flac %s, Copyright (C) 2000,2001,2002 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) {
+ if(!option_values.mode_decode) {
char padopt[16];
- if(padding < 0)
+ if(option_values.padding < 0)
strcpy(padopt, "-");
else
- sprintf(padopt, " %d", padding);
+ sprintf(padopt, " %d", option_values.padding);
fprintf(stderr,
"options:%s%s"
#ifdef FLAC__HAS_OGG
"%s"
#endif
"%s -P%s -b %u%s -l %u%s%s%s -q %u -r %u,%u -R %u%s\n",
- delete_input?" --delete-input-file":"", sector_align?" --sector-align":"",
+ option_values.delete_input?" --delete-input-file":"",
+ option_values.sector_align?" --sector-align":"",
#ifdef FLAC__HAS_OGG
- use_ogg?" --ogg":"",
+ option_values.use_ogg?" --ogg":"",
#endif
- lax?" --lax":"",
- padopt, (unsigned)blocksize, loose_mid_side?" -M":do_mid_side?" -m":"", max_lpc_order,
- do_exhaustive_model_search?" -e":"", do_escape_coding?" -E":"", do_qlp_coeff_prec_search?" -p":"",
- qlp_coeff_precision,
- (unsigned)min_residual_partition_order, (unsigned)max_residual_partition_order, (unsigned)rice_parameter_search_dist,
- verify? " -V":""
+ option_values.lax?" --lax":"",
+ padopt,
+ (unsigned)option_values.blocksize,
+ option_values.loose_mid_side?" -M":option_values.do_mid_side?" -m":"",
+ option_values.max_lpc_order,
+ option_values.do_exhaustive_model_search?" -e":"",
+ option_values.do_escape_coding?" -E":"",
+ option_values.do_qlp_coeff_prec_search?" -p":"",
+ option_values.qlp_coeff_precision,
+ (unsigned)option_values.min_residual_partition_order,
+ (unsigned)option_values.max_residual_partition_order,
+ (unsigned)option_values.rice_parameter_search_dist,
+ option_values.verify? " -V":""
);
}
}
- if(mode_decode) {
+ if(option_values.mode_decode) {
FLAC__bool first = true;
- if(i == argc) {
+ if(option_values.num_files == 0) {
retval = decode_file("-", 0);
}
else {
- if(i + 1 != argc)
- cmdline_forced_outfilename = 0;
- for(retval = 0; i < argc && retval == 0; i++) {
- if(0 == strcmp(argv[i], "-") && !first)
+ unsigned i;
+ if(option_values.num_files > 1)
+ option_values.cmdline_forced_outfilename = 0;
+ for(i = 0, retval = 0; i < option_values.num_files && retval == 0; i++) {
+ if(0 == strcmp(option_values.filenames[i], "-") && !first)
continue;
- retval = decode_file(argv[i], 0);
+ retval = decode_file(option_values.filenames[i], 0);
first = false;
}
}
@@ -477,16 +389,17 @@
else { /* encode */
FLAC__bool first = true;
- if(i == argc) {
+ if(option_values.num_files == 0) {
retval = encode_file("-", 0, true);
}
else {
- if(i + 1 != argc)
- cmdline_forced_outfilename = 0;
- for(retval = 0; i < argc && retval == 0; i++) {
- if(0 == strcmp(argv[i], "-") && !first)
+ unsigned i;
+ if(option_values.num_files > 1)
+ option_values.cmdline_forced_outfilename = 0;
+ for(i = 0, retval = 0; i < option_values.num_files && retval == 0; i++) {
+ if(0 == strcmp(option_values.filenames[i], "-") && !first)
continue;
- retval = encode_file(argv[i], 0, i == (argc-1));
+ retval = encode_file(option_values.filenames[i], 0, i == (option_values.num_files-1));
first = false;
}
}
@@ -495,190 +408,610 @@
return retval;
}
+void init_options()
+{
+ option_values.show_long_help = false;
+ option_values.mode_decode = false;
+ option_values.verify = false;
+ option_values.verbose = true;
+ option_values.continue_through_decode_errors = false;
+ option_values.lax = false;
+ option_values.test_only = false;
+ option_values.analyze = false;
+ option_values.use_ogg = false;
+ option_values.do_mid_side = true;
+ option_values.loose_mid_side = false;
+ option_values.do_exhaustive_model_search = false;
+ option_values.do_escape_coding = false;
+ option_values.do_qlp_coeff_prec_search = false;
+ option_values.force_to_stdout = false;
+ option_values.force_raw_format = false;
+ option_values.delete_input = false;
+ option_values.sector_align = false;
+ option_values.cmdline_forced_outfilename = 0;
+ option_values.output_prefix = 0;
+ option_values.aopts.do_residual_text = false;
+ option_values.aopts.do_residual_gnuplot = false;
+ option_values.padding = -1;
+ option_values.max_lpc_order = 8;
+ option_values.qlp_coeff_precision = 0;
+ option_values.skip = 0;
+ option_values.format_is_big_endian = -1;
+ option_values.format_is_unsigned_samples = false;
+ option_values.format_channels = -1;
+ option_values.format_bps = -1;
+ option_values.format_sample_rate = -1;
+ option_values.blocksize = -1;
+ option_values.min_residual_partition_order = -1;
+ option_values.max_residual_partition_order = -1;
+ option_values.rice_parameter_search_dist = -1;
+ option_values.requested_seek_points[0] = '\0';
+ option_values.num_requested_seek_points = -1;
+
+ option_values.num_files = 0;
+ option_values.filenames = 0;
+}
+
+int parse_options(int argc, char *argv[])
+{
+ int short_option;
+ int option_index = 1;
+ FLAC__bool had_error = false;
+ /*@@@ E and R: are deprecated */
+ const char *short_opts = "0123456789ab:cdeFHl:mMo:pP:q:r:sS:tV";
+
+ while ((short_option = FLAC__share__getopt_long(argc, argv, short_opts, long_options_, &option_index)) != -1) {
+ switch (short_option) {
+ case 0: /* long option with no equivalent short option */
+ had_error |= (parse_option(short_option, long_options_[option_index].name, FLAC__share__optarg) != 0);
+ break;
+ case '?':
+ case ':':
+ had_error = true;
+ break;
+ default: /* short option */
+ had_error |= (parse_option(short_option, 0, FLAC__share__optarg) != 0);
+ break;
+ }
+ }
+
+ if(had_error) {
+ return 1;
+ }
+
+ FLAC__ASSERT(FLAC__share__optind <= argc);
+
+ option_values.num_files = argc - FLAC__share__optind;
+
+ if(option_values.num_files > 0) {
+ unsigned i = 0;
+ if(0 == (option_values.filenames = malloc(sizeof(char *) * option_values.num_files)))
+ die("out of memory allocating space for file names list");
+ while(FLAC__share__optind < argc)
+ option_values.filenames[i++] = local_strdup(argv[FLAC__share__optind++]);
+ }
+
+ return 0;
+}
+
+int parse_option(int short_option, const char *long_option, const char *option_argument)
+{
+ FLAC__bool ok = true;
+ char *p;
+
+ if(short_option == 0) {
+ FLAC__ASSERT(0 != long_option);
+ if(0 == strcmp(long_option, "--delete-input-file")) {
+ option_values.delete_input = true;
+ }
+ else if(0 == strcmp(long_option, "--output-prefix")) {
+ FLAC__ASSERT(0 != option_argument);
+ option_values.output_prefix = option_argument;
+ }
+ else if(0 == strcmp(long_option, "--skip")) {
+ FLAC__ASSERT(0 != option_argument);
+ option_values.skip = (FLAC__uint64)atoi(option_argument); /* @@@ takes a pretty damn big file to overflow atoi() here, but it could happen */
+ }
+ else if(0 == strcmp(long_option, "--super-secret-impractical-compression-level")) {
+ option_values.do_exhaustive_model_search = true;
+ option_values.do_escape_coding = true;
+ option_values.do_mid_side = true;
+ option_values.loose_mid_side = false;
+ option_values.do_qlp_coeff_prec_search = true;
+ option_values.min_residual_partition_order = 0;
+ option_values.max_residual_partition_order = 16;
+ option_values.rice_parameter_search_dist = 0;
+ option_values.max_lpc_order = 32;
+ }
+ else if(0 == strcmp(long_option, "--force-raw-input")) {
+ option_values.force_raw_format = true;
+ }
+ else if(0 == strcmp(long_option, "--lax")) {
+ option_values.lax = true;
+ }
+ else if(0 == strcmp(long_option, "--sector-align")) {
+ option_values.sector_align = true;
+ }
+#ifdef FLAC__HAS_OGG
+ else if(0 == strcmp(long_option, "--ogg")) {
+ option_values.use_ogg = true;
+ }
+#endif
+ else if(0 == strcmp(long_option, "--endian")) {
+ FLAC__ASSERT(0 != option_argument);
+ if(0 == strncmp(option_argument, "big", strlen(option_argument)))
+ option_values.format_is_big_endian = true;
+ else if(0 == strncmp(option_argument, "little", strlen(option_argument)))
+ option_values.format_is_big_endian = false;
+ else {
+ return usage_error("ERROR: argument to --endian must be \"big\" or \"little\"\n");
+ ok = false;
+ }
+ }
+ else if(0 == strcmp(long_option, "--channels")) {
+ FLAC__ASSERT(0 != option_argument);
+ option_values.format_channels = atoi(option_argument);
+ }
+ else if(0 == strcmp(long_option, "--bps")) {
+ FLAC__ASSERT(0 != option_argument);
+ option_values.format_bps = atoi(option_argument);
+ }
+ else if(0 == strcmp(long_option, "--sample-rate")) {
+ FLAC__ASSERT(0 != option_argument);
+ option_values.format_sample_rate = atoi(option_argument);
+ }
+ else if(0 == strcmp(long_option, "--sign")) {
+ FLAC__ASSERT(0 != option_argument);
+ if(0 == strncmp(option_argument, "signed", strlen(option_argument)))
+ option_values.format_is_unsigned_samples = false;
+ else if(0 == strncmp(option_argument, "unsigned", strlen(option_argument)))
+ option_values.format_is_unsigned_samples = true;
+ else {
+ return usage_error("ERROR: argument to --sign must be \"signed\" or \"unsigned\"\n");
+ ok = false;
+ }
+ }
+ else if(0 == strcmp(long_option, "--residual-gnu-plot")) {
+ option_values.aopts.do_residual_gnuplot = true;
+ }
+ else if(0 == strcmp(long_option, "--residual-text")) {
+ option_values.aopts.do_residual_text = true;
+ }
+ /*
+ * negatives
+ */
+ else if(0 == strcmp(long_option, "--no-decode-through-errors")) {
+ option_values.continue_through_decode_errors = false;
+ }
+ else if(0 == strcmp(long_option, "--no-silent")) {
+ option_values.verbose = true;
+ }
+ else if(0 == strcmp(long_option, "--no-seektable")) {
+ option_values.num_requested_seek_points = 0;
+ option_values.requested_seek_points[0] = '\0';
+ }
+ else if(0 == strcmp(long_option, "--no-delete-input-file")) {
+ option_values.delete_input = false;
+ }
+ else if(0 == strcmp(long_option, "--no-sector-align")) {
+ option_values.sector_align = false;
+ }
+ else if(0 == strcmp(long_option, "--no-lax")) {
+ option_values.lax = false;
+ }
+#ifdef FLAC__HAS_OGG
+ else if(0 == strcmp(long_option, "--no-ogg")) {
+ option_values.use_ogg = false;
+ }
+#endif
+ else if(0 == strcmp(long_option, "--no-exhaustive-model-search")) {
+ option_values.do_exhaustive_model_search = false;
+ }
+#if 0
+ /* @@@ deprecated: */
+ else if(0 == strcmp(long_option, "--no-escape-coding")) {
+ option_values.do_escape_coding = false;
+ }
+#endif
+ else if(0 == strcmp(long_option, "--no-mid-side")) {
+ option_values.do_mid_side = option_values.loose_mid_side = false;
+ }
+ else if(0 == strcmp(long_option, "--no-adaptive-mid-side")) {
+ option_values.loose_mid_side = option_values.do_mid_side = false;
+ }
+ else if(0 == strcmp(long_option, "--no-qlp-coeff-prec-search")) {
+ option_values.do_qlp_coeff_prec_search = false;
+ }
+ else if(0 == strcmp(long_option, "--no-padding")) {
+ option_values.padding = -1;
+ }
+ else if(0 == strcmp(long_option, "--no-verify")) {
+ option_values.verify = false;
+ }
+ else if(0 == strcmp(long_option, "--no-residual-gnuplot")) {
+ option_values.aopts.do_residual_gnuplot = false;
+ }
+ else if(0 == strcmp(long_option, "--no-residual-text")) {
+ option_values.aopts.do_residual_text = false;
+ }
+ }
+ else {
+ switch(short_option) {
+ case 'H':
+ option_values.show_long_help = true;
+ break;
+ case 'd':
+ option_values.mode_decode = true;
+ break;
+ case 'a':
+ option_values.mode_decode = true;
+ option_values.analyze = true;
+ break;
+ case 't':
+ option_values.mode_decode = true;
+ option_values.test_only = true;
+ break;
+ case 'c':
+ option_values.force_to_stdout = true;
+ break;
+ case 's':
+ option_values.verbose = false;
+ break;
+ case 'o':
+ FLAC__ASSERT(0 != option_argument);
+ option_values.cmdline_forced_outfilename = option_argument;
+ break;
+ case 'F':
+ option_values.continue_through_decode_errors = true;
+ break;
+ case '0':
+ option_values.do_exhaustive_model_search = false;
+ option_values.do_escape_coding = false;
+ option_values.do_mid_side = false;
+ option_values.loose_mid_side = false;
+ option_values.qlp_coeff_precision = 0;
+ option_values.min_residual_partition_order = option_values.max_residual_partition_order = 2;
+ option_values.rice_parameter_search_dist = 0;
+ option_values.max_lpc_order = 0;
+ break;
+ case '1':
+ option_values.do_exhaustive_model_search = false;
+ option_values.do_escape_coding = false;
+ option_values.do_mid_side = true;
+ option_values.loose_mid_side = true;
+ option_values.qlp_coeff_precision = 0;
+ option_values.min_residual_partition_order = option_values.max_residual_partition_order = 2;
+ option_values.rice_parameter_search_dist = 0;
+ option_values.max_lpc_order = 0;
+ break;
+ case '2':
+ option_values.do_exhaustive_model_search = false;
+ option_values.do_escape_coding = false;
+ option_values.do_mid_side = true;
+ option_values.loose_mid_side = false;
+ option_values.qlp_coeff_precision = 0;
+ option_values.min_residual_partition_order = 0;
+ option_values.max_residual_partition_order = 3;
+ option_values.rice_parameter_search_dist = 0;
+ option_values.max_lpc_order = 0;
+ break;
+ case '3':
+ option_values.do_exhaustive_model_search = false;
+ option_values.do_escape_coding = false;
+ option_values.do_mid_side = false;
+ option_values.loose_mid_side = false;
+ option_values.qlp_coeff_precision = 0;
+ option_values.min_residual_partition_order = option_values.max_residual_partition_order = 3;
+ option_values.rice_parameter_search_dist = 0;
+ option_values.max_lpc_order = 6;
+ break;
+ case '4':
+ option_values.do_exhaustive_model_search = false;
+ option_values.do_escape_coding = false;
+ option_values.do_mid_side = true;
+ option_values.loose_mid_side = true;
+ option_values.qlp_coeff_precision = 0;
+ option_values.min_residual_partition_order = option_values.max_residual_partition_order = 3;
+ option_values.rice_parameter_search_dist = 0;
+ option_values.max_lpc_order = 8;
+ break;
+ case '5':
+ option_values.do_exhaustive_model_search = false;
+ option_values.do_escape_coding = false;
+ option_values.do_mid_side = true;
+ option_values.loose_mid_side = false;
+ option_values.qlp_coeff_precision = 0;
+ option_values.min_residual_partition_order = option_values.max_residual_partition_order = 3;
+ option_values.rice_parameter_search_dist = 0;
+ option_values.max_lpc_order = 8;
+ break;
+ case '6':
+ option_values.do_exhaustive_model_search = false;
+ option_values.do_escape_coding = false;
+ option_values.do_mid_side = true;
+ option_values.loose_mid_side = false;
+ option_values.qlp_coeff_precision = 0;
+ option_values.min_residual_partition_order = 0;
+ option_values.max_residual_partition_order = 4;
+ option_values.rice_parameter_search_dist = 0;
+ option_values.max_lpc_order = 8;
+ break;
+ case '7':
+ option_values.do_exhaustive_model_search = true;
+ option_values.do_escape_coding = false;
+ option_values.do_mid_side = true;
+ option_values.loose_mid_side = false;
+ option_values.qlp_coeff_precision = 0;
+ option_values.min_residual_partition_order = 0;
+ option_values.max_residual_partition_order = 6;
+ option_values.rice_parameter_search_dist = 0;
+ option_values.max_lpc_order = 8;
+ break;
+ case '8':
+ option_values.do_exhaustive_model_search = true;
+ option_values.do_escape_coding = false;
+ option_values.do_mid_side = true;
+ option_values.loose_mid_side = false;
+ option_values.qlp_coeff_precision = 0;
+ option_values.min_residual_partition_order = 0;
+ option_values.max_residual_partition_order = 6;
+ option_values.rice_parameter_search_dist = 0;
+ option_values.max_lpc_order = 12;
+ break;
+ case '9':
+ return usage_error("ERROR: compression level '9' is reserved\n");
+ break;
+ case 'V':
+ option_values.verify = true;
+ break;
+ case 'S':
+ FLAC__ASSERT(0 != option_argument);
+ if(option_values.num_requested_seek_points < 0)
+ option_values.num_requested_seek_points = 0;
+ option_values.num_requested_seek_points++;
+ strcat(option_values.requested_seek_points, option_argument);
+ strcat(option_values.requested_seek_points, "<");
+ break;
+ case 'P':
+ FLAC__ASSERT(0 != option_argument);
+ option_values.padding = atoi(option_argument);
+ if(option_values.padding < 0) {
+ return usage_error("ERROR: argument to -P must be >= 0\n");
+ }
+ break;
+ case 'b':
+ FLAC__ASSERT(0 != option_argument);
+ option_values.blocksize = atoi(option_argument);
+ break;
+ case 'e':
+ option_values.do_exhaustive_model_search = true;
+ break;
+ case 'E':
+ option_values.do_escape_coding = true;
+ break;
+ case 'l':
+ FLAC__ASSERT(0 != option_argument);
+ option_values.max_lpc_order = atoi(option_argument);
+ break;
+ case 'm':
+ option_values.do_mid_side = true;
+ option_values.loose_mid_side = false;
+ break;
+ case 'M':
+ option_values.loose_mid_side = option_values.do_mid_side = true;
+ break;
+ case 'p':
+ option_values.do_qlp_coeff_prec_search = true;
+ break;
+ case 'q':
+ FLAC__ASSERT(0 != option_argument);
+ option_values.qlp_coeff_precision = atoi(option_argument);
+ break;
+ case 'r':
+ FLAC__ASSERT(0 != option_argument);
+ p = strchr(option_argument, ',');
+ if(0 == p) {
+ option_values.min_residual_partition_order = 0;
+ option_values.max_residual_partition_order = atoi(option_argument);
+ }
+ else {
+ option_values.min_residual_partition_order = atoi(option_argument);
+ option_values.max_residual_partition_order = atoi(++p);
+ }
+ break;
+ case 'R':
+ FLAC__ASSERT(0 != option_argument);
+ option_values.rice_parameter_search_dist = atoi(option_argument);
+ break;
+ default:
+ FLAC__ASSERT(0);
+ }
+ }
+
+ return ok;
+}
+
+void free_options()
+{
+ if(0 != option_values.filenames)
+ free(option_values.filenames);
+}
+
+int usage_error(const char *message, ...)
+{
+ va_list args;
+
+ FLAC__ASSERT(0);
+
+ va_start(args, message);
+
+ (void) vfprintf(stderr, message, args);
+
+ va_end(args);
+
+ printf("Type \"flac\" for a usage summary or \"flac --help\" for all options\n");
+
+ return 1;
+}
+
static void usage_header()
{
- fprintf(stderr, "===============================================================================\n");
- fprintf(stderr, "flac - Command-line FLAC encoder/decoder version %s\n", FLAC__VERSION_STRING);
- fprintf(stderr, "Copyright (C) 2000,2001,2002 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");
+ printf("===============================================================================\n");
+ printf("flac - Command-line FLAC encoder/decoder version %s\n", FLAC__VERSION_STRING);
+ printf("Copyright (C) 2000,2001,2002 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");
}
-int short_usage(const char *message, ...)
+void short_usage()
{
- va_list args;
-
- if(message) {
- va_start(args, message);
-
- (void) vfprintf(stderr, message, args);
-
- va_end(args);
-
- }
usage_header();
- fprintf(stderr, "\n");
- fprintf(stderr, "This is the short help; for full help use 'flac --help'\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "To encode:\n");
- fprintf(stderr, " flac [-#] [infile [...]]\n");
- fprintf(stderr, "\n");
- fprintf(stderr, " -# is -0 (fastest compression) to -8 (highest compression); -5 is the default\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "To decode:\n");
- fprintf(stderr, " flac -d [infile [...]]\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "To test:\n");
- fprintf(stderr, " flac -t [infile [...]]\n");
-
- return message? 1 : 0;
+ printf("\n");
+ printf("This is the short help; for full help use 'flac --help'\n");
+ printf("\n");
+ printf("To encode:\n");
+ printf(" flac [-#] [infile [...]]\n");
+ printf("\n");
+ printf(" -# is -0 (fastest compression) to -8 (highest compression); -5 is the default\n");
+ printf("\n");
+ printf("To decode:\n");
+ printf(" flac -d [infile [...]]\n");
+ printf("\n");
+ printf("To test:\n");
+ printf(" flac -t [infile [...]]\n");
}
-int long_usage(const char *message, ...)
+void long_usage()
{
- FILE *out = (message? stderr : stdout);
- va_list args;
-
- if(message) {
- va_start(args, message);
-
- (void) vfprintf(stderr, message, args);
-
- va_end(args);
-
- }
usage_header();
- fprintf(out, "Usage:\n");
- fprintf(out, " flac [options] [infile [...]]\n");
- fprintf(out, "\n");
- fprintf(out, "For encoding:\n");
- fprintf(out, " the input file(s) may be a PCM RIFF WAVE file, AIFF file, or raw samples\n");
- fprintf(out, " the output file(s) will be in FLAC format\n");
- fprintf(out, "For decoding, the reverse is true\n");
- fprintf(out, "\n");
- fprintf(out, "A single 'infile' may be - for stdin. No 'infile' implies stdin. Use of\n");
- fprintf(out, "stdin implies -c (write to stdout). Normally you should use:\n");
- fprintf(out, " flac [options] -o outfilename or flac -d [options] -o outfilename\n");
- fprintf(out, "instead of:\n");
- fprintf(out, " flac [options] > outfilename or flac -d [options] > outfilename\n");
- fprintf(out, "since the former allows flac to seek backwards to write the STREAMINFO or\n");
- fprintf(out, "RIFF WAVE header contents when necessary.\n");
- fprintf(out, "\n");
- fprintf(out, "flac checks for the presence of a AIFF/RIFF WAVE header to decide whether or\n");
- fprintf(out, "not to treat an input file as AIFF/WAVE format or raw samples. If any infile\n");
- fprintf(out, "is raw you must specify the format options {-fb|fl} -fc -fp and -fs, which will\n");
- fprintf(out, "apply to all raw files. You can force AIFF/WAVE files to be treated as a raw\n");
- fprintf(out, "files using -fr.\n");
- fprintf(out, "\n");
- fprintf(out, "generic options:\n");
- fprintf(out, " -d : decode (default behavior is encode)\n");
- fprintf(out, " -t : test (same as -d except no decoded file is written)\n");
- fprintf(out, " -a : analyze (same as -d except an analysis file is written)\n");
- fprintf(out, " -c : write output to stdout\n");
- fprintf(out, " -s : silent (do not write runtime encode/decode statistics)\n");
- fprintf(out, " -o filename : force the output file name (usually flac just changes the\n");
- fprintf(out, " extension)\n");
- fprintf(out, " --output-prefix string : prefix each output file name with the given string.\n");
- fprintf(out, " This can be useful for encoding/decoding files to a different directory.\n");
- fprintf(out, " Make sure if your string is a path name that it ends with a '/' slash.\n");
- fprintf(out, " --delete-input-file : deletes the input file after a successful encode/decode\n");
- fprintf(out, " --skip samples : can be used both for encoding and decoding\n");
- fprintf(out, "analyze options:\n");
- fprintf(out, " --a-rtext : include residual signal in text output\n");
- fprintf(out, " --a-rgp : generate gnuplot files of residual distribution of each subframe\n");
- fprintf(out, "decoding options:\n");
- fprintf(out, " -F : force decoder to continue decoding through stream errors\n");
- fprintf(out, "encoding options:\n");
+ printf("Usage:\n");
+ printf(" flac [options] [infile [...]]\n");
+ printf("\n");
+ printf("For encoding:\n");
+ printf(" the input file(s) may be a PCM RIFF WAVE file, AIFF file, or raw samples\n");
+ printf(" the output file(s) will be in FLAC format\n");
+ printf("For decoding, the reverse is true\n");
+ printf("\n");
+ printf("A single 'infile' may be - for stdin. No 'infile' implies stdin. Use of\n");
+ printf("stdin implies -c (write to stdout). Normally you should use:\n");
+ printf(" flac [options] -o outfilename or flac -d [options] -o outfilename\n");
+ printf("instead of:\n");
+ printf(" flac [options] > outfilename or flac -d [options] > outfilename\n");
+ printf("since the former allows flac to seek backwards to write the STREAMINFO or\n");
+ printf("RIFF WAVE header contents when necessary.\n");
+ printf("\n");
+ printf("flac checks for the presence of a AIFF/RIFF WAVE header to decide whether or\n");
+ printf("not to treat an input file as AIFF/WAVE format or raw samples. If any infile\n");
+ printf("is raw you must specify the format options {-fb|fl} -fc -fp and -fs, which will\n");
+ printf("apply to all raw files. You can force AIFF/WAVE files to be treated as a raw\n");
+ printf("files 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(" -c : write output to stdout\n");
+ printf(" -s : silent (do not write runtime encode/decode statistics)\n");
+ printf(" -o filename : force the output file name (usually flac just changes the\n");
+ printf(" extension)\n");
+ printf(" --output-prefix string : prefix each output file name with the given string.\n");
+ printf(" This can be useful for encoding/decoding files to a different directory.\n");
+ printf(" Make sure if your string is a path name that it ends with a '/' slash.\n");
+ printf(" --delete-input-file : deletes the input file after a successful encode/decode\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("decoding options:\n");
+ printf(" -F : force decoder to continue decoding through stream errors\n");
+ printf("encoding options:\n");
#ifdef FLAC__HAS_OGG
- fprintf(out, " --ogg : output Ogg-FLAC stream instead of native FLAC\n");
+ printf(" --ogg : output Ogg-FLAC stream instead of native FLAC\n");
#endif
- fprintf(out, " --lax : allow encoder to generate non-Subset files\n");
- fprintf(out, " --sector-align : align encoding of multiple files on sector boundaries\n");
- fprintf(out, " -S { # | X | #x } : include a point or points in a SEEKTABLE\n");
- fprintf(out, " # : a specific sample number for a seek point\n");
- fprintf(out, " X : a placeholder point (always goes at the end of the SEEKTABLE)\n");
- fprintf(out, " #x : # evenly spaced seekpoints, the first being at sample 0\n");
- fprintf(out, " You may use many -S options; the resulting SEEKTABLE will be the unique-\n");
- fprintf(out, " ified union of all such values.\n");
- fprintf(out, " With no -S options, flac defaults to '-S 100x'. Use -S- for no SEEKTABLE.\n");
- fprintf(out, " Note: -S #x will not work if the encoder can't determine the input size\n");
- fprintf(out, " before starting.\n");
- fprintf(out, " Note: if you use -S # and # is >= samples in the input, there will be\n");
- fprintf(out, " either no seek point entered (if the input size is determinable\n");
- fprintf(out, " before encoding starts) or a placeholder point (if input size is not\n");
- fprintf(out, " determinable)\n");
- fprintf(out, " -P # : write a PADDING block of length # (goes after SEEKTABLE)\n");
- fprintf(out, " (# must be >= 0; default is -P-). Note that the overall size in bytes\n");
- fprintf(out, " of the PADDING block will be # + 4 because of the metadata header.\n");
- fprintf(out, " -b # : specify blocksize in samples; default is 1152 for -l 0, else 4608;\n");
- fprintf(out, " must be 192/576/1152/2304/4608/256/512/1024/2048/4096/8192/16384/32768\n");
- fprintf(out, " (unless --lax is used)\n");
- fprintf(out, " -m : try mid-side coding for each frame (stereo input only)\n");
- fprintf(out, " -M : adaptive mid-side coding for all frames (stereo input only)\n");
- fprintf(out, " -0 .. -8 : fastest compression .. highest compression, default is -5\n");
- fprintf(out, " these are synonyms for other options:\n");
- fprintf(out, " -0 : synonymous with -l 0 -b 1152 -r 2,2\n");
- fprintf(out, " -1 : synonymous with -l 0 -b 1152 -M -r 2,2\n");
- fprintf(out, " -2 : synonymous with -l 0 -b 1152 -m -r 3\n");
- fprintf(out, " -3 : synonymous with -l 6 -b 4608 -r 3,3\n");
- fprintf(out, " -4 : synonymous with -l 8 -b 4608 -M -r 3,3\n");
- fprintf(out, " -5 : synonymous with -l 8 -b 4608 -m -r 3,3\n");
- fprintf(out, " -6 : synonymous with -l 8 -b 4608 -m -r 4\n");
- fprintf(out, " -7 : synonymous with -l 8 -b 4608 -m -e -r 6\n");
- fprintf(out, " -8 : synonymous with -l 12 -b 4608 -m -e -r 6\n");
- fprintf(out, " --fast, --best : synonymous with -0 and -8 respectively\n");
- fprintf(out, " -e : do exhaustive model search (expensive!)\n");
- fprintf(out, " -E : include escape coding in the entropy coder\n");
- fprintf(out, " -l # : specify max LPC order; 0 => use only fixed predictors\n");
- fprintf(out, " -p : do exhaustive search of LP coefficient quantization (expensive!);\n");
- fprintf(out, " overrides -q, does nothing if using -l 0\n");
- fprintf(out, " -q # : specify precision in bits of quantized linear-predictor coefficients;\n");
- fprintf(out, " 0 => let encoder decide (min is %u, default is -q 0)\n", FLAC__MIN_QLP_COEFF_PRECISION);
- fprintf(out, " -r [#,]# : [min,]max residual partition order (# is 0..16; min defaults to 0;\n");
- fprintf(out, " default is -r 0; above 4 doesn't usually help much)\n");
+ printf(" --lax : allow encoder to generate non-Subset files\n");
+ printf(" --sector-align : align encoding of multiple files on sector boundaries\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 length # (goes after SEEKTABLE)\n");
+ printf(" (# must be >= 0; default is -P-). Note that the overall size in bytes\n");
+ printf(" of the PADDING block will be # + 4 because of the metadata header.\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 : adaptive mid-side coding for all frames (stereo input only)\n");
+ printf(" -0 .. -8 : fastest compression .. highest compression, default is -5\n");
+ printf(" these are synonyms for other options:\n");
+ printf(" -0 : synonymous with -l 0 -b 1152 -r 2,2\n");
+ printf(" -1 : synonymous with -l 0 -b 1152 -M -r 2,2\n");
+ printf(" -2 : synonymous with -l 0 -b 1152 -m -r 3\n");
+ printf(" -3 : synonymous with -l 6 -b 4608 -r 3,3\n");
+ printf(" -4 : synonymous with -l 8 -b 4608 -M -r 3,3\n");
+ printf(" -5 : synonymous with -l 8 -b 4608 -m -r 3,3\n");
+ printf(" -6 : synonymous with -l 8 -b 4608 -m -r 4\n");
+ printf(" -7 : synonymous with -l 8 -b 4608 -m -e -r 6\n");
+ printf(" -8 : synonymous with -l 12 -b 4608 -m -e -r 6\n");
+ printf(" --fast, --best : synonymous with -0 and -8 respectively\n");
+ printf(" -e : do exhaustive model search (expensive!)\n");
+ printf(" -E : include escape coding in the entropy coder\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");
#if 0
@@@ removed because it doesnt work yet and is too dangerous for users
- fprintf(out, " -R # : Rice parameter search distance (# is 0..32; above 2 doesn't help much)\n");
+ printf(" -R # : Rice parameter search distance (# is 0..32; above 2 doesn't help much)\n");
#endif
- fprintf(out, " -V : verify a correct encoding by decoding the output in parallel and\n");
- fprintf(out, " comparing to the original\n");
- fprintf(out, " -S-, -P-, -m-, -M-, -e-, -E-, -p-, -V-, --delete-input-file-,%s --lax-,\n",
+ printf(" -V : verify a correct encoding by decoding the output in parallel and\n");
+ printf(" comparing to the original\n");
+ printf(" -S-, -P-, -m-, -M-, -e-, -E-, -p-, -V-, --delete-input-file-,%s --lax-,\n",
#ifdef FLAC__HAS_OGG
" --ogg-,"
#else
""
#endif
);
- fprintf(out, " --sector-align- can all be used to turn off a particular option\n");
- fprintf(out, "format options:\n");
- fprintf(out, " -fb | -fl : big-endian | little-endian byte order\n");
- fprintf(out, " -fc channels\n");
- fprintf(out, " -fp bits_per_sample\n");
- fprintf(out, " -fs sample_rate : in Hz\n");
- fprintf(out, " -fu : unsigned samples (default is signed)\n");
- fprintf(out, " -fr : force input to be treated as raw samples\n");
-
- return message? 1 : 0;
+ printf(" --sector-align- can all be used to turn off a particular 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 input to be treated as raw samples\n");
}
void
format_mistake(const char *infilename, const char *wrong, const char *right)
{
- fprintf(stderr, "WARNING: %s is not a %s file; treating as a %s file\n",
- infilename, wrong, right);
+ fprintf(stderr, "WARNING: %s is not a %s file; treating as a %s file\n", infilename, wrong, right);
}
int encode_file(const char *infilename, const char *forced_outfilename, FLAC__bool is_last_file)
@@ -705,7 +1038,7 @@
}
}
- if(!force_raw_format) {
+ if(!option_values.force_raw_format) {
/* first set format based on name */
if(strlen(infilename) > 3 && 0 == strcasecmp(infilename+(strlen(infilename)-4), ".wav"))
fmt= WAV;
@@ -733,21 +1066,21 @@
}
}
- if(sector_align && fmt == RAW && infilesize < 0) {
+ if(option_values.sector_align && fmt == RAW && infilesize < 0) {
fprintf(stderr, "ERROR: can't --sector-align when the input size is unknown\n");
return 1;
}
if(fmt == RAW) {
- if(format_is_big_endian < 0 || format_channels < 0 || format_bps < 0 || format_sample_rate < 0)
- return long_usage("ERROR: for encoding a raw file you must specify { -fb or -fl }, -fc, -fp, and -fs\n");
+ if(option_values.format_is_big_endian < 0 || option_values.format_channels < 0 || option_values.format_bps < 0 || option_values.format_sample_rate < 0)
+ return usage_error("ERROR: for encoding a raw file you must specify { -fb or -fl }, -fc, -fp, and -fs\n");
}
- if(encode_infile == stdin || force_to_stdout)
+ if(encode_infile == stdin || option_values.force_to_stdout)
strcpy(outfilename, "-");
else {
- const char *suffix = (use_ogg? ogg_suffix : flac_suffix);
- strcpy(outfilename, output_prefix? output_prefix : "");
+ const char *suffix = (option_values.use_ogg? ogg_suffix : flac_suffix);
+ strcpy(outfilename, option_values.output_prefix? option_values.output_prefix : "");
strcat(outfilename, infilename);
if(0 == (p = strrchr(outfilename, '.')))
strcat(outfilename, suffix);
@@ -762,44 +1095,44 @@
}
if(0 == forced_outfilename)
forced_outfilename = outfilename;
- if(0 != cmdline_forced_outfilename)
- forced_outfilename = cmdline_forced_outfilename;
+ if(0 != option_values.cmdline_forced_outfilename)
+ forced_outfilename = option_values.cmdline_forced_outfilename;
- common_options.verbose = verbose;
- common_options.skip = skip;
- common_options.verify = verify;
+ common_options.verbose = option_values.verbose;
+ common_options.skip = option_values.skip;
+ common_options.verify = option_values.verify;
#ifdef FLAC__HAS_OGG
- common_options.use_ogg = use_ogg;
+ common_options.use_ogg = option_values.use_ogg;
#endif
- common_options.lax = lax;
- common_options.do_mid_side = do_mid_side;
- common_options.loose_mid_side = loose_mid_side;
- common_options.do_exhaustive_model_search = do_exhaustive_model_search;
- common_options.do_escape_coding = do_escape_coding;
- common_options.do_qlp_coeff_prec_search = do_qlp_coeff_prec_search;
- common_options.min_residual_partition_order = min_residual_partition_order;
- common_options.max_residual_partition_order = max_residual_partition_order;
- common_options.rice_parameter_search_dist = rice_parameter_search_dist;
- common_options.max_lpc_order = max_lpc_order;
- common_options.blocksize = (unsigned)blocksize;
- common_options.qlp_coeff_precision = qlp_coeff_precision;
- common_options.padding = padding;
- common_options.requested_seek_points = requested_seek_points;
- common_options.num_requested_seek_points = num_requested_seek_points;
+ common_options.lax = option_values.lax;
+ common_options.do_mid_side = option_values.do_mid_side;
+ common_options.loose_mid_side = option_values.loose_mid_side;
+ common_options.do_exhaustive_model_search = option_values.do_exhaustive_model_search;
+ common_options.do_escape_coding = option_values.do_escape_coding;
+ common_options.do_qlp_coeff_prec_search = option_values.do_qlp_coeff_prec_search;
+ common_options.min_residual_partition_order = option_values.min_residual_partition_order;
+ common_options.max_residual_partition_order = option_values.max_residual_partition_order;
+ common_options.rice_parameter_search_dist = option_values.rice_parameter_search_dist;
+ common_options.max_lpc_order = option_values.max_lpc_order;
+ common_options.blocksize = (unsigned)option_values.blocksize;
+ common_options.qlp_coeff_precision = option_values.qlp_coeff_precision;
+ common_options.padding = option_values.padding;
+ common_options.requested_seek_points = option_values.requested_seek_points;
+ common_options.num_requested_seek_points = option_values.num_requested_seek_points;
common_options.is_last_file = is_last_file;
common_options.align_reservoir = align_reservoir;
common_options.align_reservoir_samples = &align_reservoir_samples;
- common_options.sector_align = sector_align;
+ common_options.sector_align = option_values.sector_align;
if(fmt == RAW) {
raw_encode_options_t options;
options.common = common_options;
- options.is_big_endian = format_is_big_endian;
- options.is_unsigned_samples = format_is_unsigned_samples;
- options.channels = format_channels;
- options.bps = format_bps;
- options.sample_rate = format_sample_rate;
+ options.is_big_endian = option_values.format_is_big_endian;
+ options.is_unsigned_samples = option_values.format_is_unsigned_samples;
+ options.channels = option_values.format_channels;
+ options.bps = option_values.format_bps;
+ options.sample_rate = option_values.format_sample_rate;
retval = flac__encode_raw(encode_infile, infilesize, infilename, forced_outfilename, lookahead, lookahead_length, options);
}
@@ -817,7 +1150,7 @@
if(retval == 0 && strcmp(infilename, "-")) {
if(strcmp(forced_outfilename, "-"))
flac__file_copy_metadata(infilename, forced_outfilename);
- if(delete_input)
+ if(option_values.delete_input)
unlink(infilename);
}
@@ -833,16 +1166,16 @@
FLAC__bool treat_as_ogg = false;
decode_options_t common_options;
- if(!test_only && !analyze) {
- if(force_raw_format && format_is_big_endian < 0)
- return long_usage("ERROR: for decoding to a raw file you must specify -fb or -fl\n");
+ if(!option_values.test_only && !option_values.analyze) {
+ if(option_values.force_raw_format && option_values.format_is_big_endian < 0)
+ return usage_error("ERROR: for decoding to a raw file you must specify -fb or -fl\n");
}
- if(0 == strcmp(infilename, "-") || force_to_stdout)
+ if(0 == strcmp(infilename, "-") || option_values.force_to_stdout)
strcpy(outfilename, "-");
else {
- const char *suffix = suffixes[analyze? 2 : force_raw_format? 1 : 0];
- strcpy(outfilename, output_prefix? output_prefix : "");
+ const char *suffix = suffixes[option_values.analyze? 2 : option_values.force_raw_format? 1 : 0];
+ strcpy(outfilename, option_values.output_prefix? option_values.output_prefix : "");
strcat(outfilename, infilename);
if(0 == (p = strrchr(outfilename, '.')))
strcat(outfilename, suffix);
@@ -857,10 +1190,10 @@
}
if(0 == forced_outfilename)
forced_outfilename = outfilename;
- if(0 != cmdline_forced_outfilename)
- forced_outfilename = cmdline_forced_outfilename;
+ if(0 != option_values.cmdline_forced_outfilename)
+ forced_outfilename = option_values.cmdline_forced_outfilename;
- if(use_ogg)
+ if(option_values.use_ogg)
treat_as_ogg = true;
else if(0 == strcasecmp(infilename+(strlen(infilename)-4), ".ogg"))
treat_as_ogg = true;
@@ -874,36 +1207,52 @@
}
#endif
- common_options.verbose = verbose;
- common_options.continue_through_decode_errors = continue_through_decode_errors;
+ common_options.verbose = option_values.verbose;
+ common_options.continue_through_decode_errors = option_values.continue_through_decode_errors;
#ifdef FLAC__HAS_OGG
common_options.is_ogg = treat_as_ogg;
#endif
- common_options.skip = skip;
+ common_options.skip = option_values.skip;
- if(!force_raw_format) {
+ if(!option_values.force_raw_format) {
wav_decode_options_t options;
options.common = common_options;
- retval = flac__decode_wav(infilename, test_only? 0 : forced_outfilename, analyze, aopts, options);
+ retval = flac__decode_wav(infilename, option_values.test_only? 0 : forced_outfilename, option_values.analyze, option_values.aopts, options);
}
else {
raw_decode_options_t options;
options.common = common_options;
- options.is_big_endian = format_is_big_endian;
- options.is_unsigned_samples = format_is_unsigned_samples;
+ options.is_big_endian = option_values.format_is_big_endian;
+ options.is_unsigned_samples = option_values.format_is_unsigned_samples;
- retval = flac__decode_raw(infilename, test_only? 0 : forced_outfilename, analyze, aopts, options);
+ retval = flac__decode_raw(infilename, option_values.test_only? 0 : forced_outfilename, option_values.analyze, option_values.aopts, options);
}
if(retval == 0 && strcmp(infilename, "-")) {
if(strcmp(forced_outfilename, "-"))
flac__file_copy_metadata(infilename, forced_outfilename);
- if(delete_input)
+ if(option_values.delete_input)
unlink(infilename);
}
return retval;
}
+
+void die(const char *message)
+{
+ FLAC__ASSERT(0 != message);
+ fprintf(stderr, "ERROR: %s\n", message);
+ exit(1);
+}
+
+char *local_strdup(const char *source)
+{
+ char *ret;
+ FLAC__ASSERT(0 != source);
+ if(0 == (ret = strdup(source)))
+ die("out of memory during strdup()");
+ return ret;
+}