[Scummvm-git-logs] scummvm master -> b72d6d89b92a97dc771eafe0d14a42c6b112c201
sev-
sev at scummvm.org
Tue Aug 10 17:33:51 UTC 2021
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
d44938f916 COMMON: Added common CRC implementation. Borrowed from Wintermute engine
b72d6d89b9 COMMON: Proper check for MacBinary presence. This fixes false positives for QT movies
Commit: d44938f916f04f9e3703297ba9cad320f16abfe6
https://github.com/scummvm/scummvm/commit/d44938f916f04f9e3703297ba9cad320f16abfe6
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-08-10T19:33:27+02:00
Commit Message:
COMMON: Added common CRC implementation. Borrowed from Wintermute engine
Changed paths:
A common/crc.h
diff --git a/common/crc.h b/common/crc.h
new file mode 100644
index 0000000000..0641fdf147
--- /dev/null
+++ b/common/crc.h
@@ -0,0 +1,285 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/**********************************************************************
+ *
+ * Filename: crc.c
+ *
+ * Description: Slow and fast implementations of the CRC standards.
+ *
+ * Notes:
+ *
+ *
+ * Copyright (c) 2000 by Michael Barr. This software is placed into
+ * the public domain and may be used for any purpose. However, this
+ * notice must not be changed or removed and no warranty is either
+ * expressed or implied by its publication or distribution.
+ **********************************************************************/
+
+#ifndef COMMON_CRC_H
+#define COMMON_CRC_H
+
+#include "common/system.h" // For types.
+
+namespace Common {
+
+template <typename T>
+class CRC {
+public:
+ CRC(T poly, T init_remainder, T final_xor, bool reflect);
+ T init(void);
+ T processByte(byte byteVal, T remainder);
+ T finalize(T remainder);
+
+ T crcSlow(byte const message[], int nBytes);
+ T crcFast(byte const message[], int nBytes);
+
+private:
+ T _poly;
+ T _init_remainder;
+ T _final_xor;
+ bool _reflect;
+
+ int _width;
+ int _topbit;
+
+ T _crcTable[256];
+
+ bool _inited;
+
+ uint32 reflect(uint32 data, byte nBits);
+
+ byte reflectData(byte x) { return _reflect ? (byte)reflect(x, 8) : x; }
+ T reflectRemainder(T x) { return _reflect ? (T)reflect(x, _width) : x; }
+};
+
+/*********************************************************************
+ *
+ * Function: reflect()
+ *
+ * Description: Reorder the bits of a binary sequence, by reflecting
+ * them about the middle position.
+ *
+ * Notes: No checking is done that nBits <= 32.
+ *
+ * Returns: The reflection of the original data.
+ *
+ *********************************************************************/
+template<typename T>
+uint32 CRC<T>::reflect(uint32 data, byte nBits) {
+ uint32 reflection = 0x00000000;
+
+ /*
+ * Reflect the data about the center bit.
+ */
+ for (byte bit = 0; bit < nBits; ++bit) {
+ /*
+ * If the LSB bit is set, set the reflection of it.
+ */
+ if (data & 0x01) {
+ reflection |= (1 << ((nBits - 1) - bit));
+ }
+
+ data = (data >> 1);
+ }
+
+ return reflection;
+}
+
+
+/*********************************************************************
+ *
+ * Function: crcSlow()
+ *
+ * Description: Compute the CRC of a given message.
+ *
+ * Notes:
+ *
+ * Returns: The CRC of the message.
+ *
+ *********************************************************************/
+template<typename T>
+T CRC<T>::crcSlow(byte const message[], int nBytes) {
+ T remainder = _init_remainder;
+
+ /*
+ * Perform modulo-2 division, a byte at a time.
+ */
+ for (int b = 0; b < nBytes; ++b) {
+ /*
+ * Bring the next byte into the remainder.
+ */
+ remainder ^= reflectData(message[b]) << (_width - 8);
+
+ /*
+ * 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 & _topbit) {
+ remainder = (remainder << 1) ^ _poly;
+ } else {
+ remainder = (remainder << 1);
+ }
+ }
+ }
+
+ /*
+ * The final remainder is the CRC result.
+ */
+ return reflectRemainder(remainder) ^ _final_xor;
+}
+
+
+template<typename T>
+CRC<T>::CRC(T poly, T init_remainder, T final_xor, bool reflect) :
+ _poly(poly), _init_remainder(init_remainder), _final_xor(final_xor), _reflect(reflect) {
+ _width = 8 * sizeof(T);
+ _topbit = 1 << (_width - 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>
+T CRC<T>::init() {
+ /*
+ * Compute the remainder of each possible dividend.
+ */
+ for (int dividend = 0; dividend < 256; ++dividend) {
+ /*
+ * Start with the dividend followed by zeros.
+ */
+ T remainder = dividend << (_width - 8);
+
+ /*
+ * 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 & _topbit) {
+ remainder = (remainder << 1) ^ _poly;
+ } else {
+ remainder = (remainder << 1);
+ }
+ }
+
+ /*
+ * Store the result into the table.
+ */
+ _crcTable[dividend] = remainder;
+ }
+
+ _inited = true;
+
+ return _init_remainder;
+}
+
+
+/*********************************************************************
+ *
+ * Function: crcFast()
+ *
+ * Description: Compute the CRC of a given message.
+ *
+ * Notes: crcInit() must be called first.
+ *
+ * Returns: The CRC of the message.
+ *
+ *********************************************************************/
+template<typename T>
+T CRC<T>::crcFast(byte const message[], int nBytes) {
+ T remainder = _init_remainder;
+
+ if (!_inited)
+ error("CRC::crcFast(): init method must be called first");
+
+ /*
+ * Divide the message by the polynomial, a byte at a time.
+ */
+ for (int b = 0; b < nBytes; ++b) {
+ byte data = reflectData(message[b] ^ (remainder >> (_width - 8)));
+ remainder = _crcTable[data] ^ (remainder << 8);
+ }
+
+ /*
+ * The final remainder is the CRC.
+ */
+ return reflectRemainder(remainder) ^ _final_xor;
+
+}
+
+template<typename T>
+T CRC<T>::processByte(byte byteVal, T remainder) {
+ byte data = reflectData(byteVal) ^ (remainder >> (_width - 8));
+
+ remainder = _crcTable[data] ^ (remainder << 8);
+ return remainder;
+}
+
+template<typename T>
+T CRC<T>::finalize(T remainder) {
+ return reflectRemainder(remainder) ^ _final_xor;
+}
+
+class CRC_CCITT : public CRC<uint16> {
+public:
+ CRC_CCITT() : CRC(0x1021, 0xFFFF, 0x0000, false) {}
+};
+
+class CRC_BINHEX : public CRC<uint16> {
+public:
+ CRC_BINHEX() : CRC(0x1021, 0x0000, 0x0000, false) {}
+};
+
+class CRC16 : public CRC<uint16> {
+public:
+ CRC16() : CRC(0x8005, 0x0000, 0x0000, true) {}
+};
+
+class CRC32 : public CRC<uint32> {
+public:
+ CRC32() : CRC(0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true) {}
+};
+
+} // End of namespace Common
+
+#endif
Commit: b72d6d89b92a97dc771eafe0d14a42c6b112c201
https://github.com/scummvm/scummvm/commit/b72d6d89b92a97dc771eafe0d14a42c6b112c201
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-08-10T19:33:27+02:00
Commit Message:
COMMON: Proper check for MacBinary presence. This fixes false positives for QT movies
Changed paths:
common/macresman.cpp
diff --git a/common/macresman.cpp b/common/macresman.cpp
index 4f75f1ab8c..b8d8fdc4e1 100644
--- a/common/macresman.cpp
+++ b/common/macresman.cpp
@@ -21,6 +21,7 @@
*/
#include "common/scummsys.h"
+#include "common/crc.h"
#include "common/debug.h"
#include "common/util.h"
#include "common/file.h"
@@ -308,6 +309,14 @@ bool MacResManager::isMacBinary(SeekableReadStream &stream) {
if (stream.read(infoHeader, MBI_INFOHDR) != MBI_INFOHDR)
return false;
+ CRC_BINHEX crc;
+ crc.init();
+ uint16 checkSum = crc.crcFast(infoHeader, 124);
+
+ // Sanity check on the CRC. Some movies could look like MacBinary
+ if (checkSum != READ_BE_UINT16(&infoHeader[124]))
+ return false;
+
if (infoHeader[MBI_ZERO1] == 0 && infoHeader[MBI_ZERO2] == 0 &&
infoHeader[MBI_ZERO3] == 0 && infoHeader[MBI_NAMELEN] <= MAXNAMELEN) {
More information about the Scummvm-git-logs
mailing list