diff options
author | Josh Coalson <jcoalson@users.sourceforce.net> | 2006-11-03 16:16:32 +0000 |
---|---|---|
committer | Josh Coalson <jcoalson@users.sourceforce.net> | 2006-11-03 16:16:32 +0000 |
commit | c5675fb8fcacce61b4b3dc414b8408d4fed5e13f (patch) | |
tree | d5e2d4cfaea2dc7c5ef4186216e992d2f6d1dbdd /src | |
parent | ebd7be8d9a6dfeec1705a499348b666b770b17aa (diff) | |
download | flac-c5675fb8fcacce61b4b3dc414b8408d4fed5e13f.tar.gz |
switch to using FLAC__stream_encoder_set_compression_level()
Diffstat (limited to 'src')
-rw-r--r-- | src/flac/encode.c | 80 | ||||
-rw-r--r-- | src/flac/encode.h | 39 | ||||
-rw-r--r-- | src/flac/main.c | 283 |
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; |