Line data Source code
1 : /*
2 : * libpoporon - gf.c
3 : *
4 : * This file is part of libpoporon.
5 : *
6 : * Author: Brian Armstrong (original, libcorrect)
7 : * SPDX-License-Identifier: BSD-3-Clause
8 : */
9 :
10 : #include "internal/common.h"
11 :
12 35 : extern void poporon_gf_destroy(poporon_gf_t *gf)
13 : {
14 35 : if (!gf) {
15 1 : return;
16 : }
17 :
18 34 : if (gf->exp) {
19 34 : pfree(gf->exp);
20 : }
21 :
22 34 : if (gf->log) {
23 34 : pfree(gf->log);
24 : }
25 :
26 34 : pfree(gf);
27 : }
28 :
29 37 : extern poporon_gf_t *poporon_gf_create(uint8_t symbol_size, uint16_t generator_polynomial)
30 : {
31 : poporon_gf_t *gf;
32 : uint32_t i, element, table_size;
33 :
34 37 : if (symbol_size < 1 || symbol_size > 16) {
35 3 : return NULL;
36 : }
37 :
38 34 : gf = (poporon_gf_t *)pcalloc(1, sizeof(poporon_gf_t));
39 34 : if (!gf) {
40 0 : return NULL;
41 : }
42 :
43 34 : gf->symbol_size = symbol_size;
44 34 : gf->field_size = (1 << symbol_size) - 1;
45 :
46 34 : table_size = 2 * ((uint32_t)gf->field_size + 1);
47 34 : gf->exp = (uint16_t *)pcalloc(table_size, sizeof(uint16_t));
48 34 : if (!gf->exp) {
49 0 : poporon_gf_destroy(gf);
50 0 : return NULL;
51 : }
52 :
53 34 : gf->log = (uint16_t *)pcalloc((uint32_t)gf->field_size + 1, sizeof(uint16_t));
54 34 : if (!gf->log) {
55 0 : poporon_gf_destroy(gf);
56 0 : return NULL;
57 : }
58 :
59 34 : element = 1;
60 34 : gf->exp[0] = (uint16_t)element;
61 :
62 10272 : for (i = 1; i < table_size; i++) {
63 10238 : element <<= 1;
64 10238 : if (element > gf->field_size) {
65 5136 : element ^= generator_polynomial;
66 : }
67 10238 : element &= gf->field_size;
68 10238 : gf->exp[i] = (uint16_t)element;
69 :
70 10238 : if (i <= gf->field_size) {
71 5102 : gf->log[(uint16_t)element] = (uint16_t)i;
72 : }
73 : }
74 :
75 34 : if (gf->exp[gf->field_size] != 1) {
76 0 : poporon_gf_destroy(gf);
77 0 : return NULL;
78 : }
79 :
80 34 : return gf;
81 : }
|