searchwindow.hh

来自「Motion JPEG编解码器源代码」· HH 代码 · 共 1,997 行 · 第 1/5 页

HH
1,997
字号
	}	// The cell can move into a child branch.	return false;}// If the given pixel group straddles this level of the tree// (i.e. because one of its pixel values equals its// corresponding split point), then return true.// Otherwise, calculate the index of the child branch that// should take this cell, and return false.// In either case, determine whether any search-window cells// that had to stop at this level of the tree could possibly// intersect the given pixel-group.template <class PIXEL_NUM, int DIM, class PIXEL_TOL, class PIXELINDEX,	class FRAMESIZE, PIXELINDEX PGW, PIXELINDEX PGH,	class SORTERBITMASK, class PIXEL, class REFERENCEPIXEL,	class REFERENCEFRAME>boolSearchWindow<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE,	PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL,REFERENCEFRAME>	::PixelSorterBranchNode::DoesPixelGroupStopHere	(const PixelGroup *a_pPixelGroup, Tolerance_t a_tnTwiceTolerance,	SORTERBITMASK &a_rtnChildIndex, bool &a_rbMatchAtThisLevel) const{	PIXELINDEX tnX, tnY;	int i;		// Used to loop through pixels & pixel dimensions.	bool bPixelGroupStopsHere;		// True if one of the pixel-group's pixels exactly matches		// its corresponding split-point.		// Make sure they gave us a pixel-group.	assert (a_pPixelGroup != NULL);	// Compare the group's pixel values to our split values, and	// determine which child branch it should descend, or if it	// should stop at this level.	a_rtnChildIndex = 0;	bPixelGroupStopsHere = false;	a_rbMatchAtThisLevel = false;	for (tnY = 0; tnY < PGH; ++tnY)	{		for (tnX = 0; tnX < PGW; ++tnX)		{			// Get the two pixels of interest.			const Pixel_t &rGroupPixel				= a_pPixelGroup->m_atPixels[tnY][tnX];			const Pixel_t &rSplitPixel				= m_oSplitValue.m_atPixels[tnY][tnX];			// Determine the effect each dimension has on the			// bitmask that we use to determine the index of the			// child branch that this cell should descend into.			// (If the pixel value is right on a branch, then all			// pixels that would match it have been found at this			// level.)			for (i = 0; i < DIM; i++)			{				if (rGroupPixel[i] == rSplitPixel[i])					bPixelGroupStopsHere = true;				if (rGroupPixel[i] > rSplitPixel[i])					a_rtnChildIndex |= GetBitMask (tnY, tnX, i);				// If the current pixel is within twice the tolerance				// of the split-point, then some of the search-window				// cells that had to stop at this point in the tree may				// match the current pixel-group.  (And once we figure				// that out, we don't have to check any other pixels for				// this property.)				if (!a_rbMatchAtThisLevel)				{					// Make copies of the two pixels.					Pixel_t oGroupPixel = rGroupPixel;					Pixel_t oSplitPixel = rSplitPixel;					// Collapse all dimensions but the current one.					for (int j = 0; j < DIM; ++j)						if (j != i)							oGroupPixel[j] = oSplitPixel[j];										// If this axis, all by itself, is within twice the					// tolerance, then we can no longer rule out matches					// at this level.					if (oGroupPixel.IsWithinTolerance (oSplitPixel,						a_tnTwiceTolerance))					{						a_rbMatchAtThisLevel = true;					}				}			}		}	}	// Return whether the pixel group can descend into a child branch.	return bPixelGroupStopsHere;}// Set our split values to the midpoint between the given// minimum & maximum.template <class PIXEL_NUM, int DIM, class PIXEL_TOL, class PIXELINDEX,	class FRAMESIZE, PIXELINDEX PGW, PIXELINDEX PGH,	class SORTERBITMASK, class PIXEL, class REFERENCEPIXEL,	class REFERENCEFRAME>voidSearchWindow<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE,	PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL,REFERENCEFRAME>	::PixelSorterBranchNode::SplitValues (const PixelGroup &a_rMin,	const PixelGroup &a_rMax){	PIXELINDEX tnX, tnY;	int nDim;		// Used to iterate through pixel-groups.	// Loop through all the pixels & their dimensions, calculate each	// split value.	for (tnY = 0; tnY < PGH; ++tnY)		for (tnX = 0; tnX < PGW; ++tnX)			for (nDim = 0; nDim < DIM; ++nDim)				m_oSplitValue.m_atPixels[tnY][tnX][nDim] = PIXEL_NUM					((PIXEL_TOL (a_rMin.m_atPixels[tnY][tnX][nDim])					+ PIXEL_TOL (a_rMax.m_atPixels[tnY][tnX][nDim]))						/ 2);}#ifndef NDEBUGtemplate <class PIXEL_NUM, int DIM, class PIXEL_TOL, class PIXELINDEX,	class FRAMESIZE, PIXELINDEX PGW, PIXELINDEX PGH,	class SORTERBITMASK, class PIXEL, class REFERENCEPIXEL,	class REFERENCEFRAME>uint32_tSearchWindow<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE,	PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL,REFERENCEFRAME>	::PixelSorterBranchNode::sm_ulInstances;template <class PIXEL_NUM, int DIM, class PIXEL_TOL, class PIXELINDEX,	class FRAMESIZE, PIXELINDEX PGW, PIXELINDEX PGH,	class SORTERBITMASK, class PIXEL, class REFERENCEPIXEL,	class REFERENCEFRAME>uint32_tSearchWindow<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE,	PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL,REFERENCEFRAME>	::GetPixelSorterNodeCount (void){	return PixelSorterBranchNode::GetInstances();}#endif // NDEBUG// Add this search-window cell to the pixel-sorter, creating// new branch nodes as needed.template <class PIXEL_NUM, int DIM, class PIXEL_TOL, class PIXELINDEX,	class FRAMESIZE, PIXELINDEX PGW, PIXELINDEX PGH,	class SORTERBITMASK, class PIXEL, class REFERENCEPIXEL,	class REFERENCEFRAME>typename SearchWindow<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE,	PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL,	REFERENCEFRAME>::PixelSorterBranchNode *SearchWindow<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE,	PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL,	REFERENCEFRAME>::PixelSorter_Add (Status_t &a_reStatus,	SearchWindowCell *a_pCell, PixelSorterBranchNode *a_pLastSorter,	int8_t &a_reDoneSorting){	PixelSorterBranchNode *pCurrentBranch;		// Where we are in the pixel-sorter tree.	// Make sure they didn't start us off with an error.	assert (a_reStatus == g_kNoError);	// Make sure they gave us a cell to add.	assert (a_pCell != NULL);	// Make sure the cell is within the search radius.	assert (AbsoluteValue (a_pCell->m_tnX - m_tnX)		<= m_tnSearchRadiusX);	assert (AbsoluteValue (a_pCell->m_tnY - m_tnY)		<= m_tnSearchRadiusY);	// If we know where the cell should go, just put it there and exit.	if (a_pLastSorter != NULL && a_reDoneSorting)	{		a_pLastSorter->m_oSplitValue.InsertAfter			(&(a_pLastSorter->m_oSplitValue), a_pCell);		return a_pLastSorter;	}	// Initialize our traversal's minimum/maximum to the full range.	// This will get modified as we move down the tree.	m_oRangeMin = m_oPixelSorterMin;	m_oRangeMax = m_oPixelSorterMax;	// Traverse the tree, figure out where the new search-window cell	// should be put.  Create new branch nodes as needed.	pCurrentBranch = ((a_pLastSorter == NULL)		? &m_oPixelSorter : a_pLastSorter);	for (;;)	{		SORTERBITMASK tnChildIndex;			// The index of the child branch node that should take the			// newly-added cell.		// If this branch node has no cells, just put the new cell here		// and exit.  (This is almost like balancing the search tree.)		if (pCurrentBranch->m_oSplitValue.m_pForward			== &(pCurrentBranch->m_oSplitValue))		{			pCurrentBranch->m_oSplitValue.InsertAfter				(&(pCurrentBranch->m_oSplitValue), a_pCell);			a_reDoneSorting = SearchWindowCell::m_knDoneEnough;			return pCurrentBranch;		}		// If the cell must stay at this level of the tree, then put		// the cell at this level & exit.		if (pCurrentBranch->ShouldCellStayHere (*a_pCell, m_tnTolerance,			tnChildIndex, m_oRangeMin, m_oRangeMax))		{			// Hook this cell up to the branch's cell list.			pCurrentBranch->m_oSplitValue.InsertAfter				(&(pCurrentBranch->m_oSplitValue), a_pCell);			// We're done.			a_reDoneSorting = SearchWindowCell::m_knDone;			return pCurrentBranch;		}		// The cell should descend into a child branch.  If that child		// exists, then descend.		if (pCurrentBranch->m_apBranches[tnChildIndex] != NULL)		{			pCurrentBranch = pCurrentBranch->m_apBranches[tnChildIndex];			continue;		}		// Try to create the child branch that the cell should go into.		pCurrentBranch->m_apBranches[tnChildIndex]			= new PixelSorterBranchNode;		if (pCurrentBranch->m_apBranches[tnChildIndex] == NULL)		{			// We ran out of memory.  Just put the cell here.			pCurrentBranch->m_oSplitValue.InsertAfter				(&(pCurrentBranch->m_oSplitValue), a_pCell);			a_reDoneSorting = SearchWindowCell::m_knDoneEnough;			return pCurrentBranch;		}		pCurrentBranch = pCurrentBranch->m_apBranches[tnChildIndex];		// Set its split value to the midpoint between the min/max for		// this child.		pCurrentBranch->SplitValues (m_oRangeMin, m_oRangeMax);		// Put the cell here.		pCurrentBranch->m_oSplitValue.InsertAfter			(&(pCurrentBranch->m_oSplitValue), a_pCell);		// If new branch nodes are created below us, we could go deeper		// into the tree, but in the interest of tree-balancing, we stop		// here.  (We don't want to potentially create a new branch node		// when this cell gets re-inserted; we'll just be happy where we		// are.)		a_reDoneSorting = SearchWindowCell::m_knDoneEnough;		return pCurrentBranch;	}}// Remove this search-window cell from the pixel-sorter.template <class PIXEL_NUM, int DIM, class PIXEL_TOL, class PIXELINDEX,	class FRAMESIZE, PIXELINDEX PGW, PIXELINDEX PGH,	class SORTERBITMASK, class PIXEL, class REFERENCEPIXEL,	class REFERENCEFRAME>voidSearchWindow<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE,	PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL,	REFERENCEFRAME>::PixelSorter_Remove (SearchWindowCell *a_pCell){	// Make sure they gave us a cell to remove.	assert (a_pCell != NULL);	// Make sure the cell is in the pixel-sorter.	assert (a_pCell->m_pForward != NULL		&& a_pCell->m_pForward != a_pCell);	// Remove the cell from the pixel-sorter.	a_pCell->Remove();	// Put it back into a list with itself.  (This marks the cell as	// having been initialized, saving us from having to do that work	// again.)	a_pCell->m_pForward = a_pCell->m_pBackward = a_pCell;}// Begin a search through the pixel sorter for the given pixel group.template <class PIXEL_NUM, int DIM, class PIXEL_TOL, class PIXELINDEX,	class FRAMESIZE, PIXELINDEX PGW, PIXELINDEX PGH,	class SORTERBITMASK, class PIXEL, class REFERENCEPIXEL,	class REFERENCEFRAME>voidSearchWindow<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE,	PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL,	REFERENCEFRAME>::StartSearch	(PixelSorterIterator &a_rIterator, const PixelGroup &a_rSearch){	// Remember what cell we're searching for.	a_rIterator.m_pSearch = &a_rSearch;	// Start searching at the top of the tree.	a_rIterator.m_pBranch = &m_oPixelSorter;	// Remember to search this branch's cells.	a_rIterator.m_pCell = &(a_rIterator.m_pBranch->m_oSplitValue);}// If there is another pixel group that matches the one being// searched for, returns true and backpatches information on the// matched pixel group.  If the search is over, returns false.template <class PIXEL_NUM, int DIM, class PIXEL_TOL, class PIXELINDEX,	class FRAMESIZE, PIXELINDEX PGW, PIXELINDEX PGH,	class SORTERBITMASK, class PIXEL, class REFERENCEPIXEL,	class REFERENCEFRAME>const typename SearchWindow<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,	FRAMESIZE,PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL,	REFERENCEFRAME>::PixelGroup *SearchWindow<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE,	PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL,	REFERENCEFRAME>::FoundNextMatch	(PixelSorterIterator &a_rIterator#ifdef CALCULATE_SAD									 , Tolerance_t &a_rtnSAD#endif // CALCULATE_SAD															) const{	SORTERBITMASK tnChildIndex;		// The index of the branch node child that the search		// descends down next.	// Make sure they didn't try to search past the end.	assert (a_rIterator.m_pBranch != NULL);	// Loop until we find a match or reach the bottom of the tree.	for (;;)	{		bool bPixelGroupStopsHere;			// true if we don't have to descend further down the tree.		bool bMatchesAtThisLevel;			// true if it's possible for the current pixel-group to			// match pixel-groups that had to stop at this level in the			// tree.		// Move past the last match we found.  (This also works if the		// branch was just entered, i.e. we're pointing at the branch		// node's split values.)		a_rIterator.m_pCell = a_rIterator.m_pCell->m_pForward;		// See if we should descend the tree, and whether this		// pixel-group could possibly match any search-window cells that		// had to stay at this level of the tree.		bPixelGroupStopsHere = a_rIterator.m_pBranch			->DoesPixelGroupStopHere (a_rIterator.m_pSearch,			m_tnTwiceTolerance, tnChildIndex, bMatchesAtThisLevel);		// Loop through the cells attached to this branch, look for		// matches, return if we find one.		while (a_rIterator.m_pCell			!= &(a_rIterator.m_pBranch->m_oSplitValue))		{#ifndef NDEBUG			// If there are not supposed to be any matches at this			// level of the search-tree, and the current search-window			// cell is stuck at this level, then make sure there's no			// match.			if (!bMatchesAtThisLevel				&& a_rIterator.m_pCell->m_eDoneSorting					== SearchWindowCell::m_knDone)			{#ifdef CALCULATE_SAD				assert (!a_rIterator.m_pCell->IsWithinTolerance					(*(a_rIterator.m_pSearch), m_tnTolerance,					a_rtnSAD));#else // CALCULATE_SAD				assert (!a_rIterator.m_pCell->IsWithinTolerance					(*(a_rIte

⌨️ 快捷键说明

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