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 
42 namespace Common {
43 
44 template <typename T>
45 class CRCSlow {
46 public:
47  CRCSlow(T poly, T init_remainder, T final_xor, bool need_reflect);
48  T crcSlow(byte const message[], int nBytes) const;
49 
50 protected:
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  *********************************************************************/
79 template<typename T> template<typename R>
80 R 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  *********************************************************************/
112 template<typename T>
113 T 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 
147 template<typename T>
148 CRCSlow<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 
151 class CRC_CCITT_Slow : public CRCSlow<uint16> {
152 public:
153  CRC_CCITT_Slow() : CRCSlow<uint16>(0x1021, 0xFFFF, 0x0000, false) {}
154 };
155 
156 class CRC_BINHEX_Slow : public CRCSlow<uint16> {
157 public:
158  CRC_BINHEX_Slow() : CRCSlow<uint16>(0x1021, 0x0000, 0x0000, false) {}
159 };
160 
161 class CRC16_Slow : public CRCSlow<uint16> {
162 public:
163  CRC16_Slow() : CRCSlow<uint16>(0x8005, 0x0000, 0x0000, true) {}
164 };
165 
166 class CRC32_Slow : public CRCSlow<uint32> {
167 public:
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: algorithm.h:29
Definition: crc_slow.h:151
Definition: crc_slow.h:156
Definition: crc_slow.h:45