1 /* test_libFLAC - Unit tester for libFLAC
2  * Copyright (C) 2000-2009  Josh Coalson
3  * Copyright (C) 2011-2018  Xiph.Org Foundation
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 #  include <config.h>
22 #endif
23 
24 #include "FLAC/assert.h"
25 #include "share/compat.h"
26 #include "private/bitreader.h" /* from the libFLAC private include area */
27 #include "bitreader.h"
28 #include <stdio.h>
29 #include <string.h> /* for memcpy() */
30 
31 /*
32  * WATCHOUT!  Since FLAC__BitReader is a private structure, we use a copy of
33  * the definition here to get at the internals.  Make sure this is kept up
34  * to date with what is in ../libFLAC/bitreader.c
35  */
36 #if (ENABLE_64_BIT_WORDS == 0)
37 
38 typedef FLAC__uint32 brword;
39 #define FLAC__BYTES_PER_WORD 4
40 #define FLAC__BITS_PER_WORD 32
41 
42 #else
43 
44 typedef FLAC__uint64 brword;
45 #define FLAC__BYTES_PER_WORD 8
46 #define FLAC__BITS_PER_WORD 64
47 
48 #endif
49 
50 struct FLAC__BitReader {
51 	/* any partially-consumed word at the head will stay right-justified as bits are consumed from the left */
52 	/* any incomplete word at the tail will be left-justified, and bytes from the read callback are added on the right */
53 	brword *buffer;
54 	uint32_t capacity; /* in words */
55 	uint32_t words; /* # of completed words in buffer */
56 	uint32_t bytes; /* # of bytes in incomplete word at buffer[words] */
57 	uint32_t consumed_words; /* #words ... */
58 	uint32_t consumed_bits; /* ... + (#bits of head word) already consumed from the front of buffer */
59 	uint32_t read_crc16; /* the running frame CRC */
60 	uint32_t crc16_offset; /* the number of words in the current buffer that should not be CRC'd */
61 	uint32_t crc16_align; /* the number of bits in the current consumed word that should not be CRC'd */
62 	FLAC__BitReaderReadCallback read_callback;
63 	void *client_data;
64 };
65 
66 static FLAC__bool read_callback(FLAC__byte buffer[], size_t *bytes, void *data);
67 
test_bitreader(void)68 FLAC__bool test_bitreader(void)
69 {
70 	FLAC__BitReader *br;
71 	FLAC__bool ok;
72 	uint32_t i;
73 	uint32_t words, bits; /* what we think br->consumed_words and br->consumed_bits should be */
74 
75 	FLAC__uint16	 crc,expected_crcs[4] = { 0x5e4c, 0x7f6b, 0x2272, 0x42bf };
76 	FLAC__byte	 data[32];
77 
78 	FLAC__uint32	 val_uint32;
79 	FLAC__uint64	 val_uint64;
80 
81 	for (i = 0; i < 32; i++)
82 		data[i] = i * 8 + 7;
83 
84 	printf("\n+++ libFLAC unit test: bitreader\n\n");
85 
86 	/*
87 	 * test new -> delete
88 	 */
89 	printf("testing new... ");
90 	br = FLAC__bitreader_new();
91 	if(0 == br) {
92 		printf("FAILED, returned NULL\n");
93 		return false;
94 	}
95 	printf("OK\n");
96 
97 	printf("testing delete... ");
98 	FLAC__bitreader_delete(br);
99 	printf("OK\n");
100 
101 	/*
102 	 * test new -> init -> delete
103 	 */
104 	printf("testing new... ");
105 	br = FLAC__bitreader_new();
106 	if(0 == br) {
107 		printf("FAILED, returned NULL\n");
108 		return false;
109 	}
110 	printf("OK\n");
111 
112 	printf("testing init... ");
113 	if(!FLAC__bitreader_init(br, read_callback, data)) {
114 		printf("FAILED, returned false\n");
115 		return false;
116 	}
117 	printf("OK\n");
118 
119 	printf("testing delete... ");
120 	FLAC__bitreader_delete(br);
121 	printf("OK\n");
122 
123 	/*
124 	 * test new -> init -> clear -> delete
125 	 */
126 	printf("testing new... ");
127 	br = FLAC__bitreader_new();
128 	if(0 == br) {
129 		printf("FAILED, returned NULL\n");
130 		return false;
131 	}
132 	printf("OK\n");
133 
134 	printf("testing init... ");
135 	if(!FLAC__bitreader_init(br, read_callback, data)) {
136 		printf("FAILED, returned false\n");
137 		return false;
138 	}
139 	printf("OK\n");
140 
141 	printf("testing clear... ");
142 	if(!FLAC__bitreader_clear(br)) {
143 		printf("FAILED, returned false\n");
144 		return false;
145 	}
146 	printf("OK\n");
147 
148 	printf("testing delete... ");
149 	FLAC__bitreader_delete(br);
150 	printf("OK\n");
151 
152 	/*
153 	 * test normal usage
154 	 */
155 	printf("testing new... ");
156 	br = FLAC__bitreader_new();
157 	if(0 == br) {
158 		printf("FAILED, returned NULL\n");
159 		return false;
160 	}
161 	printf("OK\n");
162 
163 	printf("testing init... ");
164 	if(!FLAC__bitreader_init(br, read_callback, data)) {
165 		printf("FAILED, returned false\n");
166 		return false;
167 	}
168 	printf("OK\n");
169 
170 	printf("testing clear... ");
171 	if(!FLAC__bitreader_clear(br)) {
172 		printf("FAILED, returned false\n");
173 		return false;
174 	}
175 	printf("OK\n");
176 
177 	words = bits = 0;
178 
179 	printf("capacity = %u\n", br->capacity);
180 
181 	printf("testing raw reads... ");
182 	ok =
183 		FLAC__bitreader_read_raw_uint32(br, &val_uint32, 1) &&
184 		FLAC__bitreader_read_raw_uint32(br, &val_uint32, 2) &&
185 		FLAC__bitreader_read_raw_uint32(br, &val_uint32, 5) &&
186 		FLAC__bitreader_read_raw_uint32(br, &val_uint32, 8) &&
187 		FLAC__bitreader_read_raw_uint32(br, &val_uint32, 10) &&
188 		FLAC__bitreader_read_raw_uint32(br, &val_uint32, 4) &&
189 		FLAC__bitreader_read_raw_uint32(br, &val_uint32, 32) &&
190 		FLAC__bitreader_read_raw_uint32(br, &val_uint32, 4) &&
191 		FLAC__bitreader_read_raw_uint32(br, &val_uint32, 2) &&
192 		FLAC__bitreader_read_raw_uint32(br, &val_uint32, 8) &&
193 		FLAC__bitreader_read_raw_uint64(br, &val_uint64, 64) &&
194 		FLAC__bitreader_read_raw_uint32(br, &val_uint32, 12)
195 	;
196 	if(!ok) {
197 		printf("FAILED\n");
198 		FLAC__bitreader_dump(br, stdout);
199 		return false;
200 	}
201 	/* we read 152 bits (=19 bytes) from the bitreader */
202 	words = 152 / FLAC__BITS_PER_WORD;
203 	bits = 152 - words*FLAC__BITS_PER_WORD;
204 
205 	if(br->consumed_words != words) {
206 		printf("FAILED word count %u != %u\n", br->consumed_words, words);
207 		FLAC__bitreader_dump(br, stdout);
208 		return false;
209 	}
210 	if(br->consumed_bits != bits) {
211 		printf("FAILED bit count %u != %u\n", br->consumed_bits, bits);
212 		FLAC__bitreader_dump(br, stdout);
213 		return false;
214 	}
215 	crc = FLAC__bitreader_get_read_crc16(br);
216 	if(crc != expected_crcs[0]) {
217 		printf("FAILED reported CRC 0x%04x does not match expected 0x%04x\n", crc, expected_crcs[0]);
218 		FLAC__bitreader_dump(br, stdout);
219 		return false;
220 	}
221 	printf("OK\n");
222 	FLAC__bitreader_dump(br, stdout);
223 
224 	printf("testing CRC reset... ");
225 	FLAC__bitreader_clear(br);
226 	FLAC__bitreader_reset_read_crc16(br, 0xFFFF);
227 	crc = FLAC__bitreader_get_read_crc16(br);
228 	if(crc != 0xFFFF) {
229 		printf("FAILED reported CRC 0x%04x does not match expected 0xFFFF\n", crc);
230 		FLAC__bitreader_dump(br, stdout);
231 		return false;
232 	}
233 	FLAC__bitreader_reset_read_crc16(br, 0);
234 	crc = FLAC__bitreader_get_read_crc16(br);
235 	if(crc != 0) {
236 		printf("FAILED reported CRC 0x%04x does not match expected 0x0000\n", crc);
237 		FLAC__bitreader_dump(br, stdout);
238 		return false;
239 	}
240 	FLAC__bitreader_read_raw_uint32(br, &val_uint32, 16);
241 	FLAC__bitreader_reset_read_crc16(br, 0);
242 	FLAC__bitreader_read_raw_uint32(br, &val_uint32, 32);
243 	crc = FLAC__bitreader_get_read_crc16(br);
244 	if(crc != expected_crcs[1]) {
245 		printf("FAILED reported CRC 0x%04x does not match expected 0x%04x\n", crc, expected_crcs[1]);
246 		FLAC__bitreader_dump(br, stdout);
247 		return false;
248 	}
249 	printf("OK\n");
250 
251 	printf("testing unaligned < 32 bit reads... ");
252 	FLAC__bitreader_clear(br);
253 	FLAC__bitreader_skip_bits_no_crc(br, 8);
254 	FLAC__bitreader_reset_read_crc16(br, 0);
255 	ok =
256 		FLAC__bitreader_read_raw_uint32(br, &val_uint32, 1) &&
257 		FLAC__bitreader_read_raw_uint32(br, &val_uint32, 2) &&
258 		FLAC__bitreader_read_raw_uint32(br, &val_uint32, 5) &&
259 		FLAC__bitreader_read_raw_uint32(br, &val_uint32, 8)
260 	;
261 	if(!ok) {
262 		printf("FAILED\n");
263 		FLAC__bitreader_dump(br, stdout);
264 		return false;
265 	}
266 	crc = FLAC__bitreader_get_read_crc16(br);
267 	if(crc != expected_crcs[2]) {
268 		printf("FAILED reported CRC 0x%04x does not match expected 0x%04x\n", crc, expected_crcs[2]);
269 		FLAC__bitreader_dump(br, stdout);
270 		return false;
271 	}
272 	printf("OK\n");
273 	FLAC__bitreader_dump(br, stdout);
274 
275 	printf("testing unaligned < 64 bit reads... ");
276 	FLAC__bitreader_clear(br);
277 	FLAC__bitreader_skip_bits_no_crc(br, 8);
278 	FLAC__bitreader_reset_read_crc16(br, 0);
279 	ok =
280 		FLAC__bitreader_read_raw_uint32(br, &val_uint32, 1) &&
281 		FLAC__bitreader_read_raw_uint32(br, &val_uint32, 2) &&
282 		FLAC__bitreader_read_raw_uint32(br, &val_uint32, 5) &&
283 		FLAC__bitreader_read_raw_uint32(br, &val_uint32, 8) &&
284 		FLAC__bitreader_read_raw_uint32(br, &val_uint32, 32)
285 	;
286 	if(!ok) {
287 		printf("FAILED\n");
288 		FLAC__bitreader_dump(br, stdout);
289 		return false;
290 	}
291 	crc = FLAC__bitreader_get_read_crc16(br);
292 	if(crc != expected_crcs[3]) {
293 		printf("FAILED reported CRC 0x%04x does not match expected 0x%04x\n", crc, expected_crcs[3]);
294 		FLAC__bitreader_dump(br, stdout);
295 		return false;
296 	}
297 	printf("OK\n");
298 	FLAC__bitreader_dump(br, stdout);
299 
300 	printf("testing free... ");
301 	FLAC__bitreader_free(br);
302 	printf("OK\n");
303 
304 	printf("testing delete... ");
305 	FLAC__bitreader_delete(br);
306 	printf("OK\n");
307 
308 	printf("\nPASSED!\n");
309 	return true;
310 }
311 
312 /*----------------------------------------------------------------------------*/
313 
read_callback(FLAC__byte buffer[],size_t * bytes,void * data)314 static FLAC__bool read_callback(FLAC__byte buffer[], size_t *bytes, void *data)
315 {
316 	if (*bytes > 32)
317 		*bytes = 32;
318 
319 	memcpy(buffer, data, *bytes);
320 
321 	return true;
322 }
323