You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
2.6 KiB
106 lines
2.6 KiB
/* Common code for intializing a Reed-Solomon control block (char or int symbols) |
|
* Copyright 2004 Phil Karn, KA9Q |
|
* May be used under the terms of the GNU Lesser General Public License (LGPL) |
|
*/ |
|
#undef NULL |
|
#define NULL ((void *)0) |
|
|
|
{ |
|
int i, j, sr,root,iprim; |
|
|
|
rs = NULL; |
|
/* Check parameter ranges */ |
|
if(symsize < 0 || symsize > 8*(int)sizeof(data_t)){ |
|
goto done; |
|
} |
|
|
|
if(fcr < 0 || fcr >= (1<<symsize)) |
|
goto done; |
|
if(prim <= 0 || prim >= (1<<symsize)) |
|
goto done; |
|
if(nroots < 0 || nroots >= (1<<symsize)) |
|
goto done; /* Can't have more roots than symbol values! */ |
|
if(pad < 0 || pad >= ((1<<symsize) -1 - nroots)) |
|
goto done; /* Too much padding */ |
|
|
|
rs = (struct rs *)calloc(1,sizeof(struct rs)); |
|
if(rs == NULL) |
|
goto done; |
|
|
|
rs->mm = symsize; |
|
rs->nn = (1<<symsize)-1; |
|
rs->pad = pad; |
|
|
|
rs->alpha_to = (data_t *)malloc(sizeof(data_t)*(rs->nn+1)); |
|
if(rs->alpha_to == NULL){ |
|
free(rs); |
|
rs = NULL; |
|
goto done; |
|
} |
|
rs->index_of = (data_t *)malloc(sizeof(data_t)*(rs->nn+1)); |
|
if(rs->index_of == NULL){ |
|
free(rs->alpha_to); |
|
free(rs); |
|
rs = NULL; |
|
goto done; |
|
} |
|
|
|
/* Generate Galois field lookup tables */ |
|
rs->index_of[0] = A0; /* log(zero) = -inf */ |
|
rs->alpha_to[A0] = 0; /* alpha**-inf = 0 */ |
|
sr = 1; |
|
for(i=0;i<rs->nn;i++){ |
|
rs->index_of[sr] = i; |
|
rs->alpha_to[i] = sr; |
|
sr <<= 1; |
|
if(sr & (1<<symsize)) |
|
sr ^= gfpoly; |
|
sr &= rs->nn; |
|
} |
|
if(sr != 1){ |
|
/* field generator polynomial is not primitive! */ |
|
free(rs->alpha_to); |
|
free(rs->index_of); |
|
free(rs); |
|
rs = NULL; |
|
goto done; |
|
} |
|
|
|
/* Form RS code generator polynomial from its roots */ |
|
rs->genpoly = (data_t *)malloc(sizeof(data_t)*(nroots+1)); |
|
if(rs->genpoly == NULL){ |
|
free(rs->alpha_to); |
|
free(rs->index_of); |
|
free(rs); |
|
rs = NULL; |
|
goto done; |
|
} |
|
rs->fcr = fcr; |
|
rs->prim = prim; |
|
rs->nroots = nroots; |
|
|
|
/* Find prim-th root of 1, used in decoding */ |
|
for(iprim=1;(iprim % prim) != 0;iprim += rs->nn) |
|
; |
|
rs->iprim = iprim / prim; |
|
|
|
rs->genpoly[0] = 1; |
|
for (i = 0,root=fcr*prim; i < nroots; i++,root += prim) { |
|
rs->genpoly[i+1] = 1; |
|
|
|
/* Multiply rs->genpoly[] by @**(root + x) */ |
|
for (j = i; j > 0; j--){ |
|
if (rs->genpoly[j] != 0) |
|
rs->genpoly[j] = rs->genpoly[j-1] ^ rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[j]] + root)]; |
|
else |
|
rs->genpoly[j] = rs->genpoly[j-1]; |
|
} |
|
/* rs->genpoly[0] can never be zero */ |
|
rs->genpoly[0] = rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[0]] + root)]; |
|
} |
|
/* convert rs->genpoly[] to index form for quicker encoding */ |
|
for (i = 0; i <= nroots; i++) |
|
rs->genpoly[i] = rs->index_of[rs->genpoly[i]]; |
|
done:; |
|
|
|
}
|
|
|