]> OCCT Git - occt.git/commitdiff
0023425: diffimage generate OSD_Exception during execution
authorkgv <kgv@opencascade.com>
Thu, 27 Sep 2012 08:43:54 +0000 (12:43 +0400)
committerkgv <kgv@opencascade.com>
Thu, 27 Sep 2012 08:43:54 +0000 (12:43 +0400)
diffimage out-of-image access during border filter execution

Verify neighbor pixel position for out-of-image access
A list of referenced articles and books is added to Image_Diff.hxx file.

Adding test case bugs/vis/CR23425

Image_Diff - fix compilation error on x86_64 target using msvc
There no std::abs for ptrdiff_t in Microsoft STL implementation

Image_PixMap - fixed compilation on gcc 3

Removed extra newlines in TCL script
Image_Diff, move back extra modifications

src/Image/Image_Diff.cxx
src/Image/Image_Diff.hxx
src/Image/Image_PixMap.cxx
tests/bugs/vis/CR23425 [new file with mode: 0755]

index 5b28f18124b0bf4d4edd0ee035b5b6bb9a40a486..f9249ee87693531439510054fdef4bdff72fa9e6 100644 (file)
@@ -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<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] =
   {
@@ -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;
         }
index 1f1541c6beb3b0052a6d3c2cf823662d75a938f7..53235e603b85e3dc66162b08095df7f01227c29c 100644 (file)
 //!     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
 {
 
index 14b3f2ac6d56dfedeb507cd0e63adb3d8f548a30..d8237640aa063c5bca934c28eeee02267b9dc38c 100644 (file)
 
 #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>
@@ -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 (executable)
index 0000000..e412f8f
--- /dev/null
@@ -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