|
1 /* |
|
2 * Copyright (c) 2010 Ixonos Plc. |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - Initial contribution |
|
11 * |
|
12 * Contributors: |
|
13 * Ixonos Plc |
|
14 * |
|
15 * Description: |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 /************************************************************************** |
|
21 nok_bits2.c - Bitstream subroutines. |
|
22 |
|
23 Author(s): Juha Ojanpera |
|
24 Copyright (c) 1999-2003 by Nokia Research Center, Speech and Audio Systems. |
|
25 *************************************************************************/ |
|
26 |
|
27 /************************************************************************** |
|
28 External Objects Needed |
|
29 *************************************************************************/ |
|
30 |
|
31 /*-- Project Headers --*/ |
|
32 #include "nok_bits.h" |
|
33 |
|
34 /************************************************************************** |
|
35 Internal Objects |
|
36 *************************************************************************/ |
|
37 |
|
38 #ifdef USE_ASSERT |
|
39 #define BITSASSERT(x) { \ |
|
40 MY_ASSERT(UpdateBufIdx(bs) == 1); \ |
|
41 } |
|
42 #else |
|
43 #define BITSASSERT(x) { \ |
|
44 UpdateBufIdx(bs); \ |
|
45 } |
|
46 #endif |
|
47 |
|
48 //typedef uint32 (*GETBITS_FUNCTION)(BitStream *bs, int16 n); |
|
49 |
|
50 const uint32 bitMask[] = |
|
51 {0x0, 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, |
|
52 0x1FFFL, 0x3FFFL, 0x7FFFL, 0xFFFFL, 0x1FFFFL, 0x3FFFFL, 0x7FFFFL, 0xFFFFFL, |
|
53 0x1FFFFFL, 0x3FFFFFL, 0x7FFFFFL, 0xFFFFFFL, 0x1FFFFFFL, 0x3FFFFFFL, 0x7FFFFFFL, |
|
54 0xFFFFFFFL, 0x1FFFFFFFL, 0x3FFFFFFFL, 0x7FFFFFFFL, 0xFFFFFFFFL}; |
|
55 |
|
56 |
|
57 |
|
58 /* |
|
59 * Updates the read index of the bit buffer. |
|
60 */ |
|
61 static INLINE int16 |
|
62 UpdateBufIdx(TBitStream *bs) |
|
63 { |
|
64 bs->buf_index++; |
|
65 bs->buf_index = MOD_OPCODE(bs->buf_index, bs->buf_mask); |
|
66 bs->slots_read++; |
|
67 #if 0 |
|
68 if(bs->slots_read == bs->buf_len) |
|
69 return (0); |
|
70 #endif |
|
71 |
|
72 return (1); |
|
73 } |
|
74 |
|
75 /* |
|
76 * Writes at most 8 bits to the bit buffer. |
|
77 */ |
|
78 void |
|
79 PutBits(TBitStream *bs, uint16 n, uint32 word) |
|
80 { |
|
81 uint8 *buf = (bs->mode == BIT8) ? bs->bit_buffer : bs->dsp_buffer; |
|
82 /* |
|
83 * The number of bits left in the current buffer slot is too low. |
|
84 * Therefore, the input word needs to be splitted into two parts. |
|
85 * Each part is stored separately. |
|
86 */ |
|
87 int16 tmp = bs->bit_counter - n; |
|
88 if(tmp < 0) |
|
89 { |
|
90 /*-- Zero those bits that are to be modified. --*/ |
|
91 buf[bs->buf_index] &= ~bitMask[bs->bit_counter]; |
|
92 |
|
93 /*-- Store the upper (MSB) part to the bitstream buffer. --*/ |
|
94 tmp = -tmp; |
|
95 buf[bs->buf_index] |= (word >> tmp); |
|
96 |
|
97 /* |
|
98 * Explicitly update the bitstream buffer index. No need to |
|
99 * test whether the bit counter is zero since it is known |
|
100 * to be zero at this point. |
|
101 */ |
|
102 BITSASSERT(bs); |
|
103 bs->bit_counter = bs->slotBits; |
|
104 |
|
105 /*-- Store the lower (LSB) part to the bitstream buffer. --*/ |
|
106 bs->bit_counter = int16(bs->bit_counter - tmp); |
|
107 buf[bs->buf_index] &= bitMask[bs->bit_counter]; |
|
108 buf[bs->buf_index] |= ((word & bitMask[tmp]) << bs->bit_counter); |
|
109 } |
|
110 else |
|
111 { |
|
112 /* |
|
113 * Obtain the bit mask for the part that is to be modified. For example, |
|
114 * 'bit_counter' = 5 |
|
115 * 'n' = 3, |
|
116 * 'tmp' = 2 |
|
117 * |
|
118 * x x x m m m x x (x = ignore, m = bits to be modified) |
|
119 * |
|
120 * mask : |
|
121 * |
|
122 * 1 1 1 0 0 0 1 1 |
|
123 * |
|
124 */ |
|
125 buf[bs->buf_index] &= (~bitMask[bs->bit_counter]) | bitMask[tmp]; |
|
126 bs->bit_counter = tmp; |
|
127 buf[bs->buf_index] |= (word << bs->bit_counter); |
|
128 } |
|
129 |
|
130 /*-- Update the bitstream buffer index. --*/ |
|
131 if(bs->bit_counter == 0) |
|
132 { |
|
133 BITSASSERT(bs); |
|
134 bs->bit_counter = bs->slotBits; |
|
135 } |
|
136 } |
|
137 |
|
138 /* |
|
139 * Reads at most 8 bits from the bit buffer. |
|
140 */ |
|
141 uint32 |
|
142 GetBits(TBitStream *bs, int16 n) |
|
143 { |
|
144 int16 idx; |
|
145 uint32 tmp; |
|
146 |
|
147 idx = bs->bit_counter - n; |
|
148 if(idx < 0) |
|
149 { |
|
150 /* Mask the unwanted bits to zero. */ |
|
151 tmp = (bs->bit_buffer[bs->buf_index] & bitMask[bs->bit_counter]) << -idx; |
|
152 |
|
153 /* Update the bitstream buffer. */ |
|
154 BITSASSERT(bs); |
|
155 bs->bit_counter = bs->slotBits + idx; |
|
156 tmp |= (bs->bit_buffer[bs->buf_index] >> bs->bit_counter) & bitMask[-idx]; |
|
157 } |
|
158 else |
|
159 { |
|
160 bs->bit_counter = idx; |
|
161 tmp = (bs->bit_buffer[bs->buf_index] >> bs->bit_counter) & bitMask[n]; |
|
162 } |
|
163 |
|
164 /* Update the bitstream buffer index. */ |
|
165 if(bs->bit_counter == 0) |
|
166 { |
|
167 BITSASSERT(bs); |
|
168 bs->bit_counter = bs->slotBits; |
|
169 } |
|
170 |
|
171 return (tmp); |
|
172 } |
|
173 |
|
174 /* |
|
175 * Reads at most 16 bits from the bit buffer. |
|
176 */ |
|
177 uint32 |
|
178 GetBitsDSP(TBitStream *bs, int16 n) |
|
179 { |
|
180 int16 idx; |
|
181 uint32 tmp; |
|
182 |
|
183 idx = bs->bit_counter - n; |
|
184 if(idx < 0) |
|
185 { |
|
186 /* Mask the unwanted bits to zero. */ |
|
187 tmp = (bs->dsp_buffer[bs->buf_index] & bitMask[bs->bit_counter]) << -idx; |
|
188 |
|
189 /* Update the bitstream buffer. */ |
|
190 BITSASSERT(bs); |
|
191 bs->bit_counter = bs->slotBits + idx; |
|
192 tmp |= (bs->dsp_buffer[bs->buf_index] >> bs->bit_counter) & bitMask[-idx]; |
|
193 } |
|
194 else |
|
195 { |
|
196 bs->bit_counter = idx; |
|
197 tmp = (bs->dsp_buffer[bs->buf_index] >> bs->bit_counter) & bitMask[n]; |
|
198 } |
|
199 |
|
200 /* Update the bitstream buffer index. */ |
|
201 if(bs->bit_counter == 0) |
|
202 { |
|
203 BITSASSERT(bs); |
|
204 bs->bit_counter = bs->slotBits; |
|
205 } |
|
206 |
|
207 return (tmp); |
|
208 } |
|
209 |
|
210 //typedef uint32 (*GETBITS_FUNCTION)(BitStream *bs, int16 n); |
|
211 //static GETBITS_FUNCTION GetFunc[2] = {GetBits, GetBitsDSP}; |
|
212 |
|
213 /* |
|
214 * Returns the size of the buffer. |
|
215 */ |
|
216 EXPORT_C uint32 BsGetBufSize(TBitStream *bs) |
|
217 { return (bs->buf_len); } |
|
218 |
|
219 /* |
|
220 * Returns the size of the original buffer. Note that it is |
|
221 * possible that the update procedure of the bit buffer |
|
222 * (which is up to the implementor to specify), reduces the size |
|
223 * temporarily for some reasons. |
|
224 */ |
|
225 EXPORT_C uint32 BsGetBufOriginalSize(TBitStream *bs) |
|
226 { |
|
227 #ifndef BITSMODULO_BUFFER |
|
228 return (bs->buf_mask + 1); |
|
229 #else |
|
230 return (bs->buf_mask); |
|
231 #endif |
|
232 } |
|
233 |
|
234 /* |
|
235 * Returns the number of bits read. |
|
236 */ |
|
237 EXPORT_C uint32 BsGetBitsRead(TBitStream *bs) |
|
238 { return (bs->bits_read); } |
|
239 |
|
240 /* |
|
241 * Increments the value that describes how many |
|
242 * bits are read from the bitstream. |
|
243 */ |
|
244 EXPORT_C void BsSetBitsRead(TBitStream *bs, uint32 bits_read) |
|
245 { bs->bits_read += bits_read; } |
|
246 |
|
247 /* |
|
248 * Clears the value that describes how many |
|
249 * bits are read from the bitstream. |
|
250 */ |
|
251 EXPORT_C void BsClearBitsRead(TBitStream *bs) |
|
252 { bs->bits_read = 0; } |
|
253 |
|
254 /* |
|
255 * Returns the number of unread elements in the bit buffer. |
|
256 */ |
|
257 EXPORT_C uint32 BsSlotsLeft(TBitStream *bs) |
|
258 { return ((bs->buf_len < bs->slots_read) ? 0 : bs->buf_len - bs->slots_read); } |
|
259 |
|
260 /* |
|
261 * Resets the bitstream. |
|
262 */ |
|
263 EXPORT_C void BsReset(TBitStream *bs) |
|
264 { |
|
265 bs->buf_index = 0; |
|
266 bs->buf_writeIndex = 0; |
|
267 bs->bit_counter = bs->slotBits; |
|
268 bs->slots_read = 0; |
|
269 bs->bits_read = 0; |
|
270 } |
|
271 |
|
272 /* |
|
273 * Updates the bitstream values according to the given input parameter. |
|
274 */ |
|
275 EXPORT_C void BsBufferUpdate(TBitStream *bs, int32 bytesRead) |
|
276 { |
|
277 int32 diff = bs->bits_read - (bytesRead << 3); |
|
278 |
|
279 bs->buf_len = (bs->buf_len - bs->slots_read) + bytesRead; |
|
280 bs->slots_read = 0; |
|
281 |
|
282 if(diff < 0) |
|
283 bs->bits_read = -diff; |
|
284 else |
|
285 bs->bits_read = diff; |
|
286 } |
|
287 |
|
288 /************************************************************************** |
|
289 Title : BsInit |
|
290 |
|
291 Purpose : Initializes the bit buffer. |
|
292 |
|
293 Usage : BsInit(bs, bit_buffer, size) |
|
294 |
|
295 Input : bs - bitstream structure |
|
296 bit_buffer - address of bit buffer |
|
297 size - size of buffer |
|
298 |
|
299 Author(s) : Juha Ojanpera |
|
300 *************************************************************************/ |
|
301 |
|
302 EXPORT_C void |
|
303 BsInit(TBitStream *bs, uint8 *bit_buffer, uint32 size) |
|
304 { |
|
305 bs->dsp_buffer = NULL; |
|
306 bs->bit_buffer = bit_buffer; |
|
307 bs->mode = BIT8; |
|
308 #ifndef BITSMODULO_BUFFER |
|
309 bs->buf_mask = size - 1; |
|
310 #else |
|
311 bs->buf_mask = size; |
|
312 #endif |
|
313 bs->buf_len = size; |
|
314 bs->slotBits = sizeof(uint8) << 3; |
|
315 BsReset(bs); |
|
316 } |
|
317 |
|
318 void |
|
319 BsInit2(TBitStream *bs, DSP_BYTE *dsp_buffer, uint32 size) |
|
320 { |
|
321 bs->dsp_buffer = dsp_buffer; |
|
322 bs->bit_buffer = NULL; |
|
323 bs->mode = BIT16; |
|
324 #ifndef BITSMODULO_BUFFER |
|
325 bs->buf_mask = size - 1; |
|
326 #else |
|
327 bs->buf_mask = size; |
|
328 #endif |
|
329 bs->buf_len = size; |
|
330 bs->slotBits = sizeof(DSP_BYTE) << 3; |
|
331 BsReset(bs); |
|
332 } |
|
333 |
|
334 /************************************************************************** |
|
335 Title : BsByteAlign |
|
336 |
|
337 Purpose : Byte aligns the bit counter of the buffer. |
|
338 |
|
339 Usage : y = BsByteAlign(bs) |
|
340 |
|
341 Input : bs - bitstream parameters |
|
342 |
|
343 Output : y - # of bits read |
|
344 |
|
345 Author(s) : Juha Ojanpera |
|
346 *************************************************************************/ |
|
347 |
|
348 EXPORT_C int16 |
|
349 BsByteAlign(TBitStream *bs) |
|
350 { |
|
351 int16 bits_to_byte_align; |
|
352 |
|
353 bits_to_byte_align = bs->bit_counter & 7; |
|
354 if(bits_to_byte_align) |
|
355 BsSkipBits(bs, bits_to_byte_align); |
|
356 |
|
357 return (bits_to_byte_align); |
|
358 } |
|
359 |
|
360 /************************************************************************** |
|
361 Title : BsLookAhead |
|
362 |
|
363 Purpose : Looks ahead for the next 'n' bits from the bit buffer and |
|
364 returns the read 'n' bits. |
|
365 |
|
366 Usage : y = BsLookAhead(bs, n) |
|
367 |
|
368 Input : bs - bitstream parameters |
|
369 n - number of bits to be read from the bit buffer |
|
370 |
|
371 Output : y - bits read |
|
372 |
|
373 Author(s) : Juha Ojanpera |
|
374 *************************************************************************/ |
|
375 |
|
376 EXPORT_C uint32 |
|
377 BsLookAhead(TBitStream *bs, int16 n) |
|
378 { |
|
379 TBitStream bs_tmp; |
|
380 uint32 dword; |
|
381 |
|
382 /*-- Save the current state. --*/ |
|
383 COPY_MEMORY(&bs_tmp, bs, sizeof(TBitStream)); |
|
384 |
|
385 dword = BsGetBits(bs, n); |
|
386 |
|
387 /*-- Restore the original state. --*/ |
|
388 COPY_MEMORY(bs, &bs_tmp, sizeof(TBitStream)); |
|
389 |
|
390 return (dword); |
|
391 } |
|
392 |
|
393 /************************************************************************** |
|
394 Title : BsPutBits |
|
395 |
|
396 Purpose : Writes bits to the bit buffer. |
|
397 |
|
398 Usage : BsPutBits(bs, n, word); |
|
399 |
|
400 Input : bs - bitstream parameters |
|
401 n - number of bits to write |
|
402 word - bits to write |
|
403 |
|
404 Author(s) : Juha Ojanpera |
|
405 *************************************************************************/ |
|
406 |
|
407 EXPORT_C void |
|
408 BsPutBits(TBitStream *bs, int16 n, uint32 word) |
|
409 { |
|
410 int16 rbits; |
|
411 |
|
412 BsSetBitsRead(bs, n); |
|
413 |
|
414 /*-- Mask the unwanted bits to zero, just for safety. --*/ |
|
415 word &= bitMask[n]; |
|
416 |
|
417 while(n) |
|
418 { |
|
419 rbits = (n > (int16)bs->slotBits) ? bs->slotBits : n; |
|
420 n -= rbits; |
|
421 PutBits(bs, rbits, ((word >> n) & bitMask[rbits])); |
|
422 } |
|
423 } |
|
424 |
|
425 /************************************************************************** |
|
426 Title : BsPutBitsByteAlign |
|
427 |
|
428 Purpose : Byte aligns the write buffer. |
|
429 |
|
430 Usage : y = BsPutBitsByteAlign(bs) |
|
431 |
|
432 Input : bs - bitstream parameters |
|
433 |
|
434 Output : y - # of bits written |
|
435 |
|
436 Author(s) : Juha Ojanpera |
|
437 *************************************************************************/ |
|
438 |
|
439 EXPORT_C int16 |
|
440 BsPutBitsByteAlign(TBitStream *bs) |
|
441 { |
|
442 int16 bits_to_byte_align; |
|
443 |
|
444 bits_to_byte_align = bs->bit_counter & 7; |
|
445 if(bits_to_byte_align) |
|
446 BsPutBits(bs, bits_to_byte_align, 0); |
|
447 |
|
448 return (bits_to_byte_align); |
|
449 } |
|
450 |
|
451 /************************************************************************** |
|
452 Title : BsGetBits |
|
453 |
|
454 Purpose : Reads bits from the bit buffer. |
|
455 |
|
456 Usage : y = BsGetBits(bs, n); |
|
457 |
|
458 Input : bs - bitstream parameters |
|
459 n - number of bits to be read |
|
460 |
|
461 Output : y - bits read |
|
462 |
|
463 Author(s) : Juha Ojanpera |
|
464 *************************************************************************/ |
|
465 |
|
466 EXPORT_C uint32 |
|
467 BsGetBits(TBitStream *bs, int16 n) |
|
468 { |
|
469 int16 rbits = 0; |
|
470 uint32 value = 0; |
|
471 |
|
472 BsSetBitsRead(bs, n); |
|
473 |
|
474 while(n) |
|
475 { |
|
476 rbits = (n > (int16)bs->slotBits) ? bs->slotBits : n; |
|
477 value <<= rbits; |
|
478 |
|
479 // modified by Ali Ahmaniemi 7.6.04 |
|
480 |
|
481 if (bs->mode == BIT8) |
|
482 { |
|
483 value |= GetBits(bs, rbits); |
|
484 } |
|
485 else |
|
486 { |
|
487 value |= GetBitsDSP(bs, rbits); |
|
488 } |
|
489 |
|
490 //value |= GetFunc[bs->mode](bs, rbits); |
|
491 n -= rbits; |
|
492 } |
|
493 |
|
494 return (value); |
|
495 } |
|
496 |
|
497 /************************************************************************** |
|
498 Title : BsSkipBits |
|
499 |
|
500 Purpose : Advances the bit buffer index. |
|
501 |
|
502 Usage : BsSkipBits(bs, n); |
|
503 |
|
504 Input : bs - bitstream parameters |
|
505 n - number of bits to be discarded |
|
506 |
|
507 Explanation : The maximum number of bits that can be discarded is 'bs->slotBits'. |
|
508 |
|
509 Author(s) : Juha Ojanpera |
|
510 *************************************************************************/ |
|
511 |
|
512 EXPORT_C void |
|
513 BsSkipBits(TBitStream *bs, int16 n) |
|
514 { |
|
515 int16 idx; |
|
516 |
|
517 #ifdef USE_ASSERT |
|
518 MY_ASSERT(n < ((int16)bs->slotBits + 1)); |
|
519 #endif |
|
520 |
|
521 BsSetBitsRead(bs, n); |
|
522 |
|
523 idx = bs->bit_counter - n; |
|
524 if(idx < 0) |
|
525 { |
|
526 BITSASSERT(bs); |
|
527 bs->bit_counter = bs->slotBits + idx; |
|
528 } |
|
529 else |
|
530 bs->bit_counter = idx; |
|
531 |
|
532 if(bs->bit_counter == 0) |
|
533 { |
|
534 BITSASSERT(bs); |
|
535 bs->bit_counter = bs->slotBits; |
|
536 } |
|
537 } |
|
538 |
|
539 /************************************************************************** |
|
540 Title : BsSkipNbits |
|
541 |
|
542 Purpose : Same as 'BsSkipBits' with the exception that the number |
|
543 of bits to be discarded can be of any value. |
|
544 |
|
545 Usage : BsSkipNbits(bs, n); |
|
546 |
|
547 Input : bs - bitstream parameters |
|
548 n - number of bits to be discarded |
|
549 |
|
550 Author(s) : Juha Ojanpera |
|
551 *************************************************************************/ |
|
552 |
|
553 EXPORT_C void |
|
554 BsSkipNBits(TBitStream *bs, int32 n) |
|
555 { |
|
556 int32 slots, bits_left, scale; |
|
557 |
|
558 #ifdef BYTE_16bit |
|
559 scale = (bs->mode == BIT8) ? 3 : 4; |
|
560 #else |
|
561 scale = 3; |
|
562 #endif |
|
563 slots = (n >> scale); |
|
564 BsSetBitsRead(bs, slots << scale); |
|
565 bs->buf_index += slots; |
|
566 bs->buf_index = MOD_OPCODE(bs->buf_index, bs->buf_mask); |
|
567 bs->slots_read += slots; |
|
568 bits_left = n - (slots << scale); |
|
569 if(bits_left) |
|
570 BsSkipBits(bs, (int16) bits_left); |
|
571 } |
|
572 |
|
573 /************************************************************************** |
|
574 Title : BsCopyBytes |
|
575 |
|
576 Purpose : Copies 'bytesToCopy' bytes from the bit buffer (starting from |
|
577 the current read index) to the specified output buffer. |
|
578 |
|
579 Usage : y = BsCopyBytes(bs, outBuf, bytesToCopy) |
|
580 |
|
581 Input : bs - bitstream to be copied |
|
582 bytesToCopy - # of bytes to copy |
|
583 |
|
584 Output : y - # of bytes copied |
|
585 outBuf - copied bytes |
|
586 |
|
587 Author(s) : Juha Ojanpera |
|
588 *************************************************************************/ |
|
589 |
|
590 EXPORT_C uint32 |
|
591 BsCopyBytes(TBitStream *bs, uint8 *outBuf, uint32 bytesToCopy) |
|
592 { |
|
593 uint32 i; |
|
594 uint8 *buf0 = (bs->mode == BIT8) ? bs->bit_buffer : bs->dsp_buffer; |
|
595 |
|
596 for(i = bs->buf_index; i < (bytesToCopy + bs->buf_index); i++, outBuf++) |
|
597 *outBuf = buf0[MOD_OPCODE(i, bs->buf_mask)]; |
|
598 |
|
599 return (i - bs->buf_index); |
|
600 } |
|
601 |
|
602 /************************************************************************** |
|
603 Title : BsCopyBits |
|
604 |
|
605 Purpose : Copies 'bitsToCopy' bits from the source bit buffer (starting from |
|
606 the current read index) to the specified destination bit buffer. |
|
607 |
|
608 Usage : y = BsCopyBits(bsSrc, bsDst, bitsToCopy) |
|
609 |
|
610 Input : bsSrc - source bit buffer |
|
611 bytesToCopy - # of bits to copy |
|
612 |
|
613 Output : bsDst - destination bit buffer |
|
614 |
|
615 Author(s) : Juha Ojanpera |
|
616 *************************************************************************/ |
|
617 |
|
618 EXPORT_C void |
|
619 BsCopyBits(TBitStream *bsSrc, TBitStream *bsDst, int32 bitsToCopy) |
|
620 { |
|
621 int32 i, nBytes; |
|
622 |
|
623 nBytes = bitsToCopy >> 3; |
|
624 |
|
625 for(i = 0; i < nBytes; i++) |
|
626 BsPutBits(bsDst, 8, BsGetBits(bsSrc, 8)); |
|
627 |
|
628 i = bitsToCopy - (i << 3); |
|
629 if(i > 0) BsPutBits(bsDst, (int16) i, BsGetBits(bsSrc, (uint16) i)); |
|
630 } |
|
631 |
|
632 /************************************************************************** |
|
633 Title : BsRewindNBits |
|
634 |
|
635 Purpose : Rewinds the bit buffer 'nBits' bits. |
|
636 |
|
637 Usage : BsRewindNbits(br, nBits) |
|
638 |
|
639 Input : br - bitstream parameters |
|
640 nBits - number of bits to rewind |
|
641 |
|
642 Author(s) : Juha Ojanpera |
|
643 *************************************************************************/ |
|
644 |
|
645 EXPORT_C void |
|
646 BsRewindNBits(TBitStream *bs, uint32 nBits) |
|
647 { |
|
648 int32 tmp; |
|
649 int16 new_buf_idx, new_bit_idx; |
|
650 |
|
651 new_buf_idx = (int16) (nBits / bs->slotBits); |
|
652 new_bit_idx = (int16) (nBits % bs->slotBits); |
|
653 |
|
654 tmp = bs->bit_counter + new_bit_idx; |
|
655 if(tmp > (int16)bs->slotBits) |
|
656 { |
|
657 new_buf_idx++; |
|
658 bs->bit_counter = tmp - bs->slotBits; |
|
659 } |
|
660 else |
|
661 bs->bit_counter += new_bit_idx; |
|
662 |
|
663 bs->buf_index = MOD_OPCODE(bs->buf_index, bs->buf_mask); |
|
664 tmp = bs->buf_index - new_buf_idx; |
|
665 if(tmp > 0) |
|
666 bs->buf_index = tmp; |
|
667 else |
|
668 bs->buf_index = MOD_OPCODE(bs->buf_len + tmp, bs->buf_mask); |
|
669 |
|
670 bs->bits_read -= nBits; |
|
671 } |
|
672 |
|
673 EXPORT_C void |
|
674 BsSaveBufState(TBitStream *bsSrc, TBitStream *bsDst) |
|
675 { |
|
676 COPY_MEMORY(bsDst, bsSrc, sizeof(TBitStream)); |
|
677 } |