49 #define ALPHA_ZERO ((uintGF) self->nn) 55 #define MIN(a,b) (((a) < (b)) ? (a) : (b)) 83 rvUint8 pp_9[10] = { 1, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
86 rvUint8 pp_10[11] = { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
89 rvUint8 pp_11[12] = { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
92 rvUint8 pp_12[13] = { 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1 };
95 rvUint8 pp_13[14] = { 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
98 rvUint8 pp_14[15] = { 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 };
101 rvUint8 pp_15[16] = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
104 rvUint8 pp_16[17] = { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1 };
108 #define modnn(x) ((x) % self->nn) 133 uintGF *alphaTo =
self->alphaTo;
134 uintGF *indexOf =
self->indexOf;
138 for (i = 0; i < mm; i++) {
139 alphaTo[i] = (
uintGF) mask;
140 indexOf[alphaTo[i]] = (
uintGF) i;
142 alphaTo[mm] ^= (
uintGF) mask;
146 indexOf[alphaTo[mm]] = mm;
148 for (i = mm + 1; i < nn; i++) {
149 if (alphaTo[i - 1] >= mask) {
150 alphaTo[i] = alphaTo[mm] ^ ((alphaTo[i - 1] ^ mask) << 1);
152 alphaTo[i] = alphaTo[i - 1] << 1;
154 indexOf[alphaTo[i]] = (
uintGF) i;
171 uintGF *alphaTo =
self->alphaTo;
172 uintGF *indexOf =
self->indexOf;
176 for (i = 2; i <=
self->paritySize; i++) {
178 for (j = i - 1; j > 0; --j) {
190 for (i = 0; i <=
self->paritySize; i++) {
191 gg[i] = indexOf[gg[i]];
212 nn = ((1 << mm) - 1);
213 kk = nn - paritySize;
216 blockSize = dataSize + paritySize;
219 zeroSize = nn - blockSize;
222 if ((blockSize < 1) || (blockSize > nn))
return NULL;
223 if ((dataSize < 1) || (dataSize >= blockSize))
return NULL;
226 if (symbolSize == 3) pp =
pp_3;
227 else if (symbolSize == 4) pp =
pp_4;
228 else if (symbolSize == 5) pp =
pp_5;
229 else if (symbolSize == 6) pp =
pp_6;
230 else if (symbolSize == 7) pp =
pp_7;
231 else if (symbolSize == 8) pp =
pp_8;
236 gg = (
uintGF*) malloc(
sizeof(
uintGF) * (paritySize + 1));
241 if ((
self != NULL) && (gg != NULL) &&
242 (alphaTo != NULL) && (indexOf != NULL)) {
249 self->zeroSize = zeroSize;
250 self->dataSize = dataSize;
251 self->paritySize = paritySize;
252 self->blockSize = blockSize;
256 self->alphaTo = alphaTo;
257 self->indexOf = indexOf;
266 if (
self) free(
self);
268 if (alphaTo) free(alphaTo);
269 if (indexOf) free(indexOf);
288 uintGF *alphaTo =
self->alphaTo;
289 uintGF *indexOf =
self->indexOf;
292 for (i = 0; i <
self->paritySize; ++i) parityBuffer[i] = 0;
295 for (i = self->zeroSize + self->dataSize; i >= 0; --i) {
299 indexOf[((i >=
self->zeroSize) ? dataBuffer[i - self->zeroSize] : 0) ^
300 parityBuffer[
self->paritySize - 1]];
304 for (j = self->paritySize - 1; j > 0; --j) {
307 parityBuffer[j - 1] ^ alphaTo[
modnn(gg[j] + feedback)];
309 parityBuffer[j] = parityBuffer[j - 1];
312 parityBuffer[0] = alphaTo[
modnn(gg[0] + feedback)];
314 for (j = self->paritySize - 1; j > 0; --j) {
315 parityBuffer[j] = parityBuffer[j - 1];
350 uintGF *alphaTo =
self->alphaTo;
351 uintGF *indexOf =
self->indexOf;
357 for (i = nn - 1; i >= 0; --i) {
360 indexOf[(i >=
self->zeroSize) ? blockBuffer[i - self->zeroSize] : 0];
364 syndromes = (
uintGF*) alloca(
sizeof(
uintGF) * (
self->paritySize + 1));
371 for (i = 1; i <=
self->paritySize; i++) {
375 for (j = 0; j < nn; j++) {
383 syn_error |= syndrome;
386 syndromes[i] = indexOf[syndrome];
395 lambda = (
uintGF*) alloca(
sizeof(
uintGF) * (
self->paritySize + 1));
398 for (i = 1; i <
self->paritySize + 1; ++i) lambda[i] = 0;
402 b = (
uintGF*) alloca(
sizeof(
uintGF) * (
self->paritySize + 1));
403 t = (
uintGF*) alloca(
sizeof(
uintGF) * (
self->paritySize + 1));
405 for (i = 0; i <
self->paritySize + 1; i++) {
406 b[i] = indexOf[lambda[i]];
412 for (r = 1; r <=
self->paritySize; ++r) {
416 for (i = 0; i < r; i++) {
417 if ((lambda[i] != 0) && (syndromes[r - i] !=
ALPHA_ZERO)) {
419 alphaTo[
modnn(indexOf[lambda[i]] + syndromes[r - i])];
424 discrepancy = indexOf[discrepancy];
429 for (i = self->paritySize - 1; i >= 0; --i) {
439 for (i = 0 ; i <
self->paritySize; i++) {
441 t[i+1] = lambda[i+1] ^ alphaTo[
modnn(discrepancy + b[i])];
443 t[i+1] = lambda[i+1];
447 if ((2 * el) <= (r - 1)) {
451 for (i = 0; i <=
self->paritySize; i++) {
453 modnn(indexOf[lambda[i]] - discrepancy + nn);
457 for (i = self->paritySize - 1; i >= 0; --i) {
465 for (i = 0; i <
self->paritySize + 1; ++i) lambda[i] = t[i];
472 for (i = 0; i <
self->paritySize + 1; ++i) {
473 lambda[i] = indexOf[lambda[i]];
481 reg = (
uintGF*) alloca(
sizeof(
uintGF) * (
self->paritySize + 1));
482 root = (
uintGF*) alloca(
sizeof(
uintGF) *
self->paritySize);
485 for (i = 1; i <
self->paritySize + 1; ++i) {
492 for (i = 1; i <= nn; i++) {
495 for (j = deg_lambda; j > 0; j--) {
497 reg[j] =
modnn(reg[j] + j);
498 q ^= alphaTo[reg[j]];
511 printf(
"\n Final error positions:\t");
512 for (i = 0; i < count; i++) {
513 printf(
"%d ", loc[i]);
520 if (deg_lambda != count) {
526 omega = (
uintGF*) alloca(
sizeof(
uintGF) * (
self->paritySize + 1));
531 for (i = 0; i <
self->paritySize; ++i) {
534 for (j = (deg_lambda < i) ? deg_lambda : i; j >= 0; --j) {
537 tmp ^= alphaTo[
modnn(syndromes[i + 1 - j] + lambda[j])];
545 omega[i] = indexOf[tmp];
551 for (j = count - 1; j >= 0; j--) {
558 for (i = deg_omega; i >= 0; i--) {
560 num1 ^= alphaTo[
modnn(omega[i] + i * root[j])];
570 for (i =
MIN(deg_lambda, self->paritySize - 1) & ~1; i >= 0; i -=2) {
572 den ^= alphaTo[
modnn(lambda[i+1] + i * root[j])];
578 printf(
"\n ERROR: denominator = 0\n");
586 if (loc[j] < self->zeroSize) {
591 if ((loc[j] >= self->zeroSize) &&
592 (loc[j] < self->zeroSize + self->dataSize)) {
593 blockBuffer[loc[j] -
self->zeroSize] ^=
594 alphaTo[
modnn(indexOf[num1] + indexOf[num2] +
609 unsigned char data_bytes[8];
614 for (index = 0; index < size; index++) {
622 for (index = 0; index < size; index++) {
635 unsigned char data_bytes[8];
639 for (index = 0; index < 8; index++) {
647 for (index = 0; index < 8; index++) {
654 unsigned int symbol_size,
655 unsigned int data_size,
656 unsigned int parity_size)
658 return rvFec_New(symbol_size, data_size, parity_size);
rvInt16 rvFec_Correct(rvFec *self, rvUint8 *blockBuffer)
static void rvFec_InitGaloisField(rvFec *self, rvUint8 *pp)
rvFec * rvFec_New(rvInt16 symbolSize, rvInt16 dataSize, rvInt16 paritySize)
FEC FEC__create(unsigned int symbol_size, unsigned int data_size, unsigned int parity_size)
static void rvFec_InitPolynomial(rvFec *self)
void FEC__parity(FEC fec, unsigned int *data, unsigned int size)
rvInt16 rvFec_Parity(rvFec *self, rvUint8 *dataBuffer, rvUint8 *parityBuffer)
bool FEC__correct(FEC fec, unsigned int *data, unsigned int size)