diff --git a/modules/core/src/precomp.hpp b/modules/core/src/precomp.hpp index d30855ef1e..0efe4db5b1 100644 --- a/modules/core/src/precomp.hpp +++ b/modules/core/src/precomp.hpp @@ -372,6 +372,7 @@ extern CV_EXPORTS bool __termination; // skip some cleanups, because process is terminating // (for example, if ExitProcess() was already called) +CV_EXPORTS cv::Mutex& getInitializationMutex(); /// @brief Returns timestamp in nanoseconds since program launch diff --git a/modules/imgproc/src/color_hsv.simd.hpp b/modules/imgproc/src/color_hsv.simd.hpp index b1eb50d7a4..424a6d1494 100644 --- a/modules/imgproc/src/color_hsv.simd.hpp +++ b/modules/imgproc/src/color_hsv.simd.hpp @@ -39,36 +39,65 @@ struct RGB2HSV_b : srccn(_srccn), blueIdx(_blueIdx), hrange(_hrange) { CV_Assert( hrange == 180 || hrange == 256 ); + + const TablesSingleton& global_tables = TablesSingleton::getInstance(); + hdiv_table_ = hrange == 180 ? global_tables.hdiv_table180 : global_tables.hdiv_table256; + sdiv_table_ = global_tables.sdiv_table; } - void operator()(const uchar* src, uchar* dst, int n) const + struct TablesSingleton { - CV_INSTRUMENT_REGION(); + int sdiv_table[256]; + int hdiv_table180[256]; + int hdiv_table256[256]; - int i, bidx = blueIdx, scn = srccn; - const int hsv_shift = 12; - - static int sdiv_table[256]; - static int hdiv_table180[256]; - static int hdiv_table256[256]; - static volatile bool initialized = false; - - int hr = hrange; - const int* hdiv_table = hr == 180 ? hdiv_table180 : hdiv_table256; - - if( !initialized ) + protected: + TablesSingleton() { + const int hsv_shift = 12; + sdiv_table[0] = hdiv_table180[0] = hdiv_table256[0] = 0; - for( i = 1; i < 256; i++ ) + for (int i = 1; i < 256; i++) { sdiv_table[i] = saturate_cast((255 << hsv_shift)/(1.*i)); hdiv_table180[i] = saturate_cast((180 << hsv_shift)/(6.*i)); hdiv_table256[i] = saturate_cast((256 << hsv_shift)/(6.*i)); } - initialized = true; } + public: + static TablesSingleton& getInstance() + { +#ifdef CV_CXX11 + static TablesSingleton g_tables; + return g_tables; +#else + static TablesSingleton* volatile g_tables = NULL; + if (!g_tables) + { + AutoLock lock(getInitializationMutex()); + if (!g_tables) + { + static TablesSingleton g_tablesInstance; + g_tables = &g_tablesInstance; + } + } + return *g_tables; +#endif + } + }; - i = 0; + void operator()(const uchar* src, uchar* dst, int n) const + { + CV_INSTRUMENT_REGION(); + + int bidx = blueIdx, scn = srccn; + const int hsv_shift = 12; + + int hr = hrange; + const int* hdiv_table/*[256]*/ = hdiv_table_; + const int* sdiv_table/*[256]*/ = sdiv_table_; + + int i = 0; #if CV_SIMD const int vsize = v_uint8::nlanes; @@ -231,6 +260,9 @@ struct RGB2HSV_b } int srccn, blueIdx, hrange; + + const int* hdiv_table_/*[256]*/; + const int* sdiv_table_/*[256]*/; }; diff --git a/modules/imgproc/src/precomp.hpp b/modules/imgproc/src/precomp.hpp index b300192e9c..d69da268d6 100644 --- a/modules/imgproc/src/precomp.hpp +++ b/modules/imgproc/src/precomp.hpp @@ -119,4 +119,12 @@ inline bool isStorageOrMat(void * arr) CV_Error( CV_StsBadArg, "Destination is not CvMemStorage* nor CvMat*" ); } -#endif /*__OPENCV_CV_INTERNAL_H_*/ + +namespace cv { + +CV_EXPORTS +cv::Mutex& getInitializationMutex(); // defined in core module + +} // namespace cv + +#endif /*__OPENCV_PRECOMP_H__*/