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 
42 namespace Common {
43 
44 template <typename T>
45 class CRCNormal {
46 public:
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 
54 private:
55  const T _init_remainder;
56  const T _final_xor;
57 
58  T _crcTable[256];
59 };
60 
61 template <typename T>
62 class CRCReflected {
63 public:
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 
71 private:
72  T _crcTable[256];
73  const T _reflected_init_remainder;
74  const T _final_xor;
75 };
76 
77 
78 template <typename T>
79 CRCNormal<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 
112 template <typename T>
113 CRCReflected<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  *********************************************************************/
155 template<typename T>
156 T 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  *********************************************************************/
184 template<typename T>
185 T 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 
202 template<typename T>
203 T 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 
209 template<typename T>
210 T CRCReflected<T>::processByte(byte byteVal, T remainder) const {
211  byte data = byteVal ^ remainder;
212 
213  return _crcTable[data] ^ (remainder >> 8);
214 }
215 
216 class CRC_CCITT : public CRCNormal<uint16> {
217 public:
218  CRC_CCITT() : CRCNormal<uint16>(0x1021, 0xFFFF, 0x0000) {}
219 };
220 
221 class CRC_BINHEX : public CRCNormal<uint16> {
222 public:
223  CRC_BINHEX() : CRCNormal<uint16>(0x1021, 0x0000, 0x0000) {}
224 };
225 
226 class CRC16 : public CRCReflected<uint16> {
227 public:
228  CRC16() : CRCReflected<uint16>(0xa001, 0x0000, 0x0000) {}
229 };
230 
231 class CRC32 : public CRCReflected<uint32> {
232 public:
233  CRC32() : CRCReflected<uint32>(0xEDB88320, 0xFFFFFFFF, 0xFFFFFFFF) {}
234 };
235 
236 } // End of namespace Common
237 
238 #endif
Definition: crc.h:45
Definition: crc.h:62
Definition: crc.h:226
Definition: algorithm.h:29
Definition: crc.h:216
Definition: crc.h:221
Definition: crc.h:231