📄 dct_decode.c
字号:
SrcPtr2 = &DestReconPtr[ PixelIndex ]; DestPtr2 = &DestReconPtr[ PixelIndex + 1 ]; /* Now copy the top and bottom source lines into each line of the respective borders */ for ( i = 0; i < PlaneHeight; i++ ) { memset( DestPtr1, SrcPtr1[0], PlaneBorderWidth ); memset( DestPtr2, SrcPtr2[0], PlaneBorderWidth ); SrcPtr1 += PlaneStride; SrcPtr2 += PlaneStride; DestPtr1 += PlaneStride; DestPtr2 += PlaneStride; }}void UpdateUMVBorder( PB_INSTANCE *pbi, unsigned char * DestReconPtr ) { ogg_uint32_t 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 );}static void CopyRecon( PB_INSTANCE *pbi, unsigned char * DestReconPtr, unsigned char * SrcReconPtr ) { ogg_uint32_t i; ogg_uint32_t PlaneLineStep; /* Pixels per line */ ogg_uint32_t PixelIndex; unsigned char *SrcPtr; /* Pointer to line of source image data */ unsigned char *DestPtr; /* Pointer to line of destination image data */ /* Copy over only updated blocks.*/ /* First Y plane */ PlaneLineStep = pbi->YStride; for ( i = 0; i < pbi->YPlaneFragments; i++ ) { if ( pbi->display_fragments[i] ) { PixelIndex = pbi->recon_pixel_index_table[i]; SrcPtr = &SrcReconPtr[ PixelIndex ]; DestPtr = &DestReconPtr[ PixelIndex ]; dsp_copy8x8 (pbi->dsp, SrcPtr, DestPtr, PlaneLineStep); } } /* Then U and V */ PlaneLineStep = pbi->UVStride; for ( i = pbi->YPlaneFragments; i < pbi->UnitFragments; i++ ) { if ( pbi->display_fragments[i] ) { PixelIndex = pbi->recon_pixel_index_table[i]; SrcPtr = &SrcReconPtr[ PixelIndex ]; DestPtr = &DestReconPtr[ PixelIndex ]; dsp_copy8x8 (pbi->dsp, SrcPtr, DestPtr, PlaneLineStep); } }}static void CopyNotRecon( PB_INSTANCE *pbi, unsigned char * DestReconPtr, unsigned char * SrcReconPtr ) { ogg_uint32_t i; ogg_uint32_t PlaneLineStep; /* Pixels per line */ ogg_uint32_t PixelIndex; unsigned char *SrcPtr; /* Pointer to line of source image data */ unsigned char *DestPtr; /* Pointer to line of destination image data*/ /* Copy over only updated blocks. */ /* First Y plane */ PlaneLineStep = pbi->YStride; for ( i = 0; i < pbi->YPlaneFragments; i++ ) { if ( !pbi->display_fragments[i] ) { PixelIndex = pbi->recon_pixel_index_table[i]; SrcPtr = &SrcReconPtr[ PixelIndex ]; DestPtr = &DestReconPtr[ PixelIndex ]; dsp_copy8x8 (pbi->dsp, SrcPtr, DestPtr, PlaneLineStep); } } /* Then U and V */ PlaneLineStep = pbi->UVStride; for ( i = pbi->YPlaneFragments; i < pbi->UnitFragments; i++ ) { if ( !pbi->display_fragments[i] ) { PixelIndex = pbi->recon_pixel_index_table[i]; SrcPtr = &SrcReconPtr[ PixelIndex ]; DestPtr = &DestReconPtr[ PixelIndex ]; dsp_copy8x8 (pbi->dsp, SrcPtr, DestPtr, PlaneLineStep); } }}void ExpandToken( Q_LIST_ENTRY * ExpandedBlock, unsigned char * CoeffIndex, ogg_uint32_t Token, ogg_int32_t 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 += (unsigned char)((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{ /* else we have 2->3 zeros followed by a value */ /* 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; } else if ( Token == DCT_SHORT_ZRL_TOKEN ) { /* Token is a ZRL token so step on by the appropriate number of zeros */ *CoeffIndex += ExtraBits + 1; } else if ( Token == DCT_ZRL_TOKEN ) { /* Token is a ZRL token so step on by the appropriate number of zeros */ *CoeffIndex += ExtraBits + 1; } else if ( Token < LOW_VAL_TOKENS ) { /* Token is a small single value token. */ 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; }else{ /* Token is a larger single value token */ /* 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; }}void ClearDownQFragData(PB_INSTANCE *pbi){ ogg_int32_t i; Q_LIST_ENTRY * QFragPtr; for ( i = 0; i < pbi->CodedBlockIndex; i++ ) { /* Get the linear index for the current fragment. */ QFragPtr = pbi->QFragData[pbi->CodedBlockList[i]]; memset(QFragPtr, 0, 64*sizeof(Q_LIST_ENTRY)); }}static void FilterHoriz(unsigned char * PixelPtr, ogg_int32_t LineLength, ogg_int32_t *BoundingValuePtr){ ogg_int32_t j; ogg_int32_t FiltVal; for ( j = 0; j < 8; j++ ){ FiltVal = ( PixelPtr[0] ) - ( PixelPtr[1] * 3 ) + ( PixelPtr[2] * 3 ) - ( PixelPtr[3] ); FiltVal = *(BoundingValuePtr+((FiltVal + 4) >> 3)); PixelPtr[1] = clamp255(PixelPtr[1] + FiltVal); PixelPtr[2] = clamp255(PixelPtr[2] - FiltVal); PixelPtr += LineLength; }}static void FilterVert(unsigned char * PixelPtr, ogg_int32_t LineLength, ogg_int32_t *BoundingValuePtr){ ogg_int32_t j; ogg_int32_t FiltVal; /* the math was correct, but negative array indicies are forbidden by ANSI/C99 and will break optimization on several modern compilers */ PixelPtr -= 2*LineLength; for ( j = 0; j < 8; j++ ) { FiltVal = ( (ogg_int32_t)PixelPtr[0] ) - ( (ogg_int32_t)PixelPtr[LineLength] * 3 ) + ( (ogg_int32_t)PixelPtr[2 * LineLength] * 3 ) - ( (ogg_int32_t)PixelPtr[3 * LineLength] ); FiltVal = *(BoundingValuePtr+((FiltVal + 4) >> 3)); PixelPtr[LineLength] = clamp255(PixelPtr[LineLength] + FiltVal); PixelPtr[2 * LineLength] = clamp255(PixelPtr[2*LineLength] - FiltVal); PixelPtr ++; }}void LoopFilter(PB_INSTANCE *pbi){ ogg_int32_t i; ogg_int32_t * BoundingValuePtr=pbi->FiltBoundingValue+256; int FragsAcross=pbi->HFragments; int FromFragment,ToFragment; int FragsDown = pbi->VFragments; ogg_int32_t LineFragments; ogg_int32_t LineLength; ogg_int32_t FLimit; int QIndex; int j,m,n; /* Set the limit value for the loop filter based upon the current quantizer. */ QIndex = Q_TABLE_SIZE - 1; while ( QIndex >= 0 ) { if ( (QIndex == 0) || ( pbi->QThreshTable[QIndex] >= pbi->ThisFrameQualityValue) ) break; QIndex --; } FLimit = pbi->LoopFilterLimits[QIndex]; if ( FLimit == 0 ) return; SetupBoundingValueArray_Generic(pbi, FLimit); for ( j = 0; j < 3 ; j++){ switch(j) { case 0: /* y */ FromFragment = 0; ToFragment = pbi->YPlaneFragments; FragsAcross = pbi->HFragments; FragsDown = pbi->VFragments; LineLength = pbi->YStride; LineFragments = pbi->HFragments; break; case 1: /* u */ FromFragment = pbi->YPlaneFragments; ToFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments ; FragsAcross = pbi->HFragments >> 1; FragsDown = pbi->VFragments >> 1; LineLength = pbi->UVStride; LineFragments = pbi->HFragments / 2; break; /*case 2: v */ default: FromFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments; ToFragment = pbi->YPlaneFragments + (2 * pbi->UVPlaneFragments) ; FragsAcross = pbi->HFragments >> 1; FragsDown = pbi->VFragments >> 1; LineLength = pbi->UVStride; LineFragments = pbi->HFragments / 2; break; } i=FromFragment; /************************************************************** First Row **************************************************************/ /* first column conditions */ /* only do 2 prediction if fragment coded and on non intra or if all fragments are intra */ if( pbi->display_fragments[i]){ /* Filter right hand border only if the block to the right is not coded */ if ( !pbi->display_fragments[ i + 1 ] ){ FilterHoriz(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i]+6, LineLength,BoundingValuePtr); } /* Bottom done if next row set */ if( !pbi->display_fragments[ i + LineFragments] ){ FilterVert(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i+LineFragments], LineLength, BoundingValuePtr); } } i++; /***************************************************************/ /* middle columns */ for ( n = 1 ; n < FragsAcross - 1 ; n++, i++) { if( pbi->display_fragments[i]){ /* Filter Left edge always */ FilterHoriz(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i]-2, LineLength, BoundingValuePtr); /* Filter right hand border only if the block to the right is not coded */ if ( !pbi->display_fragments[ i + 1 ] ){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -