caa01e213678b5e9938219c5e4da3bcc4facc5b7
[platform/upstream/flac.git] / src / libFLAC++ / stream_decoder.cpp
1 /* libFLAC++ - Free Lossless Audio Codec library
2  * Copyright (C) 2002,2003,2004,2005,2006  Josh Coalson
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * - Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * - Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * - Neither the name of the Xiph.org Foundation nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #include "FLAC++/decoder.h"
33 #include "FLAC/assert.h"
34
35 #ifdef _MSC_VER
36 // warning C4800: 'int' : forcing to bool 'true' or 'false' (performance warning)
37 #pragma warning ( disable : 4800 )
38 #endif
39
40 namespace FLAC {
41         namespace Decoder {
42
43                 // ------------------------------------------------------------
44                 //
45                 // Stream
46                 //
47                 // ------------------------------------------------------------
48
49                 Stream::Stream():
50                 decoder_(::FLAC__stream_decoder_new())
51                 { }
52
53                 Stream::Stream(::FLAC__StreamDecoder *decoder):
54                 decoder_(decoder)
55                 { }
56
57                 Stream::~Stream()
58                 {
59             // WATCHOUT: must check for NULL not only because
60             // ::FLAC__stream_encoder_new() might have failed in
61             // the constructor, but also because
62             // OggFLAC::Encoder::Stream deletes the encoder_ before
63             // we get to it here to make the C inheritance magic
64             // work.
65                         if(0 != decoder_) {
66                                 ::FLAC__stream_decoder_finish(decoder_);
67                                 ::FLAC__stream_decoder_delete(decoder_);
68                         }
69                 }
70
71                 bool Stream::is_valid() const
72                 {
73                         return 0 != decoder_;
74                 }
75
76                 bool Stream::set_ogg_serial_number(long value)
77                 {
78                         FLAC__ASSERT(is_valid());
79                         return (bool)::FLAC__stream_decoder_set_ogg_serial_number(decoder_, value);
80                 }
81
82                 bool Stream::set_md5_checking(bool value)
83                 {
84                         FLAC__ASSERT(is_valid());
85                         return (bool)::FLAC__stream_decoder_set_md5_checking(decoder_, value);
86                 }
87
88                 bool Stream::set_metadata_respond(::FLAC__MetadataType type)
89                 {
90                         FLAC__ASSERT(is_valid());
91                         return (bool)::FLAC__stream_decoder_set_metadata_respond(decoder_, type);
92                 }
93
94                 bool Stream::set_metadata_respond_application(const FLAC__byte id[4])
95                 {
96                         FLAC__ASSERT(is_valid());
97                         return (bool)::FLAC__stream_decoder_set_metadata_respond_application(decoder_, id);
98                 }
99
100                 bool Stream::set_metadata_respond_all()
101                 {
102                         FLAC__ASSERT(is_valid());
103                         return (bool)::FLAC__stream_decoder_set_metadata_respond_all(decoder_);
104                 }
105
106                 bool Stream::set_metadata_ignore(::FLAC__MetadataType type)
107                 {
108                         FLAC__ASSERT(is_valid());
109                         return (bool)::FLAC__stream_decoder_set_metadata_ignore(decoder_, type);
110                 }
111
112                 bool Stream::set_metadata_ignore_application(const FLAC__byte id[4])
113                 {
114                         FLAC__ASSERT(is_valid());
115                         return (bool)::FLAC__stream_decoder_set_metadata_ignore_application(decoder_, id);
116                 }
117
118                 bool Stream::set_metadata_ignore_all()
119                 {
120                         FLAC__ASSERT(is_valid());
121                         return (bool)::FLAC__stream_decoder_set_metadata_ignore_all(decoder_);
122                 }
123
124                 Stream::State Stream::get_state() const
125                 {
126                         FLAC__ASSERT(is_valid());
127                         return State(::FLAC__stream_decoder_get_state(decoder_));
128                 }
129
130                 bool Stream::get_md5_checking() const
131                 {
132                         FLAC__ASSERT(is_valid());
133                         return (bool)::FLAC__stream_decoder_get_md5_checking(decoder_);
134                 }
135
136                 FLAC__uint64 Stream::get_total_samples() const
137                 {
138                         FLAC__ASSERT(is_valid());
139                         return ::FLAC__stream_decoder_get_total_samples(decoder_);
140                 }
141
142                 unsigned Stream::get_channels() const
143                 {
144                         FLAC__ASSERT(is_valid());
145                         return ::FLAC__stream_decoder_get_channels(decoder_);
146                 }
147
148                 ::FLAC__ChannelAssignment Stream::get_channel_assignment() const
149                 {
150                         FLAC__ASSERT(is_valid());
151                         return ::FLAC__stream_decoder_get_channel_assignment(decoder_);
152                 }
153
154                 unsigned Stream::get_bits_per_sample() const
155                 {
156                         FLAC__ASSERT(is_valid());
157                         return ::FLAC__stream_decoder_get_bits_per_sample(decoder_);
158                 }
159
160                 unsigned Stream::get_sample_rate() const
161                 {
162                         FLAC__ASSERT(is_valid());
163                         return ::FLAC__stream_decoder_get_sample_rate(decoder_);
164                 }
165
166                 unsigned Stream::get_blocksize() const
167                 {
168                         FLAC__ASSERT(is_valid());
169                         return ::FLAC__stream_decoder_get_blocksize(decoder_);
170                 }
171
172                 ::FLAC__StreamDecoderInitStatus Stream::init()
173                 {
174                         FLAC__ASSERT(is_valid());
175                         return ::FLAC__stream_decoder_init_stream(decoder_, read_callback_, seek_callback_, tell_callback_, length_callback_, eof_callback_, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this);
176                 }
177
178                 ::FLAC__StreamDecoderInitStatus Stream::init_ogg()
179                 {
180                         FLAC__ASSERT(is_valid());
181                         return ::FLAC__stream_decoder_init_ogg_stream(decoder_, read_callback_, seek_callback_, tell_callback_, length_callback_, eof_callback_, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this);
182                 }
183
184                 void Stream::finish()
185                 {
186                         FLAC__ASSERT(is_valid());
187                         ::FLAC__stream_decoder_finish(decoder_);
188                 }
189
190                 bool Stream::flush()
191                 {
192                         FLAC__ASSERT(is_valid());
193                         return (bool)::FLAC__stream_decoder_flush(decoder_);
194                 }
195
196                 bool Stream::reset()
197                 {
198                         FLAC__ASSERT(is_valid());
199                         return (bool)::FLAC__stream_decoder_reset(decoder_);
200                 }
201
202                 bool Stream::process_single()
203                 {
204                         FLAC__ASSERT(is_valid());
205                         return (bool)::FLAC__stream_decoder_process_single(decoder_);
206                 }
207
208                 bool Stream::process_until_end_of_metadata()
209                 {
210                         FLAC__ASSERT(is_valid());
211                         return (bool)::FLAC__stream_decoder_process_until_end_of_metadata(decoder_);
212                 }
213
214                 bool Stream::process_until_end_of_stream()
215                 {
216                         FLAC__ASSERT(is_valid());
217                         return (bool)::FLAC__stream_decoder_process_until_end_of_stream(decoder_);
218                 }
219
220                 bool Stream::skip_single_frame()
221                 {
222                         FLAC__ASSERT(is_valid());
223                         return (bool)::FLAC__stream_decoder_skip_single_frame(decoder_);
224                 }
225
226                 bool Stream::seek_absolute(FLAC__uint64 sample)
227                 {
228                         FLAC__ASSERT(is_valid());
229                         return (bool)::FLAC__stream_decoder_seek_absolute(decoder_, sample);
230                 }
231
232                 ::FLAC__StreamDecoderSeekStatus Stream::seek_callback(FLAC__uint64 absolute_byte_offset)
233                 {
234                         (void)absolute_byte_offset;
235                         return ::FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED;
236                 }
237
238                 ::FLAC__StreamDecoderTellStatus Stream::tell_callback(FLAC__uint64 *absolute_byte_offset)
239                 {
240                         (void)absolute_byte_offset;
241                         return ::FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED;
242                 }
243
244                 ::FLAC__StreamDecoderLengthStatus Stream::length_callback(FLAC__uint64 *stream_length)
245                 {
246                         (void)stream_length;
247                         return ::FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
248                 }
249
250                 bool Stream::eof_callback()
251                 {
252                         return false;
253                 }
254
255                 void Stream::metadata_callback(const ::FLAC__StreamMetadata *metadata)
256                 {
257                         (void)metadata;
258                 }
259
260                 ::FLAC__StreamDecoderReadStatus Stream::read_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
261                 {
262                         (void)decoder;
263                         FLAC__ASSERT(0 != client_data);
264                         Stream *instance = reinterpret_cast<Stream *>(client_data);
265                         FLAC__ASSERT(0 != instance);
266                         return instance->read_callback(buffer, bytes);
267                 }
268
269                 ::FLAC__StreamDecoderSeekStatus Stream::seek_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
270                 {
271                         (void) decoder;
272                         FLAC__ASSERT(0 != client_data);
273                         Stream *instance = reinterpret_cast<Stream *>(client_data);
274                         FLAC__ASSERT(0 != instance);
275                         return instance->seek_callback(absolute_byte_offset);
276                 }
277
278                 ::FLAC__StreamDecoderTellStatus Stream::tell_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
279                 {
280                         (void) decoder;
281                         FLAC__ASSERT(0 != client_data);
282                         Stream *instance = reinterpret_cast<Stream *>(client_data);
283                         FLAC__ASSERT(0 != instance);
284                         return instance->tell_callback(absolute_byte_offset);
285                 }
286
287                 ::FLAC__StreamDecoderLengthStatus Stream::length_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
288                 {
289                         (void) decoder;
290                         FLAC__ASSERT(0 != client_data);
291                         Stream *instance = reinterpret_cast<Stream *>(client_data);
292                         FLAC__ASSERT(0 != instance);
293                         return instance->length_callback(stream_length);
294                 }
295
296                 FLAC__bool Stream::eof_callback_(const ::FLAC__StreamDecoder *decoder, void *client_data)
297                 {
298                         (void) decoder;
299                         FLAC__ASSERT(0 != client_data);
300                         Stream *instance = reinterpret_cast<Stream *>(client_data);
301                         FLAC__ASSERT(0 != instance);
302                         return instance->eof_callback();
303                 }
304
305                 ::FLAC__StreamDecoderWriteStatus Stream::write_callback_(const ::FLAC__StreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
306                 {
307                         (void)decoder;
308                         FLAC__ASSERT(0 != client_data);
309                         Stream *instance = reinterpret_cast<Stream *>(client_data);
310                         FLAC__ASSERT(0 != instance);
311                         return instance->write_callback(frame, buffer);
312                 }
313
314                 void Stream::metadata_callback_(const ::FLAC__StreamDecoder *decoder, const ::FLAC__StreamMetadata *metadata, void *client_data)
315                 {
316                         (void)decoder;
317                         FLAC__ASSERT(0 != client_data);
318                         Stream *instance = reinterpret_cast<Stream *>(client_data);
319                         FLAC__ASSERT(0 != instance);
320                         instance->metadata_callback(metadata);
321                 }
322
323                 void Stream::error_callback_(const ::FLAC__StreamDecoder *decoder, ::FLAC__StreamDecoderErrorStatus status, void *client_data)
324                 {
325                         (void)decoder;
326                         FLAC__ASSERT(0 != client_data);
327                         Stream *instance = reinterpret_cast<Stream *>(client_data);
328                         FLAC__ASSERT(0 != instance);
329                         instance->error_callback(status);
330                 }
331
332                 // ------------------------------------------------------------
333                 //
334                 // File
335                 //
336                 // ------------------------------------------------------------
337
338                 File::File():
339                         Stream()
340                 { }
341
342                 File::~File()
343                 {
344                 }
345
346                 ::FLAC__StreamDecoderInitStatus File::init(FILE *file)
347                 {
348                         FLAC__ASSERT(0 != decoder_);
349                         return ::FLAC__stream_decoder_init_FILE(decoder_, file, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this);
350                 }
351
352                 ::FLAC__StreamDecoderInitStatus File::init(const char *filename)
353                 {
354                         FLAC__ASSERT(0 != decoder_);
355                         return ::FLAC__stream_decoder_init_file(decoder_, filename, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this);
356                 }
357
358                 ::FLAC__StreamDecoderInitStatus File::init(const std::string &filename)
359                 {
360                         return init(filename.c_str());
361                 }
362
363                 ::FLAC__StreamDecoderInitStatus File::init_ogg(FILE *file)
364                 {
365                         FLAC__ASSERT(0 != decoder_);
366                         return ::FLAC__stream_decoder_init_ogg_FILE(decoder_, file, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this);
367                 }
368
369                 ::FLAC__StreamDecoderInitStatus File::init_ogg(const char *filename)
370                 {
371                         FLAC__ASSERT(0 != decoder_);
372                         return ::FLAC__stream_decoder_init_ogg_file(decoder_, filename, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this);
373                 }
374
375                 ::FLAC__StreamDecoderInitStatus File::init_ogg(const std::string &filename)
376                 {
377                         return init_ogg(filename.c_str());
378                 }
379
380                 // This is a dummy to satisfy the pure virtual from Stream; the
381                 // read callback will never be called since we are initializing
382                 // with FLAC__stream_decoder_init_FILE() or
383                 // FLAC__stream_decoder_init_file() and those supply the read
384                 // callback internally.
385                 ::FLAC__StreamDecoderReadStatus File::read_callback(FLAC__byte buffer[], size_t *bytes)
386                 {
387                         (void)buffer, (void)bytes;
388                         FLAC__ASSERT(false);
389                         return ::FLAC__STREAM_DECODER_READ_STATUS_ABORT; // double protection
390                 }
391
392         }
393 }