📄 scan.c
字号:
line_length2 = tmp_line_length + tmp_line_length2 - 1;
if ( line_length2 > ppi->MaxLineSearchLen )
line_length2 = ppi->MaxLineSearchLen;
}else
line_length2 = tmp_line_length;
}
/* Take the largest line length */
if ( line_length2 > line_length )
line_length = line_length2;
/* Create line length score */
line_length_score = LineLengthScores[line_length];
return (unsigned char)line_length_score;
}
static void LineSearchScoreRow( PP_INSTANCE *ppi,
unsigned char * ChangedLocalsPtr,
ogg_int16_t * YUVDiffsPtr,
unsigned char * PixelNoiseScorePtr,
ogg_uint32_t * FragScorePtr,
signed char * DispFragPtr,
ogg_int32_t RowNumber ){
ogg_uint32_t AbsDiff;
unsigned char changed_locals = 0;
ogg_int32_t Score;
ogg_uint32_t FragScore;
ogg_int32_t i,j;
/* The defining rule used here is as follows. */
/* An edge pixels has 2-5 changed locals. */
/* And one or more of these changed locals has itself got 7-8
changed locals. */
/* Loop for all pixels in the row. */
for ( i = 0; i < ppi->PlaneWidth; i += HFRAGPIXELS ){
/* Does the fragment contain anything interesting to work with. */
if ( *DispFragPtr == CANDIDATE_BLOCK ){
/* Reset the cumulative fragment score. */
FragScore = 0;
/* Pixels grouped along the row into fragments */
for ( j = 0; j < HFRAGPIXELS; j++ ){
/* How many changed locals has the current pixel got. */
changed_locals = ChangedLocalsPtr[j];
/* Is the pixel a suitable candidate for edge enhancement */
if ( (changed_locals > 1) && (changed_locals < 6) &&
(PixelNoiseScorePtr[j] < ppi->LineSearchTripTresh) ) {
Score = (ogg_int32_t)
LineSearchScorePixel( ppi, &ChangedLocalsPtr[j], RowNumber, i+j );
if ( Score ){
AbsDiff = abs( YUVDiffsPtr[j] );
Score = (ogg_int32_t)
( (double)Score * ppi->AbsDiff_ScoreMultiplierTable[AbsDiff] );
if ( Score < 1 )
Score = 1;
PixelNoiseScorePtr[j] += (unsigned char)Score;
FragScore += (ogg_uint32_t)Score;
}
}
}
/* Add fragment score (with plane correction factor) into main
data structure */
*FragScorePtr +=
(ogg_int32_t)(FragScore * ppi->YUVPlaneCorrectionFactor);
/* If score is greater than trip threshold then mark blcok for update. */
if ( *FragScorePtr > ppi->BlockThreshold ){
*DispFragPtr = BLOCK_CODED_LOW;
}
}
/* Increment the various pointers */
FragScorePtr++;
DispFragPtr++;
PixelNoiseScorePtr += HFRAGPIXELS;
ChangedLocalsPtr += HFRAGPIXELS;
YUVDiffsPtr += HFRAGPIXELS;
}
}
static void RowCopy( PP_INSTANCE *ppi, ogg_uint32_t BlockMapIndex ){
ogg_uint32_t i,j;
ogg_uint32_t PixelIndex = ppi->ScanPixelIndexTable[BlockMapIndex];
signed char * BlockMapPtr = &ppi->ScanDisplayFragments[BlockMapIndex];
signed char * PrevFragmentsPtr = &ppi->PrevFragments[0][BlockMapIndex];
unsigned char * SourcePtr;
unsigned char * DestPtr;
/* Copy pixels from changed blocks back to reference frame. */
for ( i = 0; i < (ogg_uint32_t)ppi->PlaneHFragments; i ++ ){
/* If the fragement is marked for update or was recently marked
for update (PrevFragmentsPtr[i]) */
if ( (BlockMapPtr[i] > BLOCK_NOT_CODED) ||
(PrevFragmentsPtr[i] == BLOCK_CODED) ){
/* Set up the various pointers required. */
SourcePtr = &ppi->ScanConfig.Yuv1ptr[PixelIndex];
DestPtr = &ppi->ScanConfig.SrfWorkSpcPtr[PixelIndex];
/* For each row of the block */
for ( j = 0; j < VFRAGPIXELS; j++ ){
/* Copy the data unaltered from source to destination */
memcpy(DestPtr,SourcePtr,8);
/* Increment pointers for next line in the block */
SourcePtr += ppi->PlaneWidth;
DestPtr += ppi->PlaneWidth;
}
}
/* Increment pixel index for next block. */
PixelIndex += HFRAGPIXELS;
}
}
static void RowBarEnhBlockMap( PP_INSTANCE *ppi,
signed char * UpdatedBlockMapPtr,
signed char * BarBlockMapPtr,
ogg_uint32_t RowNumber ){
int i;
/* Start by blanking the row in the bar block map structure. */
memset( BarBlockMapPtr, BLOCK_NOT_CODED, ppi->PlaneHFragments );
/* First row */
if ( RowNumber == 0 ){
/* For each fragment in the row. */
for ( i = 0; i < ppi->PlaneHFragments; i ++ ){
/* Test for CANDIDATE_BLOCK or CANDIDATE_BLOCK_LOW. Uncoded or
coded blocks will be ignored. */
if ( UpdatedBlockMapPtr[i] <= CANDIDATE_BLOCK ){
/* Is one of the immediate neighbours updated in the main map. */
/* Note special cases for blocks at the start and end of rows. */
if ( i == 0 ){
if ((UpdatedBlockMapPtr[i+1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments]>BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments+1]>BLOCK_NOT_CODED ) )
BarBlockMapPtr[i] = BLOCK_CODED_BAR;
}else if ( i == (ppi->PlaneHFragments - 1) ){
if ((UpdatedBlockMapPtr[i-1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments-1]>BLOCK_NOT_CODED) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments]>BLOCK_NOT_CODED) )
BarBlockMapPtr[i] = BLOCK_CODED_BAR;
}else{
if((UpdatedBlockMapPtr[i-1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments-1] > BLOCK_NOT_CODED)||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments+1] > BLOCK_NOT_CODED) )
BarBlockMapPtr[i] = BLOCK_CODED_BAR;
}
}
}
} else if ( RowNumber == (ogg_uint32_t)(ppi->PlaneVFragments-1)) {
/* Last row */
/* Used to read PlaneHFragments */
/* For each fragment in the row. */
for ( i = 0; i < ppi->PlaneHFragments; i ++ ){
/* Test for CANDIDATE_BLOCK or CANDIDATE_BLOCK_LOW
Uncoded or coded blocks will be ignored. */
if ( UpdatedBlockMapPtr[i] <= CANDIDATE_BLOCK ){
/* Is one of the immediate neighbours updated in the main map. */
/* Note special cases for blocks at the start and end of rows. */
if ( i == 0 ){
if((UpdatedBlockMapPtr[i+1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments+1] > BLOCK_NOT_CODED ))
BarBlockMapPtr[i] = BLOCK_CODED_BAR;
}else if ( i == (ppi->PlaneHFragments - 1) ){
if((UpdatedBlockMapPtr[i-1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments-1] > BLOCK_NOT_CODED)||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments] > BLOCK_NOT_CODED ) )
BarBlockMapPtr[i] = BLOCK_CODED_BAR;
}else{
if((UpdatedBlockMapPtr[i-1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments-1] > BLOCK_NOT_CODED)||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments+1] > BLOCK_NOT_CODED) )
BarBlockMapPtr[i] = BLOCK_CODED_BAR;
}
}
}
}else{
/* All other rows */
/* For each fragment in the row. */
for ( i = 0; i < ppi->PlaneHFragments; i ++ ){
/* Test for CANDIDATE_BLOCK or CANDIDATE_BLOCK_LOW */
/* Uncoded or coded blocks will be ignored. */
if ( UpdatedBlockMapPtr[i] <= CANDIDATE_BLOCK ){
/* Is one of the immediate neighbours updated in the main map. */
/* Note special cases for blocks at the start and end of rows. */
if ( i == 0 ){
if((UpdatedBlockMapPtr[i+1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments+1] > BLOCK_NOT_CODED)||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments+1] > BLOCK_NOT_CODED) )
BarBlockMapPtr[i] = BLOCK_CODED_BAR;
}else if ( i == (ppi->PlaneHFragments - 1) ){
if((UpdatedBlockMapPtr[i-1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments-1] > BLOCK_NOT_CODED)||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments-1] > BLOCK_NOT_CODED)||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments] > BLOCK_NOT_CODED ) )
BarBlockMapPtr[i] = BLOCK_CODED_BAR;
}else{
if((UpdatedBlockMapPtr[i-1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments-1] > BLOCK_NOT_CODED)||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments+1] > BLOCK_NOT_CODED)||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments-1] > BLOCK_NOT_CODED)||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments+1] > BLOCK_NOT_CODED ))
BarBlockMapPtr[i] = BLOCK_CODED_BAR;
}
}
}
}
}
static void BarCopyBack( PP_INSTANCE *ppi,
signed char * UpdatedBlockMapPtr,
signed char * BarBlockMapPtr ){
ogg_int32_t i;
/* For each fragment in the row. */
for ( i = 0; i < ppi->PlaneHFragments; i ++ ){
if ( BarBlockMapPtr[i] > BLOCK_NOT_CODED ){
UpdatedBlockMapPtr[i] = BarBlockMapPtr[i];
}
}
}
static void AnalysePlane( PP_INSTANCE *ppi,
unsigned char * PlanePtr0,
unsigned char * PlanePtr1,
ogg_uint32_t FragArrayOffset,
ogg_uint32_t PWidth,
ogg_uint32_t PHeight,
ogg_uint32_t PStride ) {
unsigned char * RawPlanePtr0;
unsigned char * RawPlanePtr1;
ogg_int16_t * YUVDiffsPtr;
ogg_int16_t * YUVDiffsPtr1;
ogg_int16_t * YUVDiffsPtr2;
ogg_uint32_t FragIndex;
ogg_uint32_t ScoreFragIndex1;
ogg_uint32_t ScoreFragIndex2;
ogg_uint32_t ScoreFragIndex3;
ogg_uint32_t ScoreFragIndex4;
int UpdatedOrCandidateBlocks = 0;
unsigned char * ChLocalsPtr0;
unsigned char * ChLocalsPtr1;
unsigned char * ChLocalsPtr2;
unsigned char * PixelsChangedPtr0;
unsigned char * PixelsChangedPtr1;
unsigned char * PixelScoresPtr1;
unsigned char * PixelScoresPtr2;
signed char * DispFragPtr0;
signed char * DispFragPtr1;
signed char * DispFragPtr2;
ogg_uint32_t * FragScoresPtr1;
ogg_uint32_t * FragScoresPtr2;
ogg_int32_t * RowDiffsPtr;
ogg_int32_t * RowDiffsPtr1;
ogg_int32_t * RowDiffsPtr2;
ogg_int32_t i,j;
ogg_int32_t RowNumber1;
ogg_int32_t RowNumber2;
ogg_int32_t RowNumber3;
ogg_int32_t RowNumber4;
int EdgeRow;
ogg_int32_t LineSearchRowNumber = 0;
/* Variables used as temporary stores for frequently used values. */
ogg_int32_t Row0Mod3;
ogg_int32_t Row1Mod3;
ogg_int32_t Row2Mod3;
ogg_int32_t BlockRowPixels;
/* Set pixel difference threshold */
if ( FragArrayOffset == 0 ){
/* Luminance */
ppi->LevelThresh = (int)ppi->SgcLevelThresh;
ppi->NegLevelThresh = -ppi->LevelThresh;
ppi->SrfThresh = (int)ppi->SRFGreyThresh;
ppi->NegSrfThresh = -ppi->SrfThresh;
/* Scores correction for Y pixels. */
ppi->YUVPlaneCorrectionFactor = 1.0;
ppi->BlockThreshold = ppi->PrimaryBlockThreshold;
ppi->BlockSgcThresh = ppi->SgcThresh;
}else{
/* Chrominance */
ppi->LevelThresh = (int)ppi->SuvcLevelThresh;
ppi->NegLevelThresh = -ppi->LevelThresh;
ppi->SrfThresh = (int)ppi->SRFColThresh;
ppi->NegSrfThresh = -ppi->SrfThresh;
/* Scores correction for UV pixels. */
ppi->YUVPlaneCorrectionFactor = 1.5;
/* Block threholds different for subsampled U and V blocks */
ppi->BlockThreshold =
(ppi->PrimaryBlockThreshold / ppi->UVBlockThreshCorrection);
ppi->BlockSgcThresh =
(ppi->SgcThresh / ppi->UVSgcCorrection);
}
/* Initialise the SRF thresh table and pointer. */
memset( ppi->SrfThreshTable, 1, 512 );
for ( i = ppi->NegSrfThresh; i <= ppi->SrfThresh; i++ )
ppi->SrfThreshTable[i+255] = 0;
/* Initialise the PAK thresh table. */
for ( i = -255; i <= 255; i++ )
if ( ppi->SrfThreshTable[i+255] &&
(i <= ppi->HighChange) &&
(i >= ppi->NegHighChange) )
ppi->SrfPakThreshTable[i+255] = 1;
else
ppi->SrfPakThreshTable[i+255] = 0;
/* Initialise the SGc lookup table */
for ( i = -255; i <= 255; i++ ){
if ( i <= ppi->NegLevelThresh )
ppi->SgcThreshTable[i+255] = (unsigned char) -1;
else if ( i >= ppi->LevelThresh )
ppi->SgcThreshTable[i+255] = 1;
else
ppi->SgcThreshTable[i+255] = 0;
}
/* Set up plane dimension variables */
ppi->PlaneHFragments = PWidth / HFRAGPIXELS;
ppi->PlaneVFragments = PHeight / VFRAGPIXELS;
ppi->PlaneWidth = PWidth;
ppi->PlaneHeight = PHeight;
ppi->PlaneStride = PStride;
/* Set up local pointers into the raw image data. */
RawPlanePtr0 = PlanePtr0;
RawPlanePtr1 = PlanePtr1;
/* Note size and endo points for circular buffers. */
ppi->YuvDiffsCircularBufferSize = YDIFF_CB_ROWS * ppi->PlaneWidth;
ppi->ChLocalsCircularBufferSize = CHLOCALS_CB_ROWS * ppi->PlaneWidth;
ppi->PixelMapCircularBufferSize = PMAP_CB_ROWS * ppi->PlaneWidth;
/* Set high change thresh where PAK not needed */
ppi->HighChange = ppi->SrfThresh * 4;
ppi->NegHighChange = -ppi->HighChange;
/* Set up row difference pointers. */
RowDiffsPtr = ppi->RowChangedPixels;
RowDiffsPtr1 = ppi->RowChangedPixels;
RowDiffsPtr2 = ppi->RowChangedPixels;
Bl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -