init_rs.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /* Common code for intializing a Reed-Solomon control block (char or int symbols)
  2. * Copyright 2004 Phil Karn, KA9Q
  3. * May be used under the terms of the GNU Lesser General Public License (LGPL)
  4. */
  5. #undef NULL
  6. #define NULL ((void *)0)
  7. {
  8. int i, j, sr,root,iprim;
  9. rs = NULL;
  10. /* Check parameter ranges */
  11. if(symsize < 0 || symsize > 8*sizeof(data_t)){
  12. goto done;
  13. }
  14. if(fcr < 0 || fcr >= (1<<symsize))
  15. goto done;
  16. if(prim <= 0 || prim >= (1<<symsize))
  17. goto done;
  18. if(nroots < 0 || nroots >= (1<<symsize))
  19. goto done; /* Can't have more roots than symbol values! */
  20. if(pad < 0 || pad >= ((1<<symsize) -1 - nroots))
  21. goto done; /* Too much padding */
  22. rs = (struct rs *)calloc(1,sizeof(struct rs));
  23. if(rs == NULL)
  24. goto done;
  25. rs->mm = symsize;
  26. rs->nn = (1<<symsize)-1;
  27. rs->pad = pad;
  28. rs->alpha_to = (data_t *)malloc(sizeof(data_t)*(rs->nn+1));
  29. if(rs->alpha_to == NULL){
  30. free(rs);
  31. rs = NULL;
  32. goto done;
  33. }
  34. rs->index_of = (data_t *)malloc(sizeof(data_t)*(rs->nn+1));
  35. if(rs->index_of == NULL){
  36. free(rs->alpha_to);
  37. free(rs);
  38. rs = NULL;
  39. goto done;
  40. }
  41. /* Generate Galois field lookup tables */
  42. rs->index_of[0] = A0; /* log(zero) = -inf */
  43. rs->alpha_to[A0] = 0; /* alpha**-inf = 0 */
  44. sr = 1;
  45. for(i=0;i<rs->nn;i++){
  46. rs->index_of[sr] = i;
  47. rs->alpha_to[i] = sr;
  48. sr <<= 1;
  49. if(sr & (1<<symsize))
  50. sr ^= gfpoly;
  51. sr &= rs->nn;
  52. }
  53. if(sr != 1){
  54. /* field generator polynomial is not primitive! */
  55. free(rs->alpha_to);
  56. free(rs->index_of);
  57. free(rs);
  58. rs = NULL;
  59. goto done;
  60. }
  61. /* Form RS code generator polynomial from its roots */
  62. rs->genpoly = (data_t *)malloc(sizeof(data_t)*(nroots+1));
  63. if(rs->genpoly == NULL){
  64. free(rs->alpha_to);
  65. free(rs->index_of);
  66. free(rs);
  67. rs = NULL;
  68. goto done;
  69. }
  70. rs->fcr = fcr;
  71. rs->prim = prim;
  72. rs->nroots = nroots;
  73. /* Find prim-th root of 1, used in decoding */
  74. for(iprim=1;(iprim % prim) != 0;iprim += rs->nn)
  75. ;
  76. rs->iprim = iprim / prim;
  77. rs->genpoly[0] = 1;
  78. for (i = 0,root=fcr*prim; i < nroots; i++,root += prim) {
  79. rs->genpoly[i+1] = 1;
  80. /* Multiply rs->genpoly[] by @**(root + x) */
  81. for (j = i; j > 0; j--){
  82. if (rs->genpoly[j] != 0)
  83. rs->genpoly[j] = rs->genpoly[j-1] ^ rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[j]] + root)];
  84. else
  85. rs->genpoly[j] = rs->genpoly[j-1];
  86. }
  87. /* rs->genpoly[0] can never be zero */
  88. rs->genpoly[0] = rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[0]] + root)];
  89. }
  90. /* convert rs->genpoly[] to index form for quicker encoding */
  91. for (i = 0; i <= nroots; i++)
  92. rs->genpoly[i] = rs->index_of[rs->genpoly[i]];
  93. done:;
  94. }