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