ScummVM API documentation
crc.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: Fast 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_H
38#define COMMON_CRC_H
39
40#include "common/system.h" // For types.
41
42namespace Common {
43
44template <typename T>
45class CRCNormal {
46public:
47 CRCNormal(T poly, T init_remainder, T final_xor);
48
49 T crcFast(byte const message[], int nBytes) const;
50 T processByte(byte byteVal, T remainder) const;
51 T getInitRemainder() const { return _init_remainder; }
52 T finalize(T remainder) const { return remainder ^ _final_xor; }
53
54private:
55 const T _init_remainder;
56 const T _final_xor;
57
58 T _crcTable[256];
59};
60
61template <typename T>
63public:
64 CRCReflected(T poly, T init_remainder, T final_xor);
65
66 T crcFast(byte const message[], int nBytes) const;
67 T processByte(byte byteVal, T remainder) const;
68 T getInitRemainder() const { return _reflected_init_remainder; }
69 T finalize(T remainder) const { return remainder ^ _final_xor; }
70
71private:
72 T _crcTable[256];
73 const T _reflected_init_remainder;
74 const T _final_xor;
75};
76
77
78template <typename T>
79CRCNormal<T>::CRCNormal(T poly, T init_remainder, T final_xor) : _init_remainder(init_remainder), _final_xor(final_xor) {
80 const T topbit = 1ULL << (8 * sizeof(T) - 1);
81
82 /*
83 * Compute the remainder of each possible dividend.
84 */
85 for (int dividend = 0; dividend < 256; ++dividend) {
86 /*
87 * Start with the dividend followed by zeros.
88 */
89 T remainder = dividend << (8 * sizeof(T) - 8);
90
91 /*
92 * Perform modulo-2 division, a bit at a time.
93 */
94 for (byte bit = 8; bit > 0; --bit) {
95 /*
96 * Try to divide the current data bit.
97 */
98 if (remainder & topbit) {
99 remainder = (remainder << 1) ^ poly;
100 } else {
101 remainder = (remainder << 1);
102 }
103 }
104
105 /*
106 * Store the result into the table.
107 */
108 _crcTable[dividend] = remainder;
109 }
110}
111
112template <typename T>
113CRCReflected<T>::CRCReflected(T reflected_poly, T reflected_init_remainder, T final_xor) : _reflected_init_remainder(reflected_init_remainder), _final_xor(final_xor) {
114 /*
115 * Compute the remainder of each possible dividend.
116 */
117 for (int dividend = 0; dividend < 256; ++dividend) {
118 /*
119 * Start with the dividend followed by zeros.
120 */
121 T remainder = dividend;
122
123 /*
124 * Perform modulo-2 division, a bit at a time.
125 */
126 for (byte bit = 8; bit > 0; --bit) {
127 /*
128 * Try to divide the current data bit.
129 */
130 if (remainder & 1) {
131 remainder = (remainder >> 1) ^ reflected_poly;
132 } else {
133 remainder = (remainder >> 1);
134 }
135 }
136
137 /*
138 * Store the result into the table.
139 */
140 _crcTable[dividend] = remainder;
141 }
142}
143
144/*********************************************************************
145 *
146 * Function: crcFast()
147 *
148 * Description: Compute the CRC of a given message.
149 *
150 * Notes: crcInit() must be called first.
151 *
152 * Returns: The CRC of the message.
153 *
154 *********************************************************************/
155template<typename T>
156T CRCNormal<T>::crcFast(byte const message[], int nBytes) const {
157 T remainder = _init_remainder;
158
159 /*
160 * Divide the message by the polynomial, a byte at a time.
161 */
162 for (int b = 0; b < nBytes; ++b) {
163 byte data = message[b] ^ (remainder >> (8 * sizeof(T) - 8));
164 remainder = _crcTable[data] ^ (remainder << 8);
165 }
166
167 /*
168 * The final remainder is the CRC.
169 */
170 return remainder ^ _final_xor;
171}
172
173/*********************************************************************
174 *
175 * Function: crcFast()
176 *
177 * Description: Compute the CRC of a given message.
178 *
179 * Notes: crcInit() must be called first.
180 *
181 * Returns: The CRC of the message.
182 *
183 *********************************************************************/
184template<typename T>
185T CRCReflected<T>::crcFast(byte const message[], int nBytes) const {
186 T remainder = _reflected_init_remainder;
187
188 /*
189 * Divide the message by the polynomial, a byte at a time.
190 */
191 for (int b = 0; b < nBytes; ++b) {
192 byte data = message[b] ^ remainder;
193 remainder = _crcTable[data] ^ (remainder >> 8);
194 }
195
196 /*
197 * The final remainder is the CRC.
198 */
199 return remainder ^ _final_xor;
200}
201
202template<typename T>
203T CRCNormal<T>::processByte(byte byteVal, T remainder) const {
204 byte data = byteVal ^ (remainder >> (8 * sizeof(T) - 8));
205
206 return _crcTable[data] ^ (remainder << 8);
207}
208
209template<typename T>
210T CRCReflected<T>::processByte(byte byteVal, T remainder) const {
211 byte data = byteVal ^ remainder;
212
213 return _crcTable[data] ^ (remainder >> 8);
214}
215
216class CRC_CCITT : public CRCNormal<uint16> {
217public:
218 CRC_CCITT() : CRCNormal<uint16>(0x1021, 0xFFFF, 0x0000) {}
219};
220
221class CRC_BINHEX : public CRCNormal<uint16> {
222public:
223 CRC_BINHEX() : CRCNormal<uint16>(0x1021, 0x0000, 0x0000) {}
224};
225
226class CRC16 : public CRCReflected<uint16> {
227public:
228 CRC16() : CRCReflected<uint16>(0xa001, 0x0000, 0x0000) {}
229};
230
231class CRC32 : public CRCReflected<uint32> {
232public:
233 CRC32() : CRCReflected<uint32>(0xEDB88320, 0xFFFFFFFF, 0xFFFFFFFF) {}
234};
235
236} // End of namespace Common
237
238#endif
Definition: crc.h:226
Definition: crc.h:231
Definition: crc.h:221
Definition: crc.h:216
Definition: crc.h:45
Definition: crc.h:62
Definition: algorithm.h:29