searchborder.hh

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

HH
2,118
字号
			if (tnBorderIndex == 0)				bLastBorderExtentFound = true;			// Get the region that'll be merged from.			pRegionUnderConstructionMergedFrom = (*itStart).m_pRegion;			pRegionMergedFrom = pRegionUnderConstructionMergedFrom				->m_pRegion;			// If this region is different than the first region we			// looked at, merge it with that first region.			if (pRegionMergedFrom != pRegionMergedTo)			{				RegionUnderConstruction *pCurrentRUC, *pNextRUC;					// The regions under construction that we move to					// the merged-to region's circular list.#ifdef PRINT_SEARCHBORDER				if (frame == 61)				{				fprintf (stderr, "Region to merge from:\n");				PrintRegion (*pRegionMergedFrom);				fprintf (stderr, "\n");				}#endif				// Merge the regions together.  (Merge() only works on				// regions that don't already intersect, for speed				// reasons; the way we manage the border ensures that.				// How handy for us.)				pRegionMergedTo->Merge (*pRegionMergedFrom);				// Run through the circular list of regions under				// construction, the ones pointing to the merged-from				// region, update each one to point to the merged-to				// region, and put each one into the merged-to region's				// circular list.				pCurrentRUC = pRegionUnderConstructionMergedFrom;				for (;;)				{					// Remember the next region in the circular list.					pNextRUC = pCurrentRUC->m_pForward;					// (Sanity check: make sure everyone in this					// circular list points to the same region.)					assert (pCurrentRUC->m_pRegion						== pRegionMergedFrom);					// Update the region it refers to.					pCurrentRUC->m_pRegion = pRegionMergedTo;					// Move it into the merged-to region's circular					// list.					pCurrentRUC->Remove();					pRegionUnderConstructionMergedTo->InsertBefore						(pRegionUnderConstructionMergedTo, pCurrentRUC);					// If all regions have been removed from this					// circular list, stop.					if (pCurrentRUC == pNextRUC)						break;					// Move to the next region in the circular list.					pCurrentRUC = pNextRUC;				}			}			// Finally, remove the startpoint/endpoint we found for this			// region, adjusting reference counts & cleaning up as			// necessary.			assert (m_setBorderEndpoints.LowerBound (*itEnd)				== itEnd);	// sanity			for (tnJ = 0; tnJ <= m_tnPGH; ++tnJ)				if (m_paitBorderEndpoints[tnJ] == itEnd)					++m_paitBorderEndpoints[tnJ];			m_setBorderEndpoints.Erase (itEnd);			assert (m_setBorderStartpoints.LowerBound (*itStart)				== itStart);	// sanity			for (tnJ = 0; tnJ <= m_tnPGH; ++tnJ)				if (m_paitBorderStartpoints[tnJ] == itStart)					++m_paitBorderStartpoints[tnJ];			m_setBorderStartpoints.Erase (itStart);			pRegionUnderConstructionMergedFrom->m_tnReferences -= 2;			if (pRegionUnderConstructionMergedFrom				!= pRegionUnderConstructionMergedTo			&& pRegionUnderConstructionMergedFrom->m_tnReferences == 0)			{				// This region under construction, now pointing to the				// merged-to region, has no more references to it.  Get				// rid of it.				assert (pRegionUnderConstructionMergedFrom->m_pRegion					== pRegionMergedTo);				assert (pRegionUnderConstructionMergedFrom->m_pForward					!= pRegionUnderConstructionMergedFrom);				pRegionUnderConstructionMergedFrom->Remove();				pRegionUnderConstructionMergedFrom->m_pRegion = NULL;			 	delete pRegionUnderConstructionMergedFrom;			}			// We're done with this region.			if (pRegionMergedFrom != pRegionMergedTo)				delete pRegionMergedFrom;			// Move to the next item in the set.			itHere = itNext;		}	}	// At this point, the region that contains the new pixel-group has	// either been created, or it's been retrieved from the	// possibly-intersecting set, and all regions that are contiguous	// with the new pixel-group have been merged into it.  But the new	// pixel-group hasn't been added yet in either case.	// Add the pixel-group's extents to this new/merged region.	{		PIXELINDEX tnY;			// Used to loop through the pixel-group's lines.#ifdef PRINTREGIONMATH		bool bRegionEmpty = ((pRegionMergedTo->NumberOfPoints() == 0)			? true : false);#endif // PRINTREGIONMATH		// Add each line in the pixel-group.		for (tnY = m_tnY; tnY < m_tnY + m_tnPGH; ++tnY)		{#ifdef PRINTREGIONMATH			//if (!bRegionEmpty /* && frame == 4 */)			{				fprintf (stderr, "Before Union with [%d, %d-%d]:\n",					int (tnY), int (m_tnX), int (m_tnX + m_tnPGW));				PrintRegion (*pRegionMergedTo);				fprintf (stderr, "\n");			}#endif // PRINTREGIONMATH			pRegionMergedTo->Union (a_reStatus, tnY, m_tnX,				m_tnX + m_tnPGW);			if (a_reStatus != g_kNoError)			{				// We couldn't add the new pixel-group.  If this				// region has no references, we have to delete it				// now.  (It could have no references because it's				// newly created, or because all references to it				// were removed from the search-border.)				if (pRegionUnderConstructionMergedTo->m_tnReferences					== 0)						goto cleanup2;				// Return with our error.				return 0;			}#ifdef PRINTREGIONMATH			//if (!bRegionEmpty /* && frame == 4 */)			{				fprintf (stderr, "After Union with [%d, %d-%d]:\n",					int (tnY), int (m_tnX), int (m_tnX + m_tnPGW));				PrintRegion (*pRegionMergedTo);				fprintf (stderr, "\n");				getchar();				fprintf (stderr, "\n");			}#endif // PRINTREGIONMATH		}	}#ifdef PRINT_SEARCHBORDER	if (frame == 61)	{	fprintf (stderr, "Final new/merged region:\n");	PrintRegion (*pRegionMergedTo);	fprintf (stderr, "\n");	}#endif	// Hook the new/merged region to our startpoints/endpoints.	for (tnI = 0; tnI <= m_tnPGH; ++tnI)		aStart[tnI].m_pRegion = aEnd[tnI].m_pRegion			= pRegionUnderConstructionMergedTo;	// Add all startpoint/endpoints to the current-boundary lines.	for (tnI = 0; tnI <= m_tnPGH; ++tnI)	{		// (If there is no last-border extent, skip adding the		// last-border startpoint/endpoint.)		if (tnI == 0 && !bLastBorderExtentFound)			continue;		// Add this startpoint to the current-boundary.		{			typename BorderExtentBoundarySet::InsertResult oInsertResult				= m_setBorderStartpoints.Insert (a_reStatus,					aStart[tnI]);			if (a_reStatus != g_kNoError)				goto cleanup5;			assert (oInsertResult.m_bInserted);				// Remember where it got inserted.			aitCurrentStarts[tnI] = oInsertResult.m_itPosition;				// That's one more reference to this region under			// construction.			++pRegionUnderConstructionMergedTo->m_tnReferences;			// If this new item was inserted before the current item on			// this line, and it's got an equivalent index value, it			// becomes the new current item.			if (m_tnStepX == 1)			{				++oInsertResult.m_itPosition;				for (tnJ = 0; tnJ <= m_tnPGH; ++tnJ)				{					if (m_paitBorderStartpoints[tnJ]						== oInsertResult.m_itPosition					&& ((*aitCurrentStarts[tnI]).m_tnLine						> m_tnY + tnJ - PIXELINDEX (1)					|| ((*aitCurrentStarts[tnI]).m_tnLine							== m_tnY + tnJ - PIXELINDEX (1)						&& (*aitCurrentStarts[tnI]).m_tnIndex							>= (m_tnX + m_tnPGW + 1 -								((tnJ == 0) ? 1 : 0)))))					{						--m_paitBorderStartpoints[tnJ];						assert (m_paitBorderStartpoints[tnJ]							== aitCurrentStarts[tnI]);					}				}			}			else			{				assert (m_tnStepX == -1);				++oInsertResult.m_itPosition;				for (tnJ = 0; tnJ <= m_tnPGH; ++tnJ)				{					if (m_paitBorderStartpoints[tnJ]						== oInsertResult.m_itPosition					&& ((*aitCurrentStarts[tnI]).m_tnLine						> m_tnY + tnJ - PIXELINDEX (1)					|| ((*aitCurrentStarts[tnI]).m_tnLine							== m_tnY + tnJ - PIXELINDEX (1)						&& (*aitCurrentStarts[tnI]).m_tnIndex							> (m_tnX + m_tnPGW								- ((tnJ == 0) ? 1 : 0)))))					{						--m_paitBorderStartpoints[tnJ];						assert (m_paitBorderStartpoints[tnJ]							== aitCurrentStarts[tnI]);					}				}			}		}			// Add this endpoint to the current-boundary.		{			typename BorderExtentBoundarySet::InsertResult oInsertResult				= m_setBorderEndpoints.Insert (a_reStatus, aEnd[tnI]);			if (a_reStatus != g_kNoError)				goto cleanup3;			assert (oInsertResult.m_bInserted);				// Remember where it got inserted.			aitCurrentEnds[tnI] = oInsertResult.m_itPosition;				// That's one more reference to this region under			// construction.			++pRegionUnderConstructionMergedTo->m_tnReferences;			// If this new item was inserted before the current item on			// this line, and it's got an equivalent index value, it			// becomes the new current item.			if (m_tnStepX == 1)			{				++oInsertResult.m_itPosition;				for (tnJ = 0; tnJ <= m_tnPGH; ++tnJ)				{					if (m_paitBorderEndpoints[tnJ]						== oInsertResult.m_itPosition					&& ((*aitCurrentEnds[tnI]).m_tnLine						> m_tnY + tnJ - PIXELINDEX (1)					|| ((*aitCurrentEnds[tnI]).m_tnLine							== m_tnY + tnJ - PIXELINDEX (1)						&& (*aitCurrentEnds[tnI]).m_tnIndex							>= (m_tnX + ((tnJ == 0) ? 1 : 0)))))					{						--m_paitBorderEndpoints[tnJ];						assert (m_paitBorderEndpoints[tnJ]							== aitCurrentEnds[tnI]);					}				}			}			else			{				++oInsertResult.m_itPosition;				for (tnJ = 0; tnJ <= m_tnPGH; ++tnJ)				{					if (m_paitBorderEndpoints[tnJ]						== oInsertResult.m_itPosition					&& ((*aitCurrentEnds[tnI]).m_tnLine						> m_tnY + tnJ - PIXELINDEX (1)					|| ((*aitCurrentEnds[tnI]).m_tnLine							== m_tnY + tnJ - PIXELINDEX (1)						&& (*aitCurrentEnds[tnI]).m_tnIndex							> (m_tnX - 1 + ((tnJ == 0) ? 1 : 0)))))					{						--m_paitBorderEndpoints[tnJ];						assert (m_paitBorderEndpoints[tnJ]							== aitCurrentEnds[tnI]);					}				}			}		}			// Now that startpoint & endpoint are inserted, we can set up		// their counterpart links.		(*aitCurrentStarts[tnI]).m_pCounterpart			= &(*aitCurrentEnds[tnI]);		(*aitCurrentEnds[tnI]).m_pCounterpart			= &(*aitCurrentStarts[tnI]);			// Add this region under construction to the list of regions		// that intersect with the current pixel-group.  (Since this		// new region contains the current pixel-group, obviously it		// intersects.)		{			typename IntersectingRegionsSet::InsertResult oInsertResult				= m_setBorderRegions.Insert (a_reStatus,					*(aitCurrentStarts[tnI]));			if (a_reStatus != g_kNoError)				goto cleanup4;			assert (oInsertResult.m_bInserted);				// Remember where it got inserted, in case the operation			// fails and we have to clean up after ourselves.			aitCurrentRegions[tnI] = oInsertResult.m_itPosition;	#ifdef PRINT_SEARCHBORDER			if (frame == 61)			{			fprintf (stderr, "Inserted border startpoint "				"(%d,%d), motion vector (%d,%d)\n",				(*aitCurrentRegions[tnI]).m_tnIndex,				(*aitCurrentRegions[tnI]).m_tnLine,				(*aitCurrentRegions[tnI]).m_tnMotionX,				(*aitCurrentRegions[tnI]).m_tnMotionY);			fprintf (stderr, "\tcorresponding endpoint at (%d,%d)\n",				(*aitCurrentEnds[tnI]).m_tnIndex,				(*aitCurrentEnds[tnI]).m_tnLine);			}#endif		}	}	// If this is the first added match, then the last-border startpoint	// and endpoint start off as one past the last item on its line,	// i.e. the first item on the next line, i.e. the first item in the	// set.	if (m_paitBorderStartpoints[0] == m_setBorderStartpoints.End()	&& m_paitBorderEndpoints[0] == m_setBorderEndpoints.End())	{#ifdef PRINT_SEARCHBORDER		if (frame == 61)		fprintf (stderr, "Initialized last-border "			"startpoint/endpoint.\n");#endif // PRINT_SEARCHBORDER		m_paitBorderStartpoints[0] = m_setBorderStartpoints.Begin();		m_paitBorderEndpoints[0] = m_setBorderEndpoints.Begin();	}	// All done.	return pRegionMergedTo->NumberOfPoints();	// Handle errors.cleanup5:	for (;;)	{		m_setBorderRegions.Erase (aitCurrentRegions[tnI]);cleanup4:		for (tnJ = 0; tnJ <= m_tnPGH; ++tnJ)			if (m_paitBorderEndpoints[tnJ] == aitCurrentEnds[tnI])				++m_paitBorderEndpoints[tnJ];		m_setBorderEndpoints.Erase (aitCurrentEnds[tnI]);		--pRegionUnderConstructionMergedTo->m_tnReferences;cleanup3:		for (tnJ = 0; tnJ <= m_tnPGH; ++tnJ)			if (m_paitBorderStartpoints[tnJ] == aitCurrentStarts[tnI])				++m_paitBorderStartpoints[tnJ];		m_setBorderStartpoints.Erase (aitCurrentStarts[tnI]);		--pRegionUnderConstructionMergedTo->m_tnReferences;		if (tnI == 0)			break;		--tnI;		if (m_tnY == 0 && tnI == 0)		// skip nonexistent last-borders			break;	}cleanup2:	if (pRegionUnderConstructionMergedTo->m_tnReferences == 0)	{		if (pRegionUnderConstructionMergedTo->m_pForward			== pRegionUnderConstructionMergedTo)				delete pRegionMergedTo;		pRegionUnderConstructionMergedTo->Remove();		pRegionUnderConstructionMergedTo->m_pRegion = NULL;		delete pRegionUnderConstructionMergedTo;	}	return 0;cleanup1:	delete pRegionMergedTo;cleanup0:	return 0;}// Remove all regions that matched the current pixel-group, except for// the single best one, and return it.template <class PIXELINDEX, class FRAMESIZE>typename SearchBorder<PIXELINDEX,FRAMESIZE>::MovedRegion *SearchBorder<PIXELINDEX,FRAMESIZE>::ChooseBestActiveRegion	(Status_t &a_reStatus){	RegionUnderConstruction *pUn

⌨️ 快捷键说明

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