ScummVM API documentation
crc_slow.h
1/* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22/**********************************************************************
23 *
24 * Filename: crc.c
25 *
26 * Description: Slow implementation of the CRC standards.
27 *
28 * Notes:
29 *
30 *
31 * Copyright (c) 2000 by Michael Barr. This software is placed into
32 * the public domain and may be used for any purpose. However, this
33 * notice must not be changed or removed and no warranty is either
34 * expressed or implied by its publication or distribution.
35 **********************************************************************/
36
37#ifndef COMMON_CRC_SLOW_H
38#define COMMON_CRC_SLOW_H
39
40#include "common/system.h" // For types.
41
42namespace Common {
43
44template <typename T>
45class CRCSlow {
46public:
47 CRCSlow(T poly, T init_remainder, T final_xor, bool need_reflect);
48 T crcSlow(byte const message[], int nBytes) const;
49
50protected:
51 const T _poly;
52 const T _init_remainder;
53 const T _final_xor;
54
55 const int _width;
56 const int _topbit;
57
58 const bool _reflect;
59
60 template<typename R>
61 static R reflect(R data);
62
63 byte reflectData(byte x) const { return _reflect ? reflect<byte>(x) : x; }
64 T reflectRemainder(T x) const { return _reflect ? reflect<T>(x) : x; }
65};
66
67/*********************************************************************
68 *
69 * Function: reflect()
70 *
71 * Description: Reorder the bits of a binary sequence, by reflecting
72 * them about the middle position.
73 *
74 * Notes: No checking is done that nBits <= 32.
75 *
76 * Returns: The reflection of the original data.
77 *
78 *********************************************************************/
79template<typename T> template<typename R>
80R CRCSlow<T>::reflect(R data) {
81 R reflection = 0;
82
83 /*
84 * Reflect the data about the center bit.
85 */
86 for (byte bit = 0; bit < sizeof(R) * 8; ++bit) {
87 /*
88 * If the LSB bit is set, set the reflection of it.
89 */
90 if (data & 0x01) {
91 reflection |= (1 << ((sizeof(R) * 8 - 1) - bit));
92 }
93
94 data = (data >> 1);
95 }
96
97 return reflection;
98}
99
100
101/*********************************************************************
102 *
103 * Function: crcSlow()
104 *
105 * Description: Compute the CRC of a given message.
106 *
107 * Notes:
108 *
109 * Returns: The CRC of the message.
110 *
111 *********************************************************************/
112template<typename T>
113T CRCSlow<T>::crcSlow(byte const message[], int nBytes) const {
114 T remainder = _init_remainder;
115
116 /*
117 * Perform modulo-2 division, a byte at a time.
118 */
119 for (int b = 0; b < nBytes; ++b) {
120 /*
121 * Bring the next byte into the remainder.
122 */
123 remainder ^= reflectData(message[b]) << (_width - 8);
124
125 /*
126 * Perform modulo-2 division, a bit at a time.
127 */
128 for (byte bit = 8; bit > 0; --bit) {
129 /*
130 * Try to divide the current data bit.
131 */
132 if (remainder & _topbit) {
133 remainder = (remainder << 1) ^ _poly;
134 } else {
135 remainder = (remainder << 1);
136 }
137 }
138 }
139
140 /*
141 * The final remainder is the CRC result.
142 */
143 return reflectRemainder(remainder) ^ _final_xor;
144}
145
146
147template<typename T>
148CRCSlow<T>::CRCSlow(T poly, T init_remainder, T final_xor, bool need_reflect) :
149 _poly(poly), _init_remainder(init_remainder), _final_xor(final_xor), _width(8 * sizeof(T)), _topbit(1 << (8 * sizeof(T) - 1)), _reflect(need_reflect) {}
150
151class CRC_CCITT_Slow : public CRCSlow<uint16> {
152public:
153 CRC_CCITT_Slow() : CRCSlow<uint16>(0x1021, 0xFFFF, 0x0000, false) {}
154};
155
156class CRC_BINHEX_Slow : public CRCSlow<uint16> {
157public:
158 CRC_BINHEX_Slow() : CRCSlow<uint16>(0x1021, 0x0000, 0x0000, false) {}
159};
160
161class CRC16_Slow : public CRCSlow<uint16> {
162public:
163 CRC16_Slow() : CRCSlow<uint16>(0x8005, 0x0000, 0x0000, true) {}
164};
165
166class CRC32_Slow : public CRCSlow<uint32> {
167public:
168 CRC32_Slow() : CRCSlow<uint32>(0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true) {}
169};
170
171} // End of namespace Common
172
173#endif
Definition: crc_slow.h:161
Definition: crc_slow.h:166
Definition: crc_slow.h:156
Definition: crc_slow.h:151
Definition: crc_slow.h:45
Definition: algorithm.h:29