summaryrefslogtreecommitdiff
path: root/jpwl/encoder/libopenjpeg/rs.c
diff options
context:
space:
mode:
Diffstat (limited to 'jpwl/encoder/libopenjpeg/rs.c')
-rw-r--r--jpwl/encoder/libopenjpeg/rs.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/jpwl/encoder/libopenjpeg/rs.c b/jpwl/encoder/libopenjpeg/rs.c
new file mode 100644
index 00000000..3d27fe3e
--- /dev/null
+++ b/jpwl/encoder/libopenjpeg/rs.c
@@ -0,0 +1,138 @@
+/* rs.c */
+/* This program is an encoder/decoder for Reed-Solomon codes. Encoding is in
+ systematic form, decoding via the Berlekamp iterative algorithm.
+ In the present form , the constants mm, nn, tt, and kk=nn-2tt must be
+ specified (the double letters are used simply to avoid clashes with
+ other n,k,t used in other programs into which this was incorporated!)
+ Also, the irreducible polynomial used to generate GF(2**mm) must also be
+ entered -- these can be found in Lin and Costello, and also Clark and Cain.
+
+ The representation of the elements of GF(2**m) is either in index form,
+ where the number is the power of the primitive element alpha, which is
+ convenient for multiplication (add the powers modulo 2**m-1) or in
+ polynomial form, where the bits represent the coefficients of the
+ polynomial representation of the number, which is the most convenient form
+ for addition. The two forms are swapped between via lookup tables.
+ This leads to fairly messy looking expressions, but unfortunately, there
+ is no easy alternative when working with Galois arithmetic.
+
+ The code is not written in the most elegant way, but to the best
+ of my knowledge, (no absolute guarantees!), it works.
+ However, when including it into a simulation program, you may want to do
+ some conversion of global variables (used here because I am lazy!) to
+ local variables where appropriate, and passing parameters (eg array
+ addresses) to the functions may be a sensible move to reduce the number
+ of global variables and thus decrease the chance of a bug being introduced.
+
+ This program does not handle erasures at present, but should not be hard
+ to adapt to do this, as it is just an adjustment to the Berlekamp-Massey
+ algorithm. It also does not attempt to decode past the BCH bound -- see
+ Blahut "Theory and practice of error control codes" for how to do this.
+
+ Simon Rockliff, University of Adelaide 21/9/89
+
+ 26/6/91 Slight modifications to remove a compiler dependent bug which hadn't
+ previously surfaced. A few extra comments added for clarity.
+ Appears to all work fine, ready for posting to net!
+
+ Notice
+ --------
+ This program may be freely modified and/or given to whoever wants it.
+ A condition of such distribution is that the author's contribution be
+ acknowledged by his name being left in the comments heading the program,
+ however no responsibility is accepted for any financial or other loss which
+ may result from some unforseen errors or malfunctioning of the program
+ during use.
+ Simon Rockliff, 26th June 1991
+*/
+
+#include <math.h>
+#include <stdio.h>
+
+#define mm 8 /* RS code over GF(2**4) - change to suit */
+#define nn 255 /* nn=2**mm -1 length of codeword */
+
+int pp [mm+1] = { 1, 0, 1, 1, 1, 0, 0, 0, 1 } ; /* specify irreducible polynomial coeffts */
+
+void generate_gf(int *alpha_to, int *index_of)
+/* generate GF(2**mm) from the irreducible polynomial p(X) in pp[0]..pp[mm]
+ lookup tables: index->polynomial form alpha_to[] contains j=alpha**i;
+ polynomial form -> index form index_of[j=alpha**i] = i
+ alpha=2 is the primitive element of GF(2**mm)
+*/
+ {
+ register int i, mask ;
+
+ mask = 1 ;
+ alpha_to[mm] = 0 ;
+ for (i=0; i<mm; i++)
+ { alpha_to[i] = mask ;
+ index_of[alpha_to[i]] = i ;
+ if (pp[i]!=0)
+ alpha_to[mm] ^= mask ;
+ mask <<= 1 ;
+ }
+ index_of[alpha_to[mm]] = mm ;
+ mask >>= 1 ;
+ for (i=mm+1; i<nn; i++)
+ { if (alpha_to[i-1] >= mask)
+ alpha_to[i] = alpha_to[mm] ^ ((alpha_to[i-1]^mask)<<1) ;
+ else alpha_to[i] = alpha_to[i-1]<<1 ;
+ index_of[alpha_to[i]] = i ;
+ }
+ index_of[0] = -1 ;
+ }
+
+
+void gen_poly(int kk, int *alpha_to, int *index_of, int *gg)
+/* Obtain the generator polynomial of the tt-error correcting, length
+ nn=(2**mm -1) Reed Solomon code from the product of (X+alpha**i), i=1..2*tt
+*/
+ {
+ register int i,j ;
+
+ gg[0] = 2 ; /* primitive element alpha = 2 for GF(2**mm) */
+ gg[1] = 1 ; /* g(x) = (X+alpha) initially */
+ for (i=2; i<=nn-kk; i++)
+ { gg[i] = 1 ;
+ for (j=i-1; j>0; j--)
+ if (gg[j] != 0) gg[j] = gg[j-1]^ alpha_to[(index_of[gg[j]]+i)%nn] ;
+ else gg[j] = gg[j-1] ;
+ gg[0] = alpha_to[(index_of[gg[0]]+i)%nn] ; /* gg[0] can never be zero */
+ }
+ /* convert gg[] to index form for quicker encoding */
+ for (i=0; i<=nn-kk; i++) gg[i] = index_of[gg[i]] ;
+ }
+
+
+void encode_rs(int kk, int *alpha_to, int *index_of, int *gg, int *bb, int *data)
+/* take the string of symbols in data[i], i=0..(k-1) and encode systematically
+ to produce 2*tt parity symbols in bb[0]..bb[2*tt-1]
+ data[] is input and bb[] is output in polynomial form.
+ Encoding is done by using a feedback shift register with appropriate
+ connections specified by the elements of gg[], which was generated above.
+ Codeword is c(X) = data(X)*X**(nn-kk)+ b(X) */
+ {
+ register int i,j ;
+ int feedback ;
+
+ for (i=0; i<nn-kk; i++) bb[i] = 0 ;
+ for (i=kk-1; i>=0; i--)
+ { feedback = index_of[data[i]^bb[nn-kk-1]] ;
+ if (feedback != -1)
+ { for (j=nn-kk-1; j>0; j--)
+ if (gg[j] != -1)
+ bb[j] = bb[j-1]^alpha_to[(gg[j]+feedback)%nn] ;
+ else
+ bb[j] = bb[j-1] ;
+ bb[0] = alpha_to[(gg[0]+feedback)%nn] ;
+ }
+ else
+ { for (j=nn-kk-1; j>0; j--)
+ bb[j] = bb[j-1] ;
+ bb[0] = 0 ;
+ } ;
+ } ;
+ } ;
+
+