summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJosh Coalson <jcoalson@users.sourceforce.net>2006-11-03 16:16:32 +0000
committerJosh Coalson <jcoalson@users.sourceforce.net>2006-11-03 16:16:32 +0000
commitc5675fb8fcacce61b4b3dc414b8408d4fed5e13f (patch)
treed5e2d4cfaea2dc7c5ef4186216e992d2f6d1dbdd /src
parentebd7be8d9a6dfeec1705a499348b666b770b17aa (diff)
downloadflac-c5675fb8fcacce61b4b3dc414b8408d4fed5e13f.tar.gz
switch to using FLAC__stream_encoder_set_compression_level()
Diffstat (limited to 'src')
-rw-r--r--src/flac/encode.c80
-rw-r--r--src/flac/encode.h39
-rw-r--r--src/flac/main.c283
3 files changed, 169 insertions, 233 deletions
diff --git a/src/flac/encode.c b/src/flac/encode.c
index 2e046fcb..2de8ca42 100644
--- a/src/flac/encode.c
+++ b/src/flac/encode.c
@@ -75,7 +75,6 @@ typedef struct {
FLAC__uint64 total_samples_to_encode;
FLAC__uint64 bytes_written;
FLAC__uint64 samples_written;
- unsigned blocksize;
unsigned stats_mask;
FLAC__StreamEncoder *encoder;
@@ -1531,7 +1530,6 @@ FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC_
e->total_samples_to_encode = 0;
e->bytes_written = 0;
e->samples_written = 0;
- e->blocksize = 0;
e->stats_mask = 0;
e->encoder = 0;
@@ -1629,6 +1627,7 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio
FLAC__StreamMetadata **metadata = static_metadata;
FLAC__StreamEncoderInitStatus init_status;
const FLAC__bool is_cdda = (channels == 1 || channels == 2) && (bps == 16) && (sample_rate == 44100);
+ char apodizations[2000];
FLAC__ASSERT(sizeof(options.pictures)/sizeof(options.pictures[0]) <= 64);
@@ -1637,6 +1636,8 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio
e->bits_per_sample = bps;
e->sample_rate = sample_rate;
+ apodizations[0] = '\0';
+
if(e->replay_gain) {
if(channels != 1 && channels != 2) {
flac__utils_printf(stderr, 1, "%s: ERROR, number of channels (%u) must be 1 or 2 for --replay-gain\n", e->inbasefilename, channels);
@@ -1654,9 +1655,6 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio
}
}
- if(channels != 2)
- options.do_mid_side = options.loose_mid_side = false;
-
if(!parse_cuesheet(&cuesheet, options.cuesheet_filename, e->inbasefilename, is_cdda, e->total_samples_to_encode))
return false;
@@ -1891,26 +1889,66 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio
return false;
}
- e->blocksize = options.blocksize;
- e->stats_mask = (options.do_exhaustive_model_search || options.do_qlp_coeff_prec_search)? 0x0f : 0x3f;
-
FLAC__stream_encoder_set_verify(e->encoder, options.verify);
FLAC__stream_encoder_set_streamable_subset(e->encoder, !options.lax);
- FLAC__stream_encoder_set_do_mid_side_stereo(e->encoder, options.do_mid_side);
- FLAC__stream_encoder_set_loose_mid_side_stereo(e->encoder, options.loose_mid_side);
FLAC__stream_encoder_set_channels(e->encoder, channels);
FLAC__stream_encoder_set_bits_per_sample(e->encoder, bps);
FLAC__stream_encoder_set_sample_rate(e->encoder, sample_rate);
- FLAC__stream_encoder_set_blocksize(e->encoder, options.blocksize);
- FLAC__stream_encoder_set_apodization(e->encoder, options.apodizations);
- FLAC__stream_encoder_set_max_lpc_order(e->encoder, options.max_lpc_order);
- FLAC__stream_encoder_set_qlp_coeff_precision(e->encoder, options.qlp_coeff_precision);
- FLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder, options.do_qlp_coeff_prec_search);
- FLAC__stream_encoder_set_do_escape_coding(e->encoder, options.do_escape_coding);
- FLAC__stream_encoder_set_do_exhaustive_model_search(e->encoder, options.do_exhaustive_model_search);
- FLAC__stream_encoder_set_min_residual_partition_order(e->encoder, options.min_residual_partition_order);
- FLAC__stream_encoder_set_max_residual_partition_order(e->encoder, options.max_residual_partition_order);
- FLAC__stream_encoder_set_rice_parameter_search_dist(e->encoder, options.rice_parameter_search_dist);
+ for(i = 0; i < options.num_compression_settings; i++) {
+ switch(options.compression_settings[i].type) {
+ case CST_BLOCKSIZE:
+ FLAC__stream_encoder_set_blocksize(e->encoder, options.compression_settings[i].value.t_unsigned);
+ break;
+ case CST_COMPRESSION_LEVEL:
+ FLAC__stream_encoder_set_compression_level(e->encoder, options.compression_settings[i].value.t_unsigned);
+ apodizations[0] = '\0';
+ break;
+ case CST_DO_MID_SIDE:
+ FLAC__stream_encoder_set_do_mid_side_stereo(e->encoder, options.compression_settings[i].value.t_bool);
+ break;
+ case CST_LOOSE_MID_SIDE:
+ FLAC__stream_encoder_set_loose_mid_side_stereo(e->encoder, options.compression_settings[i].value.t_bool);
+ break;
+ case CST_APODIZATION:
+ if(strlen(apodizations)+strlen(options.compression_settings[i].value.t_string)+2 >= sizeof(apodizations)) {
+ flac__utils_printf(stderr, 1, "%s: ERROR: too many apodization functions requested\n", e->inbasefilename);
+ if(0 != cuesheet)
+ FLAC__metadata_object_delete(cuesheet);
+ return false;
+ }
+ else {
+ strcat(apodizations, options.compression_settings[i].value.t_string);
+ strcat(apodizations, ";");
+ }
+ break;
+ case CST_MAX_LPC_ORDER:
+ FLAC__stream_encoder_set_max_lpc_order(e->encoder, options.compression_settings[i].value.t_unsigned);
+ break;
+ case CST_QLP_COEFF_PRECISION:
+ FLAC__stream_encoder_set_qlp_coeff_precision(e->encoder, options.compression_settings[i].value.t_unsigned);
+ break;
+ case CST_DO_QLP_COEFF_PREC_SEARCH:
+ FLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder, options.compression_settings[i].value.t_bool);
+ break;
+ case CST_DO_ESCAPE_CODING:
+ FLAC__stream_encoder_set_do_escape_coding(e->encoder, options.compression_settings[i].value.t_bool);
+ break;
+ case CST_DO_EXHAUSTIVE_MODEL_SEARCH:
+ FLAC__stream_encoder_set_do_exhaustive_model_search(e->encoder, options.compression_settings[i].value.t_bool);
+ break;
+ case CST_MIN_RESIDUAL_PARTITION_ORDER:
+ FLAC__stream_encoder_set_min_residual_partition_order(e->encoder, options.compression_settings[i].value.t_unsigned);
+ break;
+ case CST_MAX_RESIDUAL_PARTITION_ORDER:
+ FLAC__stream_encoder_set_max_residual_partition_order(e->encoder, options.compression_settings[i].value.t_unsigned);
+ break;
+ case CST_RICE_PARAMETER_SEARCH_DIST:
+ FLAC__stream_encoder_set_rice_parameter_search_dist(e->encoder, options.compression_settings[i].value.t_unsigned);
+ break;
+ }
+ }
+ if(*apodizations)
+ FLAC__stream_encoder_set_apodization(e->encoder, apodizations);
FLAC__stream_encoder_set_total_samples_estimate(e->encoder, e->total_samples_to_encode);
FLAC__stream_encoder_set_metadata(e->encoder, (num_metadata > 0)? metadata : 0, num_metadata);
@@ -1941,6 +1979,8 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio
else
e->outputfile_opened = true;
+ e->stats_mask = (FLAC__stream_encoder_get_do_exhaustive_model_search(e->encoder) || FLAC__stream_encoder_get_do_qlp_coeff_prec_search(e->encoder))? 0x0f : 0x3f;
+
if(0 != cuesheet)
FLAC__metadata_object_delete(cuesheet);
diff --git a/src/flac/encode.h b/src/flac/encode.h
index 1450253a..9aed30af 100644
--- a/src/flac/encode.h
+++ b/src/flac/encode.h
@@ -33,6 +33,31 @@
extern const int FLAC_ENCODE__DEFAULT_PADDING;
+typedef enum {
+ CST_BLOCKSIZE,
+ CST_COMPRESSION_LEVEL,
+ CST_DO_MID_SIDE,
+ CST_LOOSE_MID_SIDE,
+ CST_APODIZATION,
+ CST_MAX_LPC_ORDER,
+ CST_QLP_COEFF_PRECISION,
+ CST_DO_QLP_COEFF_PREC_SEARCH,
+ CST_DO_ESCAPE_CODING,
+ CST_DO_EXHAUSTIVE_MODEL_SEARCH,
+ CST_MIN_RESIDUAL_PARTITION_ORDER,
+ CST_MAX_RESIDUAL_PARTITION_ORDER,
+ CST_RICE_PARAMETER_SEARCH_DIST
+} compression_setting_type_t;
+
+typedef struct {
+ compression_setting_type_t type;
+ union {
+ FLAC__bool t_bool;
+ unsigned t_unsigned;
+ const char *t_string;
+ } value;
+} compression_setting_t;
+
typedef struct {
utils__SkipUntilSpecification skip_specification;
utils__SkipUntilSpecification until_specification;
@@ -42,19 +67,9 @@ typedef struct {
long serial_number;
#endif
FLAC__bool lax;
- 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;
- unsigned min_residual_partition_order;
- unsigned max_residual_partition_order;
- unsigned rice_parameter_search_dist;
- char *apodizations;
- unsigned max_lpc_order;
- unsigned blocksize;
- unsigned qlp_coeff_precision;
int padding;
+ size_t num_compression_settings;
+ compression_setting_t compression_settings[64];
char *requested_seek_points;
int num_requested_seek_points;
const char *cuesheet_filename;
diff --git a/src/flac/main.c b/src/flac/main.c
index 83aa1a77..4b0a2cdb 100644
--- a/src/flac/main.c
+++ b/src/flac/main.c
@@ -64,6 +64,9 @@ static FLAC__bool 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 void add_compression_setting_bool(compression_setting_type_t type, FLAC__bool value);
+static void add_compression_setting_string(compression_setting_type_t type, const char *value);
+static void add_compression_setting_unsigned(compression_setting_type_t type, unsigned value);
static int usage_error(const char *message, ...);
static void short_usage();
@@ -221,11 +224,6 @@ static struct {
FLAC__bool use_ogg;
FLAC__bool has_serial_number; /* true iff --serial-number was used */
long serial_number; /* this is the Ogg serial number and is unused for native FLAC */
- 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_aiff_format;
FLAC__bool force_raw_format;
@@ -236,9 +234,8 @@ static struct {
const char *output_prefix;
analysis_options aopts;
int padding; /* -1 => no -P options were given, 0 => -P- was given, else -P value */
- char apodizations[1000]; /* bad MAGIC NUMBER but buffer overflow is checked */
- unsigned max_lpc_order;
- unsigned qlp_coeff_precision;
+ size_t num_compression_settings;
+ compression_setting_t compression_settings[64]; /* bad MAGIC NUMBER but buffer overflow is checked */
const char *skip_specification;
const char *until_specification;
const char *cue_specification;
@@ -248,10 +245,6 @@ static struct {
int format_bps;
int format_sample_rate;
off_t format_input_size;
- int blocksize;
- int min_residual_partition_order;
- int max_residual_partition_order;
- int rice_parameter_search_dist;
char requested_seek_points[5000]; /* bad MAGIC NUMBER but buffer overflow is checked */
int num_requested_seek_points; /* -1 => no -S options were given, 0 => -S- was given */
const char *cuesheet_filename;
@@ -334,26 +327,6 @@ int do_it()
* 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;
- }
if(0 != option_values.cue_specification)
return usage_error("ERROR: --cue is not allowed in test mode\n");
}
@@ -373,8 +346,6 @@ int do_it()
if(0 != option_values.cue_specification && (0 != option_values.skip_specification || 0 != option_values.until_specification))
return usage_error("ERROR: --cue may not be combined with --skip or --until\n");
- FLAC__ASSERT(option_values.blocksize >= 0 || option_values.mode_decode);
-
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);
@@ -403,12 +374,6 @@ int do_it()
if(option_values.format_sample_rate >= 0)
return usage_error("ERROR: --sample-rate not allowed with --decode\n");
}
- 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 '%u' for qlp coeff precision, must be 0 or >= %u\n", option_values.qlp_coeff_precision, FLAC__MIN_QLP_COEFF_PRECISION);
- }
if(option_values.sector_align) {
if(option_values.mode_decode)
@@ -464,32 +429,6 @@ int do_it()
flac__utils_printf(stderr, 2, "flac comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n");
flac__utils_printf(stderr, 2, "welcome to redistribute it under certain conditions. Type `flac' for details.\n\n");
- if(!option_values.mode_decode) {
- char padopt[16];
- if(option_values.padding == 0)
- strcpy(padopt, "-");
- else
- sprintf(padopt, " %d", option_values.padding > 0? option_values.padding : FLAC_ENCODE__DEFAULT_PADDING);
- flac__utils_printf(stderr, 2,
- "options:%s%s%s%s -P%s -b %u%s -l %u%s%s%s -q %u -r %u,%u%s\n",
- option_values.delete_input?" --delete-input-file":"",
- option_values.sector_align?" --sector-align":"",
- option_values.use_ogg?" --ogg":"",
- 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,
- option_values.verify? " -V":""
- );
- }
-
if(option_values.mode_decode) {
FLAC__bool first = true;
@@ -570,11 +509,6 @@ FLAC__bool init_options()
option_values.use_ogg = false;
option_values.has_serial_number = false;
option_values.serial_number = 0;
- 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_aiff_format = false;
option_values.force_raw_format = false;
@@ -586,9 +520,7 @@ FLAC__bool init_options()
option_values.aopts.do_residual_text = false;
option_values.aopts.do_residual_gnuplot = false;
option_values.padding = -1;
- option_values.apodizations[0] = '\0';
- option_values.max_lpc_order = 8;
- option_values.qlp_coeff_precision = 0;
+ option_values.num_compression_settings = 0;
option_values.skip_specification = 0;
option_values.until_specification = 0;
option_values.cue_specification = 0;
@@ -598,10 +530,6 @@ FLAC__bool init_options()
option_values.format_bps = -1;
option_values.format_sample_rate = -1;
option_values.format_input_size = (off_t)(-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.cuesheet_filename = 0;
@@ -667,6 +595,7 @@ int parse_option(int short_option, const char *long_option, const char *option_a
{
const char *violation;
char *p;
+ int i;
if(short_option == 0) {
FLAC__ASSERT(0 != long_option);
@@ -857,16 +786,18 @@ int parse_option(int short_option, const char *long_option, const char *option_a
}
#endif
else if(0 == strcmp(long_option, "no-exhaustive-model-search")) {
- option_values.do_exhaustive_model_search = false;
+ add_compression_setting_bool(CST_DO_EXHAUSTIVE_MODEL_SEARCH, false);
}
else if(0 == strcmp(long_option, "no-mid-side")) {
- option_values.do_mid_side = option_values.loose_mid_side = false;
+ add_compression_setting_bool(CST_DO_MID_SIDE, false);
+ add_compression_setting_bool(CST_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;
+ add_compression_setting_bool(CST_DO_MID_SIDE, false);
+ add_compression_setting_bool(CST_LOOSE_MID_SIDE, false);
}
else if(0 == strcmp(long_option, "no-qlp-coeff-prec-search")) {
- option_values.do_qlp_coeff_prec_search = false;
+ add_compression_setting_bool(CST_DO_QLP_COEFF_PREC_SEARCH, false);
}
else if(0 == strcmp(long_option, "no-padding")) {
option_values.padding = 0;
@@ -934,98 +865,15 @@ int parse_option(int short_option, const char *long_option, const char *option_a
return usage_error("ERROR: (-T/--tag) %s\n", violation);
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;
+ add_compression_setting_unsigned(CST_COMPRESSION_LEVEL, short_option-'0');
break;
case '9':
return usage_error("ERROR: compression level '9' is reserved\n");
@@ -1055,61 +903,76 @@ int parse_option(int short_option, const char *long_option, const char *option_a
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; for no padding use -P-\n");
+ return usage_error("ERROR: argument to -%c must be >= 0; for no padding use -%c-\n", short_option, short_option);
break;
case 'b':
FLAC__ASSERT(0 != option_argument);
- option_values.blocksize = atoi(option_argument);
+ i = atoi(option_argument);
+ if((i < (int)FLAC__MIN_BLOCK_SIZE || i > (int)FLAC__MAX_BLOCK_SIZE))
+ return usage_error("ERROR: invalid blocksize (-%c) '%d', must be >= %u and <= %u\n", short_option, i, FLAC__MIN_BLOCK_SIZE, FLAC__MAX_BLOCK_SIZE);
+ add_compression_setting_unsigned(CST_BLOCKSIZE, (unsigned)i);
break;
case 'e':
- option_values.do_exhaustive_model_search = true;
+ add_compression_setting_bool(CST_DO_EXHAUSTIVE_MODEL_SEARCH, true);
break;
case 'E':
- option_values.do_escape_coding = true;
+ add_compression_setting_bool(CST_DO_ESCAPE_CODING, true);
break;
case 'l':
FLAC__ASSERT(0 != option_argument);
- option_values.max_lpc_order = atoi(option_argument);
+ i = atoi(option_argument);
+ if((i < 0 || i > (int)FLAC__MAX_LPC_ORDER))
+ return usage_error("ERROR: invalid LPC order (-%c) '%d', must be >= %u and <= %u\n", short_option, i, 0, FLAC__MAX_LPC_ORDER);
+ add_compression_setting_unsigned(CST_MAX_LPC_ORDER, (unsigned)i);
break;
case 'A':
FLAC__ASSERT(0 != option_argument);
- if(strlen(option_values.apodizations)+strlen(option_argument)+2 >= sizeof(option_values.apodizations)) {
- return usage_error("ERROR: too many apodization functions requested\n");
- }
- else {
- strcat(option_values.apodizations, option_argument);
- strcat(option_values.apodizations, ";");
- }
+ add_compression_setting_string(CST_APODIZATION, option_argument);
break;
case 'm':
- option_values.do_mid_side = true;
- option_values.loose_mid_side = false;
+ add_compression_setting_bool(CST_DO_MID_SIDE, true);
+ add_compression_setting_bool(CST_LOOSE_MID_SIDE, false);
break;
case 'M':
- option_values.loose_mid_side = option_values.do_mid_side = true;
+ add_compression_setting_bool(CST_DO_MID_SIDE, true);
+ add_compression_setting_bool(CST_LOOSE_MID_SIDE, true);
break;
case 'p':
- option_values.do_qlp_coeff_prec_search = true;
+ add_compression_setting_bool(CST_DO_QLP_COEFF_PREC_SEARCH, true);
break;
case 'q':
FLAC__ASSERT(0 != option_argument);
- option_values.qlp_coeff_precision = atoi(option_argument);
+ i = atoi(option_argument);
+ if(i < 0 || (i > 0 && (i < (int)FLAC__MIN_QLP_COEFF_PRECISION || i > (int)FLAC__MAX_QLP_COEFF_PRECISION)))
+ return usage_error("ERROR: invalid value '%d' for qlp coeff precision (-%c), must be 0 or between %u and %u, inclusive\n", i, short_option, FLAC__MIN_QLP_COEFF_PRECISION, FLAC__MAX_QLP_COEFF_PRECISION);
+ add_compression_setting_unsigned(CST_QLP_COEFF_PRECISION, (unsigned)i);
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);
+ add_compression_setting_unsigned(CST_MIN_RESIDUAL_PARTITION_ORDER, 0);
+ i = atoi(option_argument);
+ if(i < 0)
+ return usage_error("ERROR: invalid value '%d' for residual partition order (-%c), must be between 0 and %u, inclusive\n", i, short_option, FLAC__MAX_RICE_PARTITION_ORDER);
+ add_compression_setting_unsigned(CST_MAX_RESIDUAL_PARTITION_ORDER, (unsigned)i);
}
else {
- option_values.min_residual_partition_order = atoi(option_argument);
- option_values.max_residual_partition_order = atoi(++p);
+ i = atoi(option_argument);
+ if(i < 0)
+ return usage_error("ERROR: invalid value '%d' for min residual partition order (-%c), must be between 0 and %u, inclusive\n", i, short_option, FLAC__MAX_RICE_PARTITION_ORDER);
+ add_compression_setting_unsigned(CST_MIN_RESIDUAL_PARTITION_ORDER, (unsigned)i);
+ i = atoi(++p);
+ if(i < 0)
+ return usage_error("ERROR: invalid value '%d' for max residual partition order (-%c), must be between 0 and %u, inclusive\n", i, short_option, FLAC__MAX_RICE_PARTITION_ORDER);
+ add_compression_setting_unsigned(CST_MAX_RESIDUAL_PARTITION_ORDER, (unsigned)i);
}
break;
case 'R':
- FLAC__ASSERT(0 != option_argument);
- option_values.rice_parameter_search_dist = atoi(option_argument);
+ i = atoi(option_argument);
+ if(i < 0)
+ return usage_error("ERROR: invalid value '%d' for Rice parameter search distance (-%c), must be >= 0\n", i, short_option);
+ add_compression_setting_unsigned(CST_RICE_PARAMETER_SEARCH_DIST, (unsigned)i);
break;
default:
FLAC__ASSERT(0);
@@ -1135,6 +998,33 @@ void free_options()
FLAC__metadata_object_delete(option_values.pictures[i]);
}
+void add_compression_setting_bool(compression_setting_type_t type, FLAC__bool value)
+{
+ if(option_values.num_compression_settings >= sizeof(option_values.compression_settings)/sizeof(option_values.compression_settings[0]))
+ die("too many compression settings");
+ option_values.compression_settings[option_values.num_compression_settings].type = type;
+ option_values.compression_settings[option_values.num_compression_settings].value.t_bool = value;
+ option_values.num_compression_settings++;
+}
+
+void add_compression_setting_string(compression_setting_type_t type, const char *value)
+{
+ if(option_values.num_compression_settings >= sizeof(option_values.compression_settings)/sizeof(option_values.compression_settings[0]))
+ die("too many compression settings");
+ option_values.compression_settings[option_values.num_compression_settings].type = type;
+ option_values.compression_settings[option_values.num_compression_settings].value.t_string = value;
+ option_values.num_compression_settings++;
+}
+
+void add_compression_setting_unsigned(compression_setting_type_t type, unsigned value)
+{
+ if(option_values.num_compression_settings >= sizeof(option_values.compression_settings)/sizeof(option_values.compression_settings[0]))
+ die("too many compression settings");
+ option_values.compression_settings[option_values.num_compression_settings].type = type;
+ option_values.compression_settings[option_values.num_compression_settings].value.t_unsigned = value;
+ option_values.num_compression_settings++;
+}
+
int usage_error(const char *message, ...)
{
if(flac__utils_verbosity_ >= 1) {
@@ -1745,19 +1635,10 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
common_options.serial_number = option_values.serial_number++;
#endif
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.apodizations = option_values.apodizations;
- 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.num_compression_settings = option_values.num_compression_settings;
+ FLAC__ASSERT(sizeof(common_options.compression_settings) >= sizeof(option_values.compression_settings));
+ memcpy(common_options.compression_settings, option_values.compression_settings, sizeof(option_values.compression_settings));
common_options.requested_seek_points = option_values.requested_seek_points;
common_options.num_requested_seek_points = option_values.num_requested_seek_points;
common_options.cuesheet_filename = option_values.cuesheet_filename;