1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4 © Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
5 Forschung e.V. All rights reserved.
6
7 1. INTRODUCTION
8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
11 a wide variety of Android devices.
12
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14 general perceptual audio codecs. AAC-ELD is considered the best-performing
15 full-bandwidth communications codec by independent studies and is widely
16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17 specifications.
18
19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
20 those of Fraunhofer) may be obtained through Via Licensing
21 (www.vialicensing.com) or through the respective patent owners individually for
22 the purpose of encoding or decoding bit streams in products that are compliant
23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24 Android devices already license these patent claims through Via Licensing or
25 directly from the patent owners, and therefore FDK AAC Codec software may
26 already be covered under those patent licenses when it is used for those
27 licensed purposes only.
28
29 Commercially-licensed AAC software libraries, including floating-point versions
30 with enhanced sound quality, are also available from Fraunhofer. Users are
31 encouraged to check the Fraunhofer website for additional applications
32 information and documentation.
33
34 2. COPYRIGHT LICENSE
35
36 Redistribution and use in source and binary forms, with or without modification,
37 are permitted without payment of copyright license fees provided that you
38 satisfy the following conditions:
39
40 You must retain the complete text of this software license in redistributions of
41 the FDK AAC Codec or your modifications thereto in source code form.
42
43 You must retain the complete text of this software license in the documentation
44 and/or other materials provided with redistributions of the FDK AAC Codec or
45 your modifications thereto in binary form. You must make available free of
46 charge copies of the complete source code of the FDK AAC Codec and your
47 modifications thereto to recipients of copies in binary form.
48
49 The name of Fraunhofer may not be used to endorse or promote products derived
50 from this library without prior written permission.
51
52 You may not charge copyright license fees for anyone to use, copy or distribute
53 the FDK AAC Codec software or your modifications thereto.
54
55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
56 that you changed the software and the date of any change. For modified versions
57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59 AAC Codec Library for Android."
60
61 3. NO PATENT LICENSE
62
63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65 Fraunhofer provides no warranty of patent non-infringement with respect to this
66 software.
67
68 You may use this FDK AAC Codec software or modifications thereto only for
69 purposes that are authorized by appropriate patent licenses.
70
71 4. DISCLAIMER
72
73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75 including but not limited to the implied warranties of merchantability and
76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78 or consequential damages, including but not limited to procurement of substitute
79 goods or services; loss of use, data, or profits, or business interruption,
80 however caused and on any theory of liability, whether in contract, strict
81 liability, or tort (including negligence), arising in any way out of the use of
82 this software, even if advised of the possibility of such damage.
83
84 5. CONTACT INFORMATION
85
86 Fraunhofer Institute for Integrated Circuits IIS
87 Attention: Audio and Multimedia Departments - FDK AAC LL
88 Am Wolfsmantel 33
89 91058 Erlangen, Germany
90
91 www.iis.fraunhofer.de/amm
92 amm-info@iis.fraunhofer.de
93 ----------------------------------------------------------------------------- */
94
95 /******************* Library for basic calculation routines ********************
96
97 Author(s):
98
99 Description: CRC calculation
100
101 *******************************************************************************/
102
103 #include "FDK_crc.h"
104
105 /*---------------- constants -----------------------*/
106
107 /**
108 * \brief This table defines precalculated lookup tables for crc polynom x^16
109 * + x^15 + x^2 + x^0.
110 */
111 static const USHORT crcLookup_16_15_2_0[256] = {
112 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011, 0x8033,
113 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022, 0x8063, 0x0066,
114 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072, 0x0050, 0x8055, 0x805f,
115 0x005a, 0x804b, 0x004e, 0x0044, 0x8041, 0x80c3, 0x00c6, 0x00cc, 0x80c9,
116 0x00d8, 0x80dd, 0x80d7, 0x00d2, 0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb,
117 0x00ee, 0x00e4, 0x80e1, 0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be,
118 0x00b4, 0x80b1, 0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087,
119 0x0082, 0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192,
120 0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1, 0x01e0,
121 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1, 0x81d3, 0x01d6,
122 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2, 0x0140, 0x8145, 0x814f,
123 0x014a, 0x815b, 0x015e, 0x0154, 0x8151, 0x8173, 0x0176, 0x017c, 0x8179,
124 0x0168, 0x816d, 0x8167, 0x0162, 0x8123, 0x0126, 0x012c, 0x8129, 0x0138,
125 0x813d, 0x8137, 0x0132, 0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e,
126 0x0104, 0x8101, 0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317,
127 0x0312, 0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321,
128 0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371, 0x8353,
129 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342, 0x03c0, 0x83c5,
130 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1, 0x83f3, 0x03f6, 0x03fc,
131 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2, 0x83a3, 0x03a6, 0x03ac, 0x83a9,
132 0x03b8, 0x83bd, 0x83b7, 0x03b2, 0x0390, 0x8395, 0x839f, 0x039a, 0x838b,
133 0x038e, 0x0384, 0x8381, 0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e,
134 0x0294, 0x8291, 0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7,
135 0x02a2, 0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2,
136 0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1, 0x8243,
137 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252, 0x0270, 0x8275,
138 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261, 0x0220, 0x8225, 0x822f,
139 0x022a, 0x823b, 0x023e, 0x0234, 0x8231, 0x8213, 0x0216, 0x021c, 0x8219,
140 0x0208, 0x820d, 0x8207, 0x0202};
141
142 /**
143 * \brief This table defines precalculated lookup tables for crc polynom x^16
144 * + x^12 + x^5 + x^0.
145 */
146 static const USHORT crcLookup_16_12_5_0[256] = {
147 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108,
148 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210,
149 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b,
150 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401,
151 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee,
152 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6,
153 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d,
154 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
155 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5,
156 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc,
157 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4,
158 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd,
159 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13,
160 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a,
161 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e,
162 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
163 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1,
164 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb,
165 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0,
166 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8,
167 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657,
168 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9,
169 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882,
170 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
171 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e,
172 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07,
173 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d,
174 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74,
175 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0};
176
177 /**
178 * \brief This table defines precalculated lookup tables for crc polynom x^16
179 * + x^15 + x^5 + x^0.
180 */
181
182 static const USHORT crcLookup_16_15_5_0[256] = {
183 0x0000, 0x8021, 0x8063, 0x0042, 0x80e7, 0x00c6, 0x0084, 0x80a5, 0x81ef,
184 0x01ce, 0x018c, 0x81ad, 0x0108, 0x8129, 0x816b, 0x014a, 0x83ff, 0x03de,
185 0x039c, 0x83bd, 0x0318, 0x8339, 0x837b, 0x035a, 0x0210, 0x8231, 0x8273,
186 0x0252, 0x82f7, 0x02d6, 0x0294, 0x82b5, 0x87df, 0x07fe, 0x07bc, 0x879d,
187 0x0738, 0x8719, 0x875b, 0x077a, 0x0630, 0x8611, 0x8653, 0x0672, 0x86d7,
188 0x06f6, 0x06b4, 0x8695, 0x0420, 0x8401, 0x8443, 0x0462, 0x84c7, 0x04e6,
189 0x04a4, 0x8485, 0x85cf, 0x05ee, 0x05ac, 0x858d, 0x0528, 0x8509, 0x854b,
190 0x056a, 0x8f9f, 0x0fbe, 0x0ffc, 0x8fdd, 0x0f78, 0x8f59, 0x8f1b, 0x0f3a,
191 0x0e70, 0x8e51, 0x8e13, 0x0e32, 0x8e97, 0x0eb6, 0x0ef4, 0x8ed5, 0x0c60,
192 0x8c41, 0x8c03, 0x0c22, 0x8c87, 0x0ca6, 0x0ce4, 0x8cc5, 0x8d8f, 0x0dae,
193 0x0dec, 0x8dcd, 0x0d68, 0x8d49, 0x8d0b, 0x0d2a, 0x0840, 0x8861, 0x8823,
194 0x0802, 0x88a7, 0x0886, 0x08c4, 0x88e5, 0x89af, 0x098e, 0x09cc, 0x89ed,
195 0x0948, 0x8969, 0x892b, 0x090a, 0x8bbf, 0x0b9e, 0x0bdc, 0x8bfd, 0x0b58,
196 0x8b79, 0x8b3b, 0x0b1a, 0x0a50, 0x8a71, 0x8a33, 0x0a12, 0x8ab7, 0x0a96,
197 0x0ad4, 0x8af5, 0x9f1f, 0x1f3e, 0x1f7c, 0x9f5d, 0x1ff8, 0x9fd9, 0x9f9b,
198 0x1fba, 0x1ef0, 0x9ed1, 0x9e93, 0x1eb2, 0x9e17, 0x1e36, 0x1e74, 0x9e55,
199 0x1ce0, 0x9cc1, 0x9c83, 0x1ca2, 0x9c07, 0x1c26, 0x1c64, 0x9c45, 0x9d0f,
200 0x1d2e, 0x1d6c, 0x9d4d, 0x1de8, 0x9dc9, 0x9d8b, 0x1daa, 0x18c0, 0x98e1,
201 0x98a3, 0x1882, 0x9827, 0x1806, 0x1844, 0x9865, 0x992f, 0x190e, 0x194c,
202 0x996d, 0x19c8, 0x99e9, 0x99ab, 0x198a, 0x9b3f, 0x1b1e, 0x1b5c, 0x9b7d,
203 0x1bd8, 0x9bf9, 0x9bbb, 0x1b9a, 0x1ad0, 0x9af1, 0x9ab3, 0x1a92, 0x9a37,
204 0x1a16, 0x1a54, 0x9a75, 0x1080, 0x90a1, 0x90e3, 0x10c2, 0x9067, 0x1046,
205 0x1004, 0x9025, 0x916f, 0x114e, 0x110c, 0x912d, 0x1188, 0x91a9, 0x91eb,
206 0x11ca, 0x937f, 0x135e, 0x131c, 0x933d, 0x1398, 0x93b9, 0x93fb, 0x13da,
207 0x1290, 0x92b1, 0x92f3, 0x12d2, 0x9277, 0x1256, 0x1214, 0x9235, 0x975f,
208 0x177e, 0x173c, 0x971d, 0x17b8, 0x9799, 0x97db, 0x17fa, 0x16b0, 0x9691,
209 0x96d3, 0x16f2, 0x9657, 0x1676, 0x1634, 0x9615, 0x14a0, 0x9481, 0x94c3,
210 0x14e2, 0x9447, 0x1466, 0x1424, 0x9405, 0x954f, 0x156e, 0x152c, 0x950d,
211 0x15a8, 0x9589, 0x95cb, 0x15ea,
212 };
213
214 /*--------------- function declarations --------------------*/
215
216 static inline INT calcCrc_Bits(USHORT *const pCrc, USHORT crcMask,
217 USHORT crcPoly, HANDLE_FDK_BITSTREAM hBs,
218 INT nBits);
219
220 static inline INT calcCrc_Bytes(USHORT *const pCrc, const USHORT *pCrcLookup,
221 HANDLE_FDK_BITSTREAM hBs, INT nBytes);
222
223 static void crcCalc(HANDLE_FDK_CRCINFO hCrcInfo, HANDLE_FDK_BITSTREAM hBs,
224 const INT reg);
225
226 /*------------- function definitions ----------------*/
227
FDKcrcInit(HANDLE_FDK_CRCINFO hCrcInfo,const UINT crcPoly,const UINT crcStartValue,const UINT crcLen)228 void FDKcrcInit(HANDLE_FDK_CRCINFO hCrcInfo, const UINT crcPoly,
229 const UINT crcStartValue, const UINT crcLen) {
230 /* crc polynom example:
231 x^16 + x^15 + x^5 + x^0 (1) 1000 0000 0010 0001 -> 0x8021
232 x^16 + x^15 + x^2 + x^0 (1) 1000 0000 0000 0101 -> 0x8005
233 x^16 + x^12 + x^5 + x^0 (1) 0001 0000 0010 0001 -> 0x1021
234 x^8 + x^4 + x^3 + x^2 + x^0 (1) 0001 1101 -> 0x001d */
235
236 hCrcInfo->crcLen = crcLen;
237 hCrcInfo->crcPoly = crcPoly;
238 hCrcInfo->startValue = crcStartValue;
239 hCrcInfo->crcMask = (crcLen) ? (1 << (crcLen - 1)) : 0;
240
241 FDKcrcReset(hCrcInfo);
242
243 hCrcInfo->pCrcLookup =
244 0; /* Preset 0 for "crcLen" != 16 or unknown 16-bit polynoms "crcPoly" */
245
246 if (hCrcInfo->crcLen == 16) {
247 switch (crcPoly) {
248 case 0x8021:
249 hCrcInfo->pCrcLookup = crcLookup_16_15_5_0;
250 break;
251 case 0x8005:
252 hCrcInfo->pCrcLookup = crcLookup_16_15_2_0;
253 break;
254 case 0x1021:
255 hCrcInfo->pCrcLookup = crcLookup_16_12_5_0;
256 break;
257 case 0x001d:
258 default:
259 /* no lookup table */
260 break;
261 }
262 }
263 }
264
FDKcrcReset(HANDLE_FDK_CRCINFO hCrcInfo)265 void FDKcrcReset(HANDLE_FDK_CRCINFO hCrcInfo) {
266 int i;
267
268 hCrcInfo->crcValue = hCrcInfo->startValue;
269
270 for (i = 0; i < MAX_CRC_REGS; i++) {
271 hCrcInfo->crcRegData[i].isActive = 0;
272 }
273 hCrcInfo->regStart = 0;
274 hCrcInfo->regStop = 0;
275 }
276
FDKcrcStartReg(HANDLE_FDK_CRCINFO hCrcInfo,const HANDLE_FDK_BITSTREAM hBs,const INT mBits)277 INT FDKcrcStartReg(HANDLE_FDK_CRCINFO hCrcInfo, const HANDLE_FDK_BITSTREAM hBs,
278 const INT mBits) {
279 int reg = hCrcInfo->regStart;
280
281 FDK_ASSERT(hCrcInfo->crcRegData[reg].isActive == 0);
282 hCrcInfo->crcRegData[reg].isActive = 1;
283 hCrcInfo->crcRegData[reg].maxBits = mBits;
284 hCrcInfo->crcRegData[reg].validBits = (INT)FDKgetValidBits(hBs);
285 hCrcInfo->crcRegData[reg].bitBufCntBits = 0;
286
287 hCrcInfo->regStart = (hCrcInfo->regStart + 1) % MAX_CRC_REGS;
288
289 return (reg);
290 }
291
FDKcrcEndReg(HANDLE_FDK_CRCINFO hCrcInfo,const HANDLE_FDK_BITSTREAM hBs,const INT reg)292 INT FDKcrcEndReg(HANDLE_FDK_CRCINFO hCrcInfo, const HANDLE_FDK_BITSTREAM hBs,
293 const INT reg) {
294 FDK_ASSERT((reg == (INT)hCrcInfo->regStop) &&
295 (hCrcInfo->crcRegData[reg].isActive == 1));
296
297 if (hBs->ConfigCache == BS_WRITER) {
298 hCrcInfo->crcRegData[reg].bitBufCntBits =
299 (INT)FDKgetValidBits(hBs) - hCrcInfo->crcRegData[reg].validBits;
300 } else {
301 hCrcInfo->crcRegData[reg].bitBufCntBits =
302 hCrcInfo->crcRegData[reg].validBits - (INT)FDKgetValidBits(hBs);
303 }
304
305 if (hCrcInfo->crcRegData[reg].maxBits == 0) {
306 hCrcInfo->crcRegData[reg].maxBits = hCrcInfo->crcRegData[reg].bitBufCntBits;
307 }
308
309 crcCalc(hCrcInfo, hBs, reg);
310
311 hCrcInfo->crcRegData[reg].isActive = 0;
312 hCrcInfo->regStop = (hCrcInfo->regStop + 1) % MAX_CRC_REGS;
313
314 return 0;
315 }
316
FDKcrcGetCRC(const HANDLE_FDK_CRCINFO hCrcInfo)317 USHORT FDKcrcGetCRC(const HANDLE_FDK_CRCINFO hCrcInfo) {
318 return (hCrcInfo->crcValue & (((hCrcInfo->crcMask - 1) << 1) + 1));
319 }
320
321 /**
322 * \brief Calculate crc bits.
323 *
324 * Calculate crc starting at current bitstream postion over nBits.
325 *
326 * \param pCrc Pointer to an outlying allocated crc info
327 * structure.
328 * \param crcMask CrcMask in use.
329 * \param crcPoly Crc polynom in use.
330 * \param hBs Handle to current bit buffer structure.
331 * \param nBits Number of processing bits.
332 *
333 * \return Number of processed bits.
334 */
calcCrc_Bits(USHORT * const pCrc,USHORT crcMask,USHORT crcPoly,HANDLE_FDK_BITSTREAM hBs,INT nBits)335 static inline INT calcCrc_Bits(USHORT *const pCrc, USHORT crcMask,
336 USHORT crcPoly, HANDLE_FDK_BITSTREAM hBs,
337 INT nBits) {
338 int i;
339 USHORT crc = *pCrc; /* get crc value */
340
341 if (hBs != NULL) {
342 for (i = 0; (i < nBits); i++) {
343 USHORT tmp = FDKreadBit(hBs); // process single bit
344 tmp ^= ((crc & crcMask) ? 1 : 0);
345 if (tmp != 0) tmp = crcPoly;
346 crc <<= 1;
347 crc ^= tmp;
348 }
349 } else {
350 for (i = 0; (i < nBits); i++) {
351 USHORT tmp = (crc & crcMask) ? crcPoly : 0; // process single bit
352 crc <<= 1;
353 crc ^= tmp;
354 }
355 }
356 *pCrc = crc; /* update crc value */
357
358 return nBits;
359 }
360
361 /**
362 * \brief Calculate crc bytes.
363 *
364 * Calculate crc starting at current bitstream postion over nBytes.
365 *
366 * \param pCrc Pointer to an outlying allocated crc info
367 * structure.
368 * \param pCrcLookup Pointer to lookup table used for fast crc
369 * calculation.
370 * \param hBs Handle to current bit buffer structure.
371 * \param nBits Number of processing bytes.
372 *
373 * \return Number of processed bits.
374 */
375
calcCrc_Bytes(USHORT * const pCrc,const USHORT * pCrcLookup,HANDLE_FDK_BITSTREAM hBs,INT nBytes)376 static inline INT calcCrc_Bytes(USHORT *const pCrc, const USHORT *pCrcLookup,
377 HANDLE_FDK_BITSTREAM hBs, INT nBytes) {
378 int i;
379 USHORT crc = *pCrc; /* get crc value */
380
381 if (hBs != NULL) {
382 ULONG data;
383 INT bits;
384 for (i = 0; i < (nBytes >> 2); i++) {
385 data = (ULONG)FDKreadBits(hBs, 32);
386 crc =
387 (crc << 8) ^ pCrcLookup[((crc >> 8) ^ ((USHORT)(data >> 24))) & 0xFF];
388 crc =
389 (crc << 8) ^ pCrcLookup[((crc >> 8) ^ ((USHORT)(data >> 16))) & 0xFF];
390 crc =
391 (crc << 8) ^ pCrcLookup[((crc >> 8) ^ ((USHORT)(data >> 8))) & 0xFF];
392 crc =
393 (crc << 8) ^ pCrcLookup[((crc >> 8) ^ ((USHORT)(data >> 0))) & 0xFF];
394 }
395 bits = (nBytes & 3) << 3;
396 if (bits > 0) {
397 data = (ULONG)FDKreadBits(hBs, bits);
398 for (bits -= 8; bits >= 0; bits -= 8)
399 crc = (crc << 8) ^
400 pCrcLookup[((crc >> 8) ^ (USHORT)(data >> bits)) & 0xFF];
401 }
402 } else {
403 for (i = 0; i < nBytes; i++) {
404 crc = (crc << 8) ^ pCrcLookup[(crc >> 8) & 0xFF];
405 }
406 }
407
408 *pCrc = crc; /* update crc value */
409
410 return (nBytes);
411 }
412
413 /**
414 * \brief Calculate crc.
415 *
416 * Calculate crc. Lenght depends on mBits parameter in FDKcrcStartReg()
417 * configuration.
418 *
419 * \param hCrcInfo Pointer to an outlying allocated crc info
420 * structure.
421 * \param hBs Pointer to current bit buffer structure.
422 * \param reg Crc region ID.
423 *
424 * \return Number of processed bits.
425 */
crcCalc(HANDLE_FDK_CRCINFO hCrcInfo,HANDLE_FDK_BITSTREAM hBs,const INT reg)426 static void crcCalc(HANDLE_FDK_CRCINFO hCrcInfo, HANDLE_FDK_BITSTREAM hBs,
427 const INT reg) {
428 USHORT crc = hCrcInfo->crcValue;
429 CCrcRegData *rD = &hCrcInfo->crcRegData[reg];
430 FDK_BITSTREAM bsReader;
431
432 if (hBs->ConfigCache == BS_READER) {
433 bsReader = *hBs;
434 FDKpushBiDirectional(&bsReader,
435 -(rD->validBits - (INT)FDKgetValidBits(&bsReader)));
436 } else {
437 FDKinitBitStream(&bsReader, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize,
438 hBs->hBitBuf.ValidBits, BS_READER);
439 FDKpushBiDirectional(&bsReader, rD->validBits);
440 }
441
442 int bits, rBits;
443 rBits = (rD->maxBits >= 0) ? rD->maxBits : -rD->maxBits; /* ramaining bits */
444 if ((rD->maxBits > 0) && ((rD->bitBufCntBits >> 3 << 3) < rBits)) {
445 bits = rD->bitBufCntBits;
446 } else {
447 bits = rBits;
448 }
449
450 int words = bits >> 3; /* processing bytes */
451 int mBits = bits & 0x7; /* modulo bits */
452
453 if (hCrcInfo->pCrcLookup) {
454 rBits -= (calcCrc_Bytes(&crc, hCrcInfo->pCrcLookup, &bsReader, words) << 3);
455 } else {
456 rBits -= calcCrc_Bits(&crc, hCrcInfo->crcMask, hCrcInfo->crcPoly, &bsReader,
457 words << 3);
458 }
459
460 /* remaining valid bits*/
461 if (mBits != 0) {
462 rBits -= calcCrc_Bits(&crc, hCrcInfo->crcMask, hCrcInfo->crcPoly, &bsReader,
463 mBits);
464 }
465
466 if (rBits != 0) {
467 /* zero bytes */
468 if ((hCrcInfo->pCrcLookup) && (rBits > 8)) {
469 rBits -=
470 (calcCrc_Bytes(&crc, hCrcInfo->pCrcLookup, NULL, rBits >> 3) << 3);
471 }
472 /* remaining zero bits */
473 if (rBits != 0) {
474 calcCrc_Bits(&crc, hCrcInfo->crcMask, hCrcInfo->crcPoly, NULL, rBits);
475 }
476 }
477
478 hCrcInfo->crcValue = crc;
479 }
480