⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unpack.c

📁 魔兽2Linux版
💻 C
字号:
//==========================================================================////  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR//  PURPOSE.////  Copyright (c) 1999 - 2001  On2 Technologies Inc. All Rights Reserved.////--------------------------------------------------------------------------/******************************************************************************   Module Title :     unpack.C**   Description  :     Video CODEC: Top level decode module.*******************************************************************************//*****************************************************************************  Header Files******************************************************************************/#define STRICT              /* Strict type checking. *///#include "BlockMapping.h"#include "pbdll.h"#include "codec_common_interface.h"#include <string.h>/*****************************************************************************  Module constants.******************************************************************************/        /*****************************************************************************  Exported Global Variables******************************************************************************//*****************************************************************************  Exported Functions******************************************************************************//*****************************************************************************  Module Statics******************************************************************************/              /*****************************************************************************  Imports******************************************************************************/  /**************************************************************************** *  *  ROUTINE       :     UnPackVideo * *  INPUTS        :     None.  *                       *  OUTPUTS       :     None. * *  RETURNS       :     None. * *  FUNCTION      :     Upacks and decodes the video stream. * *  SPECIAL NOTES :     None.  * * *  ERRORS        :     None. * ****************************************************************************/void UnPackVideo (PB_INSTANCE *pbi){    INT32       EncodedCoeffs = 1;    INT32       FragIndex;    INT32 *     CodedBlockListPtr;    INT32 *     CodedBlockListEnd;    UINT8       AcHuffIndex1;    UINT8       AcHuffIndex2;    UINT8       AcHuffChoice1;    UINT8       AcHuffChoice2;        UINT8       DcHuffChoice1;    UINT8       DcHuffChoice2;    // Bail out immediately if a decode error has already been reported.    if ( pbi->DecoderErrorCode != NO_DECODER_ERROR )        return;    // Clear down the array that indicates the current coefficient index for each block.    memset(pbi->FragCoeffs, 0, pbi->UnitFragments);    memset(pbi->FragCoefEOB, 0, pbi->UnitFragments);    // Clear down the pbi->QFragData structure for all coded blocks.    pbi->ClearDownQFrag(pbi);    // Note the number of blocks to decode    pbi->BlocksToDecode = pbi->CodedBlockIndex;    // Get the DC huffman table choice for Y and then UV    DcHuffChoice1 = (UINT8)bitread( &pbi->br,  DC_HUFF_CHOICE_BITS ) + DC_HUFF_OFFSET;    DcHuffChoice2 = (UINT8)bitread( &pbi->br,  DC_HUFF_CHOICE_BITS ) + DC_HUFF_OFFSET;    // UnPack DC coefficients / tokens    CodedBlockListPtr = pbi->CodedBlockList;    CodedBlockListEnd = &pbi->CodedBlockList[pbi->CodedBlockIndex];    while ( CodedBlockListPtr < CodedBlockListEnd  )    {        // Get the block data index        FragIndex = *CodedBlockListPtr;		pbi->FragCoefEOB[FragIndex] = pbi->FragCoeffs[FragIndex];        // Select the appropriate huffman table offset according to whether the token is fro am Y or UV block        if ( FragIndex < (INT32)pbi->YPlaneFragments )            pbi->DcHuffChoice = DcHuffChoice1;        else            pbi->DcHuffChoice = DcHuffChoice2;        // If we are in the middle of an EOB run        if ( pbi->EOB_Run )        {            // Mark the current block as fully expanded and decrement EOB_RUN count            pbi->FragCoeffs[FragIndex] = BLOCK_SIZE;            pbi->EOB_Run --;            pbi->BlocksToDecode --;        }        // Else unpack a DC token        else        {            UnpackAndExpandDcToken( pbi, pbi->QFragData[FragIndex], &pbi->FragCoeffs[FragIndex] );        }        CodedBlockListPtr++;    }    // Get the AC huffman table choice for Y and then for UV.    AcHuffIndex1 = (UINT8) bitread( &pbi->br,  AC_HUFF_CHOICE_BITS ) + AC_HUFF_OFFSET;    AcHuffIndex2 = (unsigned char) bitread( &pbi->br,  AC_HUFF_CHOICE_BITS ) + AC_HUFF_OFFSET;    // Unpack Lower AC coefficients.    while ( EncodedCoeffs < 64 )     {        // Repeatedly scan through the list of blocks.        CodedBlockListPtr = pbi->CodedBlockList;        CodedBlockListEnd = &pbi->CodedBlockList[pbi->CodedBlockIndex];        // Huffman table selection based upon which AC coefficient we are on        if ( EncodedCoeffs <= AC_TABLE_2_THRESH )        {            AcHuffChoice1 = AcHuffIndex1;            AcHuffChoice2 = AcHuffIndex2;        }        else if ( EncodedCoeffs <= AC_TABLE_3_THRESH )        {            AcHuffChoice1 = AcHuffIndex1 + AC_HUFF_CHOICES;            AcHuffChoice2 = AcHuffIndex2 + AC_HUFF_CHOICES;        }        else if ( EncodedCoeffs <= AC_TABLE_4_THRESH )        {            AcHuffChoice1 = AcHuffIndex1 + (AC_HUFF_CHOICES * 2);            AcHuffChoice2 = AcHuffIndex2 + (AC_HUFF_CHOICES * 2);        }        else        {            AcHuffChoice1 = AcHuffIndex1 + (AC_HUFF_CHOICES * 3);            AcHuffChoice2 = AcHuffIndex2 + (AC_HUFF_CHOICES * 3);        }        while( CodedBlockListPtr < CodedBlockListEnd )        {            // Get the linear index for the current fragment.            FragIndex = *CodedBlockListPtr;            // Should we decode a token for this block on this pass.            if ( pbi->FragCoeffs[FragIndex] <= EncodedCoeffs )            {				pbi->FragCoefEOB[FragIndex] = pbi->FragCoeffs[FragIndex];                // If we are in the middle of an EOB run                if ( pbi->EOB_Run )                {                    // Mark the current block as fully expanded and decrement EOB_RUN count                    pbi->FragCoeffs[FragIndex] = BLOCK_SIZE;                    pbi->EOB_Run --;                    pbi->BlocksToDecode --;                }                // Else unpack an AC token                else                {                    // Work out which huffman table to use, then decode a token                    if ( FragIndex < (INT32)pbi->YPlaneFragments )                        pbi->ACHuffChoice = AcHuffChoice1;                    else                        pbi->ACHuffChoice = AcHuffChoice2;                    UnpackAndExpandAcToken( pbi, pbi->QFragData[FragIndex], &pbi->FragCoeffs[FragIndex] );                }            }            CodedBlockListPtr++;        }        // Test for condition where there are no blocks left with any tokesn to decode        if ( !pbi->BlocksToDecode )            break;        EncodedCoeffs ++;    }}/**************************************************************************** *  *  ROUTINE       :     ExtractToken * *  INPUTS        :     INT8 * ExpandedBlock *                             Pointer to block structure into which the token *                             should be expanded. * *                      UINT32 * CoeffIndex *                             Where we are in the current block. * *  OUTPUTS       :      * *  RETURNS       :     The number of bits decoded * *  FUNCTION      :     Unpacks and expands an DC DCT token. * *  SPECIAL NOTES :     PROBLEM !!!!!!!!!!!   right now handles only left  *                      justified bits in bitreader.  the c version keeps every *                      thing in place so I can't use it!! *                       * * *  ERRORS        :     None. * ****************************************************************************/UINT32 ExtractToken(BITREADER *br, HUFF_ENTRY * CurrentRoot){	UINT32 Token;    // Loop searches down through tree based upon bits read from the bitstream     // until it hits a leaf at which point we have decoded a token	while ( CurrentRoot->Value < 0 )    {				if ( bitread1(br) )            CurrentRoot = (HUFF_ENTRY *)(CurrentRoot->OneChild);        else            CurrentRoot = (HUFF_ENTRY *)(CurrentRoot->ZeroChild);    }    Token = CurrentRoot->Value; 	return Token;}/**************************************************************************** *  *  ROUTINE       :     UnpackAndExpandDcToken * *  INPUTS        :     INT8 * ExpandedBlock *                             Pointer to block structure into which the token *                             should be expanded. * *                      UINT32 * CoeffIndex *                             Where we are in the current block. * *  OUTPUTS       :      * *  RETURNS       :     The number of bits decoded * *  FUNCTION      :     Unpacks and expands an DC DCT token. * *  SPECIAL NOTES :      * * *  ERRORS        :     None. * ****************************************************************************/void UnpackAndExpandDcToken( PB_INSTANCE *pbi, Q_LIST_ENTRY * ExpandedBlock, UINT8 * CoeffIndex ){    INT32           ExtraBits;    UINT32          Token;#ifdef DEBUG    ExtraBits = 0;#endif    // Extract a token.       Token = ExtractToken(&pbi->br, pbi->HuffRoot_VP3x[pbi->DcHuffChoice]);    /* Now.. if we are using the DCT optimised coding system, extract any    *  assosciated additional bits token.     */    if ( ExtraBitLengths_VP31[Token] > 0 )    {        /* Extract the appropriate number of extra bits. */        ExtraBits = bitread(&pbi->br, ExtraBitLengths_VP31[Token]);    }    // Take token dependant action    if ( Token >= DCT_SHORT_ZRL_TOKEN )    {        // "Value", "zero run" and "zero run value" tokens        ExpandToken(  pbi, ExpandedBlock, CoeffIndex, Token, ExtraBits );        if ( *CoeffIndex >= BLOCK_SIZE )            pbi->BlocksToDecode --;    }    else if ( Token == DCT_EOB_TOKEN )    {        *CoeffIndex = BLOCK_SIZE;        pbi->BlocksToDecode --;    }    else    {        // Special action and EOB tokens        switch ( Token )        {        case DCT_EOB_PAIR_TOKEN:            pbi->EOB_Run = 1;            *CoeffIndex = BLOCK_SIZE;            pbi->BlocksToDecode --;            break;        case DCT_EOB_TRIPLE_TOKEN:            pbi->EOB_Run = 2;            *CoeffIndex = BLOCK_SIZE;            pbi->BlocksToDecode --;            break;        case DCT_REPEAT_RUN_TOKEN:            pbi->EOB_Run = ExtraBits + 3;            *CoeffIndex = BLOCK_SIZE;            pbi->BlocksToDecode --;            break;        case DCT_REPEAT_RUN2_TOKEN:            pbi->EOB_Run = ExtraBits + 7;            *CoeffIndex = BLOCK_SIZE;            pbi->BlocksToDecode --;            break;        case DCT_REPEAT_RUN3_TOKEN:            pbi->EOB_Run = ExtraBits + 15;            *CoeffIndex = BLOCK_SIZE;            pbi->BlocksToDecode --;            break;        case DCT_REPEAT_RUN4_TOKEN:            pbi->EOB_Run = ExtraBits - 1;            *CoeffIndex = BLOCK_SIZE;            pbi->BlocksToDecode --;            break;        }    }}/**************************************************************************** *  *  ROUTINE       :     UnpackAndExpandAcToken * *  INPUTS        :     INT8 * ExpandedBlock *                             Pointer to block structure into which the token *                             should be expanded. * *                      UINT32 * CoeffIndex *                             Where we are in the current block. * *  OUTPUTS       :      * *  RETURNS       :     The number of bits decoded * *  FUNCTION      :     Unpacks and expands a AC DCT token. * *  SPECIAL NOTES :      * * *  ERRORS        :     None. * ****************************************************************************/void UnpackAndExpandAcToken( PB_INSTANCE *pbi, Q_LIST_ENTRY * ExpandedBlock, UINT8 * CoeffIndex  ){    INT32           ExtraBits;    UINT32          Token;#ifdef DEBUG    ExtraBits = 0;#endif    // Extract a token.       Token = ExtractToken(&pbi->br, pbi->HuffRoot_VP3x[pbi->ACHuffChoice]);    /* Now.. if we are using the DCT optimised coding system, extract any    *  assosciated additional bits token.     */    if ( ExtraBitLengths_VP31[Token] > 0 )    {        /* Extract the appropriate number of extra bits. */        ExtraBits = bitread(&pbi->br,ExtraBitLengths_VP31[Token]); //0;    }    // Take token dependant action    if ( Token >= DCT_SHORT_ZRL_TOKEN )    {        // "Value", "zero run" and "zero run value" tokens        ExpandToken(  pbi, ExpandedBlock, CoeffIndex, Token, ExtraBits );        if ( *CoeffIndex >= BLOCK_SIZE )            pbi->BlocksToDecode --;    }    else if ( Token == DCT_EOB_TOKEN )    {        *CoeffIndex = BLOCK_SIZE;        pbi->BlocksToDecode --;    }    else    {        // Special action and EOB tokens        switch ( Token )        {        case DCT_EOB_PAIR_TOKEN:            pbi->EOB_Run = 1;            *CoeffIndex = BLOCK_SIZE;            pbi->BlocksToDecode --;            break;        case DCT_EOB_TRIPLE_TOKEN:            pbi->EOB_Run = 2;            *CoeffIndex = BLOCK_SIZE;            pbi->BlocksToDecode --;            break;        case DCT_REPEAT_RUN_TOKEN:            pbi->EOB_Run = ExtraBits + 3;            *CoeffIndex = BLOCK_SIZE;            pbi->BlocksToDecode --;            break;        case DCT_REPEAT_RUN2_TOKEN:            pbi->EOB_Run = ExtraBits + 7;            *CoeffIndex = BLOCK_SIZE;            pbi->BlocksToDecode --;            break;        case DCT_REPEAT_RUN3_TOKEN:            pbi->EOB_Run = ExtraBits + 15;            *CoeffIndex = BLOCK_SIZE;            pbi->BlocksToDecode --;            break;        case DCT_REPEAT_RUN4_TOKEN:            pbi->EOB_Run = ExtraBits - 1;            *CoeffIndex = BLOCK_SIZE;            pbi->BlocksToDecode --;            break;        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -