Code Coverage Report for src/decode/stb_vorbis.c


Hit Total Coverage
Lines: 122 122 100.0%
Branches: 368 368 100.0%

1 /*
2 * libnogg: a decoder library for Ogg Vorbis streams
3 * Copyright (c) 2014-2023 Andrew Church <achurch@achurch.org>
4 *
5 * This software may be copied and redistributed under certain conditions;
6 * see the file "COPYING" in the source code distribution for details.
7 * NO WARRANTY is provided with this software.
8 */
9
10 /*
11 * This decoder implementation is based on the public-domain stb_vorbis.c
12 * decoder (version 0.99996) from <http://nothings.org/stb_vorbis/>.
13 * It shares the following limitations with that implementation:
14 * - Lossless sample truncation at the beginning of the stream
15 * (negative initial sample position) is ignored.
16 * - Only a single Ogg bitstream per stream is supported.
17 */
18
19 #include "include/nogg.h"
20 #include "src/common.h"
21 #include "src/decode/common.h"
22 #include "src/decode/crc32.h"
23 #include "src/decode/decode.h"
24 #include "src/decode/io.h"
25 #include "src/decode/packet.h"
26 #include "src/decode/setup.h"
27 #include "src/util/memory.h"
28
29 #include <string.h>
30
31 /*************************************************************************/
32 /**************************** Helper routines ****************************/
33 /*************************************************************************/
34
35 /**
36 * create_handle: Create a new stb_vorbis handle with the given parameters.
37 * Implements stb_vorbis_open_callbacks() and stb_vorbis_open_packet().
38 *
39 * [Parameters]
40 * As for stb_vorbis_open_callbacks() and stb_vorbis_open_packet().
41 * [Return value]
42 * New stb_vorbis handle, or NULL on error.
43 */
44 static stb_vorbis *create_handle(
45 int32_t (*read_callback)(void *opaque, void *buf, int32_t len),
46 void (*seek_callback)(void *opaque, int64_t offset),
47 int64_t (*tell_callback)(void *opaque),
48 void *opaque, int64_t length,
49 const void *id_packet, int32_t id_packet_len,
50 const void *setup_packet, int32_t setup_packet_len,
51 unsigned int options, int *error_ret)
52 {
53 stb_vorbis *handle = mem_alloc(opaque, sizeof(*handle), 0);
54 (18/18) if (!handle) {
55 *error_ret = VORBIS_outofmem;
56 return NULL;
57 }
58 memset(handle, 0, sizeof(*handle));
59
60 handle->read_callback = read_callback;
61 handle->seek_callback = seek_callback;
62 handle->tell_callback = tell_callback;
63 handle->opaque = opaque;
64 handle->packet_mode = (id_packet != NULL);
65 handle->stream_len = length;
66 handle->error = VORBIS__no_error;
67
68 handle->fast_huffman_length = 10;
69 (18/18) if (options & VORBIS_OPTION_FAST_HUFFMAN_LENGTH_FLAG) {
70 const int fast_bits = VORBIS_OPTION_FAST_HUFFMAN_LENGTH_VALUE(options);
71 (18/18) if (fast_bits <= 24) {
72 handle->fast_huffman_length = fast_bits;
73 }
74 }
75 handle->fast_huffman_mask =
76 (UINT32_C(1) << handle->fast_huffman_length) - 1;
77 handle->huffman_binary_search =
78 ((options & VORBIS_OPTION_NO_HUFFMAN_BINARY_SEARCH) == 0);
79 handle->divides_in_residue =
80 ((options & VORBIS_OPTION_DIVIDES_IN_RESIDUE) != 0);
81 handle->divides_in_codebook =
82 ((options & VORBIS_OPTION_DIVIDES_IN_CODEBOOK) != 0);
83 handle->scan_for_next_page =
84 ((options & VORBIS_OPTION_SCAN_FOR_NEXT_PAGE) != 0);
85
86 (18/18) if (!start_decoder(handle, id_packet, id_packet_len,
87 setup_packet, setup_packet_len)) {
88 *error_ret = handle->error;
89 stb_vorbis_close(handle);
90 return NULL;
91 }
92
93 return handle;
94 }
95
96 /*************************************************************************/
97 /************************** Interface routines ***************************/
98 /*************************************************************************/
99
100 stb_vorbis *stb_vorbis_open_callbacks(
101 int32_t (*read_callback)(void *opaque, void *buf, int32_t len),
102 void (*seek_callback)(void *opaque, int64_t offset),
103 int64_t (*tell_callback)(void *opaque),
104 void *opaque, int64_t length, unsigned int options, int *error_ret)
105 {
106 return create_handle(read_callback, seek_callback, tell_callback, opaque,
107 length, NULL, 0, NULL, 0, options, error_ret);
108 }
109
110 /*-----------------------------------------------------------------------*/
111
112 stb_vorbis *stb_vorbis_open_packet(
113 void *opaque, const void *id_packet, int32_t id_packet_len,
114 const void *setup_packet, int32_t setup_packet_len,
115 unsigned int options, int *error_ret)
116 {
117 return create_handle(NULL, NULL, NULL, opaque, -1, id_packet,
118 id_packet_len, setup_packet, setup_packet_len,
119 options, error_ret);
120 }
121
122 /*-----------------------------------------------------------------------*/
123
124 void stb_vorbis_close(stb_vorbis *handle)
125 {
126 (18/18) if (handle->codebooks) {
127 (18/18) for (int i = 0; i < handle->codebook_count; i++) {
128 Codebook *book = &handle->codebooks[i];
129 mem_free(handle->opaque, book->codeword_lengths);
130 mem_free(handle->opaque, book->multiplicands);
131 mem_free(handle->opaque, book->codewords);
132 mem_free(handle->opaque, book->fast_huffman);
133 mem_free(handle->opaque, book->sorted_codewords);
134 /* book->sorted_values points one entry past the allocated
135 * address (see notes in setup.c). */
136 (18/18) if (book->sorted_values) {
137 mem_free(handle->opaque, book->sorted_values-1);
138 }
139 }
140 mem_free(handle->opaque, handle->codebooks);
141 }
142
143 (18/18) if (handle->floor_config) {
144 (18/18) for (int i = 0; i < handle->floor_count; i++) {
145 Floor *floor = &handle->floor_config[i];
146 (18/18) if (handle->floor_types[i] == 0) {
147 mem_free(handle->opaque, floor->floor0.map[0]);
148 }
149 }
150 mem_free(handle->opaque, handle->floor_config);
151 }
152
153 (18/18) if (handle->residue_config) {
154 (18/18) for (int i = 0; i < handle->residue_count; i++) {
155 Residue *res = &handle->residue_config[i];
156 (18/18) if (res->classdata) {
157 mem_free(handle->opaque, res->classdata[0]);
158 mem_free(handle->opaque, res->classdata);
159 }
160 mem_free(handle->opaque, res->residue_books);
161 }
162 mem_free(handle->opaque, handle->residue_config);
163 }
164
165 (18/18) if (handle->mapping) {
166 (18/18) for (int i = 0; i < handle->mapping_count; i++) {
167 mem_free(handle->opaque, handle->mapping[i].coupling);
168 }
169 mem_free(handle->opaque, handle->mapping[0].mux);
170 mem_free(handle->opaque, handle->mapping);
171 }
172
173 #ifndef USE_LOOKUP_TABLES
174 (8/8) for (int i = 0; i < 2; i++) {
175 mem_free(handle->opaque, handle->A[i]);
176 mem_free(handle->opaque, handle->B[i]);
177 mem_free(handle->opaque, handle->C[i]);
178 mem_free(handle->opaque, handle->bit_reverse[i]);
179 mem_free(handle->opaque, handle->window_weights[i]);
180 }
181 #endif
182
183 mem_free(handle->opaque, handle->channel_buffers[0]);
184 mem_free(handle->opaque, handle->outputs);
185 mem_free(handle->opaque, handle->previous_window);
186 mem_free(handle->opaque, handle->coefficients);
187 mem_free(handle->opaque, handle->final_Y);
188 mem_free(handle->opaque, handle->classifications);
189 mem_free(handle->opaque, handle->imdct_temp_buf);
190
191 mem_free(handle->opaque, handle);
192 }
193
194 /*-----------------------------------------------------------------------*/
195
196 STBVorbisError stb_vorbis_get_error(stb_vorbis *handle)
197 {
198 const STBVorbisError last_error = handle->error;
199 handle->error = VORBIS__no_error;
200 return last_error;
201 }
202
203 /*-----------------------------------------------------------------------*/
204
205 stb_vorbis_info stb_vorbis_get_info(stb_vorbis *handle)
206 {
207 return ((stb_vorbis_info){
208 .sample_rate = handle->sample_rate,
209 .nominal_bitrate = handle->nominal_bitrate,
210 .min_bitrate = handle->min_bitrate,
211 .max_bitrate = handle->max_bitrate,
212 .channels = handle->channels,
213 /* The maximum data size that can be returned for a frame is in
214 * the case of a long block preceded by another long block and
215 * followed by a short block. */
216 .max_frame_size = handle->blocksize[1]*3/4 - handle->blocksize[0]/4,
217 });
218 }
219
220 /*-----------------------------------------------------------------------*/
221
222 uint64_t stb_vorbis_tell_pcm(stb_vorbis *handle)
223 {
224 (18/18) return handle->current_loc_valid ? handle->current_loc : 0;
225 }
226
227 /*-----------------------------------------------------------------------*/
228
229 uint64_t stb_vorbis_tell_bits(stb_vorbis *handle)
230 {
231 (18/18) if (handle->stream_len >= 0) {
232 uint64_t byte_pos = (*handle->tell_callback)(handle->opaque);
233 (18/18) if (handle->segment_size > 0) {
234 byte_pos -= handle->segment_size;
235 byte_pos += handle->segment_pos;
236 }
237 return byte_pos * 8 - max(handle->valid_bits, 0);
238 } else {
239 return 0;
240 }
241 }
242
243 /*-----------------------------------------------------------------------*/
244
245 void stb_vorbis_reset_eof(stb_vorbis *handle)
246 {
247 handle->eof = false;
248 }
249
250 /*-----------------------------------------------------------------------*/
251
252 bool stb_vorbis_get_frame_float(stb_vorbis *handle, float ***output_ret,
253 int *len_ret)
254 {
255 ASSERT(!handle->packet_mode);
256
257 int len;
258 (18/18) if (!vorbis_decode_packet(handle, &len)) {
259 return false;
260 }
261 *len_ret = len;
262 *output_ret = handle->outputs;
263 return true;
264 }
265
266 /*-----------------------------------------------------------------------*/
267
268 bool stb_vorbis_decode_packet_float(
269 stb_vorbis *handle, const void *packet, int32_t packet_len,
270 float ***output_ret, int *len_ret)
271 {
272 ASSERT(handle->packet_mode);
273
274 int len;
275 (18/18) if (!vorbis_decode_packet_direct(handle, packet, packet_len, &len)) {
276 return false;
277 }
278 *len_ret = len;
279 *output_ret = handle->outputs;
280 return true;
281 }
282
283 /*************************************************************************/
284 /*************************************************************************/