bump version number to 1.1.3
[flac.git] / src / libFLAC / file_encoder.c
1 /* libFLAC - Free Lossless Audio Codec library
2  * Copyright (C) 2002,2003,2004,2005,2006  Josh Coalson
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * - Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * - Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * - Neither the name of the Xiph.org Foundation nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #if HAVE_CONFIG_H
33 #  include <config.h>
34 #endif
35
36 #include <stdio.h>
37 #include <stdlib.h> /* for malloc() */
38 #include <string.h> /* for strlen(), strcpy() */
39 #if defined _MSC_VER || defined __MINGW32__
40 #include <sys/types.h> /* for off_t */
41 //@@@ [2G limit] hacks for MSVC6
42 #define fseeko fseek
43 #define ftello ftell
44 #endif
45 #include "FLAC/assert.h"
46 #include "protected/file_encoder.h"
47
48 #ifdef max
49 #undef max
50 #endif
51 #define max(x,y) ((x)>(y)?(x):(y))
52
53 /***********************************************************************
54  *
55  * Private class method prototypes
56  *
57  ***********************************************************************/
58
59 /* unpublished debug routines */
60 extern FLAC__bool FLAC__seekable_stream_encoder_disable_constant_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value);
61 extern FLAC__bool FLAC__seekable_stream_encoder_disable_fixed_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value);
62 extern FLAC__bool FLAC__seekable_stream_encoder_disable_verbatim_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value);
63
64 static void set_defaults_(FLAC__FileEncoder *encoder);
65 static FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data);
66 static FLAC__SeekableStreamEncoderTellStatus tell_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
67 static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
68
69 /***********************************************************************
70  *
71  * Private class data
72  *
73  ***********************************************************************/
74
75 typedef struct FLAC__FileEncoderPrivate {
76         FLAC__FileEncoderProgressCallback progress_callback;
77         void *client_data;
78         char *filename;
79         FLAC__uint64 bytes_written;
80         FLAC__uint64 samples_written;
81         unsigned frames_written;
82         unsigned total_frames_estimate;
83         FLAC__SeekableStreamEncoder *seekable_stream_encoder;
84         FILE *file;
85 } FLAC__FileEncoderPrivate;
86
87 /***********************************************************************
88  *
89  * Public static class data
90  *
91  ***********************************************************************/
92
93 FLAC_API const char * const FLAC__FileEncoderStateString[] = {
94         "FLAC__FILE_ENCODER_OK",
95         "FLAC__FILE_ENCODER_NO_FILENAME",
96         "FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR",
97         "FLAC__FILE_ENCODER_FATAL_ERROR_WHILE_WRITING",
98         "FLAC__FILE_ENCODER_ERROR_OPENING_FILE",
99         "FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR",
100         "FLAC__FILE_ENCODER_ALREADY_INITIALIZED",
101         "FLAC__FILE_ENCODER_UNINITIALIZED"
102 };
103
104
105 /***********************************************************************
106  *
107  * Class constructor/destructor
108  *
109  ***********************************************************************/
110
111 FLAC_API FLAC__FileEncoder *FLAC__file_encoder_new()
112 {
113         FLAC__FileEncoder *encoder;
114
115         FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
116
117         encoder = (FLAC__FileEncoder*)calloc(1, sizeof(FLAC__FileEncoder));
118         if(encoder == 0) {
119                 return 0;
120         }
121
122         encoder->protected_ = (FLAC__FileEncoderProtected*)calloc(1, sizeof(FLAC__FileEncoderProtected));
123         if(encoder->protected_ == 0) {
124                 free(encoder);
125                 return 0;
126         }
127
128         encoder->private_ = (FLAC__FileEncoderPrivate*)calloc(1, sizeof(FLAC__FileEncoderPrivate));
129         if(encoder->private_ == 0) {
130                 free(encoder->protected_);
131                 free(encoder);
132                 return 0;
133         }
134
135         encoder->private_->seekable_stream_encoder = FLAC__seekable_stream_encoder_new();
136         if(0 == encoder->private_->seekable_stream_encoder) {
137                 free(encoder->private_);
138                 free(encoder->protected_);
139                 free(encoder);
140                 return 0;
141         }
142
143         encoder->private_->file = 0;
144
145         set_defaults_(encoder);
146
147         encoder->protected_->state = FLAC__FILE_ENCODER_UNINITIALIZED;
148
149         return encoder;
150 }
151
152 FLAC_API void FLAC__file_encoder_delete(FLAC__FileEncoder *encoder)
153 {
154         FLAC__ASSERT(0 != encoder);
155         FLAC__ASSERT(0 != encoder->protected_);
156         FLAC__ASSERT(0 != encoder->private_);
157         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
158
159         (void)FLAC__file_encoder_finish(encoder);
160
161         FLAC__seekable_stream_encoder_delete(encoder->private_->seekable_stream_encoder);
162
163         free(encoder->private_);
164         free(encoder->protected_);
165         free(encoder);
166 }
167
168 /***********************************************************************
169  *
170  * Public class methods
171  *
172  ***********************************************************************/
173
174 FLAC_API FLAC__FileEncoderState FLAC__file_encoder_init(FLAC__FileEncoder *encoder)
175 {
176         FLAC__ASSERT(0 != encoder);
177
178         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
179                 return encoder->protected_->state = FLAC__FILE_ENCODER_ALREADY_INITIALIZED;
180
181         if(0 == encoder->private_->filename)
182                 return encoder->protected_->state = FLAC__FILE_ENCODER_NO_FILENAME;
183
184         encoder->private_->file = fopen(encoder->private_->filename, "w+b");
185
186         if(encoder->private_->file == 0)
187                 return encoder->protected_->state = FLAC__FILE_ENCODER_ERROR_OPENING_FILE;
188
189         encoder->private_->bytes_written = 0;
190         encoder->private_->samples_written = 0;
191         encoder->private_->frames_written = 0;
192
193         FLAC__seekable_stream_encoder_set_seek_callback(encoder->private_->seekable_stream_encoder, seek_callback_);
194         FLAC__seekable_stream_encoder_set_tell_callback(encoder->private_->seekable_stream_encoder, tell_callback_);
195         FLAC__seekable_stream_encoder_set_write_callback(encoder->private_->seekable_stream_encoder, write_callback_);
196         FLAC__seekable_stream_encoder_set_client_data(encoder->private_->seekable_stream_encoder, encoder);
197
198         if(FLAC__seekable_stream_encoder_init(encoder->private_->seekable_stream_encoder) != FLAC__SEEKABLE_STREAM_ENCODER_OK)
199                 return encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
200
201         {
202                 unsigned blocksize = FLAC__file_encoder_get_blocksize(encoder);
203
204                 FLAC__ASSERT(blocksize != 0);
205                 encoder->private_->total_frames_estimate = (unsigned)((FLAC__file_encoder_get_total_samples_estimate(encoder) + blocksize - 1) / blocksize);
206         }
207
208         return encoder->protected_->state = FLAC__FILE_ENCODER_OK;
209 }
210
211 FLAC_API void FLAC__file_encoder_finish(FLAC__FileEncoder *encoder)
212 {
213         FLAC__ASSERT(0 != encoder);
214
215         if(encoder->protected_->state == FLAC__FILE_ENCODER_UNINITIALIZED)
216                 return;
217
218         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
219
220         /* FLAC__seekable_stream_encoder_finish() might write data so we must close the file after it. */
221
222         FLAC__seekable_stream_encoder_finish(encoder->private_->seekable_stream_encoder);
223
224         if(0 != encoder->private_->file) {
225                 fclose(encoder->private_->file);
226                 encoder->private_->file = 0;
227         }
228
229         if(0 != encoder->private_->filename) {
230                 free(encoder->private_->filename);
231                 encoder->private_->filename = 0;
232         }
233
234         set_defaults_(encoder);
235
236         encoder->protected_->state = FLAC__FILE_ENCODER_UNINITIALIZED;
237 }
238
239 FLAC_API FLAC__bool FLAC__file_encoder_set_verify(FLAC__FileEncoder *encoder, FLAC__bool value)
240 {
241         FLAC__ASSERT(0 != encoder);
242         FLAC__ASSERT(0 != encoder->private_);
243         FLAC__ASSERT(0 != encoder->protected_);
244         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
245         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
246                 return false;
247         return FLAC__seekable_stream_encoder_set_verify(encoder->private_->seekable_stream_encoder, value);
248 }
249
250 FLAC_API FLAC__bool FLAC__file_encoder_set_streamable_subset(FLAC__FileEncoder *encoder, FLAC__bool value)
251 {
252         FLAC__ASSERT(0 != encoder);
253         FLAC__ASSERT(0 != encoder->private_);
254         FLAC__ASSERT(0 != encoder->protected_);
255         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
256         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
257                 return false;
258         return FLAC__seekable_stream_encoder_set_streamable_subset(encoder->private_->seekable_stream_encoder, value);
259 }
260
261 FLAC_API FLAC__bool FLAC__file_encoder_set_do_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value)
262 {
263         FLAC__ASSERT(0 != encoder);
264         FLAC__ASSERT(0 != encoder->private_);
265         FLAC__ASSERT(0 != encoder->protected_);
266         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
267         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
268                 return false;
269         return FLAC__seekable_stream_encoder_set_do_mid_side_stereo(encoder->private_->seekable_stream_encoder, value);
270 }
271
272 FLAC_API FLAC__bool FLAC__file_encoder_set_loose_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value)
273 {
274         FLAC__ASSERT(0 != encoder);
275         FLAC__ASSERT(0 != encoder->private_);
276         FLAC__ASSERT(0 != encoder->protected_);
277         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
278         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
279                 return false;
280         return FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder, value);
281 }
282
283 FLAC_API FLAC__bool FLAC__file_encoder_set_channels(FLAC__FileEncoder *encoder, unsigned value)
284 {
285         FLAC__ASSERT(0 != encoder);
286         FLAC__ASSERT(0 != encoder->private_);
287         FLAC__ASSERT(0 != encoder->protected_);
288         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
289         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
290                 return false;
291         return FLAC__seekable_stream_encoder_set_channels(encoder->private_->seekable_stream_encoder, value);
292 }
293
294 FLAC_API FLAC__bool FLAC__file_encoder_set_bits_per_sample(FLAC__FileEncoder *encoder, unsigned value)
295 {
296         FLAC__ASSERT(0 != encoder);
297         FLAC__ASSERT(0 != encoder->private_);
298         FLAC__ASSERT(0 != encoder->protected_);
299         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
300         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
301                 return false;
302         return FLAC__seekable_stream_encoder_set_bits_per_sample(encoder->private_->seekable_stream_encoder, value);
303 }
304
305 FLAC_API FLAC__bool FLAC__file_encoder_set_sample_rate(FLAC__FileEncoder *encoder, unsigned value)
306 {
307         FLAC__ASSERT(0 != encoder);
308         FLAC__ASSERT(0 != encoder->private_);
309         FLAC__ASSERT(0 != encoder->protected_);
310         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
311         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
312                 return false;
313         return FLAC__seekable_stream_encoder_set_sample_rate(encoder->private_->seekable_stream_encoder, value);
314 }
315
316 FLAC_API FLAC__bool FLAC__file_encoder_set_blocksize(FLAC__FileEncoder *encoder, unsigned value)
317 {
318         FLAC__ASSERT(0 != encoder);
319         FLAC__ASSERT(0 != encoder->private_);
320         FLAC__ASSERT(0 != encoder->protected_);
321         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
322         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
323                 return false;
324         return FLAC__seekable_stream_encoder_set_blocksize(encoder->private_->seekable_stream_encoder, value);
325 }
326
327 FLAC_API FLAC__bool FLAC__file_encoder_set_apodization(FLAC__FileEncoder *encoder, const char *specification)
328 {
329         FLAC__ASSERT(0 != encoder);
330         FLAC__ASSERT(0 != encoder->private_);
331         FLAC__ASSERT(0 != encoder->protected_);
332         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
333         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
334                 return false;
335         return FLAC__seekable_stream_encoder_set_apodization(encoder->private_->seekable_stream_encoder, specification);
336 }
337
338 FLAC_API FLAC__bool FLAC__file_encoder_set_max_lpc_order(FLAC__FileEncoder *encoder, unsigned value)
339 {
340         FLAC__ASSERT(0 != encoder);
341         FLAC__ASSERT(0 != encoder->private_);
342         FLAC__ASSERT(0 != encoder->protected_);
343         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
344         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
345                 return false;
346         return FLAC__seekable_stream_encoder_set_max_lpc_order(encoder->private_->seekable_stream_encoder, value);
347 }
348
349 FLAC_API FLAC__bool FLAC__file_encoder_set_qlp_coeff_precision(FLAC__FileEncoder *encoder, unsigned value)
350 {
351         FLAC__ASSERT(0 != encoder);
352         FLAC__ASSERT(0 != encoder->private_);
353         FLAC__ASSERT(0 != encoder->protected_);
354         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
355         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
356                 return false;
357         return FLAC__seekable_stream_encoder_set_qlp_coeff_precision(encoder->private_->seekable_stream_encoder, value);
358 }
359
360 FLAC_API FLAC__bool FLAC__file_encoder_set_do_qlp_coeff_prec_search(FLAC__FileEncoder *encoder, FLAC__bool value)
361 {
362         FLAC__ASSERT(0 != encoder);
363         FLAC__ASSERT(0 != encoder->private_);
364         FLAC__ASSERT(0 != encoder->protected_);
365         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
366         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
367                 return false;
368         return FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder, value);
369 }
370
371 FLAC_API FLAC__bool FLAC__file_encoder_set_do_escape_coding(FLAC__FileEncoder *encoder, FLAC__bool value)
372 {
373         FLAC__ASSERT(0 != encoder);
374         FLAC__ASSERT(0 != encoder->private_);
375         FLAC__ASSERT(0 != encoder->protected_);
376         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
377         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
378                 return false;
379         return FLAC__seekable_stream_encoder_set_do_escape_coding(encoder->private_->seekable_stream_encoder, value);
380 }
381
382 FLAC_API FLAC__bool FLAC__file_encoder_set_do_exhaustive_model_search(FLAC__FileEncoder *encoder, FLAC__bool value)
383 {
384         FLAC__ASSERT(0 != encoder);
385         FLAC__ASSERT(0 != encoder->private_);
386         FLAC__ASSERT(0 != encoder->protected_);
387         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
388         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
389                 return false;
390         return FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder, value);
391 }
392
393 FLAC_API FLAC__bool FLAC__file_encoder_set_min_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value)
394 {
395         FLAC__ASSERT(0 != encoder);
396         FLAC__ASSERT(0 != encoder->private_);
397         FLAC__ASSERT(0 != encoder->protected_);
398         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
399         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
400                 return false;
401         return FLAC__seekable_stream_encoder_set_min_residual_partition_order(encoder->private_->seekable_stream_encoder, value);
402 }
403
404 FLAC_API FLAC__bool FLAC__file_encoder_set_max_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value)
405 {
406         FLAC__ASSERT(0 != encoder);
407         FLAC__ASSERT(0 != encoder->private_);
408         FLAC__ASSERT(0 != encoder->protected_);
409         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
410         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
411                 return false;
412         return FLAC__seekable_stream_encoder_set_max_residual_partition_order(encoder->private_->seekable_stream_encoder, value);
413 }
414
415 FLAC_API FLAC__bool FLAC__file_encoder_set_rice_parameter_search_dist(FLAC__FileEncoder *encoder, unsigned value)
416 {
417         FLAC__ASSERT(0 != encoder);
418         FLAC__ASSERT(0 != encoder->private_);
419         FLAC__ASSERT(0 != encoder->protected_);
420         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
421         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
422                 return false;
423         return FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder, value);
424 }
425
426 FLAC_API FLAC__bool FLAC__file_encoder_set_total_samples_estimate(FLAC__FileEncoder *encoder, FLAC__uint64 value)
427 {
428         FLAC__ASSERT(0 != encoder);
429         FLAC__ASSERT(0 != encoder->private_);
430         FLAC__ASSERT(0 != encoder->protected_);
431         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
432         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
433                 return false;
434         return FLAC__seekable_stream_encoder_set_total_samples_estimate(encoder->private_->seekable_stream_encoder, value);
435 }
436
437 FLAC_API FLAC__bool FLAC__file_encoder_set_metadata(FLAC__FileEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
438 {
439         FLAC__ASSERT(0 != encoder);
440         FLAC__ASSERT(0 != encoder->private_);
441         FLAC__ASSERT(0 != encoder->protected_);
442         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
443         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
444                 return false;
445         return FLAC__seekable_stream_encoder_set_metadata(encoder->private_->seekable_stream_encoder, metadata, num_blocks);
446 }
447
448 FLAC_API FLAC__bool FLAC__file_encoder_set_filename(FLAC__FileEncoder *encoder, const char *value)
449 {
450         FLAC__ASSERT(0 != encoder);
451         FLAC__ASSERT(0 != encoder->private_);
452         FLAC__ASSERT(0 != encoder->protected_);
453         FLAC__ASSERT(0 != value);
454         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
455                 return false;
456         if(0 != encoder->private_->filename) {
457                 free(encoder->private_->filename);
458                 encoder->private_->filename = 0;
459         }
460         if(0 == (encoder->private_->filename = (char*)malloc(strlen(value)+1))) {
461                 encoder->protected_->state = FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR;
462                 return false;
463         }
464         strcpy(encoder->private_->filename, value);
465         return true;
466 }
467
468 FLAC_API FLAC__bool FLAC__file_encoder_set_progress_callback(FLAC__FileEncoder *encoder, FLAC__FileEncoderProgressCallback value)
469 {
470         FLAC__ASSERT(0 != encoder);
471         FLAC__ASSERT(0 != encoder->private_);
472         FLAC__ASSERT(0 != encoder->protected_);
473         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
474                 return false;
475         encoder->private_->progress_callback = value;
476         return true;
477 }
478
479 FLAC_API FLAC__bool FLAC__file_encoder_set_client_data(FLAC__FileEncoder *encoder, void *value)
480 {
481         FLAC__ASSERT(0 != encoder);
482         FLAC__ASSERT(0 != encoder->private_);
483         FLAC__ASSERT(0 != encoder->protected_);
484         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
485                 return false;
486         encoder->private_->client_data = value;
487         return true;
488 }
489
490 /*
491  * These three functions are not static, but not publically exposed in
492  * include/FLAC/ either.  They are used by the test suite.
493  */
494 FLAC_API FLAC__bool FLAC__file_encoder_disable_constant_subframes(FLAC__FileEncoder *encoder, FLAC__bool value)
495 {
496         FLAC__ASSERT(0 != encoder);
497         FLAC__ASSERT(0 != encoder->private_);
498         FLAC__ASSERT(0 != encoder->protected_);
499         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
500                 return false;
501         return FLAC__seekable_stream_encoder_disable_constant_subframes(encoder->private_->seekable_stream_encoder, value);
502 }
503
504 FLAC_API FLAC__bool FLAC__file_encoder_disable_fixed_subframes(FLAC__FileEncoder *encoder, FLAC__bool value)
505 {
506         FLAC__ASSERT(0 != encoder);
507         FLAC__ASSERT(0 != encoder->private_);
508         FLAC__ASSERT(0 != encoder->protected_);
509         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
510                 return false;
511         return FLAC__seekable_stream_encoder_disable_fixed_subframes(encoder->private_->seekable_stream_encoder, value);
512 }
513
514 FLAC_API FLAC__bool FLAC__file_encoder_disable_verbatim_subframes(FLAC__FileEncoder *encoder, FLAC__bool value)
515 {
516         FLAC__ASSERT(0 != encoder);
517         FLAC__ASSERT(0 != encoder->private_);
518         FLAC__ASSERT(0 != encoder->protected_);
519         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
520                 return false;
521         return FLAC__seekable_stream_encoder_disable_verbatim_subframes(encoder->private_->seekable_stream_encoder, value);
522 }
523
524 FLAC_API FLAC__FileEncoderState FLAC__file_encoder_get_state(const FLAC__FileEncoder *encoder)
525 {
526         FLAC__ASSERT(0 != encoder);
527         FLAC__ASSERT(0 != encoder->protected_);
528         return encoder->protected_->state;
529 }
530
531 FLAC_API FLAC__SeekableStreamEncoderState FLAC__file_encoder_get_seekable_stream_encoder_state(const FLAC__FileEncoder *encoder)
532 {
533         FLAC__ASSERT(0 != encoder);
534         FLAC__ASSERT(0 != encoder->private_);
535         return FLAC__seekable_stream_encoder_get_state(encoder->private_->seekable_stream_encoder);
536 }
537
538 FLAC_API FLAC__StreamEncoderState FLAC__file_encoder_get_stream_encoder_state(const FLAC__FileEncoder *encoder)
539 {
540         FLAC__ASSERT(0 != encoder);
541         FLAC__ASSERT(0 != encoder->private_);
542         return FLAC__seekable_stream_encoder_get_stream_encoder_state(encoder->private_->seekable_stream_encoder);
543 }
544
545 FLAC_API FLAC__StreamDecoderState FLAC__file_encoder_get_verify_decoder_state(const FLAC__FileEncoder *encoder)
546 {
547         FLAC__ASSERT(0 != encoder);
548         FLAC__ASSERT(0 != encoder->private_);
549         return FLAC__seekable_stream_encoder_get_verify_decoder_state(encoder->private_->seekable_stream_encoder);
550 }
551
552 FLAC_API const char *FLAC__file_encoder_get_resolved_state_string(const FLAC__FileEncoder *encoder)
553 {
554         if(encoder->protected_->state != FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR)
555                 return FLAC__FileEncoderStateString[encoder->protected_->state];
556         else
557                 return FLAC__seekable_stream_encoder_get_resolved_state_string(encoder->private_->seekable_stream_encoder);
558 }
559
560 FLAC_API void FLAC__file_encoder_get_verify_decoder_error_stats(const FLAC__FileEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got)
561 {
562         FLAC__ASSERT(0 != encoder);
563         FLAC__ASSERT(0 != encoder->private_);
564         FLAC__seekable_stream_encoder_get_verify_decoder_error_stats(encoder->private_->seekable_stream_encoder, absolute_sample, frame_number, channel, sample, expected, got);
565 }
566
567 FLAC_API FLAC__bool FLAC__file_encoder_get_verify(const FLAC__FileEncoder *encoder)
568 {
569         FLAC__ASSERT(0 != encoder);
570         FLAC__ASSERT(0 != encoder->private_);
571         return FLAC__seekable_stream_encoder_get_verify(encoder->private_->seekable_stream_encoder);
572 }
573
574 FLAC_API FLAC__bool FLAC__file_encoder_get_streamable_subset(const FLAC__FileEncoder *encoder)
575 {
576         FLAC__ASSERT(0 != encoder);
577         FLAC__ASSERT(0 != encoder->private_);
578         return FLAC__seekable_stream_encoder_get_streamable_subset(encoder->private_->seekable_stream_encoder);
579 }
580
581 FLAC_API FLAC__bool FLAC__file_encoder_get_do_mid_side_stereo(const FLAC__FileEncoder *encoder)
582 {
583         FLAC__ASSERT(0 != encoder);
584         FLAC__ASSERT(0 != encoder->private_);
585         return FLAC__seekable_stream_encoder_get_do_mid_side_stereo(encoder->private_->seekable_stream_encoder);
586 }
587
588 FLAC_API FLAC__bool FLAC__file_encoder_get_loose_mid_side_stereo(const FLAC__FileEncoder *encoder)
589 {
590         FLAC__ASSERT(0 != encoder);
591         FLAC__ASSERT(0 != encoder->private_);
592         return FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder);
593 }
594
595 FLAC_API unsigned FLAC__file_encoder_get_channels(const FLAC__FileEncoder *encoder)
596 {
597         FLAC__ASSERT(0 != encoder);
598         FLAC__ASSERT(0 != encoder->private_);
599         return FLAC__seekable_stream_encoder_get_channels(encoder->private_->seekable_stream_encoder);
600 }
601
602 FLAC_API unsigned FLAC__file_encoder_get_bits_per_sample(const FLAC__FileEncoder *encoder)
603 {
604         FLAC__ASSERT(0 != encoder);
605         FLAC__ASSERT(0 != encoder->private_);
606         return FLAC__seekable_stream_encoder_get_bits_per_sample(encoder->private_->seekable_stream_encoder);
607 }
608
609 FLAC_API unsigned FLAC__file_encoder_get_sample_rate(const FLAC__FileEncoder *encoder)
610 {
611         FLAC__ASSERT(0 != encoder);
612         FLAC__ASSERT(0 != encoder->private_);
613         return FLAC__seekable_stream_encoder_get_sample_rate(encoder->private_->seekable_stream_encoder);
614 }
615
616 FLAC_API unsigned FLAC__file_encoder_get_blocksize(const FLAC__FileEncoder *encoder)
617 {
618         FLAC__ASSERT(0 != encoder);
619         FLAC__ASSERT(0 != encoder->private_);
620         return FLAC__seekable_stream_encoder_get_blocksize(encoder->private_->seekable_stream_encoder);
621 }
622
623 FLAC_API unsigned FLAC__file_encoder_get_max_lpc_order(const FLAC__FileEncoder *encoder)
624 {
625         FLAC__ASSERT(0 != encoder);
626         FLAC__ASSERT(0 != encoder->private_);
627         return FLAC__seekable_stream_encoder_get_max_lpc_order(encoder->private_->seekable_stream_encoder);
628 }
629
630 FLAC_API unsigned FLAC__file_encoder_get_qlp_coeff_precision(const FLAC__FileEncoder *encoder)
631 {
632         FLAC__ASSERT(0 != encoder);
633         FLAC__ASSERT(0 != encoder->private_);
634         return FLAC__seekable_stream_encoder_get_qlp_coeff_precision(encoder->private_->seekable_stream_encoder);
635 }
636
637 FLAC_API FLAC__bool FLAC__file_encoder_get_do_qlp_coeff_prec_search(const FLAC__FileEncoder *encoder)
638 {
639         FLAC__ASSERT(0 != encoder);
640         FLAC__ASSERT(0 != encoder->private_);
641         return FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder);
642 }
643
644 FLAC_API FLAC__bool FLAC__file_encoder_get_do_escape_coding(const FLAC__FileEncoder *encoder)
645 {
646         FLAC__ASSERT(0 != encoder);
647         FLAC__ASSERT(0 != encoder->private_);
648         return FLAC__seekable_stream_encoder_get_do_escape_coding(encoder->private_->seekable_stream_encoder);
649 }
650
651 FLAC_API FLAC__bool FLAC__file_encoder_get_do_exhaustive_model_search(const FLAC__FileEncoder *encoder)
652 {
653         FLAC__ASSERT(0 != encoder);
654         FLAC__ASSERT(0 != encoder->private_);
655         return FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder);
656 }
657
658 FLAC_API unsigned FLAC__file_encoder_get_min_residual_partition_order(const FLAC__FileEncoder *encoder)
659 {
660         FLAC__ASSERT(0 != encoder);
661         FLAC__ASSERT(0 != encoder->private_);
662         return FLAC__seekable_stream_encoder_get_min_residual_partition_order(encoder->private_->seekable_stream_encoder);
663 }
664
665 FLAC_API unsigned FLAC__file_encoder_get_max_residual_partition_order(const FLAC__FileEncoder *encoder)
666 {
667         FLAC__ASSERT(0 != encoder);
668         FLAC__ASSERT(0 != encoder->private_);
669         return FLAC__seekable_stream_encoder_get_max_residual_partition_order(encoder->private_->seekable_stream_encoder);
670 }
671
672 FLAC_API unsigned FLAC__file_encoder_get_rice_parameter_search_dist(const FLAC__FileEncoder *encoder)
673 {
674         FLAC__ASSERT(0 != encoder);
675         FLAC__ASSERT(0 != encoder->private_);
676         return FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder);
677 }
678
679 FLAC_API FLAC__uint64 FLAC__file_encoder_get_total_samples_estimate(const FLAC__FileEncoder *encoder)
680 {
681         FLAC__ASSERT(0 != encoder);
682         FLAC__ASSERT(0 != encoder->private_);
683         return FLAC__seekable_stream_encoder_get_total_samples_estimate(encoder->private_->seekable_stream_encoder);
684 }
685
686 FLAC_API FLAC__bool FLAC__file_encoder_process(FLAC__FileEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
687 {
688         FLAC__ASSERT(0 != encoder);
689         FLAC__ASSERT(0 != encoder->private_);
690         if(!FLAC__seekable_stream_encoder_process(encoder->private_->seekable_stream_encoder, buffer, samples)) {
691                 encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
692                 return false;
693         }
694         else
695                 return true;
696 }
697
698 /* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */
699 FLAC_API FLAC__bool FLAC__file_encoder_process_interleaved(FLAC__FileEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
700 {
701         FLAC__ASSERT(0 != encoder);
702         FLAC__ASSERT(0 != encoder->private_);
703         if(!FLAC__seekable_stream_encoder_process_interleaved(encoder->private_->seekable_stream_encoder, buffer, samples)) {
704                 encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
705                 return false;
706         }
707         else
708                 return true;
709 }
710
711
712 /***********************************************************************
713  *
714  * Private class methods
715  *
716  ***********************************************************************/
717
718 void set_defaults_(FLAC__FileEncoder *encoder)
719 {
720         FLAC__ASSERT(0 != encoder);
721         FLAC__ASSERT(0 != encoder->private_);
722
723         encoder->private_->progress_callback = 0;
724         encoder->private_->client_data = 0;
725         encoder->private_->total_frames_estimate = 0;
726         encoder->private_->filename = 0;
727 }
728
729 FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
730 {
731         FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data;
732
733         (void)encoder;
734
735         FLAC__ASSERT(0 != file_encoder);
736
737         if(fseeko(file_encoder->private_->file, (off_t)absolute_byte_offset, SEEK_SET) < 0)
738                 return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR;
739         else
740                 return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK;
741 }
742
743 FLAC__SeekableStreamEncoderTellStatus tell_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
744 {
745         FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data;
746         off_t offset;
747
748         (void)encoder;
749
750         FLAC__ASSERT(0 != file_encoder);
751
752         offset = ftello(file_encoder->private_->file);
753
754         if(offset < 0) {
755                 return FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_ERROR;
756         }
757         else {
758                 *absolute_byte_offset = (FLAC__uint64)offset;
759                 return FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK;
760         }
761 }
762
763 #ifdef FLAC__VALGRIND_TESTING
764 static size_t local__fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
765 {
766         size_t ret = fwrite(ptr, size, nmemb, stream);
767         if(!ferror(stream))
768                 fflush(stream);
769         return ret;
770 }
771 #else
772 #define local__fwrite fwrite
773 #endif
774
775 FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
776 {
777         FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data;
778
779         (void)encoder, (void)samples, (void)current_frame;
780
781         FLAC__ASSERT(0 != file_encoder);
782
783         if(local__fwrite(buffer, sizeof(FLAC__byte), bytes, file_encoder->private_->file) == bytes) {
784                 file_encoder->private_->bytes_written += bytes;
785                 file_encoder->private_->samples_written += samples;
786                 /* we keep a high watermark on the number of frames written because
787                  * when the encoder goes back to write metadata, 'current_frame'
788                  * will drop back to 0.
789                  */
790                 file_encoder->private_->frames_written = max(file_encoder->private_->frames_written, current_frame+1);
791                 if(0 != file_encoder->private_->progress_callback && samples > 0)
792                         file_encoder->private_->progress_callback(file_encoder, file_encoder->private_->bytes_written, file_encoder->private_->samples_written, file_encoder->private_->frames_written, file_encoder->private_->total_frames_estimate, file_encoder->private_->client_data);
793                 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
794         }
795         else
796                 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
797 }