#pragma once
#include "PDFModulusPoly.h"
#include "ZXConfig.h"
#include <stdexcept>
#include <vector>
namespace ZXing {
namespace Pdf417 {
class ModulusGF
{
int _modulus;
std::vector<short> _expTable;
std::vector<short> _logTable;
ModulusPoly _zero;
ModulusPoly _one;
static int fast_mod(int a, int d) { return a < d ? a : a - d; }
public:
ModulusGF(int modulus, int generator);
const ModulusPoly& zero() const {
return _zero;
}
const ModulusPoly& one() const {
return _one;
}
ModulusPoly buildMonomial(int degree, int coefficient) const;
int add(int a, int b) const {
return fast_mod(a + b, _modulus);
}
int subtract(int a, int b) const {
return fast_mod(_modulus + a - b, _modulus);
}
int exp(int a) const {
return _expTable.at(a);
}
int log(int a) const {
if (a == 0) {
throw std::invalid_argument("a == 0");
}
return _logTable[a];
}
int inverse(int a) const {
if (a == 0) {
throw std::invalid_argument("a == 0");
}
return _expTable[_modulus - _logTable[a] - 1];
}
int multiply(int a, int b) const {
if (a == 0 || b == 0) {
return 0;
}
#ifdef ZX_REED_SOLOMON_USE_MORE_MEMORY_FOR_SPEED
return _expTable[_logTable[a] + _logTable[b]];
#else
return _expTable[fast_mod(_logTable[a] + _logTable[b], _modulus - 1)];
#endif
}
int size() const {
return _modulus;
}
};
} }