org.krysalis.barcode4j.impl.datamatrix.DataMatrixErrorCorrection Maven / Gradle / Ivy
/*
* Copyright 2006 Jeremias Maerki.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* $Id: DataMatrixErrorCorrection.java,v 1.2 2006/12/22 15:58:27 jmaerki Exp $ */
package org.krysalis.barcode4j.impl.datamatrix;
/**
* Error Correction Code for ECC200.
*
* @version $Id: DataMatrixErrorCorrection.java,v 1.2 2006/12/22 15:58:27 jmaerki Exp $
*/
public class DataMatrixErrorCorrection implements DataMatrixReedSolomonFactors {
private static final int MODULO_VALUE = 0x12d;
private static final int[] LOG;
private static final int[] ALOG;
static {
//Create log and antilog table
LOG = new int[256];
ALOG = new int[255];
int p = 1;
for (int i = 0; i < 255; i++) {
ALOG[i] = p;
LOG[p] = i;
p <<= 1;
if (p >= 256) {
p ^= MODULO_VALUE;
}
}
}
/**
* Creates the ECC200 error correction for an encoded message.
* @param codewords the codewords
* @param symbolInfo information about the symbol to be encoded
* @return the codewords with interleaved error correction.
*/
public static String encodeECC200(String codewords, DataMatrixSymbolInfo symbolInfo) {
if (codewords.length() != symbolInfo.dataCapacity) {
throw new IllegalArgumentException(
"The number of codewords does not match the selected symbol");
}
StringBuffer sb = new StringBuffer(symbolInfo.dataCapacity + symbolInfo.errorCodewords);
sb.append(codewords);
int blockCount = symbolInfo.getInterleavedBlockCount();
if (blockCount == 1) {
String ecc = createECCBlock(codewords, symbolInfo.errorCodewords);
sb.append(ecc);
} else {
sb.setLength(sb.capacity());
int[] dataSizes = new int[blockCount];
int[] errorSizes = new int[blockCount];
int[] startPos = new int[blockCount];
for (int i = 0; i < blockCount; i++) {
dataSizes[i] = symbolInfo.getDataLengthForInterleavedBlock(i + 1);
errorSizes[i] = symbolInfo.getErrorLengthForInterleavedBlock(i + 1);
startPos[i] = 0;
if (i > 0) {
startPos[i] = startPos[i - 1] + dataSizes[i];
}
}
for (int block = 0; block < blockCount; block++) {
StringBuffer temp = new StringBuffer(dataSizes[block]);
for (int d = block; d < symbolInfo.dataCapacity; d += blockCount) {
temp.append(codewords.charAt(d));
}
String ecc = createECCBlock(temp.toString(), errorSizes[block]);
int pos = 0;
for (int e = block; e < errorSizes[block] * blockCount; e += blockCount) {
sb.setCharAt(symbolInfo.dataCapacity + e, ecc.charAt(pos++));
}
}
}
return sb.toString();
}
private static String createECCBlock(String codewords, int numECWords) {
return createECCBlock(codewords, 0, codewords.length(), numECWords);
}
private static String createECCBlock(String codewords, int start, int len, int numECWords) {
int table = -1;
for (int i = 0; i < FACTOR_SETS.length; i++) {
if (FACTOR_SETS[i] == numECWords) {
table = i;
break;
}
}
if (table < 0) {
throw new IllegalArgumentException(
"Illegal number of error correction codewords specified: " + numECWords);
}
int[] poly = DataMatrixReedSolomonFactors.FACTORS[table];
char[] ecc = new char[numECWords];
for (int i = 0; i < numECWords; i++) {
ecc[i] = 0;
}
for (int i = start; i < start + len; i++) {
int m = ecc[numECWords - 1] ^ codewords.charAt(i);
for (int k = numECWords - 1; k > 0; k--) {
if (m != 0 && poly[k] != 0) {
ecc[k] = (char)(ecc[k - 1] ^ ALOG[(LOG[m] + LOG[poly[k]]) % 255]);
} else {
ecc[k] = ecc[k - 1];
}
}
if (m != 0 && poly[0] != 0) {
ecc[0] = (char)(ALOG[(LOG[m] + LOG[poly[0]]) % 255]);
} else {
ecc[0] = 0;
}
}
char[] eccReversed = new char[numECWords];
for (int i = 0; i < numECWords; i++) {
eccReversed[i] = ecc[numECWords - i - 1];
}
return String.valueOf(eccReversed);
}
}