videoeditorengine/h263decoder/src/biblin.cpp
changeset 0 951a5db380a0
equal deleted inserted replaced
-1:000000000000 0:951a5db380a0
       
     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