xref: /aosp_15_r20/external/flac/src/test_libFLAC/crc.c (revision 600f14f40d737144c998e2ec7a483122d3776fbc)
1*600f14f4SXin Li /* test_libFLAC - Unit tester for libFLAC
2*600f14f4SXin Li  * Copyright (C) 2014-2023  Xiph.Org Foundation
3*600f14f4SXin Li  *
4*600f14f4SXin Li  * This program is free software; you can redistribute it and/or
5*600f14f4SXin Li  * modify it under the terms of the GNU General Public License
6*600f14f4SXin Li  * as published by the Free Software Foundation; either version 2
7*600f14f4SXin Li  * of the License, or (at your option) any later version.
8*600f14f4SXin Li  *
9*600f14f4SXin Li  * This program is distributed in the hope that it will be useful,
10*600f14f4SXin Li  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11*600f14f4SXin Li  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12*600f14f4SXin Li  * GNU General Public License for more details.
13*600f14f4SXin Li  *
14*600f14f4SXin Li  * You should have received a copy of the GNU General Public License along
15*600f14f4SXin Li  * with this program; if not, write to the Free Software Foundation, Inc.,
16*600f14f4SXin Li  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17*600f14f4SXin Li  */
18*600f14f4SXin Li 
19*600f14f4SXin Li #ifdef HAVE_CONFIG_H
20*600f14f4SXin Li #  include <config.h>
21*600f14f4SXin Li #endif
22*600f14f4SXin Li 
23*600f14f4SXin Li #include <stdio.h>
24*600f14f4SXin Li 
25*600f14f4SXin Li #include "FLAC/assert.h"
26*600f14f4SXin Li #include "share/compat.h"
27*600f14f4SXin Li #include "private/crc.h"
28*600f14f4SXin Li #include "crc.h"
29*600f14f4SXin Li 
30*600f14f4SXin Li static FLAC__uint8 crc8_update_ref(FLAC__byte byte, FLAC__uint8 crc);
31*600f14f4SXin Li static FLAC__uint16 crc16_update_ref(FLAC__byte byte, FLAC__uint16 crc);
32*600f14f4SXin Li 
33*600f14f4SXin Li static FLAC__bool test_crc8(const FLAC__byte *data, size_t size);
34*600f14f4SXin Li static FLAC__bool test_crc16(const FLAC__byte *data, size_t size);
35*600f14f4SXin Li static FLAC__bool test_crc16_update(const FLAC__byte *data, size_t size);
36*600f14f4SXin Li static FLAC__bool test_crc16_32bit_words(const FLAC__uint32 *words, size_t size);
37*600f14f4SXin Li static FLAC__bool test_crc16_64bit_words(const FLAC__uint64 *words, size_t size);
38*600f14f4SXin Li 
39*600f14f4SXin Li #define DATA_SIZE 32768
40*600f14f4SXin Li 
test_crc(void)41*600f14f4SXin Li FLAC__bool test_crc(void)
42*600f14f4SXin Li {
43*600f14f4SXin Li 	uint32_t i;
44*600f14f4SXin Li 	FLAC__byte data[DATA_SIZE] = { 0 };
45*600f14f4SXin Li 
46*600f14f4SXin Li 	/* Initialize data reproducibly with pseudo-random values. */
47*600f14f4SXin Li 	for (i = 1; i < DATA_SIZE; i++)
48*600f14f4SXin Li 		data[i] = crc8_update_ref(i % 256, data[i - 1]);
49*600f14f4SXin Li 
50*600f14f4SXin Li 	printf("\n+++ libFLAC unit test: crc\n\n");
51*600f14f4SXin Li 
52*600f14f4SXin Li 	if (! test_crc8(data, DATA_SIZE))
53*600f14f4SXin Li 		return false;
54*600f14f4SXin Li 
55*600f14f4SXin Li 	if (! test_crc16(data, DATA_SIZE))
56*600f14f4SXin Li 		return false;
57*600f14f4SXin Li 
58*600f14f4SXin Li 	if (! test_crc16_update(data, DATA_SIZE))
59*600f14f4SXin Li 		return false;
60*600f14f4SXin Li 
61*600f14f4SXin Li 	if (! test_crc16_32bit_words((FLAC__uint32 *)data, DATA_SIZE / 4))
62*600f14f4SXin Li 		return false;
63*600f14f4SXin Li 
64*600f14f4SXin Li 	if (! test_crc16_64bit_words((FLAC__uint64 *)data, DATA_SIZE / 8))
65*600f14f4SXin Li 		return false;
66*600f14f4SXin Li 
67*600f14f4SXin Li 	printf("\nPASSED!\n");
68*600f14f4SXin Li 	return true;
69*600f14f4SXin Li }
70*600f14f4SXin Li 
71*600f14f4SXin Li /*----------------------------------------------------------------------------*/
72*600f14f4SXin Li 
73*600f14f4SXin Li /* Reference implementations of CRC-8 and CRC-16 to check against. */
74*600f14f4SXin Li 
75*600f14f4SXin Li #define CRC8_POLYNOMIAL 0x07
76*600f14f4SXin Li 
crc8_update_ref(FLAC__byte byte,FLAC__uint8 crc)77*600f14f4SXin Li static FLAC__uint8 crc8_update_ref(FLAC__byte byte, FLAC__uint8 crc)
78*600f14f4SXin Li {
79*600f14f4SXin Li     uint32_t i;
80*600f14f4SXin Li 
81*600f14f4SXin Li     crc ^= byte;
82*600f14f4SXin Li 
83*600f14f4SXin Li     for (i = 0; i < 8; i++) {
84*600f14f4SXin Li         crc = (crc << 1) ^ ((crc >> 7) ? CRC8_POLYNOMIAL : 0);
85*600f14f4SXin Li     }
86*600f14f4SXin Li 
87*600f14f4SXin Li     return crc;
88*600f14f4SXin Li }
89*600f14f4SXin Li 
90*600f14f4SXin Li #define CRC16_POLYNOMIAL 0x8005
91*600f14f4SXin Li 
crc16_update_ref(FLAC__byte byte,FLAC__uint16 crc)92*600f14f4SXin Li static FLAC__uint16 crc16_update_ref(FLAC__byte byte, FLAC__uint16 crc)
93*600f14f4SXin Li {
94*600f14f4SXin Li     uint32_t i;
95*600f14f4SXin Li 
96*600f14f4SXin Li     crc ^= byte << 8;
97*600f14f4SXin Li 
98*600f14f4SXin Li     for (i = 0; i < 8; i++) {
99*600f14f4SXin Li         crc = (crc << 1) ^ ((crc >> 15) ? CRC16_POLYNOMIAL : 0);
100*600f14f4SXin Li     }
101*600f14f4SXin Li 
102*600f14f4SXin Li     return crc;
103*600f14f4SXin Li }
104*600f14f4SXin Li 
105*600f14f4SXin Li /*----------------------------------------------------------------------------*/
106*600f14f4SXin Li 
test_crc8(const FLAC__byte * data,size_t size)107*600f14f4SXin Li static FLAC__bool test_crc8(const FLAC__byte *data, size_t size)
108*600f14f4SXin Li {
109*600f14f4SXin Li 	uint32_t i;
110*600f14f4SXin Li 	FLAC__uint8 crc0,crc1;
111*600f14f4SXin Li 
112*600f14f4SXin Li 	printf("testing FLAC__crc8 ... ");
113*600f14f4SXin Li 
114*600f14f4SXin Li 	crc0 = 0;
115*600f14f4SXin Li 	crc1 = FLAC__crc8(data, 0);
116*600f14f4SXin Li 
117*600f14f4SXin Li 	if (crc1 != crc0) {
118*600f14f4SXin Li 		printf("FAILED, FLAC__crc8 returned non-zero CRC for zero bytes of data\n");
119*600f14f4SXin Li 		return false;
120*600f14f4SXin Li 	}
121*600f14f4SXin Li 
122*600f14f4SXin Li 	for (i = 0; i < size; i++) {
123*600f14f4SXin Li 		crc0 = crc8_update_ref(data[i], crc0);
124*600f14f4SXin Li 		crc1 = FLAC__crc8(data, i + 1);
125*600f14f4SXin Li 
126*600f14f4SXin Li 		if (crc1 != crc0) {
127*600f14f4SXin Li 			printf("FAILED, FLAC__crc8 result did not match reference CRC for %u bytes of test data\n", i + 1);
128*600f14f4SXin Li 			return false;
129*600f14f4SXin Li 		}
130*600f14f4SXin Li 	}
131*600f14f4SXin Li 
132*600f14f4SXin Li 	printf("OK\n");
133*600f14f4SXin Li 
134*600f14f4SXin Li 	return true;
135*600f14f4SXin Li }
136*600f14f4SXin Li 
test_crc16(const FLAC__byte * data,size_t size)137*600f14f4SXin Li static FLAC__bool test_crc16(const FLAC__byte *data, size_t size)
138*600f14f4SXin Li {
139*600f14f4SXin Li 	uint32_t i;
140*600f14f4SXin Li 	FLAC__uint16 crc0,crc1;
141*600f14f4SXin Li 
142*600f14f4SXin Li 	printf("testing FLAC__crc16 ... ");
143*600f14f4SXin Li 
144*600f14f4SXin Li 	crc0 = 0;
145*600f14f4SXin Li 	crc1 = FLAC__crc16(data, 0);
146*600f14f4SXin Li 
147*600f14f4SXin Li 	if (crc1 != crc0) {
148*600f14f4SXin Li 		printf("FAILED, FLAC__crc16 returned non-zero CRC for zero bytes of data\n");
149*600f14f4SXin Li 		return false;
150*600f14f4SXin Li 	}
151*600f14f4SXin Li 
152*600f14f4SXin Li 	for (i = 0; i < size; i++) {
153*600f14f4SXin Li 		crc0 = crc16_update_ref(data[i], crc0);
154*600f14f4SXin Li 		crc1 = FLAC__crc16(data, i + 1);
155*600f14f4SXin Li 
156*600f14f4SXin Li 		if (crc1 != crc0) {
157*600f14f4SXin Li 			printf("FAILED, FLAC__crc16 result did not match reference CRC for %u bytes of test data\n", i + 1);
158*600f14f4SXin Li 			return false;
159*600f14f4SXin Li 		}
160*600f14f4SXin Li 	}
161*600f14f4SXin Li 
162*600f14f4SXin Li 	printf("OK\n");
163*600f14f4SXin Li 
164*600f14f4SXin Li 	return true;
165*600f14f4SXin Li }
166*600f14f4SXin Li 
test_crc16_update(const FLAC__byte * data,size_t size)167*600f14f4SXin Li static FLAC__bool test_crc16_update(const FLAC__byte *data, size_t size)
168*600f14f4SXin Li {
169*600f14f4SXin Li 	uint32_t i;
170*600f14f4SXin Li 	FLAC__uint16 crc0,crc1;
171*600f14f4SXin Li 
172*600f14f4SXin Li 	printf("testing FLAC__CRC16_UPDATE macro ... ");
173*600f14f4SXin Li 
174*600f14f4SXin Li 	crc0 = 0;
175*600f14f4SXin Li 	crc1 = 0;
176*600f14f4SXin Li 
177*600f14f4SXin Li 	for (i = 0; i < size; i++) {
178*600f14f4SXin Li 		crc0 = crc16_update_ref(data[i], crc0);
179*600f14f4SXin Li 		crc1 = FLAC__CRC16_UPDATE(data[i], crc1);
180*600f14f4SXin Li 
181*600f14f4SXin Li 		if (crc1 != crc0) {
182*600f14f4SXin Li 			printf("FAILED, FLAC__CRC16_UPDATE result did not match reference CRC after %u bytes of test data\n", i + 1);
183*600f14f4SXin Li 			return false;
184*600f14f4SXin Li 		}
185*600f14f4SXin Li 	}
186*600f14f4SXin Li 
187*600f14f4SXin Li 	printf("OK\n");
188*600f14f4SXin Li 
189*600f14f4SXin Li 	return true;
190*600f14f4SXin Li }
191*600f14f4SXin Li 
test_crc16_32bit_words(const FLAC__uint32 * words,size_t size)192*600f14f4SXin Li static FLAC__bool test_crc16_32bit_words(const FLAC__uint32 *words, size_t size)
193*600f14f4SXin Li {
194*600f14f4SXin Li 	uint32_t n,i,k;
195*600f14f4SXin Li 	FLAC__uint16 crc0,crc1;
196*600f14f4SXin Li 
197*600f14f4SXin Li 	for (n = 1; n <= 16; n++) {
198*600f14f4SXin Li 		printf("testing FLAC__crc16_update_words32 (length=%i) ... ", n);
199*600f14f4SXin Li 
200*600f14f4SXin Li 		crc0 = 0;
201*600f14f4SXin Li 		crc1 = 0;
202*600f14f4SXin Li 
203*600f14f4SXin Li 		for (i = 0; i <= size - n; i += n) {
204*600f14f4SXin Li 			for (k = 0; k < n; k++) {
205*600f14f4SXin Li 				crc0 = crc16_update_ref( words[i + k] >> 24,         crc0);
206*600f14f4SXin Li 				crc0 = crc16_update_ref((words[i + k] >> 16) & 0xFF, crc0);
207*600f14f4SXin Li 				crc0 = crc16_update_ref((words[i + k] >>  8) & 0xFF, crc0);
208*600f14f4SXin Li 				crc0 = crc16_update_ref( words[i + k]        & 0xFF, crc0);
209*600f14f4SXin Li 			}
210*600f14f4SXin Li 
211*600f14f4SXin Li 			crc1 = FLAC__crc16_update_words32(words + i, n, crc1);
212*600f14f4SXin Li 
213*600f14f4SXin Li 			if (crc1 != crc0) {
214*600f14f4SXin Li 				printf("FAILED, FLAC__crc16_update_words32 result did not match reference CRC after %u words of test data\n", i + n);
215*600f14f4SXin Li 				return false;
216*600f14f4SXin Li 			}
217*600f14f4SXin Li 		}
218*600f14f4SXin Li 
219*600f14f4SXin Li 		crc1 = FLAC__crc16_update_words32(words, 0, crc1);
220*600f14f4SXin Li 
221*600f14f4SXin Li 		if (crc1 != crc0) {
222*600f14f4SXin Li 			printf("FAILED, FLAC__crc16_update_words32 called with zero bytes changed CRC value\n");
223*600f14f4SXin Li 			return false;
224*600f14f4SXin Li 		}
225*600f14f4SXin Li 
226*600f14f4SXin Li 		printf("OK\n");
227*600f14f4SXin Li 	}
228*600f14f4SXin Li 
229*600f14f4SXin Li 	return true;
230*600f14f4SXin Li }
231*600f14f4SXin Li 
test_crc16_64bit_words(const FLAC__uint64 * words,size_t size)232*600f14f4SXin Li static FLAC__bool test_crc16_64bit_words(const FLAC__uint64 *words, size_t size)
233*600f14f4SXin Li {
234*600f14f4SXin Li 	uint32_t n,i,k;
235*600f14f4SXin Li 	FLAC__uint16 crc0,crc1;
236*600f14f4SXin Li 
237*600f14f4SXin Li 	for (n = 1; n <= 16; n++) {
238*600f14f4SXin Li 		printf("testing FLAC__crc16_update_words64 (length=%i) ... ", n);
239*600f14f4SXin Li 
240*600f14f4SXin Li 		crc0 = 0;
241*600f14f4SXin Li 		crc1 = 0;
242*600f14f4SXin Li 
243*600f14f4SXin Li 		for (i = 0; i <= size - n; i += n) {
244*600f14f4SXin Li 			for (k = 0; k < n; k++) {
245*600f14f4SXin Li 				crc0 = crc16_update_ref( words[i + k] >> 56,         crc0);
246*600f14f4SXin Li 				crc0 = crc16_update_ref((words[i + k] >> 48) & 0xFF, crc0);
247*600f14f4SXin Li 				crc0 = crc16_update_ref((words[i + k] >> 40) & 0xFF, crc0);
248*600f14f4SXin Li 				crc0 = crc16_update_ref((words[i + k] >> 32) & 0xFF, crc0);
249*600f14f4SXin Li 				crc0 = crc16_update_ref((words[i + k] >> 24) & 0xFF, crc0);
250*600f14f4SXin Li 				crc0 = crc16_update_ref((words[i + k] >> 16) & 0xFF, crc0);
251*600f14f4SXin Li 				crc0 = crc16_update_ref((words[i + k] >>  8) & 0xFF, crc0);
252*600f14f4SXin Li 				crc0 = crc16_update_ref( words[i + k]        & 0xFF, crc0);
253*600f14f4SXin Li 			}
254*600f14f4SXin Li 
255*600f14f4SXin Li 			crc1 = FLAC__crc16_update_words64(words + i, n, crc1);
256*600f14f4SXin Li 
257*600f14f4SXin Li 			if (crc1 != crc0) {
258*600f14f4SXin Li 				printf("FAILED, FLAC__crc16_update_words64 result did not match reference CRC after %u words of test data\n", i + n);
259*600f14f4SXin Li 				return false;
260*600f14f4SXin Li 			}
261*600f14f4SXin Li 		}
262*600f14f4SXin Li 
263*600f14f4SXin Li 		crc1 = FLAC__crc16_update_words64(words, 0, crc1);
264*600f14f4SXin Li 
265*600f14f4SXin Li 		if (crc1 != crc0) {
266*600f14f4SXin Li 			printf("FAILED, FLAC__crc16_update_words64 called with zero bytes changed CRC value\n");
267*600f14f4SXin Li 			return false;
268*600f14f4SXin Li 		}
269*600f14f4SXin Li 
270*600f14f4SXin Li 		printf("OK\n");
271*600f14f4SXin Li 	}
272*600f14f4SXin Li 
273*600f14f4SXin Li 	return true;
274*600f14f4SXin Li }
275