--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/videoeditorengine/h263decoder/src/biblin.cpp Fri Jan 29 14:08:33 2010 +0200
@@ -0,0 +1,1127 @@
+/*
+* Copyright (c) 2010 Ixonos Plc.
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - Initial contribution
+*
+* Contributors:
+* Ixonos Plc
+*
+* Description:
+* Bit buffer reading operations.
+*
+*/
+
+
+
+
+/*
+* Includes
+*/
+
+#include "h263dConfig.h"
+#include "Biblin.h"
+#include "debug.h"
+
+#ifdef DEBUG_OUTPUT
+bibBuffer_t * buffer_global;
+#endif
+
+
+/*
+* Definitions
+*/
+
+#define bibMalloc malloc
+#define bibCalloc calloc
+#define bibRealloc realloc
+#define bibDealloc free
+
+#ifndef bibAssert
+#define bibAssert(exp) assert(exp);
+#endif
+
+
+/*
+* Local function prototypes
+*/
+
+static void bibInitialize(
+ bibBuffer_t *bibBuffer,
+ void *srcBuffer,
+ unsigned srcBufferLength,
+ int16 *errorCode);
+
+
+
+
+/*
+* Imported variables
+*/
+
+
+
+/*
+* Global functions
+*/
+
+/* {{-output"bibCreate.txt"}} */
+/*
+*
+* bibCreate
+*
+*
+* Parameters:
+* srcBuffer buffer containing the data
+* srcBufferLength the length of the buffer
+* errorCode error code
+*
+* Function:
+* This function creates a bit buffer from a buffer given as a parameter.
+*
+* Returns:
+* The bibCreate function returns a pointer to a bibBuffer_t
+* structure. If the function is unsuccessful NULL is returned.
+*
+* Error codes:
+* ERR_BIB_STRUCT_ALLOC if the bit buffer structure could not be
+* allocated
+*
+*/
+
+bibBuffer_t *bibCreate(void *srcBuffer, unsigned srcBufferLength, int16 *errorCode)
+/* {{-output"bibCreate.txt"}} */
+{
+ bibBuffer_t *bibBuffer = NULL;
+ int16 tmpError = 0;
+
+ bibBuffer = (bibBuffer_t *) bibMalloc(sizeof(bibBuffer_t));
+ if (bibBuffer == NULL) {
+ *errorCode = ERR_BIB_STRUCT_ALLOC;
+ deb("bibCreate: ERROR - bibMalloc failed.\n");
+ return NULL;
+ }
+
+ bibInitialize(bibBuffer, srcBuffer, srcBufferLength, &tmpError);
+ if (tmpError) {
+ bibDealloc(bibBuffer);
+ return NULL;
+ }
+
+#ifdef DEBUG_OUTPUT
+ debLoad("deb_dec.log");
+ buffer_global = bibBuffer;
+#endif
+
+ return bibBuffer;
+}
+
+
+
+
+bibBufferEdit_t *bibBufferEditCreate(int16 *errorCode)
+/* {{-output"bibCreate.txt"}} */
+{
+ bibBufferEdit_t *bufEdit = NULL;
+
+ bufEdit = (bibBufferEdit_t *) bibMalloc(sizeof(bibBufferEdit_t));
+ if (bufEdit == NULL) {
+ *errorCode = ERR_BIB_STRUCT_ALLOC;
+ deb("bibBufferEditCreate: ERROR - bibMalloc failed.\n");
+ return NULL;
+ }
+ bufEdit->copyMode = CopyWhole/*CopyWhole*/;
+ bufEdit->numChanges=0;
+ bufEdit->editParams=NULL;
+
+ return bufEdit;
+}
+
+
+
+
+/* {{-output"bibDelete.txt"}} */
+/*
+*
+* bibDelete
+*
+*
+* Parameters:
+* buffer a pointer to a bit buffer structure
+* errorCode error code
+*
+* Function:
+* The bibDelete function frees the memory allocated for the buffer.
+*
+* Returns:
+* Nothing
+*
+* Error codes:
+* None
+*
+*/
+
+void bibDelete(bibBuffer_t *buffer, int16 * /*errorCode*/)
+/* {{-output"bibDelete.txt"}} */
+{
+ if (buffer) {
+ // note that the BaseAddr is just a reference to memory allocated elsewhere
+ // and there is no other dynamic allocations inside buffer
+ bibDealloc((void *) buffer);
+ }
+}
+
+
+
+void bibBufEditDelete(bibBufferEdit_t *bufEdit, int16 * /*errorCode*/)
+{
+ int i;
+ if (bufEdit) {
+ for(i=0; i<bufEdit->numChanges; i++)
+ bibDealloc((void *) bufEdit->editParams);
+ bibDealloc((void *) bufEdit);
+ }
+}
+
+
+/*
+*
+* bibFlushBits
+* bibGetBits
+* bibShowBits
+*
+*
+* Parameters:
+* numberOfBits the number of bits wanted (1..32)
+* buffer a pointer to a bit buffer structure
+* numberOfBitsGot the number of bits actually got
+* syncStartIndex the number of the first bit belonging to
+* a synchronization code (1 .. numberOfBits).
+* Bits are numbered starting from 1 given to
+* the most significant bit of the returned code.
+* Thus, syncStartIndex - 1 most significant bits
+* of the returned code are valid coding
+* parameters (do not belong to a sync code).
+* 0 is returned if the returned code does not
+* contain any part of a synchronization code.
+* bitErrorIndication indication code for bit errors,
+* see biterr.h for the possible values
+* errorCode error code
+*
+* Function:
+* The bibFlushBits function removes the next numberOfBits bits from
+* the buffer.
+*
+* The bibGetBits function gets the next numberOfBits bits from the buffer.
+* The returned bits are removed.
+*
+* The bibShowBits function gets the next numberOfBits bits from the
+* buffer. The returned bits are not removed from the buffer.
+*
+* Returns:
+* bibGetBits and bibShowBits:
+* the next numberOfBits bits / the rest of the buffer if the end of
+* the input file has been reached
+*
+* Error codes:
+* ERR_BIB_NOT_ENOUGH_DATA if one tries to get more bits from the buffer
+* than there is left
+*
+*/
+
+void bibFlushBits(int numberOfBits, bibBuffer_t *buffer)
+{
+ bibAssert(buffer != NULL);
+ bibAssert(numberOfBits > 0 && numberOfBits <= 32);
+
+ /* Check if enough bits are available. */
+ if (buffer->bitsLeft < (u_int32) numberOfBits) {
+ goto flush_underflow;
+ }
+ buffer->bitsLeft -= numberOfBits;
+
+ if ( buffer->bitIndex >= numberOfBits ) {
+ /* All in the current byte, bits still left */
+ buffer->bitIndex -= numberOfBits;
+ }
+ else if ( buffer->bitIndex == (numberOfBits-1) ) {
+ /* Current byte used completely */
+ buffer->bitIndex = 7;
+ buffer->getIndex++;
+ buffer->numBytesRead++;
+ }
+ else {
+ /* Current byte plus then some */
+ numberOfBits -= buffer->bitIndex + 1; /* this many bits after current byte */
+ buffer->getIndex += ((numberOfBits>>3) + 1);
+ buffer->numBytesRead += ((numberOfBits>>3) + 1);
+ buffer->bitIndex = 7 - (numberOfBits&7);
+ }
+ return;
+flush_underflow:
+ buffer->error = ERR_BIB_NOT_ENOUGH_DATA;
+}
+
+
+
+/*
+*
+* bibGetAlignedByte
+*
+*
+* A fast function to get one byte from byte-boundary.
+*
+*/
+inline u_int8 bibGetAlignedByte(bibBuffer_t *buffer)
+ {
+ return buffer->baseAddr[buffer->getIndex++];
+ }
+
+
+/*
+*
+* bibGetBits
+*
+*
+* See bibFlushBits.
+*
+*/
+
+u_int32 bibGetBits(int numberOfBits, bibBuffer_t *buffer)
+{
+ static const u_char
+ msbMask[8] = {1, 3, 7, 15, 31, 63, 127, 255},
+ lsbMask[9] = {255, 254, 252, 248, 240, 224, 192, 128, 0};
+ u_char
+ *startAddr;
+ int32
+ bitIndex;
+ u_int32
+ endShift; /* the number of shifts after masking the last byte */
+ u_int32
+ numBytesFlushed; /* the number of bytes flushed from the buffer */
+ u_int32
+ returnValue = 0;
+
+ bibAssert(buffer != NULL);
+ bibAssert(numberOfBits > 0 && numberOfBits <= 32);
+
+ startAddr = buffer->baseAddr + buffer->getIndex;
+ bitIndex = buffer->bitIndex;
+
+ /* Check if enough bits are available. */
+ if (buffer->bitsLeft < (u_int32) numberOfBits) {
+ goto get_underflow;
+ }
+
+ buffer->bitsLeft -= numberOfBits;
+
+ if ( bitIndex >= numberOfBits ) {
+ /* All in the current byte, bits still left */
+ endShift = bitIndex - numberOfBits + 1;
+ buffer->bitIndex -= numberOfBits;
+ return ((startAddr[0] & msbMask[bitIndex] & lsbMask[endShift]) >> endShift);
+ }
+ else if ( bitIndex == (numberOfBits-1) ) {
+ /* Current byte used completely */
+ buffer->bitIndex = 7;
+ buffer->getIndex++;
+ buffer->numBytesRead++;
+ return startAddr[0] & msbMask[bitIndex];
+ }
+ else {
+ /* Current byte plus then some */
+
+ /* Remainder of this byte */
+ returnValue = *(startAddr++) & msbMask[bitIndex];
+ numberOfBits -= bitIndex + 1;
+ numBytesFlushed = 1 + (numberOfBits >> 3);
+
+ /* Get full bytes */
+ while ( numberOfBits >= 8 ) {
+ returnValue = (returnValue << 8) | *(startAddr++);
+ numberOfBits -= 8;
+ }
+
+ /* Get bits from last byte */
+ endShift = 8 - numberOfBits;
+ returnValue = (returnValue << numberOfBits) | ((startAddr[0] & lsbMask[endShift]) >> endShift);
+ /* (safe, since lsbMask[8]==0) */
+
+ /* Update position in buffer */
+ buffer->bitIndex = 7 - numberOfBits;
+ buffer->getIndex += numBytesFlushed;
+ buffer->numBytesRead += numBytesFlushed;
+ }
+
+ return returnValue;
+get_underflow:
+ buffer->error = ERR_BIB_NOT_ENOUGH_DATA;
+ return 0;
+}
+
+
+/* {{-output"bibNumberOfFlushedBits.txt"}} */
+/*
+*
+* bibNumberOfFlushedBits
+*
+*
+* Parameters:
+* buffer a pointer to a bit buffer structure
+*
+* Function:
+* The bibNumberOfFlushedBytes returns the number of bits which
+* are got (bibGetBits) or flushed (bibFlushBits) from the buffer since
+* the buffer was created
+*
+* Returns:
+* See above.
+*
+* Error codes:
+* None.
+*
+*/
+
+u_int32 bibNumberOfFlushedBits(bibBuffer_t *buffer)
+/* {{-output"bibNumberOfFlushedBits.txt"}} */
+{
+ bibAssert(buffer != NULL);
+
+ return ((buffer->numBytesRead<<3) + (7-buffer->bitIndex));
+}
+
+
+/* {{-output"bibNumberOfFlushedBytes.txt"}} */
+/*
+*
+* bibNumberOfFlushedBytes
+*
+*
+* Parameters:
+* buffer a pointer to a bit buffer structure
+*
+* Function:
+* The bibNumberOfFlushedBytes returns the number of whole bytes which
+* are got (bibGetBits) or flushed (bibFlushBits) from the buffer since
+* bibCreate was called.
+*
+* Returns:
+* See above.
+*
+* Error codes:
+* None.
+*
+*/
+
+u_int32 bibNumberOfFlushedBytes(bibBuffer_t *buffer)
+/* {{-output"bibNumberOfFlushedBytes.txt"}} */
+{
+ bibAssert(buffer != NULL);
+
+ return buffer->numBytesRead;
+}
+
+
+/* {{-output"bibNumberOfRewBits.txt"}} */
+/*
+*
+* bibNumberOfRewBits
+*
+*
+* Parameters:
+* buffer a pointer to a bit buffer structure
+*
+* Function:
+* The bibNumberOfRewBits returns the number of bits which can be
+* successfully rewinded.
+*
+* Returns:
+* See above.
+*
+* Error codes:
+* None.
+*
+*/
+
+u_int32 bibNumberOfRewBits(bibBuffer_t *buffer)
+/* {{-output"bibNumberOfRewBits.txt"}} */
+{
+ bibAssert(buffer != NULL);
+
+ return ((buffer->numBytesRead<<3) + (7-buffer->bitIndex));
+}
+
+
+/* {{-output"bibRewindBits.txt"}} */
+/*
+*
+* bibRewindBits
+*
+*
+* Parameters:
+* numberOfBits the number of bits to rewind
+* buffer a pointer to a bit buffer structure
+* errorCode error code
+*
+* Function:
+* This function rewinds the pointers to the buffer
+* so that already flushed or got bits can be read
+* again.
+*
+* Returns:
+* Nothing.
+*
+* Error codes:
+* ERR_BIB_CANNOT_REWIND if numberOfBits is larger than which is
+* possible to get (see also bibNumberOfRewBits).
+*
+* ERR_BIB_BUFLIST if there was a fatal error when handling
+* buffer lists
+*
+*/
+
+void bibRewindBits(u_int32 numberOfBits, bibBuffer_t *buffer, int16 *errorCode)
+/* {{-output"bibRewindBits.txt"}} */
+{
+ bibAssert(buffer != NULL);
+
+ /* All bits to rewind are in the latest byte */
+ if (numberOfBits <= (u_int32) (7 - buffer->bitIndex)) {
+ buffer->bitIndex += numberOfBits;
+ }
+ /* Bits to rewind are within several bytes */
+ else {
+ u_int32
+ numBitsWithoutFirstByte = numberOfBits - (7 - buffer->bitIndex),
+ numWholeBytes = (numBitsWithoutFirstByte>>3),
+ numBitsInLastByte = numBitsWithoutFirstByte - (numWholeBytes<<3);
+
+ if (numBitsInLastByte) {
+ if (buffer->getIndex >= numWholeBytes + 1) {
+ buffer->getIndex -= numWholeBytes + 1;
+ buffer->bitIndex = numBitsInLastByte - 1;
+ buffer->numBytesRead -= numWholeBytes + 1;
+ }
+ else {
+ *errorCode = ERR_BIB_CANNOT_REWIND;
+ deb("bibRewindBits: ERROR - cannot rewind.\n");
+ }
+ }
+ else {
+ if (buffer->getIndex >= numWholeBytes) {
+ buffer->getIndex -= numWholeBytes;
+ buffer->bitIndex = 7;
+ buffer->numBytesRead -= numWholeBytes;
+ }
+ else {
+ *errorCode = ERR_BIB_CANNOT_REWIND;
+ deb("bibRewindBits: ERROR - cannot rewind.\n");
+ }
+ }
+ }
+ buffer->bitsLeft += numberOfBits;
+}
+
+
+/* {{-output"bibShowBits.txt"}} */
+/*
+*
+* bibShowBits
+*
+*
+* See bibFlushBits.
+*
+*/
+
+u_int32 bibShowBits(int numberOfBits, bibBuffer_t *buffer)
+/* {{-output"bibShowBits.txt"}} */
+{
+ static const u_char
+ msbMask[8] = {1, 3, 7, 15, 31, 63, 127, 255},
+ lsbMask[9] = {255, 254, 252, 248, 240, 224, 192, 128, 0};
+ u_char
+ *startAddr;
+ int32
+ bitIndex;
+ u_int32
+ endShift; /* the number of shifts after masking the last byte */
+ u_int32
+ returnValue = 0;
+
+ bibAssert(buffer != NULL);
+ bibAssert(numberOfBits > 0 && numberOfBits <= 32);
+
+ startAddr = buffer->baseAddr + buffer->getIndex;
+ bitIndex = buffer->bitIndex;
+
+ /* Check if enough bits are available. */
+ if (buffer->bitsLeft < (u_int32) numberOfBits) {
+ goto show_underflow;
+ }
+
+ if ( bitIndex >= numberOfBits ) {
+ /* All in the current byte, bits still left */
+ endShift = bitIndex - numberOfBits + 1;
+ return ((startAddr[0] & msbMask[bitIndex] & lsbMask[endShift]) >> endShift);
+ }
+ else if ( bitIndex == (numberOfBits-1) ) {
+ /* Current byte used completely */
+ return startAddr[0] & msbMask[bitIndex];
+ }
+ else {
+ /* Current byte plus then some */
+
+ /* Remainder of this byte */
+ returnValue = *(startAddr++) & msbMask[bitIndex];
+ numberOfBits -= bitIndex + 1;
+
+ /* Get full bytes */
+ while ( numberOfBits >= 8 )
+ {
+ returnValue = (returnValue << 8) | *(startAddr++);
+ numberOfBits -= 8;
+ }
+
+ /* Get bits from last byte */
+ endShift = 8 - numberOfBits;
+ returnValue = (returnValue << numberOfBits) | ((startAddr[0] & lsbMask[endShift]) >> endShift);
+ /* (safe, since lsbMask[8]==0) */
+ }
+
+ return returnValue;
+show_underflow:
+ buffer->error = ERR_BIB_NOT_ENOUGH_DATA;
+ return 0;
+}
+
+
+/*
+* Local functions
+*/
+
+/*
+*
+* bibInitialize
+*
+*
+* Parameters:
+* bibBuffer input bit buffer instance
+* srcBuffer buffer containing the data
+* srcBufferLength the length of the buffer
+* errorCode error code
+*
+* Function:
+* This function initializes the values of the bibBuffer structure.
+*
+* Returns:
+* Nothing.
+*
+* Error codes:
+* ERR_BIB_BUFLIST if the internal buffer list has been corrupted
+*
+*/
+
+static void bibInitialize(
+ bibBuffer_t *bibBuffer,
+ void *srcBuffer,
+ unsigned srcBufferLength,
+ int16 */*errorCode*/)
+{
+ bibBuffer->baseAddr = (u_char *) srcBuffer;
+ bibBuffer->size = srcBufferLength;
+ bibBuffer->getIndex = 0;
+ bibBuffer->bitIndex = 7;
+ bibBuffer->bitsLeft = (u_int32) (srcBufferLength<<3);
+ bibBuffer->numBytesRead = 0;
+ bibBuffer->error = 0;
+
+
+}
+
+
+
+/*
+*
+* CopyStream
+*
+*
+* Function to copy stream from SrcBuffer to DestBuffer based on settings in bufEdit and ByteStart & BitStart
+*
+*
+*/
+
+void CopyStream(bibBuffer_t *SrcBuffer,bibBuffer_t *DestBuffer,bibBufferEdit_t *bufEdit,
+ int ByteStart, int BitStart)
+{
+ int32 temp;
+ unsigned tgetIndex;
+ int tbitIndex;
+ u_int32 tbitsLeft;
+ u_int32 tnumBytesRead;
+ int tByteStart;
+ int tBitStart;
+
+ bibEditParams_t *edParam;
+
+ //Add assertions and checks here !!
+ bibAssert(SrcBuffer->baseAddr);
+ bibAssert(DestBuffer->baseAddr);
+ bibAssert(bufEdit);
+
+ //Save the params of SrcBuffer to recover them later:
+ tgetIndex=SrcBuffer->getIndex;
+ tbitIndex=SrcBuffer->bitIndex;
+ tbitsLeft=SrcBuffer->bitsLeft;
+ tnumBytesRead=SrcBuffer->numBytesRead;
+
+
+
+ // check to see if we need to change some header parameter
+ if(bufEdit->copyMode == CopyWithEdit/*CopyWithEdit*/)
+ {
+ bibAssert(bufEdit->editParams);
+ edParam = &(bufEdit->editParams[0]);
+
+ // check if the editing position is in the current range of bit data
+ temp=((SrcBuffer->getIndex<<3) + (7-SrcBuffer->bitIndex))-
+ ((edParam->StartByteIndex<<3) + 7-(edParam->StartBitIndex));
+ if (temp>=0) // yes, it is
+ {
+ // copy upto the editing point
+ CopyBuffer(SrcBuffer, DestBuffer, ByteStart, BitStart, edParam->StartByteIndex,
+ edParam->StartBitIndex);
+
+ CopyBufferEdit(SrcBuffer, DestBuffer, &(bufEdit->editParams[0]));
+
+ // store new starting copy position
+ tByteStart = SrcBuffer->getIndex;
+ tBitStart = SrcBuffer->bitIndex;
+ // restore original stop copy position
+ SrcBuffer->getIndex=tgetIndex;
+ SrcBuffer->bitIndex=tbitIndex;
+ SrcBuffer->bitsLeft=tbitsLeft;
+ SrcBuffer->numBytesRead=tnumBytesRead;
+
+ CopyBuffer(SrcBuffer, DestBuffer, tByteStart, tBitStart, tgetIndex, tbitIndex);
+
+ }
+ else // no
+ {
+ // put panic here !
+ return;
+ }
+ }
+ else if (bufEdit->copyMode == CopyWhole/*CopyWhole*/)
+ {
+ CopyBuffer(SrcBuffer, DestBuffer, ByteStart, BitStart,
+ SrcBuffer->getIndex, SrcBuffer->bitIndex);
+ }
+ else if (bufEdit->copyMode == EditOnly /*EditOnly*/)
+ {
+ CopyBufferEdit(SrcBuffer, DestBuffer, &(bufEdit->editParams[0]));
+ }
+ else if(bufEdit->copyMode == CopyNone/*CopyNone*/)
+ {
+ return;
+ }
+
+
+ //4- Retrieve the original Srcbuffer params.
+ // Using getbits it should be equal to where we started
+ SrcBuffer->getIndex=tgetIndex;
+ SrcBuffer->bitIndex=tbitIndex;
+ SrcBuffer->bitsLeft=tbitsLeft;
+ SrcBuffer->numBytesRead=tnumBytesRead;
+
+ //5- Update the destbuffer statistics:
+ DestBuffer->getIndex=DestBuffer->numBytesRead;
+
+ DestBuffer->bitsLeft -= (DestBuffer->getIndex<<3);
+
+}
+
+/*
+*
+* CopyBuffer
+*
+*
+* Function to copy data from SrcBuffer to DestBuffer from ByteStart & BitStart to ByteEnd & BitEnd
+*
+*
+*/
+
+void CopyBuffer(bibBuffer_t *SrcBuffer,bibBuffer_t *DestBuffer,
+ int ByteStart,int BitStart, int ByteEnd, int BitEnd)
+{
+ u_char *DestStartAddr;
+ u_int32 i;
+ u_int32 temp;
+ u_int32 BitsToRewind;
+ u_int32 BitsToCopy;
+ u_int32 BytesToCopy;
+ u_int32 Bytes4ToCopy;
+ u_int32 BitsRemaining;
+ int16 errorCode;
+ u_int32 bitshift;
+ u_int32 bitstoget;
+ static const u_char msbMask[8] = {1, 3, 7, 15, 31, 63, 127, 255};
+
+ DestStartAddr = DestBuffer->baseAddr + DestBuffer->getIndex;
+
+ //Rewind the src buffer to the start address(ByteStart,BitStart)
+ BitsToRewind=((SrcBuffer->getIndex<<3) + (7-SrcBuffer->bitIndex))-
+ ((ByteStart<<3) + (7-BitStart));
+ bibRewindBits(BitsToRewind,SrcBuffer, &errorCode);
+
+ // evaluate the number of bits to copy
+ BitsToCopy = ((ByteEnd<<3) + (7-BitEnd))-((ByteStart<<3) + (7-BitStart));
+ if (BitsToCopy<=0)
+ return;
+ else if (BitsToCopy > BitsToRewind)
+ BitsToCopy = BitsToRewind; // or else provide a panic here !!!
+
+ //1- Fill the remaining of the byte in destination:
+ bitshift=0;
+ bitstoget=0;
+ if(DestBuffer->bitIndex!=7)
+ {
+ bitshift = DestBuffer->bitIndex+1;
+ bitstoget = ((BitsToCopy < bitshift) ? BitsToCopy : bitshift);
+ temp = bibGetBits(bitstoget,SrcBuffer);
+
+ // update statistics to take care of bit addition or byte completion
+ if (BitsToCopy < bitshift)
+ {
+ // bits added but byte not completed
+ *(DestStartAddr)=(unsigned char)((((*DestStartAddr)>>bitshift)<<bitshift) |
+ ((temp << (bitshift-BitsToCopy) ) & msbMask[bitshift-1]));
+ DestBuffer->bitIndex -= BitsToCopy;
+ bibAssert(DestBuffer->bitIndex >= 0)
+ }
+ else
+ {
+ // byte completed
+ *(DestStartAddr)=(unsigned char)((((*DestStartAddr)>>bitshift)<<(bitshift)) |
+ (temp & msbMask[bitshift-1]));
+ DestStartAddr+=1;
+ DestBuffer->numBytesRead++;
+ DestBuffer->bitIndex=7;
+ }
+ }
+
+ //2- Extract all bytes (in 8 bits) from src to destination.
+ //Checks for BytesToCopy.
+ BytesToCopy=(BitsToCopy-bitstoget)>>3;
+ if ( BytesToCopy > 0 )
+ {
+
+ if ( SrcBuffer->bitIndex == 7 )
+ {
+ // we can copy the data from src in full bytes, utilize faster inline method
+ // and try to utilize pipelining in the for-loop
+ // truncate it to 4-byte-boundary
+ Bytes4ToCopy = BytesToCopy>>2;
+ for(i=0; i<Bytes4ToCopy; i++)
+ {
+ *(DestStartAddr++) = bibGetAlignedByte(SrcBuffer);
+ *(DestStartAddr++) = bibGetAlignedByte(SrcBuffer);
+ *(DestStartAddr++) = bibGetAlignedByte(SrcBuffer);
+ *(DestStartAddr++) = bibGetAlignedByte(SrcBuffer);
+ }
+ i <<= 2;
+ if ( BytesToCopy > i )
+ {
+ // copy the leftovers
+ for(;i<BytesToCopy;i++)
+ {
+ *(DestStartAddr++) = bibGetAlignedByte(SrcBuffer);
+ }
+ }
+ SrcBuffer->numBytesRead+=i;
+ }
+ else
+ {
+ for(i=0;i<BytesToCopy;i++)
+ {
+ *(DestStartAddr++) = (unsigned char)bibGetBits(8,SrcBuffer);
+ }
+
+ }
+ }
+ DestBuffer->numBytesRead+=BytesToCopy;
+
+ //3- Fill the last byte:
+ BitsRemaining=((BitsToCopy-bitstoget))%8;
+ if(BitsRemaining!=0)
+ {
+ temp = bibGetBits(BitsRemaining,SrcBuffer);
+ *(DestStartAddr++)=(u_char)(temp<<(8-BitsRemaining));
+ DestBuffer->bitIndex=7-BitsRemaining;
+ }
+
+ //5- Update the destbuffer statistics:
+ DestBuffer->getIndex=DestBuffer->numBytesRead;
+}
+
+/*
+*
+* CopyBufferEdit
+*
+*
+* Function to copy data with editing from SrcBuffer to DestBuffer with settings in edParam
+*
+*
+*/
+
+void CopyBufferEdit(bibBuffer_t *SrcBuffer, bibBuffer_t *DestBuffer,
+ bibEditParams_t *edParam, int updateSrcBufferStats)
+{
+ u_char *DestStartAddr;
+ u_int32 i;
+ u_int32 temp;
+ u_int32 BitsToSkip;
+ u_int32 BitsToEdit;
+ u_int32 BytesToSkip;
+ u_int32 BitsRemaining;
+ u_int32 BytesToEdit;
+ unsigned bitshift;
+ unsigned bitstoget;
+ unsigned bitstomove;
+ u_int32 StartBitPosition;
+ static const u_char msbMask[8] = {1, 3, 7, 15, 31, 63, 127, 255};
+
+ DestStartAddr = DestBuffer->baseAddr + DestBuffer->getIndex;
+
+ // evaluate the number of bits to copy
+ BitsToEdit = edParam->newNumBits;
+ StartBitPosition = edParam->newNumBits-1;
+
+ //1- Fill the remaining of the byte in destination:
+ bitshift=0;
+ bitstoget=0;
+ if(DestBuffer->bitIndex!=7)
+ {
+ bitshift=DestBuffer->bitIndex+1;
+ bitstoget = ((BitsToEdit < bitshift) ? BitsToEdit : bitshift);
+
+ temp = bibGetBitsFromWord(edParam->newValue, bitstoget, &StartBitPosition,
+ edParam->newNumBits);
+
+ // update statistics to take care of bit addition or byte completion
+ if (BitsToEdit < bitshift)
+ {
+ // bits added but byte not completed
+ *(DestStartAddr)=(unsigned char)((((*DestStartAddr)>>bitshift)<<(bitshift)) |
+ ((temp << (bitshift-BitsToEdit) ) & msbMask[bitshift-1]));
+ DestBuffer->bitIndex -= BitsToEdit;
+ bibAssert(DestBuffer->bitIndex >= 0)
+ }
+ else
+ {
+ // byte completed
+ *(DestStartAddr)=(unsigned char)((((*DestStartAddr)>>bitshift)<<(bitshift)) |
+ (temp & msbMask[bitshift-1]));
+ DestStartAddr++;
+ DestBuffer->numBytesRead++;
+ DestBuffer->bitIndex=7;
+ }
+ }
+
+
+ //2- Extract all bytes (in 8 bits) from src to destination.
+ //Checks for BytesToCopy
+ BytesToEdit=(BitsToEdit-bitstoget)>>3;
+ for(i=0;i<BytesToEdit;i++)
+ {
+ *(DestStartAddr++)=(unsigned char)bibGetBitsFromWord(edParam->newValue, 8, &StartBitPosition, edParam->newNumBits);
+ }
+ DestBuffer->numBytesRead+=BytesToEdit;
+
+ //3- Fill the last byte:
+ BitsRemaining=((BitsToEdit-bitstoget))%8;
+ if(BitsRemaining!=0)
+ {
+ temp = bibGetBitsFromWord(edParam->newValue, BitsRemaining, &StartBitPosition,
+ edParam->newNumBits);
+ *(DestStartAddr++)=(u_char)(temp<<(8-BitsRemaining));
+ DestBuffer->bitIndex=7-BitsRemaining;
+ }
+
+ //5- Update the destbuffer statistics:
+ DestBuffer->getIndex=DestBuffer->numBytesRead;
+
+
+ // update the src buffer statistics to reflect skipping of the value
+ if(updateSrcBufferStats)
+ {
+ BitsToSkip = edParam->curNumBits;
+ bitshift=0;
+ bitstomove=0;
+ if (SrcBuffer->bitIndex!=7)
+ {
+ bitshift=SrcBuffer->bitIndex+1;
+ bitstomove = ((BitsToSkip < bitshift) ? BitsToSkip : bitshift);
+ // update statistics to take care of bit addition or byte completion
+ if (BitsToSkip < bitshift)
+ {
+ // bits skipped but byte not completed
+ SrcBuffer->bitIndex -= bitstomove;
+ bibAssert(SrcBuffer->bitIndex >= 0)
+ }
+ else
+ {
+ // byte completed
+ SrcBuffer->numBytesRead++;
+ SrcBuffer->bitIndex=7;
+ }
+ }
+ // full bytes to skip
+ BytesToSkip=(BitsToSkip-bitstomove)>>3;
+ SrcBuffer->numBytesRead+=BytesToSkip;
+
+ // skip the remaining bits
+ BitsRemaining=((BitsToSkip-bitstomove))%8;
+ if(BitsRemaining!=0)
+ {
+ SrcBuffer->bitIndex=7-BitsRemaining;
+ }
+ SrcBuffer->bitsLeft -= BitsToSkip;
+ SrcBuffer->getIndex=SrcBuffer->numBytesRead;
+ }
+}
+
+void ResetH263IntraDcUV(bibBuffer_t *DestBuffer, int uValue, int vValue)
+{
+ bibEditParams_t edParam;
+
+ edParam.curNumBits = edParam.newNumBits = 8;
+ edParam.StartByteIndex = edParam.StartBitIndex = 0; // used for source buffer only
+
+ // u
+ edParam.newValue = uValue;
+ CopyBufferEdit((bibBuffer_t*)NULL, DestBuffer, &edParam, 0);
+ // v
+ edParam.newValue = vValue;
+ CopyBufferEdit((bibBuffer_t*)NULL, DestBuffer, &edParam, 0);
+}
+
+void ResetMPEG4IntraDcUV(bibBuffer_t *DestBuffer, int IntraDC_size)
+{
+ int i;
+ bibEditParams_t edParam;
+ const int DctDcSizeChrominanceNumBits[13] = { 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
+
+ // u,v
+ for(i=0; i<2; i++)
+ {
+ // change dct dc size chrominance - IntraDC for U.V is 0 (codeword '11')
+ edParam.curNumBits = DctDcSizeChrominanceNumBits[IntraDC_size];
+ edParam.newNumBits = 2;
+ edParam.StartByteIndex = edParam.StartBitIndex = 0; // used or source buffer only
+ edParam.newValue = 3;
+ CopyBufferEdit((bibBuffer_t*)NULL, DestBuffer, &edParam, 0);
+ }
+}
+
+// assume SrcValue is max 32 bits
+u_int32 bibGetBitsFromWord(u_int32 SrcValue, u_int32 getBits, u_int32 *StartBit,
+ u_int32 MaxNumBits)
+{
+ int val;
+ u_int32 bitshift;
+ static const u_int32 mask[32] =
+ {0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
+ 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
+ 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
+ 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff};
+
+ bibAssert(MaxNumBits <= 32);
+ bibAssert(*StartBit < MaxNumBits);
+ bibAssert(getBits-1 <= *StartBit);
+ bibAssert(getBits > 0);
+
+ bitshift = *StartBit - getBits + 1;
+ val = (SrcValue>>bitshift) & mask[getBits-1];
+ if ( getBits > *StartBit )
+ {
+ // taking the last bits of the word; *StartBit is uint32, so it goes to max uint32 unless this special handling
+ // other cases asserted already above
+ *StartBit = 31;
+ }
+ else
+ {
+ *StartBit -= getBits;
+ }
+
+ return val;
+}
+
+void bibForwardBits(u_int32 numberOfBits, bibBuffer_t *buffer)
+{
+ u_int32 BitsToForward;
+ u_int32 BytesToForward;
+ u_int32 BitsRemaining;
+ unsigned bitshift;
+ unsigned bitstomove;
+
+ BitsToForward = numberOfBits;
+ bitshift=0;
+ bitstomove=0;
+
+ bibAssert(buffer != NULL);
+
+ // complete the byte
+ if (buffer->bitIndex!=7)
+ {
+ bitshift=buffer->bitIndex+1;
+ bitstomove = ((BitsToForward < bitshift) ? BitsToForward : bitshift);
+ // update statistics to take care of bit addition or byte completion
+ if (BitsToForward < bitshift)
+ {
+ // bits skipped but byte not completed
+ buffer->bitIndex -= bitstomove;
+ bibAssert(buffer->bitIndex >= 0)
+ }
+ else
+ {
+ // byte completed
+ buffer->numBytesRead++;
+ buffer->bitIndex=7;
+ }
+ }
+ // full bytes to skip
+ BytesToForward=(BitsToForward-bitstomove)>>3;
+ buffer->numBytesRead+=BytesToForward;
+
+ // skip the remaining bits
+ BitsRemaining=((BitsToForward-bitstomove))%8;
+ if(BitsRemaining!=0)
+ {
+ buffer->bitIndex=7-BitsRemaining;
+ }
+ buffer->bitsLeft -= BitsToForward;
+ buffer->getIndex=buffer->numBytesRead;
+}
+
+void bibStuffBits(bibBuffer_t *buffer)
+{
+ // the extra bits are already set to zero
+ bibAssert(buffer->baseAddr);
+ if(buffer->bitIndex!=7)
+ {
+ buffer->bitIndex=7;
+ buffer->getIndex++;
+ buffer->numBytesRead++;
+ }
+}
+
+
+
+
+// End of File