one last pass over the new help system
[flac.git] / src / flac / main.c
1 /* flac - Command-line FLAC encoder/decoder
2  * Copyright (C) 2000,2001,2002  Josh Coalson
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17  */
18
19 #include <ctype.h>
20 #include <stdarg.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #if !defined _MSC_VER && !defined __MINGW32__
25 /* unlink is in stdio.h in VC++ */
26 #include <unistd.h> /* for unlink() */
27 #else
28 #define strcasecmp stricmp
29 #endif
30 #include "FLAC/all.h"
31 #include "analyze.h"
32 #include "decode.h"
33 #include "encode.h"
34 #include "file.h"
35
36 #if 0
37 /*[JEC] was:#if HAVE_GETOPT_LONG*/
38 /*[JEC] see flac/include/share/getopt.h as to why the change */
39 #  include <getopt.h>
40 #else
41 #  include "share/getopt.h"
42 #endif
43
44 typedef enum { RAW, WAV, AIF } FileFormat;
45
46 static int do_it();
47
48 static void init_options();
49 static int parse_options(int argc, char *argv[]);
50 static int parse_option(int short_option, const char *long_option, const char *option_argument);
51 static void free_options();
52
53 static int usage_error(const char *message, ...);
54 static void short_usage();
55 static void show_help();
56 static void show_explain();
57 static void format_mistake(const char *infilename, const char *wrong, const char *right);
58
59 static int encode_file(const char *infilename, const char *forced_outfilename, FLAC__bool is_last_file);
60 static int decode_file(const char *infilename, const char *forced_outfilename);
61
62 static void die(const char *message);
63 static char *local_strdup(const char *source);
64
65
66 /*
67  * FLAC__share__getopt format struct; note that for long options with no
68  * short option equivalent we just set the 'val' field to 0.
69  */
70 static struct FLAC__share__option long_options_[] = {
71         /*
72          * general options
73          */
74         { "help", 0, 0, 'h' },
75         { "decode", 0, 0, 'd' },
76         { "analyze", 0, 0, 'a' },
77         { "test", 0, 0, 't' },
78         { "stdout", 0, 0, 'c' },
79         { "silent", 0, 0, 's' },
80         { "delete-input-file", 0, 0, 0 },
81         { "output-prefix", 1, 0, 0 },
82         { "output-name", 1, 0, 'o' },
83         { "skip", 1, 0, 0 },
84
85         /*
86          * decoding options
87          */
88         { "decode-through-errors", 0, 0, 'F' },
89
90         /*
91          * encoding options
92          */
93         { "compression-level-0", 0, 0, '0' },
94         { "compression-level-1", 0, 0, '1' },
95         { "compression-level-2", 0, 0, '2' },
96         { "compression-level-3", 0, 0, '3' },
97         { "compression-level-4", 0, 0, '4' },
98         { "compression-level-5", 0, 0, '5' },
99         { "compression-level-6", 0, 0, '6' },
100         { "compression-level-7", 0, 0, '7' },
101         { "compression-level-8", 0, 0, '8' },
102         { "compression-level-9", 0, 0, '9' },
103         { "best", 0, 0, '8' },
104         { "fast", 0, 0, '0' },
105         { "super-secret-impractical-compression-level", 0, 0, 0 },
106         { "verify", 0, 0, 'V' },
107         { "force-raw-input", 0, 0, 0 },
108         { "lax", 0, 0, 0 },
109         { "sector-align", 0, 0, 0 },
110         { "seekpoint", 1, 0, 'S' },
111         { "padding", 1, 0, 'P' },
112 #ifdef FLAC__HAS_OGG
113         { "ogg", 0, 0, 0 },
114 #endif
115         { "blocksize", 1, 0, 'b' },
116         { "exhaustive-model-search", 0, 0, 'e' },
117 #if 0
118         /* @@@ deprecated: */
119         { "escape-coding", 0, 0, 'E' },
120 #endif
121         { "max-lpc-order", 1, 0, 'l' },
122         { "mid-side", 0, 0, 'm' },
123         { "adaptive-mid-side", 0, 0, 'M' },
124         { "qlp-coeff-precision-search", 0, 0, 'p' },
125         { "qlp-coeff-precision", 1, 0, 'q' },
126         { "rice-partition-order", 1, 0, 'r' },
127 #if 0
128         /* @@@ deprecated: */
129         { "rice-parameter-search-distance", 1, 0, 'R' },
130 #endif
131         { "endian", 1, 0, 0 },
132         { "channels", 1, 0, 0 },
133         { "bps", 1, 0, 0 },
134         { "sample-rate", 1, 0, 0 },
135         { "sign", 1, 0, 0 },
136
137         /*
138          * analysis options
139          */
140         { "residual-gnu-plot", 0, 0, 0 },
141         { "residual-text", 0, 0, 0 },
142
143         /*
144          * negatives
145          */
146         { "no-decode-through-errors", 0, 0, 0 },
147         { "no-silent", 0, 0, 0 },
148         { "no-seektable", 0, 0, 0 },
149         { "no-delete-input-file", 0, 0, 0 },
150         { "no-sector-align", 0, 0, 0 },
151         { "no-lax", 0, 0, 0 },
152 #ifdef FLAC__HAS_OGG
153         { "no-ogg", 0, 0, 0 },
154 #endif
155         { "no-exhaustive-model-search", 0, 0, 0 },
156 #if 0
157         /* @@@ deprecated: */
158         { "no-escape-coding", 0, 0, 0 },
159 #endif
160         { "no-mid-side", 0, 0, 0 },
161         { "no-adaptive-mid-side", 0, 0, 0 },
162         { "no-qlp-coeff-prec-search", 0, 0, 0 },
163         { "no-padding", 0, 0, 0 },
164         { "no-verify", 0, 0, 0 },
165         { "no-residual-gnuplot", 0, 0, 0 },
166         { "no-residual-text", 0, 0, 0 },
167
168         {0, 0, 0, 0}
169 };
170
171
172 /*
173  * global to hold command-line option values
174  */
175
176 static struct {
177         FLAC__bool show_help;
178         FLAC__bool show_explain;
179         FLAC__bool mode_decode;
180         FLAC__bool verify;
181         FLAC__bool verbose;
182         FLAC__bool continue_through_decode_errors;
183         FLAC__bool lax;
184         FLAC__bool test_only;
185         FLAC__bool analyze;
186         FLAC__bool use_ogg;
187         FLAC__bool do_mid_side;
188         FLAC__bool loose_mid_side;
189         FLAC__bool do_exhaustive_model_search;
190         FLAC__bool do_escape_coding;
191         FLAC__bool do_qlp_coeff_prec_search;
192         FLAC__bool force_to_stdout;
193         FLAC__bool force_raw_format;
194         FLAC__bool delete_input;
195         FLAC__bool sector_align;
196         const char *cmdline_forced_outfilename;
197         const char *output_prefix;
198         analysis_options aopts;
199         int padding;
200         unsigned max_lpc_order;
201         unsigned qlp_coeff_precision;
202         FLAC__uint64 skip;
203         int format_is_big_endian;
204         int format_is_unsigned_samples;
205         int format_channels;
206         int format_bps;
207         int format_sample_rate;
208         int blocksize;
209         int min_residual_partition_order;
210         int max_residual_partition_order;
211         int rice_parameter_search_dist;
212         char requested_seek_points[50000]; /* @@@ bad MAGIC NUMBER */
213         int num_requested_seek_points; /* -1 => no -S options were given, 0 => -S- was given */
214
215         unsigned num_files;
216         char **filenames;
217 } option_values;
218
219
220 /*
221  * miscellaneous globals
222  */
223
224 static FLAC__int32 align_reservoir_0[588], align_reservoir_1[588]; /* for carrying over samples from --sector-align */
225 static FLAC__int32 *align_reservoir[2] = { align_reservoir_0, align_reservoir_1 };
226 static unsigned align_reservoir_samples = 0; /* 0 .. 587 */
227
228 static const char *flac_suffix = ".flac", *ogg_suffix = ".ogg";
229
230
231 int main(int argc, char *argv[])
232 {
233         int retval = 0;
234
235         init_options();
236
237         if((retval = parse_options(argc, argv)) == 0)
238                 retval = do_it();
239
240         free_options();
241
242         return retval;
243 }
244
245 int do_it()
246 {
247         int retval = 0;
248
249         if(option_values.show_explain) {
250                 show_explain();
251                 return 0;
252         }
253         else if(option_values.show_help) {
254                 show_help();
255                 return 0;
256         }
257         else {
258                 if(option_values.num_files == 0) {
259                         short_usage();
260                         return 0;
261                 }
262
263                 /*
264                  * tweak options; validate the values
265                  */
266                 if(!option_values.mode_decode) {
267                         if(option_values.blocksize < 0) {
268                                 if(option_values.max_lpc_order == 0)
269                                         option_values.blocksize = 1152;
270                                 else
271                                         option_values.blocksize = 4608;
272                         }
273                         if(option_values.max_residual_partition_order < 0) {
274                                 if(option_values.blocksize <= 1152)
275                                         option_values.max_residual_partition_order = 2;
276                                 else if(option_values.blocksize <= 2304)
277                                         option_values.max_residual_partition_order = 3;
278                                 else if(option_values.blocksize <= 4608)
279                                         option_values.max_residual_partition_order = 3;
280                                 else
281                                         option_values.max_residual_partition_order = 4;
282                                 option_values.min_residual_partition_order = option_values.max_residual_partition_order;
283                         }
284                         if(option_values.rice_parameter_search_dist < 0) {
285                                 option_values.rice_parameter_search_dist = 0;
286                         }
287                 }
288                 else {
289                         if(option_values.test_only) {
290                                 if(option_values.skip > 0)
291                                         return usage_error("ERROR: --skip is not allowed in test mode\n");
292                         }
293                 }
294
295                 FLAC__ASSERT(option_values.blocksize >= 0 || option_values.mode_decode);
296
297                 if(option_values.format_channels >= 0) {
298                         if(option_values.format_channels == 0 || (unsigned)option_values.format_channels > FLAC__MAX_CHANNELS)
299                                 return usage_error("ERROR: invalid number of channels '%u', must be > 0 and <= %u\n", option_values.format_channels, FLAC__MAX_CHANNELS);
300                 }
301                 if(option_values.format_bps >= 0) {
302                         if(option_values.format_bps != 8 && option_values.format_bps != 16 && option_values.format_bps != 24)
303                                 return usage_error("ERROR: invalid bits per sample '%u' (must be 8/16/24)\n", option_values.format_bps);
304                 }
305                 if(option_values.format_sample_rate >= 0) {
306                         if(!FLAC__format_sample_rate_is_valid(option_values.format_sample_rate))
307                                 return usage_error("ERROR: invalid sample rate '%u', must be > 0 and <= %u\n", option_values.format_sample_rate, FLAC__MAX_SAMPLE_RATE);
308                 }
309                 if(!option_values.mode_decode && ((unsigned)option_values.blocksize < FLAC__MIN_BLOCK_SIZE || (unsigned)option_values.blocksize > FLAC__MAX_BLOCK_SIZE)) {
310                         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);
311                 }
312                 if(option_values.qlp_coeff_precision > 0 && option_values.qlp_coeff_precision < FLAC__MIN_QLP_COEFF_PRECISION) {
313                         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);
314                 }
315
316                 if(option_values.sector_align) {
317                         if(option_values.mode_decode)
318                                 return usage_error("ERROR: --sector-align only allowed for encoding\n");
319                         else if(option_values.skip > 0)
320                                 return usage_error("ERROR: --sector-align not allowed with --skip\n");
321                         else if(option_values.format_channels >= 0 && option_values.format_channels != 2)
322                                 return usage_error("ERROR: --sector-align can only be done with stereo input\n");
323                         else if(option_values.format_bps >= 0 && option_values.format_bps != 16)
324                                 return usage_error("ERROR: --sector-align can only be done with 16-bit samples\n");
325                         else if(option_values.format_sample_rate >= 0 && option_values.format_sample_rate != 44100)
326                                 return usage_error("ERROR: --sector-align can only be done with a sample rate of 44100\n");
327                 }
328                 if(option_values.num_files > 1 && option_values.cmdline_forced_outfilename) {
329                         return usage_error("ERROR: -o/--output-name cannot be used with multiple files\n");
330                 }
331                 if(option_values.cmdline_forced_outfilename && option_values.output_prefix) {
332                         return usage_error("ERROR: --output-prefix conflicts with -o/--output-name\n");
333                 }
334         }
335         if(option_values.verbose) {
336                 fprintf(stderr, "\n");
337                 fprintf(stderr, "flac %s, Copyright (C) 2000,2001,2002 Josh Coalson\n", FLAC__VERSION_STRING);
338                 fprintf(stderr, "flac comes with ABSOLUTELY NO WARRANTY.  This is free software, and you are\n");
339                 fprintf(stderr, "welcome to redistribute it under certain conditions.  Type `flac' for details.\n\n");
340
341                 if(!option_values.mode_decode) {
342                         char padopt[16];
343                         if(option_values.padding < 0)
344                                 strcpy(padopt, "-");
345                         else
346                                 sprintf(padopt, " %d", option_values.padding);
347                         fprintf(stderr,
348                                 "options:%s%s"
349 #ifdef FLAC__HAS_OGG
350                                 "%s"
351 #endif
352                                 "%s -P%s -b %u%s -l %u%s%s%s -q %u -r %u,%u%s\n",
353                                 option_values.delete_input?" --delete-input-file":"",
354                                 option_values.sector_align?" --sector-align":"",
355 #ifdef FLAC__HAS_OGG
356                                 option_values.use_ogg?" --ogg":"",
357 #endif
358                                 option_values.lax?" --lax":"",
359                                 padopt,
360                                 (unsigned)option_values.blocksize,
361                                 option_values.loose_mid_side?" -M":option_values.do_mid_side?" -m":"",
362                                 option_values.max_lpc_order,
363                                 option_values.do_exhaustive_model_search?" -e":"",
364                                 option_values.do_escape_coding?" -E":"",
365                                 option_values.do_qlp_coeff_prec_search?" -p":"",
366                                 option_values.qlp_coeff_precision,
367                                 (unsigned)option_values.min_residual_partition_order,
368                                 (unsigned)option_values.max_residual_partition_order,
369                                 option_values.verify? " -V":""
370                         );
371                 }
372         }
373
374         if(option_values.mode_decode) {
375                 FLAC__bool first = true;
376
377                 if(option_values.num_files == 0) {
378                         retval = decode_file("-", 0);
379                 }
380                 else {
381                         unsigned i;
382                         if(option_values.num_files > 1)
383                                 option_values.cmdline_forced_outfilename = 0;
384                         for(i = 0, retval = 0; i < option_values.num_files && retval == 0; i++) {
385                                 if(0 == strcmp(option_values.filenames[i], "-") && !first)
386                                         continue;
387                                 retval = decode_file(option_values.filenames[i], 0);
388                                 first = false;
389                         }
390                 }
391         }
392         else { /* encode */
393                 FLAC__bool first = true;
394
395                 if(option_values.num_files == 0) {
396                         retval = encode_file("-", 0, true);
397                 }
398                 else {
399                         unsigned i;
400                         if(option_values.num_files > 1)
401                                 option_values.cmdline_forced_outfilename = 0;
402                         for(i = 0, retval = 0; i < option_values.num_files && retval == 0; i++) {
403                                 if(0 == strcmp(option_values.filenames[i], "-") && !first)
404                                         continue;
405                                 retval = encode_file(option_values.filenames[i], 0, i == (option_values.num_files-1));
406                                 first = false;
407                         }
408                 }
409         }
410
411         return retval;
412 }
413
414 void init_options()
415 {
416         option_values.show_help = false;
417         option_values.show_explain = false;
418         option_values.mode_decode = false;
419         option_values.verify = false;
420         option_values.verbose = true;
421         option_values.continue_through_decode_errors = false;
422         option_values.lax = false;
423         option_values.test_only = false;
424         option_values.analyze = false;
425         option_values.use_ogg = false;
426         option_values.do_mid_side = true;
427         option_values.loose_mid_side = false;
428         option_values.do_exhaustive_model_search = false;
429         option_values.do_escape_coding = false;
430         option_values.do_qlp_coeff_prec_search = false;
431         option_values.force_to_stdout = false;
432         option_values.force_raw_format = false;
433         option_values.delete_input = false;
434         option_values.sector_align = false;
435         option_values.cmdline_forced_outfilename = 0;
436         option_values.output_prefix = 0;
437         option_values.aopts.do_residual_text = false;
438         option_values.aopts.do_residual_gnuplot = false;
439         option_values.padding = -1;
440         option_values.max_lpc_order = 8;
441         option_values.qlp_coeff_precision = 0;
442         option_values.skip = 0;
443         option_values.format_is_big_endian = -1;
444         option_values.format_is_unsigned_samples = false;
445         option_values.format_channels = -1;
446         option_values.format_bps = -1;
447         option_values.format_sample_rate = -1;
448         option_values.blocksize = -1;
449         option_values.min_residual_partition_order = -1;
450         option_values.max_residual_partition_order = -1;
451         option_values.rice_parameter_search_dist = -1;
452         option_values.requested_seek_points[0] = '\0';
453         option_values.num_requested_seek_points = -1;
454
455         option_values.num_files = 0;
456         option_values.filenames = 0;
457 }
458
459 int parse_options(int argc, char *argv[])
460 {
461         int short_option;
462         int option_index = 1;
463         FLAC__bool had_error = false;
464         /*@@@ E and R: are deprecated */
465         const char *short_opts = "0123456789ab:cdeFhHl:mMo:pP:q:r:sS:tV";
466
467         while ((short_option = FLAC__share__getopt_long(argc, argv, short_opts, long_options_, &option_index)) != -1) {
468                 switch (short_option) {
469                         case 0: /* long option with no equivalent short option */
470                                 had_error |= (parse_option(short_option, long_options_[option_index].name, FLAC__share__optarg) != 0);
471                                 break;
472                         case '?':
473                         case ':':
474                                 had_error = true;
475                                 break;
476                         default: /* short option */
477                                 had_error |= (parse_option(short_option, 0, FLAC__share__optarg) != 0);
478                                 break;
479                 }
480         }
481
482         if(had_error) {
483                 return 1;
484         }
485
486         FLAC__ASSERT(FLAC__share__optind <= argc);
487
488         option_values.num_files = argc - FLAC__share__optind;
489
490         if(option_values.num_files > 0) {
491                 unsigned i = 0;
492                 if(0 == (option_values.filenames = malloc(sizeof(char *) * option_values.num_files)))
493                         die("out of memory allocating space for file names list");
494                 while(FLAC__share__optind < argc)
495                         option_values.filenames[i++] = local_strdup(argv[FLAC__share__optind++]);
496         }
497
498         return 0;
499 }
500
501 int parse_option(int short_option, const char *long_option, const char *option_argument)
502 {
503         char *p;
504
505         if(short_option == 0) {
506                 FLAC__ASSERT(0 != long_option);
507                 if(0 == strcmp(long_option, "delete-input-file")) {
508                         option_values.delete_input = true;
509                 }
510                 else if(0 == strcmp(long_option, "output-prefix")) {
511                         FLAC__ASSERT(0 != option_argument);
512                         option_values.output_prefix = option_argument;
513                 }
514                 else if(0 == strcmp(long_option, "skip")) {
515                         FLAC__ASSERT(0 != option_argument);
516                         option_values.skip = (FLAC__uint64)atoi(option_argument); /* @@@ takes a pretty damn big file to overflow atoi() here, but it could happen */
517                 }
518                 else if(0 == strcmp(long_option, "super-secret-impractical-compression-level")) {
519                         option_values.do_exhaustive_model_search = true;
520                         option_values.do_escape_coding = true;
521                         option_values.do_mid_side = true;
522                         option_values.loose_mid_side = false;
523                         option_values.do_qlp_coeff_prec_search = true;
524                         option_values.min_residual_partition_order = 0;
525                         option_values.max_residual_partition_order = 16;
526                         option_values.rice_parameter_search_dist = 0;
527                         option_values.max_lpc_order = 32;
528                 }
529                 else if(0 == strcmp(long_option, "force-raw-input")) {
530                         option_values.force_raw_format = true;
531                 }
532                 else if(0 == strcmp(long_option, "lax")) {
533                         option_values.lax = true;
534                 }
535                 else if(0 == strcmp(long_option, "sector-align")) {
536                         option_values.sector_align = true;
537                 }
538 #ifdef FLAC__HAS_OGG
539                 else if(0 == strcmp(long_option, "ogg")) {
540                         option_values.use_ogg = true;
541                 }
542 #endif
543                 else if(0 == strcmp(long_option, "endian")) {
544                         FLAC__ASSERT(0 != option_argument);
545                         if(0 == strncmp(option_argument, "big", strlen(option_argument)))
546                                 option_values.format_is_big_endian = true;
547                         else if(0 == strncmp(option_argument, "little", strlen(option_argument)))
548                                 option_values.format_is_big_endian = false;
549                         else
550                                 return usage_error("ERROR: argument to --endian must be \"big\" or \"little\"\n");
551                 }
552                 else if(0 == strcmp(long_option, "channels")) {
553                         FLAC__ASSERT(0 != option_argument);
554                         option_values.format_channels = atoi(option_argument);
555                 }
556                 else if(0 == strcmp(long_option, "bps")) {
557                         FLAC__ASSERT(0 != option_argument);
558                         option_values.format_bps = atoi(option_argument);
559                 }
560                 else if(0 == strcmp(long_option, "sample-rate")) {
561                         FLAC__ASSERT(0 != option_argument);
562                         option_values.format_sample_rate = atoi(option_argument);
563                 }
564                 else if(0 == strcmp(long_option, "sign")) {
565                         FLAC__ASSERT(0 != option_argument);
566                         if(0 == strncmp(option_argument, "signed", strlen(option_argument)))
567                                 option_values.format_is_unsigned_samples = false;
568                         else if(0 == strncmp(option_argument, "unsigned", strlen(option_argument)))
569                                 option_values.format_is_unsigned_samples = true;
570                         else
571                                 return usage_error("ERROR: argument to --sign must be \"signed\" or \"unsigned\"\n");
572                 }
573                 else if(0 == strcmp(long_option, "residual-gnu-plot")) {
574                         option_values.aopts.do_residual_gnuplot = true;
575                 }
576                 else if(0 == strcmp(long_option, "residual-text")) {
577                         option_values.aopts.do_residual_text = true;
578                 }
579                 /*
580                  * negatives
581                  */
582                 else if(0 == strcmp(long_option, "no-decode-through-errors")) {
583                         option_values.continue_through_decode_errors = false;
584                 }
585                 else if(0 == strcmp(long_option, "no-silent")) {
586                         option_values.verbose = true;
587                 }
588                 else if(0 == strcmp(long_option, "no-seektable")) {
589                         option_values.num_requested_seek_points = 0;
590                         option_values.requested_seek_points[0] = '\0';
591                 }
592                 else if(0 == strcmp(long_option, "no-delete-input-file")) {
593                         option_values.delete_input = false;
594                 }
595                 else if(0 == strcmp(long_option, "no-sector-align")) {
596                         option_values.sector_align = false;
597                 }
598                 else if(0 == strcmp(long_option, "no-lax")) {
599                         option_values.lax = false;
600                 }
601 #ifdef FLAC__HAS_OGG
602                 else if(0 == strcmp(long_option, "no-ogg")) {
603                         option_values.use_ogg = false;
604                 }
605 #endif
606                 else if(0 == strcmp(long_option, "no-exhaustive-model-search")) {
607                         option_values.do_exhaustive_model_search = false;
608                 }
609 #if 0
610                 /* @@@ deprecated: */
611                 else if(0 == strcmp(long_option, "no-escape-coding")) {
612                         option_values.do_escape_coding = false;
613                 }
614 #endif
615                 else if(0 == strcmp(long_option, "no-mid-side")) {
616                         option_values.do_mid_side = option_values.loose_mid_side = false;
617                 }
618                 else if(0 == strcmp(long_option, "no-adaptive-mid-side")) {
619                         option_values.loose_mid_side = option_values.do_mid_side = false;
620                 }
621                 else if(0 == strcmp(long_option, "no-qlp-coeff-prec-search")) {
622                         option_values.do_qlp_coeff_prec_search = false;
623                 }
624                 else if(0 == strcmp(long_option, "no-padding")) {
625                         option_values.padding = -1;
626                 }
627                 else if(0 == strcmp(long_option, "no-verify")) {
628                         option_values.verify = false;
629                 }
630                 else if(0 == strcmp(long_option, "no-residual-gnuplot")) {
631                         option_values.aopts.do_residual_gnuplot = false;
632                 }
633                 else if(0 == strcmp(long_option, "no-residual-text")) {
634                         option_values.aopts.do_residual_text = false;
635                 }
636         }
637         else {
638                 switch(short_option) {
639                         case 'h':
640                                 option_values.show_help = true;
641                                 break;
642                         case 'H':
643                                 option_values.show_explain = true;
644                                 break;
645                         case 'd':
646                                 option_values.mode_decode = true;
647                                 break;
648                         case 'a':
649                                 option_values.mode_decode = true;
650                                 option_values.analyze = true;
651                                 break;
652                         case 't':
653                                 option_values.mode_decode = true;
654                                 option_values.test_only = true;
655                                 break;
656                         case 'c':
657                                 option_values.force_to_stdout = true;
658                                 break;
659                         case 's':
660                                 option_values.verbose = false;
661                                 break;
662                         case 'o':
663                                 FLAC__ASSERT(0 != option_argument);
664                                 option_values.cmdline_forced_outfilename = option_argument;
665                                 break;
666                         case 'F':
667                                 option_values.continue_through_decode_errors = true;
668                                 break;
669                         case '0':
670                                 option_values.do_exhaustive_model_search = false;
671                                 option_values.do_escape_coding = false;
672                                 option_values.do_mid_side = false;
673                                 option_values.loose_mid_side = false;
674                                 option_values.qlp_coeff_precision = 0;
675                                 option_values.min_residual_partition_order = option_values.max_residual_partition_order = 2;
676                                 option_values.rice_parameter_search_dist = 0;
677                                 option_values.max_lpc_order = 0;
678                                 break;
679                         case '1':
680                                 option_values.do_exhaustive_model_search = false;
681                                 option_values.do_escape_coding = false;
682                                 option_values.do_mid_side = true;
683                                 option_values.loose_mid_side = true;
684                                 option_values.qlp_coeff_precision = 0;
685                                 option_values.min_residual_partition_order = option_values.max_residual_partition_order = 2;
686                                 option_values.rice_parameter_search_dist = 0;
687                                 option_values.max_lpc_order = 0;
688                                 break;
689                         case '2':
690                                 option_values.do_exhaustive_model_search = false;
691                                 option_values.do_escape_coding = false;
692                                 option_values.do_mid_side = true;
693                                 option_values.loose_mid_side = false;
694                                 option_values.qlp_coeff_precision = 0;
695                                 option_values.min_residual_partition_order = 0;
696                                 option_values.max_residual_partition_order = 3;
697                                 option_values.rice_parameter_search_dist = 0;
698                                 option_values.max_lpc_order = 0;
699                                 break;
700                         case '3':
701                                 option_values.do_exhaustive_model_search = false;
702                                 option_values.do_escape_coding = false;
703                                 option_values.do_mid_side = false;
704                                 option_values.loose_mid_side = false;
705                                 option_values.qlp_coeff_precision = 0;
706                                 option_values.min_residual_partition_order = option_values.max_residual_partition_order = 3;
707                                 option_values.rice_parameter_search_dist = 0;
708                                 option_values.max_lpc_order = 6;
709                                 break;
710                         case '4':
711                                 option_values.do_exhaustive_model_search = false;
712                                 option_values.do_escape_coding = false;
713                                 option_values.do_mid_side = true;
714                                 option_values.loose_mid_side = true;
715                                 option_values.qlp_coeff_precision = 0;
716                                 option_values.min_residual_partition_order = option_values.max_residual_partition_order = 3;
717                                 option_values.rice_parameter_search_dist = 0;
718                                 option_values.max_lpc_order = 8;
719                                 break;
720                         case '5':
721                                 option_values.do_exhaustive_model_search = false;
722                                 option_values.do_escape_coding = false;
723                                 option_values.do_mid_side = true;
724                                 option_values.loose_mid_side = false;
725                                 option_values.qlp_coeff_precision = 0;
726                                 option_values.min_residual_partition_order = option_values.max_residual_partition_order = 3;
727                                 option_values.rice_parameter_search_dist = 0;
728                                 option_values.max_lpc_order = 8;
729                                 break;
730                         case '6':
731                                 option_values.do_exhaustive_model_search = false;
732                                 option_values.do_escape_coding = false;
733                                 option_values.do_mid_side = true;
734                                 option_values.loose_mid_side = false;
735                                 option_values.qlp_coeff_precision = 0;
736                                 option_values.min_residual_partition_order = 0;
737                                 option_values.max_residual_partition_order = 4;
738                                 option_values.rice_parameter_search_dist = 0;
739                                 option_values.max_lpc_order = 8;
740                                 break;
741                         case '7':
742                                 option_values.do_exhaustive_model_search = true;
743                                 option_values.do_escape_coding = false;
744                                 option_values.do_mid_side = true;
745                                 option_values.loose_mid_side = false;
746                                 option_values.qlp_coeff_precision = 0;
747                                 option_values.min_residual_partition_order = 0;
748                                 option_values.max_residual_partition_order = 6;
749                                 option_values.rice_parameter_search_dist = 0;
750                                 option_values.max_lpc_order = 8;
751                                 break;
752                         case '8':
753                                 option_values.do_exhaustive_model_search = true;
754                                 option_values.do_escape_coding = false;
755                                 option_values.do_mid_side = true;
756                                 option_values.loose_mid_side = false;
757                                 option_values.qlp_coeff_precision = 0;
758                                 option_values.min_residual_partition_order = 0;
759                                 option_values.max_residual_partition_order = 6;
760                                 option_values.rice_parameter_search_dist = 0;
761                                 option_values.max_lpc_order = 12;
762                                 break;
763                         case '9':
764                                 return usage_error("ERROR: compression level '9' is reserved\n");
765                         case 'V':
766                                 option_values.verify = true;
767                                 break;
768                         case 'S':
769                                 FLAC__ASSERT(0 != option_argument);
770                                 if(option_values.num_requested_seek_points < 0)
771                                         option_values.num_requested_seek_points = 0;
772                                 option_values.num_requested_seek_points++;
773                                 strcat(option_values.requested_seek_points, option_argument);
774                                 strcat(option_values.requested_seek_points, "<");
775                                 break;
776                         case 'P':
777                                 FLAC__ASSERT(0 != option_argument);
778                                 option_values.padding = atoi(option_argument);
779                                 if(option_values.padding < 0)
780                                         return usage_error("ERROR: argument to -P must be >= 0\n");
781                                 break;
782                         case 'b':
783                                 FLAC__ASSERT(0 != option_argument);
784                                 option_values.blocksize = atoi(option_argument);
785                                 break;
786                         case 'e':
787                                 option_values.do_exhaustive_model_search = true;
788                                 break;
789                         case 'E':
790                                 option_values.do_escape_coding = true;
791                                 break;
792                         case 'l':
793                                 FLAC__ASSERT(0 != option_argument);
794                                 option_values.max_lpc_order = atoi(option_argument);
795                                 break;
796                         case 'm':
797                                 option_values.do_mid_side = true;
798                                 option_values.loose_mid_side = false;
799                                 break;
800                         case 'M':
801                                 option_values.loose_mid_side = option_values.do_mid_side = true;
802                                 break;
803                         case 'p':
804                                 option_values.do_qlp_coeff_prec_search = true;
805                                 break;
806                         case 'q':
807                                 FLAC__ASSERT(0 != option_argument);
808                                 option_values.qlp_coeff_precision = atoi(option_argument);
809                                 break;
810                         case 'r':
811                                 FLAC__ASSERT(0 != option_argument);
812                                 p = strchr(option_argument, ',');
813                                 if(0 == p) {
814                                         option_values.min_residual_partition_order = 0;
815                                         option_values.max_residual_partition_order = atoi(option_argument);
816                                 }
817                                 else {
818                                         option_values.min_residual_partition_order = atoi(option_argument);
819                                         option_values.max_residual_partition_order = atoi(++p);
820                                 }
821                                 break;
822                         case 'R':
823                                 FLAC__ASSERT(0 != option_argument);
824                                 option_values.rice_parameter_search_dist = atoi(option_argument);
825                                 break;
826                         default:
827                                 FLAC__ASSERT(0);
828                 }
829         }
830
831         return 0;
832 }
833
834 void free_options()
835 {
836         if(0 != option_values.filenames)
837                 free(option_values.filenames);
838 }
839
840 int usage_error(const char *message, ...)
841 {
842         va_list args;
843
844         FLAC__ASSERT(0 != message);
845
846         va_start(args, message);
847
848         (void) vfprintf(stderr, message, args);
849
850         va_end(args);
851
852         printf("Type \"flac\" for a usage summary or \"flac --help\" for all options\n");
853
854         return 1;
855 }
856
857 static void usage_header()
858 {
859         printf("===============================================================================\n");
860         printf("flac - Command-line FLAC encoder/decoder version %s\n", FLAC__VERSION_STRING);
861         printf("Copyright (C) 2000,2001,2002  Josh Coalson\n");
862         printf("\n");
863         printf("This program is free software; you can redistribute it and/or\n");
864         printf("modify it under the terms of the GNU General Public License\n");
865         printf("as published by the Free Software Foundation; either version 2\n");
866         printf("of the License, or (at your option) any later version.\n");
867         printf("\n");
868         printf("This program is distributed in the hope that it will be useful,\n");
869         printf("but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
870         printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n");
871         printf("GNU General Public License for more details.\n");
872         printf("\n");
873         printf("You should have received a copy of the GNU General Public License\n");
874         printf("along with this program; if not, write to the Free Software\n");
875         printf("Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\n");
876         printf("===============================================================================\n");
877 }
878
879 static void usage_summary()
880 {
881         printf("Usage:\n");
882         printf("\n");
883         printf(" Encoding: flac [-s] [--skip #] [<encoding/format-options>] [INPUTFILE [...]]\n");
884         printf(" Decoding: flac -d [-s] [--skip #] [-F] [<format-options>] [INPUTFILE [...]]\n");
885         printf("  Testing: flac -t [-s] [INPUTFILE [...]]\n");
886         printf("Analyzing: flac -a [-s] [--skip #] [<analysis-options>] [INPUTFILE [...]]\n");
887         printf("\n");
888 }
889
890 void short_usage()
891 {
892         usage_header();
893         printf("\n");
894         printf("This is the short help; for all options use 'flac --help'; for even more\n");
895         printf("instructions use 'flac --explain'\n");
896         printf("\n");
897         printf("To encode:\n");
898         printf("  flac [-#] [INPUTFILE [...]]\n");
899         printf("\n");
900         printf("  -# is -0 (fastest compression) to -8 (highest compression); -5 is the default\n");
901         printf("\n");
902         printf("To decode:\n");
903         printf("  flac -d [INPUTFILE [...]]\n");
904         printf("\n");
905         printf("To test:\n");
906         printf("  flac -t [INPUTFILE [...]]\n");
907 }
908
909 void show_help()
910 {
911         usage_header();
912         usage_summary();
913         printf("generic options:\n");
914         printf("  -h, --help                   Show this screen\n");
915         printf("  -H, --explain                Show detailed explanation of usage and options\n");
916         printf("  -d, --decode                 Decode (the default behavior is to encode)\n");
917         printf("  -t, --test                   Same as -d except no decoded file is written\n");
918         printf("  -a, --analyze                Same as -d except an analysis file is written\n");
919         printf("  -c, --stdout                 Write output to stdout\n");
920         printf("  -s, --silent                 Do not write runtime encode/decode statistics\n");
921         printf("  -o, --output-name=FILENAME   Force the output file name\n");
922         printf("      --output-prefix=STRING   Prepend STRING to output names\n");
923         printf("      --delete-input-file      Deletes after a successful encode/decode\n");
924         printf("      --skip=#                 Skip the first # samples of each input file\n");
925         printf("analysis options:\n");
926         printf("      --residual-text          Include residual signal in text output\n");
927         printf("      --residual-gnuplot       Generate gnuplot files of residual distribution\n");
928         printf("decoding options:\n");
929         printf("  -F, --decode-through-errors  Continue decoding through stream errors\n");
930         printf("encoding options:\n");
931         printf("  -V, --verify                 Verify a correct encoding\n");
932 #ifdef FLAC__HAS_OGG
933         printf("      --ogg                    Use Ogg as transport layer\n");
934 #endif
935         printf("      --lax                    Allow encoder to generate non-Subset files\n");
936         printf("      --sector-align           Align multiple files on sector boundaries\n");
937         printf("  -S, --seekpoint={#|X|#x}     Add seek point(s)\n");
938         printf("  -P, --padding=#              Write a PADDING block of length #\n");
939         printf("  -b, --blocksize=#            Specify blocksize in samples\n");
940         printf("  -m, --mid-side               Try mid-side coding for each frame\n");
941         printf("  -M, --adaptive-mid-side      Adaptive mid-side coding for all frames\n");
942         printf("  -0, --compression-level-0, --fast  Synonymous with -l 0 -b 1152 -r 2,2\n");
943         printf("  -1, --compression-level-1          Synonymous with -l 0 -b 1152 -M -r 2,2\n");
944         printf("  -2, --compression-level-2          Synonymous with -l 0 -b 1152 -m -r 3\n");
945         printf("  -3, --compression-level-3          Synonymous with -l 6 -b 4608 -r 3,3\n");
946         printf("  -4, --compression-level-4          Synonymous with -l 8 -b 4608 -M -r 3,3\n");
947         printf("  -5, --compression-level-5          Synonymous with -l 8 -b 4608 -m -r 3,3\n");
948         printf("  -6, --compression-level-6          Synonymous with -l 8 -b 4608 -m -r 4\n");
949         printf("  -7, --compression-level-7          Synonymous with -l 8 -b 4608 -m -e -r 6\n");
950         printf("  -8, --compression-level-8, --best  Synonymous with -l 12 -b 4608 -m -e -r 6\n");
951         printf("  -e, --exhaustive-model-search      Do exhaustive model search (expensive!)\n");
952 #if 0
953         /*@@@ deprecated: */
954         printf("  -E, --escape-coding                Do escape coding in the entropy coder\n");
955 #endif
956         printf("  -l, --max-lpc-order=#              Max LPC order; 0 => only fixed predictors\n");
957         printf("  -p, --qlp-coeff-precision-search   Exhaustively search LP coeff quantization\n");
958         printf("  -q, --qlp-coeff-precision=#        Specify precision in bits\n");
959         printf("  -r, --rice-partition-order=[#,]#   Set [min,]max residual partition order\n");
960 #if 0
961         /*@@@ deprecated: */
962         printf("  -R, -rice-parameter-search-distance=#   Rice parameter search distance\n");
963 #endif
964         printf("format options:\n");
965         printf("      --endian={big|little}    Set byte order for samples\n");
966         printf("      --channels=#             Number of channels\n");
967         printf("      --bps=#                  Number of bits per sample\n");
968         printf("      --sample-rate=#          Sample rate in Hz\n");
969         printf("      --sign={signed|unsigned} Sign of samples\n");
970         printf("      --force-raw-input        Force input to be treated as raw samples\n");
971         printf("negative options:\n");
972         printf("      --no-adaptive-mid-side\n");
973         printf("      --no-decode-through-errors\n");
974         printf("      --no-delete-input-file\n");
975 #if 0
976 /* @@@ deprecated: */
977         printf("      --no-escape-coding\n");
978 #endif
979         printf("      --no-exhaustive-model-search\n");
980         printf("      --no-lax\n");
981         printf("      --no-mid-side\n");
982 #ifdef FLAC__HAS_OGG
983         printf("      --no-ogg\n");
984 #endif
985         printf("      --no-padding\n");
986         printf("      --no-qlp-coeff-prec-search\n");
987         printf("      --no-residual-gnuplot\n");
988         printf("      --no-residual-text\n");
989         printf("      --no-sector-align\n");
990         printf("      --no-seektable\n");
991         printf("      --no-silent\n");
992         printf("      --no-verify\n");
993 }
994
995 void show_explain()
996 {
997         usage_header();
998         usage_summary();
999         printf("For encoding:\n");
1000         printf("  The input file(s) may be a PCM RIFF WAVE file, AIFF file, or raw samples.\n");
1001         printf("  The output file(s) will be in native FLAC or Ogg FLAC format\n");
1002         printf("For decoding, the reverse is true.\n");
1003         printf("\n");
1004         printf("A single INPUTFILE may be - for stdin.  No INPUTFILE implies stdin.  Use of\n");
1005         printf("stdin implies -c (write to stdout).  Normally you should use:\n");
1006         printf("   flac [options] -o outfilename  or  flac -d [options] -o outfilename\n");
1007         printf("instead of:\n");
1008         printf("   flac [options] > outfilename   or  flac -d [options] > outfilename\n");
1009         printf("since the former allows flac to seek backwards to write the STREAMINFO or\n");
1010         printf("WAVE/AIFF header contents when necessary.\n");
1011         printf("\n");
1012         printf("flac checks for the presence of a AIFF/WAVE header to decide whether or not to\n");
1013         printf("treat an input file as AIFF/WAVE format or raw samples.  If any input file is\n");
1014         printf("raw you must specify the format options {-fb|fl} -fc -fp and -fs, which will\n");
1015         printf("apply to all raw files.  You can force AIFF/WAVE files to be treated as raw\n");
1016         printf("files using -fr.\n");
1017         printf("\n");
1018         printf("generic options:\n");
1019         printf("  -h, --help                   Show basic usage a list of all options\n");
1020         printf("  -H, --explain                Show this screen\n");
1021         printf("  -d, --decode                 Decode (the default behavior is to encode)\n");
1022         printf("  -t, --test                   Same as -d except no decoded file is written\n");
1023         printf("  -a, --analyze                Same as -d except an analysis file is written\n");
1024         printf("  -c, --stdout                 Write output to stdout\n");
1025         printf("  -s, --silent                 Do not write runtime encode/decode statistics\n");
1026         printf("  -o, --output-name=FILENAME   Force the output file name; usually flac just\n");
1027         printf("                               changes the extension.  May only be used when\n");
1028         printf("                               encoding a single file.  May not be used in\n");
1029         printf("                               conjunction with --output-prefix.\n");
1030         printf("      --output-prefix=STRING   Prefix each output file name with the given\n");
1031         printf("                               STRING.  This can be useful for encoding or\n");
1032         printf("                               decoding files to a different directory.  Make\n");
1033         printf("                               sure if your STRING is a path name that it ends\n");
1034         printf("                               with a '/' slash.\n");
1035         printf("      --delete-input-file      Automatically delete the input file after a\n");
1036         printf("                               successful encode or decode.  If there was an\n");
1037         printf("                               error (including a verify error) the input file\n");
1038         printf("                               is left intact.\n");
1039         printf("      --skip=#                 Skip the first # samples of each input file; can\n");
1040         printf("                               be used both for encoding and decoding\n");
1041         printf("analysis options:\n");
1042         printf("      --residual-text          Include residual signal in text output.  This will make the file very big, much larger than even the decoded file.\n");
1043         printf("      --residual-gnuplot       Generate gnuplot files of residual distribution\n");
1044         printf("                               of each subframe\n");
1045         printf("decoding options:\n");
1046         printf("  -F, --decode-through-errors  By default flac stops decoding with an error and removes the partially decoded file if it encounters a bitstream error.  With -F, errors are still printed but flac will continue decoding to completion.  Note that errors may cause the decoded audio to be missing some samples or have silent sections.\n");
1047         printf("encoding options:\n");
1048         printf("  -V, --verify                 Verify a correct encoding by decoding the output in parallel and comparing to the original\n");
1049 #ifdef FLAC__HAS_OGG
1050         printf("      --ogg                    When encoding, generate Ogg-FLAC output instead of native-FLAC.  Ogg-FLAC streams are FLAC streams wrapped in an Ogg transport layer.  The resulting file should have an '.ogg' extension and will still be decodable by flac.  When decoding, force the input to be treated as Ogg-FLAC.  This is useful when piping input from stdin or when the filename does not end in '.ogg'.\n");
1051 #endif
1052         printf("      --lax                    Allow encoder to generate non-Subset files\n");
1053         printf("      --sector-align           Align encoding of multiple CD format WAVE files on sector boundaries.\n");
1054         printf("  -S, --seekpoint={#|X|#x}     Include a point or points in a SEEKTABLE\n");
1055         printf("       #  : a specific sample number for a seek point\n");
1056         printf("       X  : a placeholder point (always goes at the end of the SEEKTABLE)\n");
1057         printf("       #x : # evenly spaced seekpoints, the first being at sample 0\n");
1058         printf("     You may use many -S options; the resulting SEEKTABLE will be the unique-\n");
1059         printf("           ified union of all such values.\n");
1060         printf("     With no -S options, flac defaults to '-S 100x'.  Use -S- for no SEEKTABLE.\n");
1061         printf("     Note: -S #x will not work if the encoder can't determine the input size\n");
1062         printf("           before starting.\n");
1063         printf("     Note: if you use -S # and # is >= samples in the input, there will be\n");
1064         printf("           either no seek point entered (if the input size is determinable\n");
1065         printf("           before encoding starts) or a placeholder point (if input size is not\n");
1066         printf("           determinable)\n");
1067         printf("  -P, --padding=#              Tell the encoder to write a PADDING metadata block of the given length (in bytes) after the STREAMINFO block.  This is useful if you plan to tag the file later with an APPLICATION block; instead of having to rewrite the entire file later just to insert your block, you can write directly over the PADDING block.  Note that the total length of the PADDING block will be 4 bytes longer than the length given because of the 4 metadata block header bytes.  You can force no PADDING block at all to be written with -P-, which is the default.\n");
1068         printf("  -b, --blocksize=#            Specify the blocksize in samples; the default is\n");
1069         printf("                               1152 for -l 0, else 4608; must be one of 192,\n");
1070         printf("                               576, 1152, 2304, 4608, 256, 512, 1024, 2048,\n");
1071         printf("                               4096, 8192, 16384, or 32768 (unless --lax is\n");
1072         printf("                               used)\n");
1073         printf("  -m, --mid-side               Try mid-side coding for each frame (stereo only)\n");
1074         printf("  -M, --adaptive-mid-side      Adaptive mid-side coding for all frames (stereo\n");
1075         printf("                               only)\n");
1076         printf("  -0, --compression-level-0, --fast  Synonymous with -l 0 -b 1152 -r 2,2\n");
1077         printf("  -1, --compression-level-1          Synonymous with -l 0 -b 1152 -M -r 2,2\n");
1078         printf("  -2, --compression-level-2          Synonymous with -l 0 -b 1152 -m -r 3\n");
1079         printf("  -3, --compression-level-3          Synonymous with -l 6 -b 4608 -r 3,3\n");
1080         printf("  -4, --compression-level-4          Synonymous with -l 8 -b 4608 -M -r 3,3\n");
1081         printf("  -5, --compression-level-5          Synonymous with -l 8 -b 4608 -m -r 3,3\n");
1082         printf("                                     -5 is the default setting\n");
1083         printf("  -6, --compression-level-6          Synonymous with -l 8 -b 4608 -m -r 4\n");
1084         printf("  -7, --compression-level-7          Synonymous with -l 8 -b 4608 -m -e -r 6\n");
1085         printf("  -8, --compression-level-8, --best  Synonymous with -l 12 -b 4608 -m -e -r 6\n");
1086         printf("  -e, --exhaustive-model-search      Do exhaustive model search (expensive!)\n");
1087 #if 0
1088         /*@@@ deprecated: */
1089         printf("  -E, --escape-coding                Do escape coding in the entropy coder.  This causes the encoder to use an unencoded representation of the residual in a partition if it is smaller.  It increases the runtime and usually results in an improvement of less than 1%.\n");
1090 #endif
1091         printf("  -l, --max-lpc-order=#              Max LPC order; 0 => only fixed predictors\n");
1092         printf("  -p, --qlp-coeff-precision-search   Do exhaustive search of LP coefficient\n");
1093         printf("                                     quantization (expensive!); overrides -q;\n");
1094         printf("                                     does nothing if using -l 0\n");
1095 /*@@@@@@    ................................................................................*/
1096         printf("  -q, --qlp-coeff-precision=#        Specify precision in bits of quantized\n");
1097         printf("                                     linear-predictor coefficients; 0 => let\n");
1098         printf("                                     encoder decide (the minimun is %u, the\n", FLAC__MIN_QLP_COEFF_PRECISION);
1099         printf("                                     default is -q 0)\n");
1100         printf("  -r, --rice-partition-order=[#,]#   Set [min,]max residual partition order\n");
1101         printf("                                     (# is 0..16; min defaults to 0; the\n");
1102         printf("                                     default is -r 0; above 4 doesn't usually\n");
1103         printf("                                     help much)\n");
1104 #if 0
1105         /*@@@ deprecated: */
1106         printf("  -R, -rice-parameter-search-distance=#   Rice parameter search distance\n");
1107 #endif
1108         printf("format options:\n");
1109         printf("      --endian={big|little}    Set byte order for samples\n");
1110         printf("      --channels=#             Number of channels\n");
1111         printf("      --bps=#                  Number of bits per sample\n");
1112         printf("      --sample-rate=#          Sample rate in Hz\n");
1113         printf("      --sign={signed|unsigned} Sign of samples (the default is signed)\n");
1114         printf("      --force-raw-input        Force input to be treated as raw samples\n");
1115         printf("negative options:\n");
1116         printf("      --no-adaptive-mid-side\n");
1117         printf("      --no-decode-through-errors\n");
1118         printf("      --no-delete-input-file\n");
1119 #if 0
1120 /* @@@ deprecated: */
1121         printf("      --no-escape-coding\n");
1122 #endif
1123         printf("      --no-exhaustive-model-search\n");
1124         printf("      --no-lax\n");
1125         printf("      --no-mid-side\n");
1126 #ifdef FLAC__HAS_OGG
1127         printf("      --no-ogg\n");
1128 #endif
1129         printf("      --no-padding\n");
1130         printf("      --no-qlp-coeff-prec-search\n");
1131         printf("      --no-residual-gnuplot\n");
1132         printf("      --no-residual-text\n");
1133         printf("      --no-sector-align\n");
1134         printf("      --no-seektable\n");
1135         printf("      --no-silent\n");
1136         printf("      --no-verify\n");
1137 }
1138
1139 void
1140 format_mistake(const char *infilename, const char *wrong, const char *right)
1141 {
1142         fprintf(stderr, "WARNING: %s is not a %s file; treating as a %s file\n", infilename, wrong, right);
1143 }
1144
1145 int encode_file(const char *infilename, const char *forced_outfilename, FLAC__bool is_last_file)
1146 {
1147         FILE *encode_infile;
1148         char outfilename[4096]; /* @@@ bad MAGIC NUMBER */
1149         char *p;
1150         FLAC__byte lookahead[12];
1151         unsigned lookahead_length = 0;
1152         FileFormat fmt= RAW;
1153         int retval;
1154         long infilesize;
1155         encode_options_t common_options;
1156
1157         if(0 == strcmp(infilename, "-")) {
1158                 infilesize = -1;
1159                 encode_infile = file__get_binary_stdin();
1160         }
1161         else {
1162                 infilesize = flac__file_get_filesize(infilename);
1163                 if(0 == (encode_infile = fopen(infilename, "rb"))) {
1164                         fprintf(stderr, "ERROR: can't open input file %s\n", infilename);
1165                         return 1;
1166                 }
1167         }
1168
1169         if(!option_values.force_raw_format) {
1170                 /* first set format based on name */
1171                 if(strlen(infilename) > 3 && 0 == strcasecmp(infilename+(strlen(infilename)-4), ".wav"))
1172                         fmt= WAV;
1173                 else if(strlen(infilename) > 3 && 0 == strcasecmp(infilename+(strlen(infilename)-4), ".aif"))
1174                         fmt= AIF;
1175                 else if(strlen(infilename) > 4 && 0 == strcasecmp(infilename+(strlen(infilename)-5), ".aiff"))
1176                         fmt= AIF;
1177
1178                 /* attempt to guess the file type based on the first 12 bytes */
1179                 if((lookahead_length = fread(lookahead, 1, 12, encode_infile)) < 12) {
1180                         if(fmt != RAW)
1181                                 format_mistake(infilename, fmt == AIF ? "AIFF" : "WAVE", "raw");
1182                         fmt= RAW;
1183                 }
1184                 else {
1185                         if(!strncmp(lookahead, "RIFF", 4) && !strncmp(lookahead+8, "WAVE", 4))
1186                                 fmt= WAV;
1187                         else if(!strncmp(lookahead, "FORM", 4) && !strncmp(lookahead+8, "AIFF", 4))
1188                                 fmt= AIF;
1189                         else {
1190                                 if(fmt != RAW)
1191                                         format_mistake(infilename, fmt == AIF ? "AIFF" : "WAVE", "raw");
1192                                 fmt= RAW;
1193                         }
1194                 }
1195         }
1196
1197         if(option_values.sector_align && fmt == RAW && infilesize < 0) {
1198                 fprintf(stderr, "ERROR: can't --sector-align when the input size is unknown\n");
1199                 return 1;
1200         }
1201
1202         if(fmt == RAW) {
1203                 if(option_values.format_is_big_endian < 0 || option_values.format_channels < 0 || option_values.format_bps < 0 || option_values.format_sample_rate < 0)
1204                         return usage_error("ERROR: for encoding a raw file you must specify a value for --endian, --channels, --bps, and --sample-rate\n");
1205         }
1206
1207         if(encode_infile == stdin || option_values.force_to_stdout)
1208                 strcpy(outfilename, "-");
1209         else {
1210                 const char *suffix = (option_values.use_ogg? ogg_suffix : flac_suffix);
1211                 strcpy(outfilename, option_values.output_prefix? option_values.output_prefix : "");
1212                 strcat(outfilename, infilename);
1213                 if(0 == (p = strrchr(outfilename, '.')))
1214                         strcat(outfilename, suffix);
1215                 else {
1216                         if(0 == strcmp(p, suffix)) {
1217                                 strcpy(p, "_new");
1218                                 strcat(p, suffix);
1219                         }
1220                         else
1221                                 strcpy(p, suffix);
1222                 }
1223         }
1224         if(0 == forced_outfilename)
1225                 forced_outfilename = outfilename;
1226         if(0 != option_values.cmdline_forced_outfilename)
1227                 forced_outfilename = option_values.cmdline_forced_outfilename;
1228
1229         common_options.verbose = option_values.verbose;
1230         common_options.skip = option_values.skip;
1231         common_options.verify = option_values.verify;
1232 #ifdef FLAC__HAS_OGG
1233         common_options.use_ogg = option_values.use_ogg;
1234 #endif
1235         common_options.lax = option_values.lax;
1236         common_options.do_mid_side = option_values.do_mid_side;
1237         common_options.loose_mid_side = option_values.loose_mid_side;
1238         common_options.do_exhaustive_model_search = option_values.do_exhaustive_model_search;
1239         common_options.do_escape_coding = option_values.do_escape_coding;
1240         common_options.do_qlp_coeff_prec_search = option_values.do_qlp_coeff_prec_search;
1241         common_options.min_residual_partition_order = option_values.min_residual_partition_order;
1242         common_options.max_residual_partition_order = option_values.max_residual_partition_order;
1243         common_options.rice_parameter_search_dist = option_values.rice_parameter_search_dist;
1244         common_options.max_lpc_order = option_values.max_lpc_order;
1245         common_options.blocksize = (unsigned)option_values.blocksize;
1246         common_options.qlp_coeff_precision = option_values.qlp_coeff_precision;
1247         common_options.padding = option_values.padding;
1248         common_options.requested_seek_points = option_values.requested_seek_points;
1249         common_options.num_requested_seek_points = option_values.num_requested_seek_points;
1250         common_options.is_last_file = is_last_file;
1251         common_options.align_reservoir = align_reservoir;
1252         common_options.align_reservoir_samples = &align_reservoir_samples;
1253         common_options.sector_align = option_values.sector_align;
1254
1255         if(fmt == RAW) {
1256                 raw_encode_options_t options;
1257
1258                 options.common = common_options;
1259                 options.is_big_endian = option_values.format_is_big_endian;
1260                 options.is_unsigned_samples = option_values.format_is_unsigned_samples;
1261                 options.channels = option_values.format_channels;
1262                 options.bps = option_values.format_bps;
1263                 options.sample_rate = option_values.format_sample_rate;
1264
1265                 retval = flac__encode_raw(encode_infile, infilesize, infilename, forced_outfilename, lookahead, lookahead_length, options);
1266         }
1267         else {
1268                 wav_encode_options_t options;
1269
1270                 options.common = common_options;
1271
1272                 if(fmt == AIF)
1273                         retval = flac__encode_aif(encode_infile, infilesize, infilename, forced_outfilename, lookahead, lookahead_length, options);
1274                 else
1275                         retval = flac__encode_wav(encode_infile, infilesize, infilename, forced_outfilename, lookahead, lookahead_length, options);
1276         }
1277
1278         if(retval == 0 && strcmp(infilename, "-")) {
1279                 if(strcmp(forced_outfilename, "-"))
1280                         flac__file_copy_metadata(infilename, forced_outfilename);
1281                 if(option_values.delete_input)
1282                         unlink(infilename);
1283         }
1284
1285         return retval;
1286 }
1287
1288 int decode_file(const char *infilename, const char *forced_outfilename)
1289 {
1290         static const char *suffixes[] = { ".wav", ".raw", ".ana" };
1291         char outfilename[4096]; /* @@@ bad MAGIC NUMBER */
1292         char *p;
1293         int retval;
1294         FLAC__bool treat_as_ogg = false;
1295         decode_options_t common_options;
1296
1297         if(!option_values.test_only && !option_values.analyze) {
1298                 if(option_values.force_raw_format && option_values.format_is_big_endian < 0)
1299                         return usage_error("ERROR: for decoding to a raw file you must specify a value for --endian\n");
1300         }
1301
1302         if(0 == strcmp(infilename, "-") || option_values.force_to_stdout)
1303                 strcpy(outfilename, "-");
1304         else {
1305                 const char *suffix = suffixes[option_values.analyze? 2 : option_values.force_raw_format? 1 : 0];
1306                 strcpy(outfilename, option_values.output_prefix? option_values.output_prefix : "");
1307                 strcat(outfilename, infilename);
1308                 if(0 == (p = strrchr(outfilename, '.')))
1309                         strcat(outfilename, suffix);
1310                 else {
1311                         if(0 == strcmp(p, suffix)) {
1312                                 strcpy(p, "_new");
1313                                 strcat(p, suffix);
1314                         }
1315                         else
1316                                 strcpy(p, suffix);
1317                 }
1318         }
1319         if(0 == forced_outfilename)
1320                 forced_outfilename = outfilename;
1321         if(0 != option_values.cmdline_forced_outfilename)
1322                 forced_outfilename = option_values.cmdline_forced_outfilename;
1323
1324         if(option_values.use_ogg)
1325                 treat_as_ogg = true;
1326         else if(0 == strcasecmp(infilename+(strlen(infilename)-4), ".ogg"))
1327                 treat_as_ogg = true;
1328         else
1329                 treat_as_ogg = false;
1330
1331 #ifndef FLAC__HAS_OGG
1332         if(treat_as_ogg) {
1333                 fprintf(stderr, "%s: Ogg support has not been built into this copy of flac\n", infilename);
1334                 return 1;
1335         }
1336 #endif
1337
1338         common_options.verbose = option_values.verbose;
1339         common_options.continue_through_decode_errors = option_values.continue_through_decode_errors;
1340 #ifdef FLAC__HAS_OGG
1341         common_options.is_ogg = treat_as_ogg;
1342 #endif
1343         common_options.skip = option_values.skip;
1344
1345         if(!option_values.force_raw_format) {
1346                 wav_decode_options_t options;
1347
1348                 options.common = common_options;
1349
1350                 retval = flac__decode_wav(infilename, option_values.test_only? 0 : forced_outfilename, option_values.analyze, option_values.aopts, options);
1351         }
1352         else {
1353                 raw_decode_options_t options;
1354
1355                 options.common = common_options;
1356                 options.is_big_endian = option_values.format_is_big_endian;
1357                 options.is_unsigned_samples = option_values.format_is_unsigned_samples;
1358
1359                 retval = flac__decode_raw(infilename, option_values.test_only? 0 : forced_outfilename, option_values.analyze, option_values.aopts, options);
1360         }
1361
1362         if(retval == 0 && strcmp(infilename, "-")) {
1363                 if(strcmp(forced_outfilename, "-"))
1364                         flac__file_copy_metadata(infilename, forced_outfilename);
1365                 if(option_values.delete_input && !option_values.test_only && !option_values.analyze)
1366                         unlink(infilename);
1367         }
1368
1369         return retval;
1370 }
1371
1372 void die(const char *message)
1373 {
1374         FLAC__ASSERT(0 != message);
1375         fprintf(stderr, "ERROR: %s\n", message);
1376         exit(1);
1377 }
1378
1379 char *local_strdup(const char *source)
1380 {
1381         char *ret;
1382         FLAC__ASSERT(0 != source);
1383         if(0 == (ret = strdup(source)))
1384                 die("out of memory during strdup()");
1385         return ret;
1386 }