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 * Bit buffer reading operations. |
|
17 * |
|
18 */ |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 /* |
|
24 * Includes |
|
25 */ |
|
26 |
|
27 #include "h263dConfig.h" |
|
28 #include "Biblin.h" |
|
29 #include "debug.h" |
|
30 |
|
31 #ifdef DEBUG_OUTPUT |
|
32 bibBuffer_t * buffer_global; |
|
33 #endif |
|
34 |
|
35 |
|
36 /* |
|
37 * Definitions |
|
38 */ |
|
39 |
|
40 #define bibMalloc malloc |
|
41 #define bibCalloc calloc |
|
42 #define bibRealloc realloc |
|
43 #define bibDealloc free |
|
44 |
|
45 #ifndef bibAssert |
|
46 #define bibAssert(exp) assert(exp); |
|
47 #endif |
|
48 |
|
49 |
|
50 /* |
|
51 * Local function prototypes |
|
52 */ |
|
53 |
|
54 static void bibInitialize( |
|
55 bibBuffer_t *bibBuffer, |
|
56 void *srcBuffer, |
|
57 unsigned srcBufferLength, |
|
58 int16 *errorCode); |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 /* |
|
64 * Imported variables |
|
65 */ |
|
66 |
|
67 |
|
68 |
|
69 /* |
|
70 * Global functions |
|
71 */ |
|
72 |
|
73 /* {{-output"bibCreate.txt"}} */ |
|
74 /* |
|
75 * |
|
76 * bibCreate |
|
77 * |
|
78 * |
|
79 * Parameters: |
|
80 * srcBuffer buffer containing the data |
|
81 * srcBufferLength the length of the buffer |
|
82 * errorCode error code |
|
83 * |
|
84 * Function: |
|
85 * This function creates a bit buffer from a buffer given as a parameter. |
|
86 * |
|
87 * Returns: |
|
88 * The bibCreate function returns a pointer to a bibBuffer_t |
|
89 * structure. If the function is unsuccessful NULL is returned. |
|
90 * |
|
91 * Error codes: |
|
92 * ERR_BIB_STRUCT_ALLOC if the bit buffer structure could not be |
|
93 * allocated |
|
94 * |
|
95 */ |
|
96 |
|
97 bibBuffer_t *bibCreate(void *srcBuffer, unsigned srcBufferLength, int16 *errorCode) |
|
98 /* {{-output"bibCreate.txt"}} */ |
|
99 { |
|
100 bibBuffer_t *bibBuffer = NULL; |
|
101 int16 tmpError = 0; |
|
102 |
|
103 bibBuffer = (bibBuffer_t *) bibMalloc(sizeof(bibBuffer_t)); |
|
104 if (bibBuffer == NULL) { |
|
105 *errorCode = ERR_BIB_STRUCT_ALLOC; |
|
106 deb("bibCreate: ERROR - bibMalloc failed.\n"); |
|
107 return NULL; |
|
108 } |
|
109 |
|
110 bibInitialize(bibBuffer, srcBuffer, srcBufferLength, &tmpError); |
|
111 if (tmpError) { |
|
112 bibDealloc(bibBuffer); |
|
113 return NULL; |
|
114 } |
|
115 |
|
116 #ifdef DEBUG_OUTPUT |
|
117 debLoad("deb_dec.log"); |
|
118 buffer_global = bibBuffer; |
|
119 #endif |
|
120 |
|
121 return bibBuffer; |
|
122 } |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 bibBufferEdit_t *bibBufferEditCreate(int16 *errorCode) |
|
128 /* {{-output"bibCreate.txt"}} */ |
|
129 { |
|
130 bibBufferEdit_t *bufEdit = NULL; |
|
131 |
|
132 bufEdit = (bibBufferEdit_t *) bibMalloc(sizeof(bibBufferEdit_t)); |
|
133 if (bufEdit == NULL) { |
|
134 *errorCode = ERR_BIB_STRUCT_ALLOC; |
|
135 deb("bibBufferEditCreate: ERROR - bibMalloc failed.\n"); |
|
136 return NULL; |
|
137 } |
|
138 bufEdit->copyMode = CopyWhole/*CopyWhole*/; |
|
139 bufEdit->numChanges=0; |
|
140 bufEdit->editParams=NULL; |
|
141 |
|
142 return bufEdit; |
|
143 } |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 /* {{-output"bibDelete.txt"}} */ |
|
149 /* |
|
150 * |
|
151 * bibDelete |
|
152 * |
|
153 * |
|
154 * Parameters: |
|
155 * buffer a pointer to a bit buffer structure |
|
156 * errorCode error code |
|
157 * |
|
158 * Function: |
|
159 * The bibDelete function frees the memory allocated for the buffer. |
|
160 * |
|
161 * Returns: |
|
162 * Nothing |
|
163 * |
|
164 * Error codes: |
|
165 * None |
|
166 * |
|
167 */ |
|
168 |
|
169 void bibDelete(bibBuffer_t *buffer, int16 * /*errorCode*/) |
|
170 /* {{-output"bibDelete.txt"}} */ |
|
171 { |
|
172 if (buffer) { |
|
173 // note that the BaseAddr is just a reference to memory allocated elsewhere |
|
174 // and there is no other dynamic allocations inside buffer |
|
175 bibDealloc((void *) buffer); |
|
176 } |
|
177 } |
|
178 |
|
179 |
|
180 |
|
181 void bibBufEditDelete(bibBufferEdit_t *bufEdit, int16 * /*errorCode*/) |
|
182 { |
|
183 int i; |
|
184 if (bufEdit) { |
|
185 for(i=0; i<bufEdit->numChanges; i++) |
|
186 bibDealloc((void *) bufEdit->editParams); |
|
187 bibDealloc((void *) bufEdit); |
|
188 } |
|
189 } |
|
190 |
|
191 |
|
192 /* |
|
193 * |
|
194 * bibFlushBits |
|
195 * bibGetBits |
|
196 * bibShowBits |
|
197 * |
|
198 * |
|
199 * Parameters: |
|
200 * numberOfBits the number of bits wanted (1..32) |
|
201 * buffer a pointer to a bit buffer structure |
|
202 * numberOfBitsGot the number of bits actually got |
|
203 * syncStartIndex the number of the first bit belonging to |
|
204 * a synchronization code (1 .. numberOfBits). |
|
205 * Bits are numbered starting from 1 given to |
|
206 * the most significant bit of the returned code. |
|
207 * Thus, syncStartIndex - 1 most significant bits |
|
208 * of the returned code are valid coding |
|
209 * parameters (do not belong to a sync code). |
|
210 * 0 is returned if the returned code does not |
|
211 * contain any part of a synchronization code. |
|
212 * bitErrorIndication indication code for bit errors, |
|
213 * see biterr.h for the possible values |
|
214 * errorCode error code |
|
215 * |
|
216 * Function: |
|
217 * The bibFlushBits function removes the next numberOfBits bits from |
|
218 * the buffer. |
|
219 * |
|
220 * The bibGetBits function gets the next numberOfBits bits from the buffer. |
|
221 * The returned bits are removed. |
|
222 * |
|
223 * The bibShowBits function gets the next numberOfBits bits from the |
|
224 * buffer. The returned bits are not removed from the buffer. |
|
225 * |
|
226 * Returns: |
|
227 * bibGetBits and bibShowBits: |
|
228 * the next numberOfBits bits / the rest of the buffer if the end of |
|
229 * the input file has been reached |
|
230 * |
|
231 * Error codes: |
|
232 * ERR_BIB_NOT_ENOUGH_DATA if one tries to get more bits from the buffer |
|
233 * than there is left |
|
234 * |
|
235 */ |
|
236 |
|
237 void bibFlushBits(int numberOfBits, bibBuffer_t *buffer) |
|
238 { |
|
239 bibAssert(buffer != NULL); |
|
240 bibAssert(numberOfBits > 0 && numberOfBits <= 32); |
|
241 |
|
242 /* Check if enough bits are available. */ |
|
243 if (buffer->bitsLeft < (u_int32) numberOfBits) { |
|
244 goto flush_underflow; |
|
245 } |
|
246 buffer->bitsLeft -= numberOfBits; |
|
247 |
|
248 if ( buffer->bitIndex >= numberOfBits ) { |
|
249 /* All in the current byte, bits still left */ |
|
250 buffer->bitIndex -= numberOfBits; |
|
251 } |
|
252 else if ( buffer->bitIndex == (numberOfBits-1) ) { |
|
253 /* Current byte used completely */ |
|
254 buffer->bitIndex = 7; |
|
255 buffer->getIndex++; |
|
256 buffer->numBytesRead++; |
|
257 } |
|
258 else { |
|
259 /* Current byte plus then some */ |
|
260 numberOfBits -= buffer->bitIndex + 1; /* this many bits after current byte */ |
|
261 buffer->getIndex += ((numberOfBits>>3) + 1); |
|
262 buffer->numBytesRead += ((numberOfBits>>3) + 1); |
|
263 buffer->bitIndex = 7 - (numberOfBits&7); |
|
264 } |
|
265 return; |
|
266 flush_underflow: |
|
267 buffer->error = ERR_BIB_NOT_ENOUGH_DATA; |
|
268 } |
|
269 |
|
270 |
|
271 |
|
272 /* |
|
273 * |
|
274 * bibGetAlignedByte |
|
275 * |
|
276 * |
|
277 * A fast function to get one byte from byte-boundary. |
|
278 * |
|
279 */ |
|
280 inline u_int8 bibGetAlignedByte(bibBuffer_t *buffer) |
|
281 { |
|
282 return buffer->baseAddr[buffer->getIndex++]; |
|
283 } |
|
284 |
|
285 |
|
286 /* |
|
287 * |
|
288 * bibGetBits |
|
289 * |
|
290 * |
|
291 * See bibFlushBits. |
|
292 * |
|
293 */ |
|
294 |
|
295 u_int32 bibGetBits(int numberOfBits, bibBuffer_t *buffer) |
|
296 { |
|
297 static const u_char |
|
298 msbMask[8] = {1, 3, 7, 15, 31, 63, 127, 255}, |
|
299 lsbMask[9] = {255, 254, 252, 248, 240, 224, 192, 128, 0}; |
|
300 u_char |
|
301 *startAddr; |
|
302 int32 |
|
303 bitIndex; |
|
304 u_int32 |
|
305 endShift; /* the number of shifts after masking the last byte */ |
|
306 u_int32 |
|
307 numBytesFlushed; /* the number of bytes flushed from the buffer */ |
|
308 u_int32 |
|
309 returnValue = 0; |
|
310 |
|
311 bibAssert(buffer != NULL); |
|
312 bibAssert(numberOfBits > 0 && numberOfBits <= 32); |
|
313 |
|
314 startAddr = buffer->baseAddr + buffer->getIndex; |
|
315 bitIndex = buffer->bitIndex; |
|
316 |
|
317 /* Check if enough bits are available. */ |
|
318 if (buffer->bitsLeft < (u_int32) numberOfBits) { |
|
319 goto get_underflow; |
|
320 } |
|
321 |
|
322 buffer->bitsLeft -= numberOfBits; |
|
323 |
|
324 if ( bitIndex >= numberOfBits ) { |
|
325 /* All in the current byte, bits still left */ |
|
326 endShift = bitIndex - numberOfBits + 1; |
|
327 buffer->bitIndex -= numberOfBits; |
|
328 return ((startAddr[0] & msbMask[bitIndex] & lsbMask[endShift]) >> endShift); |
|
329 } |
|
330 else if ( bitIndex == (numberOfBits-1) ) { |
|
331 /* Current byte used completely */ |
|
332 buffer->bitIndex = 7; |
|
333 buffer->getIndex++; |
|
334 buffer->numBytesRead++; |
|
335 return startAddr[0] & msbMask[bitIndex]; |
|
336 } |
|
337 else { |
|
338 /* Current byte plus then some */ |
|
339 |
|
340 /* Remainder of this byte */ |
|
341 returnValue = *(startAddr++) & msbMask[bitIndex]; |
|
342 numberOfBits -= bitIndex + 1; |
|
343 numBytesFlushed = 1 + (numberOfBits >> 3); |
|
344 |
|
345 /* Get full bytes */ |
|
346 while ( numberOfBits >= 8 ) { |
|
347 returnValue = (returnValue << 8) | *(startAddr++); |
|
348 numberOfBits -= 8; |
|
349 } |
|
350 |
|
351 /* Get bits from last byte */ |
|
352 endShift = 8 - numberOfBits; |
|
353 returnValue = (returnValue << numberOfBits) | ((startAddr[0] & lsbMask[endShift]) >> endShift); |
|
354 /* (safe, since lsbMask[8]==0) */ |
|
355 |
|
356 /* Update position in buffer */ |
|
357 buffer->bitIndex = 7 - numberOfBits; |
|
358 buffer->getIndex += numBytesFlushed; |
|
359 buffer->numBytesRead += numBytesFlushed; |
|
360 } |
|
361 |
|
362 return returnValue; |
|
363 get_underflow: |
|
364 buffer->error = ERR_BIB_NOT_ENOUGH_DATA; |
|
365 return 0; |
|
366 } |
|
367 |
|
368 |
|
369 /* {{-output"bibNumberOfFlushedBits.txt"}} */ |
|
370 /* |
|
371 * |
|
372 * bibNumberOfFlushedBits |
|
373 * |
|
374 * |
|
375 * Parameters: |
|
376 * buffer a pointer to a bit buffer structure |
|
377 * |
|
378 * Function: |
|
379 * The bibNumberOfFlushedBytes returns the number of bits which |
|
380 * are got (bibGetBits) or flushed (bibFlushBits) from the buffer since |
|
381 * the buffer was created |
|
382 * |
|
383 * Returns: |
|
384 * See above. |
|
385 * |
|
386 * Error codes: |
|
387 * None. |
|
388 * |
|
389 */ |
|
390 |
|
391 u_int32 bibNumberOfFlushedBits(bibBuffer_t *buffer) |
|
392 /* {{-output"bibNumberOfFlushedBits.txt"}} */ |
|
393 { |
|
394 bibAssert(buffer != NULL); |
|
395 |
|
396 return ((buffer->numBytesRead<<3) + (7-buffer->bitIndex)); |
|
397 } |
|
398 |
|
399 |
|
400 /* {{-output"bibNumberOfFlushedBytes.txt"}} */ |
|
401 /* |
|
402 * |
|
403 * bibNumberOfFlushedBytes |
|
404 * |
|
405 * |
|
406 * Parameters: |
|
407 * buffer a pointer to a bit buffer structure |
|
408 * |
|
409 * Function: |
|
410 * The bibNumberOfFlushedBytes returns the number of whole bytes which |
|
411 * are got (bibGetBits) or flushed (bibFlushBits) from the buffer since |
|
412 * bibCreate was called. |
|
413 * |
|
414 * Returns: |
|
415 * See above. |
|
416 * |
|
417 * Error codes: |
|
418 * None. |
|
419 * |
|
420 */ |
|
421 |
|
422 u_int32 bibNumberOfFlushedBytes(bibBuffer_t *buffer) |
|
423 /* {{-output"bibNumberOfFlushedBytes.txt"}} */ |
|
424 { |
|
425 bibAssert(buffer != NULL); |
|
426 |
|
427 return buffer->numBytesRead; |
|
428 } |
|
429 |
|
430 |
|
431 /* {{-output"bibNumberOfRewBits.txt"}} */ |
|
432 /* |
|
433 * |
|
434 * bibNumberOfRewBits |
|
435 * |
|
436 * |
|
437 * Parameters: |
|
438 * buffer a pointer to a bit buffer structure |
|
439 * |
|
440 * Function: |
|
441 * The bibNumberOfRewBits returns the number of bits which can be |
|
442 * successfully rewinded. |
|
443 * |
|
444 * Returns: |
|
445 * See above. |
|
446 * |
|
447 * Error codes: |
|
448 * None. |
|
449 * |
|
450 */ |
|
451 |
|
452 u_int32 bibNumberOfRewBits(bibBuffer_t *buffer) |
|
453 /* {{-output"bibNumberOfRewBits.txt"}} */ |
|
454 { |
|
455 bibAssert(buffer != NULL); |
|
456 |
|
457 return ((buffer->numBytesRead<<3) + (7-buffer->bitIndex)); |
|
458 } |
|
459 |
|
460 |
|
461 /* {{-output"bibRewindBits.txt"}} */ |
|
462 /* |
|
463 * |
|
464 * bibRewindBits |
|
465 * |
|
466 * |
|
467 * Parameters: |
|
468 * numberOfBits the number of bits to rewind |
|
469 * buffer a pointer to a bit buffer structure |
|
470 * errorCode error code |
|
471 * |
|
472 * Function: |
|
473 * This function rewinds the pointers to the buffer |
|
474 * so that already flushed or got bits can be read |
|
475 * again. |
|
476 * |
|
477 * Returns: |
|
478 * Nothing. |
|
479 * |
|
480 * Error codes: |
|
481 * ERR_BIB_CANNOT_REWIND if numberOfBits is larger than which is |
|
482 * possible to get (see also bibNumberOfRewBits). |
|
483 * |
|
484 * ERR_BIB_BUFLIST if there was a fatal error when handling |
|
485 * buffer lists |
|
486 * |
|
487 */ |
|
488 |
|
489 void bibRewindBits(u_int32 numberOfBits, bibBuffer_t *buffer, int16 *errorCode) |
|
490 /* {{-output"bibRewindBits.txt"}} */ |
|
491 { |
|
492 bibAssert(buffer != NULL); |
|
493 |
|
494 /* All bits to rewind are in the latest byte */ |
|
495 if (numberOfBits <= (u_int32) (7 - buffer->bitIndex)) { |
|
496 buffer->bitIndex += numberOfBits; |
|
497 } |
|
498 /* Bits to rewind are within several bytes */ |
|
499 else { |
|
500 u_int32 |
|
501 numBitsWithoutFirstByte = numberOfBits - (7 - buffer->bitIndex), |
|
502 numWholeBytes = (numBitsWithoutFirstByte>>3), |
|
503 numBitsInLastByte = numBitsWithoutFirstByte - (numWholeBytes<<3); |
|
504 |
|
505 if (numBitsInLastByte) { |
|
506 if (buffer->getIndex >= numWholeBytes + 1) { |
|
507 buffer->getIndex -= numWholeBytes + 1; |
|
508 buffer->bitIndex = numBitsInLastByte - 1; |
|
509 buffer->numBytesRead -= numWholeBytes + 1; |
|
510 } |
|
511 else { |
|
512 *errorCode = ERR_BIB_CANNOT_REWIND; |
|
513 deb("bibRewindBits: ERROR - cannot rewind.\n"); |
|
514 } |
|
515 } |
|
516 else { |
|
517 if (buffer->getIndex >= numWholeBytes) { |
|
518 buffer->getIndex -= numWholeBytes; |
|
519 buffer->bitIndex = 7; |
|
520 buffer->numBytesRead -= numWholeBytes; |
|
521 } |
|
522 else { |
|
523 *errorCode = ERR_BIB_CANNOT_REWIND; |
|
524 deb("bibRewindBits: ERROR - cannot rewind.\n"); |
|
525 } |
|
526 } |
|
527 } |
|
528 buffer->bitsLeft += numberOfBits; |
|
529 } |
|
530 |
|
531 |
|
532 /* {{-output"bibShowBits.txt"}} */ |
|
533 /* |
|
534 * |
|
535 * bibShowBits |
|
536 * |
|
537 * |
|
538 * See bibFlushBits. |
|
539 * |
|
540 */ |
|
541 |
|
542 u_int32 bibShowBits(int numberOfBits, bibBuffer_t *buffer) |
|
543 /* {{-output"bibShowBits.txt"}} */ |
|
544 { |
|
545 static const u_char |
|
546 msbMask[8] = {1, 3, 7, 15, 31, 63, 127, 255}, |
|
547 lsbMask[9] = {255, 254, 252, 248, 240, 224, 192, 128, 0}; |
|
548 u_char |
|
549 *startAddr; |
|
550 int32 |
|
551 bitIndex; |
|
552 u_int32 |
|
553 endShift; /* the number of shifts after masking the last byte */ |
|
554 u_int32 |
|
555 returnValue = 0; |
|
556 |
|
557 bibAssert(buffer != NULL); |
|
558 bibAssert(numberOfBits > 0 && numberOfBits <= 32); |
|
559 |
|
560 startAddr = buffer->baseAddr + buffer->getIndex; |
|
561 bitIndex = buffer->bitIndex; |
|
562 |
|
563 /* Check if enough bits are available. */ |
|
564 if (buffer->bitsLeft < (u_int32) numberOfBits) { |
|
565 goto show_underflow; |
|
566 } |
|
567 |
|
568 if ( bitIndex >= numberOfBits ) { |
|
569 /* All in the current byte, bits still left */ |
|
570 endShift = bitIndex - numberOfBits + 1; |
|
571 return ((startAddr[0] & msbMask[bitIndex] & lsbMask[endShift]) >> endShift); |
|
572 } |
|
573 else if ( bitIndex == (numberOfBits-1) ) { |
|
574 /* Current byte used completely */ |
|
575 return startAddr[0] & msbMask[bitIndex]; |
|
576 } |
|
577 else { |
|
578 /* Current byte plus then some */ |
|
579 |
|
580 /* Remainder of this byte */ |
|
581 returnValue = *(startAddr++) & msbMask[bitIndex]; |
|
582 numberOfBits -= bitIndex + 1; |
|
583 |
|
584 /* Get full bytes */ |
|
585 while ( numberOfBits >= 8 ) |
|
586 { |
|
587 returnValue = (returnValue << 8) | *(startAddr++); |
|
588 numberOfBits -= 8; |
|
589 } |
|
590 |
|
591 /* Get bits from last byte */ |
|
592 endShift = 8 - numberOfBits; |
|
593 returnValue = (returnValue << numberOfBits) | ((startAddr[0] & lsbMask[endShift]) >> endShift); |
|
594 /* (safe, since lsbMask[8]==0) */ |
|
595 } |
|
596 |
|
597 return returnValue; |
|
598 show_underflow: |
|
599 buffer->error = ERR_BIB_NOT_ENOUGH_DATA; |
|
600 return 0; |
|
601 } |
|
602 |
|
603 |
|
604 /* |
|
605 * Local functions |
|
606 */ |
|
607 |
|
608 /* |
|
609 * |
|
610 * bibInitialize |
|
611 * |
|
612 * |
|
613 * Parameters: |
|
614 * bibBuffer input bit buffer instance |
|
615 * srcBuffer buffer containing the data |
|
616 * srcBufferLength the length of the buffer |
|
617 * errorCode error code |
|
618 * |
|
619 * Function: |
|
620 * This function initializes the values of the bibBuffer structure. |
|
621 * |
|
622 * Returns: |
|
623 * Nothing. |
|
624 * |
|
625 * Error codes: |
|
626 * ERR_BIB_BUFLIST if the internal buffer list has been corrupted |
|
627 * |
|
628 */ |
|
629 |
|
630 static void bibInitialize( |
|
631 bibBuffer_t *bibBuffer, |
|
632 void *srcBuffer, |
|
633 unsigned srcBufferLength, |
|
634 int16 */*errorCode*/) |
|
635 { |
|
636 bibBuffer->baseAddr = (u_char *) srcBuffer; |
|
637 bibBuffer->size = srcBufferLength; |
|
638 bibBuffer->getIndex = 0; |
|
639 bibBuffer->bitIndex = 7; |
|
640 bibBuffer->bitsLeft = (u_int32) (srcBufferLength<<3); |
|
641 bibBuffer->numBytesRead = 0; |
|
642 bibBuffer->error = 0; |
|
643 |
|
644 |
|
645 } |
|
646 |
|
647 |
|
648 |
|
649 /* |
|
650 * |
|
651 * CopyStream |
|
652 * |
|
653 * |
|
654 * Function to copy stream from SrcBuffer to DestBuffer based on settings in bufEdit and ByteStart & BitStart |
|
655 * |
|
656 * |
|
657 */ |
|
658 |
|
659 void CopyStream(bibBuffer_t *SrcBuffer,bibBuffer_t *DestBuffer,bibBufferEdit_t *bufEdit, |
|
660 int ByteStart, int BitStart) |
|
661 { |
|
662 int32 temp; |
|
663 unsigned tgetIndex; |
|
664 int tbitIndex; |
|
665 u_int32 tbitsLeft; |
|
666 u_int32 tnumBytesRead; |
|
667 int tByteStart; |
|
668 int tBitStart; |
|
669 |
|
670 bibEditParams_t *edParam; |
|
671 |
|
672 //Add assertions and checks here !! |
|
673 bibAssert(SrcBuffer->baseAddr); |
|
674 bibAssert(DestBuffer->baseAddr); |
|
675 bibAssert(bufEdit); |
|
676 |
|
677 //Save the params of SrcBuffer to recover them later: |
|
678 tgetIndex=SrcBuffer->getIndex; |
|
679 tbitIndex=SrcBuffer->bitIndex; |
|
680 tbitsLeft=SrcBuffer->bitsLeft; |
|
681 tnumBytesRead=SrcBuffer->numBytesRead; |
|
682 |
|
683 |
|
684 |
|
685 // check to see if we need to change some header parameter |
|
686 if(bufEdit->copyMode == CopyWithEdit/*CopyWithEdit*/) |
|
687 { |
|
688 bibAssert(bufEdit->editParams); |
|
689 edParam = &(bufEdit->editParams[0]); |
|
690 |
|
691 // check if the editing position is in the current range of bit data |
|
692 temp=((SrcBuffer->getIndex<<3) + (7-SrcBuffer->bitIndex))- |
|
693 ((edParam->StartByteIndex<<3) + 7-(edParam->StartBitIndex)); |
|
694 if (temp>=0) // yes, it is |
|
695 { |
|
696 // copy upto the editing point |
|
697 CopyBuffer(SrcBuffer, DestBuffer, ByteStart, BitStart, edParam->StartByteIndex, |
|
698 edParam->StartBitIndex); |
|
699 |
|
700 CopyBufferEdit(SrcBuffer, DestBuffer, &(bufEdit->editParams[0])); |
|
701 |
|
702 // store new starting copy position |
|
703 tByteStart = SrcBuffer->getIndex; |
|
704 tBitStart = SrcBuffer->bitIndex; |
|
705 // restore original stop copy position |
|
706 SrcBuffer->getIndex=tgetIndex; |
|
707 SrcBuffer->bitIndex=tbitIndex; |
|
708 SrcBuffer->bitsLeft=tbitsLeft; |
|
709 SrcBuffer->numBytesRead=tnumBytesRead; |
|
710 |
|
711 CopyBuffer(SrcBuffer, DestBuffer, tByteStart, tBitStart, tgetIndex, tbitIndex); |
|
712 |
|
713 } |
|
714 else // no |
|
715 { |
|
716 // put panic here ! |
|
717 return; |
|
718 } |
|
719 } |
|
720 else if (bufEdit->copyMode == CopyWhole/*CopyWhole*/) |
|
721 { |
|
722 CopyBuffer(SrcBuffer, DestBuffer, ByteStart, BitStart, |
|
723 SrcBuffer->getIndex, SrcBuffer->bitIndex); |
|
724 } |
|
725 else if (bufEdit->copyMode == EditOnly /*EditOnly*/) |
|
726 { |
|
727 CopyBufferEdit(SrcBuffer, DestBuffer, &(bufEdit->editParams[0])); |
|
728 } |
|
729 else if(bufEdit->copyMode == CopyNone/*CopyNone*/) |
|
730 { |
|
731 return; |
|
732 } |
|
733 |
|
734 |
|
735 //4- Retrieve the original Srcbuffer params. |
|
736 // Using getbits it should be equal to where we started |
|
737 SrcBuffer->getIndex=tgetIndex; |
|
738 SrcBuffer->bitIndex=tbitIndex; |
|
739 SrcBuffer->bitsLeft=tbitsLeft; |
|
740 SrcBuffer->numBytesRead=tnumBytesRead; |
|
741 |
|
742 //5- Update the destbuffer statistics: |
|
743 DestBuffer->getIndex=DestBuffer->numBytesRead; |
|
744 |
|
745 DestBuffer->bitsLeft -= (DestBuffer->getIndex<<3); |
|
746 |
|
747 } |
|
748 |
|
749 /* |
|
750 * |
|
751 * CopyBuffer |
|
752 * |
|
753 * |
|
754 * Function to copy data from SrcBuffer to DestBuffer from ByteStart & BitStart to ByteEnd & BitEnd |
|
755 * |
|
756 * |
|
757 */ |
|
758 |
|
759 void CopyBuffer(bibBuffer_t *SrcBuffer,bibBuffer_t *DestBuffer, |
|
760 int ByteStart,int BitStart, int ByteEnd, int BitEnd) |
|
761 { |
|
762 u_char *DestStartAddr; |
|
763 u_int32 i; |
|
764 u_int32 temp; |
|
765 u_int32 BitsToRewind; |
|
766 u_int32 BitsToCopy; |
|
767 u_int32 BytesToCopy; |
|
768 u_int32 Bytes4ToCopy; |
|
769 u_int32 BitsRemaining; |
|
770 int16 errorCode; |
|
771 u_int32 bitshift; |
|
772 u_int32 bitstoget; |
|
773 static const u_char msbMask[8] = {1, 3, 7, 15, 31, 63, 127, 255}; |
|
774 |
|
775 DestStartAddr = DestBuffer->baseAddr + DestBuffer->getIndex; |
|
776 |
|
777 //Rewind the src buffer to the start address(ByteStart,BitStart) |
|
778 BitsToRewind=((SrcBuffer->getIndex<<3) + (7-SrcBuffer->bitIndex))- |
|
779 ((ByteStart<<3) + (7-BitStart)); |
|
780 bibRewindBits(BitsToRewind,SrcBuffer, &errorCode); |
|
781 |
|
782 // evaluate the number of bits to copy |
|
783 BitsToCopy = ((ByteEnd<<3) + (7-BitEnd))-((ByteStart<<3) + (7-BitStart)); |
|
784 if (BitsToCopy<=0) |
|
785 return; |
|
786 else if (BitsToCopy > BitsToRewind) |
|
787 BitsToCopy = BitsToRewind; // or else provide a panic here !!! |
|
788 |
|
789 //1- Fill the remaining of the byte in destination: |
|
790 bitshift=0; |
|
791 bitstoget=0; |
|
792 if(DestBuffer->bitIndex!=7) |
|
793 { |
|
794 bitshift = DestBuffer->bitIndex+1; |
|
795 bitstoget = ((BitsToCopy < bitshift) ? BitsToCopy : bitshift); |
|
796 temp = bibGetBits(bitstoget,SrcBuffer); |
|
797 |
|
798 // update statistics to take care of bit addition or byte completion |
|
799 if (BitsToCopy < bitshift) |
|
800 { |
|
801 // bits added but byte not completed |
|
802 *(DestStartAddr)=(unsigned char)((((*DestStartAddr)>>bitshift)<<bitshift) | |
|
803 ((temp << (bitshift-BitsToCopy) ) & msbMask[bitshift-1])); |
|
804 DestBuffer->bitIndex -= BitsToCopy; |
|
805 bibAssert(DestBuffer->bitIndex >= 0) |
|
806 } |
|
807 else |
|
808 { |
|
809 // byte completed |
|
810 *(DestStartAddr)=(unsigned char)((((*DestStartAddr)>>bitshift)<<(bitshift)) | |
|
811 (temp & msbMask[bitshift-1])); |
|
812 DestStartAddr+=1; |
|
813 DestBuffer->numBytesRead++; |
|
814 DestBuffer->bitIndex=7; |
|
815 } |
|
816 } |
|
817 |
|
818 //2- Extract all bytes (in 8 bits) from src to destination. |
|
819 //Checks for BytesToCopy. |
|
820 BytesToCopy=(BitsToCopy-bitstoget)>>3; |
|
821 if ( BytesToCopy > 0 ) |
|
822 { |
|
823 |
|
824 if ( SrcBuffer->bitIndex == 7 ) |
|
825 { |
|
826 // we can copy the data from src in full bytes, utilize faster inline method |
|
827 // and try to utilize pipelining in the for-loop |
|
828 // truncate it to 4-byte-boundary |
|
829 Bytes4ToCopy = BytesToCopy>>2; |
|
830 for(i=0; i<Bytes4ToCopy; i++) |
|
831 { |
|
832 *(DestStartAddr++) = bibGetAlignedByte(SrcBuffer); |
|
833 *(DestStartAddr++) = bibGetAlignedByte(SrcBuffer); |
|
834 *(DestStartAddr++) = bibGetAlignedByte(SrcBuffer); |
|
835 *(DestStartAddr++) = bibGetAlignedByte(SrcBuffer); |
|
836 } |
|
837 i <<= 2; |
|
838 if ( BytesToCopy > i ) |
|
839 { |
|
840 // copy the leftovers |
|
841 for(;i<BytesToCopy;i++) |
|
842 { |
|
843 *(DestStartAddr++) = bibGetAlignedByte(SrcBuffer); |
|
844 } |
|
845 } |
|
846 SrcBuffer->numBytesRead+=i; |
|
847 } |
|
848 else |
|
849 { |
|
850 for(i=0;i<BytesToCopy;i++) |
|
851 { |
|
852 *(DestStartAddr++) = (unsigned char)bibGetBits(8,SrcBuffer); |
|
853 } |
|
854 |
|
855 } |
|
856 } |
|
857 DestBuffer->numBytesRead+=BytesToCopy; |
|
858 |
|
859 //3- Fill the last byte: |
|
860 BitsRemaining=((BitsToCopy-bitstoget))%8; |
|
861 if(BitsRemaining!=0) |
|
862 { |
|
863 temp = bibGetBits(BitsRemaining,SrcBuffer); |
|
864 *(DestStartAddr++)=(u_char)(temp<<(8-BitsRemaining)); |
|
865 DestBuffer->bitIndex=7-BitsRemaining; |
|
866 } |
|
867 |
|
868 //5- Update the destbuffer statistics: |
|
869 DestBuffer->getIndex=DestBuffer->numBytesRead; |
|
870 } |
|
871 |
|
872 /* |
|
873 * |
|
874 * CopyBufferEdit |
|
875 * |
|
876 * |
|
877 * Function to copy data with editing from SrcBuffer to DestBuffer with settings in edParam |
|
878 * |
|
879 * |
|
880 */ |
|
881 |
|
882 void CopyBufferEdit(bibBuffer_t *SrcBuffer, bibBuffer_t *DestBuffer, |
|
883 bibEditParams_t *edParam, int updateSrcBufferStats) |
|
884 { |
|
885 u_char *DestStartAddr; |
|
886 u_int32 i; |
|
887 u_int32 temp; |
|
888 u_int32 BitsToSkip; |
|
889 u_int32 BitsToEdit; |
|
890 u_int32 BytesToSkip; |
|
891 u_int32 BitsRemaining; |
|
892 u_int32 BytesToEdit; |
|
893 unsigned bitshift; |
|
894 unsigned bitstoget; |
|
895 unsigned bitstomove; |
|
896 u_int32 StartBitPosition; |
|
897 static const u_char msbMask[8] = {1, 3, 7, 15, 31, 63, 127, 255}; |
|
898 |
|
899 DestStartAddr = DestBuffer->baseAddr + DestBuffer->getIndex; |
|
900 |
|
901 // evaluate the number of bits to copy |
|
902 BitsToEdit = edParam->newNumBits; |
|
903 StartBitPosition = edParam->newNumBits-1; |
|
904 |
|
905 //1- Fill the remaining of the byte in destination: |
|
906 bitshift=0; |
|
907 bitstoget=0; |
|
908 if(DestBuffer->bitIndex!=7) |
|
909 { |
|
910 bitshift=DestBuffer->bitIndex+1; |
|
911 bitstoget = ((BitsToEdit < bitshift) ? BitsToEdit : bitshift); |
|
912 |
|
913 temp = bibGetBitsFromWord(edParam->newValue, bitstoget, &StartBitPosition, |
|
914 edParam->newNumBits); |
|
915 |
|
916 // update statistics to take care of bit addition or byte completion |
|
917 if (BitsToEdit < bitshift) |
|
918 { |
|
919 // bits added but byte not completed |
|
920 *(DestStartAddr)=(unsigned char)((((*DestStartAddr)>>bitshift)<<(bitshift)) | |
|
921 ((temp << (bitshift-BitsToEdit) ) & msbMask[bitshift-1])); |
|
922 DestBuffer->bitIndex -= BitsToEdit; |
|
923 bibAssert(DestBuffer->bitIndex >= 0) |
|
924 } |
|
925 else |
|
926 { |
|
927 // byte completed |
|
928 *(DestStartAddr)=(unsigned char)((((*DestStartAddr)>>bitshift)<<(bitshift)) | |
|
929 (temp & msbMask[bitshift-1])); |
|
930 DestStartAddr++; |
|
931 DestBuffer->numBytesRead++; |
|
932 DestBuffer->bitIndex=7; |
|
933 } |
|
934 } |
|
935 |
|
936 |
|
937 //2- Extract all bytes (in 8 bits) from src to destination. |
|
938 //Checks for BytesToCopy |
|
939 BytesToEdit=(BitsToEdit-bitstoget)>>3; |
|
940 for(i=0;i<BytesToEdit;i++) |
|
941 { |
|
942 *(DestStartAddr++)=(unsigned char)bibGetBitsFromWord(edParam->newValue, 8, &StartBitPosition, edParam->newNumBits); |
|
943 } |
|
944 DestBuffer->numBytesRead+=BytesToEdit; |
|
945 |
|
946 //3- Fill the last byte: |
|
947 BitsRemaining=((BitsToEdit-bitstoget))%8; |
|
948 if(BitsRemaining!=0) |
|
949 { |
|
950 temp = bibGetBitsFromWord(edParam->newValue, BitsRemaining, &StartBitPosition, |
|
951 edParam->newNumBits); |
|
952 *(DestStartAddr++)=(u_char)(temp<<(8-BitsRemaining)); |
|
953 DestBuffer->bitIndex=7-BitsRemaining; |
|
954 } |
|
955 |
|
956 //5- Update the destbuffer statistics: |
|
957 DestBuffer->getIndex=DestBuffer->numBytesRead; |
|
958 |
|
959 |
|
960 // update the src buffer statistics to reflect skipping of the value |
|
961 if(updateSrcBufferStats) |
|
962 { |
|
963 BitsToSkip = edParam->curNumBits; |
|
964 bitshift=0; |
|
965 bitstomove=0; |
|
966 if (SrcBuffer->bitIndex!=7) |
|
967 { |
|
968 bitshift=SrcBuffer->bitIndex+1; |
|
969 bitstomove = ((BitsToSkip < bitshift) ? BitsToSkip : bitshift); |
|
970 // update statistics to take care of bit addition or byte completion |
|
971 if (BitsToSkip < bitshift) |
|
972 { |
|
973 // bits skipped but byte not completed |
|
974 SrcBuffer->bitIndex -= bitstomove; |
|
975 bibAssert(SrcBuffer->bitIndex >= 0) |
|
976 } |
|
977 else |
|
978 { |
|
979 // byte completed |
|
980 SrcBuffer->numBytesRead++; |
|
981 SrcBuffer->bitIndex=7; |
|
982 } |
|
983 } |
|
984 // full bytes to skip |
|
985 BytesToSkip=(BitsToSkip-bitstomove)>>3; |
|
986 SrcBuffer->numBytesRead+=BytesToSkip; |
|
987 |
|
988 // skip the remaining bits |
|
989 BitsRemaining=((BitsToSkip-bitstomove))%8; |
|
990 if(BitsRemaining!=0) |
|
991 { |
|
992 SrcBuffer->bitIndex=7-BitsRemaining; |
|
993 } |
|
994 SrcBuffer->bitsLeft -= BitsToSkip; |
|
995 SrcBuffer->getIndex=SrcBuffer->numBytesRead; |
|
996 } |
|
997 } |
|
998 |
|
999 void ResetH263IntraDcUV(bibBuffer_t *DestBuffer, int uValue, int vValue) |
|
1000 { |
|
1001 bibEditParams_t edParam; |
|
1002 |
|
1003 edParam.curNumBits = edParam.newNumBits = 8; |
|
1004 edParam.StartByteIndex = edParam.StartBitIndex = 0; // used for source buffer only |
|
1005 |
|
1006 // u |
|
1007 edParam.newValue = uValue; |
|
1008 CopyBufferEdit((bibBuffer_t*)NULL, DestBuffer, &edParam, 0); |
|
1009 // v |
|
1010 edParam.newValue = vValue; |
|
1011 CopyBufferEdit((bibBuffer_t*)NULL, DestBuffer, &edParam, 0); |
|
1012 } |
|
1013 |
|
1014 void ResetMPEG4IntraDcUV(bibBuffer_t *DestBuffer, int IntraDC_size) |
|
1015 { |
|
1016 int i; |
|
1017 bibEditParams_t edParam; |
|
1018 const int DctDcSizeChrominanceNumBits[13] = { 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; |
|
1019 |
|
1020 // u,v |
|
1021 for(i=0; i<2; i++) |
|
1022 { |
|
1023 // change dct dc size chrominance - IntraDC for U.V is 0 (codeword '11') |
|
1024 edParam.curNumBits = DctDcSizeChrominanceNumBits[IntraDC_size]; |
|
1025 edParam.newNumBits = 2; |
|
1026 edParam.StartByteIndex = edParam.StartBitIndex = 0; // used or source buffer only |
|
1027 edParam.newValue = 3; |
|
1028 CopyBufferEdit((bibBuffer_t*)NULL, DestBuffer, &edParam, 0); |
|
1029 } |
|
1030 } |
|
1031 |
|
1032 // assume SrcValue is max 32 bits |
|
1033 u_int32 bibGetBitsFromWord(u_int32 SrcValue, u_int32 getBits, u_int32 *StartBit, |
|
1034 u_int32 MaxNumBits) |
|
1035 { |
|
1036 int val; |
|
1037 u_int32 bitshift; |
|
1038 static const u_int32 mask[32] = |
|
1039 {0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, |
|
1040 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, |
|
1041 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, |
|
1042 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff}; |
|
1043 |
|
1044 bibAssert(MaxNumBits <= 32); |
|
1045 bibAssert(*StartBit < MaxNumBits); |
|
1046 bibAssert(getBits-1 <= *StartBit); |
|
1047 bibAssert(getBits > 0); |
|
1048 |
|
1049 bitshift = *StartBit - getBits + 1; |
|
1050 val = (SrcValue>>bitshift) & mask[getBits-1]; |
|
1051 if ( getBits > *StartBit ) |
|
1052 { |
|
1053 // taking the last bits of the word; *StartBit is uint32, so it goes to max uint32 unless this special handling |
|
1054 // other cases asserted already above |
|
1055 *StartBit = 31; |
|
1056 } |
|
1057 else |
|
1058 { |
|
1059 *StartBit -= getBits; |
|
1060 } |
|
1061 |
|
1062 return val; |
|
1063 } |
|
1064 |
|
1065 void bibForwardBits(u_int32 numberOfBits, bibBuffer_t *buffer) |
|
1066 { |
|
1067 u_int32 BitsToForward; |
|
1068 u_int32 BytesToForward; |
|
1069 u_int32 BitsRemaining; |
|
1070 unsigned bitshift; |
|
1071 unsigned bitstomove; |
|
1072 |
|
1073 BitsToForward = numberOfBits; |
|
1074 bitshift=0; |
|
1075 bitstomove=0; |
|
1076 |
|
1077 bibAssert(buffer != NULL); |
|
1078 |
|
1079 // complete the byte |
|
1080 if (buffer->bitIndex!=7) |
|
1081 { |
|
1082 bitshift=buffer->bitIndex+1; |
|
1083 bitstomove = ((BitsToForward < bitshift) ? BitsToForward : bitshift); |
|
1084 // update statistics to take care of bit addition or byte completion |
|
1085 if (BitsToForward < bitshift) |
|
1086 { |
|
1087 // bits skipped but byte not completed |
|
1088 buffer->bitIndex -= bitstomove; |
|
1089 bibAssert(buffer->bitIndex >= 0) |
|
1090 } |
|
1091 else |
|
1092 { |
|
1093 // byte completed |
|
1094 buffer->numBytesRead++; |
|
1095 buffer->bitIndex=7; |
|
1096 } |
|
1097 } |
|
1098 // full bytes to skip |
|
1099 BytesToForward=(BitsToForward-bitstomove)>>3; |
|
1100 buffer->numBytesRead+=BytesToForward; |
|
1101 |
|
1102 // skip the remaining bits |
|
1103 BitsRemaining=((BitsToForward-bitstomove))%8; |
|
1104 if(BitsRemaining!=0) |
|
1105 { |
|
1106 buffer->bitIndex=7-BitsRemaining; |
|
1107 } |
|
1108 buffer->bitsLeft -= BitsToForward; |
|
1109 buffer->getIndex=buffer->numBytesRead; |
|
1110 } |
|
1111 |
|
1112 void bibStuffBits(bibBuffer_t *buffer) |
|
1113 { |
|
1114 // the extra bits are already set to zero |
|
1115 bibAssert(buffer->baseAddr); |
|
1116 if(buffer->bitIndex!=7) |
|
1117 { |
|
1118 buffer->bitIndex=7; |
|
1119 buffer->getIndex++; |
|
1120 buffer->numBytesRead++; |
|
1121 } |
|
1122 } |
|
1123 |
|
1124 |
|
1125 |
|
1126 |
|
1127 // End of File |
|