• 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):   M. Lohwasser
98 
99    Description: common bitbuffer read/write routines
100 
101 *******************************************************************************/
102 
103 #include "FDK_bitbuffer.h"
104 
105 #include "genericStds.h"
106 #include "common_fix.h"
107 #include "fixminmax.h"
108 
109 const UINT BitMask[32 + 1] = {
110     0x0,        0x1,        0x3,       0x7,       0xf,       0x1f,
111     0x3f,       0x7f,       0xff,      0x1ff,     0x3ff,     0x7ff,
112     0xfff,      0x1fff,     0x3fff,    0x7fff,    0xffff,    0x1ffff,
113     0x3ffff,    0x7ffff,    0xfffff,   0x1fffff,  0x3fffff,  0x7fffff,
114     0xffffff,   0x1ffffff,  0x3ffffff, 0x7ffffff, 0xfffffff, 0x1fffffff,
115     0x3fffffff, 0x7fffffff, 0xffffffff};
116 
FDK_CreateBitBuffer(HANDLE_FDK_BITBUF * hBitBuf,UCHAR * pBuffer,UINT bufSize)117 void FDK_CreateBitBuffer(HANDLE_FDK_BITBUF *hBitBuf, UCHAR *pBuffer,
118                          UINT bufSize) {
119   FDK_InitBitBuffer(*hBitBuf, pBuffer, bufSize, 0);
120 
121   FDKmemclear((*hBitBuf)->Buffer, bufSize * sizeof(UCHAR));
122 }
123 
FDK_DeleteBitBuffer(HANDLE_FDK_BITBUF hBitBuf)124 void FDK_DeleteBitBuffer(HANDLE_FDK_BITBUF hBitBuf) { ; }
125 
FDK_InitBitBuffer(HANDLE_FDK_BITBUF hBitBuf,UCHAR * pBuffer,UINT bufSize,UINT validBits)126 void FDK_InitBitBuffer(HANDLE_FDK_BITBUF hBitBuf, UCHAR *pBuffer, UINT bufSize,
127                        UINT validBits) {
128   hBitBuf->ValidBits = validBits;
129   hBitBuf->ReadOffset = 0;
130   hBitBuf->WriteOffset = 0;
131   hBitBuf->BitNdx = 0;
132 
133   hBitBuf->Buffer = pBuffer;
134   hBitBuf->bufSize = bufSize;
135   hBitBuf->bufBits = (bufSize << 3);
136   /*assure bufsize (2^n) */
137   FDK_ASSERT(hBitBuf->ValidBits <= hBitBuf->bufBits);
138   FDK_ASSERT((bufSize > 0) && (bufSize <= MAX_BUFSIZE_BYTES));
139   {
140     UINT x = 0, n = bufSize;
141     for (x = 0; n > 0; x++, n >>= 1) {
142     }
143     if (bufSize != ((UINT)1 << (x - 1))) {
144       FDK_ASSERT(0);
145     }
146   }
147 }
148 
FDK_ResetBitBuffer(HANDLE_FDK_BITBUF hBitBuf)149 void FDK_ResetBitBuffer(HANDLE_FDK_BITBUF hBitBuf) {
150   hBitBuf->ValidBits = 0;
151   hBitBuf->ReadOffset = 0;
152   hBitBuf->WriteOffset = 0;
153   hBitBuf->BitNdx = 0;
154 }
155 
156 #ifndef FUNCTION_FDK_get
FDK_get(HANDLE_FDK_BITBUF hBitBuf,const UINT numberOfBits)157 INT FDK_get(HANDLE_FDK_BITBUF hBitBuf, const UINT numberOfBits) {
158   UINT byteOffset = hBitBuf->BitNdx >> 3;
159   UINT bitOffset = hBitBuf->BitNdx & 0x07;
160 
161   hBitBuf->BitNdx = (hBitBuf->BitNdx + numberOfBits) & (hBitBuf->bufBits - 1);
162   hBitBuf->ValidBits -= numberOfBits;
163 
164   UINT byteMask = hBitBuf->bufSize - 1;
165 
166   UINT tx = (hBitBuf->Buffer[byteOffset & byteMask] << 24) |
167             (hBitBuf->Buffer[(byteOffset + 1) & byteMask] << 16) |
168             (hBitBuf->Buffer[(byteOffset + 2) & byteMask] << 8) |
169             hBitBuf->Buffer[(byteOffset + 3) & byteMask];
170 
171   if (bitOffset) {
172     tx <<= bitOffset;
173     tx |= hBitBuf->Buffer[(byteOffset + 4) & byteMask] >> (8 - bitOffset);
174   }
175 
176   return (tx >> (32 - numberOfBits));
177 }
178 #endif /* #ifndef FUNCTION_FDK_get */
179 
180 #ifndef FUNCTION_FDK_get32
FDK_get32(HANDLE_FDK_BITBUF hBitBuf)181 INT FDK_get32(HANDLE_FDK_BITBUF hBitBuf) {
182   UINT BitNdx = hBitBuf->BitNdx + 32;
183   hBitBuf->BitNdx = BitNdx & (hBitBuf->bufBits - 1);
184   hBitBuf->ValidBits = (UINT)((INT)hBitBuf->ValidBits - (INT)32);
185 
186   UINT byteOffset = (BitNdx - 1) >> 3;
187   if (BitNdx <= hBitBuf->bufBits) {
188     UINT cache = (hBitBuf->Buffer[(byteOffset - 3)] << 24) |
189                  (hBitBuf->Buffer[(byteOffset - 2)] << 16) |
190                  (hBitBuf->Buffer[(byteOffset - 1)] << 8) |
191                  hBitBuf->Buffer[(byteOffset - 0)];
192 
193     if ((BitNdx = (BitNdx & 7)) != 0) {
194       cache = (cache >> (8 - BitNdx)) |
195               ((UINT)hBitBuf->Buffer[byteOffset - 4] << (24 + BitNdx));
196     }
197     return (cache);
198   } else {
199     UINT byte_mask = hBitBuf->bufSize - 1;
200     UINT cache = (hBitBuf->Buffer[(byteOffset - 3) & byte_mask] << 24) |
201                  (hBitBuf->Buffer[(byteOffset - 2) & byte_mask] << 16) |
202                  (hBitBuf->Buffer[(byteOffset - 1) & byte_mask] << 8) |
203                  hBitBuf->Buffer[(byteOffset - 0) & byte_mask];
204 
205     if ((BitNdx = (BitNdx & 7)) != 0) {
206       cache = (cache >> (8 - BitNdx)) |
207               ((UINT)hBitBuf->Buffer[(byteOffset - 4) & byte_mask]
208                << (24 + BitNdx));
209     }
210     return (cache);
211   }
212 }
213 #endif
214 
FDK_getBwd(HANDLE_FDK_BITBUF hBitBuf,const UINT numberOfBits)215 INT FDK_getBwd(HANDLE_FDK_BITBUF hBitBuf, const UINT numberOfBits) {
216   UINT byteOffset = hBitBuf->BitNdx >> 3;
217   UINT bitOffset = hBitBuf->BitNdx & 0x07;
218   UINT byteMask = hBitBuf->bufSize - 1;
219   int i;
220 
221   hBitBuf->BitNdx = (hBitBuf->BitNdx - numberOfBits) & (hBitBuf->bufBits - 1);
222   hBitBuf->ValidBits += numberOfBits;
223 
224   UINT tx = hBitBuf->Buffer[(byteOffset - 3) & byteMask] << 24 |
225             hBitBuf->Buffer[(byteOffset - 2) & byteMask] << 16 |
226             hBitBuf->Buffer[(byteOffset - 1) & byteMask] << 8 |
227             hBitBuf->Buffer[byteOffset & byteMask];
228   UINT txa = 0x0;
229 
230   tx >>= (8 - bitOffset);
231 
232   if (bitOffset && numberOfBits > 24) {
233     tx |= hBitBuf->Buffer[(byteOffset - 4) & byteMask] << (24 + bitOffset);
234   }
235 
236   /* in place turn around */
237   for (i = 0; i < 16; i++) {
238     UINT bitMaskR = 0x00000001 << i;
239     UINT bitMaskL = 0x80000000 >> i;
240 
241     txa |= (tx & bitMaskR) << (31 - (i << 1));
242     txa |= (tx & bitMaskL) >> (31 - (i << 1));
243   }
244 
245   return (txa >> (32 - numberOfBits));
246 }
247 
FDK_put(HANDLE_FDK_BITBUF hBitBuf,UINT value,const UINT numberOfBits)248 void FDK_put(HANDLE_FDK_BITBUF hBitBuf, UINT value, const UINT numberOfBits) {
249   if (numberOfBits != 0) {
250     UINT byteOffset0 = hBitBuf->BitNdx >> 3;
251     UINT bitOffset = hBitBuf->BitNdx & 0x7;
252 
253     hBitBuf->BitNdx = (hBitBuf->BitNdx + numberOfBits) & (hBitBuf->bufBits - 1);
254     hBitBuf->ValidBits += numberOfBits;
255 
256     UINT byteMask = hBitBuf->bufSize - 1;
257 
258     UINT byteOffset1 = (byteOffset0 + 1) & byteMask;
259     UINT byteOffset2 = (byteOffset0 + 2) & byteMask;
260     UINT byteOffset3 = (byteOffset0 + 3) & byteMask;
261 
262     // Create tmp containing free bits at the left border followed by bits to
263     // write, LSB's are cleared, if available Create mask to apply upon all
264     // buffer bytes
265     UINT tmp = (value << (32 - numberOfBits)) >> bitOffset;
266     UINT mask = ~((BitMask[numberOfBits] << (32 - numberOfBits)) >> bitOffset);
267 
268     // read all 4 bytes from buffer and create a 32-bit cache
269     UINT cache = (((UINT)hBitBuf->Buffer[byteOffset0]) << 24) |
270                  (((UINT)hBitBuf->Buffer[byteOffset1]) << 16) |
271                  (((UINT)hBitBuf->Buffer[byteOffset2]) << 8) |
272                  (((UINT)hBitBuf->Buffer[byteOffset3]) << 0);
273 
274     cache = (cache & mask) | tmp;
275     hBitBuf->Buffer[byteOffset0] = (UCHAR)(cache >> 24);
276     hBitBuf->Buffer[byteOffset1] = (UCHAR)(cache >> 16);
277     hBitBuf->Buffer[byteOffset2] = (UCHAR)(cache >> 8);
278     hBitBuf->Buffer[byteOffset3] = (UCHAR)(cache >> 0);
279 
280     if ((bitOffset + numberOfBits) > 32) {
281       UINT byteOffset4 = (byteOffset0 + 4) & byteMask;
282       // remaining bits: in range 1..7
283       // replace MSBits of next byte in buffer by LSBits of "value"
284       int bits = (bitOffset + numberOfBits) & 7;
285       cache =
286           (UINT)hBitBuf->Buffer[byteOffset4] & (~(BitMask[bits] << (8 - bits)));
287       cache |= value << (8 - bits);
288       hBitBuf->Buffer[byteOffset4] = (UCHAR)cache;
289     }
290   }
291 }
292 
FDK_putBwd(HANDLE_FDK_BITBUF hBitBuf,UINT value,const UINT numberOfBits)293 void FDK_putBwd(HANDLE_FDK_BITBUF hBitBuf, UINT value,
294                 const UINT numberOfBits) {
295   UINT byteOffset = hBitBuf->BitNdx >> 3;
296   UINT bitOffset = 7 - (hBitBuf->BitNdx & 0x07);
297   UINT byteMask = hBitBuf->bufSize - 1;
298 
299   UINT mask = ~(BitMask[numberOfBits] << bitOffset);
300   UINT tmp = 0x0000;
301   int i;
302 
303   hBitBuf->BitNdx = (hBitBuf->BitNdx - numberOfBits) & (hBitBuf->bufBits - 1);
304   hBitBuf->ValidBits -= numberOfBits;
305 
306   /* in place turn around */
307   for (i = 0; i < 16; i++) {
308     UINT bitMaskR = 0x00000001 << i;
309     UINT bitMaskL = 0x80000000 >> i;
310 
311     tmp |= (value & bitMaskR) << (31 - (i << 1));
312     tmp |= (value & bitMaskL) >> (31 - (i << 1));
313   }
314   value = tmp;
315   tmp = value >> (32 - numberOfBits) << bitOffset;
316 
317   hBitBuf->Buffer[byteOffset & byteMask] =
318       (hBitBuf->Buffer[byteOffset & byteMask] & (mask)) | (UCHAR)(tmp);
319   hBitBuf->Buffer[(byteOffset - 1) & byteMask] =
320       (hBitBuf->Buffer[(byteOffset - 1) & byteMask] & (mask >> 8)) |
321       (UCHAR)(tmp >> 8);
322   hBitBuf->Buffer[(byteOffset - 2) & byteMask] =
323       (hBitBuf->Buffer[(byteOffset - 2) & byteMask] & (mask >> 16)) |
324       (UCHAR)(tmp >> 16);
325   hBitBuf->Buffer[(byteOffset - 3) & byteMask] =
326       (hBitBuf->Buffer[(byteOffset - 3) & byteMask] & (mask >> 24)) |
327       (UCHAR)(tmp >> 24);
328 
329   if ((bitOffset + numberOfBits) > 32) {
330     hBitBuf->Buffer[(byteOffset - 4) & byteMask] =
331         (UCHAR)(value >> (64 - numberOfBits - bitOffset)) |
332         (hBitBuf->Buffer[(byteOffset - 4) & byteMask] &
333          ~(BitMask[bitOffset] >> (32 - numberOfBits)));
334   }
335 }
336 
337 #ifndef FUNCTION_FDK_pushBack
FDK_pushBack(HANDLE_FDK_BITBUF hBitBuf,const UINT numberOfBits,UCHAR config)338 void FDK_pushBack(HANDLE_FDK_BITBUF hBitBuf, const UINT numberOfBits,
339                   UCHAR config) {
340   hBitBuf->ValidBits =
341       (config == 0) ? (UINT)((INT)hBitBuf->ValidBits + (INT)numberOfBits)
342                     : ((UINT)((INT)hBitBuf->ValidBits - (INT)numberOfBits));
343   hBitBuf->BitNdx = ((UINT)((INT)hBitBuf->BitNdx - (INT)numberOfBits)) &
344                     (hBitBuf->bufBits - 1);
345 }
346 #endif
347 
FDK_pushForward(HANDLE_FDK_BITBUF hBitBuf,const UINT numberOfBits,UCHAR config)348 void FDK_pushForward(HANDLE_FDK_BITBUF hBitBuf, const UINT numberOfBits,
349                      UCHAR config) {
350   hBitBuf->ValidBits =
351       (config == 0) ? ((UINT)((INT)hBitBuf->ValidBits - (INT)numberOfBits))
352                     : (UINT)((INT)hBitBuf->ValidBits + (INT)numberOfBits);
353   hBitBuf->BitNdx =
354       (UINT)((INT)hBitBuf->BitNdx + (INT)numberOfBits) & (hBitBuf->bufBits - 1);
355 }
356 
357 #ifndef FUNCTION_FDK_getValidBits
FDK_getValidBits(HANDLE_FDK_BITBUF hBitBuf)358 UINT FDK_getValidBits(HANDLE_FDK_BITBUF hBitBuf) { return hBitBuf->ValidBits; }
359 #endif /* #ifndef FUNCTION_FDK_getValidBits */
360 
FDK_getFreeBits(HANDLE_FDK_BITBUF hBitBuf)361 INT FDK_getFreeBits(HANDLE_FDK_BITBUF hBitBuf) {
362   return (hBitBuf->bufBits - hBitBuf->ValidBits);
363 }
364 
FDK_Feed(HANDLE_FDK_BITBUF hBitBuf,const UCHAR * RESTRICT inputBuffer,const UINT bufferSize,UINT * bytesValid)365 void FDK_Feed(HANDLE_FDK_BITBUF hBitBuf, const UCHAR *RESTRICT inputBuffer,
366               const UINT bufferSize, UINT *bytesValid) {
367   inputBuffer = &inputBuffer[bufferSize - *bytesValid];
368 
369   UINT bTotal = 0;
370 
371   UINT bToRead = (hBitBuf->bufBits - hBitBuf->ValidBits) >> 3;
372   UINT noOfBytes =
373       fMin(bToRead,
374            *bytesValid);  //(bToRead < *bytesValid) ? bToRead : *bytesValid ;
375 
376   while (noOfBytes > 0) {
377     /* split read to buffer size */
378     bToRead = hBitBuf->bufSize - hBitBuf->ReadOffset;
379     bToRead = fMin(bToRead,
380                    noOfBytes);  //(bToRead < noOfBytes) ? bToRead : noOfBytes ;
381 
382     /* copy 'bToRead' bytes from 'ptr' to inputbuffer */
383     FDKmemcpy(&hBitBuf->Buffer[hBitBuf->ReadOffset], inputBuffer,
384               bToRead * sizeof(UCHAR));
385 
386     /* add noOfBits to number of valid bits in buffer */
387     hBitBuf->ValidBits += bToRead << 3;
388     bTotal += bToRead;
389     inputBuffer += bToRead;
390 
391     hBitBuf->ReadOffset =
392         (hBitBuf->ReadOffset + bToRead) & (hBitBuf->bufSize - 1);
393     noOfBytes -= bToRead;
394   }
395 
396   *bytesValid -= bTotal;
397 }
398 
CopyAlignedBlock(HANDLE_FDK_BITBUF h_BitBufSrc,UCHAR * RESTRICT dstBuffer,UINT bToRead)399 void CopyAlignedBlock(HANDLE_FDK_BITBUF h_BitBufSrc, UCHAR *RESTRICT dstBuffer,
400                       UINT bToRead) {
401   UINT byteOffset = h_BitBufSrc->BitNdx >> 3;
402   const UINT byteMask = h_BitBufSrc->bufSize - 1;
403 
404   UCHAR *RESTRICT pBBB = h_BitBufSrc->Buffer;
405   for (UINT i = 0; i < bToRead; i++) {
406     dstBuffer[i] = pBBB[(byteOffset + i) & byteMask];
407   }
408 
409   bToRead <<= 3;
410 
411   h_BitBufSrc->BitNdx =
412       (h_BitBufSrc->BitNdx + bToRead) & (h_BitBufSrc->bufBits - 1);
413   h_BitBufSrc->ValidBits -= bToRead;
414 }
415 
FDK_Copy(HANDLE_FDK_BITBUF h_BitBufDst,HANDLE_FDK_BITBUF h_BitBufSrc,UINT * bytesValid)416 void FDK_Copy(HANDLE_FDK_BITBUF h_BitBufDst, HANDLE_FDK_BITBUF h_BitBufSrc,
417               UINT *bytesValid) {
418   INT bTotal = 0;
419 
420   /* limit noOfBytes to valid bytes in src buffer and available bytes in dst
421    * buffer */
422   UINT bToRead = h_BitBufSrc->ValidBits >> 3;
423   UINT noOfBytes =
424       fMin(bToRead,
425            *bytesValid);  //(*bytesValid < bToRead) ? *bytesValid : bToRead ;
426   bToRead = FDK_getFreeBits(h_BitBufDst);
427   noOfBytes =
428       fMin(bToRead, noOfBytes);  //(bToRead < noOfBytes) ? bToRead : noOfBytes;
429 
430   while (noOfBytes > 0) {
431     /* Split Read to buffer size */
432     bToRead = h_BitBufDst->bufSize - h_BitBufDst->ReadOffset;
433     bToRead = fMin(noOfBytes,
434                    bToRead);  //(noOfBytes < bToRead) ? noOfBytes : bToRead ;
435 
436     /* copy 'bToRead' bytes from buffer to buffer */
437     if (!(h_BitBufSrc->BitNdx & 0x07)) {
438       CopyAlignedBlock(h_BitBufSrc,
439                        h_BitBufDst->Buffer + h_BitBufDst->ReadOffset, bToRead);
440     } else {
441       for (UINT i = 0; i < bToRead; i++) {
442         h_BitBufDst->Buffer[h_BitBufDst->ReadOffset + i] =
443             (UCHAR)FDK_get(h_BitBufSrc, 8);
444       }
445     }
446 
447     /* add noOfBits to number of valid bits in buffer */
448     h_BitBufDst->ValidBits += bToRead << 3;
449     bTotal += bToRead;
450 
451     h_BitBufDst->ReadOffset =
452         (h_BitBufDst->ReadOffset + bToRead) & (h_BitBufDst->bufSize - 1);
453     noOfBytes -= bToRead;
454   }
455 
456   *bytesValid -= bTotal;
457 }
458 
FDK_Fetch(HANDLE_FDK_BITBUF hBitBuf,UCHAR * outBuf,UINT * writeBytes)459 void FDK_Fetch(HANDLE_FDK_BITBUF hBitBuf, UCHAR *outBuf, UINT *writeBytes) {
460   UCHAR *RESTRICT outputBuffer = outBuf;
461   UINT bTotal = 0;
462 
463   UINT bToWrite = (hBitBuf->ValidBits) >> 3;
464   UINT noOfBytes =
465       fMin(bToWrite,
466            *writeBytes);  //(bToWrite < *writeBytes) ? bToWrite : *writeBytes ;
467 
468   while (noOfBytes > 0) {
469     /* split write to buffer size */
470     bToWrite = hBitBuf->bufSize - hBitBuf->WriteOffset;
471     bToWrite = fMin(
472         bToWrite, noOfBytes);  //(bToWrite < noOfBytes) ? bToWrite : noOfBytes ;
473 
474     /* copy 'bToWrite' bytes from bitbuffer to outputbuffer */
475     FDKmemcpy(outputBuffer, &hBitBuf->Buffer[hBitBuf->WriteOffset],
476               bToWrite * sizeof(UCHAR));
477 
478     /* sub noOfBits from number of valid bits in buffer */
479     hBitBuf->ValidBits -= bToWrite << 3;
480     bTotal += bToWrite;
481     outputBuffer += bToWrite;
482 
483     hBitBuf->WriteOffset =
484         (hBitBuf->WriteOffset + bToWrite) & (hBitBuf->bufSize - 1);
485     noOfBytes -= bToWrite;
486   }
487 
488   *writeBytes = bTotal;
489 }
490