fix bug in free()ing of output arrays
[platform/upstream/flac.git] / src / libFLAC / seekable_stream_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 calloc() */
22 #include <string.h> /* for memcpy() */
23 #include "FLAC/assert.h"
24 #include "protected/seekable_stream_encoder.h"
25 #include "protected/stream_encoder.h"
26
27 #ifdef max
28 #undef max
29 #endif
30 #define max(a,b) ((a)>(b)?(a):(b))
31
32 /***********************************************************************
33  *
34  * Private class method prototypes
35  *
36  ***********************************************************************/
37
38 /* unpublished debug routines */
39 extern FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
40 extern FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
41 extern FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
42
43 static void set_defaults_(FLAC__SeekableStreamEncoder *encoder);
44 static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
45 static void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
46
47 /***********************************************************************
48  *
49  * Private class data
50  *
51  ***********************************************************************/
52
53 typedef struct FLAC__SeekableStreamEncoderPrivate {
54         FLAC__SeekableStreamEncoderSeekCallback seek_callback;
55         FLAC__SeekableStreamEncoderWriteCallback write_callback;
56         void *client_data;
57         FLAC__StreamEncoder *stream_encoder;
58         FLAC__StreamMetadata_SeekTable *seek_table;
59         /* internal vars (all the above are class settings) */
60         unsigned first_seekpoint_to_check;
61         FLAC__uint64 stream_offset, seektable_offset;
62         FLAC__uint64 bytes_written;
63 } FLAC__SeekableStreamEncoderPrivate;
64
65 /***********************************************************************
66  *
67  * Public static class data
68  *
69  ***********************************************************************/
70
71 FLAC_API const char * const FLAC__SeekableStreamEncoderStateString[] = {
72         "FLAC__SEEKABLE_STREAM_ENCODER_OK",
73         "FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR",
74         "FLAC__SEEKABLE_STREAM_ENCODER_MEMORY_ALLOCATION_ERROR",
75         "FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR",
76         "FLAC__SEEKABLE_STREAM_ENCODER_READ_ERROR",
77         "FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR",
78         "FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED",
79         "FLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK",
80         "FLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE",
81         "FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED"
82 };
83
84 FLAC_API const char * const FLAC__SeekableStreamEncoderSeekStatusString[] = {
85         "FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK",
86         "FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR"
87 };
88
89
90 /***********************************************************************
91  *
92  * Class constructor/destructor
93  *
94  ***********************************************************************/
95
96 FLAC_API FLAC__SeekableStreamEncoder *FLAC__seekable_stream_encoder_new()
97 {
98         FLAC__SeekableStreamEncoder *encoder;
99
100         FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
101
102         encoder = (FLAC__SeekableStreamEncoder*)calloc(1, sizeof(FLAC__SeekableStreamEncoder));
103         if(encoder == 0) {
104                 return 0;
105         }
106
107         encoder->protected_ = (FLAC__SeekableStreamEncoderProtected*)calloc(1, sizeof(FLAC__SeekableStreamEncoderProtected));
108         if(encoder->protected_ == 0) {
109                 free(encoder);
110                 return 0;
111         }
112
113         encoder->private_ = (FLAC__SeekableStreamEncoderPrivate*)calloc(1, sizeof(FLAC__SeekableStreamEncoderPrivate));
114         if(encoder->private_ == 0) {
115                 free(encoder->protected_);
116                 free(encoder);
117                 return 0;
118         }
119
120         encoder->private_->stream_encoder = FLAC__stream_encoder_new();
121         if(0 == encoder->private_->stream_encoder) {
122                 free(encoder->private_);
123                 free(encoder->protected_);
124                 free(encoder);
125                 return 0;
126         }
127
128         set_defaults_(encoder);
129
130         encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
131
132         return encoder;
133 }
134
135 FLAC_API void FLAC__seekable_stream_encoder_delete(FLAC__SeekableStreamEncoder *encoder)
136 {
137         FLAC__ASSERT(0 != encoder);
138         FLAC__ASSERT(0 != encoder->protected_);
139         FLAC__ASSERT(0 != encoder->private_);
140         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
141
142         (void)FLAC__seekable_stream_encoder_finish(encoder);
143
144         FLAC__stream_encoder_delete(encoder->private_->stream_encoder);
145
146         free(encoder->private_);
147         free(encoder->protected_);
148         free(encoder);
149 }
150
151
152 /***********************************************************************
153  *
154  * Public class methods
155  *
156  ***********************************************************************/
157
158 FLAC_API FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_init(FLAC__SeekableStreamEncoder *encoder)
159 {
160         FLAC__ASSERT(0 != encoder);
161
162         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
163                 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED;
164
165         if(0 == encoder->private_->seek_callback || 0 == encoder->private_->write_callback)
166                 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK;
167
168         if(0 != encoder->private_->seek_table && !FLAC__format_seektable_is_legal(encoder->private_->seek_table))
169                 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE;
170
171         /*
172          * This must be done before we init the stream encoder because that
173          * calls the write_callback, which uses these values.
174          */
175         encoder->private_->first_seekpoint_to_check = 0;
176         encoder->private_->stream_offset = 0;
177         encoder->private_->seektable_offset = 0;
178         encoder->private_->bytes_written = 0;
179
180         FLAC__stream_encoder_set_write_callback(encoder->private_->stream_encoder, write_callback_);
181         FLAC__stream_encoder_set_metadata_callback(encoder->private_->stream_encoder, metadata_callback_);
182         FLAC__stream_encoder_set_client_data(encoder->private_->stream_encoder, encoder);
183
184         if(FLAC__stream_encoder_init(encoder->private_->stream_encoder) != FLAC__STREAM_ENCODER_OK)
185                 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
186
187         /*
188          * Initializing the stream encoder writes all the metadata, so we
189          * save the stream offset now.
190          */
191         encoder->private_->stream_offset = encoder->private_->bytes_written;
192
193         return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_OK;
194 }
195
196 FLAC_API void FLAC__seekable_stream_encoder_finish(FLAC__SeekableStreamEncoder *encoder)
197 {
198         FLAC__ASSERT(0 != encoder);
199         FLAC__ASSERT(0 != encoder->private_);
200         FLAC__ASSERT(0 != encoder->protected_);
201
202         if(encoder->protected_->state == FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
203                 return;
204
205         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
206
207         FLAC__stream_encoder_finish(encoder->private_->stream_encoder);
208
209         set_defaults_(encoder);
210
211         encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
212 }
213
214 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_verify(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
215 {
216         FLAC__ASSERT(0 != encoder);
217         FLAC__ASSERT(0 != encoder->private_);
218         FLAC__ASSERT(0 != encoder->protected_);
219         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
220         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
221                 return false;
222         return FLAC__stream_encoder_set_verify(encoder->private_->stream_encoder, value);
223 }
224
225 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_streamable_subset(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
226 {
227         FLAC__ASSERT(0 != encoder);
228         FLAC__ASSERT(0 != encoder->private_);
229         FLAC__ASSERT(0 != encoder->protected_);
230         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
231         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
232                 return false;
233         return FLAC__stream_encoder_set_streamable_subset(encoder->private_->stream_encoder, value);
234 }
235
236 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
237 {
238         FLAC__ASSERT(0 != encoder);
239         FLAC__ASSERT(0 != encoder->private_);
240         FLAC__ASSERT(0 != encoder->protected_);
241         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
242         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
243                 return false;
244         return FLAC__stream_encoder_set_do_mid_side_stereo(encoder->private_->stream_encoder, value);
245 }
246
247 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
248 {
249         FLAC__ASSERT(0 != encoder);
250         FLAC__ASSERT(0 != encoder->private_);
251         FLAC__ASSERT(0 != encoder->protected_);
252         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
253         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
254                 return false;
255         return FLAC__stream_encoder_set_loose_mid_side_stereo(encoder->private_->stream_encoder, value);
256 }
257
258 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_channels(FLAC__SeekableStreamEncoder *encoder, unsigned value)
259 {
260         FLAC__ASSERT(0 != encoder);
261         FLAC__ASSERT(0 != encoder->private_);
262         FLAC__ASSERT(0 != encoder->protected_);
263         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
264         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
265                 return false;
266         return FLAC__stream_encoder_set_channels(encoder->private_->stream_encoder, value);
267 }
268
269 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_bits_per_sample(FLAC__SeekableStreamEncoder *encoder, unsigned value)
270 {
271         FLAC__ASSERT(0 != encoder);
272         FLAC__ASSERT(0 != encoder->private_);
273         FLAC__ASSERT(0 != encoder->protected_);
274         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
275         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
276                 return false;
277         return FLAC__stream_encoder_set_bits_per_sample(encoder->private_->stream_encoder, value);
278 }
279
280 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_sample_rate(FLAC__SeekableStreamEncoder *encoder, unsigned value)
281 {
282         FLAC__ASSERT(0 != encoder);
283         FLAC__ASSERT(0 != encoder->private_);
284         FLAC__ASSERT(0 != encoder->protected_);
285         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
286         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
287                 return false;
288         return FLAC__stream_encoder_set_sample_rate(encoder->private_->stream_encoder, value);
289 }
290
291 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_blocksize(FLAC__SeekableStreamEncoder *encoder, unsigned value)
292 {
293         FLAC__ASSERT(0 != encoder);
294         FLAC__ASSERT(0 != encoder->private_);
295         FLAC__ASSERT(0 != encoder->protected_);
296         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
297         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
298                 return false;
299         return FLAC__stream_encoder_set_blocksize(encoder->private_->stream_encoder, value);
300 }
301
302 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_max_lpc_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
303 {
304         FLAC__ASSERT(0 != encoder);
305         FLAC__ASSERT(0 != encoder->private_);
306         FLAC__ASSERT(0 != encoder->protected_);
307         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
308         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
309                 return false;
310         return FLAC__stream_encoder_set_max_lpc_order(encoder->private_->stream_encoder, value);
311 }
312
313 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_qlp_coeff_precision(FLAC__SeekableStreamEncoder *encoder, unsigned value)
314 {
315         FLAC__ASSERT(0 != encoder);
316         FLAC__ASSERT(0 != encoder->private_);
317         FLAC__ASSERT(0 != encoder->protected_);
318         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
319         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
320                 return false;
321         return FLAC__stream_encoder_set_qlp_coeff_precision(encoder->private_->stream_encoder, value);
322 }
323
324 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
325 {
326         FLAC__ASSERT(0 != encoder);
327         FLAC__ASSERT(0 != encoder->private_);
328         FLAC__ASSERT(0 != encoder->protected_);
329         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
330         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
331                 return false;
332         return FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->stream_encoder, value);
333 }
334
335 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_escape_coding(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
336 {
337         FLAC__ASSERT(0 != encoder);
338         FLAC__ASSERT(0 != encoder->private_);
339         FLAC__ASSERT(0 != encoder->protected_);
340         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
341         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
342                 return false;
343         return FLAC__stream_encoder_set_do_escape_coding(encoder->private_->stream_encoder, value);
344 }
345
346 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
347 {
348         FLAC__ASSERT(0 != encoder);
349         FLAC__ASSERT(0 != encoder->private_);
350         FLAC__ASSERT(0 != encoder->protected_);
351         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
352         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
353                 return false;
354         return FLAC__stream_encoder_set_do_exhaustive_model_search(encoder->private_->stream_encoder, value);
355 }
356
357 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_min_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
358 {
359         FLAC__ASSERT(0 != encoder);
360         FLAC__ASSERT(0 != encoder->private_);
361         FLAC__ASSERT(0 != encoder->protected_);
362         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
363         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
364                 return false;
365         return FLAC__stream_encoder_set_min_residual_partition_order(encoder->private_->stream_encoder, value);
366 }
367
368 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_max_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
369 {
370         FLAC__ASSERT(0 != encoder);
371         FLAC__ASSERT(0 != encoder->private_);
372         FLAC__ASSERT(0 != encoder->protected_);
373         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
374         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
375                 return false;
376         return FLAC__stream_encoder_set_max_residual_partition_order(encoder->private_->stream_encoder, value);
377 }
378
379 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(FLAC__SeekableStreamEncoder *encoder, unsigned value)
380 {
381         FLAC__ASSERT(0 != encoder);
382         FLAC__ASSERT(0 != encoder->private_);
383         FLAC__ASSERT(0 != encoder->protected_);
384         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
385         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
386                 return false;
387         return FLAC__stream_encoder_set_rice_parameter_search_dist(encoder->private_->stream_encoder, value);
388 }
389
390 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_total_samples_estimate(FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 value)
391 {
392         FLAC__ASSERT(0 != encoder);
393         FLAC__ASSERT(0 != encoder->private_);
394         FLAC__ASSERT(0 != encoder->protected_);
395         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
396         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
397                 return false;
398         return FLAC__stream_encoder_set_total_samples_estimate(encoder->private_->stream_encoder, value);
399 }
400
401 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_metadata(FLAC__SeekableStreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
402 {
403         FLAC__ASSERT(0 != encoder);
404         FLAC__ASSERT(0 != encoder->private_);
405         FLAC__ASSERT(0 != encoder->protected_);
406         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
407         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
408                 return false;
409         if(0 != metadata && num_blocks > 0) {
410                 unsigned i;
411                 for(i = 0; i < num_blocks; i++) {
412                         if(0 != metadata[i] && metadata[i]->type == FLAC__METADATA_TYPE_SEEKTABLE) {
413                                 encoder->private_->seek_table = &metadata[i]->data.seek_table;
414                                 break; /* take only the first one */
415                         }
416                 }
417         }
418         return FLAC__stream_encoder_set_metadata(encoder->private_->stream_encoder, metadata, num_blocks);
419 }
420
421 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_seek_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderSeekCallback value)
422 {
423         FLAC__ASSERT(0 != encoder);
424         FLAC__ASSERT(0 != encoder->private_);
425         FLAC__ASSERT(0 != encoder->protected_);
426         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
427                 return false;
428         encoder->private_->seek_callback = value;
429         return true;
430 }
431
432 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_write_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderWriteCallback value)
433 {
434         FLAC__ASSERT(0 != encoder);
435         FLAC__ASSERT(0 != encoder->private_);
436         FLAC__ASSERT(0 != encoder->protected_);
437         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
438                 return false;
439         encoder->private_->write_callback = value;
440         return true;
441 }
442
443 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_client_data(FLAC__SeekableStreamEncoder *encoder, void *value)
444 {
445         FLAC__ASSERT(0 != encoder);
446         FLAC__ASSERT(0 != encoder->private_);
447         FLAC__ASSERT(0 != encoder->protected_);
448         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
449                 return false;
450         encoder->private_->client_data = value;
451         return true;
452 }
453
454 /*
455  * These three functions are not static, but not publically exposed in
456  * include/FLAC/ either.  They are used by the test suite.
457  */
458 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_disable_constant_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
459 {
460         FLAC__ASSERT(0 != encoder);
461         FLAC__ASSERT(0 != encoder->private_);
462         FLAC__ASSERT(0 != encoder->protected_);
463         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
464                 return false;
465         return FLAC__stream_encoder_disable_constant_subframes(encoder->private_->stream_encoder, value);
466 }
467
468 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_disable_fixed_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool 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__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
474                 return false;
475         return FLAC__stream_encoder_disable_fixed_subframes(encoder->private_->stream_encoder, value);
476 }
477
478 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_disable_verbatim_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
479 {
480         FLAC__ASSERT(0 != encoder);
481         FLAC__ASSERT(0 != encoder->private_);
482         FLAC__ASSERT(0 != encoder->protected_);
483         if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
484                 return false;
485         return FLAC__stream_encoder_disable_verbatim_subframes(encoder->private_->stream_encoder, value);
486 }
487
488 FLAC_API FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_get_state(const FLAC__SeekableStreamEncoder *encoder)
489 {
490         FLAC__ASSERT(0 != encoder);
491         FLAC__ASSERT(0 != encoder->protected_);
492         return encoder->protected_->state;
493 }
494
495 FLAC_API FLAC__StreamEncoderState FLAC__seekable_stream_encoder_get_stream_encoder_state(const FLAC__SeekableStreamEncoder *encoder)
496 {
497         FLAC__ASSERT(0 != encoder);
498         FLAC__ASSERT(0 != encoder->private_);
499         return FLAC__stream_encoder_get_state(encoder->private_->stream_encoder);
500 }
501
502 FLAC_API FLAC__StreamDecoderState FLAC__seekable_stream_encoder_get_verify_decoder_state(const FLAC__SeekableStreamEncoder *encoder)
503 {
504         FLAC__ASSERT(0 != encoder);
505         FLAC__ASSERT(0 != encoder->private_);
506         return FLAC__stream_encoder_get_verify_decoder_state(encoder->private_->stream_encoder);
507 }
508
509 FLAC_API void FLAC__seekable_stream_encoder_get_verify_decoder_error_stats(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got)
510 {
511         FLAC__ASSERT(0 != encoder);
512         FLAC__ASSERT(0 != encoder->private_);
513         FLAC__stream_encoder_get_verify_decoder_error_stats(encoder->private_->stream_encoder, absolute_sample, frame_number, channel, sample, expected, got);
514 }
515
516 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_verify(const FLAC__SeekableStreamEncoder *encoder)
517 {
518         FLAC__ASSERT(0 != encoder);
519         FLAC__ASSERT(0 != encoder->private_);
520         return FLAC__stream_encoder_get_verify(encoder->private_->stream_encoder);
521 }
522
523 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_streamable_subset(const FLAC__SeekableStreamEncoder *encoder)
524 {
525         FLAC__ASSERT(0 != encoder);
526         FLAC__ASSERT(0 != encoder->private_);
527         return FLAC__stream_encoder_get_streamable_subset(encoder->private_->stream_encoder);
528 }
529
530 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder)
531 {
532         FLAC__ASSERT(0 != encoder);
533         FLAC__ASSERT(0 != encoder->private_);
534         return FLAC__stream_encoder_get_do_mid_side_stereo(encoder->private_->stream_encoder);
535 }
536
537 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder)
538 {
539         FLAC__ASSERT(0 != encoder);
540         FLAC__ASSERT(0 != encoder->private_);
541         return FLAC__stream_encoder_get_loose_mid_side_stereo(encoder->private_->stream_encoder);
542 }
543
544 FLAC_API unsigned FLAC__seekable_stream_encoder_get_channels(const FLAC__SeekableStreamEncoder *encoder)
545 {
546         FLAC__ASSERT(0 != encoder);
547         FLAC__ASSERT(0 != encoder->private_);
548         return FLAC__stream_encoder_get_channels(encoder->private_->stream_encoder);
549 }
550
551 FLAC_API unsigned FLAC__seekable_stream_encoder_get_bits_per_sample(const FLAC__SeekableStreamEncoder *encoder)
552 {
553         FLAC__ASSERT(0 != encoder);
554         FLAC__ASSERT(0 != encoder->private_);
555         return FLAC__stream_encoder_get_bits_per_sample(encoder->private_->stream_encoder);
556 }
557
558 FLAC_API unsigned FLAC__seekable_stream_encoder_get_sample_rate(const FLAC__SeekableStreamEncoder *encoder)
559 {
560         FLAC__ASSERT(0 != encoder);
561         FLAC__ASSERT(0 != encoder->private_);
562         return FLAC__stream_encoder_get_sample_rate(encoder->private_->stream_encoder);
563 }
564
565 FLAC_API unsigned FLAC__seekable_stream_encoder_get_blocksize(const FLAC__SeekableStreamEncoder *encoder)
566 {
567         FLAC__ASSERT(0 != encoder);
568         FLAC__ASSERT(0 != encoder->private_);
569         return FLAC__stream_encoder_get_blocksize(encoder->private_->stream_encoder);
570 }
571
572 FLAC_API unsigned FLAC__seekable_stream_encoder_get_max_lpc_order(const FLAC__SeekableStreamEncoder *encoder)
573 {
574         FLAC__ASSERT(0 != encoder);
575         FLAC__ASSERT(0 != encoder->private_);
576         return FLAC__stream_encoder_get_max_lpc_order(encoder->private_->stream_encoder);
577 }
578
579 FLAC_API unsigned FLAC__seekable_stream_encoder_get_qlp_coeff_precision(const FLAC__SeekableStreamEncoder *encoder)
580 {
581         FLAC__ASSERT(0 != encoder);
582         FLAC__ASSERT(0 != encoder->private_);
583         return FLAC__stream_encoder_get_qlp_coeff_precision(encoder->private_->stream_encoder);
584 }
585
586 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__SeekableStreamEncoder *encoder)
587 {
588         FLAC__ASSERT(0 != encoder);
589         FLAC__ASSERT(0 != encoder->private_);
590         return FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->stream_encoder);
591 }
592
593 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_escape_coding(const FLAC__SeekableStreamEncoder *encoder)
594 {
595         FLAC__ASSERT(0 != encoder);
596         FLAC__ASSERT(0 != encoder->private_);
597         return FLAC__stream_encoder_get_do_escape_coding(encoder->private_->stream_encoder);
598 }
599
600 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(const FLAC__SeekableStreamEncoder *encoder)
601 {
602         FLAC__ASSERT(0 != encoder);
603         FLAC__ASSERT(0 != encoder->private_);
604         return FLAC__stream_encoder_get_do_exhaustive_model_search(encoder->private_->stream_encoder);
605 }
606
607 FLAC_API unsigned FLAC__seekable_stream_encoder_get_min_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder)
608 {
609         FLAC__ASSERT(0 != encoder);
610         FLAC__ASSERT(0 != encoder->private_);
611         return FLAC__stream_encoder_get_min_residual_partition_order(encoder->private_->stream_encoder);
612 }
613
614 FLAC_API unsigned FLAC__seekable_stream_encoder_get_max_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder)
615 {
616         FLAC__ASSERT(0 != encoder);
617         FLAC__ASSERT(0 != encoder->private_);
618         return FLAC__stream_encoder_get_max_residual_partition_order(encoder->private_->stream_encoder);
619 }
620
621 FLAC_API unsigned FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(const FLAC__SeekableStreamEncoder *encoder)
622 {
623         FLAC__ASSERT(0 != encoder);
624         FLAC__ASSERT(0 != encoder->private_);
625         return FLAC__stream_encoder_get_rice_parameter_search_dist(encoder->private_->stream_encoder);
626 }
627
628 FLAC_API FLAC__uint64 FLAC__seekable_stream_encoder_get_total_samples_estimate(const FLAC__SeekableStreamEncoder *encoder)
629 {
630         FLAC__ASSERT(0 != encoder);
631         FLAC__ASSERT(0 != encoder->private_);
632         return FLAC__stream_encoder_get_total_samples_estimate(encoder->private_->stream_encoder);
633 }
634
635 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_process(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
636 {
637         FLAC__ASSERT(0 != encoder);
638         FLAC__ASSERT(0 != encoder->private_);
639         if(!FLAC__stream_encoder_process(encoder->private_->stream_encoder, buffer, samples)) {
640                 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
641                 return false;
642         }
643         else
644                 return true;
645 }
646
647 /* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */
648 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_process_interleaved(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
649 {
650         FLAC__ASSERT(0 != encoder);
651         FLAC__ASSERT(0 != encoder->private_);
652         if(!FLAC__stream_encoder_process_interleaved(encoder->private_->stream_encoder, buffer, samples)) {
653                 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
654                 return false;
655         }
656         else
657                 return true;
658 }
659
660 /***********************************************************************
661  *
662  * Private class methods
663  *
664  ***********************************************************************/
665
666 void set_defaults_(FLAC__SeekableStreamEncoder *encoder)
667 {
668         FLAC__ASSERT(0 != encoder);
669         FLAC__ASSERT(0 != encoder->private_);
670         FLAC__ASSERT(0 != encoder->protected_);
671
672         encoder->private_->seek_callback = 0;
673         encoder->private_->write_callback = 0;
674         encoder->private_->client_data = 0;
675
676         encoder->private_->seek_table = 0;
677 }
678
679 FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
680 {
681         FLAC__SeekableStreamEncoder *seekable_stream_encoder = (FLAC__SeekableStreamEncoder*)client_data;
682         FLAC__StreamEncoderWriteStatus status;
683
684         /*
685          * Watch for the first SEEKTABLE block to go by and store its offset.
686          */
687         if(samples == 0 && (buffer[0] & 0x7f) == FLAC__METADATA_TYPE_SEEKTABLE)
688                 seekable_stream_encoder->private_->seektable_offset = seekable_stream_encoder->private_->bytes_written;
689
690         /*
691          * Mark the current seek point if hit (if stream_offset == 0 that
692          * means we're still writing metadata and haven't hit the first
693          * frame yet)
694          */
695         if(0 != seekable_stream_encoder->private_->seek_table && seekable_stream_encoder->private_->stream_offset > 0 && seekable_stream_encoder->private_->seek_table->num_points > 0) {
696                 /*@@@ WATCHOUT: assumes the encoder is fixed-blocksize, which will be true indefinitely: */
697                 const unsigned blocksize = FLAC__stream_encoder_get_blocksize(encoder);
698                 const FLAC__uint64 frame_first_sample = (FLAC__uint64)current_frame * (FLAC__uint64)blocksize;
699                 const FLAC__uint64 frame_last_sample = frame_first_sample + (FLAC__uint64)blocksize - 1;
700                 FLAC__uint64 test_sample;
701                 unsigned i;
702                 for(i = seekable_stream_encoder->private_->first_seekpoint_to_check; i < seekable_stream_encoder->private_->seek_table->num_points; i++) {
703                         test_sample = seekable_stream_encoder->private_->seek_table->points[i].sample_number;
704                         if(test_sample > frame_last_sample) {
705                                 break;
706                         }
707                         else if(test_sample >= frame_first_sample) {
708                                 seekable_stream_encoder->private_->seek_table->points[i].sample_number = frame_first_sample;
709                                 seekable_stream_encoder->private_->seek_table->points[i].stream_offset = seekable_stream_encoder->private_->bytes_written - seekable_stream_encoder->private_->stream_offset;
710                                 seekable_stream_encoder->private_->seek_table->points[i].frame_samples = blocksize;
711                                 seekable_stream_encoder->private_->first_seekpoint_to_check++;
712                                 /* DO NOT: "break;" and here's why:
713                                  * The seektable template may contain more than one target
714                                  * sample for any given frame; we will keep looping, generating
715                                  * duplicate seekpoints for them, and we'll clean it up later,
716                                  * just before writing the seektable back to the metadata.
717                                  */
718                         }
719                         else {
720                                 seekable_stream_encoder->private_->first_seekpoint_to_check++;
721                         }
722                 }
723         }
724
725         status = seekable_stream_encoder->private_->write_callback(seekable_stream_encoder, buffer, bytes, samples, current_frame, seekable_stream_encoder->private_->client_data);
726
727         if(status == FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
728                 seekable_stream_encoder->private_->bytes_written += bytes;
729         else
730                 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
731
732         return status;
733 }
734
735 void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data)
736 {
737         FLAC__SeekableStreamEncoder *seekable_stream_encoder = (FLAC__SeekableStreamEncoder*)client_data;
738         FLAC__byte b[max(6, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)];
739         const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
740         const unsigned min_framesize = metadata->data.stream_info.min_framesize;
741         const unsigned max_framesize = metadata->data.stream_info.max_framesize;
742         const unsigned bps = metadata->data.stream_info.bits_per_sample;
743
744         FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
745
746         /* We get called by the stream encoder when the encoding process
747          * has finished so that we can update the STREAMINFO and SEEKTABLE
748          * blocks.
749          */
750
751         (void)encoder; /* silence compiler warning about unused parameter */
752
753         /*@@@ reopen callback here?  The docs currently require user to open files in update mode from the start */
754
755         /* All this is based on intimate knowledge of the stream header
756          * layout, but a change to the header format that would break this
757          * would also break all streams encoded in the previous format.
758          */
759
760         /*
761          * Write MD5 signature
762          */
763         if(seekable_stream_encoder->private_->seek_callback(seekable_stream_encoder, 26, seekable_stream_encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
764                 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
765                 return;
766         }
767         if(seekable_stream_encoder->private_->write_callback(seekable_stream_encoder, metadata->data.stream_info.md5sum, 16, 0, 0, seekable_stream_encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
768                 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
769                 return;
770         }
771
772         /*
773          * Write total samples
774          */
775         b[0] = ((FLAC__byte)(bps-1) << 4) | (FLAC__byte)((samples >> 32) & 0x0F);
776         b[1] = (FLAC__byte)((samples >> 24) & 0xFF);
777         b[2] = (FLAC__byte)((samples >> 16) & 0xFF);
778         b[3] = (FLAC__byte)((samples >> 8) & 0xFF);
779         b[4] = (FLAC__byte)(samples & 0xFF);
780         if(seekable_stream_encoder->private_->seek_callback(seekable_stream_encoder, 21, seekable_stream_encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
781                 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
782                 return;
783         }
784         if(seekable_stream_encoder->private_->write_callback(seekable_stream_encoder, b, 5, 0, 0, seekable_stream_encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
785                 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
786                 return;
787         }
788
789         /*
790          * Write min/max framesize
791          */
792         b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF);
793         b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF);
794         b[2] = (FLAC__byte)(min_framesize & 0xFF);
795         b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF);
796         b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF);
797         b[5] = (FLAC__byte)(max_framesize & 0xFF);
798         if(seekable_stream_encoder->private_->seek_callback(seekable_stream_encoder, 12, seekable_stream_encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
799                 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
800                 return;
801         }
802         if(seekable_stream_encoder->private_->write_callback(seekable_stream_encoder, b, 6, 0, 0, seekable_stream_encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
803                 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
804                 return;
805         }
806
807         /*
808          * Write seektable
809          */
810         if(0 != seekable_stream_encoder->private_->seek_table && seekable_stream_encoder->private_->seek_table->num_points > 0 && seekable_stream_encoder->private_->seektable_offset > 0) {
811                 unsigned i;
812
813                 FLAC__format_seektable_sort(seekable_stream_encoder->private_->seek_table);
814
815                 FLAC__ASSERT(FLAC__format_seektable_is_legal(seekable_stream_encoder->private_->seek_table));
816
817                 if(seekable_stream_encoder->private_->seek_callback(seekable_stream_encoder, seekable_stream_encoder->private_->seektable_offset + FLAC__STREAM_METADATA_HEADER_LENGTH, seekable_stream_encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
818                         seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
819                         return;
820                 }
821
822                 for(i = 0; i < seekable_stream_encoder->private_->seek_table->num_points; i++) {
823                         FLAC__uint64 xx;
824                         unsigned x;
825                         xx = seekable_stream_encoder->private_->seek_table->points[i].sample_number;
826                         b[7] = (FLAC__byte)xx; xx >>= 8;
827                         b[6] = (FLAC__byte)xx; xx >>= 8;
828                         b[5] = (FLAC__byte)xx; xx >>= 8;
829                         b[4] = (FLAC__byte)xx; xx >>= 8;
830                         b[3] = (FLAC__byte)xx; xx >>= 8;
831                         b[2] = (FLAC__byte)xx; xx >>= 8;
832                         b[1] = (FLAC__byte)xx; xx >>= 8;
833                         b[0] = (FLAC__byte)xx; xx >>= 8;
834                         xx = seekable_stream_encoder->private_->seek_table->points[i].stream_offset;
835                         b[15] = (FLAC__byte)xx; xx >>= 8;
836                         b[14] = (FLAC__byte)xx; xx >>= 8;
837                         b[13] = (FLAC__byte)xx; xx >>= 8;
838                         b[12] = (FLAC__byte)xx; xx >>= 8;
839                         b[11] = (FLAC__byte)xx; xx >>= 8;
840                         b[10] = (FLAC__byte)xx; xx >>= 8;
841                         b[9] = (FLAC__byte)xx; xx >>= 8;
842                         b[8] = (FLAC__byte)xx; xx >>= 8;
843                         x = seekable_stream_encoder->private_->seek_table->points[i].frame_samples;
844                         b[17] = (FLAC__byte)x; x >>= 8;
845                         b[16] = (FLAC__byte)x; x >>= 8;
846                         if(seekable_stream_encoder->private_->write_callback(seekable_stream_encoder, b, 18, 0, 0, seekable_stream_encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
847                                 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
848                                 return;
849                         }
850                 }
851         }
852 }