revamp decoder process calls
[flac.git] / src / flac / encode.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 #if defined _WIN32 && !defined __CYGWIN__
20 /* where MSVC puts unlink() */
21 # include <io.h>
22 #else
23 # include <unistd.h>
24 #endif
25 #include <limits.h> /* for LONG_MAX */
26 #include <math.h> /* for floor() */
27 #include <stdio.h> /* for FILE et al. */
28 #include <stdlib.h> /* for malloc */
29 #include <string.h> /* for strcmp() */
30 #include "FLAC/all.h"
31 #include "encode.h"
32 #include "file.h"
33 #ifdef FLAC__HAS_OGG
34 #include "ogg/ogg.h"
35 #endif
36
37 #ifdef min
38 #undef min
39 #endif
40 #define min(x,y) ((x)<(y)?(x):(y))
41
42 /* this MUST be >= 588 so that sector aligning can take place with one read */
43 #define CHUNK_OF_SAMPLES 2048
44
45 typedef enum {
46         FLAC__VERIFY_OK,
47         FLAC__VERIFY_FAILED_IN_FRAME,
48         FLAC__VERIFY_FAILED_IN_METADATA
49 } verify_code;
50
51 static const char *verify_code_string[] = {
52         "FLAC__VERIFY_OK",
53         "FLAC__VERIFY_FAILED_IN_FRAME",
54         "FLAC__VERIFY_FAILED_IN_METADATA"
55 };
56
57 typedef struct {
58         FLAC__int32 *original[FLAC__MAX_CHANNELS];
59         unsigned size; /* of each original[] in samples */
60         unsigned tail; /* in wide samples */
61         const FLAC__byte *encoded_signal;
62         unsigned encoded_signal_capacity;
63         unsigned encoded_bytes;
64         FLAC__bool into_frames;
65         verify_code result;
66         FLAC__StreamDecoder *decoder;
67 } verify_fifo_struct;
68
69 #ifdef FLAC__HAS_OGG
70 typedef struct {
71         ogg_stream_state os;
72         ogg_page og;
73 } ogg_info_struct;
74 #endif
75
76 typedef struct {
77         const char *inbasefilename;
78         FILE *fout;
79         const char *outfilename;
80         FLAC__StreamEncoder *encoder;
81         FLAC__bool verify;
82         FLAC__bool verbose;
83         FLAC__uint64 unencoded_size;
84         FLAC__uint64 total_samples_to_encode;
85         FLAC__uint64 bytes_written;
86         FLAC__uint64 samples_written;
87         FLAC__uint64 stream_offset; /* i.e. number of bytes before the first byte of the the first frame's header */
88         unsigned current_frame;
89         verify_fifo_struct verify_fifo;
90         FLAC__StreamMetadata_SeekTable seek_table;
91         unsigned first_seek_point_to_check;
92 #ifdef FLAC__HAS_OGG
93         FLAC__bool use_ogg;
94         ogg_info_struct ogg;
95 #endif
96 } encoder_wrapper_struct;
97
98 static FLAC__bool is_big_endian_host;
99
100 static unsigned char ucbuffer[CHUNK_OF_SAMPLES*FLAC__MAX_CHANNELS*((FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE+7)/8)];
101 static signed char *scbuffer = (signed char *)ucbuffer;
102 static FLAC__uint16 *usbuffer = (FLAC__uint16 *)ucbuffer;
103 static FLAC__int16 *ssbuffer = (FLAC__int16 *)ucbuffer;
104
105 static FLAC__int32 in[FLAC__MAX_CHANNELS][CHUNK_OF_SAMPLES];
106 static FLAC__int32 *input[FLAC__MAX_CHANNELS];
107
108 /* local routines */
109 static FLAC__bool init(encoder_wrapper_struct *encoder_wrapper);
110 static FLAC__bool init_encoder(encode_options_t options, unsigned channels, unsigned bps, unsigned sample_rate, encoder_wrapper_struct *encoder_wrapper);
111 static FLAC__bool convert_to_seek_table(char *requested_seek_points, int num_requested_seek_points, FLAC__uint64 stream_samples, unsigned blocksize, FLAC__StreamMetadata_SeekTable *seek_table);
112 static void append_point_to_seek_table(FLAC__StreamMetadata_SeekTable *seek_table, FLAC__uint64 sample, FLAC__uint64 stream_samples, FLAC__uint64 blocksize);
113 static int seekpoint_compare(const FLAC__StreamMetadata_SeekPoint *l, const FLAC__StreamMetadata_SeekPoint *r);
114 static void format_input(FLAC__int32 *dest[], unsigned wide_samples, FLAC__bool is_big_endian, FLAC__bool is_unsigned_samples, unsigned channels, unsigned bps, encoder_wrapper_struct *encoder_wrapper);
115 static void append_to_verify_fifo(encoder_wrapper_struct *encoder_wrapper, const FLAC__int32 * const input[], unsigned channels, unsigned wide_samples);
116 static FLAC__StreamEncoderWriteStatus write_callback(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
117 static void metadata_callback(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
118 static FLAC__StreamDecoderReadStatus verify_read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
119 static FLAC__StreamDecoderWriteStatus verify_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
120 static void verify_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
121 static void verify_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
122 static void print_stats(const encoder_wrapper_struct *encoder_wrapper);
123 static FLAC__bool read_little_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn);
124 static FLAC__bool read_little_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
125 static FLAC__bool read_big_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn);
126 static FLAC__bool read_big_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
127 static FLAC__bool read_sane_extended(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
128 static FLAC__bool write_big_endian_uint16(FILE *f, FLAC__uint16 val);
129 static FLAC__bool write_big_endian_uint64(FILE *f, FLAC__uint64 val);
130
131 int
132 flac__encode_aif(FILE *infile, long infilesize, const char *infilename, const char *outfilename,
133         const FLAC__byte *lookahead, unsigned lookahead_length, wav_encode_options_t options)
134 {
135         encoder_wrapper_struct encoder_wrapper;
136         FLAC__uint16 x;
137         FLAC__uint32 xx;
138         unsigned int channels= 0U, bps= 0U, sample_rate= 0U, sample_frames= 0U;
139         FLAC__bool got_comm_chunk= false, got_ssnd_chunk= false;
140         int info_align_carry= -1, info_align_zero= -1;
141         enum { NORMAL, DONE, ERROR, MISMATCH } status= NORMAL;
142
143         FLAC__ASSERT(!options.common.sector_align || options.common.skip == 0);
144
145         encoder_wrapper.encoder = 0;
146         encoder_wrapper.verify = options.common.verify;
147         encoder_wrapper.verbose = options.common.verbose;
148         encoder_wrapper.bytes_written = 0;
149         encoder_wrapper.samples_written = 0;
150         encoder_wrapper.stream_offset = 0;
151         encoder_wrapper.inbasefilename = flac__file_get_basename(infilename);
152         encoder_wrapper.outfilename = outfilename;
153         encoder_wrapper.seek_table.points = 0;
154         encoder_wrapper.first_seek_point_to_check = 0;
155 #ifdef FLAC__HAS_OGG
156         encoder_wrapper.use_ogg = options.common.use_ogg;
157 #endif
158
159         (void)infilesize; /* silence compiler warning about unused parameter */
160         (void)lookahead; /* silence compiler warning about unused parameter */
161         (void)lookahead_length; /* silence compiler warning about unused parameter */
162
163         if(0 == strcmp(outfilename, "-")) {
164                 encoder_wrapper.fout = file__get_binary_stdout();
165         }
166         else {
167                 if(0 == (encoder_wrapper.fout = fopen(outfilename, "wb"))) {
168                         fprintf(stderr, "%s: ERROR: can't open output file %s\n", encoder_wrapper.inbasefilename, outfilename);
169                         if(infile != stdin)
170                                 fclose(infile);
171                         return 1;
172                 }
173         }
174
175         if(!init(&encoder_wrapper))
176                 status= ERROR;
177
178         /* lookahead[] already has "FORMxxxxAIFF", do sub-chunks */
179
180         while(status==NORMAL) {
181                 size_t c= 0U;
182                 char chunk_id[4];
183
184                 /* chunk identifier; really conservative about behavior of fread() and feof() */
185                 if(feof(infile) || ((c= fread(chunk_id, 1U, 4U, infile)), c==0U && feof(infile)))
186                         status= DONE;
187                 else if(c<4U || feof(infile)) {
188                         fprintf(stderr, "%s: ERROR: incomplete chunk identifier\n", encoder_wrapper.inbasefilename);
189                         status= ERROR;
190                 }
191
192                 if(status==NORMAL && got_comm_chunk==false && !strncmp(chunk_id, "COMM", 4)) { /* common chunk */
193                         unsigned long skip;
194
195                         if(status==NORMAL) {
196                                 /* COMM chunk size */
197                                 if(!read_big_endian_uint32(infile, &xx, false, encoder_wrapper.inbasefilename))
198                                         status= ERROR;
199                                 else if(xx<18U) {
200                                         fprintf(stderr, "%s: ERROR: non-standard 'COMM' chunk has length = %u\n", encoder_wrapper.inbasefilename, (unsigned int)xx);
201                                         status= ERROR;
202                                 }
203                                 else if(xx!=18U)
204                                         fprintf(stderr, "%s: WARNING: non-standard 'COMM' chunk has length = %u\n", encoder_wrapper.inbasefilename, (unsigned int)xx);
205                                 skip= (xx-18U)+(xx & 1U);
206                         }
207
208                         if(status==NORMAL) {
209                                 /* number of channels */
210                                 if(!read_big_endian_uint16(infile, &x, false, encoder_wrapper.inbasefilename))
211                                         status= ERROR;
212                                 else if(x==0U || x>FLAC__MAX_CHANNELS) {
213                                         fprintf(stderr, "%s: ERROR: unsupported number channels %u\n", encoder_wrapper.inbasefilename, (unsigned int)x);
214                                         status= ERROR;
215                                 }
216                                 else if(options.common.sector_align && x!=2U) {
217                                         fprintf(stderr, "%s: ERROR: file has %u channels, must be 2 for --sector-align\n", encoder_wrapper.inbasefilename, (unsigned int)x);
218                                         status= ERROR;
219                                 }
220                                 channels= x;
221                         }
222
223                         if(status==NORMAL) {
224                                 /* number of sample frames */
225                                 if(!read_big_endian_uint32(infile, &xx, false, encoder_wrapper.inbasefilename))
226                                         status= ERROR;
227                                 sample_frames= xx;
228                         }
229
230                         if(status==NORMAL) {
231                                 /* bits per sample */
232                                 if(!read_big_endian_uint16(infile, &x, false, encoder_wrapper.inbasefilename))
233                                         status= ERROR;
234                                 else if(x!=8U && x!=16U && x!=24U) {
235                                         fprintf(stderr, "%s: ERROR: unsupported bits per sample %u\n", encoder_wrapper.inbasefilename, (unsigned int)x);
236                                         status= ERROR;
237                                 }
238                                 else if(options.common.sector_align && x!=16U) {
239                                         fprintf(stderr, "%s: ERROR: file has %u bits per sample, must be 16 for --sector-align\n", encoder_wrapper.inbasefilename, (unsigned int)x);
240                                         status= ERROR;
241                                 }
242                                 bps= x;
243                         }
244
245                         if(status==NORMAL) {
246                                 /* sample rate */
247                                 if(!read_sane_extended(infile, &xx, false, encoder_wrapper.inbasefilename))
248                                         status= ERROR;
249                                 else if(!FLAC__format_sample_rate_is_valid(xx)) {
250                                         fprintf(stderr, "%s: ERROR: unsupported sample rate %u\n", encoder_wrapper.inbasefilename, (unsigned int)xx);
251                                         status= ERROR;
252                                 }
253                                 else if(options.common.sector_align && xx!=44100U) {
254                                         fprintf(stderr, "%s: ERROR: file's sample rate is %u, must be 44100 for --sector-align\n", encoder_wrapper.inbasefilename, (unsigned int)xx);
255                                         status= ERROR;
256                                 }
257                                 sample_rate= xx;
258                         }
259
260                         /* skip any extra data in the COMM chunk */
261                         FLAC__ASSERT(skip<=LONG_MAX);
262                         while(status==NORMAL && skip>0U && fseek(infile, skip, SEEK_CUR)<0) {
263                                 unsigned int need= min(skip, sizeof ucbuffer);
264                                 if(fread(ucbuffer, 1U, need, infile)<need) {
265                                         fprintf(stderr, "%s: ERROR during read while skipping extra COMM data\n", encoder_wrapper.inbasefilename);
266                                         status= ERROR;
267                                 }
268                                 skip-= need;
269                         }
270
271                         got_comm_chunk= true;
272                 }
273                 else if(status==NORMAL && got_ssnd_chunk==false && !strncmp(chunk_id, "SSND", 4)) { /* sound data chunk */
274                         unsigned int offset= 0U, block_size= 0U, align_remainder= 0U, data_bytes;
275                         size_t bytes_per_frame= channels*(bps>>3);
276                         FLAC__bool pad= false;
277
278                         if(status==NORMAL && got_comm_chunk==false) {
279                                 fprintf(stderr, "%s: ERROR: got 'SSND' chunk before 'COMM' chunk\n", encoder_wrapper.inbasefilename);
280                                 status= ERROR;
281                         }
282
283                         if(status==NORMAL) {
284                                 /* SSND chunk size */
285                                 if(!read_big_endian_uint32(infile, &xx, false, encoder_wrapper.inbasefilename))
286                                         status= ERROR;
287                                 else if(xx!=(sample_frames*bytes_per_frame + 8U)) {
288                                         fprintf(stderr, "%s: ERROR: SSND chunk size inconsistent with sample frame count\n", encoder_wrapper.inbasefilename);
289                                         status= ERROR;
290                                 }
291                                 data_bytes= xx;
292                                 pad= (data_bytes & 1U) ? true : false;
293                         }
294
295                         if(status==NORMAL) {
296                                 /* offset */
297                                 if(!read_big_endian_uint32(infile, &xx, false, encoder_wrapper.inbasefilename))
298                                         status= ERROR;
299                                 else if(xx!=0U) {
300                                         fprintf(stderr, "%s: ERROR: offset is %u; must be 0\n", encoder_wrapper.inbasefilename, (unsigned int)xx);
301                                         status= ERROR;
302                                 }
303                                 offset= xx;
304                         }
305
306                         if(status==NORMAL) {
307                                 /* block size */
308                                 if(!read_big_endian_uint32(infile, &xx, false, encoder_wrapper.inbasefilename))
309                                         status= ERROR;
310                                 else if(xx!=0U) {
311                                         fprintf(stderr, "%s: ERROR: block size is %u; must be 0\n", encoder_wrapper.inbasefilename, (unsigned int)xx);
312                                         status= ERROR;
313                                 }
314                                 block_size= xx;
315                         }
316
317                         if(status==NORMAL && options.common.skip>0U) {
318                                 FLAC__uint64 remaining= options.common.skip*bytes_per_frame;
319
320                                 /* do 1<<30 bytes at a time, since 1<<30 is a nice round number, and */
321                                 /* is guaranteed to be less than LONG_MAX */
322                                 for(; remaining>0U; remaining-= remaining>(1U<<30) ? remaining : (1U<<30))
323                                 {
324                                         unsigned long skip= remaining % (1U<<30);
325
326                                         FLAC__ASSERT(skip<=LONG_MAX);
327                                         while(status==NORMAL && skip>0 && fseek(infile, skip, SEEK_CUR)<0) {
328                                                 unsigned int need= min(skip, sizeof ucbuffer);
329                                                 if(fread(ucbuffer, 1U, need, infile)<need) {
330                                                         fprintf(stderr, "%s: ERROR during read while skipping samples\n", encoder_wrapper.inbasefilename);
331                                                         status= ERROR;
332                                                 }
333                                                 skip-= need;
334                                         }
335                                 }
336                         }
337
338                         if(status==NORMAL) {
339                                 data_bytes-= (8U + (unsigned int)options.common.skip*bytes_per_frame); /*@@@ WATCHOUT: 4GB limit */
340                                 encoder_wrapper.total_samples_to_encode= data_bytes/bytes_per_frame + *options.common.align_reservoir_samples;
341                                 if(options.common.sector_align) {
342                                         align_remainder= (unsigned int)(encoder_wrapper.total_samples_to_encode % 588U);
343                                         if(options.common.is_last_file)
344                                                 encoder_wrapper.total_samples_to_encode+= (588U-align_remainder); /* will pad with zeroes */
345                                         else
346                                                 encoder_wrapper.total_samples_to_encode-= align_remainder; /* will stop short and carry over to next file */
347                                 }
348
349                                 /* +54 for the size of the AIFF headers; this is just an estimate for the progress indicator and doesn't need to be exact */
350                                 encoder_wrapper.unencoded_size= encoder_wrapper.total_samples_to_encode*bytes_per_frame+54;
351
352                                 if(!init_encoder(options.common, channels, bps, sample_rate, &encoder_wrapper))
353                                         status= ERROR;
354                                 else
355                                         encoder_wrapper.verify_fifo.into_frames = true;
356                         }
357
358                         /* first do any samples in the reservoir */
359                         if(status==NORMAL && options.common.sector_align && *options.common.align_reservoir_samples>0U) {
360                                 append_to_verify_fifo(&encoder_wrapper, (const FLAC__int32 *const *)options.common.align_reservoir, channels, *options.common.align_reservoir_samples);
361
362                                 if(!FLAC__stream_encoder_process(encoder_wrapper.encoder, (const FLAC__int32 *const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
363                                         fprintf(stderr, "%s: ERROR during encoding, state = %d:%s\n", encoder_wrapper.inbasefilename, FLAC__stream_encoder_get_state(encoder_wrapper.encoder), FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder_wrapper.encoder)]);
364                                         status= ERROR;
365                                 }
366                         }
367
368                         /* decrement the data_bytes counter if we need to align the file */
369                         if(status==NORMAL && options.common.sector_align) {
370                                 if(options.common.is_last_file)
371                                         *options.common.align_reservoir_samples= 0U;
372                                 else {
373                                         *options.common.align_reservoir_samples= align_remainder;
374                                         data_bytes-= (*options.common.align_reservoir_samples)*bytes_per_frame;
375                                 }
376                         }
377
378                         /* now do from the file */
379                         while(status==NORMAL && data_bytes>0) {
380                                 size_t bytes_read= fread(ucbuffer, 1U, min(data_bytes, CHUNK_OF_SAMPLES*bytes_per_frame), infile);
381
382                                 if(bytes_read==0U) {
383                                         if(ferror(infile)) {
384                                                 fprintf(stderr, "%s: ERROR during read\n", encoder_wrapper.inbasefilename);
385                                                 status= ERROR;
386                                         }
387                                         else if(feof(infile)) {
388                                                 fprintf(stderr, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_wrapper.inbasefilename, (unsigned int)encoder_wrapper.total_samples_to_encode, (unsigned int)encoder_wrapper.samples_written);
389                                                 data_bytes= 0;
390                                         }
391                                 }
392                                 else {
393                                         if(bytes_read % bytes_per_frame != 0U) {
394                                                 fprintf(stderr, "%s: ERROR: got partial sample\n", encoder_wrapper.inbasefilename);
395                                                 status= ERROR;
396                                         }
397                                         else {
398                                                 unsigned int frames= bytes_read/bytes_per_frame;
399                                                 format_input(input, frames, true, false, channels, bps, &encoder_wrapper);
400
401                                                 if(!FLAC__stream_encoder_process(encoder_wrapper.encoder, (const FLAC__int32 *const *)input, frames)) {
402                                                         fprintf(stderr, "%s: ERROR during encoding, state = %d:%s\n", encoder_wrapper.inbasefilename, FLAC__stream_encoder_get_state(encoder_wrapper.encoder), FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder_wrapper.encoder)]);
403                                                         status= ERROR;
404                                                 }
405                                                 else
406                                                         data_bytes-= bytes_read;
407                                         }
408                                 }
409                         }
410
411                         /* now read unaligned samples into reservoir or pad with zeroes if necessary */
412                         if(status==NORMAL && options.common.sector_align) {
413                                 if(options.common.is_last_file) {
414                                         unsigned int pad_frames= 588U-align_remainder;
415
416                                         if(pad_frames<588U) {
417                                                 unsigned int i;
418
419                                                 info_align_zero= pad_frames;
420                                                 for(i= 0U; i<channels; ++i)
421                                                         memset(input[i], 0, pad_frames*(bps>>3));
422                                                 append_to_verify_fifo(&encoder_wrapper, (const FLAC__int32 *const *)input, channels, pad_frames);
423
424                                                 if(!FLAC__stream_encoder_process(encoder_wrapper.encoder, (const FLAC__int32 *const *)input, pad_frames)) {
425                                                         fprintf(stderr, "%s: ERROR during encoding, state = %d:%s\n", encoder_wrapper.inbasefilename, FLAC__stream_encoder_get_state(encoder_wrapper.encoder), FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder_wrapper.encoder)]);
426                                                         status= ERROR;
427                                                 }
428                                         }
429                                 }
430                                 else {
431                                         if(*options.common.align_reservoir_samples > 0) {
432                                                 size_t bytes_read= fread(ucbuffer, 1U, (*options.common.align_reservoir_samples)*bytes_per_frame, infile);
433
434                                                 FLAC__ASSERT(CHUNK_OF_SAMPLES>=588U);
435                                                 if(bytes_read==0U && ferror(infile)) {
436                                                         fprintf(stderr, "%s: ERROR during read\n", encoder_wrapper.inbasefilename);
437                                                         status= ERROR;
438                                                 }
439                                                 else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_frame)
440                                                         fprintf(stderr, "%s: WARNING: unexpected EOF; read %u bytes; expected %u samples, got %u samples\n", encoder_wrapper.inbasefilename, (unsigned int)bytes_read, (unsigned int)encoder_wrapper.total_samples_to_encode, (unsigned int)encoder_wrapper.samples_written);
441                                                 else {
442                                                         info_align_carry= *options.common.align_reservoir_samples;
443                                                         format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, true, false, channels, bps, &encoder_wrapper);
444                                                 }
445                                         }
446                                 }
447                         }
448
449                         if(status==NORMAL && pad==true) {
450                                 unsigned char tmp;
451
452                                 if(fread(&tmp, 1U, 1U, infile)<1U) {
453                                         fprintf(stderr, "%s: ERROR during read of SSND pad byte\n", encoder_wrapper.inbasefilename);
454                                         status= ERROR;
455                                 }
456                         }
457
458                         got_ssnd_chunk= true;
459                 }
460                 else if(status==NORMAL) { /* other chunk */
461                         if(!strncmp(chunk_id, "COMM", 4))
462                                 fprintf(stderr, "%s: WARNING: skipping extra 'COMM' chunk\n", encoder_wrapper.inbasefilename);
463                         else if(!strncmp(chunk_id, "SSND", 4))
464                                 fprintf(stderr, "%s: WARNING: skipping extra 'SSND' chunk\n", encoder_wrapper.inbasefilename);
465                         else
466                                 fprintf(stderr, "%s: WARNING: skipping unknown chunk '%s'\n", encoder_wrapper.inbasefilename, chunk_id);
467
468                         /* chunk size */
469                         if(!read_big_endian_uint32(infile, &xx, false, encoder_wrapper.inbasefilename))
470                                 status= ERROR;
471                         else {
472                                 unsigned long skip= xx+(xx & 1U);
473
474                                 FLAC__ASSERT(skip<=LONG_MAX);
475                                 while(status==NORMAL && skip>0U && fseek(infile, skip, SEEK_CUR)<0) {
476                                         unsigned int need= min(skip, sizeof ucbuffer);
477                                         if(fread(ucbuffer, 1U, need, infile)<need) {
478                                                 fprintf(stderr, "%s: ERROR during read while skipping unknown chunk\n", encoder_wrapper.inbasefilename);
479                                                 status= ERROR;
480                                         }
481                                         skip-= need;
482                                 }
483                         }
484                 }
485         }
486
487         if(got_ssnd_chunk==false && sample_frames!=0U) {
488                 fprintf(stderr, "%s: ERROR: missing SSND chunk\n", encoder_wrapper.inbasefilename);
489                 status= ERROR;
490         }
491
492         if(encoder_wrapper.encoder) {
493                 FLAC__stream_encoder_finish(encoder_wrapper.encoder);
494                 FLAC__stream_encoder_delete(encoder_wrapper.encoder);
495 #ifdef FLAC__HAS_OGG
496                 if(encoder_wrapper.use_ogg)
497                         ogg_stream_clear(&encoder_wrapper.ogg.os);
498 #endif
499         }
500         if(encoder_wrapper.verbose && encoder_wrapper.total_samples_to_encode > 0) {
501                 if(status==DONE)
502                         print_stats(&encoder_wrapper);
503                 fprintf(stderr, "\n");
504         }
505
506         if(0 != encoder_wrapper.seek_table.points)
507                 free(encoder_wrapper.seek_table.points);
508         if(options.common.verify) {
509                 FLAC__stream_decoder_finish(encoder_wrapper.verify_fifo.decoder);
510                 FLAC__stream_decoder_delete(encoder_wrapper.verify_fifo.decoder);
511                 if(encoder_wrapper.verify_fifo.result != FLAC__VERIFY_OK) {
512                         fprintf(stderr, "Verify FAILED! (%s)  Do not trust %s\n", verify_code_string[encoder_wrapper.verify_fifo.result], outfilename);
513                         status= MISMATCH;
514                 }
515         }
516
517         if(infile != stdin)
518                 fclose(infile);
519
520         if(status==DONE) {
521                 if(info_align_carry >= 0)
522                         fprintf(stderr, "%s: INFO: sector alignment causing %d samples to be carried over\n", encoder_wrapper.inbasefilename, info_align_carry);
523                 if(info_align_zero >= 0)
524                         fprintf(stderr, "%s: INFO: sector alignment causing %d zero samples to be appended\n", encoder_wrapper.inbasefilename, info_align_zero);
525         }
526         else if(status==ERROR)
527                 unlink(outfilename);
528
529         return status==ERROR || status==MISMATCH;
530 }
531
532 int flac__encode_wav(FILE *infile, long infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, wav_encode_options_t options)
533 {
534         encoder_wrapper_struct encoder_wrapper;
535         FLAC__bool is_unsigned_samples = false;
536         unsigned channels = 0, bps = 0, sample_rate = 0, data_bytes;
537         size_t bytes_per_wide_sample, bytes_read;
538         FLAC__uint16 x;
539         FLAC__uint32 xx;
540         FLAC__bool got_fmt_chunk = false, got_data_chunk = false;
541         unsigned align_remainder = 0;
542         int info_align_carry = -1, info_align_zero = -1;
543
544         FLAC__ASSERT(!options.common.sector_align || options.common.skip == 0);
545
546         encoder_wrapper.encoder = 0;
547         encoder_wrapper.verify = options.common.verify;
548         encoder_wrapper.verbose = options.common.verbose;
549         encoder_wrapper.bytes_written = 0;
550         encoder_wrapper.samples_written = 0;
551         encoder_wrapper.stream_offset = 0;
552         encoder_wrapper.inbasefilename = flac__file_get_basename(infilename);
553         encoder_wrapper.outfilename = outfilename;
554         encoder_wrapper.seek_table.points = 0;
555         encoder_wrapper.first_seek_point_to_check = 0;
556 #ifdef FLAC__HAS_OGG
557         encoder_wrapper.use_ogg = options.common.use_ogg;
558 #endif
559         (void)infilesize;
560         (void)lookahead;
561         (void)lookahead_length;
562
563         if(0 == strcmp(outfilename, "-")) {
564                 encoder_wrapper.fout = file__get_binary_stdout();
565         }
566         else {
567                 if(0 == (encoder_wrapper.fout = fopen(outfilename, "wb"))) {
568                         fprintf(stderr, "%s: ERROR: can't open output file %s\n", encoder_wrapper.inbasefilename, outfilename);
569                         if(infile != stdin)
570                                 fclose(infile);
571                         return 1;
572                 }
573         }
574
575         if(!init(&encoder_wrapper))
576                 goto wav_abort_;
577
578         /*
579          * lookahead[] already has "RIFFxxxxWAVE", do sub-chunks
580          */
581         while(!feof(infile)) {
582                 if(!read_little_endian_uint32(infile, &xx, true, encoder_wrapper.inbasefilename))
583                         goto wav_abort_;
584                 if(feof(infile))
585                         break;
586                 if(xx == 0x20746d66 && !got_fmt_chunk) { /* "fmt " */
587                         /* fmt sub-chunk size */
588                         if(!read_little_endian_uint32(infile, &xx, false, encoder_wrapper.inbasefilename))
589                                 goto wav_abort_;
590                         if(xx < 16) {
591                                 fprintf(stderr, "%s: ERROR: found non-standard 'fmt ' sub-chunk which has length = %u\n", encoder_wrapper.inbasefilename, (unsigned)xx);
592                                 goto wav_abort_;
593                         }
594                         else if(xx != 16 && xx != 18) {
595                                 fprintf(stderr, "%s: WARNING: found non-standard 'fmt ' sub-chunk which has length = %u\n", encoder_wrapper.inbasefilename, (unsigned)xx);
596                         }
597                         data_bytes = xx;
598                         /* compression code */
599                         if(!read_little_endian_uint16(infile, &x, false, encoder_wrapper.inbasefilename))
600                                 goto wav_abort_;
601                         if(x != 1) {
602                                 fprintf(stderr, "%s: ERROR: unsupported compression type %u\n", encoder_wrapper.inbasefilename, (unsigned)x);
603                                 goto wav_abort_;
604                         }
605                         /* number of channels */
606                         if(!read_little_endian_uint16(infile, &x, false, encoder_wrapper.inbasefilename))
607                                 goto wav_abort_;
608                         if(x == 0 || x > FLAC__MAX_CHANNELS) {
609                                 fprintf(stderr, "%s: ERROR: unsupported number channels %u\n", encoder_wrapper.inbasefilename, (unsigned)x);
610                                 goto wav_abort_;
611                         }
612                         else if(options.common.sector_align && x != 2) {
613                                 fprintf(stderr, "%s: ERROR: file has %u channels, must be 2 for --sector-align\n", encoder_wrapper.inbasefilename, (unsigned)x);
614                                 goto wav_abort_;
615                         }
616                         channels = x;
617                         /* sample rate */
618                         if(!read_little_endian_uint32(infile, &xx, false, encoder_wrapper.inbasefilename))
619                                 goto wav_abort_;
620                         if(!FLAC__format_sample_rate_is_valid(xx)) {
621                                 fprintf(stderr, "%s: ERROR: unsupported sample rate %u\n", encoder_wrapper.inbasefilename, (unsigned)xx);
622                                 goto wav_abort_;
623                         }
624                         else if(options.common.sector_align && xx != 44100) {
625                                 fprintf(stderr, "%s: ERROR: file's sample rate is %u, must be 44100 for --sector-align\n", encoder_wrapper.inbasefilename, (unsigned)xx);
626                                 goto wav_abort_;
627                         }
628                         sample_rate = xx;
629                         /* avg bytes per second (ignored) */
630                         if(!read_little_endian_uint32(infile, &xx, false, encoder_wrapper.inbasefilename))
631                                 goto wav_abort_;
632                         /* block align (ignored) */
633                         if(!read_little_endian_uint16(infile, &x, false, encoder_wrapper.inbasefilename))
634                                 goto wav_abort_;
635                         /* bits per sample */
636                         if(!read_little_endian_uint16(infile, &x, false, encoder_wrapper.inbasefilename))
637                                 goto wav_abort_;
638                         if(x != 8 && x != 16 && x != 24) {
639                                 fprintf(stderr, "%s: ERROR: unsupported bits per sample %u\n", encoder_wrapper.inbasefilename, (unsigned)x);
640                                 goto wav_abort_;
641                         }
642                         else if(options.common.sector_align && x != 16) {
643                                 fprintf(stderr, "%s: ERROR: file has %u bits per sample, must be 16 for --sector-align\n", encoder_wrapper.inbasefilename, (unsigned)x);
644                                 goto wav_abort_;
645                         }
646                         bps = x;
647                         is_unsigned_samples = (x == 8);
648
649                         /* skip any extra data in the fmt sub-chunk */
650                         data_bytes -= 16;
651                         if(data_bytes > 0) {
652                                 unsigned left, need;
653                                 for(left = data_bytes; left > 0; ) {
654                                         need = min(left, CHUNK_OF_SAMPLES);
655                                         if(fread(ucbuffer, 1U, need, infile) < need) {
656                                                 fprintf(stderr, "%s: ERROR during read while skipping samples\n", encoder_wrapper.inbasefilename);
657                                                 goto wav_abort_;
658                                         }
659                                         left -= need;
660                                 }
661                         }
662
663                         got_fmt_chunk = true;
664                 }
665                 else if(xx == 0x61746164 && !got_data_chunk && got_fmt_chunk) { /* "data" */
666                         /* data size */
667                         if(!read_little_endian_uint32(infile, &xx, false, encoder_wrapper.inbasefilename))
668                                 goto wav_abort_;
669                         data_bytes = xx;
670
671                         bytes_per_wide_sample = channels * (bps >> 3);
672
673                         if(options.common.skip > 0) {
674                                 if(fseek(infile, bytes_per_wide_sample * (unsigned)options.common.skip, SEEK_CUR) < 0) {
675                                         /* can't seek input, read ahead manually... */
676                                         unsigned left, need;
677                                         for(left = (unsigned)options.common.skip; left > 0; ) { /*@@@ WATCHOUT: 4GB limit */
678                                                 need = min(left, CHUNK_OF_SAMPLES);
679                                                 if(fread(ucbuffer, bytes_per_wide_sample, need, infile) < need) {
680                                                         fprintf(stderr, "%s: ERROR during read while skipping samples\n", encoder_wrapper.inbasefilename);
681                                                         goto wav_abort_;
682                                                 }
683                                                 left -= need;
684                                         }
685                                 }
686                         }
687
688                         data_bytes -= (unsigned)options.common.skip * bytes_per_wide_sample; /*@@@ WATCHOUT: 4GB limit */
689                         encoder_wrapper.total_samples_to_encode = data_bytes / bytes_per_wide_sample + *options.common.align_reservoir_samples;
690                         if(options.common.sector_align) {
691                                 align_remainder = (unsigned)(encoder_wrapper.total_samples_to_encode % 588);
692                                 if(options.common.is_last_file)
693                                         encoder_wrapper.total_samples_to_encode += (588-align_remainder); /* will pad with zeroes */
694                                 else
695                                         encoder_wrapper.total_samples_to_encode -= align_remainder; /* will stop short and carry over to next file */
696                         }
697
698                         /* +44 for the size of the WAV headers; this is just an estimate for the progress indicator and doesn't need to be exact */
699                         encoder_wrapper.unencoded_size = encoder_wrapper.total_samples_to_encode * bytes_per_wide_sample + 44;
700
701                         if(!init_encoder(options.common, channels, bps, sample_rate, &encoder_wrapper))
702                                 goto wav_abort_;
703
704                         encoder_wrapper.verify_fifo.into_frames = true;
705
706                         /*
707                          * first do any samples in the reservoir
708                          */
709                         if(options.common.sector_align && *options.common.align_reservoir_samples > 0) {
710                                 append_to_verify_fifo(&encoder_wrapper, (const FLAC__int32 * const *)options.common.align_reservoir, channels, *options.common.align_reservoir_samples);
711
712                                 if(!FLAC__stream_encoder_process(encoder_wrapper.encoder, (const FLAC__int32 * const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
713                                         fprintf(stderr, "%s: ERROR during encoding, state = %d:%s\n", encoder_wrapper.inbasefilename, FLAC__stream_encoder_get_state(encoder_wrapper.encoder), FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder_wrapper.encoder)]);
714                                         goto wav_abort_;
715                                 }
716                         }
717
718                         /*
719                          * decrement the data_bytes counter if we need to align the file
720                          */
721                         if(options.common.sector_align) {
722                                 if(options.common.is_last_file) {
723                                         *options.common.align_reservoir_samples = 0;
724                                 }
725                                 else {
726                                         *options.common.align_reservoir_samples = align_remainder;
727                                         data_bytes -= (*options.common.align_reservoir_samples) * bytes_per_wide_sample;
728                                 }
729                         }
730
731                         /*
732                          * now do from the file
733                          */
734                         while(data_bytes > 0) {
735                                 bytes_read = fread(ucbuffer, sizeof(unsigned char), min(data_bytes, CHUNK_OF_SAMPLES * bytes_per_wide_sample), infile);
736                                 if(bytes_read == 0) {
737                                         if(ferror(infile)) {
738                                                 fprintf(stderr, "%s: ERROR during read\n", encoder_wrapper.inbasefilename);
739                                                 goto wav_abort_;
740                                         }
741                                         else if(feof(infile)) {
742                                                 fprintf(stderr, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_wrapper.inbasefilename, (unsigned)encoder_wrapper.total_samples_to_encode, (unsigned)encoder_wrapper.samples_written);
743                                                 data_bytes = 0;
744                                         }
745                                 }
746                                 else {
747                                         if(bytes_read % bytes_per_wide_sample != 0) {
748                                                 fprintf(stderr, "%s: ERROR: got partial sample\n", encoder_wrapper.inbasefilename);
749                                                 goto wav_abort_;
750                                         }
751                                         else {
752                                                 unsigned wide_samples = bytes_read / bytes_per_wide_sample;
753                                                 format_input(input, wide_samples, false, is_unsigned_samples, channels, bps, &encoder_wrapper);
754
755                                                 if(!FLAC__stream_encoder_process(encoder_wrapper.encoder, (const FLAC__int32 * const *)input, wide_samples)) {
756                                                         fprintf(stderr, "%s: ERROR during encoding, state = %d:%s\n", encoder_wrapper.inbasefilename, FLAC__stream_encoder_get_state(encoder_wrapper.encoder), FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder_wrapper.encoder)]);
757                                                         goto wav_abort_;
758                                                 }
759                                                 data_bytes -= bytes_read;
760                                         }
761                                 }
762                         }
763
764                         /*
765                          * now read unaligned samples into reservoir or pad with zeroes if necessary
766                          */
767                         if(options.common.sector_align) {
768                                 if(options.common.is_last_file) {
769                                         unsigned wide_samples = 588 - align_remainder;
770                                         if(wide_samples < 588) {
771                                                 unsigned channel;
772
773                                                 info_align_zero = wide_samples;
774                                                 data_bytes = wide_samples * (bps >> 3);
775                                                 for(channel = 0; channel < channels; channel++)
776                                                         memset(input[channel], 0, data_bytes);
777                                                 append_to_verify_fifo(&encoder_wrapper, (const FLAC__int32 * const *)input, channels, wide_samples);
778
779                                                 if(!FLAC__stream_encoder_process(encoder_wrapper.encoder, (const FLAC__int32 * const *)input, wide_samples)) {
780                                                         fprintf(stderr, "%s: ERROR during encoding, state = %d:%s\n", encoder_wrapper.inbasefilename, FLAC__stream_encoder_get_state(encoder_wrapper.encoder), FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder_wrapper.encoder)]);
781                                                         goto wav_abort_;
782                                                 }
783                                         }
784                                 }
785                                 else {
786                                         if(*options.common.align_reservoir_samples > 0) {
787                                                 FLAC__ASSERT(CHUNK_OF_SAMPLES >= 588);
788                                                 bytes_read = fread(ucbuffer, sizeof(unsigned char), (*options.common.align_reservoir_samples) * bytes_per_wide_sample, infile);
789                                                 if(bytes_read == 0 && ferror(infile)) {
790                                                         fprintf(stderr, "%s: ERROR during read\n", encoder_wrapper.inbasefilename);
791                                                         goto wav_abort_;
792                                                 }
793                                                 else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) {
794                                                         fprintf(stderr, "%s: WARNING: unexpected EOF; read %u bytes; expected %u samples, got %u samples\n", encoder_wrapper.inbasefilename, (unsigned)bytes_read, (unsigned)encoder_wrapper.total_samples_to_encode, (unsigned)encoder_wrapper.samples_written);
795                                                         data_bytes = 0;
796                                                 }
797                                                 else {
798                                                         info_align_carry = *options.common.align_reservoir_samples;
799                                                         format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, false, is_unsigned_samples, channels, bps, &encoder_wrapper);
800                                                 }
801                                         }
802                                 }
803                         }
804
805                         got_data_chunk = true;
806                 }
807                 else {
808                         if(xx == 0x20746d66 && got_fmt_chunk) { /* "fmt " */
809                                 fprintf(stderr, "%s: WARNING: skipping extra 'fmt ' sub-chunk\n", encoder_wrapper.inbasefilename);
810                         }
811                         else if(xx == 0x61746164) { /* "data" */
812                                 if(got_data_chunk) {
813                                         fprintf(stderr, "%s: WARNING: skipping extra 'data' sub-chunk\n", encoder_wrapper.inbasefilename);
814                                 }
815                                 else if(!got_fmt_chunk) {
816                                         fprintf(stderr, "%s: ERROR: got 'data' sub-chunk before 'fmt' sub-chunk\n", encoder_wrapper.inbasefilename);
817                                         goto wav_abort_;
818                                 }
819                                 else {
820                                         FLAC__ASSERT(0);
821                                 }
822                         }
823                         else {
824                                 fprintf(stderr, "%s: WARNING: skipping unknown sub-chunk '%c%c%c%c'\n", encoder_wrapper.inbasefilename, (char)(xx&255), (char)((xx>>8)&255), (char)((xx>>16)&255), (char)(xx>>24));
825                         }
826                         /* sub-chunk size */
827                         if(!read_little_endian_uint32(infile, &xx, false, encoder_wrapper.inbasefilename))
828                                 goto wav_abort_;
829                         if(fseek(infile, xx, SEEK_CUR) < 0) {
830                                 /* can't seek input, read ahead manually... */
831                                 unsigned left, need;
832                                 const unsigned chunk = sizeof(ucbuffer);
833                                 for(left = xx; left > 0; ) {
834                                         need = min(left, chunk);
835                                         if(fread(ucbuffer, 1, need, infile) < need) {
836                                                 fprintf(stderr, "%s: ERROR during read while skipping unsupported sub-chunk\n", encoder_wrapper.inbasefilename);
837                                                 goto wav_abort_;
838                                         }
839                                         left -= need;
840                                 }
841                         }
842                 }
843         }
844
845         if(encoder_wrapper.encoder) {
846                 FLAC__stream_encoder_finish(encoder_wrapper.encoder);
847                 FLAC__stream_encoder_delete(encoder_wrapper.encoder);
848 #ifdef FLAC__HAS_OGG
849                 if(encoder_wrapper.use_ogg)
850                         ogg_stream_clear(&encoder_wrapper.ogg.os);
851 #endif
852         }
853         if(encoder_wrapper.verbose && encoder_wrapper.total_samples_to_encode > 0) {
854                 print_stats(&encoder_wrapper);
855                 fprintf(stderr, "\n");
856         }
857         if(0 != encoder_wrapper.seek_table.points)
858                 free(encoder_wrapper.seek_table.points);
859         if(options.common.verify) {
860                 FLAC__stream_decoder_finish(encoder_wrapper.verify_fifo.decoder);
861                 FLAC__stream_decoder_delete(encoder_wrapper.verify_fifo.decoder);
862                 if(encoder_wrapper.verify_fifo.result != FLAC__VERIFY_OK) {
863                         fprintf(stderr, "Verify FAILED! (%s)  Do not trust %s\n", verify_code_string[encoder_wrapper.verify_fifo.result], outfilename);
864                         return 1;
865                 }
866         }
867         if(info_align_carry >= 0)
868                 fprintf(stderr, "%s: INFO: sector alignment causing %d samples to be carried over\n", encoder_wrapper.inbasefilename, info_align_carry);
869         if(info_align_zero >= 0)
870                 fprintf(stderr, "%s: INFO: sector alignment causing %d zero samples to be appended\n", encoder_wrapper.inbasefilename, info_align_zero);
871         if(infile != stdin)
872                 fclose(infile);
873         return 0;
874 wav_abort_:
875         if(encoder_wrapper.verbose && encoder_wrapper.total_samples_to_encode > 0)
876                 fprintf(stderr, "\n");
877         if(encoder_wrapper.encoder) {
878                 FLAC__stream_encoder_finish(encoder_wrapper.encoder);
879                 FLAC__stream_encoder_delete(encoder_wrapper.encoder);
880 #ifdef FLAC__HAS_OGG
881                 if(encoder_wrapper.use_ogg)
882                         ogg_stream_clear(&encoder_wrapper.ogg.os);
883 #endif
884         }
885         if(0 != encoder_wrapper.seek_table.points)
886                 free(encoder_wrapper.seek_table.points);
887         if(options.common.verify) {
888                 FLAC__stream_decoder_finish(encoder_wrapper.verify_fifo.decoder);
889                 FLAC__stream_decoder_delete(encoder_wrapper.verify_fifo.decoder);
890                 if(encoder_wrapper.verify_fifo.result != FLAC__VERIFY_OK) {
891                         fprintf(stderr, "Verify FAILED! (%s)  Do not trust %s\n", verify_code_string[encoder_wrapper.verify_fifo.result], outfilename);
892                         return 1;
893                 }
894         }
895         if(infile != stdin)
896                 fclose(infile);
897         unlink(outfilename);
898         return 1;
899 }
900
901 int flac__encode_raw(FILE *infile, long infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, raw_encode_options_t options)
902 {
903         encoder_wrapper_struct encoder_wrapper;
904         size_t bytes_read;
905         const size_t bytes_per_wide_sample = options.channels * (options.bps >> 3);
906         unsigned align_remainder = 0;
907         int info_align_carry = -1, info_align_zero = -1;
908
909         FLAC__ASSERT(!options.common.sector_align || options.common.skip == 0);
910         FLAC__ASSERT(!options.common.sector_align || options.channels == 2);
911         FLAC__ASSERT(!options.common.sector_align || options.bps == 16);
912         FLAC__ASSERT(!options.common.sector_align || options.sample_rate == 44100);
913         FLAC__ASSERT(!options.common.sector_align || infilesize >= 0);
914
915         encoder_wrapper.encoder = 0;
916         encoder_wrapper.verify = options.common.verify;
917         encoder_wrapper.verbose = options.common.verbose;
918         encoder_wrapper.bytes_written = 0;
919         encoder_wrapper.samples_written = 0;
920         encoder_wrapper.stream_offset = 0;
921         encoder_wrapper.inbasefilename = flac__file_get_basename(infilename);
922         encoder_wrapper.outfilename = outfilename;
923         encoder_wrapper.seek_table.points = 0;
924         encoder_wrapper.first_seek_point_to_check = 0;
925 #ifdef FLAC__HAS_OGG
926         encoder_wrapper.use_ogg = options.common.use_ogg;
927 #endif
928
929         if(0 == strcmp(outfilename, "-")) {
930                 encoder_wrapper.fout = file__get_binary_stdout();
931         }
932         else {
933                 if(0 == (encoder_wrapper.fout = fopen(outfilename, "wb"))) {
934                         fprintf(stderr, "ERROR: can't open output file %s\n", outfilename);
935                         if(infile != stdin)
936                                 fclose(infile);
937                         return 1;
938                 }
939         }
940
941         if(!init(&encoder_wrapper))
942                 goto raw_abort_;
943
944         /* get the file length */
945         if(infilesize < 0) {
946                 encoder_wrapper.total_samples_to_encode = encoder_wrapper.unencoded_size = 0;
947         }
948         else {
949                 if(options.common.sector_align) {
950                         FLAC__ASSERT(options.common.skip == 0);
951                         encoder_wrapper.total_samples_to_encode = (unsigned)infilesize / bytes_per_wide_sample + *options.common.align_reservoir_samples;
952                         align_remainder = (unsigned)(encoder_wrapper.total_samples_to_encode % 588);
953                         if(options.common.is_last_file)
954                                 encoder_wrapper.total_samples_to_encode += (588-align_remainder); /* will pad with zeroes */
955                         else
956                                 encoder_wrapper.total_samples_to_encode -= align_remainder; /* will stop short and carry over to next file */
957                 }
958                 else {
959                         encoder_wrapper.total_samples_to_encode = (unsigned)infilesize / bytes_per_wide_sample - options.common.skip;
960                 }
961
962                 encoder_wrapper.unencoded_size = encoder_wrapper.total_samples_to_encode * bytes_per_wide_sample;
963         }
964
965         if(encoder_wrapper.verbose && encoder_wrapper.total_samples_to_encode <= 0)
966                 fprintf(stderr, "(No runtime statistics possible; please wait for encoding to finish...)\n");
967
968         if(options.common.skip > 0) {
969                 unsigned skip_bytes = bytes_per_wide_sample * (unsigned)options.common.skip;
970                 if(skip_bytes > lookahead_length) {
971                         skip_bytes -= lookahead_length;
972                         lookahead_length = 0;
973                         if(fseek(infile, (long)skip_bytes, SEEK_CUR) < 0) {
974                                 /* can't seek input, read ahead manually... */
975                                 unsigned left, need;
976                                 const unsigned chunk = sizeof(ucbuffer);
977                                 for(left = skip_bytes; left > 0; ) {
978                                         need = min(left, chunk);
979                                         if(fread(ucbuffer, 1, need, infile) < need) {
980                                                 fprintf(stderr, "%s: ERROR during read while skipping samples\n", encoder_wrapper.inbasefilename);
981                                                 goto raw_abort_;
982                                         }
983                                         left -= need;
984                                 }
985                         }
986                 }
987                 else {
988                         lookahead += skip_bytes;
989                         lookahead_length -= skip_bytes;
990                 }
991         }
992
993         if(!init_encoder(options.common, options.channels, options.bps, options.sample_rate, &encoder_wrapper))
994                 goto raw_abort_;
995
996         encoder_wrapper.verify_fifo.into_frames = true;
997
998         /*
999          * first do any samples in the reservoir
1000          */
1001         if(options.common.sector_align && *options.common.align_reservoir_samples > 0) {
1002                 append_to_verify_fifo(&encoder_wrapper, (const FLAC__int32 * const *)options.common.align_reservoir, options.channels, *options.common.align_reservoir_samples);
1003
1004                 if(!FLAC__stream_encoder_process(encoder_wrapper.encoder, (const FLAC__int32 * const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
1005                         fprintf(stderr, "%s: ERROR during encoding, state = %d:%s\n", encoder_wrapper.inbasefilename, FLAC__stream_encoder_get_state(encoder_wrapper.encoder), FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder_wrapper.encoder)]);
1006                         goto raw_abort_;
1007                 }
1008         }
1009
1010         /*
1011          * decrement infilesize if we need to align the file
1012          */
1013         if(options.common.sector_align) {
1014                 FLAC__ASSERT(infilesize >= 0);
1015                 if(options.common.is_last_file) {
1016                         *options.common.align_reservoir_samples = 0;
1017                 }
1018                 else {
1019                         *options.common.align_reservoir_samples = align_remainder;
1020                         infilesize -= (long)((*options.common.align_reservoir_samples) * bytes_per_wide_sample);
1021                 }
1022         }
1023
1024         /*
1025          * now do from the file
1026          */
1027         while(!feof(infile)) {
1028                 if(lookahead_length > 0) {
1029                         FLAC__ASSERT(lookahead_length < CHUNK_OF_SAMPLES * bytes_per_wide_sample);
1030                         memcpy(ucbuffer, lookahead, lookahead_length);
1031                         bytes_read = fread(ucbuffer+lookahead_length, sizeof(unsigned char), CHUNK_OF_SAMPLES * bytes_per_wide_sample - lookahead_length, infile) + lookahead_length;
1032                         if(ferror(infile)) {
1033                                 fprintf(stderr, "%s: ERROR during read\n", encoder_wrapper.inbasefilename);
1034                                 goto raw_abort_;
1035                         }
1036                         lookahead_length = 0;
1037                 }
1038                 else
1039                         bytes_read = fread(ucbuffer, sizeof(unsigned char), CHUNK_OF_SAMPLES * bytes_per_wide_sample, infile);
1040
1041                 if(bytes_read == 0) {
1042                         if(ferror(infile)) {
1043                                 fprintf(stderr, "%s: ERROR during read\n", encoder_wrapper.inbasefilename);
1044                                 goto raw_abort_;
1045                         }
1046                 }
1047                 else if(bytes_read % bytes_per_wide_sample != 0) {
1048                         fprintf(stderr, "%s: ERROR: got partial sample\n", encoder_wrapper.inbasefilename);
1049                         goto raw_abort_;
1050                 }
1051                 else {
1052                         unsigned wide_samples = bytes_read / bytes_per_wide_sample;
1053                         format_input(input, wide_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps, &encoder_wrapper);
1054
1055                         if(!FLAC__stream_encoder_process(encoder_wrapper.encoder, (const FLAC__int32 * const *)input, wide_samples)) {
1056                                 fprintf(stderr, "%s: ERROR during encoding, state = %d:%s\n", encoder_wrapper.inbasefilename, FLAC__stream_encoder_get_state(encoder_wrapper.encoder), FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder_wrapper.encoder)]);
1057                                 goto raw_abort_;
1058                         }
1059                 }
1060         }
1061
1062         /*
1063          * now read unaligned samples into reservoir or pad with zeroes if necessary
1064          */
1065         if(options.common.sector_align) {
1066                 if(options.common.is_last_file) {
1067                         unsigned wide_samples = 588 - align_remainder;
1068                         if(wide_samples < 588) {
1069                                 unsigned channel, data_bytes;
1070
1071                                 info_align_zero = wide_samples;
1072                                 data_bytes = wide_samples * (options.bps >> 3);
1073                                 for(channel = 0; channel < options.channels; channel++)
1074                                         memset(input[channel], 0, data_bytes);
1075                                 append_to_verify_fifo(&encoder_wrapper, (const FLAC__int32 * const *)input, options.channels, wide_samples);
1076
1077                                 if(!FLAC__stream_encoder_process(encoder_wrapper.encoder, (const FLAC__int32 * const *)input, wide_samples)) {
1078                                         fprintf(stderr, "%s: ERROR during encoding, state = %d:%s\n", encoder_wrapper.inbasefilename, FLAC__stream_encoder_get_state(encoder_wrapper.encoder), FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder_wrapper.encoder)]);
1079                                         goto raw_abort_;
1080                                 }
1081                         }
1082                 }
1083                 else {
1084                         if(*options.common.align_reservoir_samples > 0) {
1085                                 FLAC__ASSERT(CHUNK_OF_SAMPLES >= 588);
1086                                 bytes_read = fread(ucbuffer, sizeof(unsigned char), (*options.common.align_reservoir_samples) * bytes_per_wide_sample, infile);
1087                                 if(bytes_read == 0 && ferror(infile)) {
1088                                         fprintf(stderr, "%s: ERROR during read\n", encoder_wrapper.inbasefilename);
1089                                         goto raw_abort_;
1090                                 }
1091                                 else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) {
1092                                         fprintf(stderr, "%s: WARNING: unexpected EOF; read %u bytes; expected %u samples, got %u samples\n", encoder_wrapper.inbasefilename, (unsigned)bytes_read, (unsigned)encoder_wrapper.total_samples_to_encode, (unsigned)encoder_wrapper.samples_written);
1093                                 }
1094                                 else {
1095                                         info_align_carry = *options.common.align_reservoir_samples;
1096                                         format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, false, options.is_unsigned_samples, options.channels, options.bps, &encoder_wrapper);
1097                                 }
1098                         }
1099                 }
1100         }
1101
1102         if(encoder_wrapper.encoder) {
1103                 FLAC__stream_encoder_finish(encoder_wrapper.encoder);
1104                 FLAC__stream_encoder_delete(encoder_wrapper.encoder);
1105 #ifdef FLAC__HAS_OGG
1106                 if(encoder_wrapper.use_ogg)
1107                         ogg_stream_clear(&encoder_wrapper.ogg.os);
1108 #endif
1109         }
1110         if(encoder_wrapper.verbose && encoder_wrapper.total_samples_to_encode > 0) {
1111                 print_stats(&encoder_wrapper);
1112                 fprintf(stderr, "\n");
1113         }
1114         if(0 != encoder_wrapper.seek_table.points)
1115                 free(encoder_wrapper.seek_table.points);
1116         if(options.common.verify) {
1117                 FLAC__stream_decoder_finish(encoder_wrapper.verify_fifo.decoder);
1118                 FLAC__stream_decoder_delete(encoder_wrapper.verify_fifo.decoder);
1119                 if(encoder_wrapper.verify_fifo.result != FLAC__VERIFY_OK) {
1120                         fprintf(stderr, "Verify FAILED! (%s)  Do not trust %s\n", verify_code_string[encoder_wrapper.verify_fifo.result], outfilename);
1121                         return 1;
1122                 }
1123         }
1124         if(info_align_carry >= 0)
1125                 fprintf(stderr, "%s: INFO: sector alignment causing %d samples to be carried over\n", encoder_wrapper.inbasefilename, info_align_carry);
1126         if(info_align_zero >= 0)
1127                 fprintf(stderr, "%s: INFO: sector alignment causing %d zero samples to be appended\n", encoder_wrapper.inbasefilename, info_align_zero);
1128         if(infile != stdin)
1129                 fclose(infile);
1130         return 0;
1131 raw_abort_:
1132         if(encoder_wrapper.verbose && encoder_wrapper.total_samples_to_encode > 0)
1133                 fprintf(stderr, "\n");
1134         if(encoder_wrapper.encoder) {
1135                 FLAC__stream_encoder_finish(encoder_wrapper.encoder);
1136                 FLAC__stream_encoder_delete(encoder_wrapper.encoder);
1137 #ifdef FLAC__HAS_OGG
1138                 if(encoder_wrapper.use_ogg)
1139                         ogg_stream_clear(&encoder_wrapper.ogg.os);
1140 #endif
1141         }
1142         if(0 != encoder_wrapper.seek_table.points)
1143                 free(encoder_wrapper.seek_table.points);
1144         if(options.common.verify) {
1145                 FLAC__stream_decoder_finish(encoder_wrapper.verify_fifo.decoder);
1146                 FLAC__stream_decoder_delete(encoder_wrapper.verify_fifo.decoder);
1147                 if(encoder_wrapper.verify_fifo.result != FLAC__VERIFY_OK) {
1148                         fprintf(stderr, "Verify FAILED! (%s)  Do not trust %s\n", verify_code_string[encoder_wrapper.verify_fifo.result], outfilename);
1149                         return 1;
1150                 }
1151         }
1152         if(infile != stdin)
1153                 fclose(infile);
1154         unlink(outfilename);
1155         return 1;
1156 }
1157
1158 FLAC__bool init(encoder_wrapper_struct *encoder_wrapper)
1159 {
1160         unsigned i;
1161         FLAC__uint32 test = 1;
1162
1163         is_big_endian_host = (*((FLAC__byte*)(&test)))? false : true;
1164
1165         for(i = 0; i < FLAC__MAX_CHANNELS; i++)
1166                 input[i] = &(in[i][0]);
1167
1168         encoder_wrapper->encoder = FLAC__stream_encoder_new();
1169         if(0 == encoder_wrapper->encoder) {
1170                 fprintf(stderr, "%s: ERROR creating the encoder instance\n", encoder_wrapper->inbasefilename);
1171                 return false;
1172         }
1173
1174 #ifdef FLAC__HAS_OGG
1175         if(encoder_wrapper->use_ogg) {
1176                 if(ogg_stream_init(&encoder_wrapper->ogg.os, 0) != 0) {
1177                         fprintf(stderr, "%s: ERROR initializing the Ogg stream\n", encoder_wrapper->inbasefilename);
1178                         FLAC__stream_encoder_delete(encoder_wrapper->encoder);
1179                         return false;
1180                 }
1181         }
1182 #endif
1183
1184         return true;
1185 }
1186
1187 FLAC__bool init_encoder(encode_options_t options, unsigned channels, unsigned bps, unsigned sample_rate, encoder_wrapper_struct *encoder_wrapper)
1188 {
1189         unsigned i, num_metadata;
1190         FLAC__StreamMetadata seek_table, padding;
1191         FLAC__StreamMetadata *metadata[2];
1192
1193         if(channels != 2)
1194                 options.do_mid_side = options.loose_mid_side = false;
1195
1196         if(encoder_wrapper->verify) {
1197                 /* set up the fifo which will hold the original signal to compare against */
1198                 encoder_wrapper->verify_fifo.size = options.blocksize + CHUNK_OF_SAMPLES;
1199                 for(i = 0; i < channels; i++) {
1200                         if(0 == (encoder_wrapper->verify_fifo.original[i] = (FLAC__int32*)malloc(sizeof(FLAC__int32) * encoder_wrapper->verify_fifo.size))) {
1201                                 fprintf(stderr, "%s: ERROR allocating verify buffers\n", encoder_wrapper->inbasefilename);
1202                                 return false;
1203                         }
1204                 }
1205                 encoder_wrapper->verify_fifo.tail = 0;
1206                 encoder_wrapper->verify_fifo.into_frames = false;
1207                 encoder_wrapper->verify_fifo.result = FLAC__VERIFY_OK;
1208
1209                 /* set up a stream decoder for verification */
1210                 encoder_wrapper->verify_fifo.decoder = FLAC__stream_decoder_new();
1211                 if(0 == encoder_wrapper->verify_fifo.decoder) {
1212                         fprintf(stderr, "%s: ERROR creating the verify decoder instance\n", encoder_wrapper->inbasefilename);
1213                         return false;
1214                 }
1215                 FLAC__stream_decoder_set_read_callback(encoder_wrapper->verify_fifo.decoder, verify_read_callback);
1216                 FLAC__stream_decoder_set_write_callback(encoder_wrapper->verify_fifo.decoder, verify_write_callback);
1217                 FLAC__stream_decoder_set_metadata_callback(encoder_wrapper->verify_fifo.decoder, verify_metadata_callback);
1218                 FLAC__stream_decoder_set_error_callback(encoder_wrapper->verify_fifo.decoder, verify_error_callback);
1219                 FLAC__stream_decoder_set_client_data(encoder_wrapper->verify_fifo.decoder, encoder_wrapper);
1220                 if(FLAC__stream_decoder_init(encoder_wrapper->verify_fifo.decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) {
1221                         fprintf(stderr, "%s: ERROR initializing decoder, state = %d:%s\n", encoder_wrapper->inbasefilename, FLAC__stream_decoder_get_state(encoder_wrapper->verify_fifo.decoder), FLAC__StreamDecoderStateString[FLAC__stream_decoder_get_state(encoder_wrapper->verify_fifo.decoder)]);
1222                         return false;
1223                 }
1224         }
1225
1226         if(!convert_to_seek_table(options.requested_seek_points, options.num_requested_seek_points, encoder_wrapper->total_samples_to_encode, options.blocksize, &encoder_wrapper->seek_table)) {
1227                 fprintf(stderr, "%s: ERROR allocating seek table\n", encoder_wrapper->inbasefilename);
1228                 return false;
1229         }
1230
1231         num_metadata = 0;
1232         if(encoder_wrapper->seek_table.num_points > 0) {
1233                 seek_table.is_last = false; /* the encoder will set this for us */
1234                 seek_table.type = FLAC__METADATA_TYPE_SEEKTABLE;
1235                 seek_table.length = encoder_wrapper->seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
1236                 seek_table.data.seek_table = encoder_wrapper->seek_table;
1237                 metadata[num_metadata++] = &seek_table;
1238         }
1239         if(options.padding > 0) {
1240                 padding.is_last = false; /* the encoder will set this for us */
1241                 padding.type = FLAC__METADATA_TYPE_PADDING;
1242                 padding.length = (unsigned)options.padding;
1243                 metadata[num_metadata++] = &padding;
1244         }
1245
1246         FLAC__stream_encoder_set_streamable_subset(encoder_wrapper->encoder, !options.lax);
1247         FLAC__stream_encoder_set_do_mid_side_stereo(encoder_wrapper->encoder, options.do_mid_side);
1248         FLAC__stream_encoder_set_loose_mid_side_stereo(encoder_wrapper->encoder, options.loose_mid_side);
1249         FLAC__stream_encoder_set_channels(encoder_wrapper->encoder, channels);
1250         FLAC__stream_encoder_set_bits_per_sample(encoder_wrapper->encoder, bps);
1251         FLAC__stream_encoder_set_sample_rate(encoder_wrapper->encoder, sample_rate);
1252         FLAC__stream_encoder_set_blocksize(encoder_wrapper->encoder, options.blocksize);
1253         FLAC__stream_encoder_set_max_lpc_order(encoder_wrapper->encoder, options.max_lpc_order);
1254         FLAC__stream_encoder_set_qlp_coeff_precision(encoder_wrapper->encoder, options.qlp_coeff_precision);
1255         FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder_wrapper->encoder, options.do_qlp_coeff_prec_search);
1256         FLAC__stream_encoder_set_do_escape_coding(encoder_wrapper->encoder, options.do_escape_coding);
1257         FLAC__stream_encoder_set_do_exhaustive_model_search(encoder_wrapper->encoder, options.do_exhaustive_model_search);
1258         FLAC__stream_encoder_set_min_residual_partition_order(encoder_wrapper->encoder, options.min_residual_partition_order);
1259         FLAC__stream_encoder_set_max_residual_partition_order(encoder_wrapper->encoder, options.max_residual_partition_order);
1260         FLAC__stream_encoder_set_rice_parameter_search_dist(encoder_wrapper->encoder, options.rice_parameter_search_dist);
1261         FLAC__stream_encoder_set_total_samples_estimate(encoder_wrapper->encoder, encoder_wrapper->total_samples_to_encode);
1262         FLAC__stream_encoder_set_metadata(encoder_wrapper->encoder, (num_metadata > 0)? metadata : 0, num_metadata);
1263         FLAC__stream_encoder_set_write_callback(encoder_wrapper->encoder, write_callback);
1264         FLAC__stream_encoder_set_metadata_callback(encoder_wrapper->encoder, metadata_callback);
1265         FLAC__stream_encoder_set_client_data(encoder_wrapper->encoder, encoder_wrapper);
1266
1267         if(FLAC__stream_encoder_init(encoder_wrapper->encoder) != FLAC__STREAM_ENCODER_OK) {
1268                 fprintf(stderr, "%s: ERROR initializing encoder, state = %d:%s\n", encoder_wrapper->inbasefilename, FLAC__stream_encoder_get_state(encoder_wrapper->encoder), FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder_wrapper->encoder)]);
1269                 return false;
1270         }
1271
1272         /* the above call writes all the metadata, so we save the stream offset now */
1273         encoder_wrapper->stream_offset = encoder_wrapper->bytes_written;
1274
1275         return true;
1276 }
1277
1278 FLAC__bool convert_to_seek_table(char *requested_seek_points, int num_requested_seek_points, FLAC__uint64 stream_samples, unsigned blocksize, FLAC__StreamMetadata_SeekTable *seek_table)
1279 {
1280         unsigned i, j, real_points, placeholders;
1281         char *pt = requested_seek_points, *q;
1282         FLAC__bool first;
1283
1284         seek_table->num_points = 0;
1285
1286         if(num_requested_seek_points == 0)
1287                 return true;
1288
1289         if(num_requested_seek_points < 0) {
1290                 strcpy(requested_seek_points, "100x<");
1291                 num_requested_seek_points = 1;
1292         }
1293
1294         /* first count how many individual seek points we may need */
1295         real_points = placeholders = 0;
1296         for(i = 0; i < (unsigned)num_requested_seek_points; i++) {
1297                 q = strchr(pt, '<');
1298                 FLAC__ASSERT(0 != q);
1299                 *q = '\0';
1300
1301                 if(0 == strcmp(pt, "X")) { /* -S X */
1302                         placeholders++;
1303                 }
1304                 else if(pt[strlen(pt)-1] == 'x') { /* -S #x */
1305                         if(stream_samples > 0) /* we can only do these if we know the number of samples to encode up front */
1306                                 real_points += (unsigned)atoi(pt);
1307                 }
1308                 else { /* -S # */
1309                         real_points++;
1310                 }
1311                 *q++ = '<';
1312
1313                 pt = q;
1314         }
1315         pt = requested_seek_points;
1316
1317         /* make some space */
1318         if(0 == (seek_table->points = (FLAC__StreamMetadata_SeekPoint*)malloc(sizeof(FLAC__StreamMetadata_SeekPoint) * (real_points+placeholders))))
1319                 return false;
1320
1321         /* initialize the seek_table.  we set frame_samples to zero to signify the points have not yet been hit by a frame write yet. */
1322         for(i = 0; i < real_points+placeholders; i++) {
1323                 seek_table->points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
1324                 seek_table->points[i].stream_offset = 0;
1325                 seek_table->points[i].frame_samples = 0;
1326         }
1327
1328         for(i = 0; i < (unsigned)num_requested_seek_points; i++) {
1329                 q = strchr(pt, '<');
1330                 FLAC__ASSERT(0 != q);
1331                 *q++ = '\0';
1332
1333                 if(0 == strcmp(pt, "X")) { /* -S X */
1334                         ; /* we append placeholders later */
1335                 }
1336                 else if(pt[strlen(pt)-1] == 'x') { /* -S #x */
1337                         if(stream_samples > 0) { /* we can only do these if we know the number of samples to encode up front */
1338                                 unsigned j, n;
1339                                 n = (unsigned)atoi(pt);
1340                                 for(j = 0; j < n; j++)
1341                                         append_point_to_seek_table(seek_table, stream_samples * (FLAC__uint64)j / (FLAC__uint64)n, stream_samples, blocksize);
1342                         }
1343                 }
1344                 else { /* -S # */
1345                         append_point_to_seek_table(seek_table, (FLAC__uint64)atoi(pt), stream_samples, blocksize);
1346                 }
1347
1348                 pt = q;
1349         }
1350
1351         /* sort the seekpoints */
1352         qsort(seek_table->points, seek_table->num_points, sizeof(FLAC__StreamMetadata_SeekPoint), (int (*)(const void *, const void *))seekpoint_compare);
1353
1354         /* uniquify the seekpoints */
1355         first = true;
1356         for(i = j = 0; i < seek_table->num_points; i++) {
1357                 if(!first) {
1358                         if(seek_table->points[i].sample_number == seek_table->points[j-1].sample_number)
1359                                 continue;
1360                 }
1361                 first = false;
1362                 seek_table->points[j++] = seek_table->points[i];
1363         }
1364         seek_table->num_points = j;
1365
1366         /* append placeholders */
1367         for(i = 0, j = seek_table->num_points; i < placeholders; i++, j++)
1368                 seek_table->points[j].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
1369         seek_table->num_points += placeholders;
1370
1371         return true;
1372 }
1373
1374 void append_point_to_seek_table(FLAC__StreamMetadata_SeekTable *seek_table, FLAC__uint64 sample, FLAC__uint64 stream_samples, FLAC__uint64 blocksize)
1375 {
1376         const FLAC__uint64 target_sample = (sample / blocksize) * blocksize;
1377
1378         if(stream_samples == 0 || target_sample < stream_samples)
1379                 seek_table->points[seek_table->num_points++].sample_number = target_sample;
1380 }
1381
1382 int seekpoint_compare(const FLAC__StreamMetadata_SeekPoint *l, const FLAC__StreamMetadata_SeekPoint *r)
1383 {
1384         /* we don't just 'return l->sample_number - r->sample_number' since the result (FLAC__int64) might overflow an 'int' */
1385         if(l->sample_number == r->sample_number)
1386                 return 0;
1387         else if(l->sample_number < r->sample_number)
1388                 return -1;
1389         else
1390                 return 1;
1391 }
1392
1393 void format_input(FLAC__int32 *dest[], unsigned wide_samples, FLAC__bool is_big_endian, FLAC__bool is_unsigned_samples, unsigned channels, unsigned bps, encoder_wrapper_struct *encoder_wrapper)
1394 {
1395         unsigned wide_sample, sample, channel, byte;
1396
1397         if(bps == 8) {
1398                 if(is_unsigned_samples) {
1399                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1400                                 for(channel = 0; channel < channels; channel++, sample++)
1401                                         dest[channel][wide_sample] = (FLAC__int32)ucbuffer[sample] - 0x80;
1402                 }
1403                 else {
1404                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1405                                 for(channel = 0; channel < channels; channel++, sample++)
1406                                         dest[channel][wide_sample] = (FLAC__int32)scbuffer[sample];
1407                 }
1408         }
1409         else if(bps == 16) {
1410                 if(is_big_endian != is_big_endian_host) {
1411                         unsigned char tmp;
1412                         const unsigned bytes = wide_samples * channels * (bps >> 3);
1413                         for(byte = 0; byte < bytes; byte += 2) {
1414                                 tmp = ucbuffer[byte];
1415                                 ucbuffer[byte] = ucbuffer[byte+1];
1416                                 ucbuffer[byte+1] = tmp;
1417                         }
1418                 }
1419                 if(is_unsigned_samples) {
1420                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1421                                 for(channel = 0; channel < channels; channel++, sample++)
1422                                         dest[channel][wide_sample] = (FLAC__int32)usbuffer[sample] - 0x8000;
1423                 }
1424                 else {
1425                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1426                                 for(channel = 0; channel < channels; channel++, sample++)
1427                                         dest[channel][wide_sample] = (FLAC__int32)ssbuffer[sample];
1428                 }
1429         }
1430         else if(bps == 24) {
1431                 if(!is_big_endian) {
1432                         unsigned char tmp;
1433                         const unsigned bytes = wide_samples * channels * (bps >> 3);
1434                         for(byte = 0; byte < bytes; byte += 3) {
1435                                 tmp = ucbuffer[byte];
1436                                 ucbuffer[byte] = ucbuffer[byte+2];
1437                                 ucbuffer[byte+2] = tmp;
1438                         }
1439                 }
1440                 if(is_unsigned_samples) {
1441                         for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1442                                 for(channel = 0; channel < channels; channel++, sample++) {
1443                                         dest[channel][wide_sample]  = ucbuffer[byte++]; dest[channel][wide_sample] <<= 8;
1444                                         dest[channel][wide_sample] |= ucbuffer[byte++]; dest[channel][wide_sample] <<= 8;
1445                                         dest[channel][wide_sample] |= ucbuffer[byte++];
1446                                         dest[channel][wide_sample] -= 0x800000;
1447                                 }
1448                 }
1449                 else {
1450                         for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1451                                 for(channel = 0; channel < channels; channel++, sample++) {
1452                                         dest[channel][wide_sample]  = scbuffer[byte++]; dest[channel][wide_sample] <<= 8;
1453                                         dest[channel][wide_sample] |= ucbuffer[byte++]; dest[channel][wide_sample] <<= 8;
1454                                         dest[channel][wide_sample] |= ucbuffer[byte++];
1455                                 }
1456                 }
1457         }
1458         else {
1459                 FLAC__ASSERT(0);
1460         }
1461
1462         append_to_verify_fifo(encoder_wrapper, (const FLAC__int32 * const *)dest, channels, wide_samples);
1463 }
1464
1465 void append_to_verify_fifo(encoder_wrapper_struct *encoder_wrapper, const FLAC__int32 * const input[], unsigned channels, unsigned wide_samples)
1466 {
1467         if(encoder_wrapper->verify) {
1468                 unsigned channel;
1469                 for(channel = 0; channel < channels; channel++)
1470                         memcpy(&encoder_wrapper->verify_fifo.original[channel][encoder_wrapper->verify_fifo.tail], input[channel], sizeof(FLAC__int32) * wide_samples);
1471                 encoder_wrapper->verify_fifo.tail += wide_samples;
1472                 FLAC__ASSERT(encoder_wrapper->verify_fifo.tail <= encoder_wrapper->verify_fifo.size);
1473         }
1474 }
1475
1476 FLAC__StreamEncoderWriteStatus write_callback(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
1477 {
1478         encoder_wrapper_struct *encoder_wrapper = (encoder_wrapper_struct *)client_data;
1479         const unsigned mask = (FLAC__stream_encoder_get_do_exhaustive_model_search(encoder) || FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder))? 0x1f : 0x7f;
1480
1481         /* mark the current seek point if hit (if stream_offset == 0 that means we're still writing metadata and haven't hit the first frame yet) */
1482         if(encoder_wrapper->stream_offset > 0 && encoder_wrapper->seek_table.num_points > 0) {
1483                 FLAC__uint64 current_sample = (FLAC__uint64)current_frame * (FLAC__uint64)FLAC__stream_encoder_get_blocksize(encoder), test_sample;
1484                 unsigned i;
1485                 for(i = encoder_wrapper->first_seek_point_to_check; i < encoder_wrapper->seek_table.num_points; i++) {
1486                         test_sample = encoder_wrapper->seek_table.points[i].sample_number;
1487                         if(test_sample > current_sample) {
1488                                 break;
1489                         }
1490                         else if(test_sample == current_sample) {
1491                                 encoder_wrapper->seek_table.points[i].stream_offset = encoder_wrapper->bytes_written - encoder_wrapper->stream_offset;
1492                                 encoder_wrapper->seek_table.points[i].frame_samples = FLAC__stream_encoder_get_blocksize(encoder);
1493                                 encoder_wrapper->first_seek_point_to_check++;
1494                                 break;
1495                         }
1496                         else {
1497                                 encoder_wrapper->first_seek_point_to_check++;
1498                         }
1499                 }
1500         }
1501
1502         encoder_wrapper->bytes_written += bytes;
1503         encoder_wrapper->samples_written += samples;
1504         encoder_wrapper->current_frame = current_frame;
1505
1506         if(samples && encoder_wrapper->verbose && encoder_wrapper->total_samples_to_encode > 0 && !(current_frame & mask))
1507                 print_stats(encoder_wrapper);
1508
1509         if(encoder_wrapper->verify) {
1510                 encoder_wrapper->verify_fifo.encoded_signal = buffer;
1511                 encoder_wrapper->verify_fifo.encoded_bytes = bytes;
1512                 if(encoder_wrapper->verify_fifo.into_frames) {
1513                         if(!FLAC__stream_decoder_process_one_frame(encoder_wrapper->verify_fifo.decoder)) {
1514                                 encoder_wrapper->verify_fifo.result = FLAC__VERIFY_FAILED_IN_FRAME;
1515                                 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
1516                         }
1517                 }
1518                 else {
1519                         if(!FLAC__stream_decoder_process_metadata(encoder_wrapper->verify_fifo.decoder)) {
1520                                 encoder_wrapper->verify_fifo.result = FLAC__VERIFY_FAILED_IN_METADATA;
1521                                 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
1522                         }
1523                 }
1524         }
1525
1526 #ifdef FLAC__HAS_OGG
1527         if(encoder_wrapper->use_ogg) {
1528                 ogg_packet op;
1529
1530                 memset(&op, 0, sizeof(op));
1531                 op.packet = (unsigned char *)buffer;
1532                 op.granulepos = encoder_wrapper->samples_written - 1;
1533                 /*@@@ WATCHOUT:
1534                  * this depends on the behavior of libFLAC that we will get one
1535                  * write_callback first with all the metadata (and 'samples'
1536                  * will be 0), then one write_callback for each frame.
1537                  */
1538                 op.packetno = (samples == 0? -1 : (int)encoder_wrapper->current_frame);
1539                 op.bytes = bytes;
1540
1541                 if (encoder_wrapper->bytes_written == bytes)
1542                         op.b_o_s = 1;
1543
1544                 if (encoder_wrapper->total_samples_to_encode == encoder_wrapper->samples_written)
1545                         op.e_o_s = 1;
1546
1547                 ogg_stream_packetin(&encoder_wrapper->ogg.os, &op);
1548
1549                 while(ogg_stream_pageout(&encoder_wrapper->ogg.os, &encoder_wrapper->ogg.og) != 0) {
1550                         int written;
1551                         written = fwrite(encoder_wrapper->ogg.og.header, 1, encoder_wrapper->ogg.og.header_len, encoder_wrapper->fout);
1552                         if (written != encoder_wrapper->ogg.og.header_len)
1553                                 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
1554
1555                         written = fwrite(encoder_wrapper->ogg.og.body, 1, encoder_wrapper->ogg.og.body_len, encoder_wrapper->fout);
1556                         if (written != encoder_wrapper->ogg.og.body_len)
1557                                 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
1558                 }
1559
1560                 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
1561         }
1562         else
1563 #endif
1564         {
1565                 if(fwrite(buffer, sizeof(FLAC__byte), bytes, encoder_wrapper->fout) == bytes)
1566                         return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
1567                 else
1568                         return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
1569         }
1570 }
1571
1572 void metadata_callback(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data)
1573 {
1574         encoder_wrapper_struct *encoder_wrapper = (encoder_wrapper_struct *)client_data;
1575         FLAC__byte b;
1576         FILE *f = encoder_wrapper->fout;
1577         const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
1578         const unsigned min_framesize = metadata->data.stream_info.min_framesize;
1579         const unsigned max_framesize = metadata->data.stream_info.max_framesize;
1580
1581         FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
1582
1583         /*
1584          * If we are writing to an ogg stream, there is no need to go back
1585          * and update the STREAMINFO or SEEKTABLE blocks; the values we would
1586          * update are not necessary with Ogg as the transport.  We can't do
1587          * it reliably anyway without knowing the Ogg structure.
1588          */
1589 #ifdef FLAC__HAS_OGG
1590         if(encoder_wrapper->use_ogg)
1591                 return;
1592 #endif
1593
1594         /*
1595          * we get called by the encoder when the encoding process has
1596          * finished so that we can update the STREAMINFO and SEEKTABLE
1597          * blocks.
1598          */
1599
1600         (void)encoder; /* silence compiler warning about unused parameter */
1601
1602         if(f != stdout) {
1603                 fclose(encoder_wrapper->fout);
1604                 if(0 == (f = fopen(encoder_wrapper->outfilename, "r+b")))
1605                         return;
1606         }
1607
1608         /* all this is based on intimate knowledge of the stream header
1609          * layout, but a change to the header format that would break this
1610          * would also break all streams encoded in the previous format.
1611          */
1612
1613         if(-1 == fseek(f, 26, SEEK_SET)) goto end_;
1614         fwrite(metadata->data.stream_info.md5sum, 1, 16, f);
1615
1616         /* if we get this far we know we can seek so no need to check the
1617          * return value from fseek()
1618          */
1619         fseek(f, 21, SEEK_SET);
1620         if(fread(&b, 1, 1, f) != 1) goto framesize_;
1621         fseek(f, 21, SEEK_SET);
1622         b = (b & 0xf0) | (FLAC__byte)((samples >> 32) & 0x0F);
1623         if(fwrite(&b, 1, 1, f) != 1) goto framesize_;
1624         b = (FLAC__byte)((samples >> 24) & 0xFF);
1625         if(fwrite(&b, 1, 1, f) != 1) goto framesize_;
1626         b = (FLAC__byte)((samples >> 16) & 0xFF);
1627         if(fwrite(&b, 1, 1, f) != 1) goto framesize_;
1628         b = (FLAC__byte)((samples >> 8) & 0xFF);
1629         if(fwrite(&b, 1, 1, f) != 1) goto framesize_;
1630         b = (FLAC__byte)(samples & 0xFF);
1631         if(fwrite(&b, 1, 1, f) != 1) goto framesize_;
1632
1633 framesize_:
1634         fseek(f, 12, SEEK_SET);
1635         b = (FLAC__byte)((min_framesize >> 16) & 0xFF);
1636         if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
1637         b = (FLAC__byte)((min_framesize >> 8) & 0xFF);
1638         if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
1639         b = (FLAC__byte)(min_framesize & 0xFF);
1640         if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
1641         b = (FLAC__byte)((max_framesize >> 16) & 0xFF);
1642         if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
1643         b = (FLAC__byte)((max_framesize >> 8) & 0xFF);
1644         if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
1645         b = (FLAC__byte)(max_framesize & 0xFF);
1646         if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
1647
1648 seektable_:
1649         if(encoder_wrapper->seek_table.num_points > 0) {
1650                 long pos;
1651                 unsigned i;
1652
1653                 /* convert any unused seek points to placeholders */
1654                 for(i = 0; i < encoder_wrapper->seek_table.num_points; i++) {
1655                         if(encoder_wrapper->seek_table.points[i].sample_number == FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER)
1656                                 break;
1657                         else if(encoder_wrapper->seek_table.points[i].frame_samples == 0)
1658                                 encoder_wrapper->seek_table.points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
1659                 }
1660
1661                 /* the offset of the seek table data 'pos' should be after then stream sync and STREAMINFO block and SEEKTABLE header */
1662                 pos = (FLAC__STREAM_SYNC_LEN + FLAC__STREAM_METADATA_IS_LAST_LEN + FLAC__STREAM_METADATA_TYPE_LEN + FLAC__STREAM_METADATA_LENGTH_LEN) / 8;
1663                 pos += metadata->length;
1664                 pos += (FLAC__STREAM_METADATA_IS_LAST_LEN + FLAC__STREAM_METADATA_TYPE_LEN + FLAC__STREAM_METADATA_LENGTH_LEN) / 8;
1665                 fseek(f, pos, SEEK_SET);
1666                 for(i = 0; i < encoder_wrapper->seek_table.num_points; i++) {
1667                         if(!write_big_endian_uint64(f, encoder_wrapper->seek_table.points[i].sample_number)) goto end_;
1668                         if(!write_big_endian_uint64(f, encoder_wrapper->seek_table.points[i].stream_offset)) goto end_;
1669                         if(!write_big_endian_uint16(f, (FLAC__uint16)encoder_wrapper->seek_table.points[i].frame_samples)) goto end_;
1670                 }
1671         }
1672
1673 end_:
1674         fclose(f);
1675         return;
1676 }
1677
1678 FLAC__StreamDecoderReadStatus verify_read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
1679 {
1680         encoder_wrapper_struct *encoder_wrapper = (encoder_wrapper_struct *)client_data;
1681         const unsigned encoded_bytes = encoder_wrapper->verify_fifo.encoded_bytes;
1682         (void)decoder;
1683
1684         if(encoded_bytes <= *bytes) {
1685                 *bytes = encoded_bytes;
1686                 memcpy(buffer, encoder_wrapper->verify_fifo.encoded_signal, *bytes);
1687         }
1688         else {
1689                 memcpy(buffer, encoder_wrapper->verify_fifo.encoded_signal, *bytes);
1690                 encoder_wrapper->verify_fifo.encoded_signal += *bytes;
1691                 encoder_wrapper->verify_fifo.encoded_bytes -= *bytes;
1692         }
1693
1694         return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
1695 }
1696
1697 FLAC__StreamDecoderWriteStatus verify_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
1698 {
1699         encoder_wrapper_struct *encoder_wrapper = (encoder_wrapper_struct *)client_data;
1700         unsigned channel, l, r;
1701         const unsigned channels = FLAC__stream_decoder_get_channels(decoder);
1702         const unsigned bytes_per_block = sizeof(FLAC__int32) * FLAC__stream_decoder_get_blocksize(decoder);
1703
1704         for(channel = 0; channel < channels; channel++) {
1705                 if(0 != memcmp(buffer[channel], encoder_wrapper->verify_fifo.original[channel], bytes_per_block)) {
1706                         unsigned sample = 0;
1707                         int expect = 0, got = 0;
1708                         fprintf(stderr, "\n%s: ERROR: mismatch in decoded data, verify FAILED!\n", encoder_wrapper->inbasefilename);
1709                         fprintf(stderr, "       Please submit a bug report to\n");
1710                         fprintf(stderr, "           http://sourceforge.net/bugs/?func=addbug&group_id=13478\n");
1711                         fprintf(stderr, "       Make sure to include an email contact in the comment and/or use the\n");
1712                         fprintf(stderr, "       \"Monitor\" feature to monitor the bug status.\n");
1713                         for(l = 0, r = FLAC__stream_decoder_get_blocksize(decoder); l < r; l++) {
1714                                 if(buffer[channel][l] != encoder_wrapper->verify_fifo.original[channel][l]) {
1715                                         sample = l;
1716                                         expect = (int)encoder_wrapper->verify_fifo.original[channel][l];
1717                                         got = (int)buffer[channel][l];
1718                                         break;
1719                                 }
1720                         }
1721                         FLAC__ASSERT(l < r);
1722                         FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
1723                         fprintf(stderr, "       Absolute sample=%u, frame=%u, channel=%u, sample=%u, expected %d, got %d\n", (unsigned)frame->header.number.sample_number + sample, (unsigned)frame->header.number.sample_number / FLAC__stream_decoder_get_blocksize(decoder), channel, sample, expect, got); /*@@@ WATCHOUT: 4GB limit */
1724                         return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
1725                 }
1726         }
1727         /* dequeue the frame from the fifo */
1728         for(channel = 0; channel < channels; channel++) {
1729                 for(l = 0, r = frame->header.blocksize; r < encoder_wrapper->verify_fifo.tail; l++, r++) {
1730                         encoder_wrapper->verify_fifo.original[channel][l] = encoder_wrapper->verify_fifo.original[channel][r];
1731                 }
1732         }
1733         encoder_wrapper->verify_fifo.tail -= frame->header.blocksize;
1734         return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
1735 }
1736
1737 void verify_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
1738 {
1739         (void)decoder;
1740         (void)metadata;
1741         (void)client_data;
1742 }
1743
1744 void verify_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
1745 {
1746         encoder_wrapper_struct *encoder_wrapper = (encoder_wrapper_struct *)client_data;
1747         (void)decoder;
1748         fprintf(stderr, "\n%s: ERROR: verification decoder returned error %d:%s\n", encoder_wrapper->inbasefilename, status, FLAC__StreamDecoderErrorStatusString[status]);
1749 }
1750
1751 void print_stats(const encoder_wrapper_struct *encoder_wrapper)
1752 {
1753 #if defined _MSC_VER || defined __MINGW32__
1754         /* with VC++ you have to spoon feed it the casting */
1755         const double progress = (double)(FLAC__int64)encoder_wrapper->samples_written / (double)(FLAC__int64)encoder_wrapper->total_samples_to_encode;
1756         const double ratio = (double)(FLAC__int64)encoder_wrapper->bytes_written / ((double)(FLAC__int64)encoder_wrapper->unencoded_size * progress);
1757 #else
1758         const double progress = (double)encoder_wrapper->samples_written / (double)encoder_wrapper->total_samples_to_encode;
1759         const double ratio = (double)encoder_wrapper->bytes_written / ((double)encoder_wrapper->unencoded_size * progress);
1760 #endif
1761
1762         if(encoder_wrapper->samples_written == encoder_wrapper->total_samples_to_encode) {
1763                 fprintf(stderr, "\r%s:%s wrote %u bytes, ratio=%0.3f",
1764                         encoder_wrapper->inbasefilename,
1765                         encoder_wrapper->verify? (encoder_wrapper->verify_fifo.result == FLAC__VERIFY_OK? " Verify OK," : " Verify FAILED!") : "",
1766                         (unsigned)encoder_wrapper->bytes_written,
1767                         ratio
1768                 );
1769         }
1770         else {
1771                 fprintf(stderr, "\r%s: %u%% complete, ratio=%0.3f", encoder_wrapper->inbasefilename, (unsigned)floor(progress * 100.0 + 0.5), ratio);
1772         }
1773 }
1774
1775 FLAC__bool read_little_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn)
1776 {
1777         size_t bytes_read = fread(val, 1, 2, f);
1778
1779         if(bytes_read == 0) {
1780                 if(!eof_ok) {
1781                         fprintf(stderr, "%s: ERROR: unexpected EOF\n", fn);
1782                         return false;
1783                 }
1784                 else
1785                         return true;
1786         }
1787         else if(bytes_read < 2) {
1788                 fprintf(stderr, "%s: ERROR: unexpected EOF\n", fn);
1789                 return false;
1790         }
1791         else {
1792                 if(is_big_endian_host) {
1793                         FLAC__byte tmp, *b = (FLAC__byte*)val;
1794                         tmp = b[1]; b[1] = b[0]; b[0] = tmp;
1795                 }
1796                 return true;
1797         }
1798 }
1799
1800 FLAC__bool read_little_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
1801 {
1802         size_t bytes_read = fread(val, 1, 4, f);
1803
1804         if(bytes_read == 0) {
1805                 if(!eof_ok) {
1806                         fprintf(stderr, "%s: ERROR: unexpected EOF\n", fn);
1807                         return false;
1808                 }
1809                 else
1810                         return true;
1811         }
1812         else if(bytes_read < 4) {
1813                 fprintf(stderr, "%s: ERROR: unexpected EOF\n", fn);
1814                 return false;
1815         }
1816         else {
1817                 if(is_big_endian_host) {
1818                         FLAC__byte tmp, *b = (FLAC__byte*)val;
1819                         tmp = b[3]; b[3] = b[0]; b[0] = tmp;
1820                         tmp = b[2]; b[2] = b[1]; b[1] = tmp;
1821                 }
1822                 return true;
1823         }
1824 }
1825
1826 FLAC__bool
1827 read_big_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn)
1828 {
1829         unsigned char buf[4];
1830         size_t bytes_read= fread(buf, 1, 2, f);
1831
1832         if(bytes_read==0U && eof_ok)
1833                 return true;
1834         else if(bytes_read<2U) {
1835                 fprintf(stderr, "%s: ERROR: unexpected EOF\n", fn);
1836                 return false;
1837         }
1838
1839         /* this is independent of host endianness */
1840         *val= (FLAC__uint16)(buf[0])<<8 | buf[1];
1841
1842         return true;
1843 }
1844
1845 FLAC__bool
1846 read_big_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
1847 {
1848         unsigned char buf[4];
1849         size_t bytes_read= fread(buf, 1, 4, f);
1850
1851         if(bytes_read==0U && eof_ok)
1852                 return true;
1853         else if(bytes_read<4U) {
1854                 fprintf(stderr, "%s: ERROR: unexpected EOF\n", fn);
1855                 return false;
1856         }
1857
1858         /* this is independent of host endianness */
1859         *val= (FLAC__uint32)(buf[0])<<24 | (FLAC__uint32)(buf[1])<<16 |
1860                 (FLAC__uint32)(buf[2])<<8 | buf[3];
1861
1862         return true;
1863 }
1864
1865 FLAC__bool
1866 read_sane_extended(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
1867         /* Read an IEEE 754 80-bit (aka SANE) extended floating point value from 'f',
1868          * convert it into an integral value and store in 'val'.  Return false if only
1869          * between 1 and 9 bytes remain in 'f', if 0 bytes remain in 'f' and 'eof_ok' is
1870          * false, or if the value is negative, between zero and one, or too large to be
1871          * represented by 'val'; return true otherwise.
1872          */
1873 {
1874         unsigned int i;
1875         unsigned char buf[10];
1876         size_t bytes_read= fread(buf, 1U, 10U, f);
1877         FLAC__int16 e= ((FLAC__uint16)(buf[0])<<8 | (FLAC__uint16)(buf[1]))-0x3FFF;
1878         FLAC__int16 shift= 63-e;
1879         FLAC__uint64 p= 0U;
1880
1881         if(bytes_read==0U && eof_ok)
1882                 return true;
1883         else if(bytes_read<10U) {
1884                 fprintf(stderr, "%s: ERROR: unexpected EOF\n", fn);
1885                 return false;
1886         }
1887         else if((buf[0]>>7)==1U || e<0 || e>63) {
1888                 fprintf(stderr, "%s: ERROR: invalid floating-point value\n", fn);
1889                 return false;
1890         }
1891
1892         for(i= 0U; i<8U; ++i)
1893                 p|= (FLAC__uint64)(buf[i+2])<<(56U-i*8);
1894         *val= (FLAC__uint32)(p>>shift)+(p>>(shift-1) & 0x1);
1895
1896         return true;
1897 }
1898
1899 FLAC__bool write_big_endian_uint16(FILE *f, FLAC__uint16 val)
1900 {
1901         if(!is_big_endian_host) {
1902                 FLAC__byte *b = (FLAC__byte *)&val, tmp;
1903                 tmp = b[0]; b[0] = b[1]; b[1] = tmp;
1904         }
1905         return fwrite(&val, 1, 2, f) == 2;
1906 }
1907
1908 FLAC__bool write_big_endian_uint64(FILE *f, FLAC__uint64 val)
1909 {
1910         if(!is_big_endian_host) {
1911                 FLAC__byte *b = (FLAC__byte *)&val, tmp;
1912                 tmp = b[0]; b[0] = b[7]; b[7] = tmp;
1913                 tmp = b[1]; b[1] = b[6]; b[6] = tmp;
1914                 tmp = b[2]; b[2] = b[5]; b[5] = tmp;
1915                 tmp = b[3]; b[3] = b[4]; b[4] = tmp;
1916         }
1917         return fwrite(&val, 1, 8, f) == 8;
1918 }