src/libFLAC/stream_decoder.c : Fix buffer read overflow.
[platform/upstream/flac.git] / src / libFLAC++ / stream_encoder.cpp
1 /* libFLAC++ - Free Lossless Audio Codec library
2  * Copyright (C) 2002-2009  Josh Coalson
3  * Copyright (C) 2011-2013  Xiph.Org Foundation
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * - Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * - Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * - Neither the name of the Xiph.org Foundation nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include "FLAC++/encoder.h"
34 #include "FLAC++/metadata.h"
35 #include "FLAC/assert.h"
36
37 #ifdef _MSC_VER
38 // warning C4800: 'int' : forcing to bool 'true' or 'false' (performance warning)
39 #pragma warning ( disable : 4800 )
40 #endif
41
42 namespace FLAC {
43         namespace Encoder {
44
45                 // ------------------------------------------------------------
46                 //
47                 // Stream
48                 //
49                 // ------------------------------------------------------------
50
51                 Stream::Stream():
52                 encoder_(::FLAC__stream_encoder_new())
53                 { }
54
55                 Stream::~Stream()
56                 {
57                         if(0 != encoder_) {
58                                 (void)::FLAC__stream_encoder_finish(encoder_);
59                                 ::FLAC__stream_encoder_delete(encoder_);
60                         }
61                 }
62
63                 bool Stream::is_valid() const
64                 {
65                         return 0 != encoder_;
66                 }
67
68                 bool Stream::set_ogg_serial_number(long value)
69                 {
70                         FLAC__ASSERT(is_valid());
71                         return (bool)::FLAC__stream_encoder_set_ogg_serial_number(encoder_, value);
72                 }
73
74                 bool Stream::set_verify(bool value)
75                 {
76                         FLAC__ASSERT(is_valid());
77                         return (bool)::FLAC__stream_encoder_set_verify(encoder_, value);
78                 }
79
80                 bool Stream::set_streamable_subset(bool value)
81                 {
82                         FLAC__ASSERT(is_valid());
83                         return (bool)::FLAC__stream_encoder_set_streamable_subset(encoder_, value);
84                 }
85
86                 bool Stream::set_channels(unsigned value)
87                 {
88                         FLAC__ASSERT(is_valid());
89                         return (bool)::FLAC__stream_encoder_set_channels(encoder_, value);
90                 }
91
92                 bool Stream::set_bits_per_sample(unsigned value)
93                 {
94                         FLAC__ASSERT(is_valid());
95                         return (bool)::FLAC__stream_encoder_set_bits_per_sample(encoder_, value);
96                 }
97
98                 bool Stream::set_sample_rate(unsigned value)
99                 {
100                         FLAC__ASSERT(is_valid());
101                         return (bool)::FLAC__stream_encoder_set_sample_rate(encoder_, value);
102                 }
103
104                 bool Stream::set_compression_level(unsigned value)
105                 {
106                         FLAC__ASSERT(is_valid());
107                         return (bool)::FLAC__stream_encoder_set_compression_level(encoder_, value);
108                 }
109
110                 bool Stream::set_blocksize(unsigned value)
111                 {
112                         FLAC__ASSERT(is_valid());
113                         return (bool)::FLAC__stream_encoder_set_blocksize(encoder_, value);
114                 }
115
116                 bool Stream::set_do_mid_side_stereo(bool value)
117                 {
118                         FLAC__ASSERT(is_valid());
119                         return (bool)::FLAC__stream_encoder_set_do_mid_side_stereo(encoder_, value);
120                 }
121
122                 bool Stream::set_loose_mid_side_stereo(bool value)
123                 {
124                         FLAC__ASSERT(is_valid());
125                         return (bool)::FLAC__stream_encoder_set_loose_mid_side_stereo(encoder_, value);
126                 }
127
128                 bool Stream::set_apodization(const char *specification)
129                 {
130                         FLAC__ASSERT(is_valid());
131                         return (bool)::FLAC__stream_encoder_set_apodization(encoder_, specification);
132                 }
133
134                 bool Stream::set_max_lpc_order(unsigned value)
135                 {
136                         FLAC__ASSERT(is_valid());
137                         return (bool)::FLAC__stream_encoder_set_max_lpc_order(encoder_, value);
138                 }
139
140                 bool Stream::set_qlp_coeff_precision(unsigned value)
141                 {
142                         FLAC__ASSERT(is_valid());
143                         return (bool)::FLAC__stream_encoder_set_qlp_coeff_precision(encoder_, value);
144                 }
145
146                 bool Stream::set_do_qlp_coeff_prec_search(bool value)
147                 {
148                         FLAC__ASSERT(is_valid());
149                         return (bool)::FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder_, value);
150                 }
151
152                 bool Stream::set_do_escape_coding(bool value)
153                 {
154                         FLAC__ASSERT(is_valid());
155                         return (bool)::FLAC__stream_encoder_set_do_escape_coding(encoder_, value);
156                 }
157
158                 bool Stream::set_do_exhaustive_model_search(bool value)
159                 {
160                         FLAC__ASSERT(is_valid());
161                         return (bool)::FLAC__stream_encoder_set_do_exhaustive_model_search(encoder_, value);
162                 }
163
164                 bool Stream::set_min_residual_partition_order(unsigned value)
165                 {
166                         FLAC__ASSERT(is_valid());
167                         return (bool)::FLAC__stream_encoder_set_min_residual_partition_order(encoder_, value);
168                 }
169
170                 bool Stream::set_max_residual_partition_order(unsigned value)
171                 {
172                         FLAC__ASSERT(is_valid());
173                         return (bool)::FLAC__stream_encoder_set_max_residual_partition_order(encoder_, value);
174                 }
175
176                 bool Stream::set_rice_parameter_search_dist(unsigned value)
177                 {
178                         FLAC__ASSERT(is_valid());
179                         return (bool)::FLAC__stream_encoder_set_rice_parameter_search_dist(encoder_, value);
180                 }
181
182                 bool Stream::set_total_samples_estimate(FLAC__uint64 value)
183                 {
184                         FLAC__ASSERT(is_valid());
185                         return (bool)::FLAC__stream_encoder_set_total_samples_estimate(encoder_, value);
186                 }
187
188                 bool Stream::set_metadata(::FLAC__StreamMetadata **metadata, unsigned num_blocks)
189                 {
190                         FLAC__ASSERT(is_valid());
191                         return (bool)::FLAC__stream_encoder_set_metadata(encoder_, metadata, num_blocks);
192                 }
193
194                 bool Stream::set_metadata(FLAC::Metadata::Prototype **metadata, unsigned num_blocks)
195                 {
196                         FLAC__ASSERT(is_valid());
197 #ifndef HAVE_CXX_VARARRAYS
198                         // some compilers (MSVC++, Borland C, SunPro, some GCCs w/ -pedantic) can't handle:
199                         // ::FLAC__StreamMetadata *m[num_blocks];
200                         // so we do this ugly workaround
201                         ::FLAC__StreamMetadata **m = new ::FLAC__StreamMetadata*[num_blocks];
202 #else
203                         ::FLAC__StreamMetadata *m[num_blocks];
204 #endif
205                         for(unsigned i = 0; i < num_blocks; i++) {
206                                 // we can get away with the const_cast since we know the encoder will only correct the is_last flags
207                                 m[i] = const_cast< ::FLAC__StreamMetadata*>(static_cast<const ::FLAC__StreamMetadata*>(*metadata[i]));
208                         }
209 #ifndef HAVE_CXX_VARARRAYS
210                         // complete the hack
211                         const bool ok = (bool)::FLAC__stream_encoder_set_metadata(encoder_, m, num_blocks);
212                         delete [] m;
213                         return ok;
214 #else
215                         return (bool)::FLAC__stream_encoder_set_metadata(encoder_, m, num_blocks);
216 #endif
217                 }
218
219                 Stream::State Stream::get_state() const
220                 {
221                         FLAC__ASSERT(is_valid());
222                         return State(::FLAC__stream_encoder_get_state(encoder_));
223                 }
224
225                 Decoder::Stream::State Stream::get_verify_decoder_state() const
226                 {
227                         FLAC__ASSERT(is_valid());
228                         return Decoder::Stream::State(::FLAC__stream_encoder_get_verify_decoder_state(encoder_));
229                 }
230
231                 void Stream::get_verify_decoder_error_stats(FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got)
232                 {
233                         FLAC__ASSERT(is_valid());
234                         ::FLAC__stream_encoder_get_verify_decoder_error_stats(encoder_, absolute_sample, frame_number, channel, sample, expected, got);
235                 }
236
237                 bool Stream::get_verify() const
238                 {
239                         FLAC__ASSERT(is_valid());
240                         return (bool)::FLAC__stream_encoder_get_verify(encoder_);
241                 }
242
243                 bool Stream::get_streamable_subset() const
244                 {
245                         FLAC__ASSERT(is_valid());
246                         return (bool)::FLAC__stream_encoder_get_streamable_subset(encoder_);
247                 }
248
249                 bool Stream::get_do_mid_side_stereo() const
250                 {
251                         FLAC__ASSERT(is_valid());
252                         return (bool)::FLAC__stream_encoder_get_do_mid_side_stereo(encoder_);
253                 }
254
255                 bool Stream::get_loose_mid_side_stereo() const
256                 {
257                         FLAC__ASSERT(is_valid());
258                         return (bool)::FLAC__stream_encoder_get_loose_mid_side_stereo(encoder_);
259                 }
260
261                 unsigned Stream::get_channels() const
262                 {
263                         FLAC__ASSERT(is_valid());
264                         return ::FLAC__stream_encoder_get_channels(encoder_);
265                 }
266
267                 unsigned Stream::get_bits_per_sample() const
268                 {
269                         FLAC__ASSERT(is_valid());
270                         return ::FLAC__stream_encoder_get_bits_per_sample(encoder_);
271                 }
272
273                 unsigned Stream::get_sample_rate() const
274                 {
275                         FLAC__ASSERT(is_valid());
276                         return ::FLAC__stream_encoder_get_sample_rate(encoder_);
277                 }
278
279                 unsigned Stream::get_blocksize() const
280                 {
281                         FLAC__ASSERT(is_valid());
282                         return ::FLAC__stream_encoder_get_blocksize(encoder_);
283                 }
284
285                 unsigned Stream::get_max_lpc_order() const
286                 {
287                         FLAC__ASSERT(is_valid());
288                         return ::FLAC__stream_encoder_get_max_lpc_order(encoder_);
289                 }
290
291                 unsigned Stream::get_qlp_coeff_precision() const
292                 {
293                         FLAC__ASSERT(is_valid());
294                         return ::FLAC__stream_encoder_get_qlp_coeff_precision(encoder_);
295                 }
296
297                 bool Stream::get_do_qlp_coeff_prec_search() const
298                 {
299                         FLAC__ASSERT(is_valid());
300                         return (bool)::FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder_);
301                 }
302
303                 bool Stream::get_do_escape_coding() const
304                 {
305                         FLAC__ASSERT(is_valid());
306                         return (bool)::FLAC__stream_encoder_get_do_escape_coding(encoder_);
307                 }
308
309                 bool Stream::get_do_exhaustive_model_search() const
310                 {
311                         FLAC__ASSERT(is_valid());
312                         return (bool)::FLAC__stream_encoder_get_do_exhaustive_model_search(encoder_);
313                 }
314
315                 unsigned Stream::get_min_residual_partition_order() const
316                 {
317                         FLAC__ASSERT(is_valid());
318                         return ::FLAC__stream_encoder_get_min_residual_partition_order(encoder_);
319                 }
320
321                 unsigned Stream::get_max_residual_partition_order() const
322                 {
323                         FLAC__ASSERT(is_valid());
324                         return ::FLAC__stream_encoder_get_max_residual_partition_order(encoder_);
325                 }
326
327                 unsigned Stream::get_rice_parameter_search_dist() const
328                 {
329                         FLAC__ASSERT(is_valid());
330                         return ::FLAC__stream_encoder_get_rice_parameter_search_dist(encoder_);
331                 }
332
333                 FLAC__uint64 Stream::get_total_samples_estimate() const
334                 {
335                         FLAC__ASSERT(is_valid());
336                         return ::FLAC__stream_encoder_get_total_samples_estimate(encoder_);
337                 }
338
339                 ::FLAC__StreamEncoderInitStatus Stream::init()
340                 {
341                         FLAC__ASSERT(is_valid());
342                         return ::FLAC__stream_encoder_init_stream(encoder_, write_callback_, seek_callback_, tell_callback_, metadata_callback_, /*client_data=*/(void*)this);
343                 }
344
345                 ::FLAC__StreamEncoderInitStatus Stream::init_ogg()
346                 {
347                         FLAC__ASSERT(is_valid());
348                         return ::FLAC__stream_encoder_init_ogg_stream(encoder_, read_callback_, write_callback_, seek_callback_, tell_callback_, metadata_callback_, /*client_data=*/(void*)this);
349                 }
350
351                 bool Stream::finish()
352                 {
353                         FLAC__ASSERT(is_valid());
354                         return (bool)::FLAC__stream_encoder_finish(encoder_);
355                 }
356
357                 bool Stream::process(const FLAC__int32 * const buffer[], unsigned samples)
358                 {
359                         FLAC__ASSERT(is_valid());
360                         return (bool)::FLAC__stream_encoder_process(encoder_, buffer, samples);
361                 }
362
363                 bool Stream::process_interleaved(const FLAC__int32 buffer[], unsigned samples)
364                 {
365                         FLAC__ASSERT(is_valid());
366                         return (bool)::FLAC__stream_encoder_process_interleaved(encoder_, buffer, samples);
367                 }
368
369                 ::FLAC__StreamEncoderReadStatus Stream::read_callback(FLAC__byte buffer[], size_t *bytes)
370                 {
371                         (void)buffer, (void)bytes;
372                         return ::FLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED;
373                 }
374
375                 ::FLAC__StreamEncoderSeekStatus Stream::seek_callback(FLAC__uint64 absolute_byte_offset)
376                 {
377                         (void)absolute_byte_offset;
378                         return ::FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED;
379                 }
380
381                 ::FLAC__StreamEncoderTellStatus Stream::tell_callback(FLAC__uint64 *absolute_byte_offset)
382                 {
383                         (void)absolute_byte_offset;
384                         return ::FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED;
385                 }
386
387                 void Stream::metadata_callback(const ::FLAC__StreamMetadata *metadata)
388                 {
389                         (void)metadata;
390                 }
391
392                 ::FLAC__StreamEncoderReadStatus Stream::read_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
393                 {
394                         (void)encoder;
395                         FLAC__ASSERT(0 != client_data);
396                         Stream *instance = reinterpret_cast<Stream *>(client_data);
397                         FLAC__ASSERT(0 != instance);
398                         return instance->read_callback(buffer, bytes);
399                 }
400
401                 ::FLAC__StreamEncoderWriteStatus Stream::write_callback_(const ::FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data)
402                 {
403                         (void)encoder;
404                         FLAC__ASSERT(0 != client_data);
405                         Stream *instance = reinterpret_cast<Stream *>(client_data);
406                         FLAC__ASSERT(0 != instance);
407                         return instance->write_callback(buffer, bytes, samples, current_frame);
408                 }
409
410                 ::FLAC__StreamEncoderSeekStatus Stream::seek_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
411                 {
412                         (void)encoder;
413                         FLAC__ASSERT(0 != client_data);
414                         Stream *instance = reinterpret_cast<Stream *>(client_data);
415                         FLAC__ASSERT(0 != instance);
416                         return instance->seek_callback(absolute_byte_offset);
417                 }
418
419                 ::FLAC__StreamEncoderTellStatus Stream::tell_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
420                 {
421                         (void)encoder;
422                         FLAC__ASSERT(0 != client_data);
423                         Stream *instance = reinterpret_cast<Stream *>(client_data);
424                         FLAC__ASSERT(0 != instance);
425                         return instance->tell_callback(absolute_byte_offset);
426                 }
427
428                 void Stream::metadata_callback_(const ::FLAC__StreamEncoder *encoder, const ::FLAC__StreamMetadata *metadata, void *client_data)
429                 {
430                         (void)encoder;
431                         FLAC__ASSERT(0 != client_data);
432                         Stream *instance = reinterpret_cast<Stream *>(client_data);
433                         FLAC__ASSERT(0 != instance);
434                         instance->metadata_callback(metadata);
435                 }
436
437                 // ------------------------------------------------------------
438                 //
439                 // File
440                 //
441                 // ------------------------------------------------------------
442
443                 File::File():
444                         Stream()
445                 { }
446
447                 File::~File()
448                 {
449                 }
450
451                 ::FLAC__StreamEncoderInitStatus File::init(FILE *file)
452                 {
453                         FLAC__ASSERT(is_valid());
454                         return ::FLAC__stream_encoder_init_FILE(encoder_, file, progress_callback_, /*client_data=*/(void*)this);
455                 }
456
457                 ::FLAC__StreamEncoderInitStatus File::init(const char *filename)
458                 {
459                         FLAC__ASSERT(is_valid());
460                         return ::FLAC__stream_encoder_init_file(encoder_, filename, progress_callback_, /*client_data=*/(void*)this);
461                 }
462
463                 ::FLAC__StreamEncoderInitStatus File::init(const std::string &filename)
464                 {
465                         return init(filename.c_str());
466                 }
467
468                 ::FLAC__StreamEncoderInitStatus File::init_ogg(FILE *file)
469                 {
470                         FLAC__ASSERT(is_valid());
471                         return ::FLAC__stream_encoder_init_ogg_FILE(encoder_, file, progress_callback_, /*client_data=*/(void*)this);
472                 }
473
474                 ::FLAC__StreamEncoderInitStatus File::init_ogg(const char *filename)
475                 {
476                         FLAC__ASSERT(is_valid());
477                         return ::FLAC__stream_encoder_init_ogg_file(encoder_, filename, progress_callback_, /*client_data=*/(void*)this);
478                 }
479
480                 ::FLAC__StreamEncoderInitStatus File::init_ogg(const std::string &filename)
481                 {
482                         return init_ogg(filename.c_str());
483                 }
484
485                 // This is a dummy to satisfy the pure virtual from Stream; the
486                 // read callback will never be called since we are initializing
487                 // with FLAC__stream_decoder_init_FILE() or
488                 // FLAC__stream_decoder_init_file() and those supply the read
489                 // callback internally.
490                 ::FLAC__StreamEncoderWriteStatus File::write_callback(const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame)
491                 {
492                         (void)buffer, (void)bytes, (void)samples, (void)current_frame;
493                         FLAC__ASSERT(false);
494                         return ::FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; // double protection
495                 }
496
497                 void File::progress_callback(FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate)
498                 {
499                         (void)bytes_written, (void)samples_written, (void)frames_written, (void)total_frames_estimate;
500                 }
501
502                 void File::progress_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data)
503                 {
504                         (void)encoder;
505                         FLAC__ASSERT(0 != client_data);
506                         File *instance = reinterpret_cast<File *>(client_data);
507                         FLAC__ASSERT(0 != instance);
508                         instance->progress_callback(bytes_written, samples_written, frames_written, total_frames_estimate);
509                 }
510
511         }
512 }