Merge pull request #21083 from OrestChura:oc/fix_coverity_vino_issues
authorOrest Chura <orest.chura@intel.com>
Fri, 26 Nov 2021 16:40:36 +0000 (19:40 +0300)
committerGitHub <noreply@github.com>
Fri, 26 Nov 2021 16:40:36 +0000 (16:40 +0000)
[G-API] Fixed Coverity issues

* Fixed Coverity issues
 - VectorRef&OpaqueRef m_kind = CV_UNKNOWN
 - added same-type overload for saturate()
 - sanitized resize value in ByteMemoryInStream::operator>> (std::string& str)
 - handled throws from ~GStreamingExecutor()

* Catching exception by const ref

* Addressing Sergey's comments

* Applied enable_if semanitcs to saturate(x, round) too

* Removed uncaught_exception, made destructor noexcept back

* Split Fluid ConvertTo to multiple functions to avoid ifs; added CV_ALWAYS_INLINE

* Added FIXME to address throwings from stop()

* Fix standalone

* Addressing comments

* Guarded SIMD optimizations properly

* Removed excess parameter from simd_impl functions

modules/gapi/include/opencv2/gapi/garray.hpp
modules/gapi/include/opencv2/gapi/gopaque.hpp
modules/gapi/include/opencv2/gapi/own/cvdefs.hpp
modules/gapi/include/opencv2/gapi/own/saturate.hpp
modules/gapi/src/backends/common/serialization.cpp
modules/gapi/src/backends/fluid/gfluidcore.cpp
modules/gapi/src/executor/gstreamingexecutor.cpp

index d7b365f..17b0333 100644 (file)
@@ -236,7 +236,7 @@ namespace detail
     class VectorRef
     {
         std::shared_ptr<BasicVectorRef> m_ref;
-        cv::detail::OpaqueKind m_kind;
+        cv::detail::OpaqueKind m_kind = cv::detail::OpaqueKind::CV_UNKNOWN;
 
         template<typename T> inline void check() const
         {
index 979a9db..f77795c 100644 (file)
@@ -232,7 +232,7 @@ namespace detail
     class OpaqueRef
     {
         std::shared_ptr<BasicOpaqueRef> m_ref;
-        cv::detail::OpaqueKind m_kind;
+        cv::detail::OpaqueKind m_kind = cv::detail::OpaqueKind::CV_UNKNOWN;
 
         template<typename T> inline void check() const
         {
index 9ec0f89..b0c91d3 100644 (file)
@@ -84,6 +84,16 @@ typedef unsigned short ushort;
 
 // cvdef.h:
 
+#ifndef CV_ALWAYS_INLINE
+#  if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+#    define CV_ALWAYS_INLINE inline __attribute__((always_inline))
+#  elif defined(_MSC_VER)
+#    define CV_ALWAYS_INLINE __forceinline
+#  else
+#    define CV_ALWAYS_INLINE inline
+#  endif
+#endif
+
 #define CV_MAT_CN_MASK          ((CV_CN_MAX - 1) << CV_CN_SHIFT)
 #define CV_MAT_CN(flags)        ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1)
 #define CV_MAT_TYPE_MASK        (CV_DEPTH_MAX*CV_CN_MAX - 1)
index 5b23247..74eaecf 100644 (file)
@@ -11,9 +11,9 @@
 #include <math.h>
 
 #include <limits>
-#include <type_traits>
 
 #include <opencv2/gapi/own/assert.hpp>
+#include <opencv2/gapi/util/type_traits.hpp>
 
 namespace cv { namespace gapi { namespace own {
 //-----------------------------
@@ -22,16 +22,12 @@ namespace cv { namespace gapi { namespace own {
 //
 //-----------------------------
 
-template<typename DST, typename SRC>
-static inline DST saturate(SRC x)
+template<typename DST, typename SRC,
+         typename = cv::util::enable_if_t<!std::is_same<DST, SRC>::value &&
+                                           std::is_integral<DST>::value  &&
+                                           std::is_integral<SRC>::value>   >
+static CV_ALWAYS_INLINE DST saturate(SRC x)
 {
-    // only integral types please!
-    GAPI_DbgAssert(std::is_integral<DST>::value &&
-                   std::is_integral<SRC>::value);
-
-    if (std::is_same<DST, SRC>::value)
-        return static_cast<DST>(x);
-
     if (sizeof(DST) > sizeof(SRC))
         return static_cast<DST>(x);
 
@@ -44,38 +40,35 @@ static inline DST saturate(SRC x)
                std::numeric_limits<DST>::max():
            static_cast<DST>(x);
 }
+template<typename T>
+static CV_ALWAYS_INLINE T saturate(T x)
+{
+    return x;
+}
 
+template<typename DST, typename SRC, typename R,
+         cv::util::enable_if_t<std::is_floating_point<DST>::value, bool> = true >
+static CV_ALWAYS_INLINE DST saturate(SRC x, R)
+{
+    return static_cast<DST>(x);
+}
+template<typename DST, typename SRC, typename R,
+         cv::util::enable_if_t<std::is_integral<DST>::value &&
+                               std::is_integral<SRC>::value   , bool> = true >
+static CV_ALWAYS_INLINE DST saturate(SRC x, R)
+{
+    return saturate<DST>(x);
+}
 // Note, that OpenCV rounds differently:
 // - like std::round() for add, subtract
 // - like std::rint() for multiply, divide
-template<typename DST, typename SRC, typename R>
-static inline DST saturate(SRC x, R round)
+template<typename DST, typename SRC, typename R,
+         cv::util::enable_if_t<std::is_integral<DST>::value &&
+                               std::is_floating_point<SRC>::value, bool> = true >
+static CV_ALWAYS_INLINE DST saturate(SRC x, R round)
 {
-    if (std::is_floating_point<DST>::value)
-    {
-        return static_cast<DST>(x);
-    }
-    else if (std::is_integral<SRC>::value)
-    {
-        GAPI_DbgAssert(std::is_integral<DST>::value &&
-                       std::is_integral<SRC>::value);
-        return saturate<DST>(x);
-    }
-    else
-    {
-        GAPI_DbgAssert(std::is_integral<DST>::value &&
-                 std::is_floating_point<SRC>::value);
-#ifdef _WIN32
-// Suppress warning about converting x to floating-point
-// Note that x is already floating-point at this point
-#pragma warning(disable: 4244)
-#endif
-        int ix = static_cast<int>(round(x));
-#ifdef _WIN32
-#pragma warning(default: 4244)
-#endif
-        return saturate<DST>(ix);
-    }
+    int ix = static_cast<int>(round(x));
+    return saturate<DST>(ix);
 }
 
 // explicit suffix 'd' for double type
index 619b2fe..638ce2f 100644 (file)
@@ -928,7 +928,7 @@ IIStream& ByteMemoryInStream::operator>> (std::string& str) {
     if (sz == 0u) {
         str.clear();
     } else {
-        str.resize(sz);
+        str.resize(static_cast<std::size_t>(sz));
         for (auto &&i : ade::util::iota(sz)) { *this >> str[i]; }
     }
     return *this;
index d68ae73..7a3d90a 100644 (file)
@@ -1955,93 +1955,122 @@ GAPI_FLUID_KERNEL(GFluidLUT, cv::gapi::core::GLUT, false)
 //
 //-------------------------
 
+#if CV_SIMD128
+template<typename DST, typename SRC>
+CV_ALWAYS_INLINE int run_convertto_simd(DST*, const SRC*, int)
+{
+    return 0;
+}
+CV_ALWAYS_INLINE int run_convertto_simd(uchar *out, const float *in, const int length)
+{
+    int l = 0;
+    for (; l <= length - 16; l += 16)
+    {
+        v_int32x4 i0, i1, i2, i3;
+        i0 = v_round( v_load( (float*)& in[l     ] ) );
+        i1 = v_round( v_load( (float*)& in[l +  4] ) );
+        i2 = v_round( v_load( (float*)& in[l +  8] ) );
+        i3 = v_round( v_load( (float*)& in[l + 12] ) );
+
+        v_uint16x8 us0, us1;
+        us0 = v_pack_u(i0, i1);
+        us1 = v_pack_u(i2, i3);
+
+        v_uint8x16 uc;
+        uc = v_pack(us0, us1);
+        v_store((uchar*)& out[l], uc);
+    }
+    return l;
+}
+CV_ALWAYS_INLINE int run_convertto_simd(ushort *out, const float *in, const int length)
+{
+    int l = 0;
+    for (; l <= length - 8; l += 8)
+    {
+        v_int32x4 i0, i1;
+        i0 = v_round( v_load( (float*)& in[l     ] ) );
+        i1 = v_round( v_load( (float*)& in[l +  4] ) );
+
+        v_uint16x8 us;
+        us = v_pack_u(i0, i1);
+        v_store((ushort*)& out[l], us);
+    }
+    return l;
+}
+#endif
+
+template<typename DST, typename SRC,
+         cv::util::enable_if_t<std::is_integral<DST>::value &&
+                               std::is_floating_point<SRC>::value, bool> = true >
+CV_ALWAYS_INLINE void run_convertto(DST *out, const SRC *in, const int length)
+{
+    // manual SIMD if need rounding
+    static_assert(std::is_same<SRC,float>::value, "64-bit floating-point source is not supported");
+    int l = 0; // cycle index
+#if CV_SIMD128
+    l = run_convertto_simd(out, in, length);
+#endif
+    // tail of SIMD cycle
+    for (; l < length; l++)
+    {
+        out[l] = saturate<DST>(in[l], rintf);
+    }
+}
+template<typename DST, typename SRC,
+         cv::util::enable_if_t<std::is_integral<DST>::value &&
+                               std::is_integral<SRC>::value   , bool> = true >
+CV_ALWAYS_INLINE void run_convertto(DST *out, const SRC *in, const int length)
+{
+    for (int l = 0; l < length; l++)
+    {
+        out[l] = saturate<DST>(in[l]);
+    }
+}
+template<typename DST, typename SRC,
+         cv::util::enable_if_t<std::is_floating_point<DST>::value, bool> = true >
+CV_ALWAYS_INLINE void run_convertto(DST *out, const SRC *in, const int length)
+{
+    static_assert(!std::is_same<SRC,double>::value, "64-bit floating-point source is not supported");
+    for (int l = 0; l < length; l++)
+    {
+        out[l] = static_cast<DST>(in[l]);
+    }
+}
+
+template<typename DST, typename SRC>
+CV_ALWAYS_INLINE void run_convertto(DST *out, const SRC *in, const float alpha, const float beta,
+                                    const int length)
+{
+    static_assert(!std::is_same<SRC,double>::value, "64-bit floating-point source is not supported");
+    // TODO: optimize if alpha and beta and data are integral
+    for (int l = 0; l < length; l++)
+    {
+        out[l] = saturate<DST>(in[l] * alpha + beta, rintf);
+    }
+}
+
 template<typename DST, typename SRC>
 static void run_convertto(Buffer &dst, const View &src, double _alpha, double _beta)
 {
     const auto *in  = src.InLine<SRC>(0);
           auto *out = dst.OutLine<DST>();
 
-    int width  = dst.length();
-    int chan   = dst.meta().chan;
-    int length = width * chan;
+    const int width  = dst.length();
+    const int chan   = dst.meta().chan;
+    const int length = width * chan;
 
     // NB: don't do this if SRC or DST is 64-bit
-    auto alpha = static_cast<float>( _alpha );
-    auto beta  = static_cast<float>( _beta  );
+    const auto alpha = static_cast<float>( _alpha );
+    const auto beta  = static_cast<float>( _beta  );
 
     // compute faster if no alpha no beta
-    if (alpha == 1 && beta == 0)
+    if (1.f == alpha && 0.f == beta)
     {
-        // manual SIMD if need rounding
-        if (std::is_integral<DST>::value && std::is_floating_point<SRC>::value)
-        {
-            GAPI_Assert(( std::is_same<SRC,float>::value ));
-
-            int l = 0; // cycle index
-
-        #if CV_SIMD128
-            if (std::is_same<DST,uchar>::value)
-            {
-                for (; l <= length-16; l+=16)
-                {
-                    v_int32x4 i0, i1, i2, i3;
-                    i0 = v_round( v_load( (float*)& in[l     ] ) );
-                    i1 = v_round( v_load( (float*)& in[l +  4] ) );
-                    i2 = v_round( v_load( (float*)& in[l +  8] ) );
-                    i3 = v_round( v_load( (float*)& in[l + 12] ) );
-
-                    v_uint16x8 us0, us1;
-                    us0 = v_pack_u(i0, i1);
-                    us1 = v_pack_u(i2, i3);
-
-                    v_uint8x16 uc;
-                    uc = v_pack(us0, us1);
-                    v_store((uchar*)& out[l], uc);
-                }
-            }
-            if (std::is_same<DST,ushort>::value)
-            {
-                for (; l <= length-8; l+=8)
-                {
-                    v_int32x4 i0, i1;
-                    i0 = v_round( v_load( (float*)& in[l     ] ) );
-                    i1 = v_round( v_load( (float*)& in[l +  4] ) );
-
-                    v_uint16x8 us;
-                    us = v_pack_u(i0, i1);
-                    v_store((ushort*)& out[l], us);
-                }
-            }
-        #endif
-
-            // tail of SIMD cycle
-            for (; l < length; l++)
-            {
-                out[l] = saturate<DST>(in[l], rintf);
-            }
-        }
-        else if (std::is_integral<DST>::value) // here SRC is integral
-        {
-            for (int l=0; l < length; l++)
-            {
-                out[l] = saturate<DST>(in[l]);
-            }
-        }
-        else // DST is floating-point, SRC is any
-        {
-            for (int l=0; l < length; l++)
-            {
-                out[l] = static_cast<DST>(in[l]);
-            }
-        }
+        run_convertto(out, in, length);
     }
     else // if alpha or beta is non-trivial
     {
-        // TODO: optimize if alpha and beta and data are integral
-        for (int l=0; l < length; l++)
-        {
-            out[l] = saturate<DST>(in[l]*alpha + beta, rintf);
-        }
+        run_convertto(out, in, alpha, beta, length);
     }
 }
 
index ef93833..d15e17e 100644 (file)
@@ -24,6 +24,8 @@
 #include "backends/streaming/gstreamingbackend.hpp" // GCopy
 #include "compiler/gcompiler.hpp" // for compileIslands
 
+#include <logger.hpp>
+
 #include "executor/gstreamingexecutor.hpp"
 
 #include <opencv2/gapi/streaming/meta.hpp>
@@ -1382,8 +1384,16 @@ cv::gimpl::GStreamingExecutor::GStreamingExecutor(std::unique_ptr<ade::Graph> &&
 
 cv::gimpl::GStreamingExecutor::~GStreamingExecutor()
 {
-    if (state == State::READY || state == State::RUNNING)
-        stop();
+    // FIXME: this is a temporary try-catch exception hadling.
+    // Need to eliminate throwings from stop()
+    try {
+        if (state == State::READY || state == State::RUNNING)
+            stop();
+    } catch (const std::exception& e) {
+        std::stringstream message;
+        message << "~GStreamingExecutor() threw exception with message '" << e.what() << "'\n";
+        GAPI_LOG_WARNING(NULL, message.str());
+    }
 }
 
 void cv::gimpl::GStreamingExecutor::setSource(GRunArgs &&ins)