📄 dct_decode.c
字号:
* Where we are in the current block. * * INT32 Token, ExtraBits * * OUTPUTS : * * RETURNS : None * * FUNCTION : Expands a DCT token into a data structure. * * SPECIAL NOTES : * * * ERRORS : None. * ****************************************************************************/void ExpandToken( PB_INSTANCE *pbi __attribute__((unused)), Q_LIST_ENTRY * ExpandedBlock, UINT8 * CoeffIndex, UINT32 Token, INT32 ExtraBits ){ // Is the token is a combination run and value token. if ( Token >= DCT_RUN_CATEGORY1 ) { // Expand the token and additional bits to a zero run length and data value. if ( Token < DCT_RUN_CATEGORY2 ) { // Decoding method depends on token if ( Token < DCT_RUN_CATEGORY1B ) { // Step on by the zero run length *CoeffIndex += (UINT8)((Token - DCT_RUN_CATEGORY1) + 1); // The extra bit determines the sign. if ( ExtraBits & 0x01 ) ExpandedBlock[*CoeffIndex] = -1; else ExpandedBlock[*CoeffIndex] = 1; } else if ( Token == DCT_RUN_CATEGORY1B ) { // Bits 0-1 determines the zero run length *CoeffIndex += (6 + (ExtraBits & 0x03)); // Bit 2 determines the sign if ( ExtraBits & 0x04 ) ExpandedBlock[*CoeffIndex] = -1; else ExpandedBlock[*CoeffIndex] = 1; } else { // Bits 0-2 determines the zero run length *CoeffIndex += (10 + (ExtraBits & 0x07)); // Bit 3 determines the sign if ( ExtraBits & 0x08 ) ExpandedBlock[*CoeffIndex] = -1; else ExpandedBlock[*CoeffIndex] = 1; } } else { // If token == DCT_RUN_CATEGORY2 we have a single 0 followed by a value if ( Token == DCT_RUN_CATEGORY2 ) { // Step on by the zero run length *CoeffIndex += 1; // Bit 1 determines sign, bit 0 the value if ( ExtraBits & 0x02 ) ExpandedBlock[*CoeffIndex] = -(2 + (ExtraBits & 0x01)); else ExpandedBlock[*CoeffIndex] = 2 + (ExtraBits & 0x01); } // else we have 2->3 zeros followed by a value else { // Bit 0 determines the zero run length *CoeffIndex += 2 + (ExtraBits & 0x01); // Bit 2 determines the sign, bit 1 the value if ( ExtraBits & 0x04 ) ExpandedBlock[*CoeffIndex] = -(2 + ((ExtraBits & 0x02) >> 1)); else ExpandedBlock[*CoeffIndex] = 2 + ((ExtraBits & 0x02) >> 1); } } // Step on over value *CoeffIndex += 1; } // Token is a ZRL token so step on by the appropriate number of zeros else if ( Token == DCT_SHORT_ZRL_TOKEN ) { *CoeffIndex += ExtraBits + 1; } // Token is a ZRL token so step on by the appropriate number of zeros else if ( Token == DCT_ZRL_TOKEN ) { *CoeffIndex += ExtraBits + 1; } // Token is a small single value token. else if ( Token < LOW_VAL_TOKENS ) { switch ( Token ) { case ONE_TOKEN: ExpandedBlock[*CoeffIndex] = 1; break; case MINUS_ONE_TOKEN: ExpandedBlock[*CoeffIndex] = -1; break; case TWO_TOKEN: ExpandedBlock[*CoeffIndex] = 2; break; case MINUS_TWO_TOKEN: ExpandedBlock[*CoeffIndex] = -2; break; } // Step on the coefficient index. *CoeffIndex += 1; } // Token is a larger single value token else { // Expand the token and additional bits to a data value. if ( Token < DCT_VAL_CATEGORY3 ) { // Offset from LOW_VAL_TOKENS determines value Token = Token - LOW_VAL_TOKENS; // Extra bit determines sign if ( ExtraBits ) ExpandedBlock[*CoeffIndex] = -((Q_LIST_ENTRY)(Token + DCT_VAL_CAT2_MIN)); else ExpandedBlock[*CoeffIndex] = (Q_LIST_ENTRY)(Token + DCT_VAL_CAT2_MIN); } else if ( Token == DCT_VAL_CATEGORY3 ) { // Bit 1 determines sign, Bit 0 the value if ( ExtraBits & 0x02 ) ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT3_MIN + (ExtraBits & 0x01)); else ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT3_MIN + (ExtraBits & 0x01); } else if ( Token == DCT_VAL_CATEGORY4 ) { // Bit 2 determines sign, Bit 0-1 the value if ( ExtraBits & 0x04 ) ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT4_MIN + (ExtraBits & 0x03)); else ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT4_MIN + (ExtraBits & 0x03); } else if ( Token == DCT_VAL_CATEGORY5 ) { // Bit 3 determines sign, Bit 0-2 the value if ( ExtraBits & 0x08 ) ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT5_MIN + (ExtraBits & 0x07)); else ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT5_MIN + (ExtraBits & 0x07); } else if ( Token == DCT_VAL_CATEGORY6 ) { // Bit 4 determines sign, Bit 0-3 the value if ( ExtraBits & 0x10 ) ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT6_MIN + (ExtraBits & 0x0F)); else ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT6_MIN + (ExtraBits & 0x0F); } else if ( Token == DCT_VAL_CATEGORY7 ) { // Bit 5 determines sign, Bit 0-4 the value if ( ExtraBits & 0x20 ) ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT7_MIN + (ExtraBits & 0x1F)); else ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT7_MIN + (ExtraBits & 0x1F); } else if ( Token == DCT_VAL_CATEGORY8 ) { // Bit 9 determines sign, Bit 0-8 the value if ( ExtraBits & 0x200 ) ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT8_MIN + (ExtraBits & 0x1FF)); else ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT8_MIN + (ExtraBits & 0x1FF); } // Step on the coefficient index. *CoeffIndex += 1; }}/**************************************************************************** * * ROUTINE : CopyRecon * * INPUTS : UINT8 * DestReconPtr * UINT8 * SrcReconPtr * * OUTPUTS : None * * RETURNS : None * * FUNCTION : Copies the current reconstruction to the last frame * reconstruction buffer. * * SPECIAL NOTES : * * * ERRORS : None. * ****************************************************************************/void CopyRecon( PB_INSTANCE *pbi, UINT8 * DestReconPtr, UINT8 * SrcReconPtr ){ UINT32 i; UINT32 PlaneLineStep; // Pixels per line UINT32 PixelIndex; UINT8 *SrcPtr; // Pointer to line of source image data UINT8 *DestPtr; // Pointer to line of destination image data //static Temp = 0; // Copy over only updated blocks. // First Y plane PlaneLineStep = pbi->Configuration.YStride; for ( i = 0; i < pbi->YPlaneFragments; i++ ) { if ( pbi->display_fragments[i] ) { PixelIndex = ReconGetFragIndex ( pbi->recon_pixel_index_table, i ); SrcPtr = &SrcReconPtr[ PixelIndex ]; DestPtr = &DestReconPtr[ PixelIndex ]; pbi->CopyBlock(SrcPtr, DestPtr, PlaneLineStep); } } // Then U and V PlaneLineStep = pbi->Configuration.UVStride; for ( i = pbi->YPlaneFragments; i < pbi->UnitFragments; i++ ) { if ( pbi->display_fragments[i] ) { PixelIndex = ReconGetFragIndex ( pbi->recon_pixel_index_table, i ); SrcPtr = &SrcReconPtr[ PixelIndex ]; DestPtr = &DestReconPtr[ PixelIndex ]; pbi->CopyBlock(SrcPtr, DestPtr, PlaneLineStep); } } // We may need to update the UMV border UpdateUMVBorder(pbi, DestReconPtr);}/**************************************************************************** * * ROUTINE : CopyRecon * * INPUTS : UINT8 * DestReconPtr * UINT8 * SrcReconPtr * * OUTPUTS : None * * RETURNS : None * * FUNCTION : Copies the current reconstruction to the last frame * reconstruction buffer. * * SPECIAL NOTES : * * * ERRORS : None. * ****************************************************************************/void CopyNotRecon( PB_INSTANCE *pbi, UINT8 * DestReconPtr, UINT8 * SrcReconPtr ){ UINT32 i; UINT32 PlaneLineStep; // Pixels per line UINT32 PixelIndex; UINT8 *SrcPtr; // Pointer to line of source image data UINT8 *DestPtr; // Pointer to line of destination image data //static Temp = 0; // Copy over only updated blocks. // First Y plane PlaneLineStep = pbi->Configuration.YStride; for ( i = 0; i < pbi->YPlaneFragments; i++ ) { if ( !pbi->display_fragments[i] ) { PixelIndex = ReconGetFragIndex ( pbi->recon_pixel_index_table, i ); SrcPtr = &SrcReconPtr[ PixelIndex ]; DestPtr = &DestReconPtr[ PixelIndex ]; pbi->CopyBlock(SrcPtr, DestPtr, PlaneLineStep); } } // Then U and V PlaneLineStep = pbi->Configuration.UVStride; for ( i = pbi->YPlaneFragments; i < pbi->UnitFragments; i++ ) { if ( !pbi->display_fragments[i] ) { PixelIndex = ReconGetFragIndex ( pbi->recon_pixel_index_table, i ); SrcPtr = &SrcReconPtr[ PixelIndex ]; DestPtr = &DestReconPtr[ PixelIndex ]; pbi->CopyBlock(SrcPtr, DestPtr, PlaneLineStep); } } // We may need to update the UMV border UpdateUMVBorder(pbi, DestReconPtr);}/**************************************************************************** * * ROUTINE : UpdateUMVBorder * * INPUTS : UINT8 * DestReconPtr * * OUTPUTS : None * * RETURNS : None * * FUNCTION : Updates the UMV border for the given reconstruction * buffer. * * SPECIAL NOTES : * * * ERRORS : None. * ****************************************************************************/void UpdateUMVBorder( PB_INSTANCE *pbi, UINT8 * DestReconPtr ){ UINT32 PlaneFragOffset; // Y plane PlaneFragOffset = 0; UpdateUMV_VBorders( pbi, DestReconPtr, PlaneFragOffset ); UpdateUMV_HBorders( pbi, DestReconPtr, PlaneFragOffset ); // Then the U and V Planes PlaneFragOffset = pbi->YPlaneFragments; UpdateUMV_VBorders( pbi, DestReconPtr, PlaneFragOffset ); UpdateUMV_HBorders( pbi, DestReconPtr, PlaneFragOffset ); PlaneFragOffset = pbi->YPlaneFragments + pbi->UVPlaneFragments; UpdateUMV_VBorders( pbi, DestReconPtr, PlaneFragOffset ); UpdateUMV_HBorders( pbi, DestReconPtr, PlaneFragOffset );}/**************************************************************************** * * ROUTINE : UpdateUMV_HBorders * * INPUTS : UINT8 * DestReconPtr * UINT32 PlaneFragOffset * * OUTPUTS : None * * RETURNS : None * * FUNCTION : Fills in the Horizontal UMV borders for the given * reconstruction buffer. * * SPECIAL NOTES : * * * ERRORS : None. * ****************************************************************************/void UpdateUMV_HBorders( PB_INSTANCE *pbi, UINT8 * DestReconPtr, UINT32 PlaneFragOffset ){ UINT32 i; UINT32 PixelIndex; UINT32 PlaneStride; UINT32 BlockVStep; UINT32 PlaneFragments; UINT32 LineFragments; UINT32 PlaneBorderWidth;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -