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

📄 dct_decode.c

📁 魔兽2Linux版
💻 C
📖 第 1 页 / 共 5 页
字号:
						// calculate values						vl = pbi->QFragData[l][0];						// fragment valid for prediction if coded and it comes from same frame as the one we are predicting						fl = pbi->display_fragments[l] && (Mode2Frame[pbi->FragCodingMethod[l]] == WhichFrame);						// calculate which predictor to use 						wpc = (fl*PL) ;						break;					case 3: // n == 0 & m == 0 Top Row Left Column						wpc = 0;						break;					case 4: // n+1 == FragsAcross : Right Column					default: // Johns: to avoid uninitialized warnings						// calculate values left, up, up-right and up-left						l = i-1;						u = i - FragsAcross;						ul = i - FragsAcross - 1;						// calculate values						vl = pbi->QFragData[l][0];						vu = pbi->QFragData[u][0];						vul = pbi->QFragData[ul][0];												// fragment valid for prediction if coded and it comes from same frame as the one we are predicting						fl = pbi->display_fragments[l] && (Mode2Frame[pbi->FragCodingMethod[l]] == WhichFrame);						fu = pbi->display_fragments[u] && (Mode2Frame[pbi->FragCodingMethod[u]] == WhichFrame);						ful = pbi->display_fragments[ul] && (Mode2Frame[pbi->FragCodingMethod[ul]] == WhichFrame);						// calculate which predictor to use 						wpc = (fl*PL) | (fu*PU) | (ful*PUL) ;						break;					}															if(wpc==0)					{						FragIndex = 1;												// find the nearest one that is coded 						for( k = 0; k < DCSearchPointCount ; k++)						{							FragIndex = i + DCSearchPoints[k].RowOffset * FragsAcross + DCSearchPoints[k].ColOffset;														if( FragIndex - FromFragment > 0 ) 							{								if(pbi->display_fragments[FragIndex] && (Mode2Frame[pbi->FragCodingMethod[FragIndex]] == WhichFrame))								{									pbi->QFragData[i][0] += pbi->QFragData[FragIndex][0];									FragIndex = 0;									break;								}							}						}																		// if none matched fall back to the last one ever						if(FragIndex)						{							pbi->QFragData[i][0] += Last[WhichFrame];						}											}					else					{												// don't do divide if divisor is 1 or 0						PredictedDC = (pc[wpc][0]*vul + pc[wpc][1] * vu + pc[wpc][2] * vur + pc[wpc][3] * vl );						// if we need to do a shift						if(pc[wpc][4] != 0 )						{														// If negative add in the negative correction factor							PredictedDC += (HIGHBITDUPPED(PredictedDC) & pc[wpc][5]);														// Shift in lieu of a divide							PredictedDC >>= pc[wpc][4];						}						                        // check for outranging on the two predictors that can outrange                         switch(wpc)                        {                        case 13: // pul pu pl                        case 15: // pul pu pur pl                            if( abs(PredictedDC - vu) > 128)                                PredictedDC = vu;                            else if( abs(PredictedDC - vl) > 128)                                PredictedDC = vl;                            else if( abs(PredictedDC - vul) > 128)                                PredictedDC = vul;                            break;                        }						   						pbi->QFragData[i][0] += PredictedDC;											}										// Save the last fragment coded for whatever frame we are predicting from					Last[WhichFrame] = pbi->QFragData[i][0];					// Inverse DCT and reconstitute buffer in thisframe					ExpandBlockA( pbi, i );				} // if display fragments			} // for n = 0 to columns across		} // for m = 0 to rows down	} // for j = 0 to 2 (y,u,v)    // Copy the current reconstruction back to the last frame recon buffer.//printf("%d\n",pbi->CodedBlockIndex);	if(pbi->CodedBlockIndex > (INT32) (pbi->UnitFragments >> 1))	{		SwapReconBuffersTemp = pbi->ThisFrameRecon;		pbi->ThisFrameRecon = pbi->LastFrameRecon;		pbi->LastFrameRecon = SwapReconBuffersTemp;		CopyNotRecon( pbi, pbi->LastFrameRecon, pbi->ThisFrameRecon );	}	else    {		CopyRecon( pbi, pbi->LastFrameRecon, pbi->ThisFrameRecon );    }            // We may need to update the UMV border    //UpdateUMVBorder(pbi, pbi->LastFrameRecon );        // Apply a loop filter to edge pixels of updated blocks		if( pbi->Vp3VersionNo == 0 )		ApplyReconLoopFilter(pbi);    else        LoopFilter(pbi);	    // Reconstruct the golden frame if necessary.     // For VFW codec only on key frames    if ( GetFrameType(pbi) == BASE_FRAME )    {        CopyRecon( pbi, pbi->GoldenFrame, pbi->LastFrameRecon );    }    // If appropriate clear the MMX state.    pbi->ClearSysState();}/**************************************************************************** *  *  ROUTINE       :     ExpandKFBlock * *  INPUTS        :     INT32	FragIndex  *                       *  OUTPUTS       :     None * *  RETURNS       :     None. * *  FUNCTION      :     Reverses quantisation and dc and reconstructs pixel  *                      data for an "Intra" frame block. * *  SPECIAL NOTES :      * *  ERRORS        :     None. * ****************************************************************************/void ExpandKFBlock ( PB_INSTANCE *pbi, INT32 FragmentNumber ){    UINT32		ReconPixelsPerLine;	// Pixels per line    INT32       ReconPixelIndex;    // Offset for block into a reconstruction buffer	//INT32       i;    // Select the appropriate inverse Q matrix and line stride	if ( FragmentNumber<(INT32)pbi->YPlaneFragments )	{		ReconPixelsPerLine = pbi->Configuration.YStride;		select_Y_dequantiser(pbi);	}	else	{		ReconPixelsPerLine = pbi->Configuration.UVStride;		select_UV_dequantiser(pbi);    }        // Set up pointer into the quantisation buffer.    pbi->quantized_list = (Q_LIST_ENTRY *)(&pbi->QFragData[FragmentNumber][0]);    // Invert quantisation and DCT to get pixel data.                           pbi->idct[pbi->FragCoefEOB[FragmentNumber]]( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );    // Convert fragment number to a pixel offset in a reconstruction buffer.    ReconPixelIndex = ReconGetFragIndex ( pbi->recon_pixel_index_table, FragmentNumber );    // Get the pixel index for the first pixel in the fragment.    pbi->ReconIntra( pbi, (UINT8 *)(&pbi->ThisFrameRecon[ReconPixelIndex]), (UINT16 *)pbi->ReconDataBuffer, ReconPixelsPerLine );}/**************************************************************************** *  *  ROUTINE       :     ExpandBlock * *  INPUTS        :     INT32	FragIndex  *                       *  OUTPUTS       :     None * *  RETURNS       :     None. * *  FUNCTION      :     Reverses quantisation and dc and reconstructs pixel data. * *  SPECIAL NOTES :      * *  ERRORS        :     None. * ****************************************************************************/void ExpandBlock ( PB_INSTANCE *pbi, INT32 FragmentNumber ){    UINT8       *LastFrameRecPtr;   // Pointer into previous frame reconstruction.    UINT8       *LastFrameRecPtr2;  // Pointer into previous frame reconstruction for 1/2 pixel MC.	    UINT32		ReconPixelsPerLine;	// Pixels per line    INT32       ReconPixelIndex;    // Offset for block into a reconstruction buffer    INT32       ReconPtr2Offset;    // Offset for second reconstruction in half pixel MC    INT32       MVOffset;           // Baseline motion vector offset    INT32       MvShift  ;          // Shift to correct to 1/2 or 1/4 pixel    INT32       MvModMask;          // Mask to determine whether 1/2 pixel is used    // TEST    //INT32       mmask;    //INT32       ReconPtr2OffsetB;    // Offset for second reconstruction in half pixel MC    //INT32       MVOffsetB;	// Get coding mode for this block    if ( GetFrameType(pbi) == BASE_FRAME )	{		pbi->CodingMode = CODE_INTRA;	}	else	{	    // Get Motion vector and mode for this block.        pbi->CodingMode = pbi->FragCodingMethod[FragmentNumber];	}    // Select the appropriate inverse Q matrix and line stride	if ( FragmentNumber<(INT32)pbi->YPlaneFragments )	{		ReconPixelsPerLine = pbi->Configuration.YStride;        MvShift = 1;        MvModMask = 0x00000001;        //mmask = 1;		// Select appropriate dequantiser matrix.        if ( pbi->CodingMode == CODE_INTRA )		    select_Y_dequantiser(pbi);        else            select_Inter_dequantiser(pbi);	}	else	{		ReconPixelsPerLine = pbi->Configuration.UVStride;        MvShift = 2;        MvModMask = 0x00000003;        //mmask = 3;		// Select appropriate dequantiser matrix.        if ( pbi->CodingMode == CODE_INTRA )		    select_UV_dequantiser(pbi);        else            select_Inter_dequantiser(pbi);    }        // Set up pointer into the quantisation buffer.    pbi->quantized_list = (Q_LIST_ENTRY *)(&pbi->QFragData[FragmentNumber][0]);    // Invert quantisation and DCT to get pixel data.                           pbi->idct[pbi->FragCoefEOB[FragmentNumber]]( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );    // Convert fragment number to a pixel offset in a reconstruction buffer.    ReconPixelIndex = ReconGetFragIndex ( pbi->recon_pixel_index_table, FragmentNumber );    // Action depends on decode mode.	if ( pbi->CodingMode == CODE_INTER_NO_MV )       // Inter with no motion vector    {		// Reconstruct the pixel data using the last frame reconstruction and change data        // when the motion vector is (0,0), the recon is based on the lastframe without        // loop filtering---- for testing        pbi->ReconInter( pbi, (UINT8 *)&pbi->ThisFrameRecon[ReconPixelIndex],             (UINT8 *)&pbi->LastFrameRecon[ReconPixelIndex],             pbi->ReconDataBuffer, ReconPixelsPerLine );                }	else if ( ModeUsesMC[pbi->CodingMode] )          // The mode uses a motion vector.	{        {            // Get vector from list            pbi->MVector.x = pbi->FragMVect[FragmentNumber].x;            pbi->MVector.y = pbi->FragMVect[FragmentNumber].y;                        // Work out the base motion vector offset and the 1/2 pixel offset if any.            // For the U and V planes the MV specifies 1/4 pixel accuracy. This is adjusted to            // 1/2 pixel as follows ( 0->0, 1/4->1/2, 1/2->1/2, 3/4->1/2 ).            MVOffset = 0;            ReconPtr2Offset = 0;            if ( pbi->MVector.x > 0 )            {                MVOffset = pbi->MVector.x >> MvShift;                if ( pbi->MVector.x & MvModMask )                    ReconPtr2Offset += 1;            }            else if ( pbi->MVector.x < 0 )            {                MVOffset -= (-pbi->MVector.x) >> MvShift;                if ( (-pbi->MVector.x) & MvModMask )                    ReconPtr2Offset -= 1;            }            if ( pbi->MVector.y > 0 )            {                MVOffset += (pbi->MVector.y >>  MvShift) * ReconPixelsPerLine;                if ( pbi->MVector.y & MvModMask )                    ReconPtr2Offset += ReconPixelsPerLine;            }            else if ( pbi->MVector.y < 0 )            {                MVOffset -= ((-pbi->MVector.y) >> MvShift) * ReconPixelsPerLine;                if ( (-pbi->MVector.y) & MvModMask )                    ReconPtr2Offset -= ReconPixelsPerLine;            }                        // Set up the first of the two reconstruction buffer pointers.            if ( pbi->CodingMode==CODE_GOLDEN_MV )             {                LastFrameRecPtr = (UINT8 * )( &pbi->GoldenFrame[ReconPixelIndex] + MVOffset);            }            else            {                LastFrameRecPtr = (UINT8 * )( &pbi->LastFrameRecon[ReconPixelIndex] + MVOffset);            }                        // Set up the second of the two reconstruction pointers.            LastFrameRecPtr2 = LastFrameRecPtr + ReconPtr2Offset;                        // Select the appropriate reconstruction function            if ( (int)(LastFrameRecPtr - LastFrameRecPtr2) == 0 )             {                // Reconstruct the pixel dats from the reference frame and change data                // (no half pixel in this case as the two references were the same.                pbi->ReconInter( pbi, (UINT8 *)&pbi->ThisFrameRecon[ReconPixelIndex],                     LastFrameRecPtr, pbi->ReconDataBuffer, ReconPixelsPerLine );            }            // Fractional pixel reconstruction.            // Note that we only use two pixels per reconstruction even for the diagonal.            else             {                pbi->ReconInterHalfPixel2( pbi, (UINT8 *)&pbi->ThisFrameRecon[ReconPixelIndex],                     LastFrameRecPtr, LastFrameRecPtr2, pbi->ReconDataBuffer, ReconPixelsPerLine );            }        }    }	else if ( pbi->CodingMode == CODE_USING_GOLDEN )     // Golden frame with motion vector    {		// Reconstruct the pixel data using the golden frame reconstruction and change data        pbi->ReconInter( pbi, (UINT8 *)&pbi->ThisFrameRecon[ReconPixelIndex],                     (UINT8 *)&pbi->GoldenFrame[ ReconPixelIndex ],                     pbi->ReconDataBuffer, ReconPixelsPerLine );    }	else                                            // Simple Intra coding	{        // Get the pixel index for the first pixel in the fragment.        pbi->ReconIntra( pbi, (UINT8 *)&pbi->ThisFrameRecon[ReconPixelIndex], (UINT16 *)pbi->ReconDataBuffer, ReconPixelsPerLine );	}}/**************************************************************************** *  *  ROUTINE       :     ExpandToken * *  INPUTS        :     Q_LIST_ENTRY * ExpandedBlock *                                     Pointer to block structure into which the token *                                     should be expanded. * *                      INT32 * CoeffIndex

⌨️ 快捷键说明

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