diff --git a/common/crc.h b/common/crc.h index 3454e66fb74..fa01921635e 100644 --- a/common/crc.h +++ b/common/crc.h @@ -45,7 +45,6 @@ template 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 static R reflect(R data); @@ -72,19 +67,25 @@ protected: template class CRCNormal : public CRCCommon { public: - CRCNormal(T poly, T init_remainder, T final_xor) : CRCCommon(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 class CRCReflected : public CRCCommon { public: - CRCReflected(T poly, T init_remainder, T final_xor) : CRCCommon(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::crcSlow(byte const message[], int nBytes) const { template CRCCommon::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 -T CRCCommon::init() { +template +CRCNormal::CRCNormal(T poly, T init_remainder, T final_xor) : CRCCommon(poly, init_remainder, final_xor) { /* * Compute the remainder of each possible dividend. */ @@ -199,7 +181,7 @@ T CRCCommon::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::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::init() { /* * Store the result into the table. */ - _crcTable[reflectData(dividend)] = reflectRemainder(remainder); - } - - _inited = true; - - return _init_remainder; + this->_crcTable[dividend] = remainder; + } } +template +CRCReflected::CRCReflected(T poly, T init_remainder, T final_xor) : CRCCommon(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 T CRCNormal::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 T CRCReflected::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. */ diff --git a/common/macresman.cpp b/common/macresman.cpp index 1eb222464c4..e0f468b2844 100644 --- a/common/macresman.cpp +++ b/common/macresman.cpp @@ -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 diff --git a/common/unzip.cpp b/common/unzip.cpp index e967d22979c..b53433db834 100644 --- a/common/unzip.cpp +++ b/common/unzip.cpp @@ -1000,7 +1000,6 @@ public: ZipArchive::ZipArchive(unzFile zipFile) : _zipFile(zipFile), _crc() { assert(_zipFile); - _crc.init(); } ZipArchive::~ZipArchive() { diff --git a/engines/mtropolis/boot.cpp b/engines/mtropolis/boot.cpp index 1eb9e8291f5..da6dd243479 100644 --- a/engines/mtropolis/boot.cpp +++ b/engines/mtropolis/boot.cpp @@ -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])) diff --git a/test/common/crc.h b/test/common/crc.h index d8862e8ad4c..0c4ccd9d0ba 100644 --- a/test/common/crc.h +++ b/test/common/crc.h @@ -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();