Coverage Report

Created: 2025-12-14 06:20

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