diff --git a/src/Image/Image_Diff.cxx b/src/Image/Image_Diff.cxx index 5b28f18124..f9249ee876 100644 --- a/src/Image/Image_Diff.cxx +++ b/src/Image/Image_Diff.cxx @@ -63,6 +63,12 @@ inline void int2Pixel (const Standard_Size theValue, namespace { + + inline ptrdiff_t getAbs (const ptrdiff_t theValue) + { + return theValue >= 0 ? theValue : -theValue; + } + static const Standard_Size NEIGHBOR_PIXELS_NB = 8; struct { @@ -83,6 +89,16 @@ namespace return ::isBlack (theData.Value (theRowCenter + Standard_Size(row_inc), theColCenter + Standard_Size(col_inc))); } + + inline bool isValid (const Image_PixMapData& 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] = { @@ -408,8 +424,8 @@ Standard_Integer Image_Diff::ignoreBorderEffect() { 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()) @@ -463,7 +479,8 @@ Standard_Integer Image_Diff::ignoreBorderEffect() // 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; } @@ -485,7 +502,8 @@ Standard_Integer Image_Diff::ignoreBorderEffect() 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; } diff --git a/src/Image/Image_Diff.hxx b/src/Image/Image_Diff.hxx index 1f1541c6be..53235e603b 100644 --- a/src/Image/Image_Diff.hxx +++ b/src/Image/Image_Diff.hxx @@ -52,6 +52,13 @@ //! 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 { diff --git a/src/Image/Image_PixMap.cxx b/src/Image/Image_PixMap.cxx index 14b3f2ac6d..d8237640aa 100644 --- a/src/Image/Image_PixMap.cxx +++ b/src/Image/Image_PixMap.cxx @@ -19,8 +19,12 @@ #include -#ifndef _MSC_VER +#ifdef _MSC_VER + // +#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1) #include +#else + extern "C" int posix_memalign (void** thePtr, size_t theAlign, size_t theBytesCount); #endif template @@ -29,8 +33,15 @@ inline TypePtr MemAllocAligned (const Standard_Size& theBytesCount, { #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 } @@ -38,8 +49,10 @@ inline void MemFreeAligned (void* thePtrAligned) { #if defined(_MSC_VER) _aligned_free (thePtrAligned); -#else +#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1) _mm_free (thePtrAligned); +#else + free (thePtrAligned); #endif } diff --git a/tests/bugs/vis/CR23425 b/tests/bugs/vis/CR23425 new file mode 100755 index 0000000000..e412f8f089 --- /dev/null +++ b/tests/bugs/vis/CR23425 @@ -0,0 +1,10 @@ +puts "============" +puts "CR23425" +puts "============" +puts "" +####################################################################### +# diffimage generate OSD_Exception during execution +####################################################################### + +diffimage [locate_data_file CR23425-B8_Linux.gif] [locate_data_file CR23425-B8_Win.gif] 0.01 0 1 +diffimage [locate_data_file CR23425-B8_Win.gif] [locate_data_file CR23425-B8_Linux.gif] 0.01 0 1