mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-04 08:17:40 +00:00
COMMON: Remove the need for most reflecting when initing reflected table
Instead reflect the polynomial and change the shifts. Also removes the need for explicit init. This makes our crc more similar to its standard implementation
This commit is contained in:
parent
35bac4e58c
commit
05f1a0df51
93
common/crc.h
93
common/crc.h
@ -45,7 +45,6 @@ template <typename T, bool need_reflect>
|
||||
class CRCCommon {
|
||||
public:
|
||||
CRCCommon(T poly, T init_remainder, T final_xor);
|
||||
T init(void);
|
||||
T finalize(T remainder) const;
|
||||
T crcSlow(byte const message[], int nBytes) const;
|
||||
T getInitRemainder() const { return reflectRemainder(_init_remainder); }
|
||||
@ -58,10 +57,6 @@ protected:
|
||||
const int _width;
|
||||
const int _topbit;
|
||||
|
||||
T _crcTable[256];
|
||||
|
||||
bool _inited;
|
||||
|
||||
template<typename R>
|
||||
static R reflect(R data);
|
||||
|
||||
@ -72,19 +67,25 @@ protected:
|
||||
template <typename T>
|
||||
class CRCNormal : public CRCCommon<T, false> {
|
||||
public:
|
||||
CRCNormal(T poly, T init_remainder, T final_xor) : CRCCommon<T, false>(poly, init_remainder, final_xor) {}
|
||||
CRCNormal(T poly, T init_remainder, T final_xor);
|
||||
|
||||
T crcFast(byte const message[], int nBytes) const;
|
||||
T processByte(byte byteVal, T remainder) const;
|
||||
|
||||
private:
|
||||
T _crcTable[256];
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class CRCReflected : public CRCCommon<T, true> {
|
||||
public:
|
||||
CRCReflected(T poly, T init_remainder, T final_xor) : CRCCommon<T, true>(poly, init_remainder, final_xor) {}
|
||||
CRCReflected(T poly, T init_remainder, T final_xor);
|
||||
|
||||
T crcFast(byte const message[], int nBytes) const;
|
||||
T processByte(byte byteVal, T remainder) const;
|
||||
|
||||
private:
|
||||
T _crcTable[256];
|
||||
};
|
||||
|
||||
/*********************************************************************
|
||||
@ -169,29 +170,10 @@ T CRCCommon<T, need_reflect>::crcSlow(byte const message[], int nBytes) const {
|
||||
|
||||
template<typename T, bool need_reflect>
|
||||
CRCCommon<T, need_reflect>::CRCCommon(T poly, T init_remainder, T final_xor) :
|
||||
_poly(poly), _init_remainder(init_remainder), _final_xor(final_xor), _width(8 * sizeof(T)), _topbit(1 << (8 * sizeof(T) - 1)) {
|
||||
_poly(poly), _init_remainder(init_remainder), _final_xor(final_xor), _width(8 * sizeof(T)), _topbit(1 << (8 * sizeof(T) - 1)) {}
|
||||
|
||||
for (int i = 0; i < 256; ++i)
|
||||
_crcTable[i] = 0;
|
||||
|
||||
_inited = false;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Function: crcInit()
|
||||
*
|
||||
* Description: Populate the partial CRC lookup table.
|
||||
*
|
||||
* Notes: This function must be rerun any time the CRC standard
|
||||
* is changed. If desired, it can be run "offline" and
|
||||
* the table results stored in an embedded system's ROM.
|
||||
*
|
||||
* Returns: Initial remainder.
|
||||
*
|
||||
*********************************************************************/
|
||||
template<typename T, bool need_reflect>
|
||||
T CRCCommon<T, need_reflect>::init() {
|
||||
template <typename T>
|
||||
CRCNormal<T>::CRCNormal(T poly, T init_remainder, T final_xor) : CRCCommon<T, false>(poly, init_remainder, final_xor) {
|
||||
/*
|
||||
* Compute the remainder of each possible dividend.
|
||||
*/
|
||||
@ -199,7 +181,7 @@ T CRCCommon<T, need_reflect>::init() {
|
||||
/*
|
||||
* Start with the dividend followed by zeros.
|
||||
*/
|
||||
T remainder = dividend << (_width - 8);
|
||||
T remainder = dividend << (this->_width - 8);
|
||||
|
||||
/*
|
||||
* Perform modulo-2 division, a bit at a time.
|
||||
@ -208,8 +190,8 @@ T CRCCommon<T, need_reflect>::init() {
|
||||
/*
|
||||
* Try to divide the current data bit.
|
||||
*/
|
||||
if (remainder & _topbit) {
|
||||
remainder = (remainder << 1) ^ _poly;
|
||||
if (remainder & this->_topbit) {
|
||||
remainder = (remainder << 1) ^ this->_poly;
|
||||
} else {
|
||||
remainder = (remainder << 1);
|
||||
}
|
||||
@ -218,14 +200,43 @@ T CRCCommon<T, need_reflect>::init() {
|
||||
/*
|
||||
* Store the result into the table.
|
||||
*/
|
||||
_crcTable[reflectData(dividend)] = reflectRemainder(remainder);
|
||||
}
|
||||
|
||||
_inited = true;
|
||||
|
||||
return _init_remainder;
|
||||
this->_crcTable[dividend] = remainder;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
CRCReflected<T>::CRCReflected(T poly, T init_remainder, T final_xor) : CRCCommon<T, true>(poly, init_remainder, final_xor) {
|
||||
T reflected_poly = this->reflectRemainder(poly);
|
||||
|
||||
/*
|
||||
* Compute the remainder of each possible dividend.
|
||||
*/
|
||||
for (int dividend = 0; dividend < 256; ++dividend) {
|
||||
/*
|
||||
* Start with the dividend followed by zeros.
|
||||
*/
|
||||
T remainder = dividend;
|
||||
|
||||
/*
|
||||
* Perform modulo-2 division, a bit at a time.
|
||||
*/
|
||||
for (byte bit = 8; bit > 0; --bit) {
|
||||
/*
|
||||
* Try to divide the current data bit.
|
||||
*/
|
||||
if (remainder & 1) {
|
||||
remainder = (remainder >> 1) ^ reflected_poly;
|
||||
} else {
|
||||
remainder = (remainder >> 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Store the result into the table.
|
||||
*/
|
||||
_crcTable[dividend] = remainder;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
@ -242,9 +253,6 @@ template<typename T>
|
||||
T CRCNormal<T>::crcFast(byte const message[], int nBytes) const {
|
||||
T remainder = this->_init_remainder;
|
||||
|
||||
if (!this->_inited)
|
||||
error("CRC::crcFast(): init method must be called first");
|
||||
|
||||
/*
|
||||
* Divide the message by the polynomial, a byte at a time.
|
||||
*/
|
||||
@ -274,9 +282,6 @@ template<typename T>
|
||||
T CRCReflected<T>::crcFast(byte const message[], int nBytes) const {
|
||||
T remainder = this->reflectRemainder(this->_init_remainder);
|
||||
|
||||
if (!this->_inited)
|
||||
error("CRC::crcFast(): init method must be called first");
|
||||
|
||||
/*
|
||||
* Divide the message by the polynomial, a byte at a time.
|
||||
*/
|
||||
|
@ -556,7 +556,6 @@ bool MacResManager::readAndValidateMacBinaryHeader(SeekableReadStream &stream, b
|
||||
return false;
|
||||
|
||||
CRC_BINHEX crc;
|
||||
crc.init();
|
||||
uint16 checkSum = crc.crcFast(infoHeader, 124);
|
||||
|
||||
// Sanity check on the CRC. Some movies could look like MacBinary
|
||||
|
@ -1000,7 +1000,6 @@ public:
|
||||
|
||||
ZipArchive::ZipArchive(unzFile zipFile) : _zipFile(zipFile), _crc() {
|
||||
assert(_zipFile);
|
||||
_crc.init();
|
||||
}
|
||||
|
||||
ZipArchive::~ZipArchive() {
|
||||
|
@ -760,7 +760,6 @@ static bool getMacTypesForMacBinary(const char *fileName, uint32 &outType, uint3
|
||||
return false;
|
||||
|
||||
Common::CRC_BINHEX crc;
|
||||
crc.init();
|
||||
uint16 checkSum = crc.crcFast(mbHeader, 124);
|
||||
|
||||
if (checkSum != READ_BE_UINT16(&mbHeader[124]))
|
||||
|
@ -12,7 +12,6 @@ class CrcTestSuite : public CxxTest::TestSuite
|
||||
public:
|
||||
void test_crc32() {
|
||||
Common::CRC32 crc;
|
||||
crc.init();
|
||||
TS_ASSERT_EQUALS(crc.crcFast(testString, testLen), 0x414fa339U);
|
||||
TS_ASSERT_EQUALS(crc.crcSlow(testString, testLen), 0x414fa339U);
|
||||
uint32 running = crc.getInitRemainder();
|
||||
@ -23,7 +22,6 @@ public:
|
||||
|
||||
void test_crc16() {
|
||||
Common::CRC16 crc;
|
||||
crc.init();
|
||||
TS_ASSERT_EQUALS(crc.crcFast(testString, testLen), 0xfcdfU);
|
||||
TS_ASSERT_EQUALS(crc.crcSlow(testString, testLen), 0xfcdfU);
|
||||
uint16 running = crc.getInitRemainder();
|
||||
@ -34,7 +32,6 @@ public:
|
||||
|
||||
void test_crc_ccitt() {
|
||||
Common::CRC_CCITT crc; // aka ccitt-false
|
||||
crc.init();
|
||||
TS_ASSERT_EQUALS(crc.crcFast(testString, testLen), 0x8fddU);
|
||||
TS_ASSERT_EQUALS(crc.crcSlow(testString, testLen), 0x8fddU);
|
||||
uint16 running = crc.getInitRemainder();
|
||||
@ -45,7 +42,6 @@ public:
|
||||
|
||||
void test_crc_binhex() {
|
||||
Common::CRC_BINHEX crc; // Aka xmodem
|
||||
crc.init();
|
||||
TS_ASSERT_EQUALS(crc.crcFast(testString, testLen), 0xf0c8U);
|
||||
TS_ASSERT_EQUALS(crc.crcSlow(testString, testLen), 0xf0c8U);
|
||||
uint16 running = crc.getInitRemainder();
|
||||
|
Loading…
Reference in New Issue
Block a user