Coverage Report

Created: 2025-11-15 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/flac/src/libFLAC++/stream_decoder.cpp
Line
Count
Source
1
/* libFLAC++ - Free Lossless Audio Codec library
2
 * Copyright (C) 2002-2009  Josh Coalson
3
 * Copyright (C) 2011-2025  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
#ifdef HAVE_CONFIG_H
34
#include "config.h"
35
#endif
36
37
#include "FLAC++/decoder.h"
38
#include "FLAC/assert.h"
39
40
#ifdef _MSC_VER
41
// warning C4800: 'int' : forcing to bool 'true' or 'false' (performance warning)
42
#pragma warning ( disable : 4800 )
43
#endif
44
45
namespace FLAC {
46
  namespace Decoder {
47
48
    // ------------------------------------------------------------
49
    //
50
    // Stream
51
    //
52
    // ------------------------------------------------------------
53
54
    Stream::Stream():
55
14.9k
    decoder_(::FLAC__stream_decoder_new())
56
14.9k
    { }
57
58
    Stream::~Stream()
59
14.9k
    {
60
14.9k
      if(0 != decoder_) {
61
14.9k
        (void)::FLAC__stream_decoder_finish(decoder_);
62
14.9k
        ::FLAC__stream_decoder_delete(decoder_);
63
14.9k
      }
64
14.9k
    }
65
66
    bool Stream::is_valid() const
67
458k
    {
68
458k
      return 0 != decoder_;
69
458k
    }
70
71
    bool Stream::set_ogg_serial_number(long value)
72
36
    {
73
36
      FLAC__ASSERT(is_valid());
74
36
      return static_cast<bool>(::FLAC__stream_decoder_set_ogg_serial_number(decoder_, value));
75
36
    }
76
77
    bool Stream::set_decode_chained_stream(bool value)
78
8.28k
    {
79
8.28k
      FLAC__ASSERT(is_valid());
80
8.28k
      return static_cast<bool>(::FLAC__stream_decoder_set_decode_chained_stream(decoder_, value));
81
8.28k
    }
82
83
    bool Stream::set_md5_checking(bool value)
84
1.34k
    {
85
1.34k
      FLAC__ASSERT(is_valid());
86
1.34k
      return static_cast<bool>(::FLAC__stream_decoder_set_md5_checking(decoder_, value));
87
1.34k
    }
88
89
    bool Stream::set_metadata_respond(::FLAC__MetadataType type)
90
75
    {
91
75
      FLAC__ASSERT(is_valid());
92
75
      return static_cast<bool>(::FLAC__stream_decoder_set_metadata_respond(decoder_, type));
93
75
    }
94
95
    bool Stream::set_metadata_respond_application(const FLAC__byte id[4])
96
17
    {
97
17
      FLAC__ASSERT(is_valid());
98
17
      return static_cast<bool>(::FLAC__stream_decoder_set_metadata_respond_application(decoder_, id));
99
17
    }
100
101
    bool Stream::set_metadata_respond_all()
102
11.0k
    {
103
11.0k
      FLAC__ASSERT(is_valid());
104
11.0k
      return static_cast<bool>(::FLAC__stream_decoder_set_metadata_respond_all(decoder_));
105
11.0k
    }
106
107
    bool Stream::set_metadata_ignore(::FLAC__MetadataType type)
108
95
    {
109
95
      FLAC__ASSERT(is_valid());
110
95
      return static_cast<bool>(::FLAC__stream_decoder_set_metadata_ignore(decoder_, type));
111
95
    }
112
113
    bool Stream::set_metadata_ignore_application(const FLAC__byte id[4])
114
61
    {
115
61
      FLAC__ASSERT(is_valid());
116
61
      return static_cast<bool>(::FLAC__stream_decoder_set_metadata_ignore_application(decoder_, id));
117
61
    }
118
119
    bool Stream::set_metadata_ignore_all()
120
2.77k
    {
121
2.77k
      FLAC__ASSERT(is_valid());
122
2.77k
      return static_cast<bool>(::FLAC__stream_decoder_set_metadata_ignore_all(decoder_));
123
2.77k
    }
124
125
    Stream::State Stream::get_state() const
126
0
    {
127
0
      FLAC__ASSERT(is_valid());
128
0
      return State(::FLAC__stream_decoder_get_state(decoder_));
129
0
    }
130
131
    bool Stream::get_decode_chained_stream() const
132
0
    {
133
0
      FLAC__ASSERT(is_valid());
134
0
      return static_cast<bool>(::FLAC__stream_decoder_get_decode_chained_stream(decoder_));
135
0
    }
136
137
    bool Stream::get_md5_checking() const
138
235
    {
139
235
      FLAC__ASSERT(is_valid());
140
235
      return static_cast<bool>(::FLAC__stream_decoder_get_md5_checking(decoder_));
141
235
    }
142
143
    FLAC__uint64 Stream::get_total_samples() const
144
664
    {
145
664
      FLAC__ASSERT(is_valid());
146
664
      return ::FLAC__stream_decoder_get_total_samples(decoder_);
147
664
    }
148
149
    FLAC__uint64 Stream::find_total_samples()
150
0
    {
151
0
      FLAC__ASSERT(is_valid());
152
0
      return ::FLAC__stream_decoder_find_total_samples(decoder_);
153
0
    }
154
155
    uint32_t Stream::get_channels() const
156
142k
    {
157
142k
      FLAC__ASSERT(is_valid());
158
142k
      return ::FLAC__stream_decoder_get_channels(decoder_);
159
142k
    }
160
161
    ::FLAC__ChannelAssignment Stream::get_channel_assignment() const
162
0
    {
163
0
      FLAC__ASSERT(is_valid());
164
0
      return ::FLAC__stream_decoder_get_channel_assignment(decoder_);
165
0
    }
166
167
    uint32_t Stream::get_bits_per_sample() const
168
36.5k
    {
169
36.5k
      FLAC__ASSERT(is_valid());
170
36.5k
      return ::FLAC__stream_decoder_get_bits_per_sample(decoder_);
171
36.5k
    }
172
173
    uint32_t Stream::get_sample_rate() const
174
483
    {
175
483
      FLAC__ASSERT(is_valid());
176
483
      return ::FLAC__stream_decoder_get_sample_rate(decoder_);
177
483
    }
178
179
    uint32_t Stream::get_blocksize() const
180
182
    {
181
182
      FLAC__ASSERT(is_valid());
182
182
      return ::FLAC__stream_decoder_get_blocksize(decoder_);
183
182
    }
184
185
    bool Stream::get_decode_position(FLAC__uint64 *position) const
186
0
    {
187
0
      FLAC__ASSERT(is_valid());
188
0
      return ::FLAC__stream_decoder_get_decode_position(decoder_, position);
189
0
    }
190
191
    int32_t Stream::get_link_lengths(FLAC__uint64 **link_lengths)
192
0
    {
193
0
      FLAC__ASSERT(is_valid());
194
0
      return ::FLAC__stream_decoder_get_link_lengths(decoder_, link_lengths);
195
0
    }
196
197
    ::FLAC__StreamDecoderInitStatus Stream::init()
198
12.8k
    {
199
12.8k
      FLAC__ASSERT(is_valid());
200
12.8k
      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);
201
12.8k
    }
202
203
    ::FLAC__StreamDecoderInitStatus Stream::init_ogg()
204
1.72k
    {
205
1.72k
      FLAC__ASSERT(is_valid());
206
1.72k
      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);
207
1.72k
    }
208
209
    bool Stream::finish()
210
14.9k
    {
211
14.9k
      FLAC__ASSERT(is_valid());
212
14.9k
      return static_cast<bool>(::FLAC__stream_decoder_finish(decoder_));
213
14.9k
    }
214
215
    bool Stream::finish_link()
216
0
    {
217
0
      FLAC__ASSERT(is_valid());
218
0
      return static_cast<bool>(::FLAC__stream_decoder_finish_link(decoder_));
219
0
    }
220
221
    bool Stream::flush()
222
13.0k
    {
223
13.0k
      FLAC__ASSERT(is_valid());
224
13.0k
      return static_cast<bool>(::FLAC__stream_decoder_flush(decoder_));
225
13.0k
    }
226
227
    bool Stream::reset()
228
78.0k
    {
229
78.0k
      FLAC__ASSERT(is_valid());
230
78.0k
      return static_cast<bool>(::FLAC__stream_decoder_reset(decoder_));
231
78.0k
    }
232
233
    bool Stream::process_single()
234
16.7k
    {
235
16.7k
      FLAC__ASSERT(is_valid());
236
16.7k
      return static_cast<bool>(::FLAC__stream_decoder_process_single(decoder_));
237
16.7k
    }
238
239
    bool Stream::process_until_end_of_metadata()
240
82.4k
    {
241
82.4k
      FLAC__ASSERT(is_valid());
242
82.4k
      return static_cast<bool>(::FLAC__stream_decoder_process_until_end_of_metadata(decoder_));
243
82.4k
    }
244
245
    bool Stream::process_until_end_of_link()
246
0
    {
247
0
      FLAC__ASSERT(is_valid());
248
0
      return static_cast<bool>(::FLAC__stream_decoder_process_until_end_of_link(decoder_));
249
0
    }
250
251
    bool Stream::process_until_end_of_stream()
252
31.7k
    {
253
31.7k
      FLAC__ASSERT(is_valid());
254
31.7k
      return static_cast<bool>(::FLAC__stream_decoder_process_until_end_of_stream(decoder_));
255
31.7k
    }
256
257
    bool Stream::skip_single_frame()
258
1.67k
    {
259
1.67k
      FLAC__ASSERT(is_valid());
260
1.67k
      return static_cast<bool>(::FLAC__stream_decoder_skip_single_frame(decoder_));
261
1.67k
    }
262
263
    bool Stream::skip_single_link()
264
0
    {
265
0
      FLAC__ASSERT(is_valid());
266
0
      return static_cast<bool>(::FLAC__stream_decoder_skip_single_link(decoder_));
267
0
    }
268
269
    bool Stream::seek_absolute(FLAC__uint64 sample)
270
940
    {
271
940
      FLAC__ASSERT(is_valid());
272
940
      return static_cast<bool>(::FLAC__stream_decoder_seek_absolute(decoder_, sample));
273
940
    }
274
275
    ::FLAC__StreamDecoderSeekStatus Stream::seek_callback(FLAC__uint64 absolute_byte_offset)
276
0
    {
277
0
      (void)absolute_byte_offset;
278
0
      return ::FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED;
279
0
    }
280
281
    ::FLAC__StreamDecoderTellStatus Stream::tell_callback(FLAC__uint64 *absolute_byte_offset)
282
146k
    {
283
146k
      (void)absolute_byte_offset;
284
146k
      return ::FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED;
285
146k
    }
286
287
    ::FLAC__StreamDecoderLengthStatus Stream::length_callback(FLAC__uint64 *stream_length)
288
729
    {
289
729
      (void)stream_length;
290
729
      return ::FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
291
729
    }
292
293
    bool Stream::eof_callback()
294
176k
    {
295
176k
      return false;
296
176k
    }
297
298
    void Stream::metadata_callback(const ::FLAC__StreamMetadata *metadata)
299
0
    {
300
0
      (void)metadata;
301
0
    }
302
303
    ::FLAC__StreamDecoderReadStatus Stream::read_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
304
230k
    {
305
230k
      (void)decoder;
306
230k
      FLAC__ASSERT(0 != client_data);
307
230k
      Stream *instance = reinterpret_cast<Stream *>(client_data);
308
230k
      FLAC__ASSERT(0 != instance);
309
230k
      return instance->read_callback(buffer, bytes);
310
230k
    }
311
312
    ::FLAC__StreamDecoderSeekStatus Stream::seek_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
313
77.7k
    {
314
77.7k
      (void) decoder;
315
77.7k
      FLAC__ASSERT(0 != client_data);
316
77.7k
      Stream *instance = reinterpret_cast<Stream *>(client_data);
317
77.7k
      FLAC__ASSERT(0 != instance);
318
77.7k
      return instance->seek_callback(absolute_byte_offset);
319
77.7k
    }
320
321
    ::FLAC__StreamDecoderTellStatus Stream::tell_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
322
146k
    {
323
146k
      (void) decoder;
324
146k
      FLAC__ASSERT(0 != client_data);
325
146k
      Stream *instance = reinterpret_cast<Stream *>(client_data);
326
146k
      FLAC__ASSERT(0 != instance);
327
146k
      return instance->tell_callback(absolute_byte_offset);
328
146k
    }
329
330
    ::FLAC__StreamDecoderLengthStatus Stream::length_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
331
729
    {
332
729
      (void) decoder;
333
729
      FLAC__ASSERT(0 != client_data);
334
729
      Stream *instance = reinterpret_cast<Stream *>(client_data);
335
729
      FLAC__ASSERT(0 != instance);
336
729
      return instance->length_callback(stream_length);
337
729
    }
338
339
    FLAC__bool Stream::eof_callback_(const ::FLAC__StreamDecoder *decoder, void *client_data)
340
176k
    {
341
176k
      (void) decoder;
342
176k
      FLAC__ASSERT(0 != client_data);
343
176k
      Stream *instance = reinterpret_cast<Stream *>(client_data);
344
176k
      FLAC__ASSERT(0 != instance);
345
176k
      return instance->eof_callback();
346
176k
    }
347
348
    ::FLAC__StreamDecoderWriteStatus Stream::write_callback_(const ::FLAC__StreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
349
106k
    {
350
106k
      (void)decoder;
351
106k
      FLAC__ASSERT(0 != client_data);
352
106k
      Stream *instance = reinterpret_cast<Stream *>(client_data);
353
106k
      FLAC__ASSERT(0 != instance);
354
106k
      return instance->write_callback(frame, buffer);
355
106k
    }
356
357
    void Stream::metadata_callback_(const ::FLAC__StreamDecoder *decoder, const ::FLAC__StreamMetadata *metadata, void *client_data)
358
64.7k
    {
359
64.7k
      (void)decoder;
360
64.7k
      FLAC__ASSERT(0 != client_data);
361
64.7k
      Stream *instance = reinterpret_cast<Stream *>(client_data);
362
64.7k
      FLAC__ASSERT(0 != instance);
363
64.7k
      instance->metadata_callback(metadata);
364
64.7k
    }
365
366
    void Stream::error_callback_(const ::FLAC__StreamDecoder *decoder, ::FLAC__StreamDecoderErrorStatus status, void *client_data)
367
326k
    {
368
326k
      (void)decoder;
369
326k
      FLAC__ASSERT(0 != client_data);
370
326k
      Stream *instance = reinterpret_cast<Stream *>(client_data);
371
326k
      FLAC__ASSERT(0 != instance);
372
326k
      instance->error_callback(status);
373
326k
    }
374
375
    // ------------------------------------------------------------
376
    //
377
    // File
378
    //
379
    // ------------------------------------------------------------
380
381
    File::File():
382
0
      Stream()
383
0
    { }
384
385
    File::~File()
386
    {
387
    }
388
389
    ::FLAC__StreamDecoderInitStatus File::init(FILE *file)
390
0
    {
391
0
      FLAC__ASSERT(0 != decoder_);
392
0
      return ::FLAC__stream_decoder_init_FILE(decoder_, file, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this);
393
0
    }
394
395
    ::FLAC__StreamDecoderInitStatus File::init(const char *filename)
396
0
    {
397
0
      FLAC__ASSERT(0 != decoder_);
398
0
      return ::FLAC__stream_decoder_init_file(decoder_, filename, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this);
399
0
    }
400
401
    ::FLAC__StreamDecoderInitStatus File::init(const std::string &filename)
402
0
    {
403
0
      return init(filename.c_str());
404
0
    }
405
406
    ::FLAC__StreamDecoderInitStatus File::init_ogg(FILE *file)
407
0
    {
408
0
      FLAC__ASSERT(0 != decoder_);
409
0
      return ::FLAC__stream_decoder_init_ogg_FILE(decoder_, file, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this);
410
0
    }
411
412
    ::FLAC__StreamDecoderInitStatus File::init_ogg(const char *filename)
413
0
    {
414
0
      FLAC__ASSERT(0 != decoder_);
415
0
      return ::FLAC__stream_decoder_init_ogg_file(decoder_, filename, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this);
416
0
    }
417
418
    ::FLAC__StreamDecoderInitStatus File::init_ogg(const std::string &filename)
419
0
    {
420
0
      return init_ogg(filename.c_str());
421
0
    }
422
423
    // This is a dummy to satisfy the pure virtual from Stream; the
424
    // read callback will never be called since we are initializing
425
    // with FLAC__stream_decoder_init_FILE() or
426
    // FLAC__stream_decoder_init_file() and those supply the read
427
    // callback internally.
428
    ::FLAC__StreamDecoderReadStatus File::read_callback(FLAC__byte buffer[], size_t *bytes)
429
0
    {
430
0
      (void)buffer, (void)bytes;
431
0
      FLAC__ASSERT(false);
432
0
      return ::FLAC__STREAM_DECODER_READ_STATUS_ABORT; // double protection
433
0
    }
434
435
  } // namespace Decoder
436
} // namespace FLAC