switch malloc+memset(0) to calloc()
[flac.git] / src / libFLAC / file_encoder.c
1 /* libFLAC - Free Lossless Audio Codec library
2  * Copyright (C) 2002  Josh Coalson
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA  02111-1307, USA.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h> /* for malloc() */
22 #include <string.h> /* for memcpy() */
23 #include "FLAC/assert.h"
24 #include "protected/file_encoder.h"
25 #include "protected/seekable_stream_encoder.h"
26
27 /***********************************************************************
28  *
29  * Private class method prototypes
30  *
31  ***********************************************************************/
32
33 /* unpublished debug routines */
34 extern FLAC__bool FLAC__seekable_stream_encoder_disable_constant_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value);
35 extern FLAC__bool FLAC__seekable_stream_encoder_disable_fixed_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value);
36 extern FLAC__bool FLAC__seekable_stream_encoder_disable_verbatim_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value);
37
38 static void set_defaults_(FLAC__FileEncoder *encoder);
39 static FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data);
40 static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
41
42 /***********************************************************************
43  *
44  * Private class data
45  *
46  ***********************************************************************/
47
48 typedef struct FLAC__FileEncoderPrivate {
49         FLAC__FileEncoderProgressCallback progress_callback;
50         void *client_data;
51         char *filename;
52         FLAC__uint64 bytes_written;
53         FLAC__uint64 samples_written;
54         unsigned total_frames_estimate;
55         FLAC__SeekableStreamEncoder *seekable_stream_encoder;
56         FILE *file;
57 } FLAC__FileEncoderPrivate;
58
59 /***********************************************************************
60  *
61  * Public static class data
62  *
63  ***********************************************************************/
64
65 FLAC_API const char * const FLAC__FileEncoderStateString[] = {
66         "FLAC__FILE_ENCODER_OK",
67         "FLAC__FILE_ENCODER_NO_FILENAME",
68         "FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR",
69         "FLAC__FILE_ENCODER_FATAL_ERROR_WHILE_WRITING",
70         "FLAC__FILE_ENCODER_ERROR_OPENING_FILE",
71         "FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR",
72         "FLAC__FILE_ENCODER_ALREADY_INITIALIZED",
73         "FLAC__FILE_ENCODER_UNINITIALIZED"
74 };
75
76
77 /***********************************************************************
78  *
79  * Class constructor/destructor
80  *
81  ***********************************************************************/
82
83 FLAC_API FLAC__FileEncoder *FLAC__file_encoder_new()
84 {
85         FLAC__FileEncoder *encoder;
86
87         FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
88
89         encoder = (FLAC__FileEncoder*)calloc(1, sizeof(FLAC__FileEncoder));
90         if(encoder == 0) {
91                 return 0;
92         }
93
94         encoder->protected_ = (FLAC__FileEncoderProtected*)calloc(1, sizeof(FLAC__FileEncoderProtected));
95         if(encoder->protected_ == 0) {
96                 free(encoder);
97                 return 0;
98         }
99
100         encoder->private_ = (FLAC__FileEncoderPrivate*)calloc(1, sizeof(FLAC__FileEncoderPrivate));
101         if(encoder->private_ == 0) {
102                 free(encoder->protected_);
103                 free(encoder);
104                 return 0;
105         }
106
107         encoder->private_->seekable_stream_encoder = FLAC__seekable_stream_encoder_new();
108         if(0 == encoder->private_->seekable_stream_encoder) {
109                 free(encoder->private_);
110                 free(encoder->protected_);
111                 free(encoder);
112                 return 0;
113         }
114
115         encoder->private_->file = 0;
116
117         set_defaults_(encoder);
118
119         encoder->protected_->state = FLAC__FILE_ENCODER_UNINITIALIZED;
120
121         return encoder;
122 }
123
124 FLAC_API void FLAC__file_encoder_delete(FLAC__FileEncoder *encoder)
125 {
126         FLAC__ASSERT(0 != encoder);
127         FLAC__ASSERT(0 != encoder->protected_);
128         FLAC__ASSERT(0 != encoder->private_);
129         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
130
131         (void)FLAC__file_encoder_finish(encoder);
132
133         FLAC__seekable_stream_encoder_delete(encoder->private_->seekable_stream_encoder);
134
135         free(encoder->private_);
136         free(encoder->protected_);
137         free(encoder);
138 }
139
140 /***********************************************************************
141  *
142  * Public class methods
143  *
144  ***********************************************************************/
145
146 FLAC_API FLAC__FileEncoderState FLAC__file_encoder_init(FLAC__FileEncoder *encoder)
147 {
148         FLAC__ASSERT(0 != encoder);
149
150         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
151                 return encoder->protected_->state = FLAC__FILE_ENCODER_ALREADY_INITIALIZED;
152
153         if(0 == encoder->private_->filename)
154                 return encoder->protected_->state = FLAC__FILE_ENCODER_NO_FILENAME;
155
156         encoder->private_->file = fopen(encoder->private_->filename, "w+b");
157
158         if(encoder->private_->file == 0)
159                 return encoder->protected_->state = FLAC__FILE_ENCODER_ERROR_OPENING_FILE;
160
161         encoder->private_->bytes_written = 0;
162         encoder->private_->samples_written = 0;
163
164         FLAC__seekable_stream_encoder_set_seek_callback(encoder->private_->seekable_stream_encoder, seek_callback_);
165         FLAC__seekable_stream_encoder_set_write_callback(encoder->private_->seekable_stream_encoder, write_callback_);
166         FLAC__seekable_stream_encoder_set_client_data(encoder->private_->seekable_stream_encoder, encoder);
167
168         if(FLAC__seekable_stream_encoder_init(encoder->private_->seekable_stream_encoder) != FLAC__SEEKABLE_STREAM_ENCODER_OK)
169                 return encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
170
171         {
172                 unsigned blocksize = FLAC__file_encoder_get_blocksize(encoder);
173
174                 FLAC__ASSERT(blocksize != 0);
175                 encoder->private_->total_frames_estimate = (unsigned)((FLAC__file_encoder_get_total_samples_estimate(encoder) + blocksize - 1) / blocksize);
176         }
177
178         return encoder->protected_->state = FLAC__FILE_ENCODER_OK;
179 }
180
181 FLAC_API void FLAC__file_encoder_finish(FLAC__FileEncoder *encoder)
182 {
183         FLAC__ASSERT(0 != encoder);
184
185         if(encoder->protected_->state == FLAC__FILE_ENCODER_UNINITIALIZED)
186                 return;
187
188         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
189
190         /* FLAC__seekable_stream_encoder_finish() might write data so we must close the file after it. */
191
192         FLAC__seekable_stream_encoder_finish(encoder->private_->seekable_stream_encoder);
193
194         if(0 != encoder->private_->file) {
195                 fclose(encoder->private_->file);
196                 encoder->private_->file = 0;
197         }
198
199         if(0 != encoder->private_->filename) {
200                 free(encoder->private_->filename);
201                 encoder->private_->filename = 0;
202         }
203
204         set_defaults_(encoder);
205
206         encoder->protected_->state = FLAC__FILE_ENCODER_UNINITIALIZED;
207 }
208
209 FLAC_API FLAC__bool FLAC__file_encoder_set_verify(FLAC__FileEncoder *encoder, FLAC__bool value)
210 {
211         FLAC__ASSERT(0 != encoder);
212         FLAC__ASSERT(0 != encoder->private_);
213         FLAC__ASSERT(0 != encoder->protected_);
214         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
215         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
216                 return false;
217         return FLAC__seekable_stream_encoder_set_verify(encoder->private_->seekable_stream_encoder, value);
218 }
219
220 FLAC_API FLAC__bool FLAC__file_encoder_set_streamable_subset(FLAC__FileEncoder *encoder, FLAC__bool value)
221 {
222         FLAC__ASSERT(0 != encoder);
223         FLAC__ASSERT(0 != encoder->private_);
224         FLAC__ASSERT(0 != encoder->protected_);
225         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
226         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
227                 return false;
228         return FLAC__seekable_stream_encoder_set_streamable_subset(encoder->private_->seekable_stream_encoder, value);
229 }
230
231 FLAC_API FLAC__bool FLAC__file_encoder_set_do_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value)
232 {
233         FLAC__ASSERT(0 != encoder);
234         FLAC__ASSERT(0 != encoder->private_);
235         FLAC__ASSERT(0 != encoder->protected_);
236         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
237         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
238                 return false;
239         return FLAC__seekable_stream_encoder_set_do_mid_side_stereo(encoder->private_->seekable_stream_encoder, value);
240 }
241
242 FLAC_API FLAC__bool FLAC__file_encoder_set_loose_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value)
243 {
244         FLAC__ASSERT(0 != encoder);
245         FLAC__ASSERT(0 != encoder->private_);
246         FLAC__ASSERT(0 != encoder->protected_);
247         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
248         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
249                 return false;
250         return FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder, value);
251 }
252
253 FLAC_API FLAC__bool FLAC__file_encoder_set_channels(FLAC__FileEncoder *encoder, unsigned value)
254 {
255         FLAC__ASSERT(0 != encoder);
256         FLAC__ASSERT(0 != encoder->private_);
257         FLAC__ASSERT(0 != encoder->protected_);
258         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
259         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
260                 return false;
261         return FLAC__seekable_stream_encoder_set_channels(encoder->private_->seekable_stream_encoder, value);
262 }
263
264 FLAC_API FLAC__bool FLAC__file_encoder_set_bits_per_sample(FLAC__FileEncoder *encoder, unsigned value)
265 {
266         FLAC__ASSERT(0 != encoder);
267         FLAC__ASSERT(0 != encoder->private_);
268         FLAC__ASSERT(0 != encoder->protected_);
269         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
270         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
271                 return false;
272         return FLAC__seekable_stream_encoder_set_bits_per_sample(encoder->private_->seekable_stream_encoder, value);
273 }
274
275 FLAC_API FLAC__bool FLAC__file_encoder_set_sample_rate(FLAC__FileEncoder *encoder, unsigned value)
276 {
277         FLAC__ASSERT(0 != encoder);
278         FLAC__ASSERT(0 != encoder->private_);
279         FLAC__ASSERT(0 != encoder->protected_);
280         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
281         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
282                 return false;
283         return FLAC__seekable_stream_encoder_set_sample_rate(encoder->private_->seekable_stream_encoder, value);
284 }
285
286 FLAC_API FLAC__bool FLAC__file_encoder_set_blocksize(FLAC__FileEncoder *encoder, unsigned value)
287 {
288         FLAC__ASSERT(0 != encoder);
289         FLAC__ASSERT(0 != encoder->private_);
290         FLAC__ASSERT(0 != encoder->protected_);
291         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
292         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
293                 return false;
294         return FLAC__seekable_stream_encoder_set_blocksize(encoder->private_->seekable_stream_encoder, value);
295 }
296
297 FLAC_API FLAC__bool FLAC__file_encoder_set_max_lpc_order(FLAC__FileEncoder *encoder, unsigned value)
298 {
299         FLAC__ASSERT(0 != encoder);
300         FLAC__ASSERT(0 != encoder->private_);
301         FLAC__ASSERT(0 != encoder->protected_);
302         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
303         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
304                 return false;
305         return FLAC__seekable_stream_encoder_set_max_lpc_order(encoder->private_->seekable_stream_encoder, value);
306 }
307
308 FLAC_API FLAC__bool FLAC__file_encoder_set_qlp_coeff_precision(FLAC__FileEncoder *encoder, unsigned value)
309 {
310         FLAC__ASSERT(0 != encoder);
311         FLAC__ASSERT(0 != encoder->private_);
312         FLAC__ASSERT(0 != encoder->protected_);
313         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
314         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
315                 return false;
316         return FLAC__seekable_stream_encoder_set_qlp_coeff_precision(encoder->private_->seekable_stream_encoder, value);
317 }
318
319 FLAC_API FLAC__bool FLAC__file_encoder_set_do_qlp_coeff_prec_search(FLAC__FileEncoder *encoder, FLAC__bool value)
320 {
321         FLAC__ASSERT(0 != encoder);
322         FLAC__ASSERT(0 != encoder->private_);
323         FLAC__ASSERT(0 != encoder->protected_);
324         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
325         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
326                 return false;
327         return FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder, value);
328 }
329
330 FLAC_API FLAC__bool FLAC__file_encoder_set_do_escape_coding(FLAC__FileEncoder *encoder, FLAC__bool value)
331 {
332         FLAC__ASSERT(0 != encoder);
333         FLAC__ASSERT(0 != encoder->private_);
334         FLAC__ASSERT(0 != encoder->protected_);
335         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
336         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
337                 return false;
338         return FLAC__seekable_stream_encoder_set_do_escape_coding(encoder->private_->seekable_stream_encoder, value);
339 }
340
341 FLAC_API FLAC__bool FLAC__file_encoder_set_do_exhaustive_model_search(FLAC__FileEncoder *encoder, FLAC__bool value)
342 {
343         FLAC__ASSERT(0 != encoder);
344         FLAC__ASSERT(0 != encoder->private_);
345         FLAC__ASSERT(0 != encoder->protected_);
346         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
347         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
348                 return false;
349         return FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder, value);
350 }
351
352 FLAC_API FLAC__bool FLAC__file_encoder_set_min_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value)
353 {
354         FLAC__ASSERT(0 != encoder);
355         FLAC__ASSERT(0 != encoder->private_);
356         FLAC__ASSERT(0 != encoder->protected_);
357         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
358         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
359                 return false;
360         return FLAC__seekable_stream_encoder_set_min_residual_partition_order(encoder->private_->seekable_stream_encoder, value);
361 }
362
363 FLAC_API FLAC__bool FLAC__file_encoder_set_max_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value)
364 {
365         FLAC__ASSERT(0 != encoder);
366         FLAC__ASSERT(0 != encoder->private_);
367         FLAC__ASSERT(0 != encoder->protected_);
368         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
369         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
370                 return false;
371         return FLAC__seekable_stream_encoder_set_max_residual_partition_order(encoder->private_->seekable_stream_encoder, value);
372 }
373
374 FLAC_API FLAC__bool FLAC__file_encoder_set_rice_parameter_search_dist(FLAC__FileEncoder *encoder, unsigned value)
375 {
376         FLAC__ASSERT(0 != encoder);
377         FLAC__ASSERT(0 != encoder->private_);
378         FLAC__ASSERT(0 != encoder->protected_);
379         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
380         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
381                 return false;
382         return FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder, value);
383 }
384
385 FLAC_API FLAC__bool FLAC__file_encoder_set_total_samples_estimate(FLAC__FileEncoder *encoder, FLAC__uint64 value)
386 {
387         FLAC__ASSERT(0 != encoder);
388         FLAC__ASSERT(0 != encoder->private_);
389         FLAC__ASSERT(0 != encoder->protected_);
390         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
391         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
392                 return false;
393         return FLAC__seekable_stream_encoder_set_total_samples_estimate(encoder->private_->seekable_stream_encoder, value);
394 }
395
396 FLAC_API FLAC__bool FLAC__file_encoder_set_metadata(FLAC__FileEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
397 {
398         FLAC__ASSERT(0 != encoder);
399         FLAC__ASSERT(0 != encoder->private_);
400         FLAC__ASSERT(0 != encoder->protected_);
401         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
402         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
403                 return false;
404         return FLAC__seekable_stream_encoder_set_metadata(encoder->private_->seekable_stream_encoder, metadata, num_blocks);
405 }
406
407 FLAC_API FLAC__bool FLAC__file_encoder_set_filename(FLAC__FileEncoder *encoder, const char *value)
408 {
409         FLAC__ASSERT(0 != encoder);
410         FLAC__ASSERT(0 != encoder->private_);
411         FLAC__ASSERT(0 != encoder->protected_);
412         FLAC__ASSERT(0 != value);
413         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
414                 return false;
415         if(0 != encoder->private_->filename) {
416                 free(encoder->private_->filename);
417                 encoder->private_->filename = 0;
418         }
419         if(0 == (encoder->private_->filename = (char*)malloc(strlen(value)+1))) {
420                 encoder->protected_->state = FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR;
421                 return false;
422         }
423         strcpy(encoder->private_->filename, value);
424         return true;
425 }
426
427 FLAC_API FLAC__bool FLAC__file_encoder_set_progress_callback(FLAC__FileEncoder *encoder, FLAC__FileEncoderProgressCallback value)
428 {
429         FLAC__ASSERT(0 != encoder);
430         FLAC__ASSERT(0 != encoder->private_);
431         FLAC__ASSERT(0 != encoder->protected_);
432         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
433                 return false;
434         encoder->private_->progress_callback = value;
435         return true;
436 }
437
438 FLAC_API FLAC__bool FLAC__file_encoder_set_client_data(FLAC__FileEncoder *encoder, void *value)
439 {
440         FLAC__ASSERT(0 != encoder);
441         FLAC__ASSERT(0 != encoder->private_);
442         FLAC__ASSERT(0 != encoder->protected_);
443         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
444                 return false;
445         encoder->private_->client_data = value;
446         return true;
447 }
448
449 /*
450  * These three functions are not static, but not publically exposed in
451  * include/FLAC/ either.  They are used by the test suite.
452  */
453 FLAC_API FLAC__bool FLAC__file_encoder_disable_constant_subframes(FLAC__FileEncoder *encoder, FLAC__bool value)
454 {
455         FLAC__ASSERT(0 != encoder);
456         FLAC__ASSERT(0 != encoder->private_);
457         FLAC__ASSERT(0 != encoder->protected_);
458         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
459                 return false;
460         return FLAC__seekable_stream_encoder_disable_constant_subframes(encoder->private_->seekable_stream_encoder, value);
461 }
462
463 FLAC_API FLAC__bool FLAC__file_encoder_disable_fixed_subframes(FLAC__FileEncoder *encoder, FLAC__bool value)
464 {
465         FLAC__ASSERT(0 != encoder);
466         FLAC__ASSERT(0 != encoder->private_);
467         FLAC__ASSERT(0 != encoder->protected_);
468         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
469                 return false;
470         return FLAC__seekable_stream_encoder_disable_fixed_subframes(encoder->private_->seekable_stream_encoder, value);
471 }
472
473 FLAC_API FLAC__bool FLAC__file_encoder_disable_verbatim_subframes(FLAC__FileEncoder *encoder, FLAC__bool value)
474 {
475         FLAC__ASSERT(0 != encoder);
476         FLAC__ASSERT(0 != encoder->private_);
477         FLAC__ASSERT(0 != encoder->protected_);
478         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
479                 return false;
480         return FLAC__seekable_stream_encoder_disable_verbatim_subframes(encoder->private_->seekable_stream_encoder, value);
481 }
482
483 FLAC_API FLAC__FileEncoderState FLAC__file_encoder_get_state(const FLAC__FileEncoder *encoder)
484 {
485         FLAC__ASSERT(0 != encoder);
486         FLAC__ASSERT(0 != encoder->protected_);
487         return encoder->protected_->state;
488 }
489
490 FLAC_API FLAC__SeekableStreamEncoderState FLAC__file_encoder_get_seekable_stream_encoder_state(const FLAC__FileEncoder *encoder)
491 {
492         FLAC__ASSERT(0 != encoder);
493         FLAC__ASSERT(0 != encoder->private_);
494         return FLAC__seekable_stream_encoder_get_state(encoder->private_->seekable_stream_encoder);
495 }
496
497 FLAC_API FLAC__StreamEncoderState FLAC__file_encoder_get_stream_encoder_state(const FLAC__FileEncoder *encoder)
498 {
499         FLAC__ASSERT(0 != encoder);
500         FLAC__ASSERT(0 != encoder->private_);
501         return FLAC__seekable_stream_encoder_get_stream_encoder_state(encoder->private_->seekable_stream_encoder);
502 }
503
504 FLAC_API FLAC__StreamDecoderState FLAC__file_encoder_get_verify_decoder_state(const FLAC__FileEncoder *encoder)
505 {
506         FLAC__ASSERT(0 != encoder);
507         FLAC__ASSERT(0 != encoder->private_);
508         return FLAC__seekable_stream_encoder_get_verify_decoder_state(encoder->private_->seekable_stream_encoder);
509 }
510
511 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)
512 {
513         FLAC__ASSERT(0 != encoder);
514         FLAC__ASSERT(0 != encoder->private_);
515         FLAC__seekable_stream_encoder_get_verify_decoder_error_stats(encoder->private_->seekable_stream_encoder, absolute_sample, frame_number, channel, sample, expected, got);
516 }
517
518 FLAC_API FLAC__bool FLAC__file_encoder_get_verify(const FLAC__FileEncoder *encoder)
519 {
520         FLAC__ASSERT(0 != encoder);
521         FLAC__ASSERT(0 != encoder->private_);
522         return FLAC__seekable_stream_encoder_get_verify(encoder->private_->seekable_stream_encoder);
523 }
524
525 FLAC_API FLAC__bool FLAC__file_encoder_get_streamable_subset(const FLAC__FileEncoder *encoder)
526 {
527         FLAC__ASSERT(0 != encoder);
528         FLAC__ASSERT(0 != encoder->private_);
529         return FLAC__seekable_stream_encoder_get_streamable_subset(encoder->private_->seekable_stream_encoder);
530 }
531
532 FLAC_API FLAC__bool FLAC__file_encoder_get_do_mid_side_stereo(const FLAC__FileEncoder *encoder)
533 {
534         FLAC__ASSERT(0 != encoder);
535         FLAC__ASSERT(0 != encoder->private_);
536         return FLAC__seekable_stream_encoder_get_do_mid_side_stereo(encoder->private_->seekable_stream_encoder);
537 }
538
539 FLAC_API FLAC__bool FLAC__file_encoder_get_loose_mid_side_stereo(const FLAC__FileEncoder *encoder)
540 {
541         FLAC__ASSERT(0 != encoder);
542         FLAC__ASSERT(0 != encoder->private_);
543         return FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder);
544 }
545
546 FLAC_API unsigned FLAC__file_encoder_get_channels(const FLAC__FileEncoder *encoder)
547 {
548         FLAC__ASSERT(0 != encoder);
549         FLAC__ASSERT(0 != encoder->private_);
550         return FLAC__seekable_stream_encoder_get_channels(encoder->private_->seekable_stream_encoder);
551 }
552
553 FLAC_API unsigned FLAC__file_encoder_get_bits_per_sample(const FLAC__FileEncoder *encoder)
554 {
555         FLAC__ASSERT(0 != encoder);
556         FLAC__ASSERT(0 != encoder->private_);
557         return FLAC__seekable_stream_encoder_get_bits_per_sample(encoder->private_->seekable_stream_encoder);
558 }
559
560 FLAC_API unsigned FLAC__file_encoder_get_sample_rate(const FLAC__FileEncoder *encoder)
561 {
562         FLAC__ASSERT(0 != encoder);
563         FLAC__ASSERT(0 != encoder->private_);
564         return FLAC__seekable_stream_encoder_get_sample_rate(encoder->private_->seekable_stream_encoder);
565 }
566
567 FLAC_API unsigned FLAC__file_encoder_get_blocksize(const FLAC__FileEncoder *encoder)
568 {
569         FLAC__ASSERT(0 != encoder);
570         FLAC__ASSERT(0 != encoder->private_);
571         return FLAC__seekable_stream_encoder_get_blocksize(encoder->private_->seekable_stream_encoder);
572 }
573
574 FLAC_API unsigned FLAC__file_encoder_get_max_lpc_order(const FLAC__FileEncoder *encoder)
575 {
576         FLAC__ASSERT(0 != encoder);
577         FLAC__ASSERT(0 != encoder->private_);
578         return FLAC__seekable_stream_encoder_get_max_lpc_order(encoder->private_->seekable_stream_encoder);
579 }
580
581 FLAC_API unsigned FLAC__file_encoder_get_qlp_coeff_precision(const FLAC__FileEncoder *encoder)
582 {
583         FLAC__ASSERT(0 != encoder);
584         FLAC__ASSERT(0 != encoder->private_);
585         return FLAC__seekable_stream_encoder_get_qlp_coeff_precision(encoder->private_->seekable_stream_encoder);
586 }
587
588 FLAC_API FLAC__bool FLAC__file_encoder_get_do_qlp_coeff_prec_search(const FLAC__FileEncoder *encoder)
589 {
590         FLAC__ASSERT(0 != encoder);
591         FLAC__ASSERT(0 != encoder->private_);
592         return FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder);
593 }
594
595 FLAC_API FLAC__bool FLAC__file_encoder_get_do_escape_coding(const FLAC__FileEncoder *encoder)
596 {
597         FLAC__ASSERT(0 != encoder);
598         FLAC__ASSERT(0 != encoder->private_);
599         return FLAC__seekable_stream_encoder_get_do_escape_coding(encoder->private_->seekable_stream_encoder);
600 }
601
602 FLAC_API FLAC__bool FLAC__file_encoder_get_do_exhaustive_model_search(const FLAC__FileEncoder *encoder)
603 {
604         FLAC__ASSERT(0 != encoder);
605         FLAC__ASSERT(0 != encoder->private_);
606         return FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder);
607 }
608
609 FLAC_API unsigned FLAC__file_encoder_get_min_residual_partition_order(const FLAC__FileEncoder *encoder)
610 {
611         FLAC__ASSERT(0 != encoder);
612         FLAC__ASSERT(0 != encoder->private_);
613         return FLAC__seekable_stream_encoder_get_min_residual_partition_order(encoder->private_->seekable_stream_encoder);
614 }
615
616 FLAC_API unsigned FLAC__file_encoder_get_max_residual_partition_order(const FLAC__FileEncoder *encoder)
617 {
618         FLAC__ASSERT(0 != encoder);
619         FLAC__ASSERT(0 != encoder->private_);
620         return FLAC__seekable_stream_encoder_get_max_residual_partition_order(encoder->private_->seekable_stream_encoder);
621 }
622
623 FLAC_API unsigned FLAC__file_encoder_get_rice_parameter_search_dist(const FLAC__FileEncoder *encoder)
624 {
625         FLAC__ASSERT(0 != encoder);
626         FLAC__ASSERT(0 != encoder->private_);
627         return FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder);
628 }
629
630 FLAC_API FLAC__uint64 FLAC__file_encoder_get_total_samples_estimate(const FLAC__FileEncoder *encoder)
631 {
632         FLAC__ASSERT(0 != encoder);
633         FLAC__ASSERT(0 != encoder->private_);
634         return FLAC__seekable_stream_encoder_get_total_samples_estimate(encoder->private_->seekable_stream_encoder);
635 }
636
637 FLAC_API FLAC__bool FLAC__file_encoder_process(FLAC__FileEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
638 {
639         FLAC__ASSERT(0 != encoder);
640         FLAC__ASSERT(0 != encoder->private_);
641         if(!FLAC__seekable_stream_encoder_process(encoder->private_->seekable_stream_encoder, buffer, samples)) {
642                 encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
643                 return false;
644         }
645         else
646                 return true;
647 }
648
649 /* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */
650 FLAC_API FLAC__bool FLAC__file_encoder_process_interleaved(FLAC__FileEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
651 {
652         FLAC__ASSERT(0 != encoder);
653         FLAC__ASSERT(0 != encoder->private_);
654         if(!FLAC__seekable_stream_encoder_process_interleaved(encoder->private_->seekable_stream_encoder, buffer, samples)) {
655                 encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
656                 return false;
657         }
658         else
659                 return true;
660 }
661
662
663 /***********************************************************************
664  *
665  * Private class methods
666  *
667  ***********************************************************************/
668
669 void set_defaults_(FLAC__FileEncoder *encoder)
670 {
671         FLAC__ASSERT(0 != encoder);
672         FLAC__ASSERT(0 != encoder->private_);
673
674         encoder->private_->progress_callback = 0;
675         encoder->private_->client_data = 0;
676         encoder->private_->total_frames_estimate = 0;
677         encoder->private_->filename = 0;
678 }
679
680 FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
681 {
682         FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data;
683
684         (void)encoder;
685
686         FLAC__ASSERT(0 != file_encoder);
687
688         if(fseek(file_encoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0)
689                 return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR;
690         else
691                 return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK;
692 }
693
694 FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
695 {
696         FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data;
697
698         (void)encoder, (void)samples, (void)current_frame;
699
700         FLAC__ASSERT(0 != file_encoder);
701
702         if(fwrite(buffer, sizeof(FLAC__byte), bytes, file_encoder->private_->file) == bytes) {
703                 file_encoder->private_->bytes_written += bytes;
704                 file_encoder->private_->samples_written += samples;
705                 if(0 != file_encoder->private_->progress_callback && samples > 0)
706                         file_encoder->private_->progress_callback(file_encoder, file_encoder->private_->bytes_written, file_encoder->private_->samples_written, current_frame+1, file_encoder->private_->total_frames_estimate, file_encoder->private_->client_data);
707                 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
708         }
709         else
710                 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
711 }