namespace
{
+
+ inline ptrdiff_t getAbs (const ptrdiff_t theValue)
+ {
+ return theValue >= 0 ? theValue : -theValue;
+ }
+
static const Standard_Size NEIGHBOR_PIXELS_NB = 8;
struct
{
return ::isBlack (theData.Value (theRowCenter + Standard_Size(row_inc),
theColCenter + Standard_Size(col_inc)));
}
+
+ inline bool isValid (const Image_PixMapData<Image_ColorRGB>& theData,
+ const Standard_Size theRowCenter,
+ const Standard_Size theColCenter) const
+ {
+ const Standard_Size aRow = theRowCenter + Standard_Size(row_inc);
+ const Standard_Size aCol = theColCenter + Standard_Size(col_inc);
+ return aRow < theData.SizeX() // this unsigned math checks Standard_Size(-1) at-once
+ && aCol < theData.SizeY();
+ }
}
static const NEIGHBOR_PIXELS[NEIGHBOR_PIXELS_NB] =
{
{
const Standard_Size aValue2 = myDiffPixels.Value (aPixelId2);
int2Pixel (aValue2, aRow2, aCol2);
- if (std::abs (ptrdiff_t (aCol1 - aCol2)) <= 1 &&
- std::abs (ptrdiff_t (aRow1 - aRow2)) <= 1)
+ if (getAbs (ptrdiff_t (aCol1 - aCol2)) <= 1 &&
+ getAbs (ptrdiff_t (aRow1 - aRow2)) <= 1)
{
// A neighbour is found. Create a new group and add both pixels.
if (myGroupsOfDiffPixels.IsEmpty())
// check all neighbour pixels on presence in the group
for (Standard_Size aNgbrIter = 0; aNgbrIter < NEIGHBOR_PIXELS_NB; ++aNgbrIter)
{
- if (aGroup->Contains (NEIGHBOR_PIXELS[aNgbrIter].pixel2Int (aRow1, aCol1)))
+ if (NEIGHBOR_PIXELS[aNgbrIter].isValid (aDataRef, aRow1, aCol1)
+ && aGroup->Contains (NEIGHBOR_PIXELS[aNgbrIter].pixel2Int (aRow1, aCol1)))
{
++aNeighboursNb;
}
aNeighboursNb = 0;
for (Standard_Size aNgbrIter = 0; aNgbrIter < NEIGHBOR_PIXELS_NB; ++aNgbrIter)
{
- if (!NEIGHBOR_PIXELS[aNgbrIter].isBlack (aDataRef, aRow1, aCol1))
+ if ( NEIGHBOR_PIXELS[aNgbrIter].isValid (aDataRef, aRow1, aCol1)
+ && !NEIGHBOR_PIXELS[aNgbrIter].isBlack (aDataRef, aRow1, aCol1))
{
++aNeighboursNb;
}
//! In this case the whole group of pixels is ignored (considered as same).
//! Otherwise, the group of pixels may represent a geometrical curve in the viewer 3D
//! and should be considered as "different".
+//!
+//! References:
+//! 1. http://pdiff.sourceforge.net/ypg01.pdf
+//! 2. http://pdiff.sourceforge.net/metric.html
+//! 3. http://www.cs.ucf.edu/~sumant/publications/sig99.pdf
+//! 4. http://www.worldscientific.com/worldscibooks/10.1142/2641#t=toc (there is a list of articles and books in PDF format)
+
class Image_Diff : public Standard_Transient
{
#include <Image_PixMap.hxx>
-#ifndef _MSC_VER
+#ifdef _MSC_VER
+ //
+#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
#include <mm_malloc.h>
+#else
+ extern "C" int posix_memalign (void** thePtr, size_t theAlign, size_t theBytesCount);
#endif
template<typename TypePtr>
{
#if defined(_MSC_VER)
return (TypePtr )_aligned_malloc (theBytesCount, theAlign);
-#else
+#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
return (TypePtr ) _mm_malloc (theBytesCount, theAlign);
+#else
+ void* aPtr;
+ if (posix_memalign (&aPtr, theAlign, theBytesCount))
+ {
+ aPtr = NULL;
+ }
+ return (TypePtr )aPtr;
#endif
}
{
#if defined(_MSC_VER)
_aligned_free (thePtrAligned);
-#else
+#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
_mm_free (thePtrAligned);
+#else
+ free (thePtrAligned);
#endif
}