ea1f3ec6c4498b5a36cd0d3d6cce44b3b1b2755b
[zxing.git] / core / src / com / google / zxing / common / reedsolomon / GF256.java
1 /*
2  * Copyright 2007 ZXing authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.google.zxing.common.reedsolomon;
18
19 /**
20  * <p>This class contains utility methods for performing mathematical operations over
21  * the Galois Field GF(256). Operations use a given primitive polynomial in calculations.</p>
22  *
23  * <p>Throughout this package, elements of GF(256) are represented as an <code>int</code>
24  * for convenience and speed (but at the cost of memory).
25  * Only the bottom 8 bits are really used.</p>
26  *
27  * @author Sean Owen
28  */
29 public final class GF256 {
30
31   public static final GF256 QR_CODE_FIELD = new GF256(0x011D); // x^8 + x^4 + x^3 + x^2 + 1
32   public static final GF256 DATA_MATRIX_FIELD = new GF256(0x012D); // x^8 + x^5 + x^3 + x^2 + 1
33
34   private final int[] expTable;
35   private final int[] logTable;
36   private final GF256Poly zero;
37   private final GF256Poly one;
38
39   /**
40    * Create a representation of GF(256) using the given primitive polynomial.
41    *
42    * @param primitive irreducible polynomial whose coefficients are represented by
43    *  the bits of an int, where the least-significant bit represents the constant
44    *  coefficient
45    */
46   private GF256(int primitive) {
47     expTable = new int[256];
48     logTable = new int[256];
49     int x = 1;
50     for (int i = 0; i < 256; i++) {
51       expTable[i] = x;
52       x <<= 1; // x = x * 2; we're assuming the generator alpha is 2
53       if (x >= 0x100) {
54         x ^= primitive;
55       }
56     }
57     for (int i = 0; i < 255; i++) {
58       logTable[expTable[i]] = i;
59     }
60     // logTable[0] == 0 but this should never be used
61     zero = new GF256Poly(this, new int[]{0});
62     one = new GF256Poly(this, new int[]{1});
63   }
64
65   GF256Poly getZero() {
66     return zero;
67   }
68
69   GF256Poly getOne() {
70     return one;
71   }
72
73   /**
74    * @return the monomial representing coefficient * x^degree
75    */
76   GF256Poly buildMonomial(int degree, int coefficient) {
77     if (degree < 0) {
78       throw new IllegalArgumentException();
79     }
80     if (coefficient == 0) {
81       return zero;
82     }
83     int[] coefficients = new int[degree + 1];
84     coefficients[0] = coefficient;
85     return new GF256Poly(this, coefficients);
86   }
87
88   /**
89    * Implements both addition and subtraction -- they are the same in GF(256).
90    *
91    * @return sum/difference of a and b
92    */
93   static int addOrSubtract(int a, int b) {
94     return a ^ b;
95   }
96
97   /**
98    * @return 2 to the power of a in GF(256)
99    */
100   int exp(int a) {
101     return expTable[a];
102   }
103
104   /**
105    * @return base 2 log of a in GF(256)
106    */
107   int log(int a) {
108     if (a == 0) {
109       throw new IllegalArgumentException();
110     }
111     return logTable[a];
112   }
113
114   /**
115    * @return multiplicative inverse of a
116    */
117   int inverse(int a) {
118     if (a == 0) {
119       throw new ArithmeticException();
120     }
121     return expTable[255 - logTable[a]];
122   }
123
124   /**
125    * @param a
126    * @param b
127    * @return product of a and b in GF(256)
128    */
129   int multiply(int a, int b) {
130     if (a == 0 || b == 0) {
131       return 0;
132     }
133     if (a == 1) {
134       return b;
135     }
136     if (b == 1) {
137       return a;
138     }
139     return expTable[(logTable[a] + logTable[b]) % 255];
140   }
141
142 }