diff --git a/CMakeLists.txt b/CMakeLists.txt index b4a6a5f01..46881c453 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -212,7 +212,7 @@ OCV_OPTION(ENABLE_SSE42 "Enable SSE4.2 instructions" OCV_OPTION(ENABLE_AVX "Enable AVX instructions" OFF IF ((MSVC OR CMAKE_COMPILER_IS_GNUCXX) AND (X86 OR X86_64)) ) OCV_OPTION(ENABLE_NOISY_WARNINGS "Show all warnings even if they are too noisy" OFF ) OCV_OPTION(OPENCV_WARNINGS_ARE_ERRORS "Treat warnings as errors" OFF ) - +OCV_OPTION(ENABLE_WINRT_MODE "Build with Windows Runtime support" OFF IF WIN32 ) # uncategorized options # =================================================== @@ -603,6 +603,16 @@ if(ANDROID) status(" Android examples:" BUILD_ANDROID_EXAMPLES AND CAN_BUILD_ANDROID_PROJECTS THEN YES ELSE NO) endif() +# ================== Windows RT features ================== +if(WIN32) +status("") + status(" Windows RT support:" HAVE_WINRT THEN YES ELSE NO) + if (ENABLE_WINRT_MODE) + status(" Windows SDK v8.0:" ${WINDOWS_SDK_PATH}) + status(" Visual Studio 2012:" ${VISUAL_STUDIO_PATH}) + endif() +endif(WIN32) + # ========================== GUI ========================== status("") status(" GUI: ") diff --git a/cmake/OpenCVCRTLinkage.cmake b/cmake/OpenCVCRTLinkage.cmake index 7514285d9..295b914b6 100644 --- a/cmake/OpenCVCRTLinkage.cmake +++ b/cmake/OpenCVCRTLinkage.cmake @@ -2,6 +2,40 @@ if(NOT MSVC) message(FATAL_ERROR "CRT options are available only for MSVC") endif() +#INCLUDE (CheckIncludeFiles) + +if (ENABLE_WINRT_MODE) + set(HAVE_WINRT True) + + # search Windows Platform SDK + message(STATUS "Checking for Windows Platfrom SDK") + GET_FILENAME_COMPONENT(WINDOWS_SDK_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v8.0;InstallationFolder]" ABSOLUTE CACHE) + if (WINDOWS_SDK_PATH STREQUAL "") + message(ERROR "Windows Platform SDK 8.0 was not found!") + set(HAVE_WINRT False) + endif() + + #search for Visual Studio 11.0 install directory + message(STATUS "Checking for Visual Studio 2012") + GET_FILENAME_COMPONENT(VISUAL_STUDIO_PATH [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0\\Setup\\VS;ProductDir] REALPATH CACHE) + if (VISUAL_STUDIO_PATH STREQUAL "") + message(ERROR "Visual Studio 2012 was not found!") + set(HAVE_WINRT False) + endif() + + if (HAVE_WINRT) + TRY_COMPILE(HAVE_WINRT + "${OPENCV_BINARY_DIR}/CMakeFiles/CMakeTmp" + "${OpenCV_SOURCE_DIR}/cmake/checks/winrttest.cpp" + CMAKE_FLAGS "\"kernel.lib\" \"user32.lib\"" + OUTPUT_VARIABLE OUTPUT) + endif() + + if (HAVE_WINRT) + add_definitions(/DWINVER=0x0602 /DNTDDI_VERSION=NTDDI_WIN8 /D_WIN32_WINNT=0x0602) + endif() +endif(ENABLE_WINRT_MODE) + if(NOT BUILD_SHARED_LIBS AND BUILD_WITH_STATIC_CRT) foreach(flag_var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE diff --git a/cmake/checks/winrttest.cpp b/cmake/checks/winrttest.cpp new file mode 100644 index 000000000..4172afe55 --- /dev/null +++ b/cmake/checks/winrttest.cpp @@ -0,0 +1,6 @@ +#include + +int main(int, char**) +{ + return 0; +} \ No newline at end of file diff --git a/cmake/templates/cvconfig.h.cmake b/cmake/templates/cvconfig.h.cmake index f5950b64f..7587eef6b 100644 --- a/cmake/templates/cvconfig.h.cmake +++ b/cmake/templates/cvconfig.h.cmake @@ -76,6 +76,12 @@ /* GTK+ 2.0 Thread support */ #cmakedefine HAVE_GTHREAD +/* Windows Runtime support */ +#cmakedefine HAVE_WINRT + +/* Win32 UI */ +#cmakedefine HAVE_WIN32UI + /* GTK+ 2.x toolkit */ #cmakedefine HAVE_GTK diff --git a/modules/contrib/src/inputoutput.cpp b/modules/contrib/src/inputoutput.cpp index a711f242a..e04740fae 100644 --- a/modules/contrib/src/inputoutput.cpp +++ b/modules/contrib/src/inputoutput.cpp @@ -1,5 +1,6 @@ #include "opencv2/contrib/contrib.hpp" +#include #if defined(WIN32) || defined(_WIN32) #include @@ -16,10 +17,22 @@ namespace cv list.clear(); std::string path_f = path + "/" + exten; #ifdef WIN32 - WIN32_FIND_DATA FindFileData; - HANDLE hFind; + #ifdef HAVE_WINRT + WIN32_FIND_DATAW FindFileData; + #else + WIN32_FIND_DATAA FindFileData; + #endif + HANDLE hFind; - hFind = FindFirstFile((LPCSTR)path_f.c_str(), &FindFileData); + #ifdef HAVE_WINRT + size_t size = mbstowcs(NULL, path_f.c_str(), path_f.size()); + Ptr wpath = new wchar_t[size+1]; + wpath[size] = 0; + mbstowcs(wpath, path_f.c_str(), path_f.size()); + hFind = FindFirstFileExW(wpath, FindExInfoStandard, &FindFileData, FindExSearchNameMatch, NULL, 0); + #else + hFind = FindFirstFileA((LPCSTR)path_f.c_str(), &FindFileData); + #endif if (hFind == INVALID_HANDLE_VALUE) { return list; @@ -34,13 +47,26 @@ namespace cv FindFileData.dwFileAttributes == FILE_ATTRIBUTE_SYSTEM || FindFileData.dwFileAttributes == FILE_ATTRIBUTE_READONLY) { + cv::Ptr fname; + #ifdef HAVE_WINRT + size_t asize = wcstombs(NULL, FindFileData.cFileName, 0); + fname = new char[asize+1]; + fname[asize] = 0; + wcstombs(fname, FindFileData.cFileName, asize); + #else + fname = FindFileData.cFileName; + #endif if (addPath) - list.push_back(path + "/" + FindFileData.cFileName); + list.push_back(path + "/" + std::string(fname)); else - list.push_back(FindFileData.cFileName); + list.push_back(std::string(fname)); } } - while(FindNextFile(hFind, &FindFileData)); + #ifdef HAVE_WINRT + while(FindNextFileW(hFind, &FindFileData)); + #else + while(FindNextFileA(hFind, &FindFileData)); + #endif FindClose(hFind); } #else @@ -75,10 +101,22 @@ namespace cv std::string path_f = path + "/" + exten; list.clear(); #ifdef WIN32 - WIN32_FIND_DATA FindFileData; + #ifdef HAVE_WINRT + WIN32_FIND_DATAW FindFileData; + #else + WIN32_FIND_DATAA FindFileData; + #endif HANDLE hFind; - hFind = FindFirstFile((LPCSTR)path_f.c_str(), &FindFileData); + #ifdef HAVE_WINRT + size_t size = mbstowcs(NULL, path_f.c_str(), path_f.size()); + Ptr wpath = new wchar_t[size+1]; + wpath[size] = 0; + mbstowcs(wpath, path_f.c_str(), path_f.size()); + hFind = FindFirstFileExW(wpath, FindExInfoStandard, &FindFileData, FindExSearchNameMatch, NULL, 0); + #else + hFind = FindFirstFileA((LPCSTR)path_f.c_str(), &FindFileData); + #endif if (hFind == INVALID_HANDLE_VALUE) { return list; @@ -87,17 +125,37 @@ namespace cv { do { +#ifdef HAVE_WINRT + if (FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY && + wcscmp(FindFileData.cFileName, L".") != 0 && + wcscmp(FindFileData.cFileName, L"..") != 0) +#else if (FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY && strcmp(FindFileData.cFileName, ".") != 0 && strcmp(FindFileData.cFileName, "..") != 0) +#endif { + cv::Ptr fname; + #ifdef HAVE_WINRT + size_t asize = wcstombs(NULL, FindFileData.cFileName, 0); + fname = new char[asize+1]; + fname[asize] = 0; + wcstombs(fname, FindFileData.cFileName, asize); + #else + fname = FindFileData.cFileName; + #endif + if (addPath) - list.push_back(path + "/" + FindFileData.cFileName); + list.push_back(path + "/" + std::string(fname)); else - list.push_back(FindFileData.cFileName); + list.push_back(std::string(fname)); } } - while(FindNextFile(hFind, &FindFileData)); + #ifdef HAVE_WINRT + while(FindNextFileW(hFind, &FindFileData)); + #else + while(FindNextFileA(hFind, &FindFileData)); + #endif FindClose(hFind); } diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index dc62a884f..fe13daabb 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -2,6 +2,10 @@ set(the_description "The Core Functionality") ocv_add_module(core ${ZLIB_LIBRARIES}) ocv_module_include_directories(${ZLIB_INCLUDE_DIR}) +if (HAVE_WINRT) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /ZW /GS /Gm- /AI\"${WINDOWS_SDK_PATH}/References/CommonConfiguration/Neutral\" /AI\"${VISUAL_STUDIO_PATH}/vcpackages\"") +endif() + if(HAVE_CUDA) ocv_include_directories("${OpenCV_SOURCE_DIR}/modules/gpu/include") ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef) diff --git a/modules/core/src/alloc.cpp b/modules/core/src/alloc.cpp index 1944ed17d..37b1e0db9 100644 --- a/modules/core/src/alloc.cpp +++ b/modules/core/src/alloc.cpp @@ -94,9 +94,20 @@ void fastFree(void* ptr) #define STAT(stmt) #ifdef WIN32 +#if (_WIN32_WINNT >= 0x0602) +#include +#endif + struct CriticalSection { - CriticalSection() { InitializeCriticalSection(&cs); } + CriticalSection() + { +#if (_WIN32_WINNT >= 0x0600) + InitializeCriticalSectionEx(&cs, 1000, 0); +#else + InitializeCriticalSection(&cs); +#endif + } ~CriticalSection() { DeleteCriticalSection(&cs); } void lock() { EnterCriticalSection(&cs); } void unlock() { LeaveCriticalSection(&cs); } diff --git a/modules/core/src/glob.cpp b/modules/core/src/glob.cpp index 368f304ef..e39cba016 100644 --- a/modules/core/src/glob.cpp +++ b/modules/core/src/glob.cpp @@ -56,16 +56,39 @@ namespace struct DIR { +#ifdef HAVE_WINRT + WIN32_FIND_DATAW data; +#else WIN32_FIND_DATA data; +#endif HANDLE handle; dirent ent; +#ifdef HAVE_WINRT + DIR() {}; + ~DIR() + { + if (ent.d_name) + delete[] ent.d_name; + } +#endif }; DIR* opendir(const char* path) { DIR* dir = new DIR; dir->ent.d_name = 0; - dir->handle = ::FindFirstFileA((cv::String(path) + "\\*").c_str(), &dir->data); +#ifdef HAVE_WINRT + cv::String full_path = cv::String(path) + "\\*"; + size_t size = mbstowcs(NULL, full_path.c_str(), full_path.size()); + cv::Ptr wfull_path = new wchar_t[size+1]; + wfull_path[size] = 0; + mbstowcs(wfull_path, full_path.c_str(), full_path.size()); + dir->handle = ::FindFirstFileExW(wfull_path, FindExInfoStandard, + &dir->data, FindExSearchNameMatch, NULL, 0); +#else + dir->handle = ::FindFirstFileExA((cv::String(path) + "\\*").c_str(), + FindExInfoStandard, &dir->data, FindExSearchNameMatch, NULL, 0); +#endif if(dir->handle == INVALID_HANDLE_VALUE) { /*closedir will do all cleanup*/ @@ -76,12 +99,25 @@ namespace dirent* readdir(DIR* dir) { +#ifdef HAVE_WINRT if (dir->ent.d_name != 0) { - if (::FindNextFile(dir->handle, &dir->data) != TRUE) + if (::FindNextFileW(dir->handle, &dir->data) != TRUE) + return 0; + } + size_t asize = wcstombs(NULL, dir->data.cFileName, 0); + char* aname = new char[asize+1]; + aname[asize] = 0; + wcstombs(aname, dir->data.cFileName, asize); + dir->ent.d_name = aname; +#else + if (dir->ent.d_name != 0) + { + if (::FindNextFileA(dir->handle, &dir->data) != TRUE) return 0; } dir->ent.d_name = dir->data.cFileName; +#endif return &dir->ent; } @@ -107,7 +143,19 @@ static bool isDir(const cv::String& path, DIR* dir) if (dir) attributes = dir->data.dwFileAttributes; else - attributes = ::GetFileAttributes(path.c_str()); + { + WIN32_FILE_ATTRIBUTE_DATA all_attrs; +#ifdef HAVE_WINRT + size_t size = mbstowcs(NULL, path.c_str(), path.size()); + cv::Ptr wpath = new wchar_t[size+1]; + wpath[size] = 0; + mbstowcs(wpath, path.c_str(), path.size()); + ::GetFileAttributesExW(wpath, GetFileExInfoStandard, &all_attrs); +#else + ::GetFileAttributesExA(path.c_str(), GetFileExInfoStandard, &all_attrs); +#endif + attributes = all_attrs.dwFileAttributes; + } return (attributes != INVALID_FILE_ATTRIBUTES) && ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); #else diff --git a/modules/core/src/parallel.cpp b/modules/core/src/parallel.cpp index 0a9ed0987..1ae8c9631 100644 --- a/modules/core/src/parallel.cpp +++ b/modules/core/src/parallel.cpp @@ -453,7 +453,11 @@ int cv::getNumberOfCPUs(void) { #if defined WIN32 || defined _WIN32 SYSTEM_INFO sysinfo; +#if defined(_M_ARM) || defined(_M_X64) || defined(HAVE_WINRT) + GetNativeSystemInfo( &sysinfo ); +#else GetSystemInfo( &sysinfo ); +#endif return (int)sysinfo.dwNumberOfProcessors; #elif defined ANDROID diff --git a/modules/core/src/rand.cpp b/modules/core/src/rand.cpp index 2cdbe3916..54bb753a1 100644 --- a/modules/core/src/rand.cpp +++ b/modules/core/src/rand.cpp @@ -726,33 +726,54 @@ void RNG::fill( InputOutputArray _mat, int disttype, } #ifdef WIN32 + + +#ifdef HAVE_WINRT +// using C++11 thread attribute for local thread data +__declspec( thread ) RNG* rng = NULL; + + void deleteThreadRNGData() + { + if (rng) + delete rng; +} + +RNG& theRNG() +{ + if (!rng) + { + rng = new RNG; + } + return *rng; +} +#else #ifdef WINCE # define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF) #endif static DWORD tlsRNGKey = TLS_OUT_OF_INDEXES; -void deleteThreadRNGData() -{ - if( tlsRNGKey != TLS_OUT_OF_INDEXES ) - delete (RNG*)TlsGetValue( tlsRNGKey ); + void deleteThreadRNGData() + { + if( tlsRNGKey != TLS_OUT_OF_INDEXES ) + delete (RNG*)TlsGetValue( tlsRNGKey ); } RNG& theRNG() { if( tlsRNGKey == TLS_OUT_OF_INDEXES ) { - tlsRNGKey = TlsAlloc(); - CV_Assert(tlsRNGKey != TLS_OUT_OF_INDEXES); + tlsRNGKey = TlsAlloc(); + CV_Assert(tlsRNGKey != TLS_OUT_OF_INDEXES); } RNG* rng = (RNG*)TlsGetValue( tlsRNGKey ); if( !rng ) { - rng = new RNG; - TlsSetValue( tlsRNGKey, rng ); + rng = new RNG; + TlsSetValue( tlsRNGKey, rng ); } return *rng; } - +#endif //HAVE_WINRT #else static pthread_key_t tlsRNGKey = 0; diff --git a/modules/core/src/system.cpp b/modules/core/src/system.cpp index 6da32637c..7e01ca5ea 100644 --- a/modules/core/src/system.cpp +++ b/modules/core/src/system.cpp @@ -47,6 +47,9 @@ #define _WIN32_WINNT 0x0400 // http://msdn.microsoft.com/en-us/library/ms686857(VS.85).aspx #endif #include +#if (_WIN32_WINNT >= 0x0602) + #include +#endif #undef small #undef min #undef max @@ -75,6 +78,30 @@ } #endif #endif + +#ifdef HAVE_WINRT +#include + +std::wstring GetTempPathWinRT() +{ + return std::wstring(Windows::Storage::ApplicationData::Current->TemporaryFolder->Path->Data()); +} + +std::wstring GetTempFileNameWinRT(std::wstring prefix) +{ + wchar_t guidStr[40]; + GUID g; + CoCreateGuid(&g); + wchar_t* mask = L"%08x_%04x_%04x_%02x%02x_%02x%02x%02x%02x%02x%02x"; + swprintf(&guidStr[0], sizeof(guidStr)/sizeof(wchar_t), mask, + g.Data1, g.Data2, g.Data3, UINT(g.Data4[0]), UINT(g.Data4[1]), + UINT(g.Data4[2]), UINT(g.Data4[3]), UINT(g.Data4[4]), + UINT(g.Data4[5]), UINT(g.Data4[6]), UINT(g.Data4[7])); + + return prefix + std::wstring(guidStr); +} + +#endif #else #include #include @@ -359,10 +386,38 @@ string format( const char* fmt, ... ) string tempfile( const char* suffix ) { +#ifdef HAVE_WINRT + std::wstring temp_dir = L""; + const wchar_t* opencv_temp_dir = _wgetenv(L"OPENCV_TEMP_PATH"); + if (opencv_temp_dir) + temp_dir = std::wstring(opencv_temp_dir); +#else const char *temp_dir = getenv("OPENCV_TEMP_PATH"); +#endif string fname; #if defined WIN32 || defined _WIN32 +#ifdef HAVE_WINRT + RoInitialize(RO_INIT_MULTITHREADED); + std::wstring temp_dir2; + if (temp_dir.empty()) + temp_dir = GetTempPathWinRT(); + + std::wstring temp_file; + temp_file = GetTempFileNameWinRT(L"ocv"); + if (temp_file.empty()) + return std::string(); + + temp_file = temp_dir + std::wstring(L"\\") + temp_file; + DeleteFileW(temp_file.c_str()); + + size_t asize = wcstombs(NULL, temp_file.c_str(), 0); + Ptr aname = new char[asize+1]; + aname[asize] = 0; + wcstombs(aname, temp_file.c_str(), asize); + fname = std::string(aname); + RoUninitialize(); +#else char temp_dir2[MAX_PATH + 1] = { 0 }; char temp_file[MAX_PATH + 1] = { 0 }; @@ -377,6 +432,7 @@ string tempfile( const char* suffix ) DeleteFileA(temp_file); fname = temp_file; +#endif # else # ifdef ANDROID //char defaultTemplate[] = "/mnt/sdcard/__opencv_temp.XXXXXX"; @@ -746,6 +802,10 @@ cvGetModuleInfo( const char* name, const char **version, const char **plugin_lis } #if defined CVAPI_EXPORTS && defined WIN32 && !defined WINCE +#ifdef HAVE_WINRT + #pragma warning(disable:4447) // Disable warning 'main' signature found without threading model +#endif + BOOL WINAPI DllMain( HINSTANCE, DWORD fdwReason, LPVOID ); BOOL WINAPI DllMain( HINSTANCE, DWORD fdwReason, LPVOID ) @@ -766,7 +826,15 @@ namespace cv struct Mutex::Impl { - Impl() { InitializeCriticalSection(&cs); refcount = 1; } + Impl() + { +#if (_WIN32_WINNT >= 0x0600) + ::InitializeCriticalSectionEx(&cs, 1000, 0); +#else + ::InitializeCriticalSection(&cs); +#endif + refcount = 1; + } ~Impl() { DeleteCriticalSection(&cs); } void lock() { EnterCriticalSection(&cs); } diff --git a/modules/core/test/test_main.cpp b/modules/core/test/test_main.cpp index 6b2499344..3294fab2b 100644 --- a/modules/core/test/test_main.cpp +++ b/modules/core/test/test_main.cpp @@ -1,3 +1,7 @@ +#ifdef HAVE_WINRT + #pragma warning(disable:4447) // Disable warning 'main' signature found without threading model +#endif + #include "test_precomp.hpp" CV_TEST_MAIN("cv") diff --git a/modules/ts/include/opencv2/ts/ts.hpp b/modules/ts/include/opencv2/ts/ts.hpp index eafcb8902..384046fd7 100644 --- a/modules/ts/include/opencv2/ts/ts.hpp +++ b/modules/ts/include/opencv2/ts/ts.hpp @@ -10,6 +10,10 @@ #include // for va_list +#ifdef HAVE_WINRT + #pragma warning(disable:4447) // Disable warning 'main' signature found without threading model +#endif + #ifdef _MSC_VER #pragma warning( disable: 4127 ) #endif