Fix a couple of Windows 2Gig file size issues.
[platform/upstream/flac.git] / src / flac / main.c
index 88e8639..dd03d5b 100644 (file)
@@ -1,5 +1,5 @@
 /* flac - Command-line FLAC encoder/decoder
- * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007  Josh Coalson
+ * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007,2008,2009  Josh Coalson
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -11,9 +11,9 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 #if HAVE_CONFIG_H
@@ -36,6 +36,7 @@
 #include "FLAC/all.h"
 #include "share/alloc.h"
 #include "share/grabbag.h"
+#include "share/compat.h"
 #include "analyze.h"
 #include "decode.h"
 #include "encode.h"
@@ -43,7 +44,7 @@
 #include "utils.h"
 #include "vorbiscomment.h"
 
-#if defined _MSC_VER || defined __MINGW32__ || defined __EMX__
+#if defined _MSC_VER || defined __MINGW32__
 #define FLAC__STRCASECMP stricmp
 #else
 #define FLAC__STRCASECMP strcasecmp
@@ -84,11 +85,6 @@ static const char *get_outfilename(const char *infilename, const char *suffix);
 static void die(const char *message);
 static int conditional_fclose(FILE *f);
 static char *local_strdup(const char *source);
-#ifdef _MSC_VER
-/* There's no strtoll() in MSVC6 so we just write a specialized one */
-static FLAC__int64 local__strtoll(const char *src, char **endptr);
-#endif
-
 
 /*
  * share__getopt format struct; note that for long options with no
@@ -110,6 +106,7 @@ static struct share__option long_options_[] = {
        { "warnings-as-errors"    , share__no_argument, 0, 'w' },
        { "force"                 , share__no_argument, 0, 'f' },
        { "delete-input-file"     , share__no_argument, 0, 0 },
+       { "preserve-modtime"      , share__no_argument, 0, 0 },
        { "keep-foreign-metadata" , share__no_argument, 0, 0 },
        { "output-prefix"         , share__required_argument, 0, 0 },
        { "output-name"           , share__required_argument, 0, 'o' },
@@ -145,8 +142,10 @@ static struct share__option long_options_[] = {
        { "best"                      , share__no_argument, 0, '8' },
        { "fast"                      , share__no_argument, 0, '0' },
        { "verify"                    , share__no_argument, 0, 'V' },
-       { "force-aiff-format"         , share__no_argument, 0, 0 },
        { "force-raw-format"          , share__no_argument, 0, 0 },
+       { "force-aiff-format"         , share__no_argument, 0, 0 },
+       { "force-rf64-format"         , share__no_argument, 0, 0 },
+       { "force-wave64-format"       , share__no_argument, 0, 0 },
        { "lax"                       , share__no_argument, 0, 0 },
        { "replay-gain"               , share__no_argument, 0, 0 },
        { "ignore-chunk-sizes"        , share__no_argument, 0, 0 },
@@ -182,6 +181,7 @@ static struct share__option long_options_[] = {
        /*
         * negatives
         */
+       { "no-preserve-modtime"       , share__no_argument, 0, 0 },
        { "no-decode-through-errors"  , share__no_argument, 0, 0 },
        { "no-silent"                 , share__no_argument, 0, 0 },
        { "no-force"                  , share__no_argument, 0, 0 },
@@ -238,9 +238,12 @@ static struct {
        FLAC__bool has_serial_number; /* true iff --serial-number was used */
        long serial_number; /* this is the Ogg serial number and is unused for native FLAC */
        FLAC__bool force_to_stdout;
-       FLAC__bool force_aiff_format;
        FLAC__bool force_raw_format;
+       FLAC__bool force_aiff_format;
+       FLAC__bool force_rf64_format;
+       FLAC__bool force_wave64_format;
        FLAC__bool delete_input;
+       FLAC__bool preserve_modtime;
        FLAC__bool keep_foreign_metadata;
        FLAC__bool replay_gain;
        FLAC__bool ignore_chunk_sizes;
@@ -260,7 +263,7 @@ static struct {
        int format_channels;
        int format_bps;
        int format_sample_rate;
-       off_t format_input_size;
+       FLAC__off_t format_input_size;
        char requested_seek_points[5000]; /* bad MAGIC NUMBER but buffer overflow is checked */
        int num_requested_seek_points; /* -1 => no -S options were given, 0 => -S- was given */
        const char *cuesheet_filename;
@@ -375,8 +378,8 @@ int do_it(void)
                        if(!FLAC__format_sample_rate_is_valid(option_values.format_sample_rate))
                                return usage_error("ERROR: invalid sample rate '%u', must be > 0 and <= %u\n", option_values.format_sample_rate, FLAC__MAX_SAMPLE_RATE);
                }
-               if(option_values.force_raw_format && option_values.force_aiff_format)
-                       return usage_error("ERROR: only one of --force-raw-format and --force-aiff-format allowed\n");
+               if((option_values.force_raw_format?1:0) + (option_values.force_aiff_format?1:0) + (option_values.force_rf64_format?1:0) + (option_values.force_wave64_format?1:0) > 1)
+                       return usage_error("ERROR: only one of --force-raw-format/--force-aiff-format/--force-rf64-format/--force-wave64-format allowed\n");
                if(option_values.mode_decode) {
                        if(!option_values.force_raw_format) {
                                if(option_values.format_is_big_endian >= 0)
@@ -462,15 +465,12 @@ int do_it(void)
                                return usage_error("ERROR: --keep-foreign-metadata is not allowed in test mode\n");
                        if(option_values.analyze)
                                return usage_error("ERROR: --keep-foreign-metadata is not allowed in analyis mode\n");
-                       /*@@@@@@*/
-                       if(option_values.delete_input)
-                               return usage_error("ERROR: using --delete-input-file with --keep-foreign-metadata has been disabled until more testing has been done.\n");
                        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");
                }
        }
 
        flac__utils_printf(stderr, 2, "\n");
-       flac__utils_printf(stderr, 2, "flac %s, Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007  Josh Coalson\n", FLAC__VERSION_STRING);
+       flac__utils_printf(stderr, 2, "flac %s, Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007,2008,2009  Josh Coalson\n", FLAC__VERSION_STRING);
        flac__utils_printf(stderr, 2, "flac comes with ABSOLUTELY NO WARRANTY.  This is free software, and you are\n");
        flac__utils_printf(stderr, 2, "welcome to redistribute it under certain conditions.  Type `flac' for details.\n\n");
 
@@ -520,13 +520,7 @@ int do_it(void)
                                                flac__utils_printf(stderr, 1, "ERROR: filename too long: %s", option_values.filenames[i]);
                                                return 1;
                                        }
-                                       if(0 == strcmp(option_values.filenames[i], "-")) {
-                                               FLAC__ASSERT(0);
-                                               /* double protection */
-                                               flac__utils_printf(stderr, 1, "internal error\n");
-                                               return 2;
-                                       }
-                                       if(0 != (error = grabbag__replaygain_store_to_file_album(outfilename, album_gain, album_peak, /*preserve_modtime=*/true))) {
+                                       if(0 != (error = grabbag__replaygain_store_to_file_album(outfilename, album_gain, album_peak, option_values.preserve_modtime))) {
                                                flac__utils_printf(stderr, 1, "%s: ERROR writing ReplayGain album tags (%s)\n", outfilename, error);
                                                retval = 1;
                                        }
@@ -559,9 +553,12 @@ FLAC__bool init_options(void)
        option_values.has_serial_number = false;
        option_values.serial_number = 0;
        option_values.force_to_stdout = false;
-       option_values.force_aiff_format = false;
        option_values.force_raw_format = false;
+       option_values.force_aiff_format = false;
+       option_values.force_rf64_format = false;
+       option_values.force_wave64_format = false;
        option_values.delete_input = false;
+       option_values.preserve_modtime = true;
        option_values.keep_foreign_metadata = false;
        option_values.replay_gain = false;
        option_values.ignore_chunk_sizes = false;
@@ -583,7 +580,7 @@ FLAC__bool init_options(void)
        option_values.format_channels = -1;
        option_values.format_bps = -1;
        option_values.format_sample_rate = -1;
-       option_values.format_input_size = (off_t)(-1);
+       option_values.format_input_size = (FLAC__off_t)(-1);
        option_values.requested_seek_points[0] = '\0';
        option_values.num_requested_seek_points = -1;
        option_values.cuesheet_filename = 0;
@@ -637,7 +634,7 @@ int parse_options(int argc, char *argv[])
 
        if(option_values.num_files > 0) {
                unsigned i = 0;
-               if(0 == (option_values.filenames = (char**)malloc(sizeof(char*) * option_values.num_files)))
+               if(0 == (option_values.filenames = malloc(sizeof(char*) * option_values.num_files)))
                        die("out of memory allocating space for file names list");
                while(share__optind < argc)
                        option_values.filenames[i++] = local_strdup(argv[share__optind++]);
@@ -649,8 +646,6 @@ int parse_options(int argc, char *argv[])
 int parse_option(int short_option, const char *long_option, const char *option_argument)
 {
        const char *violation;
-       char *p;
-       int i;
 
        if(short_option == 0) {
                FLAC__ASSERT(0 != long_option);
@@ -660,6 +655,9 @@ int parse_option(int short_option, const char *long_option, const char *option_a
                else if(0 == strcmp(long_option, "delete-input-file")) {
                        option_values.delete_input = true;
                }
+               else if(0 == strcmp(long_option, "preserve-modtime")) {
+                       option_values.preserve_modtime = true;
+               }
                else if(0 == strcmp(long_option, "keep-foreign-metadata")) {
                        option_values.keep_foreign_metadata = true;
                }
@@ -679,17 +677,12 @@ int parse_option(int short_option, const char *long_option, const char *option_a
                        FLAC__ASSERT(0 != option_argument);
                        {
                                char *end;
-#ifdef _MSC_VER
-                               FLAC__int64 i;
-                               i = local__strtoll(option_argument, &end);
-#else
-                               long long i;
-                               i = strtoll(option_argument, &end, 10);
-#endif
+                               FLAC__int64 ix;
+                               ix = strtoll(option_argument, &end, 10);
                                if(0 == strlen(option_argument) || *end)
                                        return usage_error("ERROR: --%s must be a number\n", long_option);
-                               option_values.format_input_size = (off_t)i;
-                               if(option_values.format_input_size != i) /* check if off_t is smaller than long long */
+                               option_values.format_input_size = (FLAC__off_t)ix;
+                               if(option_values.format_input_size != ix) /* check if FLAC__off_t is smaller than long long */
                                        return usage_error("ERROR: --%s too large; this build of flac does not support filesizes over 2GB\n", long_option);
                                if(option_values.format_input_size <= 0)
                                        return usage_error("ERROR: --%s must be > 0\n", long_option);
@@ -750,11 +743,17 @@ int parse_option(int short_option, const char *long_option, const char *option_a
                else if(0 == strcmp(long_option, "no-cued-seekpoints")) {
                        option_values.cued_seekpoints = false;
                }
+               else if(0 == strcmp(long_option, "force-raw-format")) {
+                       option_values.force_raw_format = true;
+               }
                else if(0 == strcmp(long_option, "force-aiff-format")) {
                        option_values.force_aiff_format = true;
                }
-               else if(0 == strcmp(long_option, "force-raw-format")) {
-                       option_values.force_raw_format = true;
+               else if(0 == strcmp(long_option, "force-rf64-format")) {
+                       option_values.force_rf64_format = true;
+               }
+               else if(0 == strcmp(long_option, "force-wave64-format")) {
+                       option_values.force_wave64_format = true;
                }
                else if(0 == strcmp(long_option, "lax")) {
                        option_values.lax = true;
@@ -818,6 +817,9 @@ int parse_option(int short_option, const char *long_option, const char *option_a
                /*
                 * negatives
                 */
+               else if(0 == strcmp(long_option, "no-preserve-modtime")) {
+                       option_values.preserve_modtime = false;
+               }
                else if(0 == strcmp(long_option, "no-decode-through-errors")) {
                        option_values.continue_through_decode_errors = false;
                }
@@ -987,11 +989,14 @@ int parse_option(int short_option, const char *long_option, const char *option_a
                                        return usage_error("ERROR: argument to -%c must be >= 0; for no padding use -%c-\n", short_option, short_option);
                                break;
                        case 'b':
-                               FLAC__ASSERT(0 != option_argument);
-                               i = atoi(option_argument);
-                               if((i < (int)FLAC__MIN_BLOCK_SIZE || i > (int)FLAC__MAX_BLOCK_SIZE))
-                                       return usage_error("ERROR: invalid blocksize (-%c) '%d', must be >= %u and <= %u\n", short_option, i, FLAC__MIN_BLOCK_SIZE, FLAC__MAX_BLOCK_SIZE);
-                               add_compression_setting_unsigned(CST_BLOCKSIZE, (unsigned)i);
+                               {
+                                       unsigned i ;
+                                       FLAC__ASSERT(0 != option_argument);
+                                       i = atoi(option_argument);
+                                       if((i < (int)FLAC__MIN_BLOCK_SIZE || i > (int)FLAC__MAX_BLOCK_SIZE))
+                                               return usage_error("ERROR: invalid blocksize (-%c) '%d', must be >= %u and <= %u\n", short_option, i, FLAC__MIN_BLOCK_SIZE, FLAC__MAX_BLOCK_SIZE);
+                                       add_compression_setting_unsigned(CST_BLOCKSIZE, (unsigned)i);
+                               }
                                break;
                        case 'e':
                                add_compression_setting_bool(CST_DO_EXHAUSTIVE_MODEL_SEARCH, true);
@@ -1000,11 +1005,14 @@ int parse_option(int short_option, const char *long_option, const char *option_a
                                add_compression_setting_bool(CST_DO_ESCAPE_CODING, true);
                                break;
                        case 'l':
-                               FLAC__ASSERT(0 != option_argument);
-                               i = atoi(option_argument);
-                               if((i < 0 || i > (int)FLAC__MAX_LPC_ORDER))
-                                       return usage_error("ERROR: invalid LPC order (-%c) '%d', must be >= %u and <= %u\n", short_option, i, 0, FLAC__MAX_LPC_ORDER);
-                               add_compression_setting_unsigned(CST_MAX_LPC_ORDER, (unsigned)i);
+                               {
+                                       unsigned i ;
+                                       FLAC__ASSERT(0 != option_argument);
+                                       i = atoi(option_argument);
+                                       if(i > FLAC__MAX_LPC_ORDER)
+                                               return usage_error("ERROR: invalid LPC order (-%c) '%d', must be >= %u and <= %u\n", short_option, i, 0, FLAC__MAX_LPC_ORDER);
+                                       add_compression_setting_unsigned(CST_MAX_LPC_ORDER, i);
+                               }
                                break;
                        case 'A':
                                FLAC__ASSERT(0 != option_argument);
@@ -1022,38 +1030,46 @@ int parse_option(int short_option, const char *long_option, const char *option_a
                                add_compression_setting_bool(CST_DO_QLP_COEFF_PREC_SEARCH, true);
                                break;
                        case 'q':
-                               FLAC__ASSERT(0 != option_argument);
-                               i = atoi(option_argument);
-                               if(i < 0 || (i > 0 && (i < (int)FLAC__MIN_QLP_COEFF_PRECISION || i > (int)FLAC__MAX_QLP_COEFF_PRECISION)))
-                                       return usage_error("ERROR: invalid value '%d' for qlp coeff precision (-%c), must be 0 or between %u and %u, inclusive\n", i, short_option, FLAC__MIN_QLP_COEFF_PRECISION, FLAC__MAX_QLP_COEFF_PRECISION);
-                               add_compression_setting_unsigned(CST_QLP_COEFF_PRECISION, (unsigned)i);
-                               break;
-                       case 'r':
-                               FLAC__ASSERT(0 != option_argument);
-                               p = strchr(option_argument, ',');
-                               if(0 == p) {
-                                       add_compression_setting_unsigned(CST_MIN_RESIDUAL_PARTITION_ORDER, 0);
+                               {
+                                       unsigned i ;
+                                       FLAC__ASSERT(0 != option_argument);
                                        i = atoi(option_argument);
-                                       if(i < 0)
-                                               return usage_error("ERROR: invalid value '%d' for residual partition order (-%c), must be between 0 and %u, inclusive\n", i, short_option, FLAC__MAX_RICE_PARTITION_ORDER);
-                                       add_compression_setting_unsigned(CST_MAX_RESIDUAL_PARTITION_ORDER, (unsigned)i);
+                                       if((i > 0 && (i < FLAC__MIN_QLP_COEFF_PRECISION || i > FLAC__MAX_QLP_COEFF_PRECISION)))
+                                               return usage_error("ERROR: invalid value '%d' for qlp coeff precision (-%c), must be 0 or between %u and %u, inclusive\n", i, short_option, FLAC__MIN_QLP_COEFF_PRECISION, FLAC__MAX_QLP_COEFF_PRECISION);
+                                       add_compression_setting_unsigned(CST_QLP_COEFF_PRECISION, i);
                                }
-                               else {
-                                       i = atoi(option_argument);
-                                       if(i < 0)
-                                               return usage_error("ERROR: invalid value '%d' for min residual partition order (-%c), must be between 0 and %u, inclusive\n", i, short_option, FLAC__MAX_RICE_PARTITION_ORDER);
-                                       add_compression_setting_unsigned(CST_MIN_RESIDUAL_PARTITION_ORDER, (unsigned)i);
-                                       i = atoi(++p);
-                                       if(i < 0)
-                                               return usage_error("ERROR: invalid value '%d' for max residual partition order (-%c), must be between 0 and %u, inclusive\n", i, short_option, FLAC__MAX_RICE_PARTITION_ORDER);
-                                       add_compression_setting_unsigned(CST_MAX_RESIDUAL_PARTITION_ORDER, (unsigned)i);
+                               break;
+                       case 'r':
+                               {
+                                       unsigned i;
+                                       char * p;
+                                       FLAC__ASSERT(0 != option_argument);
+                                       p = strchr(option_argument, ',');
+                                       if(0 == p) {
+                                               add_compression_setting_unsigned(CST_MIN_RESIDUAL_PARTITION_ORDER, 0);
+                                               i = atoi(option_argument);
+                                               if(i > FLAC__MAX_RICE_PARTITION_ORDER)
+                                                       return usage_error("ERROR: invalid value '%d' for residual partition order (-%c), must be between 0 and %u, inclusive\n", i, short_option, FLAC__MAX_RICE_PARTITION_ORDER);
+                                               add_compression_setting_unsigned(CST_MAX_RESIDUAL_PARTITION_ORDER, i);
+                                       }
+                                       else {
+                                               i = atoi(option_argument);
+                                               if(i > FLAC__MAX_RICE_PARTITION_ORDER)
+                                                       return usage_error("ERROR: invalid value '%d' for min residual partition order (-%c), must be between 0 and %u, inclusive\n", i, short_option, FLAC__MAX_RICE_PARTITION_ORDER);
+                                               add_compression_setting_unsigned(CST_MIN_RESIDUAL_PARTITION_ORDER, i);
+                                               i = atoi(++p);
+                                               if(i > FLAC__MAX_RICE_PARTITION_ORDER)
+                                                       return usage_error("ERROR: invalid value '%d' for max residual partition order (-%c), must be between 0 and %u, inclusive\n", i, short_option, FLAC__MAX_RICE_PARTITION_ORDER);
+                                               add_compression_setting_unsigned(CST_MAX_RESIDUAL_PARTITION_ORDER, i);
+                                       }
                                }
                                break;
                        case 'R':
-                               i = atoi(option_argument);
-                               if(i < 0)
-                                       return usage_error("ERROR: invalid value '%d' for Rice parameter search distance (-%c), must be >= 0\n", i, short_option);
-                               add_compression_setting_unsigned(CST_RICE_PARAMETER_SEARCH_DIST, (unsigned)i);
+                               {
+                                       unsigned i;
+                                       i = atoi(option_argument);
+                                       add_compression_setting_unsigned(CST_RICE_PARAMETER_SEARCH_DIST, i);
+                               }
                                break;
                        default:
                                FLAC__ASSERT(0);
@@ -1134,7 +1150,7 @@ static void usage_header(void)
 {
        printf("===============================================================================\n");
        printf("flac - Command-line FLAC encoder/decoder version %s\n", FLAC__VERSION_STRING);
-       printf("Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007  Josh Coalson\n");
+       printf("Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007,2008,2009  Josh Coalson\n");
        printf("\n");
        printf("This program is free software; you can redistribute it and/or\n");
        printf("modify it under the terms of the GNU General Public License\n");
@@ -1146,9 +1162,9 @@ static void usage_header(void)
        printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n");
        printf("GNU General Public License for more details.\n");
        printf("\n");
-       printf("You should have received a copy of the GNU General Public License\n");
-       printf("along with this program; if not, write to the Free Software\n");
-       printf("Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\n");
+       printf("You should have received a copy of the GNU General Public License along\n");
+       printf("with this program; if not, write to the Free Software Foundation, Inc.,\n");
+       printf("51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n");
        printf("===============================================================================\n");
 }
 
@@ -1208,6 +1224,7 @@ void show_help(void)
        printf("  -o, --output-name=FILENAME   Force the output file name\n");
        printf("      --output-prefix=STRING   Prepend STRING to output names\n");
        printf("      --delete-input-file      Deletes after a successful encode/decode\n");
+       printf("      --preserve-modtime       Output files keep timestamp of input (default)\n");
        printf("      --keep-foreign-metadata  Save/restore WAVE or AIFF non-audio chunks\n");
        printf("      --skip={#|mm:ss.ss}      Skip the given initial samples for each input\n");
        printf("      --until={#|[+|-]mm:ss.ss}  Stop at the given sample for each input file\n");
@@ -1224,9 +1241,7 @@ void show_help(void)
        printf("encoding options:\n");
        printf("  -V, --verify                 Verify a correct encoding\n");
        printf("      --lax                    Allow encoder to generate non-Subset files\n");
-#if 0 /*@@@ currently undocumented */
        printf("      --ignore-chunk-sizes     Ignore data chunk sizes in WAVE/AIFF files\n");
-#endif
        printf("      --sector-align (DEPRECATED) Align multiple files on sector boundaries\n");
        printf("      --replay-gain            Calculate ReplayGain & store in FLAC tags\n");
        printf("      --cuesheet=FILENAME      Import cuesheet and store in CUESHEET block\n");
@@ -1260,12 +1275,15 @@ void show_help(void)
        printf("      --sample-rate=#          Sample rate in Hz\n");
        printf("      --sign={signed|unsigned} Sign of samples\n");
        printf("      --input-size=#           Size of the raw input in bytes\n");
-       printf("      --force-aiff-format      Force decoding to AIFF format\n");
        printf("      --force-raw-format       Treat input or output as raw samples\n");
+       printf("      --force-aiff-format      Force decoding to AIFF format\n");
+       printf("      --force-rf64-format      Force decoding to RF64 format\n");
+       printf("      --force-wave64-format    Force decoding to Wave64 format\n");
        printf("negative options:\n");
        printf("      --no-adaptive-mid-side\n");
        printf("      --no-decode-through-errors\n");
        printf("      --no-delete-input-file\n");
+       printf("      --no-preserve-modtime\n");
        printf("      --no-keep-foreign-metadata\n");
        printf("      --no-exhaustive-model-search\n");
        printf("      --no-lax\n");
@@ -1278,9 +1296,7 @@ void show_help(void)
        printf("      --no-replay-gain\n");
        printf("      --no-residual-gnuplot\n");
        printf("      --no-residual-text\n");
-#if 0 /*@@@ currently undocumented */
        printf("      --no-ignore-chunk-sizes\n");
-#endif
        printf("      --no-sector-align\n");
        printf("      --no-seektable\n");
        printf("      --no-silent\n");
@@ -1294,8 +1310,8 @@ void show_explain(void)
        usage_header();
        usage_summary();
        printf("For encoding:\n");
-       printf("  The input file(s) may be a PCM WAVE file, AIFF (or uncompressed AIFF-C)\n");
-       printf("  file, or raw samples.\n");
+       printf("  The input file(s) may be a PCM WAVE or RF64 file, AIFF (or uncompressed\n");
+       printf("  AIFF-C) file, or raw samples.\n");
        printf("  The output file(s) will be in native FLAC or Ogg FLAC format\n");
        printf("For decoding, the reverse is true.\n");
        printf("\n");
@@ -1344,6 +1360,11 @@ void show_explain(void)
        printf("                               successful encode or decode.  If there was an\n");
        printf("                               error (including a verify error) the input file\n");
        printf("                               is left intact.\n");
+       printf("      --preserve-modtime       Output files have their timestamps/permissions\n");
+       printf("                               set to match those of their inputs (this is\n");
+       printf("                               default).  Use --no-preserve-modtime to make\n");
+       printf("                               output files have the current time and default\n");
+       printf("                               permissions.\n");
        printf("      --keep-foreign-metadata  If encoding, save WAVE or AIFF non-audio chunks\n");
        printf("                               in FLAC metadata.  If decoding, restore any saved\n");
        printf("                               non-audio chunks from FLAC metadata when writing\n");
@@ -1585,17 +1606,28 @@ void show_explain(void)
        printf("                               the input stream, the encoder will complain\n");
        printf("                               about an unexpected end-of-file.  If the size\n");
        printf("                               given is less, samples will be truncated.\n");
+       printf("      --force-raw-format       Force input (when encoding) or output (when\n");
+       printf("                               decoding) to be treated as raw samples\n");
        printf("      --force-aiff-format      Force the decoder to output AIFF format.  This\n");
        printf("                               option is not needed if the output filename (as\n");
        printf("                               set by -o) ends with .aif or .aiff; this option\n");
        printf("                               has no effect when encoding since input AIFF is\n");
        printf("                               auto-detected.\n");
-       printf("      --force-raw-format       Force input (when encoding) or output (when\n");
-       printf("                               decoding) to be treated as raw samples\n");
+       printf("      --force-rf64-format      Force the decoder to output RF64 format.  This\n");
+       printf("                               option is not needed if the output filename (as\n");
+       printf("                               set by -o) ends with .rf64; this option\n");
+       printf("                               has no effect when encoding since input RF64 is\n");
+       printf("                               auto-detected.\n");
+       printf("      --force-wave64-format    Force the decoder to output Wave64 format.  This\n");
+       printf("                               option is not needed if the output filename (as\n");
+       printf("                               set by -o) ends with .w64; this option\n");
+       printf("                               has no effect when encoding since input Wave64 is\n");
+       printf("                               auto-detected.\n");
        printf("negative options:\n");
        printf("      --no-adaptive-mid-side\n");
        printf("      --no-decode-through-errors\n");
        printf("      --no-delete-input-file\n");
+       printf("      --no-preserve-modtime\n");
        printf("      --no-keep-foreign-metadata\n");
        printf("      --no-exhaustive-model-search\n");
        printf("      --no-lax\n");
@@ -1621,7 +1653,7 @@ void show_explain(void)
 void format_mistake(const char *infilename, FileFormat wrong, FileFormat right)
 {
        /* WATCHOUT: indexed by FileFormat */
-       static const char * const ff[] = { " raw", " WAVE", "n AIFF", "n AIFF-C", " FLAC", "n Ogg FLAC" };
+       static const char * const ff[] = { " raw", " WAVE", "n RF64", "n AIFF", "n AIFF-C", " FLAC", "n Ogg FLAC" };
        flac__utils_printf(stderr, 1, "WARNING: %s is not a%s file; treating as a%s file\n", infilename, ff[wrong], ff[right]);
 }
 
@@ -1632,7 +1664,7 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
        unsigned lookahead_length = 0;
        FileFormat input_format = FORMAT_RAW;
        int retval;
-       off_t infilesize;
+       FLAC__off_t infilesize;
        encode_options_t encode_options;
        const char *outfilename = get_encoded_outfilename(infilename); /* the final name of the encoded file */
        /* internal_outfilename is the file we will actually write to; it will be a temporary name if infilename==outfilename */
@@ -1644,7 +1676,7 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
        }
 
        if(0 == strcmp(infilename, "-")) {
-               infilesize = (off_t)(-1);
+               infilesize = (FLAC__off_t)(-1);
                encode_infile = grabbag__file_get_binary_stdin();
        }
        else {
@@ -1659,6 +1691,10 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
                /* first set format based on name */
                if(strlen(infilename) >= 4 && 0 == FLAC__STRCASECMP(infilename+(strlen(infilename)-4), ".wav"))
                        input_format = FORMAT_WAVE;
+               else if(strlen(infilename) >= 5 && 0 == FLAC__STRCASECMP(infilename+(strlen(infilename)-5), ".rf64"))
+                       input_format = FORMAT_RF64;
+               else if(strlen(infilename) >= 4 && 0 == FLAC__STRCASECMP(infilename+(strlen(infilename)-4), ".w64"))
+                       input_format = FORMAT_WAVE64;
                else if(strlen(infilename) >= 4 && 0 == FLAC__STRCASECMP(infilename+(strlen(infilename)-4), ".aif"))
                        input_format = FORMAT_AIFF;
                else if(strlen(infilename) >= 5 && 0 == FLAC__STRCASECMP(infilename+(strlen(infilename)-5), ".aiff"))
@@ -1672,6 +1708,7 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
 
                /* attempt to guess the file type based on the first 12 bytes */
                if((lookahead_length = fread(lookahead, 1, 12, encode_infile)) < 12) {
+                       /* all supported non-raw formats have at least 12 bytes of header to read */
                        if(input_format != FORMAT_RAW) {
                                format_mistake(infilename, input_format, FORMAT_RAW);
                                if(option_values.treat_warnings_as_errors) {
@@ -1679,25 +1716,32 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
                                        return 1;
                                }
                        }
+                       /* force to raw */
                        input_format = FORMAT_RAW;
                }
                else {
-                       if(!strncmp((const char *)lookahead, "ID3", 3)) {
+                       if(!memcmp(lookahead, "ID3", 3)) {
                                flac__utils_printf(stderr, 1, "ERROR: input file %s has an ID3v2 tag\n", infilename);
+                               conditional_fclose(encode_infile);
                                return 1;
                        }
-                       else if(!strncmp((const char *)lookahead, "RIFF", 4) && !strncmp((const char *)lookahead+8, "WAVE", 4))
+                       else if(!memcmp(lookahead, "RIFF", 4) && !memcmp(lookahead+8, "WAVE", 4))
                                input_format = FORMAT_WAVE;
-                       else if(!strncmp((const char *)lookahead, "FORM", 4) && !strncmp((const char *)lookahead+8, "AIFF", 4))
+                       else if(!memcmp(lookahead, "RF64", 4) && !memcmp(lookahead+8, "WAVE", 4))
+                               input_format = FORMAT_RF64;
+                       else if(!memcmp(lookahead, "riff\x2E\x91\xCF\x11\xD6\xA5\x28\xDB", 12)) /* just check 1st 12 bytes of GUID */
+                               input_format = FORMAT_WAVE64;
+                       else if(!memcmp(lookahead, "FORM", 4) && !memcmp(lookahead+8, "AIFF", 4))
                                input_format = FORMAT_AIFF;
-                       else if(!strncmp((const char *)lookahead, "FORM", 4) && !strncmp((const char *)lookahead+8, "AIFC", 4))
+                       else if(!memcmp(lookahead, "FORM", 4) && !memcmp(lookahead+8, "AIFC", 4))
                                input_format = FORMAT_AIFF_C;
                        else if(!memcmp(lookahead, FLAC__STREAM_SYNC_STRING, sizeof(FLAC__STREAM_SYNC_STRING)))
                                input_format = FORMAT_FLAC;
-                       /* this could be made more accurate by looking at the first packet */
+                       /*@@@ this could be made more accurate by looking at the first packet to make sure it's Ogg FLAC and not, say, Ogg Vorbis.  we do catch such problems later though. */
                        else if(!memcmp(lookahead, "OggS", 4))
                                input_format = FORMAT_OGGFLAC;
                        else {
+                               /* didn't find header of any supported format */
                                if(input_format != FORMAT_RAW) {
                                        format_mistake(infilename, input_format, FORMAT_RAW);
                                        if(option_values.treat_warnings_as_errors) {
@@ -1705,6 +1749,7 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
                                                return 1;
                                        }
                                }
+                               /* force to raw */
                                input_format = FORMAT_RAW;
                        }
                }
@@ -1715,9 +1760,9 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
                        conditional_fclose(encode_infile);
                        return usage_error("ERROR: --keep-foreign-metadata cannot be used when encoding from stdin or to stdout\n");
                }
-               if(input_format != FORMAT_WAVE && input_format != FORMAT_AIFF && input_format != FORMAT_AIFF_C) {
+               if(input_format != FORMAT_WAVE && input_format != FORMAT_WAVE64 && input_format != FORMAT_RF64 && input_format != FORMAT_AIFF && input_format != FORMAT_AIFF_C) {
                        conditional_fclose(encode_infile);
-                       return usage_error("ERROR: --keep-foreign-metadata can only be used with WAVE or AIFF input\n");
+                       return usage_error("ERROR: --keep-foreign-metadata can only be used with WAVE, Wave64, RF64, or AIFF input\n");
                }
        }
 
@@ -1725,7 +1770,7 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
         * Error if output file already exists (and -f not used).
         * Use grabbag__file_get_filesize() as a cheap way to check.
         */
-       if(!option_values.test_only && !option_values.force_file_overwrite && strcmp(outfilename, "-") && grabbag__file_get_filesize(outfilename) != (off_t)(-1)) {
+       if(!option_values.test_only && !option_values.force_file_overwrite && strcmp(outfilename, "-") && grabbag__file_get_filesize(outfilename) != (FLAC__off_t)(-1)) {
                if(input_format == FORMAT_FLAC) {
                        /* need more detailed error message when re-flac'ing to avoid confusing the user */
                        flac__utils_printf(stderr, 1,
@@ -1783,7 +1828,7 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
                }
        }
 
-       if(/*@@@@@@why no stdin?*/encode_infile == stdin || option_values.force_to_stdout) {
+       if(option_values.force_to_stdout) {
                if(option_values.replay_gain) {
                        conditional_fclose(encode_infile);
                        return usage_error("ERROR: --replay-gain cannot be used when encoding to stdout\n");
@@ -1850,7 +1895,7 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
        if(encode_infile != stdin && grabbag__file_are_same(infilename, outfilename)) {
                static const char *tmp_suffix = ".tmp,fl-ac+en'c";
                /*@@@@ still a remote possibility that a file with this filename exists */
-               if(0 == (internal_outfilename = (char *)safe_malloc_add_3op_(strlen(outfilename), /*+*/strlen(tmp_suffix), /*+*/1))) {
+               if(0 == (internal_outfilename = safe_malloc_add_3op_(strlen(outfilename), /*+*/strlen(tmp_suffix), /*+*/1))) {
                        flac__utils_printf(stderr, 1, "ERROR allocating memory for tempfile name\n");
                        conditional_fclose(encode_infile);
                        return 1;
@@ -1871,14 +1916,24 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
        else if(input_format == FORMAT_FLAC || input_format == FORMAT_OGGFLAC) {
                retval = flac__encode_file(encode_infile, infilesize, infilename, internal_outfilename? internal_outfilename : outfilename, lookahead, lookahead_length, encode_options);
        }
-       else if(input_format == FORMAT_WAVE || input_format == FORMAT_AIFF || input_format == FORMAT_AIFF_C) {
+       else if(input_format == FORMAT_WAVE || input_format == FORMAT_WAVE64 || input_format == FORMAT_RF64 || input_format == FORMAT_AIFF || input_format == FORMAT_AIFF_C) {
                encode_options.format_options.iff.foreign_metadata = 0;
 
-               /* read foreign metadata if requested */
+               /* initialize foreign metadata if requested */
                if(option_values.keep_foreign_metadata) {
-                       if(0 == (encode_options.format_options.iff.foreign_metadata = flac__foreign_metadata_new(input_format==FORMAT_WAVE? FOREIGN_BLOCK_TYPE__RIFF : FOREIGN_BLOCK_TYPE__AIFF))) {
+                       encode_options.format_options.iff.foreign_metadata =
+                               flac__foreign_metadata_new(
+                                       input_format==FORMAT_WAVE || input_format==FORMAT_RF64?
+                                               FOREIGN_BLOCK_TYPE__RIFF :
+                                       input_format==FORMAT_WAVE64?
+                                               FOREIGN_BLOCK_TYPE__WAVE64 :
+                                               FOREIGN_BLOCK_TYPE__AIFF
+                               );
+                       if(0 == encode_options.format_options.iff.foreign_metadata) {
                                flac__utils_printf(stderr, 1, "ERROR: creating foreign metadata object\n");
                                conditional_fclose(encode_infile);
+                               if(internal_outfilename != 0)
+                                       free(internal_outfilename);
                                return 1;
                        }
                }
@@ -1900,14 +1955,14 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
                                const char *error;
                                grabbag__replaygain_get_title(&title_gain, &title_peak);
                                if(
-                                       0 != (error = grabbag__replaygain_store_to_file_reference(internal_outfilename? internal_outfilename : outfilename, /*preserve_modtime=*/true)) ||
-                                       0 != (error = grabbag__replaygain_store_to_file_title(internal_outfilename? internal_outfilename : outfilename, title_gain, title_peak, /*preserve_modtime=*/true))
+                                       0 != (error = grabbag__replaygain_store_to_file_reference(internal_outfilename? internal_outfilename : outfilename, option_values.preserve_modtime)) ||
+                                       0 != (error = grabbag__replaygain_store_to_file_title(internal_outfilename? internal_outfilename : outfilename, title_gain, title_peak, option_values.preserve_modtime))
                                ) {
                                        flac__utils_printf(stderr, 1, "%s: ERROR writing ReplayGain reference/title tags (%s)\n", outfilename, error);
                                        retval = 1;
                                }
                        }
-                       if(strcmp(infilename, "-"))
+                       if(option_values.preserve_modtime && strcmp(infilename, "-"))
                                grabbag__file_copy_metadata(infilename, internal_outfilename? internal_outfilename : outfilename);
                }
        }
@@ -1947,7 +2002,7 @@ int decode_file(const char *infilename)
        int retval;
        FLAC__bool treat_as_ogg = false;
        FileFormat output_format = FORMAT_WAVE;
-       decode_options_t common_options;
+       decode_options_t decode_options;
        const char *outfilename = get_decoded_outfilename(infilename);
 
        if(0 == outfilename) {
@@ -1959,7 +2014,7 @@ int decode_file(const char *infilename)
         * Error if output file already exists (and -f not used).
         * Use grabbag__file_get_filesize() as a cheap way to check.
         */
-       if(!option_values.test_only && !option_values.force_file_overwrite && strcmp(outfilename, "-") && grabbag__file_get_filesize(outfilename) != (off_t)(-1)) {
+       if(!option_values.test_only && !option_values.force_file_overwrite && strcmp(outfilename, "-") && grabbag__file_get_filesize(outfilename) != (FLAC__off_t)(-1)) {
                flac__utils_printf(stderr, 1, "ERROR: output file %s already exists, use -f to override\n", outfilename);
                return 1;
        }
@@ -1972,6 +2027,16 @@ int decode_file(const char *infilename)
                (strlen(outfilename) >= 5 && 0 == FLAC__STRCASECMP(outfilename+(strlen(outfilename)-5), ".aiff"))
        )
                output_format = FORMAT_AIFF;
+       else if(
+               option_values.force_rf64_format ||
+               (strlen(outfilename) >= 5 && 0 == FLAC__STRCASECMP(outfilename+(strlen(outfilename)-5), ".rf64"))
+       )
+               output_format = FORMAT_RF64;
+       else if(
+               option_values.force_wave64_format ||
+               (strlen(outfilename) >= 4 && 0 == FLAC__STRCASECMP(outfilename+(strlen(outfilename)-4), ".w64"))
+       )
+               output_format = FORMAT_WAVE64;
        else
                output_format = FORMAT_WAVE;
 
@@ -1983,8 +2048,8 @@ int decode_file(const char *infilename)
        if(option_values.keep_foreign_metadata) {
                if(0 == strcmp(infilename, "-") || 0 == strcmp(outfilename, "-"))
                        return usage_error("ERROR: --keep-foreign-metadata cannot be used when decoding from stdin or to stdout\n");
-               if(output_format != FORMAT_WAVE && output_format != FORMAT_AIFF)
-                       return usage_error("ERROR: --keep-foreign-metadata can only be used with WAVE or AIFF output\n");
+               if(output_format != FORMAT_WAVE && output_format != FORMAT_WAVE64 && output_format != FORMAT_RF64 && output_format != FORMAT_AIFF && output_format != FORMAT_AIFF_C)
+                       return usage_error("ERROR: --keep-foreign-metadata can only be used with WAVE, Wave64, RF64, or AIFF output\n");
        }
 
        if(option_values.use_ogg)
@@ -2003,67 +2068,67 @@ int decode_file(const char *infilename)
        }
 #endif
 
-       if(!flac__utils_parse_skip_until_specification(option_values.skip_specification, &common_options.skip_specification) || common_options.skip_specification.is_relative)
+       if(!flac__utils_parse_skip_until_specification(option_values.skip_specification, &decode_options.skip_specification) || decode_options.skip_specification.is_relative)
                return usage_error("ERROR: invalid value for --skip\n");
 
-       if(!flac__utils_parse_skip_until_specification(option_values.until_specification, &common_options.until_specification)) /*@@@ more checks: no + without --skip, no - unless known total_samples_to_{en,de}code */
+       if(!flac__utils_parse_skip_until_specification(option_values.until_specification, &decode_options.until_specification)) /*@@@ more checks: no + without --skip, no - unless known total_samples_to_{en,de}code */
                return usage_error("ERROR: invalid value for --until\n");
        /* if there is no "--until" we want to default to "--until=-0" */
        if(0 == option_values.until_specification)
-               common_options.until_specification.is_relative = true;
+               decode_options.until_specification.is_relative = true;
 
        if(option_values.cue_specification) {
-               if(!flac__utils_parse_cue_specification(option_values.cue_specification, &common_options.cue_specification))
+               if(!flac__utils_parse_cue_specification(option_values.cue_specification, &decode_options.cue_specification))
                        return usage_error("ERROR: invalid value for --cue\n");
-               common_options.has_cue_specification = true;
+               decode_options.has_cue_specification = true;
        }
        else
-               common_options.has_cue_specification = false;
+               decode_options.has_cue_specification = false;
 
-       common_options.treat_warnings_as_errors = option_values.treat_warnings_as_errors;
-       common_options.continue_through_decode_errors = option_values.continue_through_decode_errors;
-       common_options.replaygain_synthesis_spec = option_values.replaygain_synthesis_spec;
+       decode_options.treat_warnings_as_errors = option_values.treat_warnings_as_errors;
+       decode_options.continue_through_decode_errors = option_values.continue_through_decode_errors;
+       decode_options.replaygain_synthesis_spec = option_values.replaygain_synthesis_spec;
 #if FLAC__HAS_OGG
-       common_options.is_ogg = treat_as_ogg;
-       common_options.use_first_serial_number = !option_values.has_serial_number;
-       common_options.serial_number = option_values.serial_number;
+       decode_options.is_ogg = treat_as_ogg;
+       decode_options.use_first_serial_number = !option_values.has_serial_number;
+       decode_options.serial_number = option_values.serial_number;
 #endif
-       common_options.channel_map_none = option_values.channel_map_none;
+       decode_options.channel_map_none = option_values.channel_map_none;
+       decode_options.format = output_format;
 
        if(output_format == FORMAT_RAW) {
-               raw_decode_options_t options;
+               decode_options.format_options.raw.is_big_endian = option_values.format_is_big_endian;
+               decode_options.format_options.raw.is_unsigned_samples = option_values.format_is_unsigned_samples;
 
-               options.common = common_options;
-               options.is_big_endian = option_values.format_is_big_endian;
-               options.is_unsigned_samples = option_values.format_is_unsigned_samples;
-
-               retval = flac__decode_raw(infilename, option_values.test_only? 0 : outfilename, option_values.analyze, option_values.aopts, options);
+               retval = flac__decode_file(infilename, option_values.test_only? 0 : outfilename, option_values.analyze, option_values.aopts, decode_options);
        }
        else {
-               wav_decode_options_t options;
-
-               options.common = common_options;
-               options.foreign_metadata = 0;
+               decode_options.format_options.iff.foreign_metadata = 0;
 
-               /* read foreign metadata if requested */
+               /* initialize foreign metadata if requested */
                if(option_values.keep_foreign_metadata) {
-                       if(0 == (options.foreign_metadata = flac__foreign_metadata_new(output_format==FORMAT_WAVE? FOREIGN_BLOCK_TYPE__RIFF : FOREIGN_BLOCK_TYPE__AIFF))) {
+                       decode_options.format_options.iff.foreign_metadata =
+                               flac__foreign_metadata_new(
+                                       output_format==FORMAT_WAVE || output_format==FORMAT_RF64?
+                                               FOREIGN_BLOCK_TYPE__RIFF :
+                                       output_format==FORMAT_WAVE64?
+                                               FOREIGN_BLOCK_TYPE__WAVE64 :
+                                               FOREIGN_BLOCK_TYPE__AIFF
+                               );
+                       if(0 == decode_options.format_options.iff.foreign_metadata) {
                                flac__utils_printf(stderr, 1, "ERROR: creating foreign metadata object\n");
                                return 1;
                        }
                }
 
-               if(output_format == FORMAT_WAVE)
-                       retval = flac__decode_wav(infilename, option_values.test_only? 0 : outfilename, option_values.analyze, option_values.aopts, options);
-               else
-                       retval = flac__decode_aiff(infilename, option_values.test_only? 0 : outfilename, option_values.analyze, option_values.aopts, options);
+               retval = flac__decode_file(infilename, option_values.test_only? 0 : outfilename, option_values.analyze, option_values.aopts, decode_options);
 
-               if(options.foreign_metadata)
-                       flac__foreign_metadata_delete(options.foreign_metadata);
+               if(decode_options.format_options.iff.foreign_metadata)
+                       flac__foreign_metadata_delete(decode_options.format_options.iff.foreign_metadata);
        }
 
        if(retval == 0 && strcmp(infilename, "-")) {
-               if(strcmp(outfilename, "-"))
+               if(option_values.preserve_modtime && strcmp(outfilename, "-"))
                        grabbag__file_copy_metadata(infilename, outfilename);
                if(option_values.delete_input && !option_values.test_only && !option_values.analyze)
                        unlink(infilename);
@@ -2090,6 +2155,12 @@ const char *get_decoded_outfilename(const char *infilename)
        else if(option_values.force_aiff_format) {
                suffix = ".aiff";
        }
+       else if(option_values.force_rf64_format) {
+               suffix = ".rf64";
+       }
+       else if(option_values.force_wave64_format) {
+               suffix = ".w64";
+       }
        else {
                suffix = ".wav";
        }
@@ -2150,29 +2221,3 @@ char *local_strdup(const char *source)
                die("out of memory during strdup()");
        return ret;
 }
-
-#ifdef _MSC_VER
-/* There's no strtoll() in MSVC6 so we just write a specialized one */
-FLAC__int64 local__strtoll(const char *src, char **endptr)
-{
-       FLAC__bool neg = false;
-       FLAC__int64 ret = 0;
-       int c;
-       FLAC__ASSERT(0 != src);
-       if(*src == '-') {
-               neg = true;
-               src++;
-       }
-       while(0 != (c = *src)) {
-               c -= '0';
-               if(c >= 0 && c <= 9)
-                       ret = (ret * 10) + c;
-               else
-                       break;
-               src++;
-       }
-       if(endptr)
-               *endptr = (char*)src;
-       return neg? -ret : ret;
-}
-#endif