• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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