100
101
* general options
102
{ "help" , share__no_argument, 0, 'h' },
103
{ "explain" , share__no_argument, 0, 'H' },
104
{ "version" , share__no_argument, 0, 'v' },
105
{ "decode" , share__no_argument, 0, 'd' },
106
{ "analyze" , share__no_argument, 0, 'a' },
107
{ "test" , share__no_argument, 0, 't' },
108
{ "stdout" , share__no_argument, 0, 'c' },
109
{ "silent" , share__no_argument, 0, 's' },
110
{ "totally-silent" , share__no_argument, 0, 0 },
111
{ "warnings-as-errors", share__no_argument, 0, 'w' },
112
{ "force" , share__no_argument, 0, 'f' },
113
{ "delete-input-file" , share__no_argument, 0, 0 },
114
{ "output-prefix" , share__required_argument, 0, 0 },
115
{ "output-name" , share__required_argument, 0, 'o' },
116
{ "skip" , share__required_argument, 0, 0 },
117
{ "until" , share__required_argument, 0, 0 },
118
{ "channel-map" , share__required_argument, 0, 0 }, /* undocumented */
103
{ "help" , share__no_argument, 0, 'h' },
104
{ "explain" , share__no_argument, 0, 'H' },
105
{ "version" , share__no_argument, 0, 'v' },
106
{ "decode" , share__no_argument, 0, 'd' },
107
{ "analyze" , share__no_argument, 0, 'a' },
108
{ "test" , share__no_argument, 0, 't' },
109
{ "stdout" , share__no_argument, 0, 'c' },
110
{ "silent" , share__no_argument, 0, 's' },
111
{ "totally-silent" , share__no_argument, 0, 0 },
112
{ "warnings-as-errors" , share__no_argument, 0, 'w' },
113
{ "force" , share__no_argument, 0, 'f' },
114
{ "delete-input-file" , share__no_argument, 0, 0 },
115
{ "keep-foreign-metadata" , share__no_argument, 0, 0 },
116
{ "output-prefix" , share__required_argument, 0, 0 },
117
{ "output-name" , share__required_argument, 0, 'o' },
118
{ "skip" , share__required_argument, 0, 0 },
119
{ "until" , share__required_argument, 0, 0 },
120
{ "channel-map" , share__required_argument, 0, 0 }, /* undocumented */
121
123
* decoding options
149
151
{ "force-raw-format" , share__no_argument, 0, 0 },
150
152
{ "lax" , share__no_argument, 0, 0 },
151
153
{ "replay-gain" , share__no_argument, 0, 0 },
154
{ "ignore-chunk-sizes" , share__no_argument, 0, 0 },
152
155
{ "sector-align" , share__no_argument, 0, 0 },
153
156
{ "seekpoint" , share__required_argument, 0, 'S' },
154
157
{ "padding" , share__required_argument, 0, 'P' },
186
189
{ "no-force" , share__no_argument, 0, 0 },
187
190
{ "no-seektable" , share__no_argument, 0, 0 },
188
191
{ "no-delete-input-file" , share__no_argument, 0, 0 },
192
{ "no-keep-foreign-metadata" , share__no_argument, 0, 0 },
189
193
{ "no-replay-gain" , share__no_argument, 0, 0 },
194
{ "no-ignore-chunk-sizes" , share__no_argument, 0, 0 },
190
195
{ "no-sector-align" , share__no_argument, 0, 0 },
196
{ "no-utf8-convert" , share__no_argument, 0, 0 },
191
197
{ "no-lax" , share__no_argument, 0, 0 },
192
198
#if FLAC__HAS_OGG
193
199
{ "no-ogg" , share__no_argument, 0, 0 },
383
394
return usage_error("ERROR: --sample-rate not allowed with --decode\n");
397
if(option_values.ignore_chunk_sizes) {
398
if(option_values.mode_decode)
399
return usage_error("ERROR: --ignore-chunk-sizes only allowed for encoding\n");
400
if(0 != option_values.sector_align)
401
return usage_error("ERROR: --ignore-chunk-sizes not allowed with --sector-align\n");
402
if(0 != option_values.until_specification)
403
return usage_error("ERROR: --ignore-chunk-sizes not allowed with --until\n");
404
if(0 != option_values.cue_specification)
405
return usage_error("ERROR: --ignore-chunk-sizes not allowed with --cue\n");
406
if(0 != option_values.cuesheet_filename)
407
return usage_error("ERROR: --ignore-chunk-sizes not allowed with --cuesheet\n");
386
409
if(option_values.sector_align) {
387
410
if(option_values.mode_decode)
388
411
return usage_error("ERROR: --sector-align only allowed for encoding\n");
430
456
if(!option_values.mode_decode && 0 != option_values.cuesheet_filename && option_values.num_files > 1) {
431
457
return usage_error("ERROR: --cuesheet cannot be used when encoding multiple files\n");
459
if(option_values.keep_foreign_metadata) {
460
/* we're not going to try and support the re-creation of broken WAVE files */
461
if(option_values.ignore_chunk_sizes)
462
return usage_error("ERROR: using --keep-foreign-metadata cannot be used with --ignore-chunk-sizes\n");
463
if(option_values.test_only)
464
return usage_error("ERROR: --keep-foreign-metadata is not allowed in test mode\n");
465
if(option_values.analyze)
466
return usage_error("ERROR: --keep-foreign-metadata is not allowed in analyis mode\n");
468
if(option_values.delete_input)
469
return usage_error("ERROR: using --delete-input-file with --keep-foreign-metadata has been disabled until more testing has been done.\n");
470
flac__utils_printf(stderr, 1, "NOTE: --keep-foreign-metadata is a new feature; make sure to test the output file before deleting the original.\n");
435
474
flac__utils_printf(stderr, 2, "\n");
782
834
else if(0 == strcmp(long_option, "no-delete-input-file")) {
783
835
option_values.delete_input = false;
837
else if(0 == strcmp(long_option, "no-keep-foreign-metadata")) {
838
option_values.keep_foreign_metadata = false;
785
840
else if(0 == strcmp(long_option, "no-replay-gain")) {
786
841
option_values.replay_gain = false;
843
else if(0 == strcmp(long_option, "no-ignore-chunk-sizes")) {
844
option_values.ignore_chunk_sizes = false;
788
846
else if(0 == strcmp(long_option, "no-sector-align")) {
789
847
option_values.sector_align = false;
849
else if(0 == strcmp(long_option, "no-utf8-convert")) {
850
option_values.utf8_convert = false;
791
852
else if(0 == strcmp(long_option, "no-lax")) {
792
853
option_values.lax = false;
1132
1196
printf(" -c, --stdout Write output to stdout\n");
1133
1197
printf(" -s, --silent Do not write runtime encode/decode statistics\n");
1134
1198
printf(" --totally-silent Do not print anything, including errors\n");
1199
printf(" --no-utf8-convert Do not convert tags from local charset to UTF-8\n");
1135
1200
printf(" -w, --warnings-as-errors Treat all warnings as errors\n");
1136
1201
printf(" -f, --force Force overwriting of output files\n");
1137
1202
printf(" -o, --output-name=FILENAME Force the output file name\n");
1138
1203
printf(" --output-prefix=STRING Prepend STRING to output names\n");
1139
1204
printf(" --delete-input-file Deletes after a successful encode/decode\n");
1205
printf(" --keep-foreign-metadata Save/restore WAVE or AIFF non-audio chunks\n");
1140
1206
printf(" --skip={#|mm:ss.ss} Skip the given initial samples for each input\n");
1141
1207
printf(" --until={#|[+|-]mm:ss.ss} Stop at the given sample for each input file\n");
1142
1208
#if FLAC__HAS_OGG
1261
1338
printf(" successful encode or decode. If there was an\n");
1262
1339
printf(" error (including a verify error) the input file\n");
1263
1340
printf(" is left intact.\n");
1341
printf(" --keep-foreign-metadata If encoding, save WAVE or AIFF non-audio chunks\n");
1342
printf(" in FLAC metadata. If decoding, restore any saved\n");
1343
printf(" non-audio chunks from FLAC metadata when writing\n");
1344
printf(" the decoded file. Foreign metadata cannot be\n");
1345
printf(" transcoded, e.g. WAVE chunks saved in a FLAC file\n");
1346
printf(" cannot be restored when decoding to AIFF. Input\n");
1347
printf(" and output must be regular files, not stdin/out.\n");
1264
1348
printf(" --skip={#|mm:ss.ss} Skip the first # samples of each input file; can\n");
1265
1349
printf(" be used both for encoding and decoding. The\n");
1266
1350
printf(" alternative form mm:ss.ss can be used to specify\n");
1558
1651
if(!option_values.force_raw_format) {
1559
1652
/* first set format based on name */
1560
1653
if(strlen(infilename) >= 4 && 0 == FLAC__STRCASECMP(infilename+(strlen(infilename)-4), ".wav"))
1562
1655
else if(strlen(infilename) >= 4 && 0 == FLAC__STRCASECMP(infilename+(strlen(infilename)-4), ".aif"))
1564
1657
else if(strlen(infilename) >= 5 && 0 == FLAC__STRCASECMP(infilename+(strlen(infilename)-5), ".aiff"))
1566
1659
else if(strlen(infilename) >= 5 && 0 == FLAC__STRCASECMP(infilename+(strlen(infilename)-5), ".flac"))
1660
input_format = FLAC;
1661
else if(strlen(infilename) >= 4 && 0 == FLAC__STRCASECMP(infilename+(strlen(infilename)-4), ".oga"))
1662
input_format = OGGFLAC;
1568
1663
else if(strlen(infilename) >= 4 && 0 == FLAC__STRCASECMP(infilename+(strlen(infilename)-4), ".ogg"))
1664
input_format = OGGFLAC;
1571
1666
/* attempt to guess the file type based on the first 12 bytes */
1572
1667
if((lookahead_length = fread(lookahead, 1, 12, encode_infile)) < 12) {
1574
format_mistake(infilename, fmt, RAW);
1668
if(input_format != RAW) {
1669
format_mistake(infilename, input_format, RAW);
1575
1670
if(option_values.treat_warnings_as_errors) {
1576
1671
conditional_fclose(encode_infile);
1583
1678
if(!strncmp((const char *)lookahead, "ID3", 3)) {
1587
1682
else if(!strncmp((const char *)lookahead, "RIFF", 4) && !strncmp((const char *)lookahead+8, "WAVE", 4))
1589
1684
else if(!strncmp((const char *)lookahead, "FORM", 4) && !strncmp((const char *)lookahead+8, "AIFF", 4))
1591
1686
else if(!strncmp((const char *)lookahead, "FORM", 4) && !strncmp((const char *)lookahead+8, "AIFC", 4)) {
1593
1688
is_aifc = true;
1595
1690
else if(!memcmp(lookahead, FLAC__STREAM_SYNC_STRING, sizeof(FLAC__STREAM_SYNC_STRING)))
1691
input_format = FLAC;
1597
1692
/* this could be made more accurate by looking at the first packet */
1598
1693
else if(!memcmp(lookahead, "OggS", 4))
1694
input_format = OGGFLAC;
1602
format_mistake(infilename, fmt, RAW);
1696
if(input_format != RAW) {
1697
format_mistake(infilename, input_format, RAW);
1603
1698
if(option_values.treat_warnings_as_errors) {
1604
1699
conditional_fclose(encode_infile);
1708
if(option_values.keep_foreign_metadata) {
1709
if(encode_infile == stdin || option_values.force_to_stdout) {
1710
conditional_fclose(encode_infile);
1711
return usage_error("ERROR: --keep-foreign-metadata cannot be used when encoding from stdin or to stdout\n");
1713
if(input_format != WAV && input_format != AIF) {
1714
conditional_fclose(encode_infile);
1715
return usage_error("ERROR: --keep-foreign-metadata can only be used with WAVE or AIFF input\n");
1614
1720
* Error if output file already exists (and -f not used).
1615
1721
* Use grabbag__file_get_filesize() as a cheap way to check.
1617
1723
if(!option_values.test_only && !option_values.force_file_overwrite && strcmp(outfilename, "-") && grabbag__file_get_filesize(outfilename) != (off_t)(-1)) {
1724
if(input_format == FLAC) {
1619
1725
/* need more detailed error message when re-flac'ing to avoid confusing the user */
1620
1726
flac__utils_printf(stderr, 1,
1621
1727
"ERROR: output file %s already exists.\n\n"
1657
if(option_values.sector_align && (fmt == FLAC || fmt == OGGFLAC)) {
1763
if(option_values.sector_align && (input_format == FLAC || input_format == OGGFLAC)) {
1658
1764
flac__utils_printf(stderr, 1, "ERROR: can't use --sector-align when the input file is FLAC or Ogg FLAC\n");
1659
1765
conditional_fclose(encode_infile);
1662
if(option_values.sector_align && fmt == RAW && infilesize < 0) {
1768
if(option_values.sector_align && input_format == RAW && infilesize < 0) {
1663
1769
flac__utils_printf(stderr, 1, "ERROR: can't use --sector-align when the input size is unknown\n");
1664
1770
conditional_fclose(encode_infile);
1774
if(input_format == RAW) {
1669
1775
if(option_values.format_is_big_endian < 0 || option_values.format_is_unsigned_samples < 0 || option_values.format_channels < 0 || option_values.format_bps < 0 || option_values.format_sample_rate < 0) {
1670
1776
conditional_fclose(encode_infile);
1671
1777
return usage_error("ERROR: for encoding a raw file you must specify a value for --endian, --sign, --channels, --bps, and --sample-rate\n");
1675
if(encode_infile == stdin || option_values.force_to_stdout) {
1781
if(/*@@@@@@why no stdin?*/encode_infile == stdin || option_values.force_to_stdout) {
1676
1782
if(option_values.replay_gain) {
1677
1783
conditional_fclose(encode_infile);
1678
1784
return usage_error("ERROR: --replay-gain cannot be used when encoding to stdout\n");
1731
1838
common_options.debug.disable_constant_subframes = option_values.debug.disable_constant_subframes;
1732
1839
common_options.debug.disable_fixed_subframes = option_values.debug.disable_fixed_subframes;
1733
1840
common_options.debug.disable_verbatim_subframes = option_values.debug.disable_verbatim_subframes;
1841
common_options.debug.do_md5 = option_values.debug.do_md5;
1735
1843
/* if infilename and outfilename point to the same file, we need to write to a temporary file */
1736
1844
if(encode_infile != stdin && grabbag__file_are_same(infilename, outfilename)) {
1737
1845
static const char *tmp_suffix = ".tmp,fl-ac+en'c";
1738
1846
/*@@@@ still a remote possibility that a file with this filename exists */
1739
if(0 == (internal_outfilename = malloc(strlen(outfilename)+strlen(tmp_suffix)+1))) {
1847
if(0 == (internal_outfilename = (char *)safe_malloc_add_3op_(strlen(outfilename), /*+*/strlen(tmp_suffix), /*+*/1))) {
1740
1848
flac__utils_printf(stderr, 1, "ERROR allocating memory for tempfile name\n");
1741
1849
conditional_fclose(encode_infile);
1758
1866
retval = flac__encode_raw(encode_infile, infilesize, infilename, internal_outfilename? internal_outfilename : outfilename, lookahead, lookahead_length, options);
1760
else if(fmt == FLAC || fmt == OGGFLAC) {
1868
else if(input_format == FLAC || input_format == OGGFLAC) {
1761
1869
flac_encode_options_t options;
1763
1871
options.common = common_options;
1765
retval = flac__encode_flac(encode_infile, infilesize, infilename, internal_outfilename? internal_outfilename : outfilename, lookahead, lookahead_length, options, fmt==OGGFLAC);
1873
retval = flac__encode_flac(encode_infile, infilesize, infilename, internal_outfilename? internal_outfilename : outfilename, lookahead, lookahead_length, options, input_format==OGGFLAC);
1768
1876
wav_encode_options_t options;
1770
1878
options.common = common_options;
1879
options.foreign_metadata = 0;
1881
/* read foreign metadata if requested */
1882
if(option_values.keep_foreign_metadata) {
1883
if(0 == (options.foreign_metadata = flac__foreign_metadata_new(input_format==AIF? FOREIGN_BLOCK_TYPE__AIFF : FOREIGN_BLOCK_TYPE__RIFF))) {
1884
flac__utils_printf(stderr, 1, "ERROR: creating foreign metadata object\n");
1885
conditional_fclose(encode_infile);
1890
if(input_format == AIF)
1773
1891
retval = flac__encode_aif(encode_infile, infilesize, infilename, internal_outfilename? internal_outfilename : outfilename, lookahead, lookahead_length, options, is_aifc);
1775
1893
retval = flac__encode_wav(encode_infile, infilesize, infilename, internal_outfilename? internal_outfilename : outfilename, lookahead, lookahead_length, options);
1895
if(options.foreign_metadata)
1896
flac__foreign_metadata_delete(options.foreign_metadata);
1778
1899
if(retval == 0) {
1970
if(option_values.force_raw_format)
1971
output_format = RAW;
1973
option_values.force_aiff_format ||
1974
(strlen(outfilename) >= 4 && 0 == FLAC__STRCASECMP(outfilename+(strlen(outfilename)-4), ".aif")) ||
1975
(strlen(outfilename) >= 5 && 0 == FLAC__STRCASECMP(outfilename+(strlen(outfilename)-5), ".aiff"))
1977
output_format = AIF;
1979
output_format = WAV;
1847
1981
if(!option_values.test_only && !option_values.analyze) {
1848
if(option_values.force_raw_format && (option_values.format_is_big_endian < 0 || option_values.format_is_unsigned_samples < 0))
1982
if(output_format == RAW && (option_values.format_is_big_endian < 0 || option_values.format_is_unsigned_samples < 0))
1849
1983
return usage_error("ERROR: for decoding to a raw file you must specify a value for --endian and --sign\n");
1986
if(option_values.keep_foreign_metadata) {
1987
if(0 == strcmp(infilename, "-") || 0 == strcmp(outfilename, "-"))
1988
return usage_error("ERROR: --keep-foreign-metadata cannot be used when decoding from stdin or to stdout\n");
1989
if(output_format != WAV && output_format != AIF)
1990
return usage_error("ERROR: --keep-foreign-metadata can only be used with WAVE or AIFF output\n");
1852
1993
if(option_values.use_ogg)
1853
1994
treat_as_ogg = true;
1995
else if(strlen(infilename) >= 4 && 0 == FLAC__STRCASECMP(infilename+(strlen(infilename)-4), ".oga"))
1996
treat_as_ogg = true;
1854
1997
else if(strlen(infilename) >= 4 && 0 == FLAC__STRCASECMP(infilename+(strlen(infilename)-4), ".ogg"))
1855
1998
treat_as_ogg = true;
1891
2034
common_options.channel_map_none = option_values.channel_map_none;
1893
if(!option_values.force_raw_format) {
2036
if(output_format == RAW) {
2037
raw_decode_options_t options;
2039
options.common = common_options;
2040
options.is_big_endian = option_values.format_is_big_endian;
2041
options.is_unsigned_samples = option_values.format_is_unsigned_samples;
2043
retval = flac__decode_raw(infilename, option_values.test_only? 0 : outfilename, option_values.analyze, option_values.aopts, options);
1894
2046
wav_decode_options_t options;
1896
2048
options.common = common_options;
1899
option_values.force_aiff_format ||
1900
(strlen(outfilename) >= 4 && 0 == FLAC__STRCASECMP(outfilename+(strlen(outfilename)-4), ".aif")) ||
1901
(strlen(outfilename) >= 5 && 0 == FLAC__STRCASECMP(outfilename+(strlen(outfilename)-5), ".aiff"))
2049
options.foreign_metadata = 0;
2051
/* read foreign metadata if requested */
2052
if(option_values.keep_foreign_metadata) {
2053
if(0 == (options.foreign_metadata = flac__foreign_metadata_new(output_format==AIF? FOREIGN_BLOCK_TYPE__AIFF : FOREIGN_BLOCK_TYPE__RIFF))) {
2054
flac__utils_printf(stderr, 1, "ERROR: creating foreign metadata object\n");
2059
if(output_format == AIF)
1903
2060
retval = flac__decode_aiff(infilename, option_values.test_only? 0 : outfilename, option_values.analyze, option_values.aopts, options);
1905
2062
retval = flac__decode_wav(infilename, option_values.test_only? 0 : outfilename, option_values.analyze, option_values.aopts, options);
1908
raw_decode_options_t options;
1910
options.common = common_options;
1911
options.is_big_endian = option_values.format_is_big_endian;
1912
options.is_unsigned_samples = option_values.format_is_unsigned_samples;
1914
retval = flac__decode_raw(infilename, option_values.test_only? 0 : outfilename, option_values.analyze, option_values.aopts, options);
2064
if(options.foreign_metadata)
2065
flac__foreign_metadata_delete(options.foreign_metadata);
1917
2068
if(retval == 0 && strcmp(infilename, "-")) {