fix endian bug when applying replaygain
[platform/upstream/flac.git] / src / flac / decode.c
1 /* flac - Command-line FLAC encoder/decoder
2  * Copyright (C) 2000,2001,2002,2003  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 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #if defined _WIN32 && !defined __CYGWIN__
24 /* where MSVC puts unlink() */
25 # include <io.h>
26 #else
27 # include <unistd.h>
28 #endif
29 #include <math.h> /* for floor() */
30 #include <stdio.h> /* for FILE et al. */
31 #include <string.h> /* for strcmp() */
32 #include "FLAC/all.h"
33 #include "share/grabbag.h"
34 #include "share/replaygain_synthesis.h"
35 #include "decode.h"
36
37 #ifdef FLAC__HAS_OGG
38 #include "OggFLAC/stream_decoder.h"
39 #endif
40
41 typedef struct {
42 #ifdef FLAC__HAS_OGG
43         FLAC__bool is_ogg;
44 #endif
45
46         FLAC__bool verbose;
47         FLAC__bool is_aiff_out;
48         FLAC__bool is_wave_out;
49         FLAC__bool continue_through_decode_errors;
50
51         struct {
52                 replaygain_synthesis_spec_t spec;
53                 FLAC__bool apply; /* 'spec.apply' is just a request; this 'apply' means we actually parsed the RG tags and are ready to go */
54                 double scale;
55                 DitherContext dither_context;
56         } replaygain;
57
58         FLAC__bool test_only;
59         FLAC__bool analysis_mode;
60         analysis_options aopts;
61         utils__SkipUntilSpecification *skip_specification;
62         utils__SkipUntilSpecification *until_specification; /* a canonicalized value of 0 mean end-of-stream (i.e. --until=-0) */
63
64         const char *inbasefilename;
65         const char *outfilename;
66
67         FLAC__uint64 samples_processed;
68         unsigned frame_counter;
69         FLAC__bool abort_flag;
70
71         struct {
72                 FLAC__bool needs_fixup;
73                 unsigned riff_offset; /* or FORM offset for AIFF */
74                 unsigned data_offset; /* or SSND offset for AIFF */
75                 unsigned frames_offset; /* AIFF only */
76         } wave_chunk_size_fixup;
77
78         FLAC__bool is_big_endian;
79         FLAC__bool is_unsigned_samples;
80         FLAC__uint64 total_samples;
81         unsigned bps;
82         unsigned channels;
83         unsigned sample_rate;
84
85         union {
86                 union {
87                         FLAC__FileDecoder *file;
88                 } flac;
89 #ifdef FLAC__HAS_OGG
90                 union {
91                         OggFLAC__StreamDecoder *stream;
92                 } ogg;
93 #endif
94         } decoder;
95
96 #ifdef FLAC__HAS_OGG
97         FILE *fin;
98 #endif
99         FILE *fout;
100 } DecoderSession;
101
102
103 static FLAC__bool is_big_endian_host_;
104
105
106 /*
107  * local routines
108  */
109 static FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__bool verbose, FLAC__bool is_aiff_out, FLAC__bool is_wave_out, FLAC__bool continue_through_decode_errors, replaygain_synthesis_spec_t replaygain_synthesis_spec, FLAC__bool analysis_mode, analysis_options aopts, utils__SkipUntilSpecification *skip_specification, utils__SkipUntilSpecification *until_specification, const char *infilename, const char *outfilename);
110 static void DecoderSession_destroy(DecoderSession *d, FLAC__bool error_occurred);
111 static FLAC__bool DecoderSession_init_decoder(DecoderSession *d, decode_options_t decode_options, const char *infilename);
112 static FLAC__bool DecoderSession_process(DecoderSession *d);
113 static int DecoderSession_finish_ok(DecoderSession *d);
114 static int DecoderSession_finish_error(DecoderSession *d);
115 static FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input);
116 static FLAC__bool write_little_endian_uint16(FILE *f, FLAC__uint16 val);
117 static FLAC__bool write_little_endian_uint32(FILE *f, FLAC__uint32 val);
118 static FLAC__bool write_big_endian_uint16(FILE *f, FLAC__uint16 val);
119 static FLAC__bool write_big_endian_uint32(FILE *f, FLAC__uint32 val);
120 static FLAC__bool write_sane_extended(FILE *f, unsigned val);
121 static FLAC__bool fixup_wave_chunk_size(const char *outfilename, FLAC__bool is_wave_out, unsigned riff_offset, unsigned data_offset, unsigned frames_offset, FLAC__uint32 total_samples, unsigned channels, unsigned bps);
122 #ifdef FLAC__HAS_OGG
123 static FLAC__StreamDecoderReadStatus read_callback(const OggFLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
124 #endif
125 /*
126  * We use 'void *' so that we can use the same callbacks for the
127  * FLAC__StreamDecoder and FLAC__FileDecoder.  The 'decoder' argument is
128  * actually never used in the callbacks.
129  */
130 static FLAC__StreamDecoderWriteStatus write_callback(const void *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
131 static void metadata_callback(const void *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
132 static void error_callback(const void *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
133 static void print_error_with_state(const DecoderSession *d, const char *message);
134 static void print_stats(const DecoderSession *decoder_session);
135
136
137 /*
138  * public routines
139  */
140 int flac__decode_aiff(const char *infilename, const char *outfilename, FLAC__bool analysis_mode, analysis_options aopts, wav_decode_options_t options)
141 {
142         DecoderSession decoder_session;
143
144         if(!
145                 DecoderSession_construct(
146                         &decoder_session,
147 #ifdef FLAC__HAS_OGG
148                         options.common.is_ogg,
149 #else
150                         /*is_ogg=*/false,
151 #endif
152                         options.common.verbose,
153                         /*is_aiff_out=*/true,
154                         /*is_wave_out=*/false,
155                         options.common.continue_through_decode_errors,
156                         options.common.replaygain_synthesis_spec,
157                         analysis_mode,
158                         aopts,
159                         &options.common.skip_specification,
160                         &options.common.until_specification,
161                         infilename,
162                         outfilename
163                 )
164         )
165                 return 1;
166
167         if(!DecoderSession_init_decoder(&decoder_session, options.common, infilename))
168                 return DecoderSession_finish_error(&decoder_session);
169
170         if(!DecoderSession_process(&decoder_session))
171                 return DecoderSession_finish_error(&decoder_session);
172
173         return DecoderSession_finish_ok(&decoder_session);
174 }
175
176 int flac__decode_wav(const char *infilename, const char *outfilename, FLAC__bool analysis_mode, analysis_options aopts, wav_decode_options_t options)
177 {
178         DecoderSession decoder_session;
179
180         if(!
181                 DecoderSession_construct(
182                         &decoder_session,
183 #ifdef FLAC__HAS_OGG
184                         options.common.is_ogg,
185 #else
186                         /*is_ogg=*/false,
187 #endif
188                         options.common.verbose,
189                         /*is_aiff_out=*/false,
190                         /*is_wave_out=*/true,
191                         options.common.continue_through_decode_errors,
192                         options.common.replaygain_synthesis_spec,
193                         analysis_mode,
194                         aopts,
195                         &options.common.skip_specification,
196                         &options.common.until_specification,
197                         infilename,
198                         outfilename
199                 )
200         )
201                 return 1;
202
203         if(!DecoderSession_init_decoder(&decoder_session, options.common, infilename))
204                 return DecoderSession_finish_error(&decoder_session);
205
206         if(!DecoderSession_process(&decoder_session))
207                 return DecoderSession_finish_error(&decoder_session);
208
209         return DecoderSession_finish_ok(&decoder_session);
210 }
211
212 int flac__decode_raw(const char *infilename, const char *outfilename, FLAC__bool analysis_mode, analysis_options aopts, raw_decode_options_t options)
213 {
214         DecoderSession decoder_session;
215
216         decoder_session.is_big_endian = options.is_big_endian;
217         decoder_session.is_unsigned_samples = options.is_unsigned_samples;
218
219         if(!
220                 DecoderSession_construct(
221                         &decoder_session,
222 #ifdef FLAC__HAS_OGG
223                         options.common.is_ogg,
224 #else
225                         /*is_ogg=*/false,
226 #endif
227                         options.common.verbose,
228                         /*is_aiff_out=*/false,
229                         /*is_wave_out=*/false,
230                         options.common.continue_through_decode_errors,
231                         options.common.replaygain_synthesis_spec,
232                         analysis_mode,
233                         aopts,
234                         &options.common.skip_specification,
235                         &options.common.until_specification,
236                         infilename,
237                         outfilename
238                 )
239         )
240                 return 1;
241
242         if(!DecoderSession_init_decoder(&decoder_session, options.common, infilename))
243                 return DecoderSession_finish_error(&decoder_session);
244
245         if(!DecoderSession_process(&decoder_session))
246                 return DecoderSession_finish_error(&decoder_session);
247
248         return DecoderSession_finish_ok(&decoder_session);
249 }
250
251 FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__bool verbose, FLAC__bool is_aiff_out, FLAC__bool is_wave_out, FLAC__bool continue_through_decode_errors, replaygain_synthesis_spec_t replaygain_synthesis_spec, FLAC__bool analysis_mode, analysis_options aopts, utils__SkipUntilSpecification *skip_specification, utils__SkipUntilSpecification *until_specification, const char *infilename, const char *outfilename)
252 {
253 #ifdef FLAC__HAS_OGG
254         d->is_ogg = is_ogg;
255 #else
256         (void)is_ogg;
257 #endif
258
259         d->verbose = verbose;
260         d->is_aiff_out = is_aiff_out;
261         d->is_wave_out = is_wave_out;
262         d->continue_through_decode_errors = continue_through_decode_errors;
263         d->replaygain.spec = replaygain_synthesis_spec;
264         d->replaygain.apply = false;
265         d->replaygain.scale = 0.0;
266         /* d->replaygain.dither_context gets initialized later once we know the sample resolution */
267         d->test_only = (0 == outfilename);
268         d->analysis_mode = analysis_mode;
269         d->aopts = aopts;
270         d->skip_specification = skip_specification;
271         d->until_specification = until_specification;
272
273         d->inbasefilename = grabbag__file_get_basename(infilename);
274         d->outfilename = outfilename;
275
276         d->samples_processed = 0;
277         d->frame_counter = 0;
278         d->abort_flag = false;
279
280         d->wave_chunk_size_fixup.needs_fixup = false;
281
282         d->decoder.flac.file = 0;
283 #ifdef FLAC__HAS_OGG
284         d->decoder.ogg.stream = 0;
285 #endif
286
287 #ifdef FLAC__HAS_OGG
288         d->fin = 0;
289 #endif
290         d->fout = 0; /* initialized with an open file later if necessary */
291
292         FLAC__ASSERT(!(d->test_only && d->analysis_mode));
293
294         if(!d->test_only) {
295                 if(0 == strcmp(outfilename, "-")) {
296                         d->fout = grabbag__file_get_binary_stdout();
297                 }
298                 else {
299                         if(0 == (d->fout = fopen(outfilename, "wb"))) {
300                                 fprintf(stderr, "%s: ERROR: can't open output file %s\n", d->inbasefilename, outfilename);
301                                 DecoderSession_destroy(d, /*error_occurred=*/true);
302                                 return false;
303                         }
304                 }
305         }
306
307 #ifdef FLAC__HAS_OGG
308         if(d->is_ogg) {
309                 if (0 == strcmp(infilename, "-")) {
310                         d->fin = grabbag__file_get_binary_stdin();
311                 } else {
312                         if (0 == (d->fin = fopen(infilename, "rb"))) {
313                                 fprintf(stderr, "%s: ERROR: can't open input file %s\n", d->inbasefilename, infilename);
314                                 DecoderSession_destroy(d, /*error_occurred=*/true);
315                                 return false;
316                         }
317                 }
318         }
319 #endif
320
321         if(analysis_mode)
322                 flac__analyze_init(aopts);
323
324         return true;
325 }
326
327 void DecoderSession_destroy(DecoderSession *d, FLAC__bool error_occurred)
328 {
329         if(0 != d->fout && d->fout != stdout) {
330                 fclose(d->fout);
331                 if(error_occurred)
332                         unlink(d->outfilename);
333         }
334 #ifdef FLAC__HAS_OGG
335         if(0 != d->fin && d->fin != stdin)
336                 fclose(d->fin);
337 #endif
338 }
339
340 FLAC__bool DecoderSession_init_decoder(DecoderSession *decoder_session, decode_options_t decode_options, const char *infilename)
341 {
342         FLAC__uint32 test = 1;
343
344         is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true;
345
346 #ifdef FLAC__HAS_OGG
347         if(decoder_session->is_ogg) {
348                 decoder_session->decoder.ogg.stream = OggFLAC__stream_decoder_new();
349
350                 if(0 == decoder_session->decoder.ogg.stream) {
351                         fprintf(stderr, "%s: ERROR creating the decoder instance\n", decoder_session->inbasefilename);
352                         return false;
353                 }
354
355                 if(!decode_options.use_first_serial_number)
356                         OggFLAC__stream_decoder_set_serial_number(decoder_session->decoder.ogg.stream, decode_options.serial_number);
357                 if (decoder_session->replaygain.spec.apply)
358                         OggFLAC__stream_decoder_set_metadata_respond(decoder_session->decoder.ogg.stream, FLAC__METADATA_TYPE_VORBIS_COMMENT);
359
360                 OggFLAC__stream_decoder_set_read_callback(decoder_session->decoder.ogg.stream, read_callback);
361                 /*
362                  * The three ugly casts here are to 'downcast' the 'void *' argument of
363                  * the callback down to 'FLAC__StreamDecoder *'.  In C++ this would be
364                  * unnecessary but here the cast makes the C compiler happy.
365                  */
366                 OggFLAC__stream_decoder_set_write_callback(decoder_session->decoder.ogg.stream, (FLAC__StreamDecoderWriteStatus (*)(const OggFLAC__StreamDecoder *, const FLAC__Frame *, const FLAC__int32 * const [], void *))write_callback);
367                 OggFLAC__stream_decoder_set_metadata_callback(decoder_session->decoder.ogg.stream, (void (*)(const OggFLAC__StreamDecoder *, const FLAC__StreamMetadata *, void *))metadata_callback);
368                 OggFLAC__stream_decoder_set_error_callback(decoder_session->decoder.ogg.stream, (void (*)(const OggFLAC__StreamDecoder *, FLAC__StreamDecoderErrorStatus, void *))error_callback);
369                 OggFLAC__stream_decoder_set_client_data(decoder_session->decoder.ogg.stream, decoder_session);
370
371                 if(OggFLAC__stream_decoder_init(decoder_session->decoder.ogg.stream) != OggFLAC__STREAM_DECODER_OK) {
372                         print_error_with_state(decoder_session, "ERROR initializing decoder");
373                         return false;
374                 }
375         }
376         else
377 #else
378         (void)decode_options;
379 #endif
380         {
381                 decoder_session->decoder.flac.file = FLAC__file_decoder_new();
382
383                 if(0 == decoder_session->decoder.flac.file) {
384                         fprintf(stderr, "%s: ERROR creating the decoder instance\n", decoder_session->inbasefilename);
385                         return false;
386                 }
387
388                 FLAC__file_decoder_set_md5_checking(decoder_session->decoder.flac.file, true);
389                 FLAC__file_decoder_set_filename(decoder_session->decoder.flac.file, infilename);
390                 if (decoder_session->replaygain.spec.apply)
391                         FLAC__file_decoder_set_metadata_respond(decoder_session->decoder.flac.file, FLAC__METADATA_TYPE_VORBIS_COMMENT);
392                 /*
393                  * The three ugly casts here are to 'downcast' the 'void *' argument of
394                  * the callback down to 'FLAC__FileDecoder *'.
395                  */
396                 FLAC__file_decoder_set_write_callback(decoder_session->decoder.flac.file, (FLAC__StreamDecoderWriteStatus (*)(const FLAC__FileDecoder *, const FLAC__Frame *, const FLAC__int32 * const [], void *))write_callback);
397                 FLAC__file_decoder_set_metadata_callback(decoder_session->decoder.flac.file, (void (*)(const FLAC__FileDecoder *, const FLAC__StreamMetadata *, void *))metadata_callback);
398                 FLAC__file_decoder_set_error_callback(decoder_session->decoder.flac.file, (void (*)(const FLAC__FileDecoder *, FLAC__StreamDecoderErrorStatus, void *))error_callback);
399                 FLAC__file_decoder_set_client_data(decoder_session->decoder.flac.file, decoder_session);
400
401                 if(FLAC__file_decoder_init(decoder_session->decoder.flac.file) != FLAC__FILE_DECODER_OK) {
402                         print_error_with_state(decoder_session, "ERROR initializing decoder");
403                         return false;
404                 }
405         }
406
407         return true;
408 }
409
410 FLAC__bool DecoderSession_process(DecoderSession *d)
411 {
412 #ifdef FLAC__HAS_OGG
413         if(d->is_ogg) {
414                 if(!OggFLAC__stream_decoder_process_until_end_of_metadata(d->decoder.ogg.stream)) {
415                         if(d->verbose) fprintf(stderr, "\n");
416                         print_error_with_state(d, "ERROR while decoding metadata");
417                         return false;
418                 }
419                 if(OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(d->decoder.ogg.stream) != FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC && OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(d->decoder.ogg.stream) != FLAC__STREAM_DECODER_END_OF_STREAM) {
420                         if(d->verbose) fprintf(stderr, "\n");
421                         print_error_with_state(d, "ERROR during metadata decoding");
422                         return false;
423                 }
424         }
425         else
426 #endif
427         {
428                 if(!FLAC__file_decoder_process_until_end_of_metadata(d->decoder.flac.file)) {
429                         if(d->verbose) fprintf(stderr, "\n");
430                         print_error_with_state(d, "ERROR while decoding metadata");
431                         return false;
432                 }
433                 if(FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_OK && FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_END_OF_FILE) {
434                         if(d->verbose) fprintf(stderr, "\n");
435                         print_error_with_state(d, "ERROR during metadata decoding");
436                         return false;
437                 }
438         }
439         if(d->abort_flag)
440                 return false;
441
442         if(d->skip_specification->value.samples > 0) {
443                 const FLAC__uint64 skip = (FLAC__uint64)d->skip_specification->value.samples;
444
445 #ifdef FLAC__HAS_OGG
446                 if(d->is_ogg) { /*@@@ (move this check into main.c) */
447                         fprintf(stderr, "%s: ERROR, can't skip when decoding Ogg-FLAC yet; convert to native-FLAC first\n", d->inbasefilename);
448                         return false;
449                 }
450 #endif
451                 if(!FLAC__file_decoder_seek_absolute(d->decoder.flac.file, skip)) {
452                         print_error_with_state(d, "ERROR seeking while skipping bytes");
453                         return false;
454                 }
455                 if(!FLAC__file_decoder_process_until_end_of_file(d->decoder.flac.file)) {
456                         if(d->verbose) fprintf(stderr, "\n");
457                         print_error_with_state(d, "ERROR while decoding frames");
458                         return false;
459                 }
460                 if(FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_OK && FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_END_OF_FILE) {
461                         if(d->verbose) fprintf(stderr, "\n");
462                         print_error_with_state(d, "ERROR during decoding");
463                         return false;
464                 }
465         }
466         else {
467 #ifdef FLAC__HAS_OGG
468                 if(d->is_ogg) {
469                         if(!OggFLAC__stream_decoder_process_until_end_of_stream(d->decoder.ogg.stream)) {
470                                 if(d->verbose) fprintf(stderr, "\n");
471                                 print_error_with_state(d, "ERROR while decoding data");
472                                 return false;
473                         }
474                         if(OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(d->decoder.ogg.stream) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA && OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(d->decoder.ogg.stream) != FLAC__STREAM_DECODER_END_OF_STREAM) {
475                                 if(d->verbose) fprintf(stderr, "\n");
476                                 print_error_with_state(d, "ERROR during decoding");
477                                 return false;
478                         }
479                 }
480                 else
481 #endif
482                 {
483                         if(!FLAC__file_decoder_process_until_end_of_file(d->decoder.flac.file)) {
484                                 if(d->verbose) fprintf(stderr, "\n");
485                                 print_error_with_state(d, "ERROR while decoding data");
486                                 return false;
487                         }
488                         if(FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_OK && FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_END_OF_FILE) {
489                                 if(d->verbose) fprintf(stderr, "\n");
490                                 print_error_with_state(d, "ERROR during decoding");
491                                 return false;
492                         }
493                 }
494         }
495
496         if(d->is_aiff_out && ((d->total_samples * d->channels * ((d->bps+7)/8)) & 1)) {
497                 if(flac__utils_fwrite("\000", 1, 1, d->fout) != 1) {
498                         print_error_with_state(d, "ERROR writing pad byte to AIFF SSND chunk");
499                         return false;
500                 }
501         }
502
503         return true;
504 }
505
506 int DecoderSession_finish_ok(DecoderSession *d)
507 {
508         FLAC__bool md5_failure = false;
509
510 #ifdef FLAC__HAS_OGG
511         if(d->is_ogg) {
512                 if(d->decoder.ogg.stream) {
513                         OggFLAC__stream_decoder_finish(d->decoder.ogg.stream);
514                         md5_failure = false;
515                         print_stats(d);
516                         OggFLAC__stream_decoder_delete(d->decoder.ogg.stream);
517                 }
518         }
519         else
520 #endif
521         {
522                 if(d->decoder.flac.file) {
523                         md5_failure = !FLAC__file_decoder_finish(d->decoder.flac.file);
524                         print_stats(d);
525                         FLAC__file_decoder_delete(d->decoder.flac.file);
526                 }
527         }
528         if(d->analysis_mode)
529                 flac__analyze_finish(d->aopts);
530         if(md5_failure) {
531                 fprintf(stderr, "\r%s: WARNING, MD5 signature mismatch\n", d->inbasefilename);
532         }
533         else {
534                 if(d->verbose)
535                         fprintf(stderr, "\r%s: %s         \n", d->inbasefilename, d->test_only? "ok           ":d->analysis_mode?"done           ":"done");
536         }
537         DecoderSession_destroy(d, /*error_occurred=*/false);
538         if((d->is_wave_out || d->is_aiff_out) && d->wave_chunk_size_fixup.needs_fixup)
539                 if(!fixup_wave_chunk_size(d->outfilename, d->is_wave_out, d->wave_chunk_size_fixup.riff_offset, d->wave_chunk_size_fixup.data_offset, d->wave_chunk_size_fixup.frames_offset, (FLAC__uint32)d->samples_processed, d->channels, d->bps))
540                         return 1;
541         return 0;
542 }
543
544 int DecoderSession_finish_error(DecoderSession *d)
545 {
546 #ifdef FLAC__HAS_OGG
547         if(d->is_ogg) {
548                 if(d->decoder.ogg.stream) {
549                         OggFLAC__stream_decoder_finish(d->decoder.ogg.stream);
550                         OggFLAC__stream_decoder_delete(d->decoder.ogg.stream);
551                 }
552         }
553         else
554 #endif
555         {
556                 if(d->decoder.flac.file) {
557                         FLAC__file_decoder_finish(d->decoder.flac.file);
558                         FLAC__file_decoder_delete(d->decoder.flac.file);
559                 }
560         }
561         if(d->analysis_mode)
562                 flac__analyze_finish(d->aopts);
563         DecoderSession_destroy(d, /*error_occurred=*/true);
564         return 1;
565 }
566
567 FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input)
568 {
569         /* convert from mm:ss.sss to sample number if necessary */
570         flac__utils_canonicalize_skip_until_specification(spec, sample_rate);
571
572         /* special case: if "--until=-0", use the special value '0' to mean "end-of-stream" */
573         if(spec->is_relative && spec->value.samples == 0) {
574                 spec->is_relative = false;
575                 return true;
576         }
577
578         /* in any other case the total samples in the input must be known */
579         if(total_samples_in_input == 0) {
580                 fprintf(stderr, "%s: ERROR, cannot use --until when FLAC metadata has total sample count of 0\n", inbasefilename);
581                 return false;
582         }
583
584         FLAC__ASSERT(spec->value_is_samples);
585
586         /* convert relative specifications to absolute */
587         if(spec->is_relative) {
588                 if(spec->value.samples <= 0)
589                         spec->value.samples += (FLAC__int64)total_samples_in_input;
590                 else
591                         spec->value.samples += skip;
592                 spec->is_relative = false;
593         }
594
595         /* error check */
596         if(spec->value.samples < 0) {
597                 fprintf(stderr, "%s: ERROR, --until value is before beginning of input\n", inbasefilename);
598                 return false;
599         }
600         if((FLAC__uint64)spec->value.samples <= skip) {
601                 fprintf(stderr, "%s: ERROR, --until value is before --skip point\n", inbasefilename);
602                 return false;
603         }
604         if((FLAC__uint64)spec->value.samples > total_samples_in_input) {
605                 fprintf(stderr, "%s: ERROR, --until value is after end of input\n", inbasefilename);
606                 return false;
607         }
608
609         return true;
610 }
611
612 FLAC__bool write_little_endian_uint16(FILE *f, FLAC__uint16 val)
613 {
614         FLAC__byte *b = (FLAC__byte*)(&val);
615         if(is_big_endian_host_) {
616                 FLAC__byte tmp;
617                 tmp = b[1]; b[1] = b[0]; b[0] = tmp;
618         }
619         return flac__utils_fwrite(b, 1, 2, f) == 2;
620 }
621
622 FLAC__bool write_little_endian_uint32(FILE *f, FLAC__uint32 val)
623 {
624         FLAC__byte *b = (FLAC__byte*)(&val);
625         if(is_big_endian_host_) {
626                 FLAC__byte tmp;
627                 tmp = b[3]; b[3] = b[0]; b[0] = tmp;
628                 tmp = b[2]; b[2] = b[1]; b[1] = tmp;
629         }
630         return flac__utils_fwrite(b, 1, 4, f) == 4;
631 }
632
633 FLAC__bool write_big_endian_uint16(FILE *f, FLAC__uint16 val)
634 {
635         FLAC__byte *b = (FLAC__byte*)(&val);
636         if(!is_big_endian_host_) {
637                 FLAC__byte tmp;
638                 tmp = b[1]; b[1] = b[0]; b[0] = tmp;
639         }
640         return flac__utils_fwrite(b, 1, 2, f) == 2;
641 }
642
643 FLAC__bool write_big_endian_uint32(FILE *f, FLAC__uint32 val)
644 {
645         FLAC__byte *b = (FLAC__byte*)(&val);
646         if(!is_big_endian_host_) {
647                 FLAC__byte tmp;
648                 tmp = b[3]; b[3] = b[0]; b[0] = tmp;
649                 tmp = b[2]; b[2] = b[1]; b[1] = tmp;
650         }
651         return flac__utils_fwrite(b, 1, 4, f) == 4;
652 }
653
654 FLAC__bool write_sane_extended(FILE *f, unsigned val)
655         /* Write to 'f' a SANE extended representation of 'val'.  Return false if
656         * the write succeeds; return true otherwise.
657         *
658         * SANE extended is an 80-bit IEEE-754 representation with sign bit, 15 bits
659         * of exponent, and 64 bits of significand (mantissa).  Unlike most IEEE-754
660         * representations, it does not imply a 1 above the MSB of the significand.
661         *
662         * Preconditions:
663         *  val!=0U
664         */
665 {
666         unsigned int shift, exponent;
667
668         FLAC__ASSERT(val!=0U); /* handling 0 would require a special case */
669
670         for(shift= 0U; (val>>(31-shift))==0U; ++shift)
671                 ;
672         val<<= shift;
673         exponent= 63U-(shift+32U); /* add 32 for unused second word */
674
675         if(!write_big_endian_uint16(f, (FLAC__uint16)(exponent+0x3FFF)))
676                 return false;
677         if(!write_big_endian_uint32(f, val))
678                 return false;
679         if(!write_big_endian_uint32(f, 0)) /* unused second word */
680                 return false;
681
682         return true;
683 }
684
685 FLAC__bool fixup_wave_chunk_size(const char *outfilename, FLAC__bool is_wave_out, unsigned riff_offset, unsigned data_offset, unsigned frames_offset, FLAC__uint32 total_samples, unsigned channels, unsigned bps)
686 {
687         const char *fmt_desc = (is_wave_out? "WAVE" : "AIFF");
688         FLAC__bool (*write_it)(FILE *, FLAC__uint32) = (is_wave_out? write_little_endian_uint32 : write_big_endian_uint32);
689         FILE *f = fopen(outfilename, "r+b");
690         FLAC__uint32 data_size, aligned_data_size;
691
692         if(0 == f) {
693                 fprintf(stderr, "ERROR, couldn't open file %s while fixing up %s chunk size\n", outfilename, fmt_desc);
694                 return false;
695         }
696
697         data_size = aligned_data_size = total_samples * channels * ((bps+7)/8);
698         if(!is_wave_out && (aligned_data_size & 1))
699                 aligned_data_size++;
700
701         if(fseek(f, riff_offset, SEEK_SET) < 0) {
702                 fprintf(stderr, "ERROR, couldn't seek in file %s while fixing up %s chunk size\n", outfilename, fmt_desc);
703                 fclose(f);
704                 return false;
705         }
706         if(!write_it(f, aligned_data_size + (is_wave_out? 36 : 46))) {
707                 fprintf(stderr, "ERROR, couldn't write size in file %s while fixing up %s chunk size\n", outfilename, fmt_desc);
708                 fclose(f);
709                 return false;
710         }
711         if(!is_wave_out) {
712                 if(fseek(f, frames_offset, SEEK_SET) < 0) {
713                         fprintf(stderr, "ERROR, couldn't seek in file %s while fixing up %s chunk size\n", outfilename, fmt_desc);
714                         fclose(f);
715                         return false;
716                 }
717                 if(!write_it(f, total_samples)) {
718                         fprintf(stderr, "ERROR, couldn't write size in file %s while fixing up %s chunk size\n", outfilename, fmt_desc);
719                         fclose(f);
720                         return false;
721                 }
722         }
723         if(fseek(f, data_offset, SEEK_SET) < 0) {
724                 fprintf(stderr, "ERROR, couldn't seek in file %s while fixing up %s chunk size\n", outfilename, fmt_desc);
725                 fclose(f);
726                 return false;
727         }
728         if(!write_it(f, data_size + (is_wave_out? 0 : 8))) {
729                 fprintf(stderr, "ERROR, couldn't write size in file %s while fixing up %s chunk size\n", outfilename, fmt_desc);
730                 fclose(f);
731                 return false;
732         }
733         fclose(f);
734         return true;
735 }
736
737 #ifdef FLAC__HAS_OGG
738 FLAC__StreamDecoderReadStatus read_callback(const OggFLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
739 {
740         DecoderSession *decoder_session = (DecoderSession*)client_data;
741         FILE *fin = decoder_session->fin;
742         size_t bytes_read;
743
744         (void)decoder; /* avoid compiler warning */
745
746         if (decoder_session->abort_flag)
747                 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
748
749         if(feof(fin))
750                 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
751
752         bytes_read = fread(buffer, 1, *bytes, fin);
753
754         if(ferror(fin))
755                 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
756
757         *bytes = (unsigned)bytes_read;
758
759         return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
760 }
761 #endif
762
763 FLAC__StreamDecoderWriteStatus write_callback(const void *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
764 {
765         DecoderSession *decoder_session = (DecoderSession*)client_data;
766         FILE *fout = decoder_session->fout;
767         const unsigned bps = frame->header.bits_per_sample, channels = frame->header.channels;
768         FLAC__bool is_big_endian = (decoder_session->is_aiff_out? true : (decoder_session->is_wave_out? false : decoder_session->is_big_endian));
769         FLAC__bool is_unsigned_samples = (decoder_session->is_aiff_out? false : (decoder_session->is_wave_out? bps<=8 : decoder_session->is_unsigned_samples));
770         unsigned wide_samples = frame->header.blocksize, wide_sample, sample, channel, byte;
771         static FLAC__int8 s8buffer[FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS * sizeof(FLAC__int32)]; /* WATCHOUT: can be up to 2 megs */
772         FLAC__uint8  *u8buffer  = (FLAC__uint8  *)s8buffer;
773         FLAC__int16  *s16buffer = (FLAC__int16  *)s8buffer;
774         FLAC__uint16 *u16buffer = (FLAC__uint16 *)s8buffer;
775         FLAC__int32  *s32buffer = (FLAC__int32  *)s8buffer;
776         FLAC__uint32 *u32buffer = (FLAC__uint32 *)s8buffer;
777
778         (void)decoder;
779
780         if(decoder_session->abort_flag)
781                 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
782
783         if(bps != decoder_session->bps) {
784                 fprintf(stderr, "%s: ERROR, bits-per-sample is %u in frame but %u in STREAMINFO\n", decoder_session->inbasefilename, bps, decoder_session->bps);
785                 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
786         }
787         if(channels != decoder_session->channels) {
788                 fprintf(stderr, "%s: ERROR, channels is %u in frame but %u in STREAMINFO\n", decoder_session->inbasefilename, channels, decoder_session->channels);
789                 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
790         }
791         if(frame->header.sample_rate != decoder_session->sample_rate) {
792                 fprintf(stderr, "%s: ERROR, sample rate is %u in frame but %u in STREAMINFO\n", decoder_session->inbasefilename, frame->header.sample_rate, decoder_session->sample_rate);
793                 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
794         }
795
796         /*
797          * limit the number of samples to accept based on --until
798          */
799         FLAC__ASSERT(!decoder_session->skip_specification->is_relative);
800         FLAC__ASSERT(decoder_session->skip_specification->value.samples >= 0);
801         FLAC__ASSERT(!decoder_session->until_specification->is_relative);
802         FLAC__ASSERT(decoder_session->until_specification->value.samples >= 0);
803         if(decoder_session->until_specification->value.samples > 0) {
804                 const FLAC__uint64 skip = (FLAC__uint64)decoder_session->skip_specification->value.samples;
805                 const FLAC__uint64 until = (FLAC__uint64)decoder_session->until_specification->value.samples;
806                 const FLAC__uint64 input_samples_passed = skip + decoder_session->samples_processed;
807                 FLAC__ASSERT(until >= input_samples_passed);
808                 if(input_samples_passed + wide_samples > until)
809                         wide_samples = (unsigned)(until - input_samples_passed);
810         }
811
812         if(wide_samples > 0) {
813                 decoder_session->samples_processed += wide_samples;
814                 decoder_session->frame_counter++;
815
816                 if(decoder_session->verbose && !(decoder_session->frame_counter & 0x3f))
817                         print_stats(decoder_session);
818
819                 if(decoder_session->analysis_mode) {
820                         flac__analyze_frame(frame, decoder_session->frame_counter-1, decoder_session->aopts, fout);
821                 }
822                 else if(!decoder_session->test_only) {
823                         if (decoder_session->replaygain.apply) {
824                                 const size_t n = FLAC__replaygain_synthesis__apply_gain(
825                                         u8buffer,
826                                         !is_big_endian,
827                                         is_unsigned_samples,
828                                         buffer,
829                                         wide_samples,
830                                         channels,
831                                         bps, /* source_bps */
832                                         bps, /* target_bps */
833                                         decoder_session->replaygain.scale,
834                                         decoder_session->replaygain.spec.limiter == RGSS_LIMIT__HARD, /* hard_limit */
835                                         decoder_session->replaygain.spec.noise_shaping != NOISE_SHAPING_NONE, /* do_dithering */
836                                         &decoder_session->replaygain.dither_context
837                                 );
838                                 if(flac__utils_fwrite(u8buffer, 1, n, fout) != n)
839                                         return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
840                         }
841                         else if(bps == 8) {
842                                 if(is_unsigned_samples) {
843                                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
844                                                 for(channel = 0; channel < channels; channel++, sample++)
845                                                         u8buffer[sample] = (FLAC__uint8)(buffer[channel][wide_sample] + 0x80);
846                                 }
847                                 else {
848                                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
849                                                 for(channel = 0; channel < channels; channel++, sample++)
850                                                         s8buffer[sample] = (FLAC__int8)(buffer[channel][wide_sample]);
851                                 }
852                                 if(flac__utils_fwrite(u8buffer, 1, sample, fout) != sample)
853                                         return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
854                         }
855                         else if(bps == 16) {
856                                 if(is_unsigned_samples) {
857                                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
858                                                 for(channel = 0; channel < channels; channel++, sample++)
859                                                         u16buffer[sample] = (FLAC__uint16)(buffer[channel][wide_sample] + 0x8000);
860                                 }
861                                 else {
862                                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
863                                                 for(channel = 0; channel < channels; channel++, sample++)
864                                                         s16buffer[sample] = (FLAC__int16)(buffer[channel][wide_sample]);
865                                 }
866                                 if(is_big_endian != is_big_endian_host_) {
867                                         unsigned char tmp;
868                                         const unsigned bytes = sample * 2;
869                                         for(byte = 0; byte < bytes; byte += 2) {
870                                                 tmp = u8buffer[byte];
871                                                 u8buffer[byte] = u8buffer[byte+1];
872                                                 u8buffer[byte+1] = tmp;
873                                         }
874                                 }
875                                 if(flac__utils_fwrite(u16buffer, 2, sample, fout) != sample)
876                                         return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
877                         }
878                         else if(bps == 24) {
879                                 if(is_unsigned_samples) {
880                                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
881                                                 for(channel = 0; channel < channels; channel++, sample++)
882                                                         u32buffer[sample] = buffer[channel][wide_sample] + 0x800000;
883                                 }
884                                 else {
885                                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
886                                                 for(channel = 0; channel < channels; channel++, sample++)
887                                                         s32buffer[sample] = buffer[channel][wide_sample];
888                                 }
889                                 if(is_big_endian != is_big_endian_host_) {
890                                         unsigned char tmp;
891                                         const unsigned bytes = sample * 4;
892                                         for(byte = 0; byte < bytes; byte += 4) {
893                                                 tmp = u8buffer[byte];
894                                                 u8buffer[byte] = u8buffer[byte+3];
895                                                 u8buffer[byte+3] = tmp;
896                                                 tmp = u8buffer[byte+1];
897                                                 u8buffer[byte+1] = u8buffer[byte+2];
898                                                 u8buffer[byte+2] = tmp;
899                                         }
900                                 }
901                                 if(is_big_endian) {
902                                         unsigned lbyte;
903                                         const unsigned bytes = sample * 4;
904                                         for(lbyte = byte = 0; byte < bytes; ) {
905                                                 byte++;
906                                                 u8buffer[lbyte++] = u8buffer[byte++];
907                                                 u8buffer[lbyte++] = u8buffer[byte++];
908                                                 u8buffer[lbyte++] = u8buffer[byte++];
909                                         }
910                                 }
911                                 else {
912                                         unsigned lbyte;
913                                         const unsigned bytes = sample * 4;
914                                         for(lbyte = byte = 0; byte < bytes; ) {
915                                                 u8buffer[lbyte++] = u8buffer[byte++];
916                                                 u8buffer[lbyte++] = u8buffer[byte++];
917                                                 u8buffer[lbyte++] = u8buffer[byte++];
918                                                 byte++;
919                                         }
920                                 }
921                                 if(flac__utils_fwrite(u8buffer, 3, sample, fout) != sample)
922                                         return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
923                         }
924                         else {
925                                 FLAC__ASSERT(0);
926                         }
927                 }
928         }
929         return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
930 }
931
932 void metadata_callback(const void *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
933 {
934         DecoderSession *decoder_session = (DecoderSession*)client_data;
935         (void)decoder;
936         if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
937                 FLAC__uint64 skip, until;
938                 decoder_session->bps = metadata->data.stream_info.bits_per_sample;
939                 decoder_session->channels = metadata->data.stream_info.channels;
940                 decoder_session->sample_rate = metadata->data.stream_info.sample_rate;
941
942                 flac__utils_canonicalize_skip_until_specification(decoder_session->skip_specification, decoder_session->sample_rate);
943                 FLAC__ASSERT(decoder_session->skip_specification->value.samples >= 0);
944                 skip = (FLAC__uint64)decoder_session->skip_specification->value.samples;
945
946                 /* remember, metadata->data.stream_info.total_samples can be 0, meaning 'unknown' */
947                 if(metadata->data.stream_info.total_samples > 0 && skip >= metadata->data.stream_info.total_samples) {
948                         fprintf(stderr, "%s: ERROR trying to --skip more samples than in stream\n", decoder_session->inbasefilename);
949                         decoder_session->abort_flag = true;
950                         return;
951                 }
952                 else if(metadata->data.stream_info.total_samples == 0 && skip > 0) {
953                         fprintf(stderr, "%s: ERROR, can't --skip when FLAC metadata has total sample count of 0\n", decoder_session->inbasefilename);
954                         decoder_session->abort_flag = true;
955                         return;
956                 }
957                 decoder_session->total_samples = metadata->data.stream_info.total_samples - skip;
958
959                 /* note that we use metadata->data.stream_info.total_samples instead of decoder_session->total_samples */
960                 if(!canonicalize_until_specification(decoder_session->until_specification, decoder_session->inbasefilename, decoder_session->sample_rate, skip, metadata->data.stream_info.total_samples)) {
961                         decoder_session->abort_flag = true;
962                         return;
963                 }
964                 FLAC__ASSERT(decoder_session->until_specification->value.samples >= 0);
965                 until = (FLAC__uint64)decoder_session->until_specification->value.samples;
966
967                 if(until > 0)
968                         decoder_session->total_samples -= (metadata->data.stream_info.total_samples - until);
969
970                 if(decoder_session->bps != 8 && decoder_session->bps != 16 && decoder_session->bps != 24) {
971                         fprintf(stderr, "%s: ERROR: bits per sample is not 8/16/24\n", decoder_session->inbasefilename);
972                         decoder_session->abort_flag = true;
973                         return;
974                 }
975
976                 /* write the WAVE/AIFF headers if necessary */
977                 if(!decoder_session->analysis_mode && !decoder_session->test_only && (decoder_session->is_wave_out || decoder_session->is_aiff_out)) {
978                         const char *fmt_desc = decoder_session->is_wave_out? "WAVE" : "AIFF";
979                         FLAC__uint64 data_size = decoder_session->total_samples * decoder_session->channels * ((decoder_session->bps+7)/8);
980                         if(decoder_session->total_samples == 0) {
981                                 if(decoder_session->fout == stdout) {
982                                         fprintf(stderr, "%s: WARNING, don't have accurate sample count available for %s header.\n", decoder_session->inbasefilename, fmt_desc);
983                                         fprintf(stderr, "             Generated %s file will have a data chunk size of 0.  Try\n", fmt_desc);
984                                         fprintf(stderr, "             decoding directly to a file instead.\n");
985                                 }
986                                 else {
987                                         decoder_session->wave_chunk_size_fixup.needs_fixup = true;
988                                 }
989                         }
990                         if(data_size >= 0xFFFFFFDC) {
991                                 fprintf(stderr, "%s: ERROR: stream is too big to fit in a single %s file chunk\n", decoder_session->inbasefilename, fmt_desc);
992                                 decoder_session->abort_flag = true;
993                                 return;
994                         }
995                         if(decoder_session->is_wave_out) {
996                                 if(flac__utils_fwrite("RIFF", 1, 4, decoder_session->fout) != 4)
997                                         decoder_session->abort_flag = true;
998
999                                 if(decoder_session->wave_chunk_size_fixup.needs_fixup)
1000                                         decoder_session->wave_chunk_size_fixup.riff_offset = ftell(decoder_session->fout);
1001
1002                                 if(!write_little_endian_uint32(decoder_session->fout, (FLAC__uint32)(data_size+36))) /* filesize-8 */
1003                                         decoder_session->abort_flag = true;
1004
1005                                 if(flac__utils_fwrite("WAVEfmt ", 1, 8, decoder_session->fout) != 8)
1006                                         decoder_session->abort_flag = true;
1007
1008                                 if(flac__utils_fwrite("\020\000\000\000", 1, 4, decoder_session->fout) != 4) /* chunk size = 16 */
1009                                         decoder_session->abort_flag = true;
1010
1011                                 if(flac__utils_fwrite("\001\000", 1, 2, decoder_session->fout) != 2) /* compression code == 1 */
1012                                         decoder_session->abort_flag = true;
1013
1014                                 if(!write_little_endian_uint16(decoder_session->fout, (FLAC__uint16)(decoder_session->channels)))
1015                                         decoder_session->abort_flag = true;
1016
1017                                 if(!write_little_endian_uint32(decoder_session->fout, decoder_session->sample_rate))
1018                                         decoder_session->abort_flag = true;
1019
1020                                 if(!write_little_endian_uint32(decoder_session->fout, decoder_session->sample_rate * decoder_session->channels * ((decoder_session->bps+7) / 8))) /* @@@ or is it (sample_rate*channels*bps) / 8 ??? */
1021                                         decoder_session->abort_flag = true;
1022
1023                                 if(!write_little_endian_uint16(decoder_session->fout, (FLAC__uint16)(decoder_session->channels * ((decoder_session->bps+7) / 8)))) /* block align */
1024                                         decoder_session->abort_flag = true;
1025
1026                                 if(!write_little_endian_uint16(decoder_session->fout, (FLAC__uint16)(decoder_session->bps))) /* bits per sample */
1027                                         decoder_session->abort_flag = true;
1028
1029                                 if(flac__utils_fwrite("data", 1, 4, decoder_session->fout) != 4)
1030                                         decoder_session->abort_flag = true;
1031
1032                                 if(decoder_session->wave_chunk_size_fixup.needs_fixup)
1033                                         decoder_session->wave_chunk_size_fixup.data_offset = ftell(decoder_session->fout);
1034
1035                                 if(!write_little_endian_uint32(decoder_session->fout, (FLAC__uint32)data_size)) /* data size */
1036                                         decoder_session->abort_flag = true;
1037                         }
1038                         else {
1039                                 const FLAC__uint32 aligned_data_size = (FLAC__uint32)((data_size+1) & (~1U));
1040
1041                                 if(flac__utils_fwrite("FORM", 1, 4, decoder_session->fout) != 4)
1042                                         decoder_session->abort_flag = true;
1043
1044                                 if(decoder_session->wave_chunk_size_fixup.needs_fixup)
1045                                         decoder_session->wave_chunk_size_fixup.riff_offset = ftell(decoder_session->fout);
1046
1047                                 if(!write_big_endian_uint32(decoder_session->fout, (FLAC__uint32)(aligned_data_size+46))) /* filesize-8 */
1048                                         decoder_session->abort_flag = true;
1049
1050                                 if(flac__utils_fwrite("AIFFCOMM", 1, 8, decoder_session->fout) != 8)
1051                                         decoder_session->abort_flag = true;
1052
1053                                 if(flac__utils_fwrite("\000\000\000\022", 1, 4, decoder_session->fout) != 4) /* chunk size = 18 */
1054                                         decoder_session->abort_flag = true;
1055
1056                                 if(!write_big_endian_uint16(decoder_session->fout, (FLAC__uint16)(decoder_session->channels)))
1057                                         decoder_session->abort_flag = true;
1058
1059                                 if(decoder_session->wave_chunk_size_fixup.needs_fixup)
1060                                         decoder_session->wave_chunk_size_fixup.frames_offset = ftell(decoder_session->fout);
1061
1062                                 if(!write_big_endian_uint32(decoder_session->fout, (FLAC__uint32)decoder_session->total_samples))
1063                                         decoder_session->abort_flag = true;
1064
1065                                 if(!write_big_endian_uint16(decoder_session->fout, (FLAC__uint16)(decoder_session->bps)))
1066                                         decoder_session->abort_flag = true;
1067
1068                                 if(!write_sane_extended(decoder_session->fout, decoder_session->sample_rate))
1069                                         decoder_session->abort_flag = true;
1070
1071                                 if(flac__utils_fwrite("SSND", 1, 4, decoder_session->fout) != 4)
1072                                         decoder_session->abort_flag = true;
1073
1074                                 if(decoder_session->wave_chunk_size_fixup.needs_fixup)
1075                                         decoder_session->wave_chunk_size_fixup.data_offset = ftell(decoder_session->fout);
1076
1077                                 if(!write_big_endian_uint32(decoder_session->fout, (FLAC__uint32)data_size+8)) /* data size */
1078                                         decoder_session->abort_flag = true;
1079
1080                                 if(!write_big_endian_uint32(decoder_session->fout, 0/*offset*/))
1081                                         decoder_session->abort_flag = true;
1082
1083                                 if(!write_big_endian_uint32(decoder_session->fout, 0/*block_size*/))
1084                                         decoder_session->abort_flag = true;
1085                         }
1086                 }
1087         }
1088         else if(metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
1089                 if (decoder_session->replaygain.spec.apply) {
1090                         double gain, peak;
1091                         if (!(decoder_session->replaygain.apply = grabbag__replaygain_load_from_vorbiscomment(metadata, decoder_session->replaygain.spec.use_album_gain, &gain, &peak))) {
1092                                 fprintf(stderr, "%s: WARNING: can't get %s ReplayGain tag\n", decoder_session->inbasefilename, decoder_session->replaygain.spec.use_album_gain? "album":"track");
1093                         }
1094                         else {
1095                                 const char *ls[] = { "no", "peak", "hard" };
1096                                 const char *ns[] = { "no", "low", "medium", "high" };
1097                                 decoder_session->replaygain.scale = grabbag__replaygain_compute_scale_factor(peak, gain, decoder_session->replaygain.spec.preamp, decoder_session->replaygain.spec.limiter == RGSS_LIMIT__PEAK);
1098                                 FLAC__ASSERT(decoder_session->bps > 0 && decoder_session->bps <= 32);
1099                                 FLAC__replaygain_synthesis__init_dither_context(&decoder_session->replaygain.dither_context, decoder_session->bps, decoder_session->replaygain.spec.noise_shaping);
1100                                 fprintf(stderr, "%s: INFO: applying %s ReplayGain (gain=%0.2fdB+preamp=%0.1fdB, %s noise shaping, %s limiting) to output\n", decoder_session->inbasefilename, decoder_session->replaygain.spec.use_album_gain? "album":"track", gain, decoder_session->replaygain.spec.preamp, ns[decoder_session->replaygain.spec.noise_shaping], ls[decoder_session->replaygain.spec.limiter]);
1101                                 fprintf(stderr, "%s: WARNING: applying ReplayGain is not lossless\n", decoder_session->inbasefilename);
1102                         }
1103                 }
1104         }
1105 }
1106
1107 void error_callback(const void *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
1108 {
1109         DecoderSession *decoder_session = (DecoderSession*)client_data;
1110         (void)decoder;
1111         fprintf(stderr, "%s: *** Got error code %d:%s\n", decoder_session->inbasefilename, status, FLAC__StreamDecoderErrorStatusString[status]);
1112         if(!decoder_session->continue_through_decode_errors)
1113                 decoder_session->abort_flag = true;
1114 }
1115
1116 void print_error_with_state(const DecoderSession *d, const char *message)
1117 {
1118         const int ilen = strlen(d->inbasefilename) + 1;
1119
1120         fprintf(stderr, "\n%s: %s\n", d->inbasefilename, message);
1121
1122 #ifdef FLAC__HAS_OGG
1123         if(d->is_ogg) {
1124                 const OggFLAC__StreamDecoderState osd_state = OggFLAC__stream_decoder_get_state(d->decoder.ogg.stream);
1125                 if(osd_state != OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR) {
1126                         fprintf(stderr, "%*s state = %d:%s\n", ilen, "", (int)osd_state, OggFLAC__StreamDecoderStateString[osd_state]);
1127                 }
1128                 else {
1129                         const FLAC__StreamDecoderState fsd_state = OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(d->decoder.ogg.stream);
1130                         fprintf(stderr, "%*s state = %d:%s\n", ilen, "", (int)fsd_state, FLAC__StreamDecoderStateString[fsd_state]);
1131                 }
1132         }
1133         else
1134 #endif
1135         {
1136                 const FLAC__FileDecoderState ffd_state = FLAC__file_decoder_get_state(d->decoder.flac.file);
1137                 if(ffd_state != FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR) {
1138                         fprintf(stderr, "%*s state = %d:%s\n", ilen, "", (int)ffd_state, FLAC__FileDecoderStateString[ffd_state]);
1139                 }
1140                 else {
1141                         const FLAC__SeekableStreamDecoderState fssd_state = FLAC__file_decoder_get_seekable_stream_decoder_state(d->decoder.flac.file);
1142                         if(fssd_state != FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
1143                                 fprintf(stderr, "%*s state = %d:%s\n", ilen, "", (int)fssd_state, FLAC__SeekableStreamDecoderStateString[fssd_state]);
1144                         }
1145                         else {
1146                                 const FLAC__StreamDecoderState fsd_state = FLAC__file_decoder_get_stream_decoder_state(d->decoder.flac.file);
1147                                 fprintf(stderr, "%*s state = %d:%s\n", ilen, "", (int)fsd_state, FLAC__StreamDecoderStateString[fsd_state]);
1148                         }
1149                 }
1150         }
1151 }
1152
1153 void print_stats(const DecoderSession *decoder_session)
1154 {
1155         if(decoder_session->verbose) {
1156 #if defined _MSC_VER || defined __MINGW32__
1157                 /* with VC++ you have to spoon feed it the casting */
1158                 const double progress = (double)(FLAC__int64)decoder_session->samples_processed / (double)(FLAC__int64)decoder_session->total_samples * 100.0;
1159 #else
1160                 const double progress = (double)decoder_session->samples_processed / (double)decoder_session->total_samples * 100.0;
1161 #endif
1162                 if(decoder_session->total_samples > 0) {
1163                         fprintf(stderr, "\r%s: %s%u%% complete",
1164                                 decoder_session->inbasefilename,
1165                                 decoder_session->test_only? "testing, " : decoder_session->analysis_mode? "analyzing, " : "",
1166                                 (unsigned)floor(progress + 0.5)
1167                         );
1168                 }
1169                 else {
1170                         fprintf(stderr, "\r%s: %s %u samples",
1171                                 decoder_session->inbasefilename,
1172                                 decoder_session->test_only? "tested" : decoder_session->analysis_mode? "analyzed" : "wrote",
1173                                 (unsigned)decoder_session->samples_processed
1174                         );
1175                 }
1176         }
1177 }