#include <stdio.h>
#include <inttypes.h>
#include "zbuild.h"
#include "deflate.h"
#include "crc32_p.h"
static uint32_t crc_table[8][256];
static uint32_t crc_comb[GF2_DIM][GF2_DIM];
static void gf2_matrix_square(uint32_t *square, const uint32_t *mat);
static void make_crc_table(void);
static void make_crc_combine_table(void);
static void print_crc_table(void);
static void print_crc_combine_table(void);
static void write_table(const uint32_t *, int);
static void gf2_matrix_square(uint32_t *square, const uint32_t *mat) {
int n;
for (n = 0; n < GF2_DIM; n++)
square[n] = gf2_matrix_times(mat, mat[n]);
}
static void make_crc_table(void) {
int n, k;
uint32_t c;
uint32_t poly;
static const unsigned char p[] = {0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26};
poly = 0;
for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
poly |= (uint32_t)1 << (31 - p[n]);
for (n = 0; n < 256; n++) {
c = (uint32_t)n;
for (k = 0; k < 8; k++)
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
crc_table[0][n] = c;
}
for (n = 0; n < 256; n++) {
c = crc_table[0][n];
crc_table[4][n] = ZSWAP32(c);
for (k = 1; k < 4; k++) {
c = crc_table[0][c & 0xff] ^ (c >> 8);
crc_table[k][n] = c;
crc_table[k + 4][n] = ZSWAP32(c);
}
}
}
static void make_crc_combine_table(void) {
int n, k;
k = GF2_DIM - 3;
crc_comb[k][0] = 0xedb88320UL;
uint32_t row = 1;
for (n = 1; n < GF2_DIM; n++) {
crc_comb[k][n] = row;
row <<= 1;
}
gf2_matrix_square(crc_comb[k + 1], crc_comb[k]);
gf2_matrix_square(crc_comb[k + 2], crc_comb[k + 1]);
gf2_matrix_square(crc_comb[0], crc_comb[k + 2]);
for (n = 1; n < k; n++)
gf2_matrix_square(crc_comb[n], crc_comb[n - 1]);
}
static void write_table(const uint32_t *table, int k) {
int n;
for (n = 0; n < k; n++)
printf("%s0x%08" PRIx32 "%s", n % 5 ? "" : " ",
(uint32_t)(table[n]),
n == k - 1 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
}
static void print_crc_table(void) {
int k;
printf("#ifndef CRC32_TBL_H_\n");
printf("#define CRC32_TBL_H_\n\n");
printf("/* crc32_tbl.h -- tables for rapid CRC calculation\n");
printf(" * Generated automatically by makecrct.c\n */\n\n");
printf("static const uint32_t ");
printf("crc_table[8][256] =\n{\n {\n");
write_table(crc_table[0], 256);
for (k = 1; k < 8; k++) {
printf(" },\n {\n");
write_table(crc_table[k], 256);
}
printf(" }\n};\n\n");
printf("#endif /* CRC32_TBL_H_ */\n");
}
static void print_crc_combine_table(void) {
int k;
printf("#ifndef CRC32_COMB_TBL_H_\n");
printf("#define CRC32_COMB_TBL_H_\n\n");
printf("/* crc32_comb_tbl.h -- zero operators table for CRC combine\n");
printf(" * Generated automatically by makecrct.c\n */\n\n");
printf("static const uint32_t ");
printf("crc_comb[%d][%d] =\n{\n {\n", GF2_DIM, GF2_DIM);
write_table(crc_comb[0], GF2_DIM);
for (k = 1; k < GF2_DIM; k++) {
printf(" },\n {\n");
write_table(crc_comb[k], GF2_DIM);
}
printf(" }\n};\n\n");
printf("#endif /* CRC32_COMB_TBL_H_ */\n");
}
int main(int argc, char *argv[]) {
if (argc > 1 && strcmp(argv[1], "-c") == 0) {
make_crc_combine_table();
print_crc_combine_table();
} else {
make_crc_table();
print_crc_table();
}
return 0;
}