bitmapregion2d.hh

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

HH
1,442
字号
				if (a_reStatus != g_kNoError)					return;				// Look for another extent.				bStartedExtent = false;			}		}nextExtent:		// Move to the next extent.		++itExtent;		// If the to-do list needs to be replenished, do so.		if (itExtent == a_rControl.m_oToDo.End())		{			// Replenish the to-do list.			a_rControl.m_oNextToDo.Subtract (a_reStatus,				a_rControl.m_oAlreadyDone);			if (a_reStatus != g_kNoError)				return;			a_rControl.m_oToDo.Clear();			a_rControl.m_oToDo.Merge (a_rControl.m_oNextToDo);						// Start over at the beginning.			itExtent = a_rControl.m_oToDo.Begin();		}	}}// Make the current region represent the border of the other// region, i.e. every pixel that borders the region but isn't// already in the region.template <class INDEX, class SIZE>template <class OTHER>voidBitmapRegion2D<INDEX,SIZE>::MakeBorder (Status_t &a_reStatus,	const OTHER &a_rOther){	typename OTHER::ConstIterator itExtent;		// Used to loop through the other region's extents.	// Make sure they didn't start us off with an error.	assert (a_reStatus == g_kNoError);	// Start with an empty region.	Clear();	// For every extent in the other region, add every surrounding	// extent.  That creates a region that looks like the other region,	// but also contains the border we're after.	for (itExtent = a_rOther.Begin();		 itExtent != a_rOther.End();		 ++itExtent)	{		// Add the surrounding extents.		UnionSurroundingExtents (a_reStatus, (*itExtent).m_tnY,			(*itExtent).m_tnXStart, (*itExtent).m_tnXEnd);		if (a_reStatus != g_kNoError)			return;	}	// Finally, subtract the other region.  That punches a hole in us,	// and creates the border region we're after.	Subtract (a_reStatus, a_rOther);	if (a_reStatus != g_kNoError)		return;}// Add all extents surrounding the given extent.  Used by FloodFill().template <class INDEX, class SIZE>voidBitmapRegion2D<INDEX,SIZE>::UnionSurroundingExtents	(Status_t &a_reStatus, INDEX a_tnY, INDEX a_tnXStart,	INDEX a_tnXEnd){	// Make sure they didn't start us off with an error.	assert (a_reStatus == g_kNoError);	// Add the extent above this one.	if (a_tnY > 0)	{		Union (a_reStatus, a_tnY - 1, a_tnXStart, a_tnXEnd);		if (a_reStatus != g_kNoError)			return;	}	// Add the extent to the left.	if (a_tnXStart > 0)	{		Union (a_reStatus, a_tnY, a_tnXStart - 1, a_tnXStart);		if (a_reStatus != g_kNoError)			return;	}	// Add the extent to the right.	if (a_tnXEnd < m_tnWidth)	{		Union (a_reStatus, a_tnY, a_tnXEnd, a_tnXEnd + 1);		if (a_reStatus != g_kNoError)			return;	}	// Add the extent below this one.	if (a_tnY < m_tnWidth - 1)	{		Union (a_reStatus, a_tnY + 1, a_tnXStart, a_tnXEnd);		if (a_reStatus != g_kNoError)			return;	}}// Move one of our iterators forward.template <class INDEX, class SIZE>voidBitmapRegion2D<INDEX,SIZE>::IteratorForward	(ConstIterator &a_ritHere) const{	SIZE tnWordIndex, tnBitIndex;		// The word/bit index that corresponds to the x/y pixel index.	SIZE tnLastWordIndex, tnLastBitIndex;		// The word/bit index for the last pixel in the current line.	unsigned int nWord;		// A bitmap word being examined.	unsigned int nMask;		// A bitmask we generate.	// We'll start looking for a new extent after the end of the old	// extent.  Find the word/bit index for that, and the word itself.	tnBitIndex = SIZE (a_ritHere.m_oExtent.m_tnY) * SIZE (m_tnWidth)		+ SIZE (a_ritHere.m_oExtent.m_tnXEnd);	tnWordIndex = tnBitIndex >> Limits<unsigned int>::Log2Bits;	tnBitIndex -= tnWordIndex << Limits<unsigned int>::Log2Bits;	nWord = m_pnPoints[tnWordIndex];	// Skip all clear bits.  First check the current word to see if the	// rest of its bits are clear, then skip over all all-clear words.	if ((nWord & ((~0U) << tnBitIndex)) == 0U)	{		// The rest of the current word's bits are clear.		++tnWordIndex;		tnBitIndex = 0;		// Skip over all all-clear words.		while (tnWordIndex < m_tnBitmapInts				&& m_pnPoints[tnWordIndex] == 0U)			++tnWordIndex;		// If we reached the end of the bitmap, let our caller know.		if (tnWordIndex == m_tnBitmapInts)		{			a_ritHere = End();			return;		}		// Get the current word.		nWord = m_pnPoints[tnWordIndex];	}	// Look for the next set bit in the current word.	tnBitIndex = FindFirstSetBit (nWord, tnBitIndex);	// Calculate the x/y index of this first set bit, and the word/bit	// index of the end of the line.	tnLastBitIndex = tnWordIndex * Limits<unsigned int>::Bits		+ tnBitIndex;	a_ritHere.m_oExtent.m_tnY = INDEX (tnLastBitIndex / m_tnWidth);	a_ritHere.m_oExtent.m_tnXStart = tnLastBitIndex		- SIZE (a_ritHere.m_oExtent.m_tnY) * SIZE (m_tnWidth);	tnLastBitIndex = SIZE (a_ritHere.m_oExtent.m_tnY + 1)		* SIZE (m_tnWidth);	tnLastWordIndex = tnLastBitIndex >> Limits<unsigned int>::Log2Bits;	tnLastBitIndex -= tnLastWordIndex << Limits<unsigned int>::Log2Bits;	// Skip all set bits.  First check the current word to see if the	// rest of its bits are set, then skip over all all-set words.	nMask = ((~0U) << tnBitIndex);	if ((nWord & nMask) == nMask)	{		// The rest of the current word's bits are set.		++tnWordIndex;		tnBitIndex = 0;		// Skip over all all-set words.		while (tnWordIndex <= tnLastWordIndex				&& tnWordIndex < m_tnBitmapInts				&& m_pnPoints[tnWordIndex] == (~0U))			++tnWordIndex;		// If we reached the end of the line, let our caller know.		if (tnWordIndex > tnLastWordIndex)		{			a_ritHere.m_oExtent.m_tnXEnd = m_tnWidth;			return;		}		// Get the current word.		nWord = m_pnPoints[tnWordIndex];	}	// Look for the next clear bit in the current word.	tnBitIndex = FindFirstClearBit (nWord, tnBitIndex);	// Clip it to the end of the line.	if (tnWordIndex == tnLastWordIndex			&& tnBitIndex > tnLastBitIndex)		tnBitIndex = tnLastBitIndex;	// Calculate the x index of this first clear bit; it becomes the	// end of the extent.	tnLastBitIndex = tnWordIndex * Limits<unsigned int>::Bits		+ tnBitIndex;	a_ritHere.m_oExtent.m_tnXEnd = tnLastBitIndex		- SIZE (a_ritHere.m_oExtent.m_tnY) * SIZE (m_tnWidth);	assert (a_ritHere.m_oExtent.m_tnXEnd <= m_tnWidth);}// Move one of our iterators backward.template <class INDEX, class SIZE>voidBitmapRegion2D<INDEX,SIZE>::IteratorBackward	(ConstIterator &a_ritHere) const{	// Not written yet.	assert (false);}// Find the first set bit.template <class INDEX, class SIZE>intBitmapRegion2D<INDEX,SIZE>::FindFirstSetBit (unsigned int a_nWord,	int a_nSkip){	int nLow, nHigh;		// The search range.		// Skip the first a_nSkip bits by clearing them.	a_nWord &= ((~0U) << a_nSkip);		// Make sure at least one bit is set.	assert (a_nWord != 0U);	// Find the range of all-clear LSB bits, i.e. the highest index	// such that it and all lower-index bits are zero.	nLow = 0;	// faster than nLow = a_nSkip?	nHigh = Limits<unsigned int>::Bits - 1;	while (nLow < nHigh)	{		// Look in the middle.		int nCurrent = (nLow + nHigh) >> 1;		// Generate a mask where bits 0-nCurrent are all set, and		// the remaining bits are clear.		unsigned int nCurrentMask = ~((~0U) << (nCurrent + 1));		// If the nCurrent LSB bits are all clear, look above nCurrent,		// otherwise look below nCurrent.		if ((a_nWord & nCurrentMask) == 0U)			nLow = nCurrent + 1;		else			nHigh = nCurrent;	}	// Return the index of the first set bit.	assert (nLow == nHigh);	return nLow;}// Find the first clear bit.template <class INDEX, class SIZE>intBitmapRegion2D<INDEX,SIZE>::FindFirstClearBit (unsigned int a_nWord,	int a_nSkip){	int nLow, nHigh;		// The search range.		// Skip the first a_nSkip bits by setting them.	a_nWord |= ~((~0U) << a_nSkip);		// Make sure at least one bit is clear.	assert (a_nWord != (~0U));	// Find the range of all-set LSB bits.	nLow = 0;	// faster than nLow = a_nSkip?	nHigh = Limits<unsigned int>::Bits - 1;	while (nLow < nHigh)	{		// Look in the middle.		int nCurrent = (nLow + nHigh) >> 1;		// Generate a mask where bits 0-nCurrent are all set, and		// the remaining bits are clear.		unsigned int nCurrentMask = ~((~0U) << (nCurrent + 1));		// If the nCurrent LSB bits are all set, look above nCurrent,		// otherwise look below nCurrent.		if ((a_nWord & nCurrentMask) == nCurrentMask)			nLow = nCurrent + 1;		else			nHigh = nCurrent;	}	// Return the index of the first clear bit.	assert (nLow == nHigh);	return nLow;}// Find the last set bit.template <class INDEX, class SIZE>intBitmapRegion2D<INDEX,SIZE>::FindLastSetBit (unsigned int a_nWord,	int a_nSkip){	// Not written yet.	assert (false);}// Find the last clear bit.template <class INDEX, class SIZE>intBitmapRegion2D<INDEX,SIZE>::FindLastClearBit (unsigned int a_nWord,	int a_nSkip){	// Not written yet.	assert (false);}// Get the first extent in the region.template <class INDEX, class SIZE>typename BitmapRegion2D<INDEX,SIZE>::ConstIteratorBitmapRegion2D<INDEX,SIZE>::Begin (void) const{	ConstIterator itBegin;		// The iterator we construct.		// Start before the beginning of this region.	itBegin.m_pThis = this;	itBegin.m_oExtent.m_tnY = 0;	itBegin.m_oExtent.m_tnXStart = 0;	itBegin.m_oExtent.m_tnXEnd = 0;		// Move to the first valid extent & return it.	return ++itBegin;}// Get one past the last extent in the region.template <class INDEX, class SIZE>typename BitmapRegion2D<INDEX,SIZE>::ConstIteratorBitmapRegion2D<INDEX,SIZE>::End (void) const{	ConstIterator itEnd;		// The iterator we construct.		// Since extents can't be zero-length, a zero-length extent	// indicates the end.	itEnd.m_pThis = this;	itEnd.m_oExtent.m_tnY = 0;	itEnd.m_oExtent.m_tnXStart = 0;	itEnd.m_oExtent.m_tnXEnd = 0;	return itEnd;}// Move forward to the next extent.template <class INDEX, class SIZE>typename BitmapRegion2D<INDEX,SIZE>::ConstIterator&BitmapRegion2D<INDEX,SIZE>::ConstIterator::operator++(){	// Make sure we know what region we're iterating through.	assert (m_pThis != NULL);	// It does all the work.	m_pThis->IteratorForward (*this);	return *this;}// Move backward to the previous extent.template <class INDEX, class SIZE>typename BitmapRegion2D<INDEX,SIZE>::ConstIterator&BitmapRegion2D<INDEX,SIZE>::ConstIterator::operator--(){	// Make sure we know what region we're iterating through.	assert (m_pThis != NULL);	// It does all the work.	m_pThis->IteratorBackward (*this);	return *this;}	// The set-bits-per-byte table.// Used to implement NumberOfPoints().template <class INDEX, class SIZE>int8_t BitmapRegion2D<INDEX,SIZE>::m_anSetBitsPerByte[256];template <class INDEX, class SIZE>bool BitmapRegion2D<INDEX,SIZE>::m_bSetBitsPerByte = false;// Default constructor.  Must be followed by a call to Init().template <class INDEX, class SIZE>BitmapRegion2D<INDEX,SIZE>::FloodFillControl::FloodFillControl(){	// Nothing to do.}// Initializing constructor.template <class INDEX, class SIZE>BitmapRegion2D<INDEX,SIZE>::FloodFillControl::FloodFillControl	(Status_t &a_reStatus, INDEX a_tnWidth, INDEX a_tnHeight){	// Make sure they didn't start us off with an error.	assert (a_reStatus == g_kNoError);	// Initialize ourselves.	Init (a_reStatus, a_tnWidth, a_tnHeight);	if (a_reStatus != g_kNoError)		return;}// Initializer.  Must be called on default-constructed objects.template <class INDEX, class SIZE>voidBitmapRegion2D<INDEX,SIZE>::FloodFillControl::Init	(Status_t &a_reStatus, INDEX a_tnWidth, INDEX a_tnHeight){	// Make sure they didn't start us off with an error.	assert (a_reStatus == g_kNoError);	// Initialize our helper regions.	BitmapRegion2D<INDEX,SIZE>::FloodFillControl::m_oToDo.Init (a_reStatus, a_tnWidth, a_tnHeight);	if (a_reStatus != g_kNoError)		return;	BitmapRegion2D<INDEX,SIZE>::FloodFillControl::m_oAlreadyDone.Init (a_reStatus, a_tnWidth, a_tnHeight);	if (a_reStatus != g_kNoError)		return;	BitmapRegion2D<INDEX,SIZE>::FloodFillControl::m_oNextToDo.Init (a_reStatus, a_tnWidth, a_tnHeight);	if (a_reStatus != g_kNoError)		return;}#ifndef NDEBUGtemplate <class INDEX, class SIZE>uint32_t BitmapRegion2D<INDEX,SIZE>::sm_ulInstances;#endif // NDEBUG#endif // __BITMAPREGION2D_H__

⌨️ 快捷键说明

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