~ubuntu-branches/ubuntu/raring/flac/raring

« back to all changes in this revision

Viewing changes to src/flac/encode.c

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2007-12-06 16:57:20 UTC
  • mto: (8.1.1 lenny)
  • mto: This revision was merged to the branch mainline in revision 12.
  • Revision ID: james.westby@ubuntu.com-20071206165720-4przr8grn6ha3e3a
Tags: upstream-1.2.1
ImportĀ upstreamĀ versionĀ 1.2.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
#include <math.h> /* for floor() */
39
39
#include <stdio.h> /* for FILE etc. */
40
40
#include <stdlib.h> /* for malloc */
41
 
#include <string.h> /* for strcmp(), strerror( */
 
41
#include <string.h> /* for strcmp(), strerror() */
42
42
#include "FLAC/all.h"
 
43
#include "share/alloc.h"
43
44
#include "share/grabbag.h"
44
45
#include "encode.h"
45
46
 
63
64
        FLAC__bool is_stdout;
64
65
        FLAC__bool outputfile_opened; /* true if we successfully opened the output file and we want it to be deleted if there is an error */
65
66
        const char *inbasefilename;
 
67
        const char *infilename;
66
68
        const char *outfilename;
67
69
 
68
70
        FLAC__uint64 skip;
116
118
extern FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
117
119
extern FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
118
120
extern FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
 
121
extern FLAC__bool FLAC__stream_encoder_set_do_md5(FLAC__StreamEncoder *encoder, FLAC__bool value);
119
122
 
120
123
/*
121
124
 * local routines
122
125
 */
123
126
static FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC__bool verify, FLAC__bool treat_warnings_as_errors, FLAC__bool continue_through_decode_errors, FILE *infile, const char *infilename, const char *outfilename);
124
127
static void EncoderSession_destroy(EncoderSession *e);
125
 
static int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero);
 
128
static int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero, foreign_metadata_t *foreign_metadata);
126
129
static int EncoderSession_finish_error(EncoderSession *e);
127
 
static FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options, FLAC__uint32 channel_mask, unsigned channels, unsigned bps, unsigned sample_rate, FLACDecoderData *flac_decoder_data);
 
130
static FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options, FLAC__uint32 channel_mask, unsigned channels, unsigned bps, unsigned sample_rate, const foreign_metadata_t *foreign_metadata, FLACDecoderData *flac_decoder_data);
128
131
static FLAC__bool EncoderSession_process(EncoderSession *e, const FLAC__int32 * const buffer[], unsigned samples);
129
132
static FLAC__bool convert_to_seek_table_template(const char *requested_seek_points, int num_requested_seek_points, FLAC__StreamMetadata *cuesheet, EncoderSession *e);
130
133
static FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input);
151
154
static FLAC__bool read_sane_extended(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
152
155
static FLAC__bool fskip_ahead(FILE *f, FLAC__uint64 offset);
153
156
static unsigned count_channel_mask_bits(FLAC__uint32 mask);
 
157
#if 0
154
158
static FLAC__uint32 limit_channel_mask(FLAC__uint32 mask, unsigned channels);
 
159
#endif
155
160
 
156
161
/*
157
162
 * public routines
196
201
                        channel_map[i] = i;
197
202
        }
198
203
 
 
204
        if(options.foreign_metadata) {
 
205
                const char *error;
 
206
                if(!flac__foreign_metadata_read_from_aiff(options.foreign_metadata, infilename, &error)) {
 
207
                        flac__utils_printf(stderr, 1, "%s: ERROR reading foreign metadata: %s\n", encoder_session.inbasefilename, error);
 
208
                        return EncoderSession_finish_error(&encoder_session);
 
209
                }
 
210
        }
 
211
 
199
212
        /* lookahead[] already has "FORMxxxxAIFF", do sub-chunks */
200
213
 
201
214
        while(1) {
323
336
 
324
337
                        /* skip any extra data in the COMM chunk */
325
338
                        if(!fskip_ahead(infile, skip)) {
326
 
                                flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping extra COMM data\n", encoder_session.inbasefilename);
 
339
                                flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping over extra COMM data\n", encoder_session.inbasefilename);
327
340
                                return EncoderSession_finish_error(&encoder_session);
328
341
                        }
329
342
 
340
353
                }
341
354
                else if(got_ssnd_chunk==false && !memcmp(chunk_id, "SSND", 4)) { /* sound data chunk */
342
355
                        unsigned int offset= 0U, block_size= 0U, align_remainder= 0U, data_bytes;
343
 
                        size_t bytes_per_frame= channels*(bps>>3);
 
356
                        const size_t bytes_per_frame= channels*(bps>>3);
344
357
                        FLAC__uint64 total_samples_in_input, trim = 0;
345
358
                        FLAC__bool pad= false;
346
359
 
352
365
                        /* SSND chunk size */
353
366
                        if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
354
367
                                return EncoderSession_finish_error(&encoder_session);
355
 
                        data_bytes= xx;
 
368
                        if(options.common.ignore_chunk_sizes) {
 
369
                                FLAC__ASSERT(!options.common.sector_align);
 
370
                                data_bytes = (unsigned)(-(int)bytes_per_frame); /* max out data_bytes; we'll use EOF as signal to stop reading */
 
371
                        }
 
372
                        else {
 
373
                                data_bytes= xx;
 
374
                                data_bytes-= 8U; /* discount the offset and block size fields */
 
375
                        }
356
376
                        pad= (data_bytes & 1U) ? true : false;
357
 
                        data_bytes-= 8U; /* discount the offset and block size fields */
358
377
 
359
378
                        /* offset */
360
379
                        if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
403
422
                        }
404
423
 
405
424
                        data_bytes-= (unsigned int)encoder_session.skip*bytes_per_frame; /*@@@ WATCHOUT: 4GB limit */
406
 
                        encoder_session.total_samples_to_encode= total_samples_in_input - encoder_session.skip;
 
425
                        if(options.common.ignore_chunk_sizes) {
 
426
                                encoder_session.total_samples_to_encode= 0;
 
427
                                flac__utils_printf(stderr, 2, "(No runtime statistics possible; please wait for encoding to finish...)\n");
 
428
                                FLAC__ASSERT(0 == encoder_session.until);
 
429
                        }
 
430
                        else {
 
431
                                encoder_session.total_samples_to_encode= total_samples_in_input - encoder_session.skip;
 
432
                        }
407
433
                        if(encoder_session.until > 0) {
408
434
                                trim = total_samples_in_input - encoder_session.until;
409
435
                                FLAC__ASSERT(total_samples_in_input > 0);
422
448
                        /* +54 for the size of the AIFF headers; this is just an estimate for the progress indicator and doesn't need to be exact */
423
449
                        encoder_session.unencoded_size= encoder_session.total_samples_to_encode*bytes_per_frame+54;
424
450
 
425
 
                        if(!EncoderSession_init_encoder(&encoder_session, options.common, /*channel_mask=*/0, channels, bps-shift, sample_rate, /*flac_decoder_data=*/0))
 
451
                        if(!EncoderSession_init_encoder(&encoder_session, options.common, /*channel_mask=*/0, channels, bps-shift, sample_rate, options.foreign_metadata, /*flac_decoder_data=*/0))
426
452
                                return EncoderSession_finish_error(&encoder_session);
427
453
 
428
454
                        /* first do any samples in the reservoir */
454
480
                                                return EncoderSession_finish_error(&encoder_session);
455
481
                                        }
456
482
                                        else if(feof(infile)) {
457
 
                                                flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned int)encoder_session.total_samples_to_encode, (unsigned int)encoder_session.samples_written);
458
 
                                                if(encoder_session.treat_warnings_as_errors)
459
 
                                                        return EncoderSession_finish_error(&encoder_session);
 
483
                                                if(options.common.ignore_chunk_sizes) {
 
484
                                                        flac__utils_printf(stderr, 1, "%s: INFO: hit EOF with --ignore-chunk-sizes, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.samples_written);
 
485
                                                }
 
486
                                                else {
 
487
                                                        flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
 
488
                                                        if(encoder_session.treat_warnings_as_errors)
 
489
                                                                return EncoderSession_finish_error(&encoder_session);
 
490
                                                }
460
491
                                                data_bytes= 0;
461
492
                                        }
462
493
                                }
541
572
                        got_ssnd_chunk= true;
542
573
                }
543
574
                else { /* other chunk */
544
 
                        if(!memcmp(chunk_id, "COMM", 4)) {
545
 
                                flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'COMM' chunk\n", encoder_session.inbasefilename);
546
 
                                if(encoder_session.treat_warnings_as_errors)
547
 
                                        return EncoderSession_finish_error(&encoder_session);
548
 
                        }
549
 
                        else if(!memcmp(chunk_id, "SSND", 4)) {
550
 
                                flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'SSND' chunk\n", encoder_session.inbasefilename);
551
 
                                if(encoder_session.treat_warnings_as_errors)
552
 
                                        return EncoderSession_finish_error(&encoder_session);
553
 
                        }
554
 
                        else {
555
 
                                flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown chunk '%s'\n", encoder_session.inbasefilename, chunk_id);
 
575
                        if(!options.foreign_metadata) {
 
576
                                if(!memcmp(chunk_id, "COMM", 4))
 
577
                                        flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'COMM' chunk (use --keep-foreign-metadata to keep)\n", encoder_session.inbasefilename);
 
578
                                else if(!memcmp(chunk_id, "SSND", 4))
 
579
                                        flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'SSND' chunk (use --keep-foreign-metadata to keep)\n", encoder_session.inbasefilename);
 
580
                                else if(!options.foreign_metadata)
 
581
                                        flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown chunk '%s' (use --keep-foreign-metadata to keep)\n", encoder_session.inbasefilename, chunk_id);
556
582
                                if(encoder_session.treat_warnings_as_errors)
557
583
                                        return EncoderSession_finish_error(&encoder_session);
558
584
                        }
565
591
 
566
592
                                FLAC__ASSERT(skip<=LONG_MAX);
567
593
                                if(!fskip_ahead(infile, skip)) {
568
 
                                        fprintf(stderr, "%s: ERROR during read while skipping unknown chunk\n", encoder_session.inbasefilename);
 
594
                                        fprintf(stderr, "%s: ERROR during read while skipping over unknown chunk\n", encoder_session.inbasefilename);
569
595
                                        return EncoderSession_finish_error(&encoder_session);
570
596
                                }
571
597
                        }
577
603
                return EncoderSession_finish_error(&encoder_session);
578
604
        }
579
605
 
580
 
        return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
 
606
        return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero, options.foreign_metadata);
581
607
}
582
608
 
583
609
int flac__encode_wav(FILE *infile, off_t infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, wav_encode_options_t options)
585
611
        EncoderSession encoder_session;
586
612
        FLAC__bool is_unsigned_samples = false;
587
613
        unsigned channels = 0, bps = 0, sample_rate = 0, shift = 0;
588
 
        size_t bytes_per_wide_sample, bytes_read;
 
614
        size_t bytes_read;
589
615
        size_t channel_map[FLAC__MAX_CHANNELS];
590
616
        FLAC__uint16 x, format; /* format is the wFormatTag word from the 'fmt ' chunk */
591
617
        FLAC__uint32 xx, channel_mask = 0;
622
648
                        channel_map[i] = i;
623
649
        }
624
650
 
 
651
        if(options.foreign_metadata) {
 
652
                const char *error;
 
653
                if(!flac__foreign_metadata_read_from_wave(options.foreign_metadata, infilename, &error)) {
 
654
                        flac__utils_printf(stderr, 1, "%s: ERROR reading foreign metadata: %s\n", encoder_session.inbasefilename, error);
 
655
                        return EncoderSession_finish_error(&encoder_session);
 
656
                }
 
657
        }
 
658
 
625
659
        /*
626
660
         * lookahead[] already has "RIFFxxxxWAVE", do sub-chunks
627
661
         */
646
680
                         * 4 byte: avg bytes per sec
647
681
                         * 2 byte: block align
648
682
                         * 2 byte: bits per sample (not necessarily all significant)
649
 
                         * WAVEFORMAT adds
 
683
                         * WAVEFORMATEX adds
650
684
                         * 2 byte: extension size in bytes (usually 0 for WAVEFORMATEX and 22 for WAVEFORMATEXTENSIBLE with PCM)
651
685
                         * WAVEFORMATEXTENSIBLE adds
652
686
                         * 2 byte: valid bits per sample
881
915
 
882
916
                        /* skip any extra data in the fmt sub-chunk */
883
917
                        if(!fskip_ahead(infile, data_bytes)) {
884
 
                                flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping extra 'fmt' data\n", encoder_session.inbasefilename);
 
918
                                flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping over extra 'fmt' data\n", encoder_session.inbasefilename);
885
919
                                return EncoderSession_finish_error(&encoder_session);
886
920
                        }
887
921
 
899
933
                else if(xx == 0x61746164 && !got_data_chunk && got_fmt_chunk) { /* "data" */
900
934
                        FLAC__uint64 total_samples_in_input, trim = 0;
901
935
                        FLAC__bool pad = false;
 
936
                        const size_t bytes_per_wide_sample = channels * (bps >> 3);
902
937
                        unsigned data_bytes;
903
938
 
904
939
                        /* data size */
905
940
                        if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
906
941
                                return EncoderSession_finish_error(&encoder_session);
907
 
                        data_bytes = xx;
908
 
                        if(0 == data_bytes) {
909
 
                                flac__utils_printf(stderr, 1, "%s: ERROR: 'data' subchunk has size of 0\n", encoder_session.inbasefilename);
910
 
                                return EncoderSession_finish_error(&encoder_session);
 
942
                        if(options.common.ignore_chunk_sizes) {
 
943
                                FLAC__ASSERT(!options.common.sector_align);
 
944
                                data_bytes = (unsigned)(-(int)bytes_per_wide_sample); /* max out data_bytes; we'll use EOF as signal to stop reading */
 
945
                        }
 
946
                        else {
 
947
                                data_bytes = xx;
 
948
                                if(0 == data_bytes) {
 
949
                                        flac__utils_printf(stderr, 1, "%s: ERROR: 'data' subchunk has size of 0\n", encoder_session.inbasefilename);
 
950
                                        return EncoderSession_finish_error(&encoder_session);
 
951
                                }
911
952
                        }
912
953
                        pad = (data_bytes & 1U) ? true : false;
913
954
 
914
 
                        bytes_per_wide_sample = channels * (bps >> 3);
915
 
 
916
955
                        /* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */
917
956
                        FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0);
918
957
                        total_samples_in_input = data_bytes / bytes_per_wide_sample + *options.common.align_reservoir_samples;
934
973
                        }
935
974
 
936
975
                        data_bytes -= (unsigned)encoder_session.skip * bytes_per_wide_sample; /*@@@ WATCHOUT: 4GB limit */
937
 
                        encoder_session.total_samples_to_encode = total_samples_in_input - encoder_session.skip;
 
976
                        if(options.common.ignore_chunk_sizes) {
 
977
                                encoder_session.total_samples_to_encode = 0;
 
978
                                flac__utils_printf(stderr, 2, "(No runtime statistics possible; please wait for encoding to finish...)\n");
 
979
                                FLAC__ASSERT(0 == encoder_session.until);
 
980
                        }
 
981
                        else {
 
982
                                encoder_session.total_samples_to_encode = total_samples_in_input - encoder_session.skip;
 
983
                        }
938
984
                        if(encoder_session.until > 0) {
939
985
                                trim = total_samples_in_input - encoder_session.until;
940
986
                                FLAC__ASSERT(total_samples_in_input > 0);
953
999
                        /* +44 for the size of the WAV headers; this is just an estimate for the progress indicator and doesn't need to be exact */
954
1000
                        encoder_session.unencoded_size = encoder_session.total_samples_to_encode * bytes_per_wide_sample + 44;
955
1001
 
956
 
                        if(!EncoderSession_init_encoder(&encoder_session, options.common, channel_mask, channels, bps-shift, sample_rate, /*flac_decoder_data=*/0))
 
1002
                        if(!EncoderSession_init_encoder(&encoder_session, options.common, channel_mask, channels, bps-shift, sample_rate, options.foreign_metadata, /*flac_decoder_data=*/0))
957
1003
                                return EncoderSession_finish_error(&encoder_session);
958
1004
 
959
1005
                        /*
990
1036
                                                return EncoderSession_finish_error(&encoder_session);
991
1037
                                        }
992
1038
                                        else if(feof(infile)) {
993
 
                                                flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
994
 
                                                if(encoder_session.treat_warnings_as_errors)
995
 
                                                        return EncoderSession_finish_error(&encoder_session);
 
1039
                                                if(options.common.ignore_chunk_sizes) {
 
1040
                                                        flac__utils_printf(stderr, 1, "%s: INFO: hit EOF with --ignore-chunk-sizes, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.samples_written);
 
1041
                                                }
 
1042
                                                else {
 
1043
                                                        flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
 
1044
                                                        if(encoder_session.treat_warnings_as_errors)
 
1045
                                                                return EncoderSession_finish_error(&encoder_session);
 
1046
                                                }
996
1047
                                                data_bytes = 0;
997
1048
                                        }
998
1049
                                }
1076
1127
                        got_data_chunk = true;
1077
1128
                }
1078
1129
                else {
1079
 
                        if(xx == 0x20746d66 && got_fmt_chunk) { /* "fmt " */
1080
 
                                flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'fmt ' sub-chunk\n", encoder_session.inbasefilename);
1081
 
                                if(encoder_session.treat_warnings_as_errors)
1082
 
                                        return EncoderSession_finish_error(&encoder_session);
1083
 
                        }
1084
 
                        else if(xx == 0x61746164) { /* "data" */
1085
 
                                if(got_data_chunk) {
1086
 
                                        flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'data' sub-chunk\n", encoder_session.inbasefilename);
1087
 
                                        if(encoder_session.treat_warnings_as_errors)
1088
 
                                                return EncoderSession_finish_error(&encoder_session);
1089
 
                                }
1090
 
                                else if(!got_fmt_chunk) {
1091
 
                                        flac__utils_printf(stderr, 1, "%s: ERROR: got 'data' sub-chunk before 'fmt' sub-chunk\n", encoder_session.inbasefilename);
1092
 
                                        return EncoderSession_finish_error(&encoder_session);
1093
 
                                }
1094
 
                                else {
1095
 
                                        FLAC__ASSERT(0);
1096
 
                                }
1097
 
                        }
1098
 
                        else {
1099
 
                                flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown sub-chunk '%c%c%c%c'\n", encoder_session.inbasefilename, (char)(xx&255), (char)((xx>>8)&255), (char)((xx>>16)&255), (char)(xx>>24));
1100
 
                                if(encoder_session.treat_warnings_as_errors)
1101
 
                                        return EncoderSession_finish_error(&encoder_session);
1102
 
                        }
 
1130
                        if(xx == 0x61746164 && !got_fmt_chunk) { /* "data" */
 
1131
                                flac__utils_printf(stderr, 1, "%s: ERROR: got 'data' sub-chunk before 'fmt' sub-chunk\n", encoder_session.inbasefilename);
 
1132
                                return EncoderSession_finish_error(&encoder_session);
 
1133
                        }
 
1134
 
 
1135
                        if(!options.foreign_metadata) {
 
1136
                                if(xx == 0x20746d66 && got_fmt_chunk) /* "fmt " */
 
1137
                                        flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'fmt ' sub-chunk (use --keep-foreign-metadata to keep)\n", encoder_session.inbasefilename);
 
1138
                                else if(xx == 0x61746164) /* "data" */
 
1139
                                        flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'data' sub-chunk (use --keep-foreign-metadata to keep)\n", encoder_session.inbasefilename);
 
1140
                                else
 
1141
                                        flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown sub-chunk '%c%c%c%c' (use --keep-foreign-metadata to keep)\n", encoder_session.inbasefilename, (char)(xx&255), (char)((xx>>8)&255), (char)((xx>>16)&255), (char)(xx>>24));
 
1142
                                if(encoder_session.treat_warnings_as_errors)
 
1143
                                        return EncoderSession_finish_error(&encoder_session);
 
1144
                        }
 
1145
 
1103
1146
                        /* sub-chunk size */
1104
1147
                        if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
1105
1148
                                return EncoderSession_finish_error(&encoder_session);
1108
1151
 
1109
1152
                                FLAC__ASSERT(skip<=LONG_MAX);
1110
1153
                                if(!fskip_ahead(infile, skip)) {
1111
 
                                        flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping unsupported sub-chunk\n", encoder_session.inbasefilename);
 
1154
                                        flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping over unsupported sub-chunk\n", encoder_session.inbasefilename);
1112
1155
                                        return EncoderSession_finish_error(&encoder_session);
1113
1156
                                }
1114
1157
                        }
1115
1158
                }
1116
1159
        }
1117
1160
 
1118
 
        return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
 
1161
        return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero, options.foreign_metadata);
1119
1162
}
1120
1163
 
1121
1164
int flac__encode_raw(FILE *infile, off_t infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, raw_encode_options_t options)
1216
1259
                }
1217
1260
        }
1218
1261
 
1219
 
        if(!EncoderSession_init_encoder(&encoder_session, options.common, /*channel_mask=*/0, options.channels, options.bps, options.sample_rate, /*flac_decoder_data=*/0))
 
1262
        if(!EncoderSession_init_encoder(&encoder_session, options.common, /*channel_mask=*/0, options.channels, options.bps, options.sample_rate, /*foreign_metadata=*/0, /*flac_decoder_data=*/0))
1220
1263
                return EncoderSession_finish_error(&encoder_session);
1221
1264
 
1222
1265
        /*
1383
1426
                }
1384
1427
        }
1385
1428
 
1386
 
        return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
 
1429
        return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero, /*foreign_metadata=*/0);
1387
1430
}
1388
1431
 
1389
1432
int flac__encode_flac(FILE *infile, off_t infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, flac_encode_options_t options, FLAC__bool input_is_ogg)
1499
1542
                encoder_session.unencoded_size = decoder_data.filesize;
1500
1543
 
1501
1544
                /* (channel mask will get copied over from the source VORBIS_COMMENT if it exists) */
1502
 
                if(!EncoderSession_init_encoder(&encoder_session, options.common, /*channel_mask=*/0, decoder_data.metadata_blocks[0]->data.stream_info.channels, decoder_data.metadata_blocks[0]->data.stream_info.bits_per_sample, decoder_data.metadata_blocks[0]->data.stream_info.sample_rate, &decoder_data))
 
1545
                if(!EncoderSession_init_encoder(&encoder_session, options.common, /*channel_mask=*/0, decoder_data.metadata_blocks[0]->data.stream_info.channels, decoder_data.metadata_blocks[0]->data.stream_info.bits_per_sample, decoder_data.metadata_blocks[0]->data.stream_info.sample_rate, /*foreign_metadata=*/0, &decoder_data))
1503
1546
                        goto fubar2; /*@@@ yuck */
1504
1547
 
1505
1548
                /*
1539
1582
        }
1540
1583
 
1541
1584
        FLAC__stream_decoder_delete(decoder);
1542
 
        retval = EncoderSession_finish_ok(&encoder_session, -1, -1);
 
1585
        retval = EncoderSession_finish_ok(&encoder_session, -1, -1, /*foreign_metadata=*/0);
1543
1586
        /* have to wail until encoder is completely finished before deleting because of the final step of writing the seekpoint offsets */
1544
1587
        for(i = 0; i < decoder_data.num_metadata_blocks; i++)
1545
1588
                FLAC__metadata_object_delete(decoder_data.metadata_blocks[i]);
1585
1628
        e->outputfile_opened = false;
1586
1629
 
1587
1630
        e->inbasefilename = grabbag__file_get_basename(infilename);
 
1631
        e->infilename = infilename;
1588
1632
        e->outfilename = outfilename;
1589
1633
 
1590
1634
        e->skip = 0; /* filled in later after the sample_rate is known */
1630
1674
        }
1631
1675
}
1632
1676
 
1633
 
int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero)
 
1677
int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero, foreign_metadata_t *foreign_metadata)
1634
1678
{
1635
1679
        FLAC__StreamEncoderState fse_state = FLAC__STREAM_ENCODER_OK;
1636
1680
        int ret = 0;
1665
1709
                }
1666
1710
        }
1667
1711
 
 
1712
        /*@@@@@@ should this go here or somewhere else? */
 
1713
        if(ret == 0 && foreign_metadata) {
 
1714
                const char *error;
 
1715
                if(!flac__foreign_metadata_write_to_flac(foreign_metadata, e->infilename, e->outfilename, &error)) {
 
1716
                        flac__utils_printf(stderr, 1, "%s: ERROR: updating foreign metadata in FLAC file: %s\n", e->inbasefilename, error);
 
1717
                        ret = 1;
 
1718
                }
 
1719
        }
 
1720
 
1668
1721
        EncoderSession_destroy(e);
1669
1722
 
1670
1723
        return ret;
1688
1741
        return 1;
1689
1742
}
1690
1743
 
1691
 
FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options, FLAC__uint32 channel_mask, unsigned channels, unsigned bps, unsigned sample_rate, FLACDecoderData *flac_decoder_data)
1692
 
{
1693
 
        unsigned num_metadata, i;
1694
 
        FLAC__StreamMetadata padding, *cuesheet = 0;
1695
 
        FLAC__StreamMetadata *static_metadata[4+64]; /* MAGIC +64 is for pictures metadata in options.pictures */
1696
 
        FLAC__StreamMetadata **metadata = static_metadata;
 
1744
typedef struct {
 
1745
        unsigned num_metadata;
 
1746
        FLAC__bool *needs_delete;
 
1747
        FLAC__StreamMetadata **metadata;
 
1748
        FLAC__StreamMetadata *cuesheet; /* always needs to be deleted */
 
1749
} static_metadata_t;
 
1750
 
 
1751
static void static_metadata_init(static_metadata_t *m)
 
1752
{
 
1753
        m->num_metadata = 0;
 
1754
        m->needs_delete = 0;
 
1755
        m->metadata = 0;
 
1756
        m->cuesheet = 0;
 
1757
}
 
1758
 
 
1759
static void static_metadata_clear(static_metadata_t *m)
 
1760
{
 
1761
        unsigned i;
 
1762
        for(i = 0; i < m->num_metadata; i++)
 
1763
                if(m->needs_delete[i])
 
1764
                        FLAC__metadata_object_delete(m->metadata[i]);
 
1765
        if(m->metadata)
 
1766
                free(m->metadata);
 
1767
        if(m->needs_delete)
 
1768
                free(m->needs_delete);
 
1769
        if(m->cuesheet)
 
1770
                FLAC__metadata_object_delete(m->cuesheet);
 
1771
        static_metadata_init(m);
 
1772
}
 
1773
 
 
1774
static FLAC__bool static_metadata_append(static_metadata_t *m, FLAC__StreamMetadata *d, FLAC__bool needs_delete)
 
1775
{
 
1776
        void *x;
 
1777
        if(0 == (x = safe_realloc_muladd2_(m->metadata, sizeof(*m->metadata), /*times (*/m->num_metadata, /*+*/1/*)*/)))
 
1778
                return false;
 
1779
        m->metadata = (FLAC__StreamMetadata**)x;
 
1780
        if(0 == (x = safe_realloc_muladd2_(m->needs_delete, sizeof(*m->needs_delete), /*times (*/m->num_metadata, /*+*/1/*)*/)))
 
1781
                return false;
 
1782
        m->needs_delete = (FLAC__bool*)x;
 
1783
        m->metadata[m->num_metadata] = d;
 
1784
        m->needs_delete[m->num_metadata] = needs_delete;
 
1785
        m->num_metadata++;
 
1786
        return true;
 
1787
}
 
1788
 
 
1789
FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options, FLAC__uint32 channel_mask, unsigned channels, unsigned bps, unsigned sample_rate, const foreign_metadata_t *foreign_metadata, FLACDecoderData *flac_decoder_data)
 
1790
{
 
1791
        FLAC__StreamMetadata padding;
 
1792
        FLAC__StreamMetadata **metadata = 0;
 
1793
        static_metadata_t static_metadata;
 
1794
        unsigned num_metadata = 0, i;
1697
1795
        FLAC__StreamEncoderInitStatus init_status;
1698
1796
        const FLAC__bool is_cdda = (channels == 1 || channels == 2) && (bps == 16) && (sample_rate == 44100);
1699
1797
        char apodizations[2000];
1700
1798
 
1701
1799
        FLAC__ASSERT(sizeof(options.pictures)/sizeof(options.pictures[0]) <= 64);
1702
1800
 
 
1801
        static_metadata_init(&static_metadata);
 
1802
 
1703
1803
        e->replay_gain = options.replay_gain;
1704
1804
        e->channels = channels;
1705
1805
        e->bits_per_sample = bps;
1724
1824
                }
1725
1825
        }
1726
1826
 
1727
 
        if(!parse_cuesheet(&cuesheet, options.cuesheet_filename, e->inbasefilename, is_cdda, e->total_samples_to_encode, e->treat_warnings_as_errors))
 
1827
        if(!parse_cuesheet(&static_metadata.cuesheet, options.cuesheet_filename, e->inbasefilename, is_cdda, e->total_samples_to_encode, e->treat_warnings_as_errors))
1728
1828
                return false;
1729
1829
 
1730
 
        if(!convert_to_seek_table_template(options.requested_seek_points, options.num_requested_seek_points, options.cued_seekpoints? cuesheet : 0, e)) {
 
1830
        if(!convert_to_seek_table_template(options.requested_seek_points, options.num_requested_seek_points, options.cued_seekpoints? static_metadata.cuesheet : 0, e)) {
1731
1831
                flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for seek table\n", e->inbasefilename);
1732
 
                if(0 != cuesheet)
1733
 
                        FLAC__metadata_object_delete(cuesheet);
 
1832
                static_metadata_clear(&static_metadata);
1734
1833
                return false;
1735
1834
        }
1736
1835
 
 
1836
        /* build metadata */
1737
1837
        if(flac_decoder_data) {
1738
1838
                /*
1739
1839
                 * we're encoding from FLAC so we will use the FLAC file's
1748
1848
                                FLAC__StreamMetadata *pic = FLAC__metadata_object_clone(options.pictures[i]);
1749
1849
                                if(0 == pic) {
1750
1850
                                        flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for PICTURE block\n", e->inbasefilename);
1751
 
                                        if(0 != cuesheet)
1752
 
                                                FLAC__metadata_object_delete(cuesheet);
 
1851
                                        static_metadata_clear(&static_metadata);
1753
1852
                                        return false;
1754
1853
                                }
1755
1854
                                flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks++] = pic;
1773
1872
                                        (void) flac__utils_get_channel_mask_tag(flac_decoder_data->metadata_blocks[i], &channel_mask);
1774
1873
                                        flac__utils_printf(stderr, 1, "%s: WARNING, replacing tags from input FLAC file with those given on the command-line\n", e->inbasefilename);
1775
1874
                                        if(e->treat_warnings_as_errors) {
1776
 
                                                if(0 != cuesheet)
1777
 
                                                        FLAC__metadata_object_delete(cuesheet);
 
1875
                                                static_metadata_clear(&static_metadata);
1778
1876
                                                return false;
1779
1877
                                        }
1780
1878
                                        FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
1789
1887
                                FLAC__StreamMetadata *vc = FLAC__metadata_object_clone(options.vorbis_comment);
1790
1888
                                if(0 == vc || (channel_mask && !flac__utils_set_channel_mask_tag(vc, channel_mask))) {
1791
1889
                                        flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for VORBIS_COMMENT block\n", e->inbasefilename);
1792
 
                                        if(0 != cuesheet)
1793
 
                                                FLAC__metadata_object_delete(cuesheet);
 
1890
                                        static_metadata_clear(&static_metadata);
1794
1891
                                        return false;
1795
1892
                                }
1796
1893
                                for(i = flac_decoder_data->num_metadata_blocks; i > 1; i--)
1809
1906
                        for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
1810
1907
                                FLAC__bool existing_cuesheet_is_bad = false;
1811
1908
                                /* check if existing cuesheet matches the input audio */
1812
 
                                if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_CUESHEET && 0 == cuesheet) {
 
1909
                                if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_CUESHEET && 0 == static_metadata.cuesheet) {
1813
1910
                                        const FLAC__StreamMetadata_CueSheet *cs = &flac_decoder_data->metadata_blocks[i]->data.cue_sheet;
1814
1911
                                        if(e->total_samples_to_encode == 0) {
1815
1912
                                                flac__utils_printf(stderr, 1, "%s: WARNING, cuesheet in input FLAC file cannot be kept if input size is not known, dropping it...\n", e->inbasefilename);
1816
1913
                                                if(e->treat_warnings_as_errors) {
1817
 
                                                        if(0 != cuesheet)
1818
 
                                                                FLAC__metadata_object_delete(cuesheet);
 
1914
                                                        static_metadata_clear(&static_metadata);
1819
1915
                                                        return false;
1820
1916
                                                }
1821
1917
                                                existing_cuesheet_is_bad = true;
1823
1919
                                        else if(e->total_samples_to_encode != cs->tracks[cs->num_tracks-1].offset) {
1824
1920
                                                flac__utils_printf(stderr, 1, "%s: WARNING, lead-out offset of cuesheet in input FLAC file does not match input length, dropping existing cuesheet...\n", e->inbasefilename);
1825
1921
                                                if(e->treat_warnings_as_errors) {
1826
 
                                                        if(0 != cuesheet)
1827
 
                                                                FLAC__metadata_object_delete(cuesheet);
 
1922
                                                        static_metadata_clear(&static_metadata);
1828
1923
                                                        return false;
1829
1924
                                                }
1830
1925
                                                existing_cuesheet_is_bad = true;
1831
1926
                                        }
1832
1927
                                }
1833
 
                                if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_CUESHEET && (existing_cuesheet_is_bad || 0 != cuesheet)) {
1834
 
                                        if(0 != cuesheet) {
 
1928
                                if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_CUESHEET && (existing_cuesheet_is_bad || 0 != static_metadata.cuesheet)) {
 
1929
                                        if(0 != static_metadata.cuesheet) {
1835
1930
                                                flac__utils_printf(stderr, 1, "%s: WARNING, replacing cuesheet in input FLAC file with the one given on the command-line\n", e->inbasefilename);
1836
1931
                                                if(e->treat_warnings_as_errors) {
1837
 
                                                        FLAC__metadata_object_delete(cuesheet);
 
1932
                                                        static_metadata_clear(&static_metadata);
1838
1933
                                                        return false;
1839
1934
                                                }
1840
1935
                                        }
1845
1940
                                        flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
1846
1941
                        }
1847
1942
                        flac_decoder_data->num_metadata_blocks = j;
1848
 
                        if(0 != cuesheet && flac_decoder_data->num_metadata_blocks < sizeof(flac_decoder_data->metadata_blocks)/sizeof(flac_decoder_data->metadata_blocks[0])) {
 
1943
                        if(0 != static_metadata.cuesheet && flac_decoder_data->num_metadata_blocks < sizeof(flac_decoder_data->metadata_blocks)/sizeof(flac_decoder_data->metadata_blocks[0])) {
1849
1944
                                /* prepend ours */
1850
 
                                FLAC__StreamMetadata *cs = FLAC__metadata_object_clone(cuesheet);
 
1945
                                FLAC__StreamMetadata *cs = FLAC__metadata_object_clone(static_metadata.cuesheet);
1851
1946
                                if(0 == cs) {
1852
1947
                                        flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for CUESHEET block\n", e->inbasefilename);
1853
 
                                        if(0 != cuesheet)
1854
 
                                                FLAC__metadata_object_delete(cuesheet);
 
1948
                                        static_metadata_clear(&static_metadata);
1855
1949
                                        return false;
1856
1950
                                }
1857
1951
                                for(i = flac_decoder_data->num_metadata_blocks; i > 1; i--)
1882
1976
                                        if(options.num_requested_seek_points > 0) {
1883
1977
                                                flac__utils_printf(stderr, 1, "%s: WARNING, replacing seektable in input FLAC file with the one given on the command-line\n", e->inbasefilename);
1884
1978
                                                if(e->treat_warnings_as_errors) {
1885
 
                                                        if(0 != cuesheet)
1886
 
                                                                FLAC__metadata_object_delete(cuesheet);
 
1979
                                                        static_metadata_clear(&static_metadata);
1887
1980
                                                        return false;
1888
1981
                                                }
1889
1982
                                        }
1892
1985
                                        else {
1893
1986
                                                flac__utils_printf(stderr, 1, "%s: WARNING, can't use existing seektable in input FLAC since the input size is changing or unknown, dropping existing SEEKTABLE block...\n", e->inbasefilename);
1894
1987
                                                if(e->treat_warnings_as_errors) {
1895
 
                                                        if(0 != cuesheet)
1896
 
                                                                FLAC__metadata_object_delete(cuesheet);
 
1988
                                                        static_metadata_clear(&static_metadata);
1897
1989
                                                        return false;
1898
1990
                                                }
1899
1991
                                        }
1910
2002
                                FLAC__StreamMetadata *st = FLAC__metadata_object_clone(e->seek_table_template);
1911
2003
                                if(0 == st) {
1912
2004
                                        flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for SEEKTABLE block\n", e->inbasefilename);
1913
 
                                        if(0 != cuesheet)
1914
 
                                                FLAC__metadata_object_delete(cuesheet);
 
2005
                                        static_metadata_clear(&static_metadata);
1915
2006
                                        return false;
1916
2007
                                }
1917
2008
                                for(i = flac_decoder_data->num_metadata_blocks; i > 1; i--)
1952
2043
                                        flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING);
1953
2044
                                        if(0 == flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks]) {
1954
2045
                                                flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for PADDING block\n", e->inbasefilename);
1955
 
                                                if(0 != cuesheet)
1956
 
                                                        FLAC__metadata_object_delete(cuesheet);
 
2046
                                                static_metadata_clear(&static_metadata);
1957
2047
                                                return false;
1958
2048
                                        }
1959
2049
                                        flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks]->is_last = false; /* the encoder will set this for us */
1970
2060
                 * we're not encoding from FLAC so we will build the metadata
1971
2061
                 * from scratch
1972
2062
                 */
1973
 
                num_metadata = 0;
1974
2063
                if(e->seek_table_template->data.seek_table.num_points > 0) {
1975
2064
                        e->seek_table_template->is_last = false; /* the encoder will set this for us */
1976
 
                        metadata[num_metadata++] = e->seek_table_template;
 
2065
                        static_metadata_append(&static_metadata, e->seek_table_template, /*needs_delete=*/false);
1977
2066
                }
1978
 
                if(0 != cuesheet)
1979
 
                        metadata[num_metadata++] = cuesheet;
 
2067
                if(0 != static_metadata.cuesheet)
 
2068
                        static_metadata_append(&static_metadata, static_metadata.cuesheet, /*needs_delete=*/false);
1980
2069
                if(channel_mask) {
1981
2070
                        if(!flac__utils_set_channel_mask_tag(options.vorbis_comment, channel_mask)) {
1982
2071
                                flac__utils_printf(stderr, 1, "%s: ERROR adding channel mask tag\n", e->inbasefilename);
1983
 
                                if(0 != cuesheet)
1984
 
                                        FLAC__metadata_object_delete(cuesheet);
 
2072
                                static_metadata_clear(&static_metadata);
1985
2073
                                return false;
1986
2074
                        }
1987
2075
                }
1988
 
                metadata[num_metadata++] = options.vorbis_comment;
 
2076
                static_metadata_append(&static_metadata, options.vorbis_comment, /*needs_delete=*/false);
1989
2077
                for(i = 0; i < options.num_pictures; i++)
1990
 
                        metadata[num_metadata++] = options.pictures[i];
 
2078
                        static_metadata_append(&static_metadata, options.pictures[i], /*needs_delete=*/false);
 
2079
                if(foreign_metadata) {
 
2080
                        for(i = 0; i < foreign_metadata->num_blocks; i++) {
 
2081
                                FLAC__StreamMetadata *p = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING);
 
2082
                                if(!p) {
 
2083
                                        flac__utils_printf(stderr, 1, "%s: ERROR: out of memory\n", e->inbasefilename);
 
2084
                                        static_metadata_clear(&static_metadata);
 
2085
                                        return false;
 
2086
                                }
 
2087
                                static_metadata_append(&static_metadata, p, /*needs_delete=*/true);
 
2088
                                static_metadata.metadata[static_metadata.num_metadata-1]->length = FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8 + foreign_metadata->blocks[i].size;
 
2089
/*fprintf(stderr,"@@@@@@ add PADDING=%u\n",static_metadata.metadata[static_metadata.num_metadata-1]->length);*/
 
2090
                        }
 
2091
                }
1991
2092
                if(options.padding != 0) {
1992
2093
                        padding.is_last = false; /* the encoder will set this for us */
1993
2094
                        padding.type = FLAC__METADATA_TYPE_PADDING;
1994
2095
                        padding.length = (unsigned)(options.padding>0? options.padding : (e->total_samples_to_encode / e->sample_rate < 20*60? FLAC_ENCODE__DEFAULT_PADDING : FLAC_ENCODE__DEFAULT_PADDING*8));
1995
 
                        metadata[num_metadata++] = &padding;
 
2096
                        static_metadata_append(&static_metadata, &padding, /*needs_delete=*/false);
1996
2097
                }
 
2098
                metadata = static_metadata.metadata;
 
2099
                num_metadata = static_metadata.num_metadata;
1997
2100
        }
1998
2101
 
1999
2102
        /* check for a few things that have not already been checked.  the
2002
2105
         * up front to give a better error message.
2003
2106
         */
2004
2107
        if(!verify_metadata(e, metadata, num_metadata)) {
2005
 
                if(0 != cuesheet)
2006
 
                        FLAC__metadata_object_delete(cuesheet);
 
2108
                static_metadata_clear(&static_metadata);
2007
2109
                return false;
2008
2110
        }
2009
2111
 
2030
2132
                        case CST_APODIZATION:
2031
2133
                                if(strlen(apodizations)+strlen(options.compression_settings[i].value.t_string)+2 >= sizeof(apodizations)) {
2032
2134
                                        flac__utils_printf(stderr, 1, "%s: ERROR: too many apodization functions requested\n", e->inbasefilename);
2033
 
                                        if(0 != cuesheet)
2034
 
                                                FLAC__metadata_object_delete(cuesheet);
 
2135
                                        static_metadata_clear(&static_metadata);
2035
2136
                                        return false;
2036
2137
                                }
2037
2138
                                else {
2073
2174
        FLAC__stream_encoder_disable_constant_subframes(e->encoder, options.debug.disable_constant_subframes);
2074
2175
        FLAC__stream_encoder_disable_fixed_subframes(e->encoder, options.debug.disable_fixed_subframes);
2075
2176
        FLAC__stream_encoder_disable_verbatim_subframes(e->encoder, options.debug.disable_verbatim_subframes);
 
2177
        if(!options.debug.do_md5) {
 
2178
                flac__utils_printf(stderr, 1, "%s: WARNING, MD5 computation disabled, resulting file will not have MD5 sum\n", e->inbasefilename);
 
2179
                if(e->treat_warnings_as_errors) {
 
2180
                        static_metadata_clear(&static_metadata);
 
2181
                        return false;
 
2182
                }
 
2183
                FLAC__stream_encoder_set_do_md5(e->encoder, false);
 
2184
        }
2076
2185
 
2077
2186
#if FLAC__HAS_OGG
2078
2187
        if(e->use_ogg) {
2090
2199
                print_error_with_init_status(e, "ERROR initializing encoder", init_status);
2091
2200
                if(FLAC__stream_encoder_get_state(e->encoder) != FLAC__STREAM_ENCODER_IO_ERROR)
2092
2201
                        e->outputfile_opened = true;
2093
 
                if(0 != cuesheet)
2094
 
                        FLAC__metadata_object_delete(cuesheet);
 
2202
                static_metadata_clear(&static_metadata);
2095
2203
                return false;
2096
2204
        }
2097
2205
        else
2102
2210
                (FLAC__stream_encoder_get_do_exhaustive_model_search(e->encoder) || FLAC__stream_encoder_get_do_qlp_coeff_prec_search(e->encoder))? 0x0f :
2103
2211
                0x3f;
2104
2212
 
2105
 
        if(0 != cuesheet)
2106
 
                FLAC__metadata_object_delete(cuesheet);
 
2213
        static_metadata_clear(&static_metadata);
2107
2214
 
2108
2215
        return true;
2109
2216
}
2130
2237
                return true;
2131
2238
 
2132
2239
        if(num_requested_seek_points < 0) {
2133
 
                requested_seek_points = "10s;";
 
2240
#if FLAC__HAS_OGG
 
2241
                /*@@@@@@ workaround ogg bug: too many seekpoints makes table not fit in one page */
 
2242
                if(e->use_ogg && e->total_samples_to_encode > 0 && e->total_samples_to_encode / e->sample_rate / 10 > 230)
 
2243
                        requested_seek_points = "230x;";
 
2244
                else 
 
2245
#endif
 
2246
                        requested_seek_points = "10s;";
2134
2247
                num_requested_seek_points = 1;
2135
2248
        }
2136
2249
 
2540
2653
        const double ratio = (double)encoder_session->bytes_written / ((double)encoder_session->unencoded_size * min(1.0, progress));
2541
2654
#endif
2542
2655
 
 
2656
        FLAC__ASSERT(encoder_session->total_samples_to_encode > 0);
 
2657
 
2543
2658
        if(samples_written == encoder_session->total_samples_to_encode) {
2544
2659
                flac__utils_printf(stderr, 2, "\r%s:%s wrote %u bytes, ratio=%0.3f",
2545
2660
                        encoder_session->inbasefilename,
2766
2881
{
2767
2882
        static unsigned char dump[8192];
2768
2883
 
2769
 
        while(offset > 0) {
2770
 
                long need = (long)min(offset, LONG_MAX);
2771
 
                if(fseeko(f, need, SEEK_CUR) < 0) {
2772
 
                        need = (long)min(offset, sizeof(dump));
 
2884
#ifdef _MSC_VER
 
2885
        if(f == stdin) {
 
2886
                /* MS' stdio impl can't even seek forward on stdin, have to use pure non-fseek() version: */
 
2887
                while(offset > 0) {
 
2888
                        const long need = (long)min(offset, sizeof(dump));
2773
2889
                        if((long)fread(dump, 1, need, f) < need)
2774
2890
                                return false;
 
2891
                        offset -= need;
2775
2892
                }
2776
 
                offset -= need;
2777
 
        }
2778
 
#if 0 /* pure non-fseek() version */
2779
 
        while(offset > 0) {
2780
 
                const long need = (long)min(offset, sizeof(dump));
2781
 
                if(fread(dump, 1, need, f) < need)
2782
 
                        return false;
2783
 
                offset -= need;
2784
 
        }
 
2893
        }
 
2894
        else
2785
2895
#endif
 
2896
        {
 
2897
                while(offset > 0) {
 
2898
                        long need = (long)min(offset, LONG_MAX);
 
2899
                        if(fseeko(f, need, SEEK_CUR) < 0) {
 
2900
                                need = (long)min(offset, sizeof(dump));
 
2901
                                if((long)fread(dump, 1, need, f) < need)
 
2902
                                        return false;
 
2903
                        }
 
2904
                        offset -= need;
 
2905
                }
 
2906
        }
2786
2907
        return true;
2787
2908
}
2788
2909
 
2797
2918
        return count;
2798
2919
}
2799
2920
 
 
2921
#if 0
2800
2922
FLAC__uint32 limit_channel_mask(FLAC__uint32 mask, unsigned channels)
2801
2923
{
2802
2924
        FLAC__uint32 x = 0x80000000;
2811
2933
        FLAC__ASSERT(count_channel_mask_bits(mask) == channels);
2812
2934
        return mask;
2813
2935
}
 
2936
#endif