Coverage Report

Created: 2026-08-13 06:22

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
16.2k
    decoder_(::FLAC__stream_decoder_new())
56
16.2k
    { }
57
58
    Stream::~Stream()
59
16.2k
    {
60
16.2k
      if(0 != decoder_) {
61
16.2k
        (void)::FLAC__stream_decoder_finish(decoder_);
62
16.2k
        ::FLAC__stream_decoder_delete(decoder_);
63
16.2k
      }
64
16.2k
    }
65
66
    bool Stream::is_valid() const
67
492k
    {
68
492k
      return 0 != decoder_;
69
492k
    }
70
71
    bool Stream::set_ogg_serial_number(long value)
72
14
    {
73
14
      FLAC__ASSERT(is_valid());
74
14
      return static_cast<bool>(::FLAC__stream_decoder_set_ogg_serial_number(decoder_, value));
75
14
    }
76
77
    bool Stream::set_decode_chained_stream(bool value)
78
9.52k
    {
79
9.52k
      FLAC__ASSERT(is_valid());
80
9.52k
      return static_cast<bool>(::FLAC__stream_decoder_set_decode_chained_stream(decoder_, value));
81
9.52k
    }
82
83
    bool Stream::set_md5_checking(bool value)
84
1.27k
    {
85
1.27k
      FLAC__ASSERT(is_valid());
86
1.27k
      return static_cast<bool>(::FLAC__stream_decoder_set_md5_checking(decoder_, value));
87
1.27k
    }
88
89
    bool Stream::set_metadata_respond(::FLAC__MetadataType type)
90
72
    {
91
72
      FLAC__ASSERT(is_valid());
92
72
      return static_cast<bool>(::FLAC__stream_decoder_set_metadata_respond(decoder_, type));
93
72
    }
94
95
    bool Stream::set_metadata_respond_application(const FLAC__byte id[4])
96
22
    {
97
22
      FLAC__ASSERT(is_valid());
98
22
      return static_cast<bool>(::FLAC__stream_decoder_set_metadata_respond_application(decoder_, id));
99
22
    }
100
101
    bool Stream::set_metadata_respond_all()
102
11.8k
    {
103
11.8k
      FLAC__ASSERT(is_valid());
104
11.8k
      return static_cast<bool>(::FLAC__stream_decoder_set_metadata_respond_all(decoder_));
105
11.8k
    }
106
107
    bool Stream::set_metadata_ignore(::FLAC__MetadataType type)
108
90
    {
109
90
      FLAC__ASSERT(is_valid());
110
90
      return static_cast<bool>(::FLAC__stream_decoder_set_metadata_ignore(decoder_, type));
111
90
    }
112
113
    bool Stream::set_metadata_ignore_application(const FLAC__byte id[4])
114
79
    {
115
79
      FLAC__ASSERT(is_valid());
116
79
      return static_cast<bool>(::FLAC__stream_decoder_set_metadata_ignore_application(decoder_, id));
117
79
    }
118
119
    bool Stream::set_metadata_ignore_all()
120
3.51k
    {
121
3.51k
      FLAC__ASSERT(is_valid());
122
3.51k
      return static_cast<bool>(::FLAC__stream_decoder_set_metadata_ignore_all(decoder_));
123
3.51k
    }
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
346
    {
139
346
      FLAC__ASSERT(is_valid());
140
346
      return static_cast<bool>(::FLAC__stream_decoder_get_md5_checking(decoder_));
141
346
    }
142
143
    FLAC__uint64 Stream::get_total_samples() const
144
463
    {
145
463
      FLAC__ASSERT(is_valid());
146
463
      return ::FLAC__stream_decoder_get_total_samples(decoder_);
147
463
    }
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
164k
    {
157
164k
      FLAC__ASSERT(is_valid());
158
164k
      return ::FLAC__stream_decoder_get_channels(decoder_);
159
164k
    }
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
44.4k
    {
169
44.4k
      FLAC__ASSERT(is_valid());
170
44.4k
      return ::FLAC__stream_decoder_get_bits_per_sample(decoder_);
171
44.4k
    }
172
173
    uint32_t Stream::get_sample_rate() const
174
407
    {
175
407
      FLAC__ASSERT(is_valid());
176
407
      return ::FLAC__stream_decoder_get_sample_rate(decoder_);
177
407
    }
178
179
    uint32_t Stream::get_blocksize() const
180
338
    {
181
338
      FLAC__ASSERT(is_valid());
182
338
      return ::FLAC__stream_decoder_get_blocksize(decoder_);
183
338
    }
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
13.9k
    {
199
13.9k
      FLAC__ASSERT(is_valid());
200
13.9k
      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
13.9k
    }
202
203
    ::FLAC__StreamDecoderInitStatus Stream::init_ogg()
204
1.84k
    {
205
1.84k
      FLAC__ASSERT(is_valid());
206
1.84k
      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.84k
    }
208
209
    bool Stream::finish()
210
16.2k
    {
211
16.2k
      FLAC__ASSERT(is_valid());
212
16.2k
      return static_cast<bool>(::FLAC__stream_decoder_finish(decoder_));
213
16.2k
    }
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
14.9k
    {
223
14.9k
      FLAC__ASSERT(is_valid());
224
14.9k
      return static_cast<bool>(::FLAC__stream_decoder_flush(decoder_));
225
14.9k
    }
226
227
    bool Stream::reset()
228
73.3k
    {
229
73.3k
      FLAC__ASSERT(is_valid());
230
73.3k
      return static_cast<bool>(::FLAC__stream_decoder_reset(decoder_));
231
73.3k
    }
232
233
    bool Stream::process_single()
234
19.9k
    {
235
19.9k
      FLAC__ASSERT(is_valid());
236
19.9k
      return static_cast<bool>(::FLAC__stream_decoder_process_single(decoder_));
237
19.9k
    }
238
239
    bool Stream::process_until_end_of_metadata()
240
65.4k
    {
241
65.4k
      FLAC__ASSERT(is_valid());
242
65.4k
      return static_cast<bool>(::FLAC__stream_decoder_process_until_end_of_metadata(decoder_));
243
65.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
46.4k
    {
253
46.4k
      FLAC__ASSERT(is_valid());
254
46.4k
      return static_cast<bool>(::FLAC__stream_decoder_process_until_end_of_stream(decoder_));
255
46.4k
    }
256
257
    bool Stream::skip_single_frame()
258
2.68k
    {
259
2.68k
      FLAC__ASSERT(is_valid());
260
2.68k
      return static_cast<bool>(::FLAC__stream_decoder_skip_single_frame(decoder_));
261
2.68k
    }
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
978
    {
271
978
      FLAC__ASSERT(is_valid());
272
978
      return static_cast<bool>(::FLAC__stream_decoder_seek_absolute(decoder_, sample));
273
978
    }
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
161k
    {
283
161k
      (void)absolute_byte_offset;
284
161k
      return ::FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED;
285
161k
    }
286
287
    ::FLAC__StreamDecoderLengthStatus Stream::length_callback(FLAC__uint64 *stream_length)
288
776
    {
289
776
      (void)stream_length;
290
776
      return ::FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
291
776
    }
292
293
    bool Stream::eof_callback()
294
440k
    {
295
440k
      return false;
296
440k
    }
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
347k
    {
305
347k
      (void)decoder;
306
347k
      FLAC__ASSERT(0 != client_data);
307
347k
      Stream *instance = reinterpret_cast<Stream *>(client_data);
308
347k
      FLAC__ASSERT(0 != instance);
309
347k
      return instance->read_callback(buffer, bytes);
310
347k
    }
311
312
    ::FLAC__StreamDecoderSeekStatus Stream::seek_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
313
73.0k
    {
314
73.0k
      (void) decoder;
315
73.0k
      FLAC__ASSERT(0 != client_data);
316
73.0k
      Stream *instance = reinterpret_cast<Stream *>(client_data);
317
73.0k
      FLAC__ASSERT(0 != instance);
318
73.0k
      return instance->seek_callback(absolute_byte_offset);
319
73.0k
    }
320
321
    ::FLAC__StreamDecoderTellStatus Stream::tell_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
322
161k
    {
323
161k
      (void) decoder;
324
161k
      FLAC__ASSERT(0 != client_data);
325
161k
      Stream *instance = reinterpret_cast<Stream *>(client_data);
326
161k
      FLAC__ASSERT(0 != instance);
327
161k
      return instance->tell_callback(absolute_byte_offset);
328
161k
    }
329
330
    ::FLAC__StreamDecoderLengthStatus Stream::length_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
331
776
    {
332
776
      (void) decoder;
333
776
      FLAC__ASSERT(0 != client_data);
334
776
      Stream *instance = reinterpret_cast<Stream *>(client_data);
335
776
      FLAC__ASSERT(0 != instance);
336
776
      return instance->length_callback(stream_length);
337
776
    }
338
339
    FLAC__bool Stream::eof_callback_(const ::FLAC__StreamDecoder *decoder, void *client_data)
340
440k
    {
341
440k
      (void) decoder;
342
440k
      FLAC__ASSERT(0 != client_data);
343
440k
      Stream *instance = reinterpret_cast<Stream *>(client_data);
344
440k
      FLAC__ASSERT(0 != instance);
345
440k
      return instance->eof_callback();
346
440k
    }
347
348
    ::FLAC__StreamDecoderWriteStatus Stream::write_callback_(const ::FLAC__StreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
349
119k
    {
350
119k
      (void)decoder;
351
119k
      FLAC__ASSERT(0 != client_data);
352
119k
      Stream *instance = reinterpret_cast<Stream *>(client_data);
353
119k
      FLAC__ASSERT(0 != instance);
354
119k
      return instance->write_callback(frame, buffer);
355
119k
    }
356
357
    void Stream::metadata_callback_(const ::FLAC__StreamDecoder *decoder, const ::FLAC__StreamMetadata *metadata, void *client_data)
358
60.4k
    {
359
60.4k
      (void)decoder;
360
60.4k
      FLAC__ASSERT(0 != client_data);
361
60.4k
      Stream *instance = reinterpret_cast<Stream *>(client_data);
362
60.4k
      FLAC__ASSERT(0 != instance);
363
60.4k
      instance->metadata_callback(metadata);
364
60.4k
    }
365
366
    void Stream::error_callback_(const ::FLAC__StreamDecoder *decoder, ::FLAC__StreamDecoderErrorStatus status, void *client_data)
367
363k
    {
368
363k
      (void)decoder;
369
363k
      FLAC__ASSERT(0 != client_data);
370
363k
      Stream *instance = reinterpret_cast<Stream *>(client_data);
371
363k
      FLAC__ASSERT(0 != instance);
372
363k
      instance->error_callback(status);
373
363k
    }
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