📄 referenceframe.hh
字号:
// Calculate the vector difference between the two pixels. TOL tnX = TOL (m_atnVal[0]) - TOL (a_rOther.m_atnVal[0]); TOL tnY = TOL (m_atnVal[1]) - TOL (a_rOther.m_atnVal[1]); // Check to see if the length of the vector difference is within // our tolerance value. (Technically, we check the squares of // the values, but that's just as valid & much faster than // calculating a square root.) return tnX * tnX + tnY * tnY <= a_tnTolerance;}#endif// Return true if the two pixels are within the specified tolerance.template <>boolPixelCbCr::IsWithinTolerance (const PixelCbCr &a_rOther, int32_t a_tnTolerance) const{ // Calculate the vector difference between the two pixels. int32_t tnX = int32_t (m_atnVal[0]) - int32_t (a_rOther.m_atnVal[0]); int32_t tnY = int32_t (m_atnVal[1]) - int32_t (a_rOther.m_atnVal[1]); // Check to see if the length of the vector difference is within // our tolerance value. (Technically, we check the squares of // the values, but that's just as valid & much faster than // calculating a square root.) return tnX * tnX + tnY * tnY <= a_tnTolerance;}// Return true if the two pixels are within the specified tolerance.template <>boolPixelCbCr::IsWithinTolerance (const PixelCbCr &a_rOther, int32_t a_tnTolerance, int32_t &a_rtnSAD) const{ // Calculate the vector difference between the two pixels. int32_t tnX = int32_t (m_atnVal[0]) - int32_t (a_rOther.m_atnVal[0]); int32_t tnY = int32_t (m_atnVal[1]) - int32_t (a_rOther.m_atnVal[1]); // Calculate the sample-array-difference. a_rtnSAD = tnX * tnX + tnY * tnY; // Check to see if the length of the vector difference is within // our tolerance value. (Technically, we check the squares of // the values, but that's just as valid & much faster than // calculating a square root.) return a_rtnSAD <= a_tnTolerance;}// Default constructor.template <class ACCUM_NUM, class PIXEL_NUM, int DIM, class PIXEL>ReferencePixel<ACCUM_NUM,PIXEL_NUM,DIM,PIXEL>::ReferencePixel(){ // Reset the pixel value. Reset(); // No references from frames yet. m_nFrameReferences = 0;}// Destructor.template <class ACCUM_NUM, class PIXEL_NUM, int DIM, class PIXEL>ReferencePixel<ACCUM_NUM,PIXEL_NUM,DIM,PIXEL>::~ReferencePixel(){ // Make sure no frames refer to us. assert (m_nFrameReferences == 0);}// Reset ourselves, so that we may refer to a new pixel.template <class ACCUM_NUM, class PIXEL_NUM, int DIM, class PIXEL>voidReferencePixel<ACCUM_NUM,PIXEL_NUM,DIM,PIXEL>::Reset (void){ // Reset the accumulated sum. for (int i = 0; i < DIM; i++) m_atSum[i] = ACCUM_NUM (0); m_tCount = 0; // Get rid of any existing pixel value. m_oPixel.MakeInvalid();}// Incorporate another sample.template <class ACCUM_NUM, class PIXEL_NUM, int DIM, class PIXEL>voidReferencePixel<ACCUM_NUM,PIXEL_NUM,DIM,PIXEL>::AddSample (const PIXEL &a_rPixel){ // Make sure this pixel is in use. assert (m_nFrameReferences > 0); // TODO: detect & handle m_atSum[] overflowing. // HACK: do something cheesy to handle overflow. if (m_tCount >= 10) { for (int i = 0; i < DIM; i++) m_atSum[i] >>= 1; m_tCount >>= 1; } // Add the value to our accumulated sum. for (int i = 0; i < DIM; i++) m_atSum[i] += a_rPixel[i]; ++m_tCount; // Remember that the pixel value needs to be recalculated. m_oPixel.MakeInvalid();}// Return the pixel's value.template <class ACCUM_NUM, class PIXEL_NUM, int DIM, class PIXEL>const PIXEL &ReferencePixel<ACCUM_NUM,PIXEL_NUM,DIM,PIXEL>::GetValue (void){ // Make sure this pixel is in use. assert (m_nFrameReferences > 0); // If we have to recalculate the pixel value, do so. if (m_oPixel.IsPixelInvalid()) { static float afDivisors[] = { 0.0f, 1.0f, 1.0f / 2.0f, 1.0f / 3.0f, 1.0f / 4.0f, 1.0f / 5.0f, 1.0f / 6.0f, 1.0f / 7.0f, 1.0f / 8.0f, 1.0f / 9.0f, 1.0f / 10.0f }; // HACK: try to speed this up. // Calculate the pixel's value. if (m_tCount <= 10) { for (int i = 0; i < DIM; i++) m_oPixel[i] = PIXEL_NUM ((float (m_atSum[i]) * afDivisors[m_tCount]) + 0.5f); } else { for (int i = 0; i < DIM; i++) m_oPixel[i] = PIXEL_NUM ((float (m_atSum[i]) / float (m_tCount)) + 0.5f); } } // Give our caller the pixel value. return m_oPixel;}// Default constructor.template <class REFERENCEPIXEL, class FRAMESIZE>PixelAllocator<REFERENCEPIXEL,FRAMESIZE>::PixelAllocator(){ // No pixels yet. m_tnCount = m_tnNext = 0; m_pPixels = NULL;}// Destructor.template <class REFERENCEPIXEL, class FRAMESIZE>PixelAllocator<REFERENCEPIXEL,FRAMESIZE>::~PixelAllocator(){ // Free up the pixel pool. (The pixels themselves will verify that // there are no more references to them.) delete[] m_pPixels;}// Initialize the pool to contain the given number of pixels.template <class REFERENCEPIXEL, class FRAMESIZE>voidPixelAllocator<REFERENCEPIXEL,FRAMESIZE>::Initialize (Status_t &a_reStatus, FRAMESIZE a_tnCount){ // Make sure they didn't start us off with an error. assert (a_reStatus == g_kNoError); // Make sure we haven't been initialized already. assert (m_pPixels == NULL); // Try to allocate a pool of the given number of pixels. m_pPixels = new REFERENCEPIXEL[a_tnCount]; if (m_pPixels == NULL) { a_reStatus = g_kOutOfMemory; return; } // Remember that we allocated this many pixels. m_tnCount = a_tnCount; // Allocate the first pixel first. m_tnNext = 0;}// Allocate another pixel.template <class REFERENCEPIXEL, class FRAMESIZE>REFERENCEPIXEL *PixelAllocator<REFERENCEPIXEL,FRAMESIZE>::Allocate (void){ FRAMESIZE tnOrigNext; // The original value of the index of the next pixel to // allocate. Used to detect when we've run through all of // them. REFERENCEPIXEL *pPixel; // The pixel we allocate. // Loop through the pixel pool, find an unallocated one, return it // to them. tnOrigNext = m_tnNext; for (;;) { // Get the next pixel. pPixel = m_pPixels + m_tnNext; m_tnNext = (m_tnNext + 1) % m_tnCount; // If this pixel is unallocated, reset it & return it. if (pPixel->GetFrameReferences() == 0) { pPixel->Reset(); return pPixel; } // Make sure we haven't run out of pixels. (Returning NULL // may cause a segmentation fault in our client, but that's // slightly better than an infinite loop.) if (m_tnNext == tnOrigNext) { assert (false); return NULL; } }}// Initializing constructor.template <class REFERENCEPIXEL, class PIXELINDEX, class FRAMESIZE>ReferenceFrame<REFERENCEPIXEL,PIXELINDEX,FRAMESIZE>::ReferenceFrame (Status_t &a_reStatus, PIXELINDEX a_tnWidth, PIXELINDEX a_tnHeight){ FRAMESIZE tnPixels; // The total number of pixels referred to by this frame. FRAMESIZE i; // Used to loop through pixel references. // Make sure they didn't start us off with an error. assert (a_reStatus == g_kNoError); // Make sure the height and width are sane. assert (a_tnWidth > 0); assert (a_tnHeight > 0); // Allocate space for the frame's pixels. tnPixels = FRAMESIZE (a_tnWidth) * FRAMESIZE (a_tnHeight); m_ppPixels = new REFERENCEPIXEL * [tnPixels]; if (m_ppPixels == NULL) { a_reStatus = g_kOutOfMemory; return; } // Remember our dimensions. m_tnWidth = a_tnWidth; m_tnHeight = a_tnHeight; // Initially, no pixels are referred to by the frame. for (i = 0; i < tnPixels; i++) m_ppPixels[i] = NULL;}// Get the pixel at this index (which may be NULL).template <class REFERENCEPIXEL, class PIXELINDEX, class FRAMESIZE>REFERENCEPIXEL *ReferenceFrame<REFERENCEPIXEL,PIXELINDEX,FRAMESIZE>::GetPixel (PIXELINDEX a_tnX, PIXELINDEX a_tnY) const{ // Make sure the indices are within limits. assert (a_tnX >= PIXELINDEX (0) && a_tnX < m_tnWidth); assert (a_tnY >= PIXELINDEX (0) && a_tnY < m_tnHeight); // Easy enough. return m_ppPixels[FRAMESIZE (a_tnY) * FRAMESIZE (m_tnWidth) + FRAMESIZE (a_tnX)];}// Get the pixel at this offset (which may be NULL).template <class REFERENCEPIXEL, class PIXELINDEX, class FRAMESIZE>REFERENCEPIXEL *ReferenceFrame<REFERENCEPIXEL,PIXELINDEX,FRAMESIZE>::GetPixel (FRAMESIZE a_tnI) const{ // Make sure the offset is within limits. assert (a_tnI >= FRAMESIZE (0) && a_tnI < FRAMESIZE (m_tnWidth) * FRAMESIZE (m_tnHeight)); // Easy enough. return m_ppPixels[a_tnI];}// Set the pixel at this index. a_pPixel may be NULL.template <class REFERENCEPIXEL, class PIXELINDEX, class FRAMESIZE>voidReferenceFrame<REFERENCEPIXEL,PIXELINDEX,FRAMESIZE>::SetPixel (PIXELINDEX a_tnX, PIXELINDEX a_tnY, REFERENCEPIXEL *a_pPixel){ // Make sure the indices are within limits. assert (a_tnX >= PIXELINDEX (0) && a_tnX < m_tnWidth); assert (a_tnY >= PIXELINDEX (0) && a_tnY < m_tnHeight); // Get the pixel of interest. REFERENCEPIXEL *&rpPixel = m_ppPixels[FRAMESIZE (a_tnY) * FRAMESIZE (m_tnWidth) + FRAMESIZE (a_tnX)]; // If there's a pixel here already, remove our reference to it. if (rpPixel != NULL) rpPixel->RemoveFrameReference(); // Store the new pixel here. rpPixel = a_pPixel; // If they stored a valid pixel, add our reference to it. if (rpPixel != NULL) rpPixel->AddFrameReference();}// Set the pixel at this offset. a_pPixel may be NULL.template <class REFERENCEPIXEL, class PIXELINDEX, class FRAMESIZE>voidReferenceFrame<REFERENCEPIXEL,PIXELINDEX,FRAMESIZE>::SetPixel (FRAMESIZE a_tnI, REFERENCEPIXEL *a_pPixel){ // Make sure the offset is within limits. assert (a_tnI >= FRAMESIZE (0) && a_tnI < FRAMESIZE (m_tnWidth) * FRAMESIZE (m_tnHeight)); // Get the pixel of interest. REFERENCEPIXEL *&rpPixel = m_ppPixels[a_tnI]; // If there's a pixel here already, remove our reference to it. if (rpPixel != NULL) rpPixel->RemoveFrameReference(); // Store the new pixel here. rpPixel = a_pPixel; // If they stored a valid pixel, add our reference to it. if (rpPixel != NULL) rpPixel->AddFrameReference();}// Reset the frame (i.e. set all the pixels to NULL).template <class REFERENCEPIXEL, class PIXELINDEX, class FRAMESIZE>voidReferenceFrame<REFERENCEPIXEL,PIXELINDEX,FRAMESIZE>::Reset (void){ FRAMESIZE tnPixels; // The total number of pixels referred to by this frame. FRAMESIZE i; // Used to loop through pixels. // Loop through all pixels, set them to NULL. tnPixels = FRAMESIZE (m_tnWidth) * FRAMESIZE (m_tnHeight); for (i = 0; i < tnPixels; ++i) { // If there's a pixel here already, remove our reference to it, // then remove the pixel. if (m_ppPixels[i] != NULL) { m_ppPixels[i]->RemoveFrameReference(); m_ppPixels[i] = NULL; } }}#endif // __REFERENCE_FRAME_H__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -