From 5d97dd0ea5d2d752cc0c96156ed310f4897443c7 Mon Sep 17 00:00:00 2001 From: Simon Heinen Date: Fri, 20 Feb 2015 12:54:54 +0100 Subject: [PATCH 001/109] Update android+AsyncServiceHelper.java --- .../generator/src/java/android+AsyncServiceHelper.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/java/generator/src/java/android+AsyncServiceHelper.java b/modules/java/generator/src/java/android+AsyncServiceHelper.java index 568f3da170..b7c57f28c8 100644 --- a/modules/java/generator/src/java/android+AsyncServiceHelper.java +++ b/modules/java/generator/src/java/android+AsyncServiceHelper.java @@ -21,9 +21,10 @@ class AsyncServiceHelper final LoaderCallbackInterface Callback) { AsyncServiceHelper helper = new AsyncServiceHelper(Version, AppContext, Callback); - if (AppContext.bindService(new Intent("org.opencv.engine.BIND"), - helper.mServiceConnection, Context.BIND_AUTO_CREATE)) - { + Intent intent = new Intent("org.opencv.engine.BIND"); + intent.setPackage("org.opencv.engine"); + if (AppContext.bindService(intent, helper.mServiceConnection, + Context.BIND_AUTO_CREATE)) { return true; } else From 1af452123992f6dbd49ee45368455778359ce4bf Mon Sep 17 00:00:00 2001 From: hahne Date: Mon, 9 Mar 2015 16:19:47 +0100 Subject: [PATCH 002/109] fix for issue 1915 --- modules/videoio/src/cap_ffmpeg_impl.hpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/videoio/src/cap_ffmpeg_impl.hpp b/modules/videoio/src/cap_ffmpeg_impl.hpp index 5870f4bc71..b5ff31a280 100644 --- a/modules/videoio/src/cap_ffmpeg_impl.hpp +++ b/modules/videoio/src/cap_ffmpeg_impl.hpp @@ -649,13 +649,13 @@ bool CvCapture_FFMPEG::grabFrame() frame_number > ic->streams[video_stream]->nb_frames ) return false; - av_free_packet (&packet); - picture_pts = AV_NOPTS_VALUE_; // get the next frame while (!valid) { + + av_free_packet (&packet); int ret = av_read_frame(ic, &packet); if (ret == AVERROR(EAGAIN)) continue; @@ -698,8 +698,6 @@ bool CvCapture_FFMPEG::grabFrame() if (count_errs > max_number_of_attempts) break; } - - av_free_packet (&packet); } if( valid && first_frame_number < 0 ) From 2e86cedef276d0955fff614f76f4970e2ad96a77 Mon Sep 17 00:00:00 2001 From: Alexander Nitsch Date: Mon, 23 Feb 2015 15:01:00 +0100 Subject: [PATCH 003/109] Fix MinGW detection on x86 MinGW-w64 always uses "w64" as vendor key which the previously used check for "64" anywhere in the target triplet matched. This would lead to MinGW-w64 setups always being treated as x64. Turns out we do not even need this additional check since the architecture has been correctly determined earlier in this file. No need to do it again. --- cmake/OpenCVDetectCXXCompiler.cmake | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/cmake/OpenCVDetectCXXCompiler.cmake b/cmake/OpenCVDetectCXXCompiler.cmake index 72d939917a..361178be05 100644 --- a/cmake/OpenCVDetectCXXCompiler.cmake +++ b/cmake/OpenCVDetectCXXCompiler.cmake @@ -147,11 +147,7 @@ if(MSVC) elseif(MINGW) set(OpenCV_RUNTIME mingw) - execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpmachine - OUTPUT_VARIABLE OPENCV_GCC_TARGET_MACHINE - OUTPUT_STRIP_TRAILING_WHITESPACE) - if(CMAKE_OPENCV_GCC_TARGET_MACHINE MATCHES "64") - set(MINGW64 1) + if(MINGW64) set(OpenCV_ARCH x64) else() set(OpenCV_ARCH x86) From 8f84a73b821d3edad445d29478d2ab31b03d0381 Mon Sep 17 00:00:00 2001 From: Alexander Nitsch Date: Sat, 7 Mar 2015 15:37:21 +0100 Subject: [PATCH 004/109] Fix MinGW architecture detection Fix typo that would always lead to detection of x86 for MinGW builds in the OpenCVConfig.cmake file. --- cmake/OpenCVConfig.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/OpenCVConfig.cmake b/cmake/OpenCVConfig.cmake index dfd7e8f268..b69b60ff5b 100644 --- a/cmake/OpenCVConfig.cmake +++ b/cmake/OpenCVConfig.cmake @@ -87,7 +87,7 @@ elseif(MINGW) set(OpenCV_RUNTIME mingw) execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpmachine - OUTPUT_VARIABLE OPENCV_GCC_TARGET_MACHINE + OUTPUT_VARIABLE CMAKE_OPENCV_GCC_TARGET_MACHINE OUTPUT_STRIP_TRAILING_WHITESPACE) if(CMAKE_OPENCV_GCC_TARGET_MACHINE MATCHES "64") set(MINGW64 1) From 3fff0e5b3c771c3b8f6b78ca9ccb803b3b16ed6b Mon Sep 17 00:00:00 2001 From: Alexander Nitsch Date: Sat, 7 Mar 2015 15:49:48 +0100 Subject: [PATCH 005/109] Fix MinGW detection on x86 Make detection of x64 using the gcc's target triplet identical to the one used in cmake/OpenCVDetectCXXCompiler.cmake. Otherwise, MinGW-w64 setups will always be treated as x64 since they contain "w64" as vendor key. --- cmake/OpenCVConfig.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/OpenCVConfig.cmake b/cmake/OpenCVConfig.cmake index b69b60ff5b..cf45eb6bad 100644 --- a/cmake/OpenCVConfig.cmake +++ b/cmake/OpenCVConfig.cmake @@ -89,7 +89,7 @@ elseif(MINGW) execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpmachine OUTPUT_VARIABLE CMAKE_OPENCV_GCC_TARGET_MACHINE OUTPUT_STRIP_TRAILING_WHITESPACE) - if(CMAKE_OPENCV_GCC_TARGET_MACHINE MATCHES "64") + if(CMAKE_OPENCV_GCC_TARGET_MACHINE MATCHES "amd64|x86_64|AMD64") set(MINGW64 1) set(OpenCV_ARCH x64) else() From 66e653d24d4f2c773f57d37d0705b86720cfe6d4 Mon Sep 17 00:00:00 2001 From: Alexander Nitsch Date: Tue, 17 Mar 2015 13:52:59 +0100 Subject: [PATCH 006/109] Remove local variables from CMAKE namespace --- cmake/OpenCVConfig.cmake | 4 ++-- cmake/OpenCVDetectCXXCompiler.cmake | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake/OpenCVConfig.cmake b/cmake/OpenCVConfig.cmake index cf45eb6bad..4f0e398586 100644 --- a/cmake/OpenCVConfig.cmake +++ b/cmake/OpenCVConfig.cmake @@ -87,9 +87,9 @@ elseif(MINGW) set(OpenCV_RUNTIME mingw) execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpmachine - OUTPUT_VARIABLE CMAKE_OPENCV_GCC_TARGET_MACHINE + OUTPUT_VARIABLE OPENCV_GCC_TARGET_MACHINE OUTPUT_STRIP_TRAILING_WHITESPACE) - if(CMAKE_OPENCV_GCC_TARGET_MACHINE MATCHES "amd64|x86_64|AMD64") + if(OPENCV_GCC_TARGET_MACHINE MATCHES "amd64|x86_64|AMD64") set(MINGW64 1) set(OpenCV_ARCH x64) else() diff --git a/cmake/OpenCVDetectCXXCompiler.cmake b/cmake/OpenCVDetectCXXCompiler.cmake index 361178be05..871331883c 100644 --- a/cmake/OpenCVDetectCXXCompiler.cmake +++ b/cmake/OpenCVDetectCXXCompiler.cmake @@ -91,9 +91,9 @@ elseif(CMAKE_COMPILER_IS_GNUCXX) if(WIN32) execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpmachine - OUTPUT_VARIABLE CMAKE_OPENCV_GCC_TARGET_MACHINE + OUTPUT_VARIABLE OPENCV_GCC_TARGET_MACHINE OUTPUT_STRIP_TRAILING_WHITESPACE) - if(CMAKE_OPENCV_GCC_TARGET_MACHINE MATCHES "amd64|x86_64|AMD64") + if(OPENCV_GCC_TARGET_MACHINE MATCHES "amd64|x86_64|AMD64") set(MINGW64 1) endif() endif() From afd9de6f1bb51094c73ee8dfb1a3592243f9c4df Mon Sep 17 00:00:00 2001 From: Alexander Nitsch Date: Mon, 30 Mar 2015 23:38:43 +0200 Subject: [PATCH 007/109] Fix static/shared lib detection The check for BUILD_SHARED_LIBS had its logic backwards. If this variable is not defined we must assume a build of static libs. --- cmake/OpenCVConfig.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/OpenCVConfig.cmake b/cmake/OpenCVConfig.cmake index 4f0e398586..09174b02fe 100644 --- a/cmake/OpenCVConfig.cmake +++ b/cmake/OpenCVConfig.cmake @@ -47,7 +47,7 @@ endif() if(NOT DEFINED OpenCV_STATIC) # look for global setting - if(NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS) + if(BUILD_SHARED_LIBS) set(OpenCV_STATIC OFF) else() set(OpenCV_STATIC ON) From 412a2aa4ab8d4e12378fbfeaea0e08d38c433fec Mon Sep 17 00:00:00 2001 From: Maxim Kostin Date: Tue, 31 Mar 2015 16:31:37 +0300 Subject: [PATCH 008/109] Added support for 'imgcodecs' module: - Resolved GET_ENV and input type incompatibility - Made libjpeg compile for WINRT. So does imgcodecs module. - Updated .gitignore (log, tlog) --- .gitignore | 7 ++++++- 3rdparty/libjpeg/CMakeLists.txt | 7 +++++++ 3rdparty/libtiff/CMakeLists.txt | 4 ++-- modules/imgcodecs/CMakeLists.txt | 4 ---- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 228365d9eb..039d2400a6 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,6 @@ Thumbs.db tags tegra/ bin/ -CMakeFiles/ *.sdf *.opensdf *.obj @@ -17,3 +16,9 @@ CMakeFiles/ *.depend *.rule *.tmp +*/debug +*/CMakeFiles +CMakeCache.txt +*.suo +*.log +*.tlog \ No newline at end of file diff --git a/3rdparty/libjpeg/CMakeLists.txt b/3rdparty/libjpeg/CMakeLists.txt index 65a9d1c8aa..d79f00adae 100644 --- a/3rdparty/libjpeg/CMakeLists.txt +++ b/3rdparty/libjpeg/CMakeLists.txt @@ -15,6 +15,13 @@ else() ocv_list_filterout(lib_srcs jmemnobs.c) endif() +if(WINRT) + add_definitions(-DNO_GETENV) + get_directory_property( DirDefs COMPILE_DEFINITIONS ) + message(STATUS "Adding NO_GETENV to compiler definitions for WINRT:") + message(STATUS " COMPILE_DEFINITIONS = ${DirDefs}") +endif() + # ---------------------------------------------------------------------------------- # Define the library target: # ---------------------------------------------------------------------------------- diff --git a/3rdparty/libtiff/CMakeLists.txt b/3rdparty/libtiff/CMakeLists.txt index ad8a466188..b7739e0e4e 100644 --- a/3rdparty/libtiff/CMakeLists.txt +++ b/3rdparty/libtiff/CMakeLists.txt @@ -17,7 +17,7 @@ check_include_file(string.h HAVE_STRING_H) check_include_file(sys/types.h HAVE_SYS_TYPES_H) check_include_file(unistd.h HAVE_UNISTD_H) -if(WIN32) +if(WIN32 AND NOT WINRT) set(USE_WIN32_FILEIO 1) endif() @@ -79,7 +79,7 @@ set(lib_srcs "${CMAKE_CURRENT_BINARY_DIR}/tif_config.h" ) -if(WIN32) +if(WIN32 AND NOT WINRT) list(APPEND lib_srcs tif_win32.c) else() list(APPEND lib_srcs tif_unix.c) diff --git a/modules/imgcodecs/CMakeLists.txt b/modules/imgcodecs/CMakeLists.txt index 50e2d5da64..6d565217a0 100644 --- a/modules/imgcodecs/CMakeLists.txt +++ b/modules/imgcodecs/CMakeLists.txt @@ -1,7 +1,3 @@ -if(WINRT) - ocv_module_disable(imgcodecs) -endif() - set(the_description "Image codecs") ocv_add_module(imgcodecs opencv_imgproc WRAP java python) From 7c5084e385f1d7046a21a89cd6751c28d9785ba9 Mon Sep 17 00:00:00 2001 From: Pavel Rojtberg Date: Wed, 25 Mar 2015 16:11:53 +0100 Subject: [PATCH 009/109] - update documentation * correct the part about fixed aspect * improve formatting * add snippet markers to source * replace inline code by @snippet - do not run calibration twice when using a imageList - make output consistent in itself (CamelCase vs no_camel_case) as well as with old camera calibrate sample - respect write extrinsic/ points flags - set the aspectRatio value when specified - fix writing of calibration settings. also update grammar. - fix intendation and remove some size_t -> int casts by using size_t --- .../camera_calibration.markdown | 266 ++---------------- .../camera_calibration/camera_calibration.cpp | 234 ++++++++------- 2 files changed, 159 insertions(+), 341 deletions(-) diff --git a/doc/tutorials/calib3d/camera_calibration/camera_calibration.markdown b/doc/tutorials/calib3d/camera_calibration/camera_calibration.markdown index 0b23643964..a7bd1f0597 100644 --- a/doc/tutorials/calib3d/camera_calibration/camera_calibration.markdown +++ b/doc/tutorials/calib3d/camera_calibration/camera_calibration.markdown @@ -30,7 +30,7 @@ y_{corrected} = y + [ p_1(r^2+ 2y^2)+ 2p_2xy]\f] So we have five distortion parameters which in OpenCV are presented as one row matrix with 5 columns: -\f[Distortion_{coefficients}=(k_1 \hspace{10pt} k_2 \hspace{10pt} p_1 \hspace{10pt} p_2 \hspace{10pt} k_3)\f] +\f[distortion\_coefficients=(k_1 \hspace{10pt} k_2 \hspace{10pt} p_1 \hspace{10pt} p_2 \hspace{10pt} k_3)\f] Now for the unit conversion we use the following formula: @@ -96,83 +96,30 @@ on how to do this you can find in the @ref tutorial_file_input_output_with_xml_y Explanation ----------- --# **Read the settings.** - @code{.cpp} - Settings s; - const string inputSettingsFile = argc > 1 ? argv[1] : "default.xml"; - FileStorage fs(inputSettingsFile, FileStorage::READ); // Read the settings - if (!fs.isOpened()) - { - cout << "Could not open the configuration file: \"" << inputSettingsFile << "\"" << endl; - return -1; - } - fs["Settings"] >> s; - fs.release(); // close Settings file +-# **Read the settings** + @snippet samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp file_read - if (!s.goodInput) - { - cout << "Invalid input detected. Application stopping. " << endl; - return -1; - } - @endcode For this I've used simple OpenCV class input operation. After reading the file I've an additional post-processing function that checks validity of the input. Only if all inputs are good then *goodInput* variable will be true. --# **Get next input, if it fails or we have enough of them - calibrate**. After this we have a big +-# **Get next input, if it fails or we have enough of them - calibrate** + + After this we have a big loop where we do the following operations: get the next image from the image list, camera or video file. If this fails or we have enough images then we run the calibration process. In case of image we step out of the loop and otherwise the remaining frames will be undistorted (if the option is set) via changing from *DETECTION* mode to the *CALIBRATED* one. - @code{.cpp} - for(int i = 0;;++i) - { - Mat view; - bool blinkOutput = false; - - view = s.nextImage(); - - //----- If no more image, or got enough, then stop calibration and show result ------------- - if( mode == CAPTURING && imagePoints.size() >= (unsigned)s.nrFrames ) - { - if( runCalibrationAndSave(s, imageSize, cameraMatrix, distCoeffs, imagePoints)) - mode = CALIBRATED; - else - mode = DETECTION; - } - if(view.empty()) // If no more images then run calibration, save and stop loop. - { - if( imagePoints.size() > 0 ) - runCalibrationAndSave(s, imageSize, cameraMatrix, distCoeffs, imagePoints); - break; - imageSize = view.size(); // Format input image. - if( s.flipVertical ) flip( view, view, 0 ); - } - @endcode + @snippet samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp get_input For some cameras we may need to flip the input image. Here we do this too. --# **Find the pattern in the current input**. The formation of the equations I mentioned above aims +-# **Find the pattern in the current input** + + The formation of the equations I mentioned above aims to finding major patterns in the input: in case of the chessboard this are corners of the squares and for the circles, well, the circles themselves. The position of these will form the result which will be written into the *pointBuf* vector. - @code{.cpp} - vector pointBuf; - - bool found; - switch( s.calibrationPattern ) // Find feature points on the input format - { - case Settings::CHESSBOARD: - found = findChessboardCorners( view, s.boardSize, pointBuf, - CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_FAST_CHECK | CALIB_CB_NORMALIZE_IMAGE); - break; - case Settings::CIRCLES_GRID: - found = findCirclesGrid( view, s.boardSize, pointBuf ); - break; - case Settings::ASYMMETRIC_CIRCLES_GRID: - found = findCirclesGrid( view, s.boardSize, pointBuf, CALIB_CB_ASYMMETRIC_GRID ); - break; - } - @endcode + @snippet samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp find_pattern Depending on the type of the input pattern you use either the @ref cv::findChessboardCorners or the @ref cv::findCirclesGrid function. For both of them you pass the current image and the size of the board and you'll get the positions of the patterns. Furthermore, they return a boolean @@ -188,109 +135,27 @@ Explanation *imagePoints* vector to collect all of the equations into a single container. Finally, for visualization feedback purposes we will draw the found points on the input image using @ref cv::findChessboardCorners function. - @code{.cpp} - if ( found) // If done with success, - { - // improve the found corners' coordinate accuracy for chessboard - if( s.calibrationPattern == Settings::CHESSBOARD) - { - Mat viewGray; - cvtColor(view, viewGray, COLOR_BGR2GRAY); - cornerSubPix( viewGray, pointBuf, Size(11,11), - Size(-1,-1), TermCriteria( TermCriteria::EPS+TermCriteria::MAX_ITER, 30, 0.1 )); - } + @snippet samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp pattern_found +-# **Show state and result to the user, plus command line control of the application** - if( mode == CAPTURING && // For camera only take new samples after delay time - (!s.inputCapture.isOpened() || clock() - prevTimestamp > s.delay*1e-3*CLOCKS_PER_SEC) ) - { - imagePoints.push_back(pointBuf); - prevTimestamp = clock(); - blinkOutput = s.inputCapture.isOpened(); - } - - // Draw the corners. - drawChessboardCorners( view, s.boardSize, Mat(pointBuf), found ); - } - @endcode --# **Show state and result to the user, plus command line control of the application**. This part - shows text output on the image. - @code{.cpp} - //----------------------------- Output Text ------------------------------------------------ - string msg = (mode == CAPTURING) ? "100/100" : - mode == CALIBRATED ? "Calibrated" : "Press 'g' to start"; - int baseLine = 0; - Size textSize = getTextSize(msg, 1, 1, 1, &baseLine); - Point textOrigin(view.cols - 2*textSize.width - 10, view.rows - 2*baseLine - 10); - - if( mode == CAPTURING ) - { - if(s.showUndistorsed) - msg = format( "%d/%d Undist", (int)imagePoints.size(), s.nrFrames ); - else - msg = format( "%d/%d", (int)imagePoints.size(), s.nrFrames ); - } - - putText( view, msg, textOrigin, 1, 1, mode == CALIBRATED ? GREEN : RED); - - if( blinkOutput ) - bitwise_not(view, view); - @endcode + This part shows text output on the image. + @snippet samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp output_text If we ran calibration and got camera's matrix with the distortion coefficients we may want to correct the image using @ref cv::undistort function: - @code{.cpp} - //------------------------- Video capture output undistorted ------------------------------ - if( mode == CALIBRATED && s.showUndistorsed ) - { - Mat temp = view.clone(); - undistort(temp, view, cameraMatrix, distCoeffs); - } - //------------------------------ Show image and check for input commands ------------------- - imshow("Image View", view); - @endcode - Then we wait for an input key and if this is *u* we toggle the distortion removal, if it is *g* - we start again the detection process, and finally for the *ESC* key we quit the application: - @code{.cpp} - char key = waitKey(s.inputCapture.isOpened() ? 50 : s.delay); - if( key == ESC_KEY ) - break; + @snippet samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp output_undistorted + Then we show the image and wait for an input key and if this is *u* we toggle the distortion removal, + if it is *g* we start again the detection process, and finally for the *ESC* key we quit the application: + @snippet samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp await_input +-# **Show the distortion removal for the images too** - if( key == 'u' && mode == CALIBRATED ) - s.showUndistorsed = !s.showUndistorsed; - - if( s.inputCapture.isOpened() && key == 'g' ) - { - mode = CAPTURING; - imagePoints.clear(); - } - @endcode --# **Show the distortion removal for the images too**. When you work with an image list it is not + When you work with an image list it is not possible to remove the distortion inside the loop. Therefore, you must do this after the loop. Taking advantage of this now I'll expand the @ref cv::undistort function, which is in fact first calls @ref cv::initUndistortRectifyMap to find transformation matrices and then performs transformation using @ref cv::remap function. Because, after successful calibration map calculation needs to be done only once, by using this expanded form you may speed up your application: - @code{.cpp} - if( s.inputType == Settings::IMAGE_LIST && s.showUndistorsed ) - { - Mat view, rview, map1, map2; - initUndistortRectifyMap(cameraMatrix, distCoeffs, Mat(), - getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, 1, imageSize, 0), - imageSize, CV_16SC2, map1, map2); - - for(int i = 0; i < (int)s.imageList.size(); i++ ) - { - view = imread(s.imageList[i], 1); - if(view.empty()) - continue; - remap(view, rview, map1, map2, INTER_LINEAR); - imshow("Image View", rview); - char c = waitKey(); - if( c == ESC_KEY || c == 'q' || c == 'Q' ) - break; - } - } - @endcode + @snippet samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp show_results The calibration and save ------------------------ @@ -304,24 +169,7 @@ Therefore in the first function we just split up these two processes. Because we of the calibration variables we'll create these variables here and pass on both of them to the calibration and saving function. Again, I'll not show the saving part as that has little in common with the calibration. Explore the source file in order to find out how and what: -@code{.cpp} -bool runCalibrationAndSave(Settings& s, Size imageSize, Mat& cameraMatrix, Mat& distCoeffs,vector > imagePoints ) -{ - vector rvecs, tvecs; - vector reprojErrs; - double totalAvgErr = 0; - - bool ok = runCalibration(s,imageSize, cameraMatrix, distCoeffs, imagePoints, rvecs, tvecs, - reprojErrs, totalAvgErr); - cout << (ok ? "Calibration succeeded" : "Calibration failed") - << ". avg re projection error = " << totalAvgErr ; - - if( ok ) // save only if the calibration was done with success - saveCameraParams( s, imageSize, cameraMatrix, distCoeffs, rvecs ,tvecs, reprojErrs, - imagePoints, totalAvgErr); - return ok; -} -@endcode +@snippet samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp run_and_save We do the calibration with the help of the @ref cv::calibrateCamera function. It has the following parameters: @@ -331,29 +179,7 @@ parameters: present. Because, we use a single pattern for all the input images we can calculate this just once and multiply it for all the other input views. We calculate the corner points with the *calcBoardCornerPositions* function as: - @code{.cpp} - void calcBoardCornerPositions(Size boardSize, float squareSize, vector& corners, - Settings::Pattern patternType /*= Settings::CHESSBOARD*/) - { - corners.clear(); - - switch(patternType) - { - case Settings::CHESSBOARD: - case Settings::CIRCLES_GRID: - for( int i = 0; i < boardSize.height; ++i ) - for( int j = 0; j < boardSize.width; ++j ) - corners.push_back(Point3f(float( j*squareSize ), float( i*squareSize ), 0)); - break; - - case Settings::ASYMMETRIC_CIRCLES_GRID: - for( int i = 0; i < boardSize.height; i++ ) - for( int j = 0; j < boardSize.width; j++ ) - corners.push_back(Point3f(float((2*j + i % 2)*squareSize), float(i*squareSize), 0)); - break; - } - } - @endcode + @snippet samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp board_corners And then multiply it as: @code{.cpp} vector > objectPoints(1); @@ -365,12 +191,8 @@ parameters: circle pattern). We have already collected this from @ref cv::findChessboardCorners or @ref cv::findCirclesGrid function. We just need to pass it on. - The size of the image acquired from the camera, video file or the images. -- The camera matrix. If we used the fixed aspect ratio option we need to set the \f$f_x\f$ to zero: - @code{.cpp} - cameraMatrix = Mat::eye(3, 3, CV_64F); - if( s.flag & CALIB_FIX_ASPECT_RATIO ) - cameraMatrix.at(0,0) = 1.0; - @endcode +- The camera matrix. If we used the fixed aspect ratio option we need to set \f$f_x\f$: + @snippet samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp fixed_aspect - The distortion coefficient matrix. Initialize with zero. @code{.cpp} distCoeffs = Mat::zeros(8, 1, CV_64F); @@ -393,33 +215,7 @@ double rms = calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, calculate the absolute norm between what we got with our transformation and the corner/circle finding algorithm. To find the average error we calculate the arithmetical mean of the errors calculated for all the calibration images. - @code{.cpp} - double computeReprojectionErrors( const vector >& objectPoints, - const vector >& imagePoints, - const vector& rvecs, const vector& tvecs, - const Mat& cameraMatrix , const Mat& distCoeffs, - vector& perViewErrors) - { - vector imagePoints2; - int i, totalPoints = 0; - double totalErr = 0, err; - perViewErrors.resize(objectPoints.size()); - - for( i = 0; i < (int)objectPoints.size(); ++i ) - { - projectPoints( Mat(objectPoints[i]), rvecs[i], tvecs[i], cameraMatrix, // project - distCoeffs, imagePoints2); - err = norm(Mat(imagePoints[i]), Mat(imagePoints2), NORM_L2); // difference - - int n = (int)objectPoints[i].size(); - perViewErrors[i] = (float) std::sqrt(err*err/n); // save for this view - totalErr += err*err; // sum it up - totalPoints += n; - } - - return std::sqrt(totalErr/totalPoints); // calculate the arithmetical mean - } - @endcode + @snippet samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp compute_errors Results ------- @@ -461,20 +257,20 @@ the input. Here's, how a detected pattern should look: In both cases in the specified output XML/YAML file you'll find the camera and distortion coefficients matrices: @code{.xml} - + 3 3
d
6.5746697944293521e+002 0. 3.1950000000000000e+002 0. - 6.5746697944293521e+002 2.3950000000000000e+002 0. 0. 1.
- + 6.5746697944293521e+002 2.3950000000000000e+002 0. 0. 1.
+ 5 1
d
-4.1802327176423804e-001 5.0715244063187526e-001 0. 0. - -5.7843597214487474e-001
+ -5.7843597214487474e-001 @endcode Add these values as constants to your program, call the @ref cv::initUndistortRectifyMap and the @ref cv::remap function to remove distortion and enjoy distortion free inputs for cheap and low diff --git a/samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp b/samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp index 34e2504c6e..8059a4aec5 100644 --- a/samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp +++ b/samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp @@ -34,7 +34,8 @@ public: void write(FileStorage& fs) const //Write serialization for this class { - fs << "{" << "BoardSize_Width" << boardSize.width + fs << "{" + << "BoardSize_Width" << boardSize.width << "BoardSize_Height" << boardSize.height << "Square_Size" << squareSize << "Calibrate_Pattern" << patternToUse @@ -43,8 +44,8 @@ public: << "Calibrate_AssumeZeroTangentialDistortion" << calibZeroTangentDist << "Calibrate_FixPrincipalPointAtTheCenter" << calibFixPrincipalPoint - << "Write_DetectedFeaturePoints" << bwritePoints - << "Write_extrinsicParameters" << bwriteExtrinsics + << "Write_DetectedFeaturePoints" << writePoints + << "Write_extrinsicParameters" << writeExtrinsics << "Write_outputFileName" << outputFileName << "Show_UndistortedImage" << showUndistorsed @@ -62,8 +63,8 @@ public: node["Square_Size"] >> squareSize; node["Calibrate_NrOfFrameToUse"] >> nrFrames; node["Calibrate_FixAspectRatio"] >> aspectRatio; - node["Write_DetectedFeaturePoints"] >> bwritePoints; - node["Write_extrinsicParameters"] >> bwriteExtrinsics; + node["Write_DetectedFeaturePoints"] >> writePoints; + node["Write_extrinsicParameters"] >> writeExtrinsics; node["Write_outputFileName"] >> outputFileName; node["Calibrate_AssumeZeroTangentialDistortion"] >> calibZeroTangentDist; node["Calibrate_FixPrincipalPointAtTheCenter"] >> calibFixPrincipalPoint; @@ -71,9 +72,9 @@ public: node["Show_UndistortedImage"] >> showUndistorsed; node["Input"] >> input; node["Input_Delay"] >> delay; - interprate(); + validate(); } - void interprate() + void validate() { goodInput = true; if (boardSize.width <= 0 || boardSize.height <= 0) @@ -105,10 +106,10 @@ public: else { if (readStringList(input, imageList)) - { - inputType = IMAGE_LIST; - nrFrames = (nrFrames < (int)imageList.size()) ? nrFrames : (int)imageList.size(); - } + { + inputType = IMAGE_LIST; + nrFrames = (nrFrames < (int)imageList.size()) ? nrFrames : (int)imageList.size(); + } else inputType = VIDEO_FILE; } @@ -121,7 +122,7 @@ public: } if (inputType == INVALID) { - cerr << " Inexistent input: " << input; + cerr << " Input does not exist: " << input; goodInput = false; } @@ -136,10 +137,10 @@ public: if (!patternToUse.compare("CIRCLES_GRID")) calibrationPattern = CIRCLES_GRID; if (!patternToUse.compare("ASYMMETRIC_CIRCLES_GRID")) calibrationPattern = ASYMMETRIC_CIRCLES_GRID; if (calibrationPattern == NOT_EXISTING) - { - cerr << " Inexistent camera calibration mode: " << patternToUse << endl; - goodInput = false; - } + { + cerr << " Camera calibration mode does not exist: " << patternToUse << endl; + goodInput = false; + } atImageList = 0; } @@ -152,7 +153,7 @@ public: inputCapture >> view0; view0.copyTo(result); } - else if( atImageList < (int)imageList.size() ) + else if( atImageList < imageList.size() ) result = imread(imageList[atImageList++], IMREAD_COLOR); return result; @@ -173,26 +174,24 @@ public: return true; } public: - Size boardSize; // The size of the board -> Number of items by width and height - Pattern calibrationPattern;// One of the Chessboard, circles, or asymmetric circle pattern - float squareSize; // The size of a square in your defined unit (point, millimeter,etc). - int nrFrames; // The number of frames to use from the input for calibration - float aspectRatio; // The aspect ratio - int delay; // In case of a video input - bool bwritePoints; // Write detected feature points - bool bwriteExtrinsics; // Write extrinsic parameters - bool calibZeroTangentDist; // Assume zero tangential distortion - bool calibFixPrincipalPoint;// Fix the principal point at the center - bool flipVertical; // Flip the captured images around the horizontal axis - string outputFileName; // The name of the file where to write - bool showUndistorsed; // Show undistorted images after calibration - string input; // The input -> - - + Size boardSize; // The size of the board -> Number of items by width and height + Pattern calibrationPattern; // One of the Chessboard, circles, or asymmetric circle pattern + float squareSize; // The size of a square in your defined unit (point, millimeter,etc). + int nrFrames; // The number of frames to use from the input for calibration + float aspectRatio; // The aspect ratio + int delay; // In case of a video input + bool writePoints; // Write detected feature points + bool writeExtrinsics; // Write extrinsic parameters + bool calibZeroTangentDist; // Assume zero tangential distortion + bool calibFixPrincipalPoint; // Fix the principal point at the center + bool flipVertical; // Flip the captured images around the horizontal axis + string outputFileName; // The name of the file where to write + bool showUndistorsed; // Show undistorted images after calibration + string input; // The input -> int cameraID; vector imageList; - int atImageList; + size_t atImageList; VideoCapture inputCapture; InputType inputType; bool goodInput; @@ -204,7 +203,7 @@ private: }; -static void read(const FileNode& node, Settings& x, const Settings& default_value = Settings()) +static inline void read(const FileNode& node, Settings& x, const Settings& default_value = Settings()) { if(node.empty()) x = default_value; @@ -212,6 +211,11 @@ static void read(const FileNode& node, Settings& x, const Settings& default_valu x.read(node); } +static inline void write(FileStorage& fs, const String&, const Settings& s ) +{ + s.write(fs); +} + enum { DETECTION = 0, CAPTURING = 1, CALIBRATED = 2 }; bool runCalibrationAndSave(Settings& s, Size imageSize, Mat& cameraMatrix, Mat& distCoeffs, @@ -220,6 +224,8 @@ bool runCalibrationAndSave(Settings& s, Size imageSize, Mat& cameraMatrix, Mat& int main(int argc, char* argv[]) { help(); + + //! [file_read] Settings s; const string inputSettingsFile = argc > 1 ? argv[1] : "default.xml"; FileStorage fs(inputSettingsFile, FileStorage::READ); // Read the settings @@ -230,6 +236,10 @@ int main(int argc, char* argv[]) } fs["Settings"] >> s; fs.release(); // close Settings file + //! [file_read] + + //FileStorage fout("settings.yml", FileStorage::WRITE); // write config as YAML + //fout << "Settings" << s; if (!s.goodInput) { @@ -245,32 +255,35 @@ int main(int argc, char* argv[]) const Scalar RED(0,0,255), GREEN(0,255,0); const char ESC_KEY = 27; - for(int i = 0;;++i) + //! [get_input] + for(;;) { - Mat view; - bool blinkOutput = false; + Mat view; + bool blinkOutput = false; - view = s.nextImage(); + view = s.nextImage(); - //----- If no more image, or got enough, then stop calibration and show result ------------- - if( mode == CAPTURING && imagePoints.size() >= (unsigned)s.nrFrames ) - { + //----- If no more image, or got enough, then stop calibration and show result ------------- + if( mode == CAPTURING && imagePoints.size() >= (size_t)s.nrFrames ) + { if( runCalibrationAndSave(s, imageSize, cameraMatrix, distCoeffs, imagePoints)) mode = CALIBRATED; else mode = DETECTION; - } - if(view.empty()) // If no more images then run calibration, save and stop loop. - { - if( imagePoints.size() > 0 ) + } + if(view.empty()) // If there are no more images stop the loop + { + // if calibration threshold was not reached yet, calibrate now + if( mode != CALIBRATED && !imagePoints.empty() ) runCalibrationAndSave(s, imageSize, cameraMatrix, distCoeffs, imagePoints); break; - } - + } + //! [get_input] imageSize = view.size(); // Format input image. if( s.flipVertical ) flip( view, view, 0 ); + //! [find_pattern] vector pointBuf; bool found; @@ -290,7 +303,8 @@ int main(int argc, char* argv[]) found = false; break; } - + //! [find_pattern] + //! [pattern_found] if ( found) // If done with success, { // improve the found corners' coordinate accuracy for chessboard @@ -313,8 +327,9 @@ int main(int argc, char* argv[]) // Draw the corners. drawChessboardCorners( view, s.boardSize, Mat(pointBuf), found ); } - + //! [pattern_found] //----------------------------- Output Text ------------------------------------------------ + //! [output_text] string msg = (mode == CAPTURING) ? "100/100" : mode == CALIBRATED ? "Calibrated" : "Press 'g' to start"; int baseLine = 0; @@ -333,15 +348,17 @@ int main(int argc, char* argv[]) if( blinkOutput ) bitwise_not(view, view); - + //! [output_text] //------------------------- Video capture output undistorted ------------------------------ + //! [output_undistorted] if( mode == CALIBRATED && s.showUndistorsed ) { Mat temp = view.clone(); undistort(temp, view, cameraMatrix, distCoeffs); } - + //! [output_undistorted] //------------------------------ Show image and check for input commands ------------------- + //! [await_input] imshow("Image View", view); char key = (char)waitKey(s.inputCapture.isOpened() ? 50 : s.delay); @@ -356,9 +373,11 @@ int main(int argc, char* argv[]) mode = CAPTURING; imagePoints.clear(); } + //! [await_input] } // -----------------------Show the undistorted image for the image list ------------------------ + //! [show_results] if( s.inputType == Settings::IMAGE_LIST && s.showUndistorsed ) { Mat view, rview, map1, map2; @@ -366,7 +385,7 @@ int main(int argc, char* argv[]) getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, 1, imageSize, 0), imageSize, CV_16SC2, map1, map2); - for(int i = 0; i < (int)s.imageList.size(); i++ ) + for(size_t i = 0; i < s.imageList.size(); i++ ) { view = imread(s.imageList[i], 1); if(view.empty()) @@ -378,11 +397,12 @@ int main(int argc, char* argv[]) break; } } - + //! [show_results] return 0; } +//! [compute_errors] static double computeReprojectionErrors( const vector >& objectPoints, const vector >& imagePoints, const vector& rvecs, const vector& tvecs, @@ -390,17 +410,16 @@ static double computeReprojectionErrors( const vector >& objectP vector& perViewErrors) { vector imagePoints2; - int i, totalPoints = 0; + size_t totalPoints = 0; double totalErr = 0, err; perViewErrors.resize(objectPoints.size()); - for( i = 0; i < (int)objectPoints.size(); ++i ) + for(size_t i = 0; i < objectPoints.size(); ++i ) { - projectPoints( Mat(objectPoints[i]), rvecs[i], tvecs[i], cameraMatrix, - distCoeffs, imagePoints2); - err = norm(Mat(imagePoints[i]), Mat(imagePoints2), NORM_L2); + projectPoints(objectPoints[i], rvecs[i], tvecs[i], cameraMatrix, distCoeffs, imagePoints2); + err = norm(imagePoints[i], imagePoints2, NORM_L2); - int n = (int)objectPoints[i].size(); + size_t n = objectPoints[i].size(); perViewErrors[i] = (float) std::sqrt(err*err/n); totalErr += err*err; totalPoints += n; @@ -408,7 +427,8 @@ static double computeReprojectionErrors( const vector >& objectP return std::sqrt(totalErr/totalPoints); } - +//! [compute_errors] +//! [board_corners] static void calcBoardCornerPositions(Size boardSize, float squareSize, vector& corners, Settings::Pattern patternType /*= Settings::CHESSBOARD*/) { @@ -420,28 +440,28 @@ static void calcBoardCornerPositions(Size boardSize, float squareSize, vector > imagePoints, vector& rvecs, vector& tvecs, vector& reprojErrs, double& totalAvgErr) { - + //! [fixed_aspect] cameraMatrix = Mat::eye(3, 3, CV_64F); if( s.flag & CALIB_FIX_ASPECT_RATIO ) - cameraMatrix.at(0,0) = 1.0; - + cameraMatrix.at(0,0) = s.aspectRatio; + //! [fixed_aspect] distCoeffs = Mat::zeros(8, 1, CV_64F); vector > objectPoints(1); @@ -475,49 +495,48 @@ static void saveCameraParams( Settings& s, Size& imageSize, Mat& cameraMatrix, M time( &tm ); struct tm *t2 = localtime( &tm ); char buf[1024]; - strftime( buf, sizeof(buf)-1, "%c", t2 ); + strftime( buf, sizeof(buf), "%c", t2 ); - fs << "calibration_Time" << buf; + fs << "calibration_time" << buf; if( !rvecs.empty() || !reprojErrs.empty() ) - fs << "nrOfFrames" << (int)std::max(rvecs.size(), reprojErrs.size()); - fs << "image_Width" << imageSize.width; - fs << "image_Height" << imageSize.height; - fs << "board_Width" << s.boardSize.width; - fs << "board_Height" << s.boardSize.height; - fs << "square_Size" << s.squareSize; + fs << "nr_of_frames" << (int)std::max(rvecs.size(), reprojErrs.size()); + fs << "image_width" << imageSize.width; + fs << "image_height" << imageSize.height; + fs << "board_width" << s.boardSize.width; + fs << "board_height" << s.boardSize.height; + fs << "square_size" << s.squareSize; if( s.flag & CALIB_FIX_ASPECT_RATIO ) - fs << "FixAspectRatio" << s.aspectRatio; + fs << "fix_aspect_ratio" << s.aspectRatio; - if( s.flag ) + if (s.flag) { - sprintf( buf, "flags: %s%s%s%s", - s.flag & CALIB_USE_INTRINSIC_GUESS ? " +use_intrinsic_guess" : "", - s.flag & CALIB_FIX_ASPECT_RATIO ? " +fix_aspectRatio" : "", - s.flag & CALIB_FIX_PRINCIPAL_POINT ? " +fix_principal_point" : "", - s.flag & CALIB_ZERO_TANGENT_DIST ? " +zero_tangent_dist" : "" ); - //cvWriteComment( *fs, buf, 0 ); - + sprintf(buf, "flags: %s%s%s%s", + s.flag & CALIB_USE_INTRINSIC_GUESS ? " +use_intrinsic_guess" : "", + s.flag & CALIB_FIX_ASPECT_RATIO ? " +fix_aspect_ratio" : "", + s.flag & CALIB_FIX_PRINCIPAL_POINT ? " +fix_principal_point" : "", + s.flag & CALIB_ZERO_TANGENT_DIST ? " +zero_tangent_dist" : ""); + cvWriteComment(*fs, buf, 0); } - fs << "flagValue" << s.flag; + fs << "flags" << s.flag; - fs << "Camera_Matrix" << cameraMatrix; - fs << "Distortion_Coefficients" << distCoeffs; + fs << "camera_matrix" << cameraMatrix; + fs << "distortion_coefficients" << distCoeffs; - fs << "Avg_Reprojection_Error" << totalAvgErr; - if( !reprojErrs.empty() ) - fs << "Per_View_Reprojection_Errors" << Mat(reprojErrs); + fs << "avg_reprojection_error" << totalAvgErr; + if (s.writeExtrinsics && !reprojErrs.empty()) + fs << "per_view_reprojection_errors" << Mat(reprojErrs); - if( !rvecs.empty() && !tvecs.empty() ) + if(s.writeExtrinsics && !rvecs.empty() && !tvecs.empty() ) { CV_Assert(rvecs[0].type() == tvecs[0].type()); Mat bigmat((int)rvecs.size(), 6, rvecs[0].type()); - for( int i = 0; i < (int)rvecs.size(); i++ ) + for( size_t i = 0; i < rvecs.size(); i++ ) { - Mat r = bigmat(Range(i, i+1), Range(0,3)); - Mat t = bigmat(Range(i, i+1), Range(3,6)); + Mat r = bigmat(Range(int(i), int(i+1)), Range(0,3)); + Mat t = bigmat(Range(int(i), int(i+1)), Range(3,6)); CV_Assert(rvecs[i].rows == 3 && rvecs[i].cols == 1); CV_Assert(tvecs[i].rows == 3 && tvecs[i].cols == 1); @@ -526,35 +545,38 @@ static void saveCameraParams( Settings& s, Size& imageSize, Mat& cameraMatrix, M t = tvecs[i].t(); } //cvWriteComment( *fs, "a set of 6-tuples (rotation vector + translation vector) for each view", 0 ); - fs << "Extrinsic_Parameters" << bigmat; + fs << "extrinsic_parameters" << bigmat; } - if( !imagePoints.empty() ) + if(s.writePoints && !imagePoints.empty() ) { Mat imagePtMat((int)imagePoints.size(), (int)imagePoints[0].size(), CV_32FC2); - for( int i = 0; i < (int)imagePoints.size(); i++ ) + for( size_t i = 0; i < imagePoints.size(); i++ ) { - Mat r = imagePtMat.row(i).reshape(2, imagePtMat.cols); + Mat r = imagePtMat.row(int(i)).reshape(2, imagePtMat.cols); Mat imgpti(imagePoints[i]); imgpti.copyTo(r); } - fs << "Image_points" << imagePtMat; + fs << "image_points" << imagePtMat; } } -bool runCalibrationAndSave(Settings& s, Size imageSize, Mat& cameraMatrix, Mat& distCoeffs,vector > imagePoints ) +//! [run_and_save] +bool runCalibrationAndSave(Settings& s, Size imageSize, Mat& cameraMatrix, Mat& distCoeffs, + vector > imagePoints) { vector rvecs, tvecs; vector reprojErrs; double totalAvgErr = 0; - bool ok = runCalibration(s,imageSize, cameraMatrix, distCoeffs, imagePoints, rvecs, tvecs, - reprojErrs, totalAvgErr); + bool ok = runCalibration(s, imageSize, cameraMatrix, distCoeffs, imagePoints, rvecs, tvecs, reprojErrs, + totalAvgErr); cout << (ok ? "Calibration succeeded" : "Calibration failed") - << ". avg re projection error = " << totalAvgErr ; + << ". avg re projection error = " << totalAvgErr << endl; - if( ok ) - saveCameraParams( s, imageSize, cameraMatrix, distCoeffs, rvecs ,tvecs, reprojErrs, - imagePoints, totalAvgErr); + if (ok) + saveCameraParams(s, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs, reprojErrs, imagePoints, + totalAvgErr); return ok; } +//! [run_and_save] From 75850a13512efb8b1b5fd2ecc94d011e9e255b1e Mon Sep 17 00:00:00 2001 From: Maxim Kostin Date: Tue, 31 Mar 2015 17:09:09 +0300 Subject: [PATCH 010/109] Added sample imgcodecs logic to winrt sample app - Made use imread() in OcvImageProcessing sample. - Added test/sample logic to verify file creation via imgcodecs. Signed-off-by: Maxim Kostin --- .../OcvImageProcessing/MainPage.xaml.cpp | 84 ++++++++++++++++++- .../OcvImageProcessing/MainPage.xaml.h | 5 ++ .../OcvImageProcessing/opencv.props | 5 +- 3 files changed, 90 insertions(+), 4 deletions(-) diff --git a/samples/winrt/OcvImageProcessing/OcvImageProcessing/MainPage.xaml.cpp b/samples/winrt/OcvImageProcessing/OcvImageProcessing/MainPage.xaml.cpp index 2e91eb156b..fc7440fb29 100644 --- a/samples/winrt/OcvImageProcessing/OcvImageProcessing/MainPage.xaml.cpp +++ b/samples/winrt/OcvImageProcessing/OcvImageProcessing/MainPage.xaml.cpp @@ -10,6 +10,10 @@ #include #include #include +#include +#include + +#include using namespace OcvImageProcessing; @@ -18,6 +22,7 @@ using namespace concurrency; using namespace Platform; using namespace Windows::Foundation; using namespace Windows::Storage::Streams; +using namespace Windows::Storage; using namespace Windows::UI::Xaml::Media::Imaging; using namespace Windows::Graphics::Imaging; using namespace Windows::Foundation::Collections; @@ -37,6 +42,17 @@ MainPage::MainPage() { InitializeComponent(); +#ifdef __OPENCV_IMGCODECS_HPP__ + + // Image loading OpenCV way ... way more simple + cv::Mat image = cv::imread("Assets/Lena.png"); + Lena = cv::Mat(image.rows, image.cols, CV_8UC4); + cvtColor(image, Lena, CV_BGR2BGRA); + UpdateImage(Lena); + +#else + + // Image loading WinRT way RandomAccessStreamReference^ streamRef = RandomAccessStreamReference::CreateFromUri(InputImageUri); task (streamRef->OpenReadAsync()). @@ -68,6 +84,67 @@ MainPage::MainPage() memcpy(Lena.data, srcPixels->Data, 4*frameWidth*frameHeight); UpdateImage(Lena); }); + +#endif +} + +/// +/// Temporary file creation example. Will be created in WinRT application temporary directory +/// which usually is "C:\Users\{username}\AppData\Local\Packages\{package_id}\TempState\{random_name}.{suffix}" +/// +/// Temporary file suffix, e.g. "tmp" +std::string OcvImageProcessing::MainPage::CreateTempFile(const std::string &suffix) { + return cv::tempfile(suffix.c_str()); +} + +/// +/// Creating/writing a file in the application local directory +/// +/// Image to save +bool OcvImageProcessing::MainPage::SaveImage(cv::Mat image) { + StorageFolder^ localFolderRT = ApplicationData::Current->LocalFolder; + cv::String localFile = ConvertPath(ApplicationData::Current->LocalFolder->Path) + "\\Lena.png"; + + return cv::imwrite(localFile, image); +} + +/// +/// Getting std::string from managed string via std::wstring. +/// Provides an example of three ways to do it. +/// Can't use this one: https://msdn.microsoft.com/en-us/library/bb384865.aspx, not available on WinRT. +/// +/// Path to be converted +cv::String OcvImageProcessing::MainPage::ConvertPath(Platform::String^ path) { + std::wstring localPathW(path->Begin()); + + // Opt #1 + //std::string localPath(localPathW.begin(), localPathW.end()); + + // Opt #2 + //std::string localPath(StrToWStr(localPathW)); + + // Opt #3 + size_t outSize = localPathW.length() + 1; + char* localPathC = new char[outSize]; + size_t charsConverted = 0; + wcstombs_s(&charsConverted, localPathC, outSize, localPathW.c_str(), localPathW.length()); + cv::String localPath(localPathC); + + // Implicit conversion from std::string to cv::String + return localPath; +} + +std::string OcvImageProcessing::MainPage::StrToWStr(const std::wstring &input) { + if (input.empty()) { + return std::string(); + } + + int size = WideCharToMultiByte(CP_UTF8, 0, &input[0], (int)input.size(), NULL, 0, NULL, NULL); + std::string result(size, 0); + + WideCharToMultiByte(CP_UTF8, 0, &input[0], (int)input.size(), &result[0], size, NULL, NULL); + + return result; } /// @@ -91,15 +168,16 @@ void OcvImageProcessing::MainPage::UpdateImage(const cv::Mat& image) // Obtain IBufferByteAccess ComPtr pBufferByteAccess; - ComPtr pBuffer((IUnknown*)buffer); + ComPtr pBuffer((IInspectable*)buffer); pBuffer.As(&pBufferByteAccess); // Get pointer to pixel bytes pBufferByteAccess->Buffer(&dstPixels); - memcpy(dstPixels, image.data, 4*image.cols*image.rows); + memcpy(dstPixels, image.data, image.step.buf[1]*image.cols*image.rows); // Set the bitmap to the Image element - PreviewWidget->Source = bitmap;} + PreviewWidget->Source = bitmap; +} cv::Mat OcvImageProcessing::MainPage::ApplyGrayFilter(const cv::Mat& image) diff --git a/samples/winrt/OcvImageProcessing/OcvImageProcessing/MainPage.xaml.h b/samples/winrt/OcvImageProcessing/OcvImageProcessing/MainPage.xaml.h index 79c1ac74c6..bb7c4c33d5 100644 --- a/samples/winrt/OcvImageProcessing/OcvImageProcessing/MainPage.xaml.h +++ b/samples/winrt/OcvImageProcessing/OcvImageProcessing/MainPage.xaml.h @@ -39,6 +39,11 @@ namespace OcvImageProcessing cv::Mat ApplySepiaFilter(const cv::Mat& image); void UpdateImage(const cv::Mat& image); + std::string CreateTempFile(const std::string &suffix); + bool SaveImage(cv::Mat image); + + std::string StrToWStr(const std::wstring &wstr); + cv::String ConvertPath(Platform::String^ path); cv::Mat Lena; unsigned int frameWidth, frameHeight; diff --git a/samples/winrt/OcvImageProcessing/OcvImageProcessing/opencv.props b/samples/winrt/OcvImageProcessing/OcvImageProcessing/opencv.props index 40eaffd1f0..64b0ac98aa 100644 --- a/samples/winrt/OcvImageProcessing/OcvImageProcessing/opencv.props +++ b/samples/winrt/OcvImageProcessing/OcvImageProcessing/opencv.props @@ -17,6 +17,9 @@ true + + true + true @@ -33,7 +36,7 @@ - opencv_core300$(DebugSuffix).lib;opencv_imgproc300$(DebugSuffix).lib;opencv_features2d300$(DebugSuffix).lib;opencv_flann300$(DebugSuffix).lib;opencv_ml300$(DebugSuffix).lib;%(AdditionalDependencies) + opencv_core300$(DebugSuffix).lib;opencv_imgproc300$(DebugSuffix).lib;opencv_features2d300$(DebugSuffix).lib;opencv_flann300$(DebugSuffix).lib;opencv_ml300$(DebugSuffix).lib;opencv_imgcodecs300$(DebugSuffix).lib;%(AdditionalDependencies) $(OpenCV_Lib);%(AdditionalLibraryDirectories); From 952f9dbe629e8e9f310c70c78ed46d484439c1c9 Mon Sep 17 00:00:00 2001 From: Dikay900 Date: Wed, 1 Apr 2015 20:22:27 +0200 Subject: [PATCH 011/109] initialize tiltedOffset variable at correct location do not use this variable if it is not an tilted feature --- modules/objdetect/src/cascadedetect.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/objdetect/src/cascadedetect.cpp b/modules/objdetect/src/cascadedetect.cpp index 46a1d60f2d..bc1fedc80b 100644 --- a/modules/objdetect/src/cascadedetect.cpp +++ b/modules/objdetect/src/cascadedetect.cpp @@ -618,8 +618,7 @@ Ptr HaarEvaluator::clone() const void HaarEvaluator::computeChannels(int scaleIdx, InputArray img) { const ScaleData& s = scaleData->at(scaleIdx); - tofs = (int)sbufSize.area(); - sqofs = hasTiltedFeatures ? tofs*2 : tofs; + sqofs = hasTiltedFeatures ? sbufSize.area() * 2 : sbufSize.area(); if (img.isUMat()) { @@ -660,6 +659,9 @@ void HaarEvaluator::computeChannels(int scaleIdx, InputArray img) void HaarEvaluator::computeOptFeatures() { + if (hasTiltedFeatures) + tofs = sbufSize.area(); + int sstep = sbufSize.width; CV_SUM_OFS( nofs[0], nofs[1], nofs[2], nofs[3], 0, normrect, sstep ); From 6593422c05e85f41063f32b7799d6412caa17ed7 Mon Sep 17 00:00:00 2001 From: Sancho McCann Date: Wed, 1 Apr 2015 19:00:39 +0000 Subject: [PATCH 012/109] Bugfix: #4030 SVM auto-training. --- modules/ml/src/svm.cpp | 6 +- modules/ml/test/test_svmtrainauto.cpp | 89 +++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 modules/ml/test/test_svmtrainauto.cpp diff --git a/modules/ml/src/svm.cpp b/modules/ml/src/svm.cpp index 8bed117639..449eb8dcd4 100644 --- a/modules/ml/src/svm.cpp +++ b/modules/ml/src/svm.cpp @@ -1669,13 +1669,13 @@ public: Mat samples = data->getTrainSamples(); Mat responses; bool is_classification = false; - Mat class_labels0 = class_labels; int class_count = (int)class_labels.total(); if( svmType == C_SVC || svmType == NU_SVC ) { responses = data->getTrainNormCatResponses(); class_labels = data->getClassLabels(); + class_count = (int)class_labels.total(); is_classification = true; vector temp_class_labels; @@ -1755,8 +1755,9 @@ public: Mat temp_train_responses(train_sample_count, 1, rtype); Mat temp_test_responses; + // If grid.minVal == grid.maxVal, this will allow one and only one pass through the loop with params.var = grid.minVal. #define FOR_IN_GRID(var, grid) \ - for( params.var = grid.minVal; params.var == grid.minVal || params.var < grid.maxVal; params.var *= grid.logStep ) + for( params.var = grid.minVal; params.var == grid.minVal || params.var < grid.maxVal; params.var = (grid.minVal == grid.maxVal) ? grid.maxVal + 1 : params.var * grid.logStep ) FOR_IN_GRID(C, C_grid) FOR_IN_GRID(gamma, gamma_grid) @@ -1814,7 +1815,6 @@ public: } params = best_params; - class_labels = class_labels0; return do_train( samples, responses ); } diff --git a/modules/ml/test/test_svmtrainauto.cpp b/modules/ml/test/test_svmtrainauto.cpp new file mode 100644 index 0000000000..918d2b7117 --- /dev/null +++ b/modules/ml/test/test_svmtrainauto.cpp @@ -0,0 +1,89 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; +using cv::ml::SVM; +using cv::ml::TrainData; + +//-------------------------------------------------------------------------------------------- +class CV_SVMTrainAutoTest : public cvtest::BaseTest { +public: + CV_SVMTrainAutoTest() {} +protected: + virtual void run( int start_from ); +}; + +void CV_SVMTrainAutoTest::run( int /*start_from*/ ) +{ + int datasize = 100; + cv::Mat samples = cv::Mat::zeros( datasize, 2, CV_32FC1 ); + cv::Mat responses = cv::Mat::zeros( datasize, 1, CV_32S ); + + RNG rng(0); + for (int i = 0; i < datasize; ++i) + { + int response = rng.uniform(0, 2); // Random from {0, 1}. + samples.at( i, 0 ) = rng.uniform(0.f, 0.5f) + response * 0.5f; + samples.at( i, 1 ) = rng.uniform(0.f, 0.5f) + response * 0.5f; + responses.at( i, 0 ) = response; + } + + cv::Ptr data = TrainData::create( samples, cv::ml::ROW_SAMPLE, responses ); + cv::Ptr svm = SVM::create(); + svm->trainAuto( data, 10 ); // 2-fold cross validation. + + float test_data0[2] = {0.25f, 0.25f}; + cv::Mat test_point0 = cv::Mat( 1, 2, CV_32FC1, test_data0 ); + float result0 = svm->predict( test_point0 ); + float test_data1[2] = {0.75f, 0.75f}; + cv::Mat test_point1 = cv::Mat( 1, 2, CV_32FC1, test_data1 ); + float result1 = svm->predict( test_point1 ); + + if ( fabs( result0 - 0 ) > 0.001 || fabs( result1 - 1 ) > 0.001 ) + { + ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); + } +} + +TEST(ML_SVM, trainauto) { CV_SVMTrainAutoTest test; test.safe_run(); } From 0df9dc8fb9aa5bda198fac4e747b1a8ea769e005 Mon Sep 17 00:00:00 2001 From: Simon Heinen Date: Thu, 2 Apr 2015 08:42:19 +0200 Subject: [PATCH 013/109] Update android+AsyncServiceHelper.java changed tabs in last commit to spaces --- .../generator/src/java/android+AsyncServiceHelper.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/java/generator/src/java/android+AsyncServiceHelper.java b/modules/java/generator/src/java/android+AsyncServiceHelper.java index b7c57f28c8..e1f8842356 100644 --- a/modules/java/generator/src/java/android+AsyncServiceHelper.java +++ b/modules/java/generator/src/java/android+AsyncServiceHelper.java @@ -21,11 +21,11 @@ class AsyncServiceHelper final LoaderCallbackInterface Callback) { AsyncServiceHelper helper = new AsyncServiceHelper(Version, AppContext, Callback); - Intent intent = new Intent("org.opencv.engine.BIND"); - intent.setPackage("org.opencv.engine"); - if (AppContext.bindService(intent, helper.mServiceConnection, - Context.BIND_AUTO_CREATE)) { - return true; + Intent intent = new Intent("org.opencv.engine.BIND"); + intent.setPackage("org.opencv.engine"); + if (AppContext.bindService(intent, helper.mServiceConnection, Context.BIND_AUTO_CREATE)) + { + return true; } else { From d2dc7f4c27b745561d5483ee1f2ef3b7a12fa2a0 Mon Sep 17 00:00:00 2001 From: Simon Heinen Date: Thu, 2 Apr 2015 09:05:56 +0200 Subject: [PATCH 014/109] Update android+AsyncServiceHelper.java small formatting fixes --- .../java/generator/src/java/android+AsyncServiceHelper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/java/generator/src/java/android+AsyncServiceHelper.java b/modules/java/generator/src/java/android+AsyncServiceHelper.java index e1f8842356..e18d5a5001 100644 --- a/modules/java/generator/src/java/android+AsyncServiceHelper.java +++ b/modules/java/generator/src/java/android+AsyncServiceHelper.java @@ -23,9 +23,9 @@ class AsyncServiceHelper AsyncServiceHelper helper = new AsyncServiceHelper(Version, AppContext, Callback); Intent intent = new Intent("org.opencv.engine.BIND"); intent.setPackage("org.opencv.engine"); - if (AppContext.bindService(intent, helper.mServiceConnection, Context.BIND_AUTO_CREATE)) + if (AppContext.bindService(intent, helper.mServiceConnection, Context.BIND_AUTO_CREATE)) { - return true; + return true; } else { From 7e35f76d06185d7ea53e1ff4d904b826c97c7407 Mon Sep 17 00:00:00 2001 From: StevenPuttemans Date: Fri, 6 Mar 2015 11:52:26 +0100 Subject: [PATCH 015/109] allowing people to manually define how sharp a cascade classifier model should be trained --- apps/traincascade/cascadeclassifier.cpp | 13 ++++++++++--- apps/traincascade/cascadeclassifier.h | 3 ++- apps/traincascade/traincascade.cpp | 9 ++++++++- doc/user_guide/ug_traincascade.markdown | 6 ++++++ 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/apps/traincascade/cascadeclassifier.cpp b/apps/traincascade/cascadeclassifier.cpp index c9b524f5ef..a64566ee4c 100644 --- a/apps/traincascade/cascadeclassifier.cpp +++ b/apps/traincascade/cascadeclassifier.cpp @@ -135,7 +135,8 @@ bool CvCascadeClassifier::train( const string _cascadeDirName, const CvCascadeParams& _cascadeParams, const CvFeatureParams& _featureParams, const CvCascadeBoostParams& _stageParams, - bool baseFormatSave ) + bool baseFormatSave, + double acceptanceRatioBreakValue ) { // Start recording clock ticks for training time output const clock_t begin_time = clock(); @@ -185,6 +186,7 @@ bool CvCascadeClassifier::train( const string _cascadeDirName, cout << "numStages: " << numStages << endl; cout << "precalcValBufSize[Mb] : " << _precalcValBufSize << endl; cout << "precalcIdxBufSize[Mb] : " << _precalcIdxBufSize << endl; + cout << "acceptanceRatioBreakValue : " << acceptanceRatioBreakValue << endl; cascadeParams.printAttrs(); stageParams->printAttrs(); featureParams->printAttrs(); @@ -207,13 +209,18 @@ bool CvCascadeClassifier::train( const string _cascadeDirName, if ( !updateTrainingSet( tempLeafFARate ) ) { cout << "Train dataset for temp stage can not be filled. " - "Branch training terminated." << endl; + "Branch training terminated." << endl; break; } if( tempLeafFARate <= requiredLeafFARate ) { cout << "Required leaf false alarm rate achieved. " - "Branch training terminated." << endl; + "Branch training terminated." << endl; + break; + } + if( (tempLeafFARate <= acceptanceRatioBreakValue) && (acceptanceRatioBreakValue < 0) ){ + cout << "The required acceptanceRatio for the model has been reached to avoid overfitting of trainingdata. " + "Branch training terminated." << endl; break; } diff --git a/apps/traincascade/cascadeclassifier.h b/apps/traincascade/cascadeclassifier.h index 6d6cb5b3f9..d8e044828b 100644 --- a/apps/traincascade/cascadeclassifier.h +++ b/apps/traincascade/cascadeclassifier.h @@ -94,7 +94,8 @@ public: const CvCascadeParams& _cascadeParams, const CvFeatureParams& _featureParams, const CvCascadeBoostParams& _stageParams, - bool baseFormatSave = false ); + bool baseFormatSave = false, + double acceptanceRatioBreakValue = -1.0 ); private: int predict( int sampleIdx ); void save( const std::string cascadeDirName, bool baseFormat = false ); diff --git a/apps/traincascade/traincascade.cpp b/apps/traincascade/traincascade.cpp index d1c3e4e87a..ba8afb27cc 100644 --- a/apps/traincascade/traincascade.cpp +++ b/apps/traincascade/traincascade.cpp @@ -15,6 +15,7 @@ int main( int argc, char* argv[] ) int precalcValBufSize = 256, precalcIdxBufSize = 256; bool baseFormatSave = false; + double acceptanceRatioBreakValue = -1.0; CvCascadeParams cascadeParams; CvCascadeBoostParams stageParams; @@ -36,6 +37,7 @@ int main( int argc, char* argv[] ) cout << " [-precalcIdxBufSize ]" << endl; cout << " [-baseFormatSave]" << endl; cout << " [-numThreads ]" << endl; + cout << " [-acceptanceRatioBreakValue = " << acceptanceRatioBreakValue << ">]" << endl; cascadeParams.printDefaults(); stageParams.printDefaults(); for( int fi = 0; fi < fc; fi++ ) @@ -86,6 +88,10 @@ int main( int argc, char* argv[] ) { numThreads = atoi(argv[++i]); } + else if( !strcmp( argv[i], "-acceptanceRatioBreakValue" ) ) + { + acceptanceRatioBreakValue = atof(argv[++i]); + } else if ( cascadeParams.scanAttr( argv[i], argv[i+1] ) ) { i++; } else if ( stageParams.scanAttr( argv[i], argv[i+1] ) ) { i++; } else if ( !set ) @@ -112,6 +118,7 @@ int main( int argc, char* argv[] ) cascadeParams, *featureParams[cascadeParams.featureType], stageParams, - baseFormatSave ); + baseFormatSave, + acceptanceRatioBreakValue ); return 0; } diff --git a/doc/user_guide/ug_traincascade.markdown b/doc/user_guide/ug_traincascade.markdown index 059d25e8a2..ccceb50517 100644 --- a/doc/user_guide/ug_traincascade.markdown +++ b/doc/user_guide/ug_traincascade.markdown @@ -256,6 +256,12 @@ Command line arguments of opencv_traincascade application grouped by purposes: Maximum number of threads to use during training. Notice that the actual number of used threads may be lower, depending on your machine and compilation options. + - -acceptanceRatioBreakValue \ + + This argument is used to determine how precise your model should keep learning and when to stop. + A good guideline is to train not further than 10e-5, to ensure the model does not overtrain on your training data. + By default this value is set to -1 to disable this feature. + -# Cascade parameters: - -stageType \ From 796c15d3e663332d01dd3ef20f56ac5497f1cc4a Mon Sep 17 00:00:00 2001 From: StevenPuttemans Date: Fri, 3 Apr 2015 12:54:05 +0200 Subject: [PATCH 016/109] fixing wrong equation in accuracy break rule --- apps/traincascade/cascadeclassifier.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/traincascade/cascadeclassifier.cpp b/apps/traincascade/cascadeclassifier.cpp index a64566ee4c..8b3eb57ac5 100644 --- a/apps/traincascade/cascadeclassifier.cpp +++ b/apps/traincascade/cascadeclassifier.cpp @@ -218,7 +218,7 @@ bool CvCascadeClassifier::train( const string _cascadeDirName, "Branch training terminated." << endl; break; } - if( (tempLeafFARate <= acceptanceRatioBreakValue) && (acceptanceRatioBreakValue < 0) ){ + if( (tempLeafFARate <= acceptanceRatioBreakValue) && (acceptanceRatioBreakValue >= 0) ){ cout << "The required acceptanceRatio for the model has been reached to avoid overfitting of trainingdata. " "Branch training terminated." << endl; break; From ed9f933d41bc6fd9fa40b42d1ca370f1b75d3e96 Mon Sep 17 00:00:00 2001 From: Andrey Pavlenko Date: Fri, 3 Apr 2015 14:03:09 +0300 Subject: [PATCH 017/109] fixing confusing variable naming in a sample code --- modules/imgcodecs/include/opencv2/imgcodecs.hpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/imgcodecs/include/opencv2/imgcodecs.hpp b/modules/imgcodecs/include/opencv2/imgcodecs.hpp index b0c942172c..30846efeac 100644 --- a/modules/imgcodecs/include/opencv2/imgcodecs.hpp +++ b/modules/imgcodecs/include/opencv2/imgcodecs.hpp @@ -185,13 +185,14 @@ compression parameters : void createAlphaMat(Mat &mat) { + CV_Assert(mat.channels() == 4); for (int i = 0; i < mat.rows; ++i) { for (int j = 0; j < mat.cols; ++j) { - Vec4b& rgba = mat.at(i, j); - rgba[0] = UCHAR_MAX; - rgba[1] = saturate_cast((float (mat.cols - j)) / ((float)mat.cols) * UCHAR_MAX); - rgba[2] = saturate_cast((float (mat.rows - i)) / ((float)mat.rows) * UCHAR_MAX); - rgba[3] = saturate_cast(0.5 * (rgba[1] + rgba[2])); + Vec4b& bgra = mat.at(i, j); + bgra[0] = UCHAR_MAX; // Blue + bgra[1] = saturate_cast((float (mat.cols - j)) / ((float)mat.cols) * UCHAR_MAX); // Green + bgra[2] = saturate_cast((float (mat.rows - i)) / ((float)mat.rows) * UCHAR_MAX); // Red + bgra[3] = saturate_cast(0.5 * (bgra[1] + bgra[2])); // Alpha } } } From 58f20a3b7f2bc2aa3043c4ddbafe8548602d8ac0 Mon Sep 17 00:00:00 2001 From: Andrew Senin Date: Fri, 3 Apr 2015 22:49:50 +0300 Subject: [PATCH 018/109] Ximea camera fix (see issue #4235) --- modules/videoio/src/cap_ximea.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/modules/videoio/src/cap_ximea.cpp b/modules/videoio/src/cap_ximea.cpp index 8356b4d92a..ccf49e45b5 100644 --- a/modules/videoio/src/cap_ximea.cpp +++ b/modules/videoio/src/cap_ximea.cpp @@ -52,7 +52,15 @@ CvCapture* cvCreateCameraCapture_XIMEA( int index ) // Enumerate connected devices void CvCaptureCAM_XIMEA::init() { +#if defined WIN32 || defined _WIN32 xiGetNumberDevices( &numDevices); +#else + // try second re-enumeration if first one fails + if (xiGetNumberDevices( &numDevices) != XI_OK) + { + xiGetNumberDevices( &numDevices); + } +#endif hmv = NULL; frame = NULL; timeout = 0; @@ -73,8 +81,17 @@ bool CvCaptureCAM_XIMEA::open( int wIndex ) if((mvret = xiOpenDevice( wIndex, &hmv)) != XI_OK) { +#if defined WIN32 || defined _WIN32 errMsg("Open XI_DEVICE failed", mvret); return false; +#else + // try opening second time if first fails + if((mvret = xiOpenDevice( wIndex, &hmv)) != XI_OK) + { + errMsg("Open XI_DEVICE failed", mvret); + return false; + } +#endif } int width = 0; @@ -260,7 +277,7 @@ double CvCaptureCAM_XIMEA::getProperty( int property_id ) const case CV_CAP_PROP_XI_AUTO_WB : xiGetParamInt( hmv, XI_PRM_AUTO_WB, &ival); return ival; case CV_CAP_PROP_XI_AEAG : xiGetParamInt( hmv, XI_PRM_AEAG, &ival); return ival; case CV_CAP_PROP_XI_EXP_PRIORITY : xiGetParamFloat( hmv, XI_PRM_EXP_PRIORITY, &fval); return fval; - case CV_CAP_PROP_XI_AE_MAX_LIMIT : xiGetParamInt( hmv, XI_PRM_AE_MAX_LIMIT, &ival); return ival; + case CV_CAP_PROP_XI_AE_MAX_LIMIT : xiGetParamInt( hmv, XI_PRM_EXP_PRIORITY, &ival); return ival; case CV_CAP_PROP_XI_AG_MAX_LIMIT : xiGetParamFloat( hmv, XI_PRM_AG_MAX_LIMIT, &fval); return fval; case CV_CAP_PROP_XI_AEAG_LEVEL : xiGetParamInt( hmv, XI_PRM_AEAG_LEVEL, &ival); return ival; case CV_CAP_PROP_XI_TIMEOUT : return timeout; @@ -293,7 +310,7 @@ bool CvCaptureCAM_XIMEA::setProperty( int property_id, double value ) case CV_CAP_PROP_XI_OFFSET_Y : mvret = xiSetParamInt( hmv, XI_PRM_OFFSET_Y, ival); break; case CV_CAP_PROP_XI_TRG_SOURCE : mvret = xiSetParamInt( hmv, XI_PRM_TRG_SOURCE, ival); break; case CV_CAP_PROP_XI_GPI_SELECTOR : mvret = xiSetParamInt( hmv, XI_PRM_GPI_SELECTOR, ival); break; - case CV_CAP_PROP_XI_TRG_SOFTWARE : mvret = xiSetParamInt( hmv, XI_PRM_TRG_SOFTWARE, 1); break; + case CV_CAP_PROP_XI_TRG_SOFTWARE : mvret = xiSetParamInt( hmv, XI_PRM_TRG_SOURCE, 1); break; case CV_CAP_PROP_XI_GPI_MODE : mvret = xiSetParamInt( hmv, XI_PRM_GPI_MODE, ival); break; case CV_CAP_PROP_XI_GPI_LEVEL : mvret = xiSetParamInt( hmv, XI_PRM_GPI_LEVEL, ival); break; case CV_CAP_PROP_XI_GPO_SELECTOR : mvret = xiSetParamInt( hmv, XI_PRM_GPO_SELECTOR, ival); break; @@ -301,10 +318,10 @@ bool CvCaptureCAM_XIMEA::setProperty( int property_id, double value ) case CV_CAP_PROP_XI_LED_SELECTOR : mvret = xiSetParamInt( hmv, XI_PRM_LED_SELECTOR, ival); break; case CV_CAP_PROP_XI_LED_MODE : mvret = xiSetParamInt( hmv, XI_PRM_LED_MODE, ival); break; case CV_CAP_PROP_XI_AUTO_WB : mvret = xiSetParamInt( hmv, XI_PRM_AUTO_WB, ival); break; - case CV_CAP_PROP_XI_MANUAL_WB : mvret = xiSetParamInt( hmv, XI_PRM_MANUAL_WB, ival); break; + case CV_CAP_PROP_XI_MANUAL_WB : mvret = xiSetParamInt( hmv, XI_PRM_LED_MODE, ival); break; case CV_CAP_PROP_XI_AEAG : mvret = xiSetParamInt( hmv, XI_PRM_AEAG, ival); break; case CV_CAP_PROP_XI_EXP_PRIORITY : mvret = xiSetParamFloat( hmv, XI_PRM_EXP_PRIORITY, fval); break; - case CV_CAP_PROP_XI_AE_MAX_LIMIT : mvret = xiSetParamInt( hmv, XI_PRM_AE_MAX_LIMIT, ival); break; + case CV_CAP_PROP_XI_AE_MAX_LIMIT : mvret = xiSetParamInt( hmv, XI_PRM_EXP_PRIORITY, ival); break; case CV_CAP_PROP_XI_AG_MAX_LIMIT : mvret = xiSetParamFloat( hmv, XI_PRM_AG_MAX_LIMIT, fval); break; case CV_CAP_PROP_XI_AEAG_LEVEL : mvret = xiSetParamInt( hmv, XI_PRM_AEAG_LEVEL, ival); break; case CV_CAP_PROP_XI_TIMEOUT : timeout = ival; break; From 03ea24f298f90934d71fcbabe4d134286ff34d6e Mon Sep 17 00:00:00 2001 From: Ashod Nakashian Date: Wed, 11 Feb 2015 17:49:19 -0500 Subject: [PATCH 019/109] Fix for decoding large Jp2 images on Windows. On Windows, the tmpnam function returns a temp filename in the current directory, which has a prepended backslash '\\'. This subsequently fails the open function. This patch creates a proper temp filename in the temp folder and makes unlike work by opening the file as short-lived. --- 3rdparty/libjasper/jas_stream.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/3rdparty/libjasper/jas_stream.c b/3rdparty/libjasper/jas_stream.c index ca1239c7d9..4c5db5871b 100644 --- a/3rdparty/libjasper/jas_stream.c +++ b/3rdparty/libjasper/jas_stream.c @@ -365,10 +365,14 @@ jas_stream_t *jas_stream_tmpfile() #ifdef _WIN32 /* Choose a file name. */ - tmpnam(obj->pathname); + char lpTempPathBuffer[MAX_PATH]; + const DWORD dwRetVal = GetTempPath(MAX_PATH, lpTempPathBuffer); /* Open the underlying file. */ - if ((obj->fd = open(obj->pathname, O_CREAT | O_EXCL | O_RDWR | O_TRUNC | O_BINARY, + if (dwRetVal >= MAX_PATH || dwRetVal == 0 || + sprintf_s(obj->pathname, MAX_PATH, "%s\\tmp.XXXXXXXXXX", lpTempPathBuffer) <= 0 || + _mktemp_s(obj->pathname, MAX_PATH) || + (obj->fd = open(obj->pathname, O_CREAT | O_EXCL | O_RDWR | O_TRUNC | O_BINARY | O_TEMPORARY | _O_SHORT_LIVED, JAS_STREAM_PERMS)) < 0) { jas_stream_destroy(stream); return 0; From 6fd2fdc2e6fe7670b39c2728e06b57db230a441d Mon Sep 17 00:00:00 2001 From: Ashod Nakashian Date: Wed, 11 Feb 2015 21:28:44 -0500 Subject: [PATCH 020/109] Jasper unit-tests and removed a superfluous assertion. --- 3rdparty/libjasper/jas_cm.c | 1 - modules/imgcodecs/test/test_grfmt.cpp | 13 +++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/3rdparty/libjasper/jas_cm.c b/3rdparty/libjasper/jas_cm.c index dc23ead895..16d4a502df 100644 --- a/3rdparty/libjasper/jas_cm.c +++ b/3rdparty/libjasper/jas_cm.c @@ -842,7 +842,6 @@ static int jas_cmshapmat_apply(jas_cmpxform_t *pxform, jas_cmreal_t *in, *dst++ = a2; } } else { -assert(0); while (--cnt >= 0) { a0 = *src++; src++; diff --git a/modules/imgcodecs/test/test_grfmt.cpp b/modules/imgcodecs/test/test_grfmt.cpp index 423d030a0c..5ef0164fec 100644 --- a/modules/imgcodecs/test/test_grfmt.cpp +++ b/modules/imgcodecs/test/test_grfmt.cpp @@ -87,6 +87,9 @@ TEST(Imgcodecs_imread, regression) { const char* const filenames[] = { +#ifdef HAVE_JASPER + "Rome.jp2", +#endif "color_palette_alpha.png", "multipage.tif", "rle.hdr", @@ -109,6 +112,16 @@ TEST(Imgcodecs_imread, regression) } } +#ifdef HAVE_JASPER +TEST(Imgcodecs_jasper, regression) +{ + const string folder = string(cvtest::TS::ptr()->get_data_path()) + "/readwrite/"; + + ASSERT_TRUE(imread_compare(folder + "Bretagne2.jp2", IMREAD_UNCHANGED)); + ASSERT_TRUE(imread_compare(folder + "Bretagne2.jp2", IMREAD_GRAYSCALE)); +} +#endif + class CV_GrfmtWriteBigImageTest : public cvtest::BaseTest { public: From 54ab3137d5c417a6060abf1ae85a31abaf23fe32 Mon Sep 17 00:00:00 2001 From: Ashod Nakashian Date: Sun, 29 Mar 2015 16:49:47 -0400 Subject: [PATCH 021/109] Simplified temp filename generation. --- 3rdparty/libjasper/jas_stream.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/3rdparty/libjasper/jas_stream.c b/3rdparty/libjasper/jas_stream.c index 4c5db5871b..3ba7a837db 100644 --- a/3rdparty/libjasper/jas_stream.c +++ b/3rdparty/libjasper/jas_stream.c @@ -345,6 +345,7 @@ jas_stream_t *jas_stream_tmpfile() { jas_stream_t *stream; jas_stream_fileobj_t *obj; + char *tmpname; if (!(stream = jas_stream_create())) { return 0; @@ -365,14 +366,12 @@ jas_stream_t *jas_stream_tmpfile() #ifdef _WIN32 /* Choose a file name. */ - char lpTempPathBuffer[MAX_PATH]; - const DWORD dwRetVal = GetTempPath(MAX_PATH, lpTempPathBuffer); + tmpname = tempnam(NULL, NULL); + strcpy(obj->pathname, tmpname); + free(tmpname); /* Open the underlying file. */ - if (dwRetVal >= MAX_PATH || dwRetVal == 0 || - sprintf_s(obj->pathname, MAX_PATH, "%s\\tmp.XXXXXXXXXX", lpTempPathBuffer) <= 0 || - _mktemp_s(obj->pathname, MAX_PATH) || - (obj->fd = open(obj->pathname, O_CREAT | O_EXCL | O_RDWR | O_TRUNC | O_BINARY | O_TEMPORARY | _O_SHORT_LIVED, + if ((obj->fd = open(obj->pathname, O_CREAT | O_EXCL | O_RDWR | O_TRUNC | O_BINARY | O_TEMPORARY | _O_SHORT_LIVED, JAS_STREAM_PERMS)) < 0) { jas_stream_destroy(stream); return 0; From f75f2ffd48a4256dcb347cd79e241c07d9e3b419 Mon Sep 17 00:00:00 2001 From: Ashod Nakashian Date: Fri, 3 Apr 2015 20:59:13 -0400 Subject: [PATCH 022/109] Jpeg2k color to greyscale conversion on non-Windows is done post decoding because system libjasper segfaults when decoding color images as greyscale. --- modules/imgcodecs/src/grfmt_jpeg2000.cpp | 25 +++++++++++++++++++++++- modules/imgcodecs/src/loadsave.cpp | 9 +-------- modules/imgcodecs/test/test_grfmt.cpp | 22 +++++++++++++-------- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/modules/imgcodecs/src/grfmt_jpeg2000.cpp b/modules/imgcodecs/src/grfmt_jpeg2000.cpp index 83fd55a594..e499c58b89 100644 --- a/modules/imgcodecs/src/grfmt_jpeg2000.cpp +++ b/modules/imgcodecs/src/grfmt_jpeg2000.cpp @@ -45,6 +45,7 @@ #ifdef HAVE_JASPER #include "grfmt_jpeg2000.hpp" +#include "opencv2/imgproc.hpp" #ifdef WIN32 #define JAS_WIN_MSVC_BUILD 1 @@ -159,6 +160,21 @@ bool Jpeg2KDecoder::readData( Mat& img ) jas_stream_t* stream = (jas_stream_t*)m_stream; jas_image_t* image = (jas_image_t*)m_image; +#ifndef WIN32 + // At least on some Linux instances the + // system libjasper segfaults when + // converting color to grey. + // We do this conversion manually at the end. + Mat clr; + if (CV_MAT_CN(img.type()) < CV_MAT_CN(this->type())) + { + clr.create(img.size().height, img.size().width, this->type()); + color = true; + data = clr.ptr(); + step = (int)clr.step; + } +#endif + if( stream && image ) { bool convert; @@ -171,7 +187,7 @@ bool Jpeg2KDecoder::readData( Mat& img ) else { convert = (jas_clrspc_fam( jas_image_clrspc( image ) ) != JAS_CLRSPC_FAM_GRAY); - colorspace = JAS_CLRSPC_SGRAY; // TODO GENGRAY or SGRAY? + colorspace = JAS_CLRSPC_SGRAY; // TODO GENGRAY or SGRAY? (GENGRAY fails on Win.) } // convert to the desired colorspace @@ -256,6 +272,13 @@ bool Jpeg2KDecoder::readData( Mat& img ) close(); +#ifndef WIN32 + if (!clr.empty()) + { + cv::cvtColor(clr, img, COLOR_BGR2GRAY); + } +#endif + return result; } diff --git a/modules/imgcodecs/src/loadsave.cpp b/modules/imgcodecs/src/loadsave.cpp index 8526a4a3f0..383c25a2b3 100644 --- a/modules/imgcodecs/src/loadsave.cpp +++ b/modules/imgcodecs/src/loadsave.cpp @@ -374,15 +374,8 @@ imreadmulti_(const String& filename, int flags, std::vector& mats) type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1); } - // established the required input image size. - CvSize size; - size.width = decoder->width(); - size.height = decoder->height(); - - Mat mat; - mat.create(size.height, size.width, type); - // read the image data + Mat mat(decoder->height(), decoder->width(), type); if (!decoder->readData(mat)) { break; diff --git a/modules/imgcodecs/test/test_grfmt.cpp b/modules/imgcodecs/test/test_grfmt.cpp index 5ef0164fec..92238a95f0 100644 --- a/modules/imgcodecs/test/test_grfmt.cpp +++ b/modules/imgcodecs/test/test_grfmt.cpp @@ -102,13 +102,17 @@ TEST(Imgcodecs_imread, regression) for (size_t i = 0; i < sizeof(filenames) / sizeof(filenames[0]); ++i) { - ASSERT_TRUE(imread_compare(folder + string(filenames[i]), IMREAD_UNCHANGED)); - ASSERT_TRUE(imread_compare(folder + string(filenames[i]), IMREAD_GRAYSCALE)); - ASSERT_TRUE(imread_compare(folder + string(filenames[i]), IMREAD_COLOR)); - ASSERT_TRUE(imread_compare(folder + string(filenames[i]), IMREAD_ANYDEPTH)); - ASSERT_TRUE(imread_compare(folder + string(filenames[i]), IMREAD_ANYCOLOR)); - if (i != 2) // GDAL does not support hdr - ASSERT_TRUE(imread_compare(folder + string(filenames[i]), IMREAD_LOAD_GDAL)); + const string path = folder + string(filenames[i]); + ASSERT_TRUE(imread_compare(path, IMREAD_UNCHANGED)); + ASSERT_TRUE(imread_compare(path, IMREAD_GRAYSCALE)); + ASSERT_TRUE(imread_compare(path, IMREAD_COLOR)); + ASSERT_TRUE(imread_compare(path, IMREAD_ANYDEPTH)); + ASSERT_TRUE(imread_compare(path, IMREAD_ANYCOLOR)); + if (path.substr(path.length() - 3) != "hdr") + { + // GDAL does not support hdr + ASSERT_TRUE(imread_compare(path, IMREAD_LOAD_GDAL)); + } } } @@ -117,8 +121,10 @@ TEST(Imgcodecs_jasper, regression) { const string folder = string(cvtest::TS::ptr()->get_data_path()) + "/readwrite/"; - ASSERT_TRUE(imread_compare(folder + "Bretagne2.jp2", IMREAD_UNCHANGED)); + ASSERT_TRUE(imread_compare(folder + "Bretagne2.jp2", IMREAD_COLOR)); ASSERT_TRUE(imread_compare(folder + "Bretagne2.jp2", IMREAD_GRAYSCALE)); + ASSERT_TRUE(imread_compare(folder + "Grey.jp2", IMREAD_COLOR)); + ASSERT_TRUE(imread_compare(folder + "Grey.jp2", IMREAD_GRAYSCALE)); } #endif From 979721c979a24972ba69af90fff5832b31bf8443 Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Mon, 6 Apr 2015 16:12:00 +0300 Subject: [PATCH 023/109] Fix generating of android.mk --- cmake/OpenCVGenAndroidMK.cmake | 31 +++++------------- cmake/OpenCVUtils.cmake | 57 +++++++++++++++++++--------------- 2 files changed, 39 insertions(+), 49 deletions(-) diff --git a/cmake/OpenCVGenAndroidMK.cmake b/cmake/OpenCVGenAndroidMK.cmake index 318c802ffe..d6f902b0f0 100644 --- a/cmake/OpenCVGenAndroidMK.cmake +++ b/cmake/OpenCVGenAndroidMK.cmake @@ -43,34 +43,17 @@ if(ANDROID) endforeach() # build the list of opencv libs and dependencies for all modules - set(OPENCV_MODULES_CONFIGMAKE "") - set(OPENCV_EXTRA_COMPONENTS_CONFIGMAKE "") - set(OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE "") - foreach(m ${OPENCV_MODULES_PUBLIC}) - list(INSERT OPENCV_MODULES_CONFIGMAKE 0 ${${m}_MODULE_DEPS_${ocv_optkind}} ${m}) - if(${m}_EXTRA_DEPS_${ocv_optkind}) - list(INSERT OPENCV_EXTRA_COMPONENTS_CONFIGMAKE 0 ${${m}_EXTRA_DEPS_${ocv_optkind}}) - endif() - endforeach() + ocv_get_all_libs(OPENCV_MODULES_CONFIGMAKE OPENCV_EXTRA_COMPONENTS_CONFIGMAKE OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE) - # split 3rdparty libs and modules - foreach(mod ${OPENCV_MODULES_CONFIGMAKE}) - if(NOT mod MATCHES "^opencv_.+$") - list(INSERT OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE 0 ${mod}) - endif() - endforeach() - if(OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE) - list(REMOVE_ITEM OPENCV_MODULES_CONFIGMAKE ${OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE}) - endif() + # list -> string + string(REPLACE ";" " " OPENCV_MODULES_CONFIGMAKE "${OPENCV_MODULES_CONFIGMAKE}") + string(REPLACE ";" " " OPENCV_EXTRA_COMPONENTS_CONFIGMAKE "${OPENCV_EXTRA_COMPONENTS_CONFIGMAKE}") + string(REPLACE ";" " " OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE "${OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE}") - # convert CMake lists to makefile literals - foreach(lst OPENCV_MODULES_CONFIGMAKE OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE OPENCV_EXTRA_COMPONENTS_CONFIGMAKE) - ocv_list_unique(${lst}) - ocv_list_reverse(${lst}) - string(REPLACE ";" " " ${lst} "${${lst}}") - endforeach() + # replace 'opencv_' -> ''' string(REPLACE "opencv_" "" OPENCV_MODULES_CONFIGMAKE "${OPENCV_MODULES_CONFIGMAKE}") + # prepare 3rd-party component list without TBB for armeabi and mips platforms. TBB is useless there. set(OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB ${OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE}) foreach(mod ${OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB}) diff --git a/cmake/OpenCVUtils.cmake b/cmake/OpenCVUtils.cmake index 05576b3626..b9b729e2b1 100644 --- a/cmake/OpenCVUtils.cmake +++ b/cmake/OpenCVUtils.cmake @@ -415,31 +415,6 @@ function(status text) endfunction() -# splits cmake libraries list of format "general;item1;debug;item2;release;item3" to two lists -macro(ocv_split_libs_list lst lstdbg lstopt) - set(${lstdbg} "") - set(${lstopt} "") - set(perv_keyword "") - foreach(word ${${lst}}) - if(word STREQUAL "debug" OR word STREQUAL "optimized") - set(perv_keyword ${word}) - elseif(word STREQUAL "general") - set(perv_keyword "") - elseif(perv_keyword STREQUAL "debug") - list(APPEND ${lstdbg} "${word}") - set(perv_keyword "") - elseif(perv_keyword STREQUAL "optimized") - list(APPEND ${lstopt} "${word}") - set(perv_keyword "") - else() - list(APPEND ${lstdbg} "${word}") - list(APPEND ${lstopt} "${word}") - set(perv_keyword "") - endif() - endforeach() -endmacro() - - # remove all matching elements from the list macro(ocv_list_filterout lst regex) foreach(item ${${lst}}) @@ -810,3 +785,35 @@ function(ocv_add_library target) _ocv_append_target_includes(${target}) endfunction() + +# build the list of opencv libs and dependencies for all modules +# _modules - variable to hold list of all modules +# _extra - variable to hold list of extra dependencies +# _3rdparty - variable to hold list of prebuilt 3rdparty libraries +macro(ocv_get_all_libs _modules _extra _3rdparty) + set(${_modules} "") + set(${_extra} "") + set(${_3rdparty} "") + foreach(m ${OPENCV_MODULES_PUBLIC}) + get_target_property(deps ${m} INTERFACE_LINK_LIBRARIES) + list(INSERT ${_modules} 0 ${deps} ${m}) + foreach (dep ${deps} ${OPENCV_LINKER_LIBS}) + if (TARGET ${dep}) + list(INSERT ${_3rdparty} 0 ${dep}) + else() + list(INSERT ${_extra} 0 ${dep}) + endif() + endforeach() + endforeach() + + # split 3rdparty libs and modules + ocv_list_filterout(${_3rdparty} "^opencv_.+$") + ocv_list_filterout(${_extra} "^opencv_.+$") + list(REMOVE_ITEM ${_modules} ${${_3rdparty}} ${${_extra}}) + + # convert CMake lists to makefile literals + foreach(lst ${_modules} ${_3rdparty} ${_extra}) + ocv_list_unique(${lst}) + ocv_list_reverse(${lst}) + endforeach() +endmacro() From 9cccd87e793ae5638ba7ab13d26ce4aadade5510 Mon Sep 17 00:00:00 2001 From: Ying Xiong Date: Mon, 6 Apr 2015 16:37:06 -0400 Subject: [PATCH 024/109] Silence cmake 3.0+ warnings about MACOSX_RPATH --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 746faac20b..a25987cdb7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,11 @@ if(POLICY CMP0026) cmake_policy(SET CMP0026 OLD) endif() +if (POLICY CMP0042) + # silence cmake 3.0+ warnings about MACOSX_RPATH + cmake_policy(SET CMP0042 OLD) +endif() + # must go before the project command set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Configs" FORCE) if(DEFINED CMAKE_BUILD_TYPE) From 2d8b4fea9ff6c5e4c9bcc7a351df99909e5e164f Mon Sep 17 00:00:00 2001 From: Ying Xiong Date: Mon, 6 Apr 2015 19:57:10 -0400 Subject: [PATCH 025/109] Add #ifdef's such that python wrapper builds independent of other components --- modules/python/src2/cv2.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/modules/python/src2/cv2.cpp b/modules/python/src2/cv2.cpp index ff53d733c4..3611253202 100644 --- a/modules/python/src2/cv2.cpp +++ b/modules/python/src2/cv2.cpp @@ -109,12 +109,18 @@ typedef std::vector > vector_vector_Point2f; typedef std::vector > vector_vector_Point3f; typedef std::vector > vector_vector_DMatch; +#ifdef HAVE_OPENCV_FEATURES2D typedef SimpleBlobDetector::Params SimpleBlobDetector_Params; +#endif +#ifdef HAVE_OPENCV_FLANN typedef cvflann::flann_distance_t cvflann_flann_distance_t; typedef cvflann::flann_algorithm_t cvflann_flann_algorithm_t; +#endif +#ifdef HAVE_OPENCV_STITCHING typedef Stitcher::Status Status; +#endif static PyObject* failmsgp(const char *fmt, ...) { @@ -445,11 +451,13 @@ PyObject* pyopencv_from(const bool& value) return PyBool_FromLong(value); } +#ifdef HAVE_OPENCV_STITCHING template<> PyObject* pyopencv_from(const Status& value) { return PyInt_FromLong(value); } +#endif template<> bool pyopencv_to(PyObject* obj, bool& value, const char* name) @@ -486,6 +494,7 @@ PyObject* pyopencv_from(const int& value) return PyInt_FromLong(value); } +#ifdef HAVE_OPENCV_FLANN template<> PyObject* pyopencv_from(const cvflann_flann_algorithm_t& value) { @@ -497,6 +506,7 @@ PyObject* pyopencv_from(const cvflann_flann_distance_t& value) { return PyInt_FromLong(int(value)); } +#endif template<> bool pyopencv_to(PyObject* obj, int& value, const char* name) @@ -1004,6 +1014,7 @@ PyObject* pyopencv_from(const Moments& m) "nu30", m.nu30, "nu21", m.nu21, "nu12", m.nu12, "nu03", m.nu03); } +#ifdef HAVE_OPENCV_FLANN template<> bool pyopencv_to(PyObject *o, cv::flann::IndexParams& p, const char *name) { @@ -1057,6 +1068,7 @@ bool pyopencv_to(PyObject* obj, cv::flann::SearchParams & value, const char * na { return pyopencv_to(obj, value, name); } +#endif template bool pyopencv_to(PyObject *o, Ptr& p, const char *name) @@ -1065,6 +1077,7 @@ bool pyopencv_to(PyObject *o, Ptr& p, const char *name) return pyopencv_to(o, *p, name); } +#ifdef HAVE_OPENCV_FLANN template<> bool pyopencv_to(PyObject *o, cvflann::flann_distance_t& dist, const char *name) { @@ -1073,6 +1086,7 @@ bool pyopencv_to(PyObject *o, cvflann::flann_distance_t& dist, const char *name) dist = (cvflann::flann_distance_t)d; return ok; } +#endif //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1120,6 +1134,7 @@ static void OnMouse(int event, int x, int y, int flags, void* param) PyGILState_Release(gstate); } +#ifdef HAVE_OPENCV_HIGHGUI static PyObject *pycvSetMouseCallback(PyObject*, PyObject *args, PyObject *kw) { const char *keywords[] = { "window_name", "on_mouse", "param", NULL }; @@ -1139,6 +1154,7 @@ static PyObject *pycvSetMouseCallback(PyObject*, PyObject *args, PyObject *kw) ERRWRAP2(setMouseCallback(name, OnMouse, Py_BuildValue("OO", on_mouse, param))); Py_RETURN_NONE; } +#endif static void OnChange(int pos, void *param) { @@ -1154,6 +1170,7 @@ static void OnChange(int pos, void *param) PyGILState_Release(gstate); } +#ifdef HAVE_OPENCV_HIGHGUI static PyObject *pycvCreateTrackbar(PyObject*, PyObject *args) { PyObject *on_change; @@ -1171,6 +1188,7 @@ static PyObject *pycvCreateTrackbar(PyObject*, PyObject *args) ERRWRAP2(createTrackbar(trackbar_name, window_name, value, count, OnChange, Py_BuildValue("OO", on_change, Py_None))); Py_RETURN_NONE; } +#endif /////////////////////////////////////////////////////////////////////////////////////// @@ -1200,8 +1218,10 @@ static int convert_to_char(PyObject *o, char *dst, const char *name = "no_name") #include "pyopencv_generated_funcs.h" static PyMethodDef special_methods[] = { +#ifdef HAVE_OPENCV_HIGHGUI {"createTrackbar", pycvCreateTrackbar, METH_VARARGS, "createTrackbar(trackbarName, windowName, value, count, onChange) -> None"}, {"setMouseCallback", (PyCFunction)pycvSetMouseCallback, METH_VARARGS | METH_KEYWORDS, "setMouseCallback(windowName, onMouse [, param]) -> None"}, +#endif {NULL, NULL}, }; From 52c727f09a6dc8de98c3ecb5b5ecf1d6b19d962f Mon Sep 17 00:00:00 2001 From: greensea Date: Tue, 31 Mar 2015 17:28:40 +0800 Subject: [PATCH 026/109] Fix a segment fault issue in cascade classfier work_var_count and sample_count are both 32bit integer, if the product of work_var_count and sample_count is bigger than 2^31, the compiler will treat (work_var_count*sample_count) as a negative number. Force work_var_count as an unsigned 64bit integer to avoid this issue. --- apps/traincascade/boost.cpp | 56 +++++++++++++++--------------- apps/traincascade/old_ml_boost.cpp | 4 +-- apps/traincascade/old_ml_tree.cpp | 36 +++++++++---------- 3 files changed, 48 insertions(+), 48 deletions(-) diff --git a/apps/traincascade/boost.cpp b/apps/traincascade/boost.cpp index 5864022048..c2e7fb7d6a 100644 --- a/apps/traincascade/boost.cpp +++ b/apps/traincascade/boost.cpp @@ -437,7 +437,7 @@ CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_id if (is_buf_16u) { unsigned short* udst_idx = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + - vi*sample_count + data_root->offset); + (size_t)vi*sample_count + data_root->offset); for( int i = 0; i < num_valid; i++ ) { idx = src_idx[i]; @@ -450,7 +450,7 @@ CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_id else { int* idst_idx = buf->data.i + root->buf_idx*get_length_subbuf() + - vi*sample_count + root->offset; + (size_t)vi*sample_count + root->offset; for( int i = 0; i < num_valid; i++ ) { idx = src_idx[i]; @@ -467,14 +467,14 @@ CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_id if (is_buf_16u) { unsigned short* udst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + - (workVarCount-1)*sample_count + root->offset); + (size_t)(workVarCount-1)*sample_count + root->offset); for( int i = 0; i < count; i++ ) udst[i] = (unsigned short)src_lbls[sidx[i]]; } else { int* idst = buf->data.i + root->buf_idx*get_length_subbuf() + - (workVarCount-1)*sample_count + root->offset; + (size_t)(workVarCount-1)*sample_count + root->offset; for( int i = 0; i < count; i++ ) idst[i] = src_lbls[sidx[i]]; } @@ -484,14 +484,14 @@ CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_id if (is_buf_16u) { unsigned short* sample_idx_dst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + - workVarCount*sample_count + root->offset); + (size_t)workVarCount*sample_count + root->offset); for( int i = 0; i < count; i++ ) sample_idx_dst[i] = (unsigned short)sample_idx_src[sidx[i]]; } else { int* sample_idx_dst = buf->data.i + root->buf_idx*get_length_subbuf() + - workVarCount*sample_count + root->offset; + (size_t)workVarCount*sample_count + root->offset; for( int i = 0; i < count; i++ ) sample_idx_dst[i] = sample_idx_src[sidx[i]]; } @@ -677,9 +677,9 @@ void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluat // set sample labels if (is_buf_16u) - udst = (unsigned short*)(buf->data.s + work_var_count*sample_count); + udst = (unsigned short*)(buf->data.s + (size_t)work_var_count*sample_count); else - idst = buf->data.i + work_var_count*sample_count; + idst = buf->data.i + (size_t)work_var_count*sample_count; for (int si = 0; si < sample_count; si++) { @@ -747,11 +747,11 @@ void CvCascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* o if ( vi < numPrecalcIdx ) { if( !is_buf_16u ) - *sortedIndices = buf->data.i + n->buf_idx*get_length_subbuf() + vi*sample_count + n->offset; + *sortedIndices = buf->data.i + n->buf_idx*get_length_subbuf() + (size_t)vi*sample_count + n->offset; else { const unsigned short* shortIndices = (const unsigned short*)(buf->data.s + n->buf_idx*get_length_subbuf() + - vi*sample_count + n->offset ); + (size_t)vi*sample_count + n->offset ); for( int i = 0; i < nodeSampleCount; i++ ) sortedIndicesBuf[i] = shortIndices[i]; @@ -862,14 +862,14 @@ struct FeatureIdxOnlyPrecalc : ParallelLoopBody { valCachePtr[si] = (*featureEvaluator)( fi, si ); if ( is_buf_16u ) - *(udst + fi*sample_count + si) = (unsigned short)si; + *(udst + (size_t)fi*sample_count + si) = (unsigned short)si; else - *(idst + fi*sample_count + si) = si; + *(idst + (size_t)fi*sample_count + si) = si; } if ( is_buf_16u ) - std::sort(udst + fi*sample_count, udst + (fi + 1)*sample_count, LessThanIdx(valCachePtr) ); + std::sort(udst + (size_t)fi*sample_count, udst + (size_t)(fi + 1)*sample_count, LessThanIdx(valCachePtr) ); else - std::sort(idst + fi*sample_count, idst + (fi + 1)*sample_count, LessThanIdx(valCachePtr) ); + std::sort(idst + (size_t)fi*sample_count, idst + (size_t)(fi + 1)*sample_count, LessThanIdx(valCachePtr) ); } } const CvFeatureEvaluator* featureEvaluator; @@ -898,14 +898,14 @@ struct FeatureValAndIdxPrecalc : ParallelLoopBody { valCache->at(fi,si) = (*featureEvaluator)( fi, si ); if ( is_buf_16u ) - *(udst + fi*sample_count + si) = (unsigned short)si; + *(udst + (size_t)fi*sample_count + si) = (unsigned short)si; else - *(idst + fi*sample_count + si) = si; + *(idst + (size_t)fi*sample_count + si) = si; } if ( is_buf_16u ) - std::sort(udst + fi*sample_count, udst + (fi + 1)*sample_count, LessThanIdx(valCache->ptr(fi)) ); + std::sort(udst + (size_t)fi*sample_count, udst + (size_t)(fi + 1)*sample_count, LessThanIdx(valCache->ptr(fi)) ); else - std::sort(idst + fi*sample_count, idst + (fi + 1)*sample_count, LessThanIdx(valCache->ptr(fi)) ); + std::sort(idst + (size_t)fi*sample_count, idst + (size_t)(fi + 1)*sample_count, LessThanIdx(valCache->ptr(fi)) ); } } const CvFeatureEvaluator* featureEvaluator; @@ -1228,9 +1228,9 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node ) if (data->is_buf_16u) { unsigned short *ldst = (unsigned short *)(buf->data.s + left->buf_idx*length_buf_row + - (workVarCount-1)*scount + left->offset); + (size_t)(workVarCount-1)*scount + left->offset); unsigned short *rdst = (unsigned short *)(buf->data.s + right->buf_idx*length_buf_row + - (workVarCount-1)*scount + right->offset); + (size_t)(workVarCount-1)*scount + right->offset); for( int i = 0; i < n; i++ ) { @@ -1251,9 +1251,9 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node ) else { int *ldst = buf->data.i + left->buf_idx*length_buf_row + - (workVarCount-1)*scount + left->offset; + (size_t)(workVarCount-1)*scount + left->offset; int *rdst = buf->data.i + right->buf_idx*length_buf_row + - (workVarCount-1)*scount + right->offset; + (size_t)(workVarCount-1)*scount + right->offset; for( int i = 0; i < n; i++ ) { @@ -1281,9 +1281,9 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node ) if (data->is_buf_16u) { unsigned short* ldst = (unsigned short*)(buf->data.s + left->buf_idx*length_buf_row + - workVarCount*scount + left->offset); + (size_t)workVarCount*scount + left->offset); unsigned short* rdst = (unsigned short*)(buf->data.s + right->buf_idx*length_buf_row + - workVarCount*scount + right->offset); + (size_t)workVarCount*scount + right->offset); for (int i = 0; i < n; i++) { unsigned short idx = (unsigned short)tempBuf[i]; @@ -1302,9 +1302,9 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node ) else { int* ldst = buf->data.i + left->buf_idx*length_buf_row + - workVarCount*scount + left->offset; + (size_t)workVarCount*scount + left->offset; int* rdst = buf->data.i + right->buf_idx*length_buf_row + - workVarCount*scount + right->offset; + (size_t)workVarCount*scount + right->offset; for (int i = 0; i < n; i++) { int idx = tempBuf[i]; @@ -1473,7 +1473,7 @@ void CvCascadeBoost::update_weights( CvBoostTree* tree ) if (data->is_buf_16u) { unsigned short* labels = (unsigned short*)(buf->data.s + data->data_root->buf_idx*length_buf_row + - data->data_root->offset + (data->work_var_count-1)*data->sample_count); + data->data_root->offset + (size_t)(data->work_var_count-1)*data->sample_count); for( int i = 0; i < n; i++ ) { // save original categorical responses {0,1}, convert them to {-1,1} @@ -1491,7 +1491,7 @@ void CvCascadeBoost::update_weights( CvBoostTree* tree ) else { int* labels = buf->data.i + data->data_root->buf_idx*length_buf_row + - data->data_root->offset + (data->work_var_count-1)*data->sample_count; + data->data_root->offset + (size_t)(data->work_var_count-1)*data->sample_count; for( int i = 0; i < n; i++ ) { diff --git a/apps/traincascade/old_ml_boost.cpp b/apps/traincascade/old_ml_boost.cpp index be4cd81f04..fae3d60806 100644 --- a/apps/traincascade/old_ml_boost.cpp +++ b/apps/traincascade/old_ml_boost.cpp @@ -1200,7 +1200,7 @@ CvBoost::update_weights( CvBoostTree* tree ) if (data->is_buf_16u) { unsigned short* labels = (unsigned short*)(dtree_data_buf->data.s + data->data_root->buf_idx*length_buf_row + - data->data_root->offset + (data->work_var_count-1)*data->sample_count); + data->data_root->offset + (size_t)(data->work_var_count-1)*data->sample_count); for( i = 0; i < n; i++ ) { // save original categorical responses {0,1}, convert them to {-1,1} @@ -1218,7 +1218,7 @@ CvBoost::update_weights( CvBoostTree* tree ) else { int* labels = dtree_data_buf->data.i + data->data_root->buf_idx*length_buf_row + - data->data_root->offset + (data->work_var_count-1)*data->sample_count; + data->data_root->offset + (size_t)(data->work_var_count-1)*data->sample_count; for( i = 0; i < n; i++ ) { diff --git a/apps/traincascade/old_ml_tree.cpp b/apps/traincascade/old_ml_tree.cpp index b7e346ccbc..d7c6511cfd 100644 --- a/apps/traincascade/old_ml_tree.cpp +++ b/apps/traincascade/old_ml_tree.cpp @@ -424,9 +424,9 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, int* c_map; if (is_buf_16u) - udst = (unsigned short*)(buf->data.s + vi*sample_count); + udst = (unsigned short*)(buf->data.s + (size_t)vi*sample_count); else - idst = buf->data.i + vi*sample_count; + idst = buf->data.i + (size_t)vi*sample_count; // copy data for( i = 0; i < sample_count; i++ ) @@ -540,9 +540,9 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, else if( ci < 0 ) // process ordered variable { if (is_buf_16u) - udst = (unsigned short*)(buf->data.s + vi*sample_count); + udst = (unsigned short*)(buf->data.s + (size_t)vi*sample_count); else - idst = buf->data.i + vi*sample_count; + idst = buf->data.i + (size_t)vi*sample_count; for( i = 0; i < sample_count; i++ ) { @@ -583,9 +583,9 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, // set sample labels if (is_buf_16u) - udst = (unsigned short*)(buf->data.s + work_var_count*sample_count); + udst = (unsigned short*)(buf->data.s + (size_t)work_var_count*sample_count); else - idst = buf->data.i + work_var_count*sample_count; + idst = buf->data.i + (size_t)work_var_count*sample_count; for (i = 0; i < sample_count; i++) { @@ -602,7 +602,7 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, if (is_buf_16u) { - usdst = (unsigned short*)(buf->data.s + (get_work_var_count()-1)*sample_count); + usdst = (unsigned short*)(buf->data.s + (size_t)(get_work_var_count()-1)*sample_count); for( i = vi = 0; i < sample_count; i++ ) { usdst[i] = (unsigned short)vi++; @@ -619,7 +619,7 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, } else { - idst2 = buf->data.i + (get_work_var_count()-1)*sample_count; + idst2 = buf->data.i + (size_t)(get_work_var_count()-1)*sample_count; for( i = vi = 0; i < sample_count; i++ ) { idst2[i] = vi++; @@ -785,7 +785,7 @@ CvDTreeNode* CvDTreeTrainData::subsample_data( const CvMat* _subsample_idx ) if (is_buf_16u) { unsigned short* udst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + - vi*sample_count + root->offset); + (size_t)vi*sample_count + root->offset); for( i = 0; i < count; i++ ) { int val = src[sidx[i]]; @@ -796,7 +796,7 @@ CvDTreeNode* CvDTreeTrainData::subsample_data( const CvMat* _subsample_idx ) else { int* idst = buf->data.i + root->buf_idx*get_length_subbuf() + - vi*sample_count + root->offset; + (size_t)vi*sample_count + root->offset; for( i = 0; i < count; i++ ) { int val = src[sidx[i]]; @@ -822,7 +822,7 @@ CvDTreeNode* CvDTreeTrainData::subsample_data( const CvMat* _subsample_idx ) if (is_buf_16u) { unsigned short* udst_idx = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + - vi*sample_count + data_root->offset); + (size_t)vi*sample_count + data_root->offset); for( i = 0; i < num_valid; i++ ) { idx = src_idx[i]; @@ -846,7 +846,7 @@ CvDTreeNode* CvDTreeTrainData::subsample_data( const CvMat* _subsample_idx ) else { int* idst_idx = buf->data.i + root->buf_idx*get_length_subbuf() + - vi*sample_count + root->offset; + (size_t)vi*sample_count + root->offset; for( i = 0; i < num_valid; i++ ) { idx = src_idx[i]; @@ -874,14 +874,14 @@ CvDTreeNode* CvDTreeTrainData::subsample_data( const CvMat* _subsample_idx ) if (is_buf_16u) { unsigned short* sample_idx_dst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + - workVarCount*sample_count + root->offset); + (size_t)workVarCount*sample_count + root->offset); for (i = 0; i < count; i++) sample_idx_dst[i] = (unsigned short)sample_idx_src[sidx[i]]; } else { int* sample_idx_dst = buf->data.i + root->buf_idx*get_length_subbuf() + - workVarCount*sample_count + root->offset; + (size_t)workVarCount*sample_count + root->offset; for (i = 0; i < count; i++) sample_idx_dst[i] = sample_idx_src[sidx[i]]; } @@ -1192,10 +1192,10 @@ void CvDTreeTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* ord_valu if( !is_buf_16u ) *sorted_indices = buf->data.i + n->buf_idx*get_length_subbuf() + - vi*sample_count + n->offset; + (size_t)vi*sample_count + n->offset; else { const unsigned short* short_indices = (const unsigned short*)(buf->data.s + n->buf_idx*get_length_subbuf() + - vi*sample_count + n->offset ); + (size_t)vi*sample_count + n->offset ); for( int i = 0; i < node_sample_count; i++ ) sorted_indices_buf[i] = short_indices[i]; *sorted_indices = sorted_indices_buf; @@ -1266,10 +1266,10 @@ const int* CvDTreeTrainData::get_cat_var_data( CvDTreeNode* n, int vi, int* cat_ const int* cat_values = 0; if( !is_buf_16u ) cat_values = buf->data.i + n->buf_idx*get_length_subbuf() + - vi*sample_count + n->offset; + (size_t)vi*sample_count + n->offset; else { const unsigned short* short_values = (const unsigned short*)(buf->data.s + n->buf_idx*get_length_subbuf() + - vi*sample_count + n->offset); + (size_t)vi*sample_count + n->offset); for( int i = 0; i < n->sample_count; i++ ) cat_values_buf[i] = short_values[i]; cat_values = cat_values_buf; From 225da0226e4e9d54e97aee488ac2b5ed4e813443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B9=20=D0=9D=D1=83=D0=B6?= =?UTF-8?q?=D0=BD=D1=8B=D0=B9?= Date: Tue, 7 Apr 2015 15:09:47 +0300 Subject: [PATCH 027/109] Fix bug in SVM::trainAuto --- modules/ml/src/svm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ml/src/svm.cpp b/modules/ml/src/svm.cpp index 449eb8dcd4..b74df5f0a4 100644 --- a/modules/ml/src/svm.cpp +++ b/modules/ml/src/svm.cpp @@ -1787,7 +1787,7 @@ public: if( !do_train( temp_train_samples, temp_train_responses )) continue; - for( i = 0; i < test_sample_count; i++ ) + for (i = 0; i < train_sample_count; i++) { j = sidx[(i+start+train_sample_count) % sample_count]; memcpy(temp_train_samples.ptr(i), samples.ptr(j), sample_size); From 0c24ccf53897c60dff19193623a97fc4713ce14e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B9=20=D0=9D=D1=83=D0=B6?= =?UTF-8?q?=D0=BD=D1=8B=D0=B9?= Date: Tue, 7 Apr 2015 15:43:59 +0300 Subject: [PATCH 028/109] Revert "Fix bug in SVM::trainAuto" This reverts commit 225da0226e4e9d54e97aee488ac2b5ed4e813443. --- modules/ml/src/svm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ml/src/svm.cpp b/modules/ml/src/svm.cpp index b74df5f0a4..449eb8dcd4 100644 --- a/modules/ml/src/svm.cpp +++ b/modules/ml/src/svm.cpp @@ -1787,7 +1787,7 @@ public: if( !do_train( temp_train_samples, temp_train_responses )) continue; - for (i = 0; i < train_sample_count; i++) + for( i = 0; i < test_sample_count; i++ ) { j = sidx[(i+start+train_sample_count) % sample_count]; memcpy(temp_train_samples.ptr(i), samples.ptr(j), sample_size); From 3646967deb9b48f45c44203e5c96836a8a180218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B9=20=D0=9D=D1=83=D0=B6?= =?UTF-8?q?=D0=BD=D1=8B=D0=B9?= Date: Tue, 7 Apr 2015 15:48:30 +0300 Subject: [PATCH 029/109] Fix bug in SVM::trainAuto --- modules/ml/src/svm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ml/src/svm.cpp b/modules/ml/src/svm.cpp index 449eb8dcd4..95b5fb97d5 100644 --- a/modules/ml/src/svm.cpp +++ b/modules/ml/src/svm.cpp @@ -1787,7 +1787,7 @@ public: if( !do_train( temp_train_samples, temp_train_responses )) continue; - for( i = 0; i < test_sample_count; i++ ) + for( i = 0; i < train_sample_count; i++ ) { j = sidx[(i+start+train_sample_count) % sample_count]; memcpy(temp_train_samples.ptr(i), samples.ptr(j), sample_size); From 052593c76042fca65e2370829e97d300575536aa Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Tue, 7 Apr 2015 16:44:26 +0300 Subject: [PATCH 030/109] 1. Input/OutputArray optimizations; 2. Algorithm::load/save added (moved from StatModel) 3. copyrights updated; added copyright/licensing info for ffmpeg 4. some warnings from Xcode 6.x are fixed --- 3rdparty/ffmpeg/build_win32.txt | 42 ++ 3rdparty/ffmpeg/license.txt | 520 ++++++++++++++++++ 3rdparty/ffmpeg/readme.txt | 70 +-- 3rdparty/readme.txt | 44 +- LICENSE | 8 + apps/traincascade/old_ml_inner_functions.cpp | 2 +- modules/core/include/opencv2/core.hpp | 73 ++- .../core/include/opencv2/core/ippasync.hpp | 44 ++ modules/core/include/opencv2/core/mat.hpp | 95 ++-- modules/core/include/opencv2/core/mat.inl.hpp | 9 +- .../core/include/opencv2/core/operations.hpp | 2 + modules/core/include/opencv2/core/version.hpp | 4 +- modules/core/src/algorithm.cpp | 14 + modules/imgproc/src/connectedcomponents.cpp | 14 +- modules/ml/include/opencv2/ml.hpp | 55 +- modules/ml/src/ann_mlp.cpp | 2 +- modules/ml/src/boost.cpp | 2 +- modules/ml/src/em.cpp | 2 +- modules/ml/src/inner_functions.cpp | 11 +- modules/ml/src/knearest.cpp | 2 +- modules/ml/src/lr.cpp | 2 +- modules/ml/src/nbayes.cpp | 2 +- modules/ml/src/precomp.hpp | 2 +- modules/ml/src/rtrees.cpp | 2 +- modules/ml/src/svm.cpp | 2 +- modules/ml/test/test_emknearestkmeans.cpp | 2 +- modules/ml/test/test_lr.cpp | 2 +- modules/ml/test/test_mltests2.cpp | 14 +- modules/ml/test/test_save_load.cpp | 18 +- .../opencv2/stitching/detail/seam_finders.hpp | 2 + .../opencv2/stitching/detail/warpers.hpp | 4 + modules/stitching/src/seam_finders.cpp | 5 + modules/stitching/src/warpers.cpp | 21 + modules/superres/src/optical_flow.cpp | 2 +- 34 files changed, 888 insertions(+), 207 deletions(-) create mode 100644 3rdparty/ffmpeg/build_win32.txt create mode 100644 3rdparty/ffmpeg/license.txt diff --git a/3rdparty/ffmpeg/build_win32.txt b/3rdparty/ffmpeg/build_win32.txt new file mode 100644 index 0000000000..e98b285208 --- /dev/null +++ b/3rdparty/ffmpeg/build_win32.txt @@ -0,0 +1,42 @@ +The build script is to be fixed. +Right now it assumes that 32-bit MinGW is in the system path and +64-bit mingw is installed to c:\Apps\MinGW64. + +It is important that gcc is used, not g++! +Otherwise the produced DLL will likely be dependent on libgcc_s_dw2-1.dll or similar DLL. +While we want to make the DLLs with minimum dependencies: Win32 libraries + msvcrt.dll. + +ffopencv.c is really a C++ source, hence -x c++ is used. + +How to update opencv_ffmpeg.dll and opencv_ffmpeg_64.dll when a new version of FFMPEG is release? + +1. Install 32-bit MinGW + MSYS from + http://sourceforge.net/projects/mingw/files/Automated%20MinGW%20Installer/mingw-get-inst/ + Let's assume, it's installed in C:\MSYS32. +2. Install 64-bit MinGW. http://mingw-w64.sourceforge.net/ + Let's assume, it's installed in C:\MSYS64 +3. Copy C:\MSYS32\msys to C:\MSYS64\msys. Edit C:\MSYS64\msys\etc\fstab, change C:\MSYS32 to C:\MSYS64. + +4. Now you have working MSYS32 and MSYS64 environments. + Launch, one by one, C:\MSYS32\msys\msys.bat and C:\MSYS64\msys\msys.bat to create your home directories. + +4. Download ffmpeg-x.y.z.tar.gz (where x.y.z denotes the actual ffmpeg version). + Copy it to C:\MSYS{32|64}\msys\home\ directory. + +5. To build 32-bit ffmpeg libraries, run C:\MSYS32\msys\msys.bat and type the following commands: + + 5.1. tar -xzf ffmpeg-x.y.z.tar.gz + 5.2. mkdir build + 5.3. cd build + 5.4. ../ffmpeg-x.y.z/configure --enable-w32threads + 5.5. make + 5.6. make install + 5.7. cd /local/lib + 5.8. strip -g *.a + +6. Then repeat the same for 64-bit case. The output libs: libavcodec.a etc. need to be renamed to libavcodec64.a etc. + +7. Then, copy all those libs to \3rdparty\lib\, copy the headers to \3rdparty\include\ffmpeg_. + +8. Then, go to \3rdparty\ffmpeg, edit make.bat + (change paths to the actual paths to your msys32 and msys64 distributions) and then run make.bat diff --git a/3rdparty/ffmpeg/license.txt b/3rdparty/ffmpeg/license.txt new file mode 100644 index 0000000000..e018837a39 --- /dev/null +++ b/3rdparty/ffmpeg/license.txt @@ -0,0 +1,520 @@ + Copyright (C) 2001 Fabrice Bellard + + FFmpeg is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + FFmpeg is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with FFmpeg; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +================================================================================== + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/3rdparty/ffmpeg/readme.txt b/3rdparty/ffmpeg/readme.txt index e98b285208..84faf7a83b 100644 --- a/3rdparty/ffmpeg/readme.txt +++ b/3rdparty/ffmpeg/readme.txt @@ -1,42 +1,32 @@ -The build script is to be fixed. -Right now it assumes that 32-bit MinGW is in the system path and -64-bit mingw is installed to c:\Apps\MinGW64. +* On Linux and other Unix flavors OpenCV uses default or user-built ffmpeg/libav libraries. + If user builds ffmpeg/libav from source and wants OpenCV to stay BSD library, not GPL/LGPL, + he/she should use --enabled-shared configure flag and make sure that no GPL components are + enabled (some notable examples are x264 (H264 encoder) and libac3 (Dolby AC3 audio codec)). + See https://www.ffmpeg.org/legal.html for details. + + If you want to play very safe and do not want to use FFMPEG at all, regardless of whether it's installed on + your system or not, configure and build OpenCV using CMake with WITH_FFMPEG=OFF flag. OpenCV will then use + AVFoundation (OSX), GStreamer (Linux) or other available backends supported by opencv_videoio module. + + There is also our self-contained motion jpeg codec, which you can use without any worries. + It handles CV_FOURCC('M', 'J', 'P', 'G') streams within an AVI container (".avi"). + +* On Windows OpenCV uses pre-built ffmpeg binaries, built with proper flags (without GPL components) and + wrapped with simple, stable OpenCV-compatible API. + The binaries are opencv_ffmpeg.dll (version for 32-bit Windows) and + opencv_ffmpeg_64.dll (version for 64-bit Windows). + + See build_win32.txt for the build instructions, if you want to rebuild opencv_ffmpeg*.dll from scratch. -It is important that gcc is used, not g++! -Otherwise the produced DLL will likely be dependent on libgcc_s_dw2-1.dll or similar DLL. -While we want to make the DLLs with minimum dependencies: Win32 libraries + msvcrt.dll. + The pre-built opencv_ffmpeg*.dll is: + * LGPL library, not BSD libraries. + * Loaded at runtime by opencv_videoio module. + If it succeeds, ffmpeg can be used to decode/encode videos; + otherwise, other API is used. -ffopencv.c is really a C++ source, hence -x c++ is used. - -How to update opencv_ffmpeg.dll and opencv_ffmpeg_64.dll when a new version of FFMPEG is release? - -1. Install 32-bit MinGW + MSYS from - http://sourceforge.net/projects/mingw/files/Automated%20MinGW%20Installer/mingw-get-inst/ - Let's assume, it's installed in C:\MSYS32. -2. Install 64-bit MinGW. http://mingw-w64.sourceforge.net/ - Let's assume, it's installed in C:\MSYS64 -3. Copy C:\MSYS32\msys to C:\MSYS64\msys. Edit C:\MSYS64\msys\etc\fstab, change C:\MSYS32 to C:\MSYS64. - -4. Now you have working MSYS32 and MSYS64 environments. - Launch, one by one, C:\MSYS32\msys\msys.bat and C:\MSYS64\msys\msys.bat to create your home directories. - -4. Download ffmpeg-x.y.z.tar.gz (where x.y.z denotes the actual ffmpeg version). - Copy it to C:\MSYS{32|64}\msys\home\ directory. - -5. To build 32-bit ffmpeg libraries, run C:\MSYS32\msys\msys.bat and type the following commands: - - 5.1. tar -xzf ffmpeg-x.y.z.tar.gz - 5.2. mkdir build - 5.3. cd build - 5.4. ../ffmpeg-x.y.z/configure --enable-w32threads - 5.5. make - 5.6. make install - 5.7. cd /local/lib - 5.8. strip -g *.a - -6. Then repeat the same for 64-bit case. The output libs: libavcodec.a etc. need to be renamed to libavcodec64.a etc. - -7. Then, copy all those libs to \3rdparty\lib\, copy the headers to \3rdparty\include\ffmpeg_. - -8. Then, go to \3rdparty\ffmpeg, edit make.bat - (change paths to the actual paths to your msys32 and msys64 distributions) and then run make.bat + If LGPL/GPL software can not be supplied with your OpenCV-based product, simply exclude + opencv_ffmpeg*.dll from your distribution; OpenCV will stay fully functional except for the ability to + decode/encode videos using FFMPEG (though, it may still be able to do that using other API, + such as Video for Windows, Windows Media Foundation or our self-contained motion jpeg codec). + + See license.txt for the FFMPEG copyright notice and the licensing terms. diff --git a/3rdparty/readme.txt b/3rdparty/readme.txt index 64e2563a85..b067009028 100644 --- a/3rdparty/readme.txt +++ b/3rdparty/readme.txt @@ -6,41 +6,34 @@ In order to use these versions of libraries instead of system ones on UNIX syste should use BUILD_ CMake flags (for example, BUILD_PNG for the libpng library). ------------------------------------------------------------------------------------ -libjpeg 8d (8.4) - The Independent JPEG Group's JPEG software. +libjpeg The Independent JPEG Group's JPEG software. Copyright (C) 1991-2012, Thomas G. Lane, Guido Vollbeding. See IGJ home page http://www.ijg.org for details and links to the source code - HAVE_JPEG preprocessor flag must be set to make imgcodecs use libjpeg. - On UNIX systems configure script takes care of it. + WITH_JPEG CMake option must be ON to add libjpeg support to imgcodecs. ------------------------------------------------------------------------------------ -libpng 1.5.12 - Portable Network Graphics library. +libpng Portable Network Graphics library. Copyright (c) 2004, 2006-2012 Glenn Randers-Pehrson. See libpng home page http://www.libpng.org for details and links to the source code - HAVE_PNG preprocessor flag must be set to make imgcodecs use libpng. - On UNIX systems configure script takes care of it. + WITH_PNG CMake option must be ON to add libpng support to imgcodecs. ------------------------------------------------------------------------------------ -libtiff 4.0.2 - Tag Image File Format (TIFF) Software +libtiff Tag Image File Format (TIFF) Software Copyright (c) 1988-1997 Sam Leffler Copyright (c) 1991-1997 Silicon Graphics, Inc. See libtiff home page http://www.remotesensing.org/libtiff/ for details and links to the source code - HAVE_TIFF preprocessor flag must be set to make imgcodecs use libtiff. - On UNIX systems configure script takes care of it. - In this build support for ZIP (LZ77 compression) is turned on. + WITH_TIFF CMake option must be ON to add libtiff & zlib support to imgcodecs. ------------------------------------------------------------------------------------ -zlib 1.2.7 - General purpose LZ77 compression library +zlib General purpose LZ77 compression library Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler. See zlib home page http://www.zlib.net for details and links to the source code - - No preprocessor definition is needed to make imgcodecs use this library - - it is included automatically if either libpng or libtiff are used. ------------------------------------------------------------------------------------ -jasper-1.900.1 - JasPer is a collection of software +jasper JasPer is a collection of software (i.e., a library and application programs) for the coding and manipulation of images. This software can handle image data in a variety of formats. One such format supported by JasPer is the JPEG-2000 @@ -50,14 +43,9 @@ jasper-1.900.1 - JasPer is a collection of software Copyright (c) 1999-2000 The University of British Columbia Copyright (c) 2001-2003 Michael David Adams - The JasPer license can be found in src/libjasper. - - OpenCV on Windows uses pre-built libjasper library - (lib/libjasper*). To get the latest source code, - please, visit the project homepage: - http://www.ece.uvic.ca/~mdadams/jasper/ + The JasPer license can be found in libjasper. ------------------------------------------------------------------------------------ -openexr-1.7.1 - OpenEXR is a high dynamic-range (HDR) image file format developed +openexr OpenEXR is a high dynamic-range (HDR) image file format developed by Industrial Light & Magic for use in computer imaging applications. Copyright (c) 2006, Industrial Light & Magic, a division of Lucasfilm @@ -66,11 +54,17 @@ openexr-1.7.1 - OpenEXR is a high dynamic-range (HDR) image file format de The project homepage: http://www.openexr.com ------------------------------------------------------------------------------------ -ffmpeg-0.8.0 - FFmpeg is a complete, cross-platform solution to record, +ffmpeg FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. It includes libavcodec - the leading audio/video codec library, and also libavformat, libavutils and - other helper libraries that are used by OpenCV (in highgui module) to + other helper libraries that are used by OpenCV (in videoio module) to read and write video files. - The project homepage: http://ffmpeg.org/ + Copyright (c) 2001 Fabrice Bellard + + The project homepage: http://ffmpeg.org/. + + * On Linux/OSX we link user-installed ffmpeg (or ffmpeg fork libav). + * On Windows we use pre-built ffmpeg binaries, + see opencv/3rdparty/ffmpeg/readme.txt for details and licensing information ------------------------------------------------------------------------------------ diff --git a/LICENSE b/LICENSE index 5e32d88b47..ab58eebcad 100644 --- a/LICENSE +++ b/LICENSE @@ -7,6 +7,14 @@ copy or use the software. For Open Source Computer Vision Library (3-clause BSD License) +Copyright (C) 2000-2015, Intel Corporation, all rights reserved. +Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +Copyright (C) 2009-2015, NVIDIA Corporation, all rights reserved. +Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved. +Copyright (C) 2015, OpenCV Foundation, all rights reserved. +Copyright (C) 2015, Itseez Inc., all rights reserved. +Third party copyrights are property of their respective owners. + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/apps/traincascade/old_ml_inner_functions.cpp b/apps/traincascade/old_ml_inner_functions.cpp index 10b43f93fe..68e78b1e57 100644 --- a/apps/traincascade/old_ml_inner_functions.cpp +++ b/apps/traincascade/old_ml_inner_functions.cpp @@ -82,7 +82,7 @@ void CvStatModel::load( const char* filename, const char* name ) { CvFileStorage* fs = 0; - CV_FUNCNAME( "CvStatModel::load" ); + CV_FUNCNAME( "CvAlgorithm::load" ); __BEGIN__; diff --git a/modules/core/include/opencv2/core.hpp b/modules/core/include/opencv2/core.hpp index 2a51de22e5..72cb1a46d9 100644 --- a/modules/core/include/opencv2/core.hpp +++ b/modules/core/include/opencv2/core.hpp @@ -10,8 +10,10 @@ // License Agreement // For Open Source Computer Vision Library // -// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2000-2015, Intel Corporation, all rights reserved. // Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Copyright (C) 2015, OpenCV Foundation, all rights reserved. +// Copyright (C) 2015, Itseez Inc., all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, @@ -2921,6 +2923,10 @@ public: Algorithm(); virtual ~Algorithm(); + /** @brief Clears the algorithm state + */ + CV_WRAP virtual void clear() {} + /** @brief Stores algorithm parameters in a file storage */ virtual void write(FileStorage& fs) const { (void)fs; } @@ -2928,6 +2934,71 @@ public: /** @brief Reads algorithm parameters from a file storage */ virtual void read(const FileNode& fn) { (void)fn; } + + /** @brief Returns true if the Algorithm is empty (e.g. in the very beginning or after unsuccessful read + */ + virtual bool empty() const { return false; } + + /** @brief Reads algorithm from the file node + + This is static template method of Algorithm. It's usage is following (in the case of SVM): + @code + Ptr svm = Algorithm::read(fn); + @endcode + In order to make this method work, the derived class must overwrite Algorithm::read(const + FileNode& fn) and also have static create() method without parameters + (or with all the optional parameters) + */ + template static Ptr<_Tp> read(const FileNode& fn) + { + Ptr<_Tp> obj = _Tp::create(); + obj->read(fn); + return !obj->empty() ? obj : Ptr<_Tp>(); + } + + /** @brief Loads algorithm from the file + + This is static template method of Algorithm. It's usage is following (in the case of SVM): + @code + Ptr svm = Algorithm::load("my_svm_model.xml"); + @endcode + In order to make this method work, the derived class must overwrite Algorithm::read(const + FileNode& fn). + */ + template static Ptr<_Tp> load(const String& filename, const String& objname=String()) + { + FileStorage fs(filename, FileStorage::READ); + FileNode fn = objname.empty() ? fs.getFirstTopLevelNode() : fs[objname]; + Ptr<_Tp> obj = _Tp::create(); + obj->read(fn); + return !obj->empty() ? obj : Ptr<_Tp>(); + } + + /** @brief Loads algorithm from a String + + @param strModel The string variable containing the model you want to load. + + This is static template method of Algorithm. It's usage is following (in the case of SVM): + @code + Ptr svm = Algorithm::loadFromString(myStringModel); + @endcode + */ + template static Ptr<_Tp> loadFromString(const String& strModel, const String& objname=String()) + { + FileStorage fs(strModel, FileStorage::READ + FileStorage::MEMORY); + FileNode fn = objname.empty() ? fs.getFirstTopLevelNode() : fs[objname]; + Ptr<_Tp> obj = _Tp::create(); + obj->read(fn); + return !obj->empty() ? obj : Ptr<_Tp>(); + } + + /** Saves the algorithm to a file. + In order to make this method work, the derived class must implement Algorithm::write(FileStorage& fs). */ + CV_WRAP virtual void save(const String& filename) const; + + /** Returns the algorithm string identifier. + This string is used as top level xml/yml node tag when the object is saved to a file or string. */ + CV_WRAP virtual String getDefaultName() const; }; struct Param { diff --git a/modules/core/include/opencv2/core/ippasync.hpp b/modules/core/include/opencv2/core/ippasync.hpp index 2fce5d5b93..4de8611dbe 100644 --- a/modules/core/include/opencv2/core/ippasync.hpp +++ b/modules/core/include/opencv2/core/ippasync.hpp @@ -1,3 +1,47 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2015, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Copyright (C) 2015, Itseez Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + #ifndef __OPENCV_CORE_IPPASYNC_HPP__ #define __OPENCV_CORE_IPPASYNC_HPP__ diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp index 8b0d94f6e1..fa867fde05 100644 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@ -70,7 +70,7 @@ class CV_EXPORTS _OutputArray; It is defined as: @code - typedef const _InputArray& InputArray; + class InputArray; // = _InputArray @endcode where _InputArray is a class that can be constructed from `Mat`, `Mat_`, `Matx`, `std::vector`, `std::vector >` or `std::vector`. It can also be constructed @@ -185,39 +185,42 @@ public: _InputArray(const UMat& um); _InputArray(const std::vector& umv); - virtual Mat getMat(int idx=-1) const; - virtual UMat getUMat(int idx=-1) const; - virtual void getMatVector(std::vector& mv) const; - virtual void getUMatVector(std::vector& umv) const; - virtual cuda::GpuMat getGpuMat() const; - virtual ogl::Buffer getOGlBuffer() const; - void* getObj() const; + Mat getMat(int idx=-1) const; + UMat getUMat(int idx=-1) const; + void getMatVector(std::vector& mv) const; + void getUMatVector(std::vector& umv) const; + cuda::GpuMat getGpuMat() const; + ogl::Buffer getOGlBuffer() const; - virtual int kind() const; - virtual int dims(int i=-1) const; - virtual int cols(int i=-1) const; - virtual int rows(int i=-1) const; - virtual Size size(int i=-1) const; - virtual int sizend(int* sz, int i=-1) const; - virtual bool sameSize(const _InputArray& arr) const; - virtual size_t total(int i=-1) const; - virtual int type(int i=-1) const; - virtual int depth(int i=-1) const; - virtual int channels(int i=-1) const; - virtual bool isContinuous(int i=-1) const; - virtual bool isSubmatrix(int i=-1) const; - virtual bool empty() const; - virtual void copyTo(const _OutputArray& arr) const; - virtual void copyTo(const _OutputArray& arr, const _InputArray & mask) const; - virtual size_t offset(int i=-1) const; - virtual size_t step(int i=-1) const; + int getFlags() const; + void* getObj() const; + Size getSz() const; + + int kind() const; + int dims(int i=-1) const; + int cols(int i=-1) const; + int rows(int i=-1) const; + Size size(int i=-1) const; + int sizend(int* sz, int i=-1) const; + bool sameSize(const _InputArray& arr) const; + size_t total(int i=-1) const; + int type(int i=-1) const; + int depth(int i=-1) const; + int channels(int i=-1) const; + bool isContinuous(int i=-1) const; + bool isSubmatrix(int i=-1) const; + bool empty() const; + void copyTo(const _OutputArray& arr) const; + void copyTo(const _OutputArray& arr, const _InputArray & mask) const; + size_t offset(int i=-1) const; + size_t step(int i=-1) const; bool isMat() const; bool isUMat() const; bool isMatVector() const; bool isUMatVector() const; bool isMatx() const; - virtual ~_InputArray(); + ~_InputArray(); protected: int flags; @@ -303,21 +306,21 @@ public: _OutputArray(const UMat& m); _OutputArray(const std::vector& vec); - virtual bool fixedSize() const; - virtual bool fixedType() const; - virtual bool needed() const; - virtual Mat& getMatRef(int i=-1) const; - virtual UMat& getUMatRef(int i=-1) const; - virtual cuda::GpuMat& getGpuMatRef() const; - virtual ogl::Buffer& getOGlBufferRef() const; - virtual cuda::HostMem& getHostMemRef() const; - virtual void create(Size sz, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const; - virtual void create(int rows, int cols, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const; - virtual void create(int dims, const int* size, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const; - virtual void createSameSize(const _InputArray& arr, int mtype) const; - virtual void release() const; - virtual void clear() const; - virtual void setTo(const _InputArray& value, const _InputArray & mask = _InputArray()) const; + bool fixedSize() const; + bool fixedType() const; + bool needed() const; + Mat& getMatRef(int i=-1) const; + UMat& getUMatRef(int i=-1) const; + cuda::GpuMat& getGpuMatRef() const; + ogl::Buffer& getOGlBufferRef() const; + cuda::HostMem& getHostMemRef() const; + void create(Size sz, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const; + void create(int rows, int cols, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const; + void create(int dims, const int* size, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const; + void createSameSize(const _InputArray& arr, int mtype) const; + void release() const; + void clear() const; + void setTo(const _InputArray& value, const _InputArray & mask = _InputArray()) const; void assign(const UMat& u) const; void assign(const Mat& m) const; @@ -358,13 +361,15 @@ public: template _InputOutputArray(const Matx<_Tp, m, n>& matx); _InputOutputArray(const UMat& m); _InputOutputArray(const std::vector& vec); + + explicit _InputOutputArray(const _OutputArray& o); }; -typedef const _InputArray& InputArray; +typedef _InputArray InputArray; typedef InputArray InputArrayOfArrays; -typedef const _OutputArray& OutputArray; +typedef _OutputArray OutputArray; typedef OutputArray OutputArrayOfArrays; -typedef const _InputOutputArray& InputOutputArray; +typedef _InputOutputArray InputOutputArray; typedef InputOutputArray InputOutputArrayOfArrays; CV_EXPORTS InputOutputArray noArray(); diff --git a/modules/core/include/opencv2/core/mat.inl.hpp b/modules/core/include/opencv2/core/mat.inl.hpp index cb39c15fb4..057d903c68 100644 --- a/modules/core/include/opencv2/core/mat.inl.hpp +++ b/modules/core/include/opencv2/core/mat.inl.hpp @@ -7,11 +7,13 @@ // copy or use the software. // // -// License Agreement +// License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. // Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Copyright (C) 2015, Itseez Inc., all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, @@ -61,6 +63,8 @@ inline void _InputArray::init(int _flags, const void* _obj, Size _sz) { flags = _flags; obj = (void*)_obj; sz = _sz; } inline void* _InputArray::getObj() const { return obj; } +inline int _InputArray::getFlags() const { return flags; } +inline Size _InputArray::getSz() const { return sz; } inline _InputArray::_InputArray() { init(NONE, 0); } inline _InputArray::_InputArray(int _flags, void* _obj) { init(_flags, _obj); } @@ -290,6 +294,9 @@ inline _InputOutputArray::_InputOutputArray(const ogl::Buffer& buf) inline _InputOutputArray::_InputOutputArray(const cuda::HostMem& cuda_mem) { init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_RW, &cuda_mem); } +inline _InputOutputArray::_InputOutputArray(const _OutputArray& o) +{ init(o.getFlags(), o.getObj(), o.getSz()); } + //////////////////////////////////////////// Mat ////////////////////////////////////////// inline diff --git a/modules/core/include/opencv2/core/operations.hpp b/modules/core/include/opencv2/core/operations.hpp index 067140abb3..bced1a7559 100644 --- a/modules/core/include/opencv2/core/operations.hpp +++ b/modules/core/include/opencv2/core/operations.hpp @@ -12,6 +12,8 @@ // // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. // Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Copyright (C) 2015, Itseez Inc., all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, diff --git a/modules/core/include/opencv2/core/version.hpp b/modules/core/include/opencv2/core/version.hpp index f21293ad0b..4a46f7930e 100644 --- a/modules/core/include/opencv2/core/version.hpp +++ b/modules/core/include/opencv2/core/version.hpp @@ -10,8 +10,10 @@ // Intel License Agreement // For Open Source Computer Vision Library // -// Copyright( C) 2000, Intel Corporation, all rights reserved. +// Copyright( C) 2000-2015, Intel Corporation, all rights reserved. // Copyright (C) 2011-2013, NVIDIA Corporation, all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Copyright (C) 2015, Itseez Inc., all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, diff --git a/modules/core/src/algorithm.cpp b/modules/core/src/algorithm.cpp index b10a28988a..b930428719 100644 --- a/modules/core/src/algorithm.cpp +++ b/modules/core/src/algorithm.cpp @@ -53,6 +53,20 @@ Algorithm::~Algorithm() { } +void Algorithm::save(const String& filename) const +{ + FileStorage fs(filename, FileStorage::WRITE); + fs << getDefaultName() << "{"; + fs << "format" << (int)3; + write(fs); + fs << "}"; +} + +String Algorithm::getDefaultName() const +{ + return String("my_object"); +} + } /* End of file. */ diff --git a/modules/imgproc/src/connectedcomponents.cpp b/modules/imgproc/src/connectedcomponents.cpp index 523eb14c09..afa3647699 100644 --- a/modules/imgproc/src/connectedcomponents.cpp +++ b/modules/imgproc/src/connectedcomponents.cpp @@ -65,20 +65,20 @@ namespace cv{ }; struct CCStatsOp{ - const _OutputArray* _mstatsv; + OutputArray _mstatsv; cv::Mat statsv; - const _OutputArray* _mcentroidsv; + OutputArray _mcentroidsv; cv::Mat centroidsv; std::vector integrals; - CCStatsOp(OutputArray _statsv, OutputArray _centroidsv): _mstatsv(&_statsv), _mcentroidsv(&_centroidsv){ + CCStatsOp(OutputArray _statsv, OutputArray _centroidsv): _mstatsv(_statsv), _mcentroidsv(_centroidsv){ } inline void init(int nlabels){ - _mstatsv->create(cv::Size(CC_STAT_MAX, nlabels), cv::DataType::type); - statsv = _mstatsv->getMat(); - _mcentroidsv->create(cv::Size(2, nlabels), cv::DataType::type); - centroidsv = _mcentroidsv->getMat(); + _mstatsv.create(cv::Size(CC_STAT_MAX, nlabels), cv::DataType::type); + statsv = _mstatsv.getMat(); + _mcentroidsv.create(cv::Size(2, nlabels), cv::DataType::type); + centroidsv = _mcentroidsv.getMat(); for(int l = 0; l < (int) nlabels; ++l){ int *row = (int *) &statsv.at(l, 0); diff --git a/modules/ml/include/opencv2/ml.hpp b/modules/ml/include/opencv2/ml.hpp index a611583aef..19e26d3bbc 100644 --- a/modules/ml/include/opencv2/ml.hpp +++ b/modules/ml/include/opencv2/ml.hpp @@ -297,11 +297,12 @@ public: COMPRESSED_INPUT=2, PREPROCESSED_INPUT=4 }; - CV_WRAP virtual void clear(); /** @brief Returns the number of variables in training samples */ CV_WRAP virtual int getVarCount() const = 0; + CV_WRAP virtual bool empty() const; + /** @brief Returns true if the model is trained */ CV_WRAP virtual bool isTrained() const = 0; /** @brief Returns true if the model is classifier */ @@ -347,40 +348,6 @@ public: */ CV_WRAP virtual float predict( InputArray samples, OutputArray results=noArray(), int flags=0 ) const = 0; - /** @brief Loads model from the file - - This is static template method of StatModel. It's usage is following (in the case of SVM): - @code - Ptr svm = StatModel::load("my_svm_model.xml"); - @endcode - In order to make this method work, the derived class must overwrite Algorithm::read(const - FileNode& fn). - */ - template static Ptr<_Tp> load(const String& filename) - { - FileStorage fs(filename, FileStorage::READ); - Ptr<_Tp> model = _Tp::create(); - model->read(fs.getFirstTopLevelNode()); - return model->isTrained() ? model : Ptr<_Tp>(); - } - - /** @brief Loads model from a String - - @param strModel The string variable containing the model you want to load. - - This is static template method of StatModel. It's usage is following (in the case of SVM): - @code - Ptr svm = StatModel::loadFromString(myStringModel); - @endcode - */ - template static Ptr<_Tp> loadFromString(const String& strModel) - { - FileStorage fs(strModel, FileStorage::READ + FileStorage::MEMORY); - Ptr<_Tp> model = _Tp::create(); - model->read(fs.getFirstTopLevelNode()); - return model->isTrained() ? model : Ptr<_Tp>(); - } - /** @brief Create and train model with default parameters The class must implement static `create()` method with no parameters or with all default parameter values @@ -390,14 +357,6 @@ public: Ptr<_Tp> model = _Tp::create(); return !model.empty() && model->train(data, flags) ? model : Ptr<_Tp>(); } - - /** Saves the model to a file. - In order to make this method work, the derived class must implement Algorithm::write(FileStorage& fs). */ - CV_WRAP virtual void save(const String& filename) const; - - /** Returns model string identifier. - This string is used as top level xml/yml node tag when model is saved to a file or string. */ - CV_WRAP virtual String getDefaultModelName() const = 0; }; /****************************************************************************************\ @@ -939,7 +898,7 @@ public: /** Creates empty %EM model. The model should be trained then using StatModel::train(traindata, flags) method. Alternatively, you - can use one of the EM::train\* methods or load it from file using StatModel::load\(filename). + can use one of the EM::train\* methods or load it from file using Algorithm::load\(filename). */ CV_WRAP static Ptr create(); }; @@ -1127,7 +1086,7 @@ public: The static method creates empty decision tree with the specified parameters. It should be then trained using train method (see StatModel::train). Alternatively, you can load the model from - file using StatModel::load\(filename). + file using Algorithm::load\(filename). */ CV_WRAP static Ptr create(); }; @@ -1181,7 +1140,7 @@ public: /** Creates the empty model. Use StatModel::train to train the model, StatModel::train to create and train the model, - StatModel::load to load the pre-trained model. + Algorithm::load to load the pre-trained model. */ CV_WRAP static Ptr create(); }; @@ -1231,7 +1190,7 @@ public: }; /** Creates the empty model. - Use StatModel::train to train the model, StatModel::load\(filename) to load the pre-trained model. */ + Use StatModel::train to train the model, Algorithm::load\(filename) to load the pre-trained model. */ CV_WRAP static Ptr create(); }; @@ -1416,7 +1375,7 @@ public: /** @brief Creates empty model - Use StatModel::train to train the model, StatModel::load\(filename) to load the pre-trained model. + Use StatModel::train to train the model, Algorithm::load\(filename) to load the pre-trained model. Note that the train method has optional flags: ANN_MLP::TrainFlags. */ static Ptr create(); diff --git a/modules/ml/src/ann_mlp.cpp b/modules/ml/src/ann_mlp.cpp index 2b29519cef..89dfa38444 100644 --- a/modules/ml/src/ann_mlp.cpp +++ b/modules/ml/src/ann_mlp.cpp @@ -1294,7 +1294,7 @@ public: return layer_sizes.empty() ? 0 : layer_sizes[0]; } - String getDefaultModelName() const + String getDefaultName() const { return "opencv_ml_ann_mlp"; } diff --git a/modules/ml/src/boost.cpp b/modules/ml/src/boost.cpp index 5694ff1051..d7b6c61dd4 100644 --- a/modules/ml/src/boost.cpp +++ b/modules/ml/src/boost.cpp @@ -465,7 +465,7 @@ public: CV_WRAP_SAME_PROPERTY(float, RegressionAccuracy, impl.params) CV_WRAP_SAME_PROPERTY_S(cv::Mat, Priors, impl.params) - String getDefaultModelName() const { return "opencv_ml_boost"; } + String getDefaultName() const { return "opencv_ml_boost"; } bool train( const Ptr& trainData, int flags ) { diff --git a/modules/ml/src/em.cpp b/modules/ml/src/em.cpp index c84be84b9c..59c1352e42 100644 --- a/modules/ml/src/em.cpp +++ b/modules/ml/src/em.cpp @@ -227,7 +227,7 @@ public: return means.cols; } - String getDefaultModelName() const + String getDefaultName() const { return "opencv_ml_em"; } diff --git a/modules/ml/src/inner_functions.cpp b/modules/ml/src/inner_functions.cpp index 561abbaeb8..52f368874d 100644 --- a/modules/ml/src/inner_functions.cpp +++ b/modules/ml/src/inner_functions.cpp @@ -50,7 +50,7 @@ ParamGrid::ParamGrid(double _minVal, double _maxVal, double _logStep) logStep = std::max(_logStep, 1.); } -void StatModel::clear() {} +bool StatModel::empty() const { return !isTrained(); } int StatModel::getVarCount() const { return 0; } @@ -111,15 +111,6 @@ float StatModel::calcError( const Ptr& data, bool testerr, OutputArra return (float)(err / n * (isclassifier ? 100 : 1)); } -void StatModel::save(const String& filename) const -{ - FileStorage fs(filename, FileStorage::WRITE); - fs << getDefaultModelName() << "{"; - fs << "format" << (int)3; - write(fs); - fs << "}"; -} - /* Calculates upper triangular matrix S, where A is a symmetrical matrix A=S'*S */ static void Cholesky( const Mat& A, Mat& S ) { diff --git a/modules/ml/src/knearest.cpp b/modules/ml/src/knearest.cpp index 70e178e6e2..99477cd12d 100644 --- a/modules/ml/src/knearest.cpp +++ b/modules/ml/src/knearest.cpp @@ -496,7 +496,7 @@ public: return impl->train(data, flags); } - String getDefaultModelName() const { return impl->getModelName(); } + String getDefaultName() const { return impl->getModelName(); } protected: void initImpl(int algorithmType) diff --git a/modules/ml/src/lr.cpp b/modules/ml/src/lr.cpp index 5a057a205f..24fc29f67c 100644 --- a/modules/ml/src/lr.cpp +++ b/modules/ml/src/lr.cpp @@ -104,7 +104,7 @@ public: virtual int getVarCount() const { return learnt_thetas.cols; } virtual bool isTrained() const { return !learnt_thetas.empty(); } virtual bool isClassifier() const { return true; } - virtual String getDefaultModelName() const { return "opencv_ml_lr"; } + virtual String getDefaultName() const { return "opencv_ml_lr"; } protected: Mat calc_sigmoid(const Mat& data) const; double compute_cost(const Mat& _data, const Mat& _labels, const Mat& _init_theta); diff --git a/modules/ml/src/nbayes.cpp b/modules/ml/src/nbayes.cpp index 9fc0d833ba..5ca74acd91 100644 --- a/modules/ml/src/nbayes.cpp +++ b/modules/ml/src/nbayes.cpp @@ -443,7 +443,7 @@ public: bool isTrained() const { return !avg.empty(); } bool isClassifier() const { return true; } int getVarCount() const { return nallvars; } - String getDefaultModelName() const { return "opencv_ml_nbayes"; } + String getDefaultName() const { return "opencv_ml_nbayes"; } int nallvars; Mat var_idx, cls_labels, c; diff --git a/modules/ml/src/precomp.hpp b/modules/ml/src/precomp.hpp index 77700a05a2..84821988b6 100644 --- a/modules/ml/src/precomp.hpp +++ b/modules/ml/src/precomp.hpp @@ -290,7 +290,7 @@ namespace ml virtual ~DTreesImpl(); virtual void clear(); - String getDefaultModelName() const { return "opencv_ml_dtree"; } + String getDefaultName() const { return "opencv_ml_dtree"; } bool isTrained() const { return !roots.empty(); } bool isClassifier() const { return _isClassifier; } int getVarCount() const { return varType.empty() ? 0 : (int)(varType.size() - 1); } diff --git a/modules/ml/src/rtrees.cpp b/modules/ml/src/rtrees.cpp index f5e2b21bdb..4da34992dd 100644 --- a/modules/ml/src/rtrees.cpp +++ b/modules/ml/src/rtrees.cpp @@ -375,7 +375,7 @@ public: RTreesImpl() {} virtual ~RTreesImpl() {} - String getDefaultModelName() const { return "opencv_ml_rtrees"; } + String getDefaultName() const { return "opencv_ml_rtrees"; } bool train( const Ptr& trainData, int flags ) { diff --git a/modules/ml/src/svm.cpp b/modules/ml/src/svm.cpp index 449eb8dcd4..05994eb918 100644 --- a/modules/ml/src/svm.cpp +++ b/modules/ml/src/svm.cpp @@ -2008,7 +2008,7 @@ public: return var_count; } - String getDefaultModelName() const + String getDefaultName() const { return "opencv_ml_svm"; } diff --git a/modules/ml/test/test_emknearestkmeans.cpp b/modules/ml/test/test_emknearestkmeans.cpp index a079be22f2..65371755ab 100644 --- a/modules/ml/test/test_emknearestkmeans.cpp +++ b/modules/ml/test/test_emknearestkmeans.cpp @@ -576,7 +576,7 @@ protected: // Read in try { - em = StatModel::load(filename); + em = Algorithm::load(filename); } catch(...) { diff --git a/modules/ml/test/test_lr.cpp b/modules/ml/test/test_lr.cpp index e0da01cfb9..1bca9051df 100644 --- a/modules/ml/test/test_lr.cpp +++ b/modules/ml/test/test_lr.cpp @@ -179,7 +179,7 @@ void CV_LRTest_SaveLoad::run( int /*start_from*/ ) // and load to another try { - Ptr lr2 = StatModel::load(filename); + Ptr lr2 = Algorithm::load(filename); lr2->predict(tdata->getSamples(), responses2); learnt_mat2 = lr2->get_learnt_thetas(); } diff --git a/modules/ml/test/test_mltests2.cpp b/modules/ml/test/test_mltests2.cpp index cfaf0f2491..919fae6ce4 100644 --- a/modules/ml/test/test_mltests2.cpp +++ b/modules/ml/test/test_mltests2.cpp @@ -472,19 +472,19 @@ void CV_MLBaseTest::save( const char* filename ) void CV_MLBaseTest::load( const char* filename ) { if( modelName == CV_NBAYES ) - model = StatModel::load( filename ); + model = Algorithm::load( filename ); else if( modelName == CV_KNEAREST ) - model = StatModel::load( filename ); + model = Algorithm::load( filename ); else if( modelName == CV_SVM ) - model = StatModel::load( filename ); + model = Algorithm::load( filename ); else if( modelName == CV_ANN ) - model = StatModel::load( filename ); + model = Algorithm::load( filename ); else if( modelName == CV_DTREE ) - model = StatModel::load( filename ); + model = Algorithm::load( filename ); else if( modelName == CV_BOOST ) - model = StatModel::load( filename ); + model = Algorithm::load( filename ); else if( modelName == CV_RTREES ) - model = StatModel::load( filename ); + model = Algorithm::load( filename ); else CV_Error( CV_StsNotImplemented, "invalid stat model name"); } diff --git a/modules/ml/test/test_save_load.cpp b/modules/ml/test/test_save_load.cpp index 606079b818..2d6f144bb9 100644 --- a/modules/ml/test/test_save_load.cpp +++ b/modules/ml/test/test_save_load.cpp @@ -190,17 +190,17 @@ protected: bool isTree = modelName == CV_BOOST || modelName == CV_DTREE || modelName == CV_RTREES; Ptr model; if (modelName == CV_BOOST) - model = StatModel::load(filename); + model = Algorithm::load(filename); else if (modelName == CV_ANN) - model = StatModel::load(filename); + model = Algorithm::load(filename); else if (modelName == CV_DTREE) - model = StatModel::load(filename); + model = Algorithm::load(filename); else if (modelName == CV_NBAYES) - model = StatModel::load(filename); + model = Algorithm::load(filename); else if (modelName == CV_SVM) - model = StatModel::load(filename); + model = Algorithm::load(filename); else if (modelName == CV_RTREES) - model = StatModel::load(filename); + model = Algorithm::load(filename); if (!model) { code = cvtest::TS::FAIL_INVALID_TEST_DATA; @@ -273,11 +273,11 @@ TEST(DISABLED_ML_SVM, linear_save_load) { Ptr svm1, svm2, svm3; - svm1 = StatModel::load("SVM45_X_38-1.xml"); - svm2 = StatModel::load("SVM45_X_38-2.xml"); + svm1 = Algorithm::load("SVM45_X_38-1.xml"); + svm2 = Algorithm::load("SVM45_X_38-2.xml"); string tname = tempfile("a.xml"); svm2->save(tname); - svm3 = StatModel::load(tname); + svm3 = Algorithm::load(tname); ASSERT_EQ(svm1->getVarCount(), svm2->getVarCount()); ASSERT_EQ(svm1->getVarCount(), svm3->getVarCount()); diff --git a/modules/stitching/include/opencv2/stitching/detail/seam_finders.hpp b/modules/stitching/include/opencv2/stitching/detail/seam_finders.hpp index 37029215e3..4ff22c40c0 100644 --- a/modules/stitching/include/opencv2/stitching/detail/seam_finders.hpp +++ b/modules/stitching/include/opencv2/stitching/detail/seam_finders.hpp @@ -106,6 +106,8 @@ protected: class CV_EXPORTS VoronoiSeamFinder : public PairwiseSeamFinder { public: + virtual void find(const std::vector &src, const std::vector &corners, + std::vector &masks); virtual void find(const std::vector &size, const std::vector &corners, std::vector &masks); private: diff --git a/modules/stitching/include/opencv2/stitching/detail/warpers.hpp b/modules/stitching/include/opencv2/stitching/detail/warpers.hpp index 19dff8e1f0..ee8e824cbf 100644 --- a/modules/stitching/include/opencv2/stitching/detail/warpers.hpp +++ b/modules/stitching/include/opencv2/stitching/detail/warpers.hpp @@ -186,14 +186,18 @@ public: */ PlaneWarper(float scale = 1.f) { projector_.scale = scale; } + Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R); Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R, InputArray T); virtual Rect buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, OutputArray xmap, OutputArray ymap); Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap); + Point warp(InputArray src, InputArray K, InputArray R, + int interp_mode, int border_mode, OutputArray dst); virtual Point warp(InputArray src, InputArray K, InputArray R, InputArray T, int interp_mode, int border_mode, OutputArray dst); + Rect warpRoi(Size src_size, InputArray K, InputArray R); Rect warpRoi(Size src_size, InputArray K, InputArray R, InputArray T); protected: diff --git a/modules/stitching/src/seam_finders.cpp b/modules/stitching/src/seam_finders.cpp index 8a673ede0c..fc91135fa6 100644 --- a/modules/stitching/src/seam_finders.cpp +++ b/modules/stitching/src/seam_finders.cpp @@ -82,6 +82,11 @@ void PairwiseSeamFinder::run() } } +void VoronoiSeamFinder::find(const std::vector &src, const std::vector &corners, + std::vector &masks) +{ + PairwiseSeamFinder::find(src, corners, masks); +} void VoronoiSeamFinder::find(const std::vector &sizes, const std::vector &corners, std::vector &masks) diff --git a/modules/stitching/src/warpers.cpp b/modules/stitching/src/warpers.cpp index 4b6185f4e6..141fdec357 100644 --- a/modules/stitching/src/warpers.cpp +++ b/modules/stitching/src/warpers.cpp @@ -87,6 +87,13 @@ Point2f PlaneWarper::warpPoint(const Point2f &pt, InputArray K, InputArray R, In return uv; } +Point2f PlaneWarper::warpPoint(const Point2f &pt, InputArray K, InputArray R) +{ + float tz[] = {0.f, 0.f, 0.f}; + Mat_ T(3, 1, tz); + return warpPoint(pt, K, R, T); +} + Rect PlaneWarper::buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap) { return buildMaps(src_size, K, R, Mat::zeros(3, 1, CV_32FC1), xmap, ymap); @@ -155,6 +162,13 @@ Point PlaneWarper::warp(InputArray src, InputArray K, InputArray R, InputArray T return dst_roi.tl(); } +Point PlaneWarper::warp(InputArray src, InputArray K, InputArray R, + int interp_mode, int border_mode, OutputArray dst) +{ + float tz[] = {0.f, 0.f, 0.f}; + Mat_ T(3, 1, tz); + return warp(src, K, R, T, interp_mode, border_mode, dst); +} Rect PlaneWarper::warpRoi(Size src_size, InputArray K, InputArray R, InputArray T) { @@ -166,6 +180,13 @@ Rect PlaneWarper::warpRoi(Size src_size, InputArray K, InputArray R, InputArray return Rect(dst_tl, Point(dst_br.x + 1, dst_br.y + 1)); } +Rect PlaneWarper::warpRoi(Size src_size, InputArray K, InputArray R) +{ + float tz[] = {0.f, 0.f, 0.f}; + Mat_ T(3, 1, tz); + return warpRoi(src_size, K, R, T); +} + void PlaneWarper::detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br) { diff --git a/modules/superres/src/optical_flow.cpp b/modules/superres/src/optical_flow.cpp index df6725b72b..25a10af3f8 100644 --- a/modules/superres/src/optical_flow.cpp +++ b/modules/superres/src/optical_flow.cpp @@ -224,7 +224,7 @@ namespace void Farneback::impl(InputArray input0, InputArray input1, OutputArray dst) { - calcOpticalFlowFarneback(input0, input1, (InputOutputArray)dst, pyrScale_, + calcOpticalFlowFarneback(input0, input1, InputOutputArray(dst), pyrScale_, numLevels_, winSize_, numIters_, polyN_, polySigma_, flags_); } From 35b21399298175e8e0476c88a7f0a6248bad4f8b Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Thu, 26 Mar 2015 15:25:42 +0300 Subject: [PATCH 031/109] Basic HAL module --- apps/annotation/CMakeLists.txt | 2 +- apps/createsamples/CMakeLists.txt | 2 +- apps/traincascade/CMakeLists.txt | 2 +- cmake/OpenCVModule.cmake | 17 ++ modules/core/include/opencv2/core/base.hpp | 19 +- modules/core/include/opencv2/core/cvdef.h | 233 +------------- modules/core/src/precomp.hpp | 2 + modules/core/src/stat.cpp | 182 +++-------- .../features2d/include/opencv2/features2d.hpp | 32 -- modules/hal/CMakeLists.txt | 12 + modules/hal/include/opencv2/hal.hpp | 74 +++++ modules/hal/include/opencv2/hal/defs.h | 284 ++++++++++++++++++ modules/hal/src/norm.cpp | 184 ++++++++++++ modules/hal/src/precomp.hpp | 2 + modules/java/CMakeLists.txt | 1 + samples/cpp/CMakeLists.txt | 2 +- samples/directx/CMakeLists.txt | 2 +- samples/gpu/CMakeLists.txt | 2 +- samples/tapi/CMakeLists.txt | 2 +- 19 files changed, 641 insertions(+), 415 deletions(-) create mode 100644 modules/hal/CMakeLists.txt create mode 100644 modules/hal/include/opencv2/hal.hpp create mode 100644 modules/hal/include/opencv2/hal/defs.h create mode 100644 modules/hal/src/norm.cpp create mode 100644 modules/hal/src/precomp.hpp diff --git a/apps/annotation/CMakeLists.txt b/apps/annotation/CMakeLists.txt index e14721ac6b..57b133df12 100644 --- a/apps/annotation/CMakeLists.txt +++ b/apps/annotation/CMakeLists.txt @@ -9,7 +9,7 @@ project(annotation) set(the_target opencv_annotation) ocv_target_include_directories(${the_target} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" "${OpenCV_SOURCE_DIR}/include/opencv") -ocv_target_include_modules(${the_target} ${OPENCV_ANNOTATION_DEPS}) +ocv_target_include_modules_recurse(${the_target} ${OPENCV_ANNOTATION_DEPS}) file(GLOB SRCS *.cpp) diff --git a/apps/createsamples/CMakeLists.txt b/apps/createsamples/CMakeLists.txt index 8acd288ac1..24506231e0 100644 --- a/apps/createsamples/CMakeLists.txt +++ b/apps/createsamples/CMakeLists.txt @@ -9,7 +9,7 @@ project(createsamples) set(the_target opencv_createsamples) ocv_target_include_directories(${the_target} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" "${OpenCV_SOURCE_DIR}/include/opencv") -ocv_target_include_modules(${the_target} ${OPENCV_CREATESAMPLES_DEPS}) +ocv_target_include_modules_recurse(${the_target} ${OPENCV_CREATESAMPLES_DEPS}) file(GLOB SRCS *.cpp) file(GLOB HDRS *.h*) diff --git a/apps/traincascade/CMakeLists.txt b/apps/traincascade/CMakeLists.txt index 78101c0bc5..b21fb87367 100644 --- a/apps/traincascade/CMakeLists.txt +++ b/apps/traincascade/CMakeLists.txt @@ -9,7 +9,7 @@ project(traincascade) set(the_target opencv_traincascade) ocv_target_include_directories(${the_target} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" "${OpenCV_SOURCE_DIR}/include/opencv") -ocv_target_include_modules(${the_target} ${OPENCV_TRAINCASCADE_DEPS}) +ocv_target_include_modules_recurse(${the_target} ${OPENCV_TRAINCASCADE_DEPS}) file(GLOB SRCS *.cpp) file(GLOB HDRS *.h*) diff --git a/cmake/OpenCVModule.cmake b/cmake/OpenCVModule.cmake index 955dcc4afd..d1558f4060 100644 --- a/cmake/OpenCVModule.cmake +++ b/cmake/OpenCVModule.cmake @@ -176,6 +176,11 @@ macro(ocv_add_module _name) endif() endif() + # add HAL as dependency + if(NOT "${the_module}" STREQUAL "opencv_hal") + ocv_add_dependencies(${the_module} opencv_hal) + endif() + # add self to the world dependencies if((NOT DEFINED OPENCV_MODULE_IS_PART_OF_WORLD AND NOT OPENCV_MODULE_${the_module}_CLASS STREQUAL "BINDINGS" @@ -517,6 +522,18 @@ macro(ocv_include_modules) endforeach() endmacro() +# same as previous but with dependencies +macro(ocv_include_modules_recurse) + ocv_include_modules(${ARGN}) + foreach(d ${ARGN}) + if(d MATCHES "^opencv_" AND HAVE_${d} AND DEFINED OPENCV_MODULE_${d}_DEPS) + foreach (sub ${OPENCV_MODULE_${d}_DEPS}) + ocv_include_modules(${sub}) + endforeach() + endif() + endforeach() +endmacro() + # setup include paths for the list of passed modules macro(ocv_target_include_modules target) foreach(d ${ARGN}) diff --git a/modules/core/include/opencv2/core/base.hpp b/modules/core/include/opencv2/core/base.hpp index 73beb911fa..08a6642fba 100644 --- a/modules/core/include/opencv2/core/base.hpp +++ b/modules/core/include/opencv2/core/base.hpp @@ -503,8 +503,6 @@ CV_EXPORTS bool Cholesky(float* A, size_t astep, int m, float* b, size_t bstep, CV_EXPORTS bool Cholesky(double* A, size_t astep, int m, double* b, size_t bstep, int n); CV_EXPORTS int normL1_(const uchar* a, const uchar* b, int n); -CV_EXPORTS int normHamming(const uchar* a, const uchar* b, int n); -CV_EXPORTS int normHamming(const uchar* a, const uchar* b, int n, int cellSize); CV_EXPORTS float normL1_(const float* a, const float* b, int n); CV_EXPORTS float normL2Sqr_(const float* a, const float* b, int n); @@ -532,6 +530,23 @@ in degrees and varies from 0 to 360 degrees. The accuracy is about 0.3 degrees. */ CV_EXPORTS_W float fastAtan2(float y, float x); +/* + * Hamming distance functor - counts the bit differences between two strings - useful for the Brief descriptor + * bit count of A exclusive XOR'ed with B + */ +struct CV_EXPORTS Hamming +{ + enum { normType = NORM_HAMMING }; + typedef unsigned char ValueType; + typedef int ResultType; + + /** this will count the bits in a ^ b + */ + ResultType operator()( const unsigned char* a, const unsigned char* b, int size ) const; +}; + +typedef Hamming HammingLUT; + /////////////////////////////////// inline norms //////////////////////////////////// diff --git a/modules/core/include/opencv2/core/cvdef.h b/modules/core/include/opencv2/core/cvdef.h index 3498b0918b..af0a271a41 100644 --- a/modules/core/include/opencv2/core/cvdef.h +++ b/modules/core/include/opencv2/core/cvdef.h @@ -56,23 +56,7 @@ #undef abs #undef Complex -#if defined __ICL -# define CV_ICC __ICL -#elif defined __ICC -# define CV_ICC __ICC -#elif defined __ECL -# define CV_ICC __ECL -#elif defined __ECC -# define CV_ICC __ECC -#elif defined __INTEL_COMPILER -# define CV_ICC __INTEL_COMPILER -#endif - -#if defined CV_ICC && !defined CV_ENABLE_UNROLLED -# define CV_ENABLE_UNROLLED 0 -#else -# define CV_ENABLE_UNROLLED 1 -#endif +#include "opencv2/hal/defs.h" #ifdef __OPENCV_BUILD # define DISABLE_OPENCV_24_COMPATIBILITY @@ -104,216 +88,6 @@ # endif #endif -/* CPU features and intrinsics support */ -#define CV_CPU_NONE 0 -#define CV_CPU_MMX 1 -#define CV_CPU_SSE 2 -#define CV_CPU_SSE2 3 -#define CV_CPU_SSE3 4 -#define CV_CPU_SSSE3 5 -#define CV_CPU_SSE4_1 6 -#define CV_CPU_SSE4_2 7 -#define CV_CPU_POPCNT 8 - -#define CV_CPU_AVX 10 -#define CV_CPU_AVX2 11 -#define CV_CPU_FMA3 12 - -#define CV_CPU_AVX_512F 13 -#define CV_CPU_AVX_512BW 14 -#define CV_CPU_AVX_512CD 15 -#define CV_CPU_AVX_512DQ 16 -#define CV_CPU_AVX_512ER 17 -#define CV_CPU_AVX_512IFMA512 18 -#define CV_CPU_AVX_512PF 19 -#define CV_CPU_AVX_512VBMI 20 -#define CV_CPU_AVX_512VL 21 - -#define CV_CPU_NEON 100 - -// when adding to this list remember to update the enum in core/utility.cpp -#define CV_HARDWARE_MAX_FEATURE 255 - -// do not include SSE/AVX/NEON headers for NVCC compiler -#ifndef __CUDACC__ - -#if defined __SSE2__ || defined _M_X64 || (defined _M_IX86_FP && _M_IX86_FP >= 2) -# include -# define CV_MMX 1 -# define CV_SSE 1 -# define CV_SSE2 1 -# if defined __SSE3__ || (defined _MSC_VER && _MSC_VER >= 1500) -# include -# define CV_SSE3 1 -# endif -# if defined __SSSE3__ || (defined _MSC_VER && _MSC_VER >= 1500) -# include -# define CV_SSSE3 1 -# endif -# if defined __SSE4_1__ || (defined _MSC_VER && _MSC_VER >= 1500) -# include -# define CV_SSE4_1 1 -# endif -# if defined __SSE4_2__ || (defined _MSC_VER && _MSC_VER >= 1500) -# include -# define CV_SSE4_2 1 -# endif -# if defined __POPCNT__ || (defined _MSC_VER && _MSC_VER >= 1500) -# ifdef _MSC_VER -# include -# else -# include -# endif -# define CV_POPCNT 1 -# endif -# if defined __AVX__ || (defined _MSC_VER && _MSC_VER >= 1600 && 0) -// MS Visual Studio 2010 (2012?) has no macro pre-defined to identify the use of /arch:AVX -// See: http://connect.microsoft.com/VisualStudio/feedback/details/605858/arch-avx-should-define-a-predefined-macro-in-x64-and-set-a-unique-value-for-m-ix86-fp-in-win32 -# include -# define CV_AVX 1 -# if defined(_XCR_XFEATURE_ENABLED_MASK) -# define __xgetbv() _xgetbv(_XCR_XFEATURE_ENABLED_MASK) -# else -# define __xgetbv() 0 -# endif -# endif -# if defined __AVX2__ || (defined _MSC_VER && _MSC_VER >= 1800 && 0) -# include -# define CV_AVX2 1 -# if defined __FMA__ -# define CV_FMA3 1 -# endif -# endif -#endif - -#if (defined WIN32 || defined _WIN32) && defined(_M_ARM) -# include -# include "arm_neon.h" -# define CV_NEON 1 -# define CPU_HAS_NEON_FEATURE (true) -#elif defined(__ARM_NEON__) || (defined (__ARM_NEON) && defined(__aarch64__)) -# include -# define CV_NEON 1 -#endif - -#if defined __GNUC__ && defined __arm__ && (defined __ARM_PCS_VFP || defined __ARM_VFPV3__) -# define CV_VFP 1 -#endif - -#endif // __CUDACC__ - -#ifndef CV_POPCNT -#define CV_POPCNT 0 -#endif -#ifndef CV_MMX -# define CV_MMX 0 -#endif -#ifndef CV_SSE -# define CV_SSE 0 -#endif -#ifndef CV_SSE2 -# define CV_SSE2 0 -#endif -#ifndef CV_SSE3 -# define CV_SSE3 0 -#endif -#ifndef CV_SSSE3 -# define CV_SSSE3 0 -#endif -#ifndef CV_SSE4_1 -# define CV_SSE4_1 0 -#endif -#ifndef CV_SSE4_2 -# define CV_SSE4_2 0 -#endif -#ifndef CV_AVX -# define CV_AVX 0 -#endif -#ifndef CV_AVX2 -# define CV_AVX2 0 -#endif -#ifndef CV_FMA3 -# define CV_FMA3 0 -#endif -#ifndef CV_AVX_512F -# define CV_AVX_512F 0 -#endif -#ifndef CV_AVX_512BW -# define CV_AVX_512BW 0 -#endif -#ifndef CV_AVX_512CD -# define CV_AVX_512CD 0 -#endif -#ifndef CV_AVX_512DQ -# define CV_AVX_512DQ 0 -#endif -#ifndef CV_AVX_512ER -# define CV_AVX_512ER 0 -#endif -#ifndef CV_AVX_512IFMA512 -# define CV_AVX_512IFMA512 0 -#endif -#ifndef CV_AVX_512PF -# define CV_AVX_512PF 0 -#endif -#ifndef CV_AVX_512VBMI -# define CV_AVX_512VBMI 0 -#endif -#ifndef CV_AVX_512VL -# define CV_AVX_512VL 0 -#endif - -#ifndef CV_NEON -# define CV_NEON 0 -#endif - -#ifndef CV_VFP -# define CV_VFP 0 -#endif - -/* primitive types */ -/* - schar - signed 1 byte integer - uchar - unsigned 1 byte integer - short - signed 2 byte integer - ushort - unsigned 2 byte integer - int - signed 4 byte integer - uint - unsigned 4 byte integer - int64 - signed 8 byte integer - uint64 - unsigned 8 byte integer -*/ - -#if !defined _MSC_VER && !defined __BORLANDC__ -# if defined __cplusplus && __cplusplus >= 201103L -# include - typedef std::uint32_t uint; -# else -# include - typedef uint32_t uint; -# endif -#else - typedef unsigned uint; -#endif - -typedef signed char schar; - -#ifndef __IPL_H__ - typedef unsigned char uchar; - typedef unsigned short ushort; -#endif - -#if defined _MSC_VER || defined __BORLANDC__ - typedef __int64 int64; - typedef unsigned __int64 uint64; -# define CV_BIG_INT(n) n##I64 -# define CV_BIG_UINT(n) n##UI64 -#else - typedef int64_t int64; - typedef uint64_t uint64; -# define CV_BIG_INT(n) n##LL -# define CV_BIG_UINT(n) n##ULL -#endif - /* special informative macros for wrapper generators */ #define CV_EXPORTS_W CV_EXPORTS #define CV_EXPORTS_W_SIMPLE CV_EXPORTS @@ -326,11 +100,6 @@ typedef signed char schar; #define CV_WRAP #define CV_WRAP_AS(synonym) -/* fundamental constants */ -#define CV_PI 3.1415926535897932384626433832795 -#define CV_2PI 6.283185307179586476925286766559 -#define CV_LOG2 0.69314718055994530941723212145818 - /****************************************************************************************\ * Matrix type (Mat) * \****************************************************************************************/ diff --git a/modules/core/src/precomp.hpp b/modules/core/src/precomp.hpp index fa61203710..e5007e5d17 100644 --- a/modules/core/src/precomp.hpp +++ b/modules/core/src/precomp.hpp @@ -55,6 +55,8 @@ #include "opencv2/core/private.cuda.hpp" #include "opencv2/core/ocl.hpp" +#include "opencv2/hal.hpp" + #include #include #include diff --git a/modules/core/src/stat.cpp b/modules/core/src/stat.cpp index 41218904f8..ca707e78a4 100644 --- a/modules/core/src/stat.cpp +++ b/modules/core/src/stat.cpp @@ -2550,140 +2550,6 @@ int normL1_(const uchar* a, const uchar* b, int n) return d; } -static const uchar popCountTable[] = -{ - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 -}; - -static const uchar popCountTable2[] = -{ - 0, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, - 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, - 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, - 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, - 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, - 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, - 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, - 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4 -}; - -static const uchar popCountTable4[] = -{ - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 -}; - -static int normHamming(const uchar* a, int n) -{ - int i = 0, result = 0; -#if CV_NEON - { - uint32x4_t bits = vmovq_n_u32(0); - for (; i <= n - 16; i += 16) { - uint8x16_t A_vec = vld1q_u8 (a + i); - uint8x16_t bitsSet = vcntq_u8 (A_vec); - uint16x8_t bitSet8 = vpaddlq_u8 (bitsSet); - uint32x4_t bitSet4 = vpaddlq_u16 (bitSet8); - bits = vaddq_u32(bits, bitSet4); - } - uint64x2_t bitSet2 = vpaddlq_u32 (bits); - result = vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),0); - result += vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),2); - } -#endif - for( ; i <= n - 4; i += 4 ) - result += popCountTable[a[i]] + popCountTable[a[i+1]] + - popCountTable[a[i+2]] + popCountTable[a[i+3]]; - for( ; i < n; i++ ) - result += popCountTable[a[i]]; - return result; -} - -int normHamming(const uchar* a, const uchar* b, int n) -{ - int i = 0, result = 0; -#if CV_NEON - { - uint32x4_t bits = vmovq_n_u32(0); - for (; i <= n - 16; i += 16) { - uint8x16_t A_vec = vld1q_u8 (a + i); - uint8x16_t B_vec = vld1q_u8 (b + i); - uint8x16_t AxorB = veorq_u8 (A_vec, B_vec); - uint8x16_t bitsSet = vcntq_u8 (AxorB); - uint16x8_t bitSet8 = vpaddlq_u8 (bitsSet); - uint32x4_t bitSet4 = vpaddlq_u16 (bitSet8); - bits = vaddq_u32(bits, bitSet4); - } - uint64x2_t bitSet2 = vpaddlq_u32 (bits); - result = vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),0); - result += vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),2); - } -#endif - for( ; i <= n - 4; i += 4 ) - result += popCountTable[a[i] ^ b[i]] + popCountTable[a[i+1] ^ b[i+1]] + - popCountTable[a[i+2] ^ b[i+2]] + popCountTable[a[i+3] ^ b[i+3]]; - for( ; i < n; i++ ) - result += popCountTable[a[i] ^ b[i]]; - return result; -} - -static int normHamming(const uchar* a, int n, int cellSize) -{ - if( cellSize == 1 ) - return normHamming(a, n); - const uchar* tab = 0; - if( cellSize == 2 ) - tab = popCountTable2; - else if( cellSize == 4 ) - tab = popCountTable4; - else - CV_Error( CV_StsBadSize, "bad cell size (not 1, 2 or 4) in normHamming" ); - int i = 0, result = 0; -#if CV_ENABLE_UNROLLED - for( ; i <= n - 4; i += 4 ) - result += tab[a[i]] + tab[a[i+1]] + tab[a[i+2]] + tab[a[i+3]]; -#endif - for( ; i < n; i++ ) - result += tab[a[i]]; - return result; -} - -int normHamming(const uchar* a, const uchar* b, int n, int cellSize) -{ - if( cellSize == 1 ) - return normHamming(a, b, n); - const uchar* tab = 0; - if( cellSize == 2 ) - tab = popCountTable2; - else if( cellSize == 4 ) - tab = popCountTable4; - else - CV_Error( CV_StsBadSize, "bad cell size (not 1, 2 or 4) in normHamming" ); - int i = 0, result = 0; - #if CV_ENABLE_UNROLLED - for( ; i <= n - 4; i += 4 ) - result += tab[a[i] ^ b[i]] + tab[a[i+1] ^ b[i+1]] + - tab[a[i+2] ^ b[i+2]] + tab[a[i+3] ^ b[i+3]]; - #endif - for( ; i < n; i++ ) - result += tab[a[i] ^ b[i]]; - return result; -} - - template int normInf_(const T* src, const uchar* mask, ST* _result, int len, int cn) { @@ -2816,6 +2682,12 @@ normDiffL2_(const T* src1, const T* src2, const uchar* mask, ST* _result, int le return 0; } +Hamming::ResultType Hamming::operator()( const unsigned char* a, const unsigned char* b, int size ) const +{ + int result = 0; + cv::hal::normHamming(a, b, size, result); + return result; +} #define CV_DEF_NORM_FUNC(L, suffix, type, ntype) \ static int norm##L##_##suffix(const type* src, const uchar* mask, ntype* r, int len, int cn) \ @@ -3164,10 +3036,18 @@ double cv::norm( InputArray _src, int normType, InputArray _mask ) const uchar* data = src.ptr(); if( normType == NORM_HAMMING ) - return normHamming(data, (int)len); + { + int result = 0; + cv::hal::normHamming(data, (int)len, result); + return result; + } if( normType == NORM_HAMMING2 ) - return normHamming(data, (int)len, 2); + { + int result = 0; + hal::normHamming(data, (int)len, 2, result); + return result; + } } } } @@ -3191,7 +3071,11 @@ double cv::norm( InputArray _src, int normType, InputArray _mask ) int result = 0; for( size_t i = 0; i < it.nplanes; i++, ++it ) - result += normHamming(ptrs[0], total, cellSize); + { + int one = 0; + cv::hal::normHamming(ptrs[0], total, cellSize, one); + result += one; + } return result; } @@ -3673,7 +3557,11 @@ double cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _m int result = 0; for( size_t i = 0; i < it.nplanes; i++, ++it ) - result += normHamming(ptrs[0], ptrs[1], total, cellSize); + { + int one = 0; + hal::normHamming(ptrs[0], ptrs[1], total, cellSize, one); + result += one; + } return result; } @@ -3810,13 +3698,18 @@ static void batchDistHamming(const uchar* src1, const uchar* src2, size_t step2, if( !mask ) { for( int i = 0; i < nvecs; i++ ) - dist[i] = normHamming(src1, src2 + step2*i, len); + hal::normHamming(src1, src2 + step2*i, len, dist[i]); } else { int val0 = INT_MAX; for( int i = 0; i < nvecs; i++ ) - dist[i] = mask[i] ? normHamming(src1, src2 + step2*i, len) : val0; + { + if (mask[i]) + hal::normHamming(src1, src2 + step2*i, len, dist[i]); + else + dist[i] = val0; + } } } @@ -3827,13 +3720,18 @@ static void batchDistHamming2(const uchar* src1, const uchar* src2, size_t step2 if( !mask ) { for( int i = 0; i < nvecs; i++ ) - dist[i] = normHamming(src1, src2 + step2*i, len, 2); + hal::normHamming(src1, src2 + step2*i, len, 2, dist[i]); } else { int val0 = INT_MAX; for( int i = 0; i < nvecs; i++ ) - dist[i] = mask[i] ? normHamming(src1, src2 + step2*i, len, 2) : val0; + { + if (mask[i]) + hal::normHamming(src1, src2 + step2*i, len, 2, dist[i]); + else + dist[i] = val0; + } } } diff --git a/modules/features2d/include/opencv2/features2d.hpp b/modules/features2d/include/opencv2/features2d.hpp index 3d70172284..4d27c4103d 100644 --- a/modules/features2d/include/opencv2/features2d.hpp +++ b/modules/features2d/include/opencv2/features2d.hpp @@ -679,38 +679,6 @@ struct CV_EXPORTS L1 } }; -/* - * Hamming distance functor - counts the bit differences between two strings - useful for the Brief descriptor - * bit count of A exclusive XOR'ed with B - */ -struct CV_EXPORTS Hamming -{ - enum { normType = NORM_HAMMING }; - typedef unsigned char ValueType; - typedef int ResultType; - - /** this will count the bits in a ^ b - */ - ResultType operator()( const unsigned char* a, const unsigned char* b, int size ) const - { - return normHamming(a, b, size); - } -}; - -typedef Hamming HammingLUT; - -template struct HammingMultilevel -{ - enum { normType = NORM_HAMMING + (cellsize>1) }; - typedef unsigned char ValueType; - typedef int ResultType; - - ResultType operator()( const unsigned char* a, const unsigned char* b, int size ) const - { - return normHamming(a, b, size, cellsize); - } -}; - /****************************************************************************************\ * DescriptorMatcher * \****************************************************************************************/ diff --git a/modules/hal/CMakeLists.txt b/modules/hal/CMakeLists.txt new file mode 100644 index 0000000000..b5b2abb81e --- /dev/null +++ b/modules/hal/CMakeLists.txt @@ -0,0 +1,12 @@ +set(the_description "The Hardware Acceleration Layer (HAL) module") + +set(OPENCV_MODULE_TYPE STATIC) +# set(OPENCV_MODULE_IS_PART_OF_WORLD FALSE) + +if(UNIX) + if(CMAKE_COMPILER_IS_GNUCXX OR CV_ICC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") + endif() +endif() + +ocv_define_module(hal) diff --git a/modules/hal/include/opencv2/hal.hpp b/modules/hal/include/opencv2/hal.hpp new file mode 100644 index 0000000000..d0e1350803 --- /dev/null +++ b/modules/hal/include/opencv2/hal.hpp @@ -0,0 +1,74 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Copyright (C) 2015, Itseez Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_HAL_HPP__ +#define __OPENCV_HAL_HPP__ + +#include "opencv2/hal/defs.h" + +/** + @defgroup hal Hardware Acceleration Layer +*/ + +namespace cv { namespace hal { + +namespace Error { + +enum Code +{ + Ok = 0, + Unknown = -1 +}; + +} + +Error::Code normHamming(const uchar* a, int n, int & result); +Error::Code normHamming(const uchar* a, const uchar* b, int n, int & result); + +Error::Code normHamming(const uchar* a, int n, int cellSize, int & result); +Error::Code normHamming(const uchar* a, const uchar* b, int n, int cellSize, int & result); + +}} //cv::hal + +#endif //__OPENCV_HAL_HPP__ diff --git a/modules/hal/include/opencv2/hal/defs.h b/modules/hal/include/opencv2/hal/defs.h new file mode 100644 index 0000000000..96595961f0 --- /dev/null +++ b/modules/hal/include/opencv2/hal/defs.h @@ -0,0 +1,284 @@ +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Copyright (C) 2015, Itseez Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_DEF_H__ +#define __OPENCV_DEF_H__ + +#if !defined _CRT_SECURE_NO_DEPRECATE && defined _MSC_VER && _MSC_VER > 1300 +# define _CRT_SECURE_NO_DEPRECATE /* to avoid multiple Visual Studio warnings */ +#endif + +#if defined __ICL +# define CV_ICC __ICL +#elif defined __ICC +# define CV_ICC __ICC +#elif defined __ECL +# define CV_ICC __ECL +#elif defined __ECC +# define CV_ICC __ECC +#elif defined __INTEL_COMPILER +# define CV_ICC __INTEL_COMPILER +#endif + +#if defined CV_ICC && !defined CV_ENABLE_UNROLLED +# define CV_ENABLE_UNROLLED 0 +#else +# define CV_ENABLE_UNROLLED 1 +#endif + +/* CPU features and intrinsics support */ +#define CV_CPU_NONE 0 +#define CV_CPU_MMX 1 +#define CV_CPU_SSE 2 +#define CV_CPU_SSE2 3 +#define CV_CPU_SSE3 4 +#define CV_CPU_SSSE3 5 +#define CV_CPU_SSE4_1 6 +#define CV_CPU_SSE4_2 7 +#define CV_CPU_POPCNT 8 + +#define CV_CPU_AVX 10 +#define CV_CPU_AVX2 11 +#define CV_CPU_FMA3 12 + +#define CV_CPU_AVX_512F 13 +#define CV_CPU_AVX_512BW 14 +#define CV_CPU_AVX_512CD 15 +#define CV_CPU_AVX_512DQ 16 +#define CV_CPU_AVX_512ER 17 +#define CV_CPU_AVX_512IFMA512 18 +#define CV_CPU_AVX_512PF 19 +#define CV_CPU_AVX_512VBMI 20 +#define CV_CPU_AVX_512VL 21 + +#define CV_CPU_NEON 100 + +// when adding to this list remember to update the enum in core/utility.cpp +#define CV_HARDWARE_MAX_FEATURE 255 + +// do not include SSE/AVX/NEON headers for NVCC compiler +#ifndef __CUDACC__ + +#if defined __SSE2__ || defined _M_X64 || (defined _M_IX86_FP && _M_IX86_FP >= 2) +# include +# define CV_MMX 1 +# define CV_SSE 1 +# define CV_SSE2 1 +# if defined __SSE3__ || (defined _MSC_VER && _MSC_VER >= 1500) +# include +# define CV_SSE3 1 +# endif +# if defined __SSSE3__ || (defined _MSC_VER && _MSC_VER >= 1500) +# include +# define CV_SSSE3 1 +# endif +# if defined __SSE4_1__ || (defined _MSC_VER && _MSC_VER >= 1500) +# include +# define CV_SSE4_1 1 +# endif +# if defined __SSE4_2__ || (defined _MSC_VER && _MSC_VER >= 1500) +# include +# define CV_SSE4_2 1 +# endif +# if defined __POPCNT__ || (defined _MSC_VER && _MSC_VER >= 1500) +# ifdef _MSC_VER +# include +# else +# include +# endif +# define CV_POPCNT 1 +# endif +# if defined __AVX__ || (defined _MSC_VER && _MSC_VER >= 1600 && 0) +// MS Visual Studio 2010 (2012?) has no macro pre-defined to identify the use of /arch:AVX +// See: http://connect.microsoft.com/VisualStudio/feedback/details/605858/arch-avx-should-define-a-predefined-macro-in-x64-and-set-a-unique-value-for-m-ix86-fp-in-win32 +# include +# define CV_AVX 1 +# if defined(_XCR_XFEATURE_ENABLED_MASK) +# define __xgetbv() _xgetbv(_XCR_XFEATURE_ENABLED_MASK) +# else +# define __xgetbv() 0 +# endif +# endif +# if defined __AVX2__ || (defined _MSC_VER && _MSC_VER >= 1800 && 0) +# include +# define CV_AVX2 1 +# if defined __FMA__ +# define CV_FMA3 1 +# endif +# endif +#endif + +#if (defined WIN32 || defined _WIN32) && defined(_M_ARM) +# include +# include "arm_neon.h" +# define CV_NEON 1 +# define CPU_HAS_NEON_FEATURE (true) +#elif defined(__ARM_NEON__) || (defined (__ARM_NEON) && defined(__aarch64__)) +# include +# define CV_NEON 1 +#endif + +#if defined __GNUC__ && defined __arm__ && (defined __ARM_PCS_VFP || defined __ARM_VFPV3__) +# define CV_VFP 1 +#endif + +#endif // __CUDACC__ + +#ifndef CV_POPCNT +#define CV_POPCNT 0 +#endif +#ifndef CV_MMX +# define CV_MMX 0 +#endif +#ifndef CV_SSE +# define CV_SSE 0 +#endif +#ifndef CV_SSE2 +# define CV_SSE2 0 +#endif +#ifndef CV_SSE3 +# define CV_SSE3 0 +#endif +#ifndef CV_SSSE3 +# define CV_SSSE3 0 +#endif +#ifndef CV_SSE4_1 +# define CV_SSE4_1 0 +#endif +#ifndef CV_SSE4_2 +# define CV_SSE4_2 0 +#endif +#ifndef CV_AVX +# define CV_AVX 0 +#endif +#ifndef CV_AVX2 +# define CV_AVX2 0 +#endif +#ifndef CV_FMA3 +# define CV_FMA3 0 +#endif +#ifndef CV_AVX_512F +# define CV_AVX_512F 0 +#endif +#ifndef CV_AVX_512BW +# define CV_AVX_512BW 0 +#endif +#ifndef CV_AVX_512CD +# define CV_AVX_512CD 0 +#endif +#ifndef CV_AVX_512DQ +# define CV_AVX_512DQ 0 +#endif +#ifndef CV_AVX_512ER +# define CV_AVX_512ER 0 +#endif +#ifndef CV_AVX_512IFMA512 +# define CV_AVX_512IFMA512 0 +#endif +#ifndef CV_AVX_512PF +# define CV_AVX_512PF 0 +#endif +#ifndef CV_AVX_512VBMI +# define CV_AVX_512VBMI 0 +#endif +#ifndef CV_AVX_512VL +# define CV_AVX_512VL 0 +#endif + +#ifndef CV_NEON +# define CV_NEON 0 +#endif + +#ifndef CV_VFP +# define CV_VFP 0 +#endif + +/* primitive types */ +/* + schar - signed 1 byte integer + uchar - unsigned 1 byte integer + short - signed 2 byte integer + ushort - unsigned 2 byte integer + int - signed 4 byte integer + uint - unsigned 4 byte integer + int64 - signed 8 byte integer + uint64 - unsigned 8 byte integer +*/ + +#if !defined _MSC_VER && !defined __BORLANDC__ +# if defined __cplusplus && __cplusplus >= 201103L +# include + typedef std::uint32_t uint; +# else +# include + typedef uint32_t uint; +# endif +#else + typedef unsigned uint; +#endif + +typedef signed char schar; + +#ifndef __IPL_H__ + typedef unsigned char uchar; + typedef unsigned short ushort; +#endif + +#if defined _MSC_VER || defined __BORLANDC__ + typedef __int64 int64; + typedef unsigned __int64 uint64; +# define CV_BIG_INT(n) n##I64 +# define CV_BIG_UINT(n) n##UI64 +#else + typedef int64_t int64; + typedef uint64_t uint64; +# define CV_BIG_INT(n) n##LL +# define CV_BIG_UINT(n) n##ULL +#endif + +/* fundamental constants */ +#define CV_PI 3.1415926535897932384626433832795 +#define CV_2PI 6.283185307179586476925286766559 +#define CV_LOG2 0.69314718055994530941723212145818 + +#endif //__OPENCV_HAL_H__ diff --git a/modules/hal/src/norm.cpp b/modules/hal/src/norm.cpp new file mode 100644 index 0000000000..bdcf9ed727 --- /dev/null +++ b/modules/hal/src/norm.cpp @@ -0,0 +1,184 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +namespace cv { namespace hal { + +static const uchar popCountTable[] = +{ + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 +}; + +static const uchar popCountTable2[] = +{ + 0, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, + 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, + 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, + 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, + 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, + 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, + 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, + 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4 +}; + +static const uchar popCountTable4[] = +{ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 +}; + +Error::Code normHamming(const uchar* a, int n, int & result) +{ + int i = 0; + result = 0; +#if CV_NEON + { + uint32x4_t bits = vmovq_n_u32(0); + for (; i <= n - 16; i += 16) { + uint8x16_t A_vec = vld1q_u8 (a + i); + uint8x16_t bitsSet = vcntq_u8 (A_vec); + uint16x8_t bitSet8 = vpaddlq_u8 (bitsSet); + uint32x4_t bitSet4 = vpaddlq_u16 (bitSet8); + bits = vaddq_u32(bits, bitSet4); + } + uint64x2_t bitSet2 = vpaddlq_u32 (bits); + result = vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),0); + result += vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),2); + } +#endif + for( ; i <= n - 4; i += 4 ) + result += popCountTable[a[i]] + popCountTable[a[i+1]] + + popCountTable[a[i+2]] + popCountTable[a[i+3]]; + for( ; i < n; i++ ) + result += popCountTable[a[i]]; + return Error::Ok; +} + +Error::Code normHamming(const uchar* a, const uchar* b, int n, int & result) +{ + int i = 0; + result = 0; +#if CV_NEON + { + uint32x4_t bits = vmovq_n_u32(0); + for (; i <= n - 16; i += 16) { + uint8x16_t A_vec = vld1q_u8 (a + i); + uint8x16_t B_vec = vld1q_u8 (b + i); + uint8x16_t AxorB = veorq_u8 (A_vec, B_vec); + uint8x16_t bitsSet = vcntq_u8 (AxorB); + uint16x8_t bitSet8 = vpaddlq_u8 (bitsSet); + uint32x4_t bitSet4 = vpaddlq_u16 (bitSet8); + bits = vaddq_u32(bits, bitSet4); + } + uint64x2_t bitSet2 = vpaddlq_u32 (bits); + result = vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),0); + result += vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),2); + } +#endif + for( ; i <= n - 4; i += 4 ) + result += popCountTable[a[i] ^ b[i]] + popCountTable[a[i+1] ^ b[i+1]] + + popCountTable[a[i+2] ^ b[i+2]] + popCountTable[a[i+3] ^ b[i+3]]; + for( ; i < n; i++ ) + result += popCountTable[a[i] ^ b[i]]; + return Error::Ok; +} + +Error::Code normHamming(const uchar* a, int n, int cellSize, int & result) +{ + if( cellSize == 1 ) + return normHamming(a, n, result); + const uchar* tab = 0; + if( cellSize == 2 ) + tab = popCountTable2; + else if( cellSize == 4 ) + tab = popCountTable4; + else + return Error::Unknown; + int i = 0; + result = 0; +#if CV_ENABLE_UNROLLED + for( ; i <= n - 4; i += 4 ) + result += tab[a[i]] + tab[a[i+1]] + tab[a[i+2]] + tab[a[i+3]]; +#endif + for( ; i < n; i++ ) + result += tab[a[i]]; + return Error::Ok; +} + +Error::Code normHamming(const uchar* a, const uchar* b, int n, int cellSize, int & result) +{ + if( cellSize == 1 ) + return normHamming(a, b, n, result); + const uchar* tab = 0; + if( cellSize == 2 ) + tab = popCountTable2; + else if( cellSize == 4 ) + tab = popCountTable4; + else + return Error::Unknown; + int i = 0; + result = 0; + #if CV_ENABLE_UNROLLED + for( ; i <= n - 4; i += 4 ) + result += tab[a[i] ^ b[i]] + tab[a[i+1] ^ b[i+1]] + + tab[a[i+2] ^ b[i+2]] + tab[a[i+3] ^ b[i+3]]; + #endif + for( ; i < n; i++ ) + result += tab[a[i] ^ b[i]]; + return Error::Ok; +} + +}} //cv::hal diff --git a/modules/hal/src/precomp.hpp b/modules/hal/src/precomp.hpp new file mode 100644 index 0000000000..04ec378211 --- /dev/null +++ b/modules/hal/src/precomp.hpp @@ -0,0 +1,2 @@ + +#include "opencv2/hal.hpp" diff --git a/modules/java/CMakeLists.txt b/modules/java/CMakeLists.txt index 38f410e64c..3ba9c54dcd 100644 --- a/modules/java/CMakeLists.txt +++ b/modules/java/CMakeLists.txt @@ -10,6 +10,7 @@ endif() set(the_description "The java bindings") ocv_add_module(java BINDINGS opencv_core opencv_imgproc) ocv_module_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/generator/src/cpp") +ocv_module_include_directories("${OpenCV_SOURCE_DIR}/include") if(NOT ANDROID) include_directories(${JNI_INCLUDE_DIRS}) diff --git a/samples/cpp/CMakeLists.txt b/samples/cpp/CMakeLists.txt index 4dfb65d21f..ff5caa9fa8 100644 --- a/samples/cpp/CMakeLists.txt +++ b/samples/cpp/CMakeLists.txt @@ -15,7 +15,7 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) project(cpp_samples) ocv_include_directories("${OpenCV_SOURCE_DIR}/include")#for opencv.hpp - ocv_include_modules(${OPENCV_CPP_SAMPLES_REQUIRED_DEPS}) + ocv_include_modules_recurse(${OPENCV_CPP_SAMPLES_REQUIRED_DEPS}) if(HAVE_opencv_cudaoptflow) ocv_include_directories("${OpenCV_SOURCE_DIR}/modules/cudaoptflow/include") diff --git a/samples/directx/CMakeLists.txt b/samples/directx/CMakeLists.txt index 15a6575374..21ada16ed8 100644 --- a/samples/directx/CMakeLists.txt +++ b/samples/directx/CMakeLists.txt @@ -8,7 +8,7 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) project("${project}_samples") - ocv_include_modules(${OPENCV_DIRECTX_SAMPLES_REQUIRED_DEPS}) + ocv_include_modules_recurse(${OPENCV_DIRECTX_SAMPLES_REQUIRED_DEPS}) # --------------------------------------------- # Define executable targets diff --git a/samples/gpu/CMakeLists.txt b/samples/gpu/CMakeLists.txt index 8741f11701..32c53ecf1f 100644 --- a/samples/gpu/CMakeLists.txt +++ b/samples/gpu/CMakeLists.txt @@ -13,7 +13,7 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) project("${project}_samples") - ocv_include_modules(${OPENCV_CUDA_SAMPLES_REQUIRED_DEPS}) + ocv_include_modules_recurse(${OPENCV_CUDA_SAMPLES_REQUIRED_DEPS}) ocv_include_directories( "${OpenCV_SOURCE_DIR}/modules/gpu/src/nvidia" "${OpenCV_SOURCE_DIR}/modules/gpu/src/nvidia/core" diff --git a/samples/tapi/CMakeLists.txt b/samples/tapi/CMakeLists.txt index 9c69ab0a25..6f8d873efe 100644 --- a/samples/tapi/CMakeLists.txt +++ b/samples/tapi/CMakeLists.txt @@ -8,7 +8,7 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) project("${project}_samples") - ocv_include_modules(${OPENCV_TAPI_SAMPLES_REQUIRED_DEPS}) + ocv_include_modules_recurse(${OPENCV_TAPI_SAMPLES_REQUIRED_DEPS}) # --------------------------------------------- # Define executable targets From 259e41da73b4aebb8a1275aff3aa0e6e00f0090b Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Tue, 7 Apr 2015 19:34:51 +0300 Subject: [PATCH 032/109] reverted "typedef _InputArray InputArray", fixed warning from doxygen --- modules/core/include/opencv2/core.hpp | 4 ++++ modules/core/include/opencv2/core/mat.hpp | 11 +++++------ modules/core/include/opencv2/core/mat.inl.hpp | 10 +++++++--- modules/core/src/matrix.cpp | 2 +- modules/imgproc/src/connectedcomponents.cpp | 14 +++++++------- 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/modules/core/include/opencv2/core.hpp b/modules/core/include/opencv2/core.hpp index 72cb1a46d9..a9b4a30b4f 100644 --- a/modules/core/include/opencv2/core.hpp +++ b/modules/core/include/opencv2/core.hpp @@ -2958,6 +2958,9 @@ public: /** @brief Loads algorithm from the file + @param filename Name of the file to read. + @param objname The optional name of the node to read (if empty, the first top-level node will be used) + This is static template method of Algorithm. It's usage is following (in the case of SVM): @code Ptr svm = Algorithm::load("my_svm_model.xml"); @@ -2977,6 +2980,7 @@ public: /** @brief Loads algorithm from a String @param strModel The string variable containing the model you want to load. + @param objname The optional name of the node to read (if empty, the first top-level node will be used) This is static template method of Algorithm. It's usage is following (in the case of SVM): @code diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp index fa867fde05..315d498c5a 100644 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@ -70,7 +70,7 @@ class CV_EXPORTS _OutputArray; It is defined as: @code - class InputArray; // = _InputArray + typedef const _InputArray& InputArray; @endcode where _InputArray is a class that can be constructed from `Mat`, `Mat_`, `Matx`, `std::vector`, `std::vector >` or `std::vector`. It can also be constructed @@ -186,6 +186,7 @@ public: _InputArray(const std::vector& umv); Mat getMat(int idx=-1) const; + Mat getMat_(int idx=-1) const; UMat getUMat(int idx=-1) const; void getMatVector(std::vector& mv) const; void getUMatVector(std::vector& umv) const; @@ -361,15 +362,13 @@ public: template _InputOutputArray(const Matx<_Tp, m, n>& matx); _InputOutputArray(const UMat& m); _InputOutputArray(const std::vector& vec); - - explicit _InputOutputArray(const _OutputArray& o); }; -typedef _InputArray InputArray; +typedef const _InputArray& InputArray; typedef InputArray InputArrayOfArrays; -typedef _OutputArray OutputArray; +typedef const _OutputArray& OutputArray; typedef OutputArray OutputArrayOfArrays; -typedef _InputOutputArray InputOutputArray; +typedef const _InputOutputArray& InputOutputArray; typedef InputOutputArray InputOutputArrayOfArrays; CV_EXPORTS InputOutputArray noArray(); diff --git a/modules/core/include/opencv2/core/mat.inl.hpp b/modules/core/include/opencv2/core/mat.inl.hpp index 057d903c68..535baa156d 100644 --- a/modules/core/include/opencv2/core/mat.inl.hpp +++ b/modules/core/include/opencv2/core/mat.inl.hpp @@ -114,6 +114,13 @@ inline _InputArray::_InputArray(const cuda::HostMem& cuda_mem) inline _InputArray::~_InputArray() {} +inline Mat _InputArray::getMat(int i) const +{ + if( kind() == MAT && i < 0 ) + return *(const Mat*)obj; + return getMat_(i); +} + inline bool _InputArray::isMat() const { return kind() == _InputArray::MAT; } inline bool _InputArray::isUMat() const { return kind() == _InputArray::UMAT; } inline bool _InputArray::isMatVector() const { return kind() == _InputArray::STD_VECTOR_MAT; } @@ -294,9 +301,6 @@ inline _InputOutputArray::_InputOutputArray(const ogl::Buffer& buf) inline _InputOutputArray::_InputOutputArray(const cuda::HostMem& cuda_mem) { init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_RW, &cuda_mem); } -inline _InputOutputArray::_InputOutputArray(const _OutputArray& o) -{ init(o.getFlags(), o.getObj(), o.getSz()); } - //////////////////////////////////////////// Mat ////////////////////////////////////////// inline diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index c1d2c34852..65b93890ec 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -1113,7 +1113,7 @@ void scalarToRawData(const Scalar& s, void* _buf, int type, int unroll_to) Input/Output Array \*************************************************************************************************/ -Mat _InputArray::getMat(int i) const +Mat _InputArray::getMat_(int i) const { int k = kind(); int accessFlags = flags & ACCESS_MASK; diff --git a/modules/imgproc/src/connectedcomponents.cpp b/modules/imgproc/src/connectedcomponents.cpp index afa3647699..523eb14c09 100644 --- a/modules/imgproc/src/connectedcomponents.cpp +++ b/modules/imgproc/src/connectedcomponents.cpp @@ -65,20 +65,20 @@ namespace cv{ }; struct CCStatsOp{ - OutputArray _mstatsv; + const _OutputArray* _mstatsv; cv::Mat statsv; - OutputArray _mcentroidsv; + const _OutputArray* _mcentroidsv; cv::Mat centroidsv; std::vector integrals; - CCStatsOp(OutputArray _statsv, OutputArray _centroidsv): _mstatsv(_statsv), _mcentroidsv(_centroidsv){ + CCStatsOp(OutputArray _statsv, OutputArray _centroidsv): _mstatsv(&_statsv), _mcentroidsv(&_centroidsv){ } inline void init(int nlabels){ - _mstatsv.create(cv::Size(CC_STAT_MAX, nlabels), cv::DataType::type); - statsv = _mstatsv.getMat(); - _mcentroidsv.create(cv::Size(2, nlabels), cv::DataType::type); - centroidsv = _mcentroidsv.getMat(); + _mstatsv->create(cv::Size(CC_STAT_MAX, nlabels), cv::DataType::type); + statsv = _mstatsv->getMat(); + _mcentroidsv->create(cv::Size(2, nlabels), cv::DataType::type); + centroidsv = _mcentroidsv->getMat(); for(int l = 0; l < (int) nlabels; ++l){ int *row = (int *) &statsv.at(l, 0); From e800800bec8596127274f359e744723a7371b5b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B9=20=D0=9D=D1=83=D0=B6?= =?UTF-8?q?=D0=BD=D1=8B=D0=B9?= Date: Wed, 8 Apr 2015 12:43:38 +0300 Subject: [PATCH 033/109] Squashed commit of the following: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 3646967deb9b48f45c44203e5c96836a8a180218 Author: Сергей Нужный Date: Tue Apr 7 15:48:30 2015 +0300 Fix bug in SVM::trainAuto commit 0c24ccf53897c60dff19193623a97fc4713ce14e Author: Сергей Нужный Date: Tue Apr 7 15:43:59 2015 +0300 Revert "Fix bug in SVM::trainAuto" This reverts commit 225da0226e4e9d54e97aee488ac2b5ed4e813443. commit 225da0226e4e9d54e97aee488ac2b5ed4e813443 Author: Сергей Нужный Date: Tue Apr 7 15:09:47 2015 +0300 Fix bug in SVM::trainAuto --- modules/ml/src/svm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ml/src/svm.cpp b/modules/ml/src/svm.cpp index 449eb8dcd4..95b5fb97d5 100644 --- a/modules/ml/src/svm.cpp +++ b/modules/ml/src/svm.cpp @@ -1787,7 +1787,7 @@ public: if( !do_train( temp_train_samples, temp_train_responses )) continue; - for( i = 0; i < test_sample_count; i++ ) + for( i = 0; i < train_sample_count; i++ ) { j = sidx[(i+start+train_sample_count) % sample_count]; memcpy(temp_train_samples.ptr(i), samples.ptr(j), sample_size); From 4a65f3cee2a657f5e7da7c9ed26ad9576417dc04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B9=20=D0=9D=D1=83=D0=B6?= =?UTF-8?q?=D0=BD=D1=8B=D0=B9?= Date: Wed, 8 Apr 2015 12:51:57 +0300 Subject: [PATCH 034/109] Squashed commit of the following: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 5c379aa1b83ddd66f67b1a9c2ccd00e5bac8576e Merge: e800800 3646967 Author: Сергей Нужный Date: Wed Apr 8 12:44:46 2015 +0300 Merge branch 'master' of https://github.com/Nuzhny007/opencv commit e800800bec8596127274f359e744723a7371b5b7 Author: Сергей Нужный Date: Wed Apr 8 12:43:38 2015 +0300 Squashed commit of the following: commit 3646967deb9b48f45c44203e5c96836a8a180218 Author: Сергей Нужный Date: Tue Apr 7 15:48:30 2015 +0300 Fix bug in SVM::trainAuto commit 0c24ccf53897c60dff19193623a97fc4713ce14e Author: Сергей Нужный Date: Tue Apr 7 15:43:59 2015 +0300 Revert "Fix bug in SVM::trainAuto" This reverts commit 225da0226e4e9d54e97aee488ac2b5ed4e813443. commit 225da0226e4e9d54e97aee488ac2b5ed4e813443 Author: Сергей Нужный Date: Tue Apr 7 15:09:47 2015 +0300 Fix bug in SVM::trainAuto commit 3646967deb9b48f45c44203e5c96836a8a180218 Author: Сергей Нужный Date: Tue Apr 7 15:48:30 2015 +0300 Fix bug in SVM::trainAuto commit 0c24ccf53897c60dff19193623a97fc4713ce14e Author: Сергей Нужный Date: Tue Apr 7 15:43:59 2015 +0300 Revert "Fix bug in SVM::trainAuto" This reverts commit 225da0226e4e9d54e97aee488ac2b5ed4e813443. commit 225da0226e4e9d54e97aee488ac2b5ed4e813443 Author: Сергей Нужный Date: Tue Apr 7 15:09:47 2015 +0300 Fix bug in SVM::trainAuto --- modules/ml/src/svm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ml/src/svm.cpp b/modules/ml/src/svm.cpp index 449eb8dcd4..95b5fb97d5 100644 --- a/modules/ml/src/svm.cpp +++ b/modules/ml/src/svm.cpp @@ -1787,7 +1787,7 @@ public: if( !do_train( temp_train_samples, temp_train_responses )) continue; - for( i = 0; i < test_sample_count; i++ ) + for( i = 0; i < train_sample_count; i++ ) { j = sidx[(i+start+train_sample_count) % sample_count]; memcpy(temp_train_samples.ptr(i), samples.ptr(j), sample_size); From f803c2a7bba0da9fa76b4007a263ef39bce8f080 Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Wed, 8 Apr 2015 14:15:20 +0300 Subject: [PATCH 035/109] Generators: updated the library gathering loop --- cmake/OpenCVUtils.cmake | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cmake/OpenCVUtils.cmake b/cmake/OpenCVUtils.cmake index b9b729e2b1..e7d60beb9b 100644 --- a/cmake/OpenCVUtils.cmake +++ b/cmake/OpenCVUtils.cmake @@ -798,17 +798,17 @@ macro(ocv_get_all_libs _modules _extra _3rdparty) get_target_property(deps ${m} INTERFACE_LINK_LIBRARIES) list(INSERT ${_modules} 0 ${deps} ${m}) foreach (dep ${deps} ${OPENCV_LINKER_LIBS}) - if (TARGET ${dep}) - list(INSERT ${_3rdparty} 0 ${dep}) - else() - list(INSERT ${_extra} 0 ${dep}) + if (NOT DEFINED OPENCV_MODULE_${dep}_LOCATION) + if (TARGET ${dep}) + list(INSERT ${_3rdparty} 0 ${dep}) + else() + list(INSERT ${_extra} 0 ${dep}) + endif() endif() endforeach() endforeach() # split 3rdparty libs and modules - ocv_list_filterout(${_3rdparty} "^opencv_.+$") - ocv_list_filterout(${_extra} "^opencv_.+$") list(REMOVE_ITEM ${_modules} ${${_3rdparty}} ${${_extra}}) # convert CMake lists to makefile literals From e7c02f376f920f1f369dfd298e6331deeca22da4 Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Wed, 8 Apr 2015 19:16:06 +0300 Subject: [PATCH 036/109] Fixed world build with HAL --- modules/world/CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/world/CMakeLists.txt b/modules/world/CMakeLists.txt index ea0df5bc98..8a4170a79b 100644 --- a/modules/world/CMakeLists.txt +++ b/modules/world/CMakeLists.txt @@ -9,6 +9,10 @@ else() set(OPENCV_WORLD_FLAGS_PROPERTY LINK_FLAGS) endif() +function(include_one_module m) + include("${OPENCV_MODULE_${m}_LOCATION}/CMakeLists.txt") +endfunction() + if(NOT OPENCV_INITIAL_PASS) project(opencv_world) @@ -18,7 +22,7 @@ if(NOT OPENCV_INITIAL_PASS) message(STATUS " module ${m}...") set(CMAKE_CURRENT_SOURCE_DIR ${OPENCV_MODULE_${m}_LOCATION}) #add_subdirectory("${OPENCV_MODULE_${m}_LOCATION}" ${CMAKE_CURRENT_BINARY_DIR}/${m}) - include("${OPENCV_MODULE_${m}_LOCATION}/CMakeLists.txt") + include_one_module(${m}) endif() endforeach() message(STATUS "Processing WORLD modules... DONE") From 97c78838a4a2da8a6edd3d46170eea82c9184393 Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Fri, 10 Apr 2015 11:37:16 +0300 Subject: [PATCH 037/109] Fixed windows build and one warning --- cmake/templates/OpenCVConfig.cmake.in | 4 ++++ modules/superres/src/frame_source.cpp | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/cmake/templates/OpenCVConfig.cmake.in b/cmake/templates/OpenCVConfig.cmake.in index ee4a186430..bdc4c56f96 100644 --- a/cmake/templates/OpenCVConfig.cmake.in +++ b/cmake/templates/OpenCVConfig.cmake.in @@ -388,6 +388,10 @@ macro(ocv_include_modules) include_directories(BEFORE "${OpenCV_INCLUDE_DIRS}") endmacro() +macro(ocv_include_modules_recurse) + include_directories(BEFORE "${OpenCV_INCLUDE_DIRS}") +endmacro() + macro(ocv_target_link_libraries) target_link_libraries(${ARGN}) endmacro() diff --git a/modules/superres/src/frame_source.cpp b/modules/superres/src/frame_source.cpp index 216e869c14..f7b9685ab0 100644 --- a/modules/superres/src/frame_source.cpp +++ b/modules/superres/src/frame_source.cpp @@ -126,7 +126,7 @@ namespace else { // should never get here - CV_Assert(0); + CV_Error(Error::StsBadArg, "Failed to detect input frame kind" ); } } From 740ae3581c73417fe3f503b93339a4b45ea55149 Mon Sep 17 00:00:00 2001 From: kalistratovag Date: Mon, 6 Apr 2015 18:19:22 +0300 Subject: [PATCH 038/109] Initial commit of avi mjpeg decoder std::streams removed debug code removed whitespaces removed stdint.h added and trailing whitespaces removed trailing whitespaces removed warnings on windows fix warnings on windows fix pt 2 Refactoring performed: AviMjpegStream class introduced. CAP_PROP_FRAME_WIDTH and CAP_PROP_FRAME_HEIGHT properties support added. Windows warnings & uninitialized variable fix Windows warning fix Win32 warning fix --- modules/videoio/src/cap.cpp | 18 + modules/videoio/src/cap_mjpeg_decoder.cpp | 872 +++++++++++++++++++++- 2 files changed, 888 insertions(+), 2 deletions(-) diff --git a/modules/videoio/src/cap.cpp b/modules/videoio/src/cap.cpp index b5a44da3f7..1fedb0b66d 100644 --- a/modules/videoio/src/cap.cpp +++ b/modules/videoio/src/cap.cpp @@ -552,6 +552,20 @@ static Ptr IVideoCapture_create(int index) } +static Ptr IVideoCapture_create(const String& filename) +{ + Ptr capture; + + capture = createMotionJpegCapture(filename); + if (capture && capture->isOpened()) + { + return capture; + } + + // failed open a camera + return Ptr(); +} + static Ptr IVideoWriter_create(const String& filename, int _fourcc, double fps, Size frameSize, bool isColor) { Ptr iwriter; @@ -582,6 +596,10 @@ VideoCapture::~VideoCapture() bool VideoCapture::open(const String& filename) { if (isOpened()) release(); + icap = IVideoCapture_create(filename); + if (!icap.empty()) + return true; + cap.reset(cvCreateFileCapture(filename.c_str())); return isOpened(); } diff --git a/modules/videoio/src/cap_mjpeg_decoder.cpp b/modules/videoio/src/cap_mjpeg_decoder.cpp index 11a86b2ab3..c6eb8f00d2 100644 --- a/modules/videoio/src/cap_mjpeg_decoder.cpp +++ b/modules/videoio/src/cap_mjpeg_decoder.cpp @@ -40,13 +40,881 @@ //M*/ #include "precomp.hpp" +#include +#include namespace cv { -Ptr createMotionJpegCapture(const String&) +const uint32_t RIFF_CC = CV_FOURCC('R','I','F','F'); +const uint32_t LIST_CC = CV_FOURCC('L','I','S','T'); +const uint32_t HDRL_CC = CV_FOURCC('h','d','r','l'); +const uint32_t AVIH_CC = CV_FOURCC('a','v','i','h'); +const uint32_t STRL_CC = CV_FOURCC('s','t','r','l'); +const uint32_t STRH_CC = CV_FOURCC('s','t','r','h'); +const uint32_t VIDS_CC = CV_FOURCC('v','i','d','s'); +const uint32_t MJPG_CC = CV_FOURCC('M','J','P','G'); +const uint32_t MOVI_CC = CV_FOURCC('m','o','v','i'); +const uint32_t IDX1_CC = CV_FOURCC('i','d','x','1'); +const uint32_t AVI_CC = CV_FOURCC('A','V','I',' '); +const uint32_t AVIX_CC = CV_FOURCC('A','V','I','X'); +const uint32_t JUNK_CC = CV_FOURCC('J','U','N','K'); +const uint32_t INFO_CC = CV_FOURCC('I','N','F','O'); + +String fourccToString(uint32_t fourcc); + +String fourccToString(uint32_t fourcc) { - return Ptr(); + return format("%c%c%c%c", fourcc & 255, (fourcc >> 8) & 255, (fourcc >> 16) & 255, (fourcc >> 24) & 255); +} + +#ifndef DWORD +typedef uint32_t DWORD; +#endif +#ifndef WORD +typedef uint16_t WORD; +#endif +#ifndef LONG +typedef int32_t LONG; +#endif + +#pragma pack(push, 1) +struct AviMainHeader +{ + DWORD dwMicroSecPerFrame; // The period between video frames + DWORD dwMaxBytesPerSec; // Maximum data rate of the file + DWORD dwReserved1; // 0 + DWORD dwFlags; // 0x10 AVIF_HASINDEX: The AVI file has an idx1 chunk containing an index at the end of the file. + DWORD dwTotalFrames; // Field of the main header specifies the total number of frames of data in file. + DWORD dwInitialFrames; // Is used for interleaved files + DWORD dwStreams; // Specifies the number of streams in the file. + DWORD dwSuggestedBufferSize; // Field specifies the suggested buffer size forreading the file + DWORD dwWidth; // Fields specify the width of the AVIfile in pixels. + DWORD dwHeight; // Fields specify the height of the AVIfile in pixels. + DWORD dwReserved[4]; // 0, 0, 0, 0 +}; + +struct AviStreamHeader +{ + uint32_t fccType; // 'vids', 'auds', 'txts'... + uint32_t fccHandler; // "cvid", "DIB " + DWORD dwFlags; // 0 + DWORD dwPriority; // 0 + DWORD dwInitialFrames; // 0 + DWORD dwScale; // 1 + DWORD dwRate; // Fps (dwRate - frame rate for video streams) + DWORD dwStart; // 0 + DWORD dwLength; // Frames number (playing time of AVI file as defined by scale and rate) + DWORD dwSuggestedBufferSize; // For reading the stream + DWORD dwQuality; // -1 (encoding quality. If set to -1, drivers use the default quality value) + DWORD dwSampleSize; // 0 means that each frame is in its own chunk + struct { + short int left; + short int top; + short int right; + short int bottom; + } rcFrame; // If stream has a different size than dwWidth*dwHeight(unused) +}; + +struct AviIndex +{ + DWORD ckid; + DWORD dwFlags; + DWORD dwChunkOffset; + DWORD dwChunkLength; +}; + +struct BitmapInfoHeader +{ + DWORD biSize; // Write header size of BITMAPINFO header structure + LONG biWidth; // width in pixels + LONG biHeight; // heigth in pixels + WORD biPlanes; // Number of color planes in which the data is stored + WORD biBitCount; // Number of bits per pixel + DWORD biCompression; // Type of compression used (uncompressed: NO_COMPRESSION=0) + DWORD biSizeImage; // Image Buffer. Quicktime needs 3 bytes also for 8-bit png + // (biCompression==NO_COMPRESSION)?0:xDim*yDim*bytesPerPixel; + LONG biXPelsPerMeter; // Horizontal resolution in pixels per meter + LONG biYPelsPerMeter; // Vertical resolution in pixels per meter + DWORD biClrUsed; // 256 (color table size; for 8-bit only) + DWORD biClrImportant; // Specifies that the first x colors of the color table. Are important to the DIB. +}; + +struct RiffChunk +{ + uint32_t m_four_cc; + uint32_t m_size; +}; + +struct RiffList +{ + uint32_t m_riff_or_list_cc; + uint32_t m_size; + uint32_t m_list_type_cc; +}; + +#pragma pack(pop) + +class MjpegInputStream +{ +public: + MjpegInputStream(); + MjpegInputStream(const String& filename); + ~MjpegInputStream(); + MjpegInputStream& read(char*, uint64_t); + MjpegInputStream& seekg(uint64_t); + uint64_t tellg(); + bool isOpened() const; + bool open(const String& filename); + void close(); + operator bool(); + +private: + bool m_is_valid; + FILE* m_f; +}; + +MjpegInputStream::MjpegInputStream(): m_is_valid(false), m_f(0) +{ +} + +MjpegInputStream::MjpegInputStream(const String& filename): m_is_valid(false), m_f(0) +{ + open(filename); +} + +bool MjpegInputStream::isOpened() const +{ + return m_f != 0; +} + +bool MjpegInputStream::open(const String& filename) +{ + close(); + + m_f = fopen(filename.c_str(), "rb"); + + m_is_valid = isOpened(); + + return m_is_valid; +} + +void MjpegInputStream::close() +{ + if(isOpened()) + { + m_is_valid = false; + + fclose(m_f); + m_f = 0; + } +} + +MjpegInputStream& MjpegInputStream::read(char* buf, uint64_t count) +{ + if(isOpened()) + { + m_is_valid = (count == fread((void*)buf, 1, (size_t)count, m_f)); + } + + return *this; +} + +MjpegInputStream& MjpegInputStream::seekg(uint64_t pos) +{ + m_is_valid = (fseek(m_f, (long)pos, SEEK_SET) == 0); + + return *this; +} + +uint64_t MjpegInputStream::tellg() +{ + return ftell(m_f); +} + +MjpegInputStream::operator bool() +{ + return m_is_valid; +} + +MjpegInputStream::~MjpegInputStream() +{ + close(); +} + +MjpegInputStream& operator >> (MjpegInputStream& is, AviMainHeader& avih); +MjpegInputStream& operator >> (MjpegInputStream& is, AviStreamHeader& strh); +MjpegInputStream& operator >> (MjpegInputStream& is, BitmapInfoHeader& bmph); +MjpegInputStream& operator >> (MjpegInputStream& is, RiffList& riff_list); +MjpegInputStream& operator >> (MjpegInputStream& is, RiffChunk& riff_chunk); +MjpegInputStream& operator >> (MjpegInputStream& is, AviIndex& idx1); + +MjpegInputStream& operator >> (MjpegInputStream& is, AviMainHeader& avih) +{ + is.read((char*)(&avih), sizeof(AviMainHeader)); + return is; +} + +MjpegInputStream& operator >> (MjpegInputStream& is, AviStreamHeader& strh) +{ + is.read((char*)(&strh), sizeof(AviStreamHeader)); + return is; +} + +MjpegInputStream& operator >> (MjpegInputStream& is, BitmapInfoHeader& bmph) +{ + is.read((char*)(&bmph), sizeof(BitmapInfoHeader)); + return is; +} + +MjpegInputStream& operator >> (MjpegInputStream& is, RiffList& riff_list) +{ + is.read((char*)(&riff_list), sizeof(riff_list)); + return is; +} + +MjpegInputStream& operator >> (MjpegInputStream& is, RiffChunk& riff_chunk) +{ + is.read((char*)(&riff_chunk), sizeof(riff_chunk)); + return is; +} + +MjpegInputStream& operator >> (MjpegInputStream& is, AviIndex& idx1) +{ + is.read((char*)(&idx1), sizeof(idx1)); + return is; +} + +/* +AVI struct: + +RIFF ('AVI ' + LIST ('hdrl' + 'avih'(
) + LIST ('strl' + 'strh'() + 'strf'() + [ 'strd'() ] + [ 'strn'() ] + [ 'indx'() ] + ... + ) + [LIST ('strl' ...)] + [LIST ('strl' ...)] + ... + [LIST ('odml' + 'dmlh'() + ... + ) + ] + ... + ) + [LIST ('INFO' ...)] + [JUNK] + LIST ('movi' + {{xxdb|xxdc|xxpc|xxwb}() | LIST ('rec ' + {xxdb|xxdc|xxpc|xxwb}() + {xxdb|xxdc|xxpc|xxwb}() + ... + ) + ... + } + ... + ) + ['idx1' () ] + ) + + {xxdb|xxdc|xxpc|xxwb} + xx - stream number: 00, 01, 02, ... + db - uncompressed video frame + dc - commpressed video frame + pc - palette change + wb - audio frame + + JUNK section may pad any data section and must be ignored +*/ + +typedef std::deque< std::pair > frame_list; +typedef frame_list::iterator frame_iterator; + +//Represents single MJPEG video stream within single AVI/AVIX entry +//Multiple video streams within single AVI/AVIX entry are not supported +//ODML index is not supported +class AviMjpegStream +{ +public: + AviMjpegStream(); + //stores founded frames in m_frame_list which be accessed via getFrames + bool parseAvi(MjpegInputStream& in_str); + //stores founded frames in in_frame_list. getFrames() would return empty list + bool parseAvi(MjpegInputStream& in_str, frame_list& in_frame_list); + size_t getFramesCount(); + frame_list& getFrames(); + uint32_t getWidth(); + uint32_t getHeight(); + double getFps(); + +protected: + + bool parseAviWithFrameList(MjpegInputStream& in_str, frame_list& in_frame_list); + void skipJunk(RiffChunk& chunk, MjpegInputStream& in_str); + void skipJunk(RiffList& list, MjpegInputStream& in_str); + bool parseHdrlList(MjpegInputStream& in_str); + bool parseIndex(MjpegInputStream& in_str, uint32_t index_size, frame_list& in_frame_list); + bool parseMovi(MjpegInputStream& in_str, frame_list& in_frame_list); + bool parseStrl(MjpegInputStream& in_str, uint8_t stream_id); + bool parseInfo(MjpegInputStream& in_str); + void printError(MjpegInputStream& in_str, RiffList& list, uint32_t expected_fourcc); + void printError(MjpegInputStream& in_str, RiffChunk& chunk, uint32_t expected_fourcc); + + uint32_t m_stream_id; + uint64_t m_movi_start; + uint64_t m_movi_end; + frame_list m_frame_list; + uint32_t m_width; + uint32_t m_height; + double m_fps; + bool m_is_indx_present; +}; + +AviMjpegStream::AviMjpegStream(): m_stream_id(0), m_movi_end(0), m_width(0), m_height(0), m_fps(0), m_is_indx_present(false) +{ +} + +size_t AviMjpegStream::getFramesCount() +{ + return m_frame_list.size(); +} + +frame_list& AviMjpegStream::getFrames() +{ + return m_frame_list; +} + +uint32_t AviMjpegStream::getWidth() +{ + return m_width; +} + +uint32_t AviMjpegStream::getHeight() +{ + return m_height; +} + +double AviMjpegStream::getFps() +{ + return m_fps; +} + +void AviMjpegStream::printError(MjpegInputStream& in_str, RiffList& list, uint32_t expected_fourcc) +{ + if(!in_str) + { + fprintf(stderr, "Unexpected end of file while searching for %s list\n", fourccToString(expected_fourcc).c_str()); + } + else if(list.m_riff_or_list_cc != LIST_CC) + { + fprintf(stderr, "Unexpected element. Expected: %s. Got: %s.\n", fourccToString(LIST_CC).c_str(), fourccToString(list.m_riff_or_list_cc).c_str()); + } + else + { + fprintf(stderr, "Unexpected list type. Expected: %s. Got: %s.\n", fourccToString(expected_fourcc).c_str(), fourccToString(list.m_list_type_cc).c_str()); + } +} + +void AviMjpegStream::printError(MjpegInputStream& in_str, RiffChunk& chunk, uint32_t expected_fourcc) +{ + if(!in_str) + { + fprintf(stderr, "Unexpected end of file while searching for %s chunk\n", fourccToString(expected_fourcc).c_str()); + } + else + { + fprintf(stderr, "Unexpected element. Expected: %s. Got: %s.\n", fourccToString(expected_fourcc).c_str(), fourccToString(chunk.m_four_cc).c_str()); + } +} + + +bool AviMjpegStream::parseMovi(MjpegInputStream&, frame_list&) +{ + //not implemented + return true; +} + +bool AviMjpegStream::parseInfo(MjpegInputStream&) +{ + //not implemented + return true; +} + +bool AviMjpegStream::parseIndex(MjpegInputStream& in_str, uint32_t index_size, frame_list& in_frame_list) +{ + uint64_t index_end = in_str.tellg(); + index_end += index_size; + bool result = false; + + while(in_str && (in_str.tellg() < index_end)) + { + AviIndex idx1; + in_str >> idx1; + + if(idx1.ckid == m_stream_id) + { + uint64_t absolute_pos = m_movi_start + idx1.dwChunkOffset; + + if(absolute_pos < m_movi_end) + { + in_frame_list.push_back(std::make_pair(absolute_pos, idx1.dwChunkLength)); + } + else + { + //unsupported case + fprintf(stderr, "Frame offset points outside movi section.\n"); + } + } + + result = true; + } + + return result; +} + +bool AviMjpegStream::parseStrl(MjpegInputStream& in_str, uint8_t stream_id) +{ + RiffChunk strh; + in_str >> strh; + + if(in_str && strh.m_four_cc == STRH_CC) + { + uint64_t next_strl_list = in_str.tellg(); + next_strl_list += strh.m_size; + + AviStreamHeader strm_hdr; + in_str >> strm_hdr; + + if(strm_hdr.fccType == VIDS_CC && strm_hdr.fccHandler == MJPG_CC) + { + uint8_t first_digit = (stream_id/10) + '0'; + uint8_t second_digit = (stream_id%10) + '0'; + + if(m_stream_id == 0) + { + m_stream_id = CV_FOURCC(first_digit, second_digit, 'd', 'c'); + m_fps = double(strm_hdr.dwRate)/strm_hdr.dwScale; + } + else + { + //second mjpeg video stream found which is not supported + fprintf(stderr, "More than one video stream found within AVI/AVIX list. Stream %c%cdc would be ignored\n", first_digit, second_digit); + } + + return true; + } + } + + return false; +} + +void AviMjpegStream::skipJunk(RiffChunk& chunk, MjpegInputStream& in_str) +{ + if(chunk.m_four_cc == JUNK_CC) + { + in_str.seekg(in_str.tellg() + chunk.m_size); + in_str >> chunk; + } +} + +void AviMjpegStream::skipJunk(RiffList& list, MjpegInputStream& in_str) +{ + if(list.m_riff_or_list_cc == JUNK_CC) + { + //JUNK chunk is 4 bytes less than LIST + in_str.seekg(in_str.tellg() + list.m_size - 4); + in_str >> list; + } +} + +bool AviMjpegStream::parseHdrlList(MjpegInputStream& in_str) +{ + bool result = false; + + RiffChunk avih; + in_str >> avih; + + if(in_str && avih.m_four_cc == AVIH_CC) + { + uint64_t next_strl_list = in_str.tellg(); + next_strl_list += avih.m_size; + + AviMainHeader avi_hdr; + in_str >> avi_hdr; + + if(in_str) + { + m_is_indx_present = ((avi_hdr.dwFlags & 0x10) != 0); + DWORD number_of_streams = avi_hdr.dwStreams; + m_width = avi_hdr.dwWidth; + m_height = avi_hdr.dwWidth; + + //the number of strl lists must be equal to number of streams specified in main avi header + for(DWORD i = 0; i < number_of_streams; ++i) + { + in_str.seekg(next_strl_list); + RiffList strl_list; + in_str >> strl_list; + + if( in_str && strl_list.m_riff_or_list_cc == LIST_CC && strl_list.m_list_type_cc == STRL_CC ) + { + next_strl_list = in_str.tellg(); + //RiffList::m_size includes fourCC field which we have already read + next_strl_list += (strl_list.m_size - 4); + + result = parseStrl(in_str, (uint8_t)i); + } + else + { + printError(in_str, strl_list, STRL_CC); + } + } + } + } + else + { + printError(in_str, avih, AVIH_CC); + } + + return result; +} + +bool AviMjpegStream::parseAviWithFrameList(MjpegInputStream& in_str, frame_list& in_frame_list) +{ + RiffList hdrl_list; + in_str >> hdrl_list; + + if( in_str && hdrl_list.m_riff_or_list_cc == LIST_CC && hdrl_list.m_list_type_cc == HDRL_CC ) + { + uint64_t next_list = in_str.tellg(); + //RiffList::m_size includes fourCC field which we have already read + next_list += (hdrl_list.m_size - 4); + //parseHdrlList sets m_is_indx_present flag which would be used later + if(parseHdrlList(in_str)) + { + in_str.seekg(next_list); + + RiffList some_list; + in_str >> some_list; + + //an optional section INFO + if(in_str && some_list.m_riff_or_list_cc == LIST_CC && some_list.m_list_type_cc == INFO_CC) + { + next_list = in_str.tellg(); + //RiffList::m_size includes fourCC field which we have already read + next_list += (some_list.m_size - 4); + parseInfo(in_str); + + in_str.seekg(next_list); + in_str >> some_list; + } + + //an optional section JUNK + skipJunk(some_list, in_str); + + //we are expecting to find here movi list. Must present in avi + if(in_str && some_list.m_riff_or_list_cc == LIST_CC && some_list.m_list_type_cc == MOVI_CC) + { + bool is_index_found = false; + + m_movi_start = in_str.tellg(); + m_movi_start -= 4; + + m_movi_end = m_movi_start + some_list.m_size; + //if m_is_indx_present is set to true we should find index + if(m_is_indx_present) + { + //we are expecting to find index section after movi list + uint32_t indx_pos = (uint32_t)m_movi_start + 4; + indx_pos += (some_list.m_size - 4); + in_str.seekg(indx_pos); + + RiffChunk index_chunk; + in_str >> index_chunk; + + if(in_str && index_chunk.m_four_cc == IDX1_CC) + { + is_index_found = parseIndex(in_str, index_chunk.m_size, in_frame_list); + //we are not going anywhere else + } + else + { + printError(in_str, index_chunk, IDX1_CC); + } + } + //index not present or we were not able to find it + //parsing movi list + if(!is_index_found) + { + //not implemented + parseMovi(in_str, in_frame_list); + + fprintf(stderr, "Failed to parse avi: index was not found\n"); + //we are not going anywhere else + } + } + else + { + printError(in_str, some_list, MOVI_CC); + } + } + } + else + { + printError(in_str, hdrl_list, HDRL_CC); + } + + return in_frame_list.size() > 0; +} + +bool AviMjpegStream::parseAvi(MjpegInputStream& in_str, frame_list& in_frame_list) +{ + return parseAviWithFrameList(in_str, in_frame_list); +} + +bool AviMjpegStream::parseAvi(MjpegInputStream& in_str) +{ + return parseAviWithFrameList(in_str, m_frame_list); +} + + +class MotionJpegCapture: public IVideoCapture +{ +public: + virtual ~MotionJpegCapture(); + virtual double getProperty(int) const; + virtual bool setProperty(int, double); + virtual bool grabFrame(); + virtual bool retrieveFrame(int, OutputArray); + virtual bool isOpened() const; + virtual int getCaptureDomain() { return CAP_ANY; } // Return the type of the capture object: CAP_VFW, etc... + MotionJpegCapture(const String&); + + bool open(const String&); + void close(); +protected: + + bool parseRiff(MjpegInputStream& in_str); + + inline uint64_t getFramePos() const; + std::vector readFrame(frame_iterator it); + + MjpegInputStream m_file_stream; + bool m_is_first_frame; + frame_list m_mjpeg_frames; + + frame_iterator m_frame_iterator; + Mat m_current_frame; + + //frame width/height and fps could be different for + //each frame/stream. At the moment we suppose that they + //stays the same within single avi file. + uint32_t m_frame_width; + uint32_t m_frame_height; + double m_fps; +}; + +uint64_t MotionJpegCapture::getFramePos() const +{ + if(m_is_first_frame) + return 0; + + if(m_frame_iterator == m_mjpeg_frames.end()) + return m_mjpeg_frames.size(); + + return m_frame_iterator - m_mjpeg_frames.begin() + 1; +} + +bool MotionJpegCapture::setProperty(int property, double value) +{ + if(property == CAP_PROP_POS_FRAMES) + { + if(int(value) == 0) + { + m_is_first_frame = true; + m_frame_iterator = m_mjpeg_frames.end(); + return true; + } + else if(m_mjpeg_frames.size() > value) + { + m_frame_iterator = m_mjpeg_frames.begin() + int(value - 1); + m_is_first_frame = false; + return true; + } + } + + return false; +} + +double MotionJpegCapture::getProperty(int property) const +{ + switch(property) + { + case CAP_PROP_POS_FRAMES: + return (double)getFramePos(); + case CAP_PROP_POS_AVI_RATIO: + return double(getFramePos())/m_mjpeg_frames.size(); + case CAP_PROP_FRAME_WIDTH: + return (double)m_frame_width; + case CAP_PROP_FRAME_HEIGHT: + return (double)m_frame_height; + case CAP_PROP_FPS: + return m_fps; + case CAP_PROP_FOURCC: + return (double)CV_FOURCC('M','J','P','G'); + case CAP_PROP_FRAME_COUNT: + return (double)m_mjpeg_frames.size(); + case CAP_PROP_FORMAT: + return 0; + default: + return 0; + } +} + +std::vector MotionJpegCapture::readFrame(frame_iterator it) +{ + m_file_stream.seekg(it->first); + + RiffChunk chunk; + m_file_stream >> chunk; + + std::vector result; + + result.reserve(chunk.m_size); + result.resize(chunk.m_size); + + m_file_stream.read(result.data(), chunk.m_size); + + return result; +} + +bool MotionJpegCapture::grabFrame() +{ + if(isOpened()) + { + if(m_is_first_frame) + { + m_is_first_frame = false; + m_frame_iterator = m_mjpeg_frames.begin(); + } + else + { + ++m_frame_iterator; + } + } + + return m_frame_iterator != m_mjpeg_frames.end(); +} + +bool MotionJpegCapture::retrieveFrame(int, OutputArray output_frame) +{ + if(m_frame_iterator != m_mjpeg_frames.end()) + { + std::vector data = readFrame(m_frame_iterator); + + if(data.size()) + { + m_current_frame = imdecode(data, CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_COLOR); + } + + m_current_frame.copyTo(output_frame); + + return true; + } + + return false; +} + +MotionJpegCapture::~MotionJpegCapture() +{ + close(); +} + +MotionJpegCapture::MotionJpegCapture(const String& filename) +{ + open(filename); +} + +bool MotionJpegCapture::isOpened() const +{ + return m_mjpeg_frames.size() > 0; +} + +void MotionJpegCapture::close() +{ + m_file_stream.close(); + m_frame_iterator = m_mjpeg_frames.end(); +} + +bool MotionJpegCapture::open(const String& filename) +{ + close(); + + m_file_stream.open(filename); + + m_frame_iterator = m_mjpeg_frames.end(); + m_is_first_frame = true; + + if(!parseRiff(m_file_stream)) + { + close(); + } + + return isOpened(); +} + + +bool MotionJpegCapture::parseRiff(MjpegInputStream& in_str) +{ + bool result = false; + while(in_str) + { + RiffList riff_list; + + in_str >> riff_list; + + if( in_str && riff_list.m_riff_or_list_cc == RIFF_CC && + ((riff_list.m_list_type_cc == AVI_CC) | (riff_list.m_list_type_cc == AVIX_CC)) ) + { + uint64_t next_riff = in_str.tellg(); + //RiffList::m_size includes fourCC field which we have already read + next_riff += (riff_list.m_size - 4); + + AviMjpegStream mjpeg_video_stream; + bool is_parsed = mjpeg_video_stream.parseAvi(in_str, m_mjpeg_frames); + result = result || is_parsed; + + if(is_parsed) + { + m_frame_width = mjpeg_video_stream.getWidth(); + m_frame_height = mjpeg_video_stream.getHeight(); + m_fps = mjpeg_video_stream.getFps(); + } + + in_str.seekg(next_riff); + } + else + { + break; + } + } + + return result; +} + +Ptr createMotionJpegCapture(const String& filename) +{ + Ptr mjdecoder(new MotionJpegCapture(filename)); + if( mjdecoder->isOpened() ) + return mjdecoder; + return Ptr(); } } From 26997f32c6177219e8f35e6930626b5a582d40ae Mon Sep 17 00:00:00 2001 From: cbalint13 Date: Sat, 11 Apr 2015 12:09:13 +0300 Subject: [PATCH 039/109] Fix BRISK detector&descriptor using proper AGAST. --- doc/opencv.bib | 8 + .../features2d/include/opencv2/features2d.hpp | 53 +- modules/features2d/perf/perf_agast.cpp | 40 + modules/features2d/src/agast.cpp | 7667 ++++++++++++++ modules/features2d/src/agast_score.cpp | 9375 +++++++++++++++++ modules/features2d/src/agast_score.hpp | 62 + modules/features2d/src/brisk.cpp | 45 +- modules/features2d/test/test_agast.cpp | 137 + .../test/test_detectors_regression.cpp | 6 + modules/features2d/test/test_keypoints.cpp | 6 + 10 files changed, 17378 insertions(+), 21 deletions(-) create mode 100644 modules/features2d/perf/perf_agast.cpp create mode 100644 modules/features2d/src/agast.cpp create mode 100644 modules/features2d/src/agast_score.cpp create mode 100644 modules/features2d/src/agast_score.hpp create mode 100644 modules/features2d/test/test_agast.cpp diff --git a/doc/opencv.bib b/doc/opencv.bib index be53dbaa56..b2e5002224 100644 --- a/doc/opencv.bib +++ b/doc/opencv.bib @@ -625,6 +625,14 @@ pages = {430--443}, publisher = {Springer} } +@inproceedings{mair2010_agast, + title={Adaptive and Generic Corner Detection Based on the Accelerated Segment Test"}, + author={"Elmar Mair and Gregory D. Hager and Darius Burschka and Michael Suppa and Gerhard Hirzinger"}, + year={"2010"}, + month={"September"}, + booktitle={"European Conference on Computer Vision (ECCV'10)"}, + url={"http://www6.in.tum.de/Main/ResearchAgast" +} @ARTICLE{Rubner2000, author = {Rubner, Yossi and Tomasi, Carlo and Guibas, Leonidas J}, title = {The earth mover's distance as a metric for image retrieval}, diff --git a/modules/features2d/include/opencv2/features2d.hpp b/modules/features2d/include/opencv2/features2d.hpp index 4d27c4103d..cf95e7d343 100644 --- a/modules/features2d/include/opencv2/features2d.hpp +++ b/modules/features2d/include/opencv2/features2d.hpp @@ -222,7 +222,7 @@ class CV_EXPORTS_W BRISK : public Feature2D public: /** @brief The BRISK constructor - @param thresh FAST/AGAST detection threshold score. + @param thresh AGAST detection threshold score. @param octaves detection octaves. Use 0 to do single scale. @param patternScale apply this scale to the pattern used for sampling the neighbourhood of a keypoint. @@ -408,6 +408,57 @@ public: CV_WRAP virtual int getType() const = 0; }; +/** @overload */ +CV_EXPORTS void AGAST( InputArray image, CV_OUT std::vector& keypoints, + int threshold, bool nonmaxSuppression=true ); + +/** @brief Detects corners using the AGAST algorithm + +@param image grayscale image where keypoints (corners) are detected. +@param keypoints keypoints detected on the image. +@param threshold threshold on difference between intensity of the central pixel and pixels of a +circle around this pixel. +@param nonmaxSuppression if true, non-maximum suppression is applied to detected corners +(keypoints). +@param type one of the four neighborhoods as defined in the paper: +AgastFeatureDetector::AGAST_5_8, AgastFeatureDetector::AGAST_7_12d, +AgastFeatureDetector::AGAST_7_12s, AgastFeatureDetector::OAST_9_16 + +Detects corners using the AGAST algorithm by @cite mair2010_agast . + + */ +CV_EXPORTS void AGAST( InputArray image, CV_OUT std::vector& keypoints, + int threshold, bool nonmaxSuppression, int type ); +//! @} features2d_main + +//! @addtogroup features2d_main +//! @{ + +/** @brief Wrapping class for feature detection using the AGAST method. : + */ +class CV_EXPORTS_W AgastFeatureDetector : public Feature2D +{ +public: + enum + { + AGAST_5_8 = 0, AGAST_7_12d = 1, AGAST_7_12s = 2, OAST_9_16 = 3, + THRESHOLD = 10000, NONMAX_SUPPRESSION = 10001, + }; + + CV_WRAP static Ptr create( int threshold=10, + bool nonmaxSuppression=true, + int type=AgastFeatureDetector::OAST_9_16 ); + + CV_WRAP virtual void setThreshold(int threshold) = 0; + CV_WRAP virtual int getThreshold() const = 0; + + CV_WRAP virtual void setNonmaxSuppression(bool f) = 0; + CV_WRAP virtual bool getNonmaxSuppression() const = 0; + + CV_WRAP virtual void setType(int type) = 0; + CV_WRAP virtual int getType() const = 0; +}; + /** @brief Wrapping class for feature detection using the goodFeaturesToTrack function. : */ class CV_EXPORTS_W GFTTDetector : public Feature2D diff --git a/modules/features2d/perf/perf_agast.cpp b/modules/features2d/perf/perf_agast.cpp new file mode 100644 index 0000000000..264f6a226a --- /dev/null +++ b/modules/features2d/perf/perf_agast.cpp @@ -0,0 +1,40 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +CV_ENUM(AgastType, AgastFeatureDetector::AGAST_5_8, AgastFeatureDetector::AGAST_7_12d, + AgastFeatureDetector::AGAST_7_12s, AgastFeatureDetector::OAST_9_16) + +typedef std::tr1::tuple File_Type_t; +typedef perf::TestBaseWithParam agast; + +#define AGAST_IMAGES \ + "cv/detectors_descriptors_evaluation/images_datasets/leuven/img1.png",\ + "stitching/a3.png" + +PERF_TEST_P(agast, detect, testing::Combine( + testing::Values(AGAST_IMAGES), + AgastType::all() + )) +{ + string filename = getDataPath(get<0>(GetParam())); + int type = get<1>(GetParam()); + Mat frame = imread(filename, IMREAD_GRAYSCALE); + + if (frame.empty()) + FAIL() << "Unable to load source image " << filename; + + declare.in(frame); + + Ptr fd = AgastFeatureDetector::create(20, true, type); + ASSERT_FALSE( fd.empty() ); + vector points; + + TEST_CYCLE() fd->detect(frame, points); + + SANITY_CHECK_KEYPOINTS(points); +} diff --git a/modules/features2d/src/agast.cpp b/modules/features2d/src/agast.cpp new file mode 100644 index 0000000000..639ad7dc0c --- /dev/null +++ b/modules/features2d/src/agast.cpp @@ -0,0 +1,7667 @@ +/* This is AGAST and OAST, an optimal and accelerated corner detector + based on the accelerated segment tests + Below is the original copyright and the references */ + +/* +Copyright (C) 2010 Elmar Mair +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + *Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + *Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + *Neither the name of the University of Cambridge nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* +The references are: + * Adaptive and Generic Corner Detection Based on the Accelerated Segment Test, + Elmar Mair and Gregory D. Hager and Darius Burschka + and Michael Suppa and Gerhard Hirzinger ECCV 2010 + URL: http://www6.in.tum.de/Main/ResearchAgast +*/ + +#include "precomp.hpp" +#include "agast_score.hpp" + +#ifdef _WIN32 +#pragma warning( disable : 4127 ) +#endif + +namespace cv +{ + +static void AGAST_5_8(InputArray _img, std::vector& keypoints, int threshold) +{ + + cv::Mat img; + if(!_img.getMat().isContinuous()) + img = _img.getMat().clone(); + else + img = _img.getMat(); + + size_t total = 0; + int xsize = img.cols; + int ysize = img.rows; + size_t nExpectedCorners = keypoints.capacity(); + register int x, y; + register int xsizeB = xsize - 2; + register int ysizeB = ysize - 1; + register int width; + + keypoints.resize(0); + + int pixel_5_8_[16]; + makeAgastOffsets(pixel_5_8_, (int)img.step, AgastFeatureDetector::AGAST_5_8); + + register short offset0 = (short) pixel_5_8_[0]; + register short offset1 = (short) pixel_5_8_[1]; + register short offset2 = (short) pixel_5_8_[2]; + register short offset3 = (short) pixel_5_8_[3]; + register short offset4 = (short) pixel_5_8_[4]; + register short offset5 = (short) pixel_5_8_[5]; + register short offset6 = (short) pixel_5_8_[6]; + register short offset7 = (short) pixel_5_8_[7]; + + width = xsize; + + for(y = 1; y < ysizeB; y++) + { + x = 0; + while(true) + { + homogeneous: + { + x++; + if(x > xsizeB) + break; + else + { + register const unsigned char* const ptr = img.ptr() + y*width + x; + register const int cb = *ptr + threshold; + register const int c_b = *ptr - threshold; + if(ptr[offset0] > cb) + if(ptr[offset2] > cb) + if(ptr[offset3] > cb) + if(ptr[offset5] > cb) + if(ptr[offset1] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + if(ptr[offset7] > cb) + goto success_structured; + else + goto homogeneous; + else + if(ptr[offset4] > cb) + if(ptr[offset6] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset1] > cb) + if(ptr[offset4] > cb) + goto success_homogeneous; + else + if(ptr[offset7] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset7] > cb) + if(ptr[offset6] > cb) + if(ptr[offset5] > cb) + if(ptr[offset1] > cb) + goto success_structured; + else + if(ptr[offset4] > cb) + goto success_structured; + else + goto homogeneous; + else + if(ptr[offset1] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset5] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto success_structured; + else + goto structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset5] > cb) + if(ptr[offset7] > cb) + if(ptr[offset6] > cb) + if(ptr[offset1] > cb) + goto success_homogeneous; + else + if(ptr[offset4] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset5] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto homogeneous; + else + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset7] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else if(ptr[offset0] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset7] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto success_structured; + else + goto structured; + else + goto homogeneous; + else + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset5] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset6] > cb) + goto success_structured; + else + goto structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset7] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + goto success_structured; + else + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto success_structured; + else + goto structured; + else + goto homogeneous; + else + if(ptr[offset1] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + goto success_structured; + else + if(ptr[offset4] < c_b) + goto success_structured; + else + goto homogeneous; + else + if(ptr[offset1] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset3] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto homogeneous; + else + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset5] > cb) + if(ptr[offset3] > cb) + if(ptr[offset2] > cb) + if(ptr[offset1] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + goto homogeneous; + else + if(ptr[offset4] > cb) + if(ptr[offset6] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset7] > cb) + if(ptr[offset4] > cb) + if(ptr[offset6] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset5] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset1] < c_b) + goto success_homogeneous; + else + if(ptr[offset4] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset3] > cb) + if(ptr[offset5] > cb) + if(ptr[offset2] > cb) + if(ptr[offset1] > cb) + if(ptr[offset4] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset4] > cb) + if(ptr[offset6] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset7] > cb) + if(ptr[offset4] > cb) + if(ptr[offset6] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset3] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset7] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + } + } + structured: + { + x++; + if(x > xsizeB) + break; + else + { + register const unsigned char* const ptr = img.ptr() + y*width + x; + register const int cb = *ptr + threshold; + register const int c_b = *ptr - threshold; + if(ptr[offset0] > cb) + if(ptr[offset2] > cb) + if(ptr[offset3] > cb) + if(ptr[offset5] > cb) + if(ptr[offset7] > cb) + if(ptr[offset1] > cb) + goto success_structured; + else + if(ptr[offset4] > cb) + if(ptr[offset6] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset1] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset4] > cb) + if(ptr[offset6] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset7] > cb) + if(ptr[offset1] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset1] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset7] > cb) + if(ptr[offset6] > cb) + if(ptr[offset5] > cb) + if(ptr[offset1] > cb) + goto success_structured; + else + if(ptr[offset4] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset1] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset5] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto structured; + else + if(ptr[offset5] > cb) + if(ptr[offset7] > cb) + if(ptr[offset6] > cb) + if(ptr[offset1] > cb) + goto success_structured; + else + if(ptr[offset4] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset5] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset7] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto structured; + else + goto homogeneous; + else if(ptr[offset0] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset7] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset5] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset6] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto homogeneous; + else + goto structured; + else + if(ptr[offset7] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + goto success_structured; + else + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset1] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + goto success_structured; + else + if(ptr[offset4] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset1] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset3] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset5] > cb) + if(ptr[offset3] > cb) + if(ptr[offset2] > cb) + if(ptr[offset1] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset4] > cb) + if(ptr[offset6] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset7] > cb) + if(ptr[offset4] > cb) + if(ptr[offset6] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto structured; + else + if(ptr[offset5] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset1] < c_b) + goto success_structured; + else + if(ptr[offset4] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto homogeneous; + else + if(ptr[offset3] > cb) + if(ptr[offset5] > cb) + if(ptr[offset2] > cb) + if(ptr[offset1] > cb) + if(ptr[offset4] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset4] > cb) + if(ptr[offset6] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset7] > cb) + if(ptr[offset4] > cb) + if(ptr[offset6] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset3] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset7] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + } + } + success_homogeneous: + if(total == nExpectedCorners) + { + if(nExpectedCorners == 0) + { + nExpectedCorners = 512; + keypoints.reserve(nExpectedCorners); + } + else + { + nExpectedCorners *= 2; + keypoints.reserve(nExpectedCorners); + } + } + keypoints.push_back(KeyPoint(Point2f((float)x, (float)y), 1.0f)); + total++; + goto homogeneous; + success_structured: + if(total == nExpectedCorners) + { + if(nExpectedCorners == 0) + { + nExpectedCorners = 512; + keypoints.reserve(nExpectedCorners); + } + else + { + nExpectedCorners *= 2; + keypoints.reserve(nExpectedCorners); + } + } + keypoints.push_back(KeyPoint(Point2f((float)x, (float)y), 1.0f)); + total++; + goto structured; + } + } +} + +static void AGAST_7_12d(InputArray _img, std::vector& keypoints, int threshold) +{ + cv::Mat img; + if(!_img.getMat().isContinuous()) + img = _img.getMat().clone(); + else + img = _img.getMat(); + + size_t total = 0; + int xsize = img.cols; + int ysize = img.rows; + size_t nExpectedCorners = keypoints.capacity(); + register int x, y; + register int xsizeB = xsize - 4; + register int ysizeB = ysize - 3; + register int width; + + keypoints.resize(0); + + int pixel_7_12d_[16]; + makeAgastOffsets(pixel_7_12d_, (int)img.step, AgastFeatureDetector::AGAST_7_12d); + + register short offset0 = (short) pixel_7_12d_[0]; + register short offset1 = (short) pixel_7_12d_[1]; + register short offset2 = (short) pixel_7_12d_[2]; + register short offset3 = (short) pixel_7_12d_[3]; + register short offset4 = (short) pixel_7_12d_[4]; + register short offset5 = (short) pixel_7_12d_[5]; + register short offset6 = (short) pixel_7_12d_[6]; + register short offset7 = (short) pixel_7_12d_[7]; + register short offset8 = (short) pixel_7_12d_[8]; + register short offset9 = (short) pixel_7_12d_[9]; + register short offset10 = (short) pixel_7_12d_[10]; + register short offset11 = (short) pixel_7_12d_[11]; + + width = xsize; + + for(y = 3; y < ysizeB; y++) + { + x = 2; + while(true) + { + homogeneous: + { + x++; + if(x > xsizeB) + break; + else + { + register const unsigned char* const ptr = img.ptr() + y*width + x; + register const int cb = *ptr + threshold; + register const int c_b = *ptr - threshold; + if(ptr[offset0] > cb) + if(ptr[offset5] > cb) + if(ptr[offset2] > cb) + if(ptr[offset9] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_homogeneous; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + if(ptr[offset4] > cb) + if(ptr[offset7] > cb) + goto success_structured; + else + goto structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_homogeneous; + else + if(ptr[offset10] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto success_structured; + else + if(ptr[offset10] > cb) + goto success_structured; + else + goto homogeneous; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto success_homogeneous; + else + if(ptr[offset11] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset9] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset1] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto success_homogeneous; + else + if(ptr[offset10] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset5] < c_b) + if(ptr[offset9] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset11] > cb) + if(ptr[offset1] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset2] > cb) + goto success_structured; + else + if(ptr[offset7] > cb) + goto success_structured; + else + goto structured; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + goto success_structured; + else + if(ptr[offset8] < c_b) + goto success_structured; + else + goto structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset2] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto success_structured; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset11] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset1] > cb) + if(ptr[offset2] > cb) + goto success_structured; + else + if(ptr[offset7] > cb) + goto success_structured; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset11] > cb) + if(ptr[offset10] > cb) + if(ptr[offset3] > cb) + if(ptr[offset1] > cb) + if(ptr[offset2] > cb) + goto success_homogeneous; + else + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset8] > cb) + if(ptr[offset1] > cb) + if(ptr[offset2] > cb) + goto success_homogeneous; + else + if(ptr[offset7] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset9] < c_b) + if(ptr[offset2] > cb) + if(ptr[offset1] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset3] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto success_structured; + else + if(ptr[offset10] < c_b) + goto success_structured; + else + goto homogeneous; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto success_homogeneous; + else + if(ptr[offset10] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset2] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset2] > cb) + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset2] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset2] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset9] > cb) + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + goto success_homogeneous; + else + if(ptr[offset8] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset9] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset1] > cb) + goto success_homogeneous; + else + if(ptr[offset6] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else if(ptr[offset0] < c_b) + if(ptr[offset2] > cb) + if(ptr[offset5] > cb) + if(ptr[offset7] > cb) + if(ptr[offset6] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + if(ptr[offset1] > cb) + goto success_homogeneous; + else + if(ptr[offset8] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset9] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset9] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset9] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + goto success_structured; + else + if(ptr[offset6] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset9] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto structured; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto success_structured; + else + if(ptr[offset10] < c_b) + goto success_structured; + else + goto homogeneous; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset1] < c_b) + goto success_homogeneous; + else + if(ptr[offset6] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset2] < c_b) + if(ptr[offset9] > cb) + if(ptr[offset5] > cb) + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset11] > cb) + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + goto structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto success_structured; + else + if(ptr[offset10] > cb) + goto success_structured; + else + goto homogeneous; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto success_homogeneous; + else + if(ptr[offset11] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset1] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset9] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto success_homogeneous; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + if(ptr[offset4] < c_b) + if(ptr[offset7] < c_b) + goto success_structured; + else + goto structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto success_homogeneous; + else + if(ptr[offset10] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto success_structured; + else + if(ptr[offset10] < c_b) + goto success_structured; + else + goto homogeneous; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset3] < c_b) + goto success_homogeneous; + else + if(ptr[offset8] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto success_homogeneous; + else + if(ptr[offset11] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset1] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset9] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto success_homogeneous; + else + if(ptr[offset10] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset1] < c_b) + goto success_homogeneous; + else + if(ptr[offset6] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset5] > cb) + if(ptr[offset9] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto success_homogeneous; + else + if(ptr[offset10] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset5] > cb) + if(ptr[offset9] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + if(ptr[offset8] > cb) + goto success_homogeneous; + else + if(ptr[offset1] > cb) + if(ptr[offset2] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset11] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset2] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset7] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset5] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset8] < c_b) + goto success_homogeneous; + else + if(ptr[offset1] < c_b) + if(ptr[offset2] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset11] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset2] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + } + } + structured: + { + x++; + if(x > xsizeB) + break; + else + { + register const unsigned char* const ptr = img.ptr() + y*width + x; + register const int cb = *ptr + threshold; + register const int c_b = *ptr - threshold; + if(ptr[offset0] > cb) + if(ptr[offset5] > cb) + if(ptr[offset2] > cb) + if(ptr[offset9] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + if(ptr[offset4] > cb) + if(ptr[offset7] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto success_structured; + else + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto success_structured; + else + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset9] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset1] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + if(ptr[offset6] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto success_structured; + else + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset5] < c_b) + if(ptr[offset9] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset11] > cb) + if(ptr[offset1] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset2] > cb) + goto success_structured; + else + if(ptr[offset7] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + goto success_structured; + else + if(ptr[offset8] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset2] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset11] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset1] > cb) + if(ptr[offset2] > cb) + goto success_structured; + else + if(ptr[offset7] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset11] > cb) + if(ptr[offset10] > cb) + if(ptr[offset3] > cb) + if(ptr[offset1] > cb) + if(ptr[offset2] > cb) + goto success_structured; + else + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset8] > cb) + if(ptr[offset1] > cb) + if(ptr[offset2] > cb) + goto success_structured; + else + if(ptr[offset7] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset9] < c_b) + if(ptr[offset2] > cb) + if(ptr[offset1] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset3] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto success_structured; + else + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto success_structured; + else + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset2] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset2] > cb) + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset2] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto homogeneous; + else + if(ptr[offset2] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset9] > cb) + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + goto success_structured; + else + if(ptr[offset8] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset9] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset1] > cb) + goto success_structured; + else + if(ptr[offset6] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else if(ptr[offset0] < c_b) + if(ptr[offset2] > cb) + if(ptr[offset5] > cb) + if(ptr[offset7] > cb) + if(ptr[offset6] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + if(ptr[offset1] > cb) + goto success_structured; + else + if(ptr[offset8] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset9] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset9] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset9] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + goto success_structured; + else + if(ptr[offset6] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset9] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto success_structured; + else + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset1] < c_b) + goto success_structured; + else + if(ptr[offset6] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset2] < c_b) + if(ptr[offset9] > cb) + if(ptr[offset5] > cb) + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset11] > cb) + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto success_structured; + else + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto success_structured; + else + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset1] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset9] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + if(ptr[offset4] < c_b) + if(ptr[offset7] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto success_structured; + else + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset3] < c_b) + goto success_structured; + else + if(ptr[offset8] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto success_structured; + else + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset1] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset9] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto success_structured; + else + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset1] < c_b) + goto success_structured; + else + if(ptr[offset6] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset5] > cb) + if(ptr[offset9] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto success_structured; + else + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto homogeneous; + else + goto structured; + else + if(ptr[offset5] > cb) + if(ptr[offset9] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + if(ptr[offset8] > cb) + goto success_structured; + else + if(ptr[offset1] > cb) + if(ptr[offset2] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset11] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset2] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset7] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset5] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset8] < c_b) + goto success_structured; + else + if(ptr[offset1] < c_b) + if(ptr[offset2] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset11] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset2] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto homogeneous; + } + } + success_homogeneous: + if(total == nExpectedCorners) + { + if(nExpectedCorners == 0) + { + nExpectedCorners = 512; + keypoints.reserve(nExpectedCorners); + } + else + { + nExpectedCorners *= 2; + keypoints.reserve(nExpectedCorners); + } + } + keypoints.push_back(KeyPoint(Point2f((float)x, (float)y), 1.0f)); + total++; + goto homogeneous; + success_structured: + if(total == nExpectedCorners) + { + if(nExpectedCorners == 0) + { + nExpectedCorners = 512; + keypoints.reserve(nExpectedCorners); + } + else + { + nExpectedCorners *= 2; + keypoints.reserve(nExpectedCorners); + } + } + keypoints.push_back(KeyPoint(Point2f((float)x, (float)y), 1.0f)); + total++; + goto structured; + } + } +} + +static void AGAST_7_12s(InputArray _img, std::vector& keypoints, int threshold) +{ + cv::Mat img; + if(!_img.getMat().isContinuous()) + img = _img.getMat().clone(); + else + img = _img.getMat(); + + size_t total = 0; + int xsize = img.cols; + int ysize = img.rows; + size_t nExpectedCorners = keypoints.capacity(); + register int x, y; + register int xsizeB=xsize - 3; //2, +1 due to faster test x>xsizeB + register int ysizeB=ysize - 2; + register int width; + + keypoints.resize(0); + + int pixel_7_12s_[16]; + makeAgastOffsets(pixel_7_12s_, (int)img.step, AgastFeatureDetector::AGAST_7_12s); + + register short offset0 = (short) pixel_7_12s_[0]; + register short offset1 = (short) pixel_7_12s_[1]; + register short offset2 = (short) pixel_7_12s_[2]; + register short offset3 = (short) pixel_7_12s_[3]; + register short offset4 = (short) pixel_7_12s_[4]; + register short offset5 = (short) pixel_7_12s_[5]; + register short offset6 = (short) pixel_7_12s_[6]; + register short offset7 = (short) pixel_7_12s_[7]; + register short offset8 = (short) pixel_7_12s_[8]; + register short offset9 = (short) pixel_7_12s_[9]; + register short offset10 = (short) pixel_7_12s_[10]; + register short offset11 = (short) pixel_7_12s_[11]; + + width = xsize; + + for(y = 2; y < ysizeB; y++) + { + x = 1; + while(true) + { + homogeneous: + { + x++; + if(x > xsizeB) + break; + else + { + register const unsigned char* const ptr = img.ptr() + y*width + x; + register const int cb = *ptr + threshold; + register const int c_b = *ptr - threshold; + if(ptr[offset0] > cb) + if(ptr[offset2] > cb) + if(ptr[offset5] > cb) + if(ptr[offset9] > cb) + if(ptr[offset7] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + goto homogeneous; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + if(ptr[offset10] > cb) + goto success_structured; + else + goto homogeneous; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto success_structured; + else + if(ptr[offset10] > cb) + goto success_structured; + else + goto homogeneous; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset1] > cb) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_homogeneous; + else + if(ptr[offset10] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset7] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto success_homogeneous; + else + if(ptr[offset11] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto success_homogeneous; + else + if(ptr[offset11] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset9] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset3] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto success_structured; + else + if(ptr[offset10] < c_b) + goto success_structured; + else + goto homogeneous; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset9] > cb) + if(ptr[offset7] > cb) + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + goto success_homogeneous; + else + if(ptr[offset8] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + goto success_homogeneous; + else + if(ptr[offset8] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset7] > cb) + if(ptr[offset9] > cb) + if(ptr[offset8] > cb) + if(ptr[offset5] > cb) + if(ptr[offset1] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto success_homogeneous; + else + if(ptr[offset10] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset1] > cb) + goto success_homogeneous; + else + if(ptr[offset6] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset7] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset1] < c_b) + goto success_homogeneous; + else + if(ptr[offset8] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset9] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset9] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset9] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto success_homogeneous; + else + if(ptr[offset10] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else if(ptr[offset0] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + goto homogeneous; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + if(ptr[offset10] < c_b) + goto success_structured; + else + goto homogeneous; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto success_structured; + else + if(ptr[offset10] < c_b) + goto success_structured; + else + goto homogeneous; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset1] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto success_homogeneous; + else + if(ptr[offset10] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset3] < c_b) + goto success_homogeneous; + else + if(ptr[offset8] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset1] < c_b) + if(ptr[offset3] < c_b) + goto success_homogeneous; + else + if(ptr[offset8] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset9] > cb) + if(ptr[offset5] > cb) + if(ptr[offset7] > cb) + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset11] > cb) + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + goto structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto success_structured; + else + if(ptr[offset10] > cb) + goto success_structured; + else + goto homogeneous; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset1] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto success_structured; + else + if(ptr[offset11] < c_b) + goto success_structured; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto success_homogeneous; + else + if(ptr[offset11] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset1] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto success_homogeneous; + else + if(ptr[offset11] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto success_homogeneous; + else + if(ptr[offset11] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset1] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset7] > cb) + if(ptr[offset5] > cb) + if(ptr[offset2] > cb) + if(ptr[offset6] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + if(ptr[offset1] > cb) + goto success_homogeneous; + else + if(ptr[offset8] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset9] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset9] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset9] > cb) + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto success_homogeneous; + else + if(ptr[offset10] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset7] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto success_homogeneous; + else + if(ptr[offset10] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset1] < c_b) + goto success_homogeneous; + else + if(ptr[offset6] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset5] > cb) + if(ptr[offset7] > cb) + if(ptr[offset9] > cb) + if(ptr[offset6] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + if(ptr[offset8] > cb) + goto success_homogeneous; + else + if(ptr[offset1] > cb) + if(ptr[offset2] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset11] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset2] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset5] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset8] < c_b) + goto success_homogeneous; + else + if(ptr[offset1] < c_b) + if(ptr[offset2] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset11] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + if(ptr[offset2] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + goto success_homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + else + goto homogeneous; + } + } + structured: + { + x++; + if(x > xsizeB) + break; + else + { + register const unsigned char* const ptr = img.ptr() + y*width + x; + register const int cb = *ptr + threshold; + register const int c_b = *ptr - threshold; + if(ptr[offset0] > cb) + if(ptr[offset2] > cb) + if(ptr[offset5] > cb) + if(ptr[offset9] > cb) + if(ptr[offset7] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto success_structured; + else + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset1] > cb) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset7] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto success_structured; + else + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto success_structured; + else + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset7] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset3] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto success_structured; + else + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset9] > cb) + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + goto success_structured; + else + if(ptr[offset8] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset9] > cb) + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + goto success_structured; + else + if(ptr[offset8] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset7] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset7] > cb) + if(ptr[offset9] > cb) + if(ptr[offset8] > cb) + if(ptr[offset5] > cb) + if(ptr[offset1] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + if(ptr[offset6] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto success_structured; + else + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset1] > cb) + goto success_structured; + else + if(ptr[offset6] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset7] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset1] < c_b) + goto success_structured; + else + if(ptr[offset8] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset9] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset9] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset9] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto success_structured; + else + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else if(ptr[offset0] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset4] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + goto success_structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset1] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset10] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + goto success_structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset1] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset7] > cb) + if(ptr[offset9] > cb) + if(ptr[offset5] > cb) + if(ptr[offset4] > cb) + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset9] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + goto success_structured; + else + if(ptr[offset6] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset1] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset5] > cb) + if(ptr[offset7] > cb) + if(ptr[offset9] > cb) + if(ptr[offset4] > cb) + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset3] > cb) + goto success_structured; + else + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset4] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset1] < c_b) + goto success_structured; + else + if(ptr[offset8] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset9] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset7] > cb) + if(ptr[offset9] > cb) + if(ptr[offset5] > cb) + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset5] > cb) + if(ptr[offset7] > cb) + if(ptr[offset9] > cb) + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + if(ptr[offset11] > cb) + goto success_structured; + else + goto homogeneous; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset7] > cb) + if(ptr[offset5] > cb) + if(ptr[offset2] > cb) + if(ptr[offset6] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + if(ptr[offset1] > cb) + goto success_structured; + else + if(ptr[offset8] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset9] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset9] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset9] > cb) + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto success_structured; + else + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset7] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto success_structured; + else + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset1] < c_b) + goto success_structured; + else + if(ptr[offset6] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset5] > cb) + if(ptr[offset7] > cb) + if(ptr[offset9] > cb) + if(ptr[offset6] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + if(ptr[offset8] > cb) + goto success_structured; + else + if(ptr[offset1] > cb) + if(ptr[offset2] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset11] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset2] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto success_structured; + else + goto structured; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset5] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset8] < c_b) + goto success_structured; + else + if(ptr[offset1] < c_b) + if(ptr[offset2] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset11] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + if(ptr[offset2] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto success_structured; + else + goto structured; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + goto success_structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto structured; + else + goto homogeneous; + } + } + success_homogeneous: + if(total == nExpectedCorners) + { + if(nExpectedCorners == 0) + { + nExpectedCorners = 512; + keypoints.reserve(nExpectedCorners); + } + else + { + nExpectedCorners *= 2; + keypoints.reserve(nExpectedCorners); + } + } + keypoints.push_back(KeyPoint(Point2f((float)x, (float)y), 1.0f)); + total++; + goto homogeneous; + success_structured: + if(total == nExpectedCorners) + { + if(nExpectedCorners == 0) + { + nExpectedCorners = 512; + keypoints.reserve(nExpectedCorners); + } + else + { + nExpectedCorners *= 2; + keypoints.reserve(nExpectedCorners); + } + } + keypoints.push_back(KeyPoint(Point2f((float)x, (float)y), 1.0f)); + total++; + goto structured; + } + } +} + +static void OAST_9_16(InputArray _img, std::vector& keypoints, int threshold) +{ + cv::Mat img; + if(!_img.getMat().isContinuous()) + img = _img.getMat().clone(); + else + img = _img.getMat(); + + size_t total = 0; + int xsize = img.cols; + int ysize = img.rows; + size_t nExpectedCorners = keypoints.capacity(); + register int x, y; + register int xsizeB=xsize - 4; + register int ysizeB=ysize - 3; + register int width; + + keypoints.resize(0); + + int pixel_9_16_[16]; + makeAgastOffsets(pixel_9_16_, (int)img.step, AgastFeatureDetector::OAST_9_16); + + register short offset0 = (short) pixel_9_16_[0]; + register short offset1 = (short) pixel_9_16_[1]; + register short offset2 = (short) pixel_9_16_[2]; + register short offset3 = (short) pixel_9_16_[3]; + register short offset4 = (short) pixel_9_16_[4]; + register short offset5 = (short) pixel_9_16_[5]; + register short offset6 = (short) pixel_9_16_[6]; + register short offset7 = (short) pixel_9_16_[7]; + register short offset8 = (short) pixel_9_16_[8]; + register short offset9 = (short) pixel_9_16_[9]; + register short offset10 = (short) pixel_9_16_[10]; + register short offset11 = (short) pixel_9_16_[11]; + register short offset12 = (short) pixel_9_16_[12]; + register short offset13 = (short) pixel_9_16_[13]; + register short offset14 = (short) pixel_9_16_[14]; + register short offset15 = (short) pixel_9_16_[15]; + + width = xsize; + + for(y = 3; y < ysizeB; y++) + { + x = 2; + while(true) + { + x++; + if(x > xsizeB) + break; + else + { + register const unsigned char* const ptr = img.ptr() + y*width + x; + register const int cb = *ptr + threshold; + register const int c_b = *ptr - threshold; + if(ptr[offset0] > cb) + if(ptr[offset2] > cb) + if(ptr[offset4] > cb) + if(ptr[offset5] > cb) + if(ptr[offset7] > cb) + if(ptr[offset3] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + {} + else + if(ptr[offset15] > cb) + {} + else + continue; + else + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset6] > cb) + {} + else + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset6] > cb) + {} + else + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(ptr[offset1] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset1] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset7] < c_b) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + if(ptr[offset6] > cb) + {} + else + if(ptr[offset13] > cb) + {} + else + continue; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset14] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset6] < c_b) + {} + else + if(ptr[offset15] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + if(ptr[offset6] > cb) + {} + else + if(ptr[offset13] > cb) + {} + else + continue; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset5] < c_b) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + {} + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + {} + else + continue; + else + continue; + else + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset12] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset6] < c_b) + {} + else + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + {} + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + {} + else + continue; + else + continue; + else + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset12] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset6] < c_b) + {} + else + if(ptr[offset15] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset4] < c_b) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset10] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + if(ptr[offset1] > cb) + {} + else + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + {} + else + continue; + else + continue; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset5] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset11] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset3] < c_b) + {} + else + if(ptr[offset12] < c_b) + {} + else + continue; + else + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset10] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + if(ptr[offset1] > cb) + {} + else + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + {} + else + continue; + else + continue; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset5] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset11] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset5] < c_b) + {} + else + if(ptr[offset14] < c_b) + {} + else + continue; + else + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset2] < c_b) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset8] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + {} + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + {} + else + continue; + else + continue; + else + if(ptr[offset5] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(ptr[offset4] > cb) + if(ptr[offset5] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset5] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset1] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset9] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset1] < c_b) + {} + else + if(ptr[offset10] < c_b) + {} + else + continue; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset8] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + {} + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + {} + else + continue; + else + continue; + else + if(ptr[offset5] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(ptr[offset4] > cb) + if(ptr[offset5] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset5] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset1] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset9] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + {} + else + if(ptr[offset12] < c_b) + {} + else + continue; + else + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + {} + else + continue; + else + continue; + else + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset0] < c_b) + if(ptr[offset2] > cb) + if(ptr[offset9] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset6] > cb) + if(ptr[offset5] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + if(ptr[offset1] > cb) + {} + else + if(ptr[offset10] > cb) + {} + else + continue; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + {} + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + {} + else + continue; + else + continue; + else + if(ptr[offset5] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(ptr[offset4] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset1] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset2] < c_b) + if(ptr[offset4] > cb) + if(ptr[offset11] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset6] > cb) + if(ptr[offset5] > cb) + if(ptr[offset3] > cb) + {} + else + if(ptr[offset12] > cb) + {} + else + continue; + else + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + if(ptr[offset1] < c_b) + {} + else + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + {} + else + continue; + else + continue; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset5] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset1] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset4] < c_b) + if(ptr[offset5] > cb) + if(ptr[offset12] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset13] > cb) + if(ptr[offset6] > cb) + {} + else + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset3] < c_b) + {} + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + {} + else + continue; + else + continue; + else + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset5] < c_b) + if(ptr[offset7] > cb) + if(ptr[offset14] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset6] > cb) + {} + else + if(ptr[offset15] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset6] < c_b) + {} + else + if(ptr[offset13] < c_b) + {} + else + continue; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset7] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + {} + else + if(ptr[offset15] < c_b) + {} + else + continue; + else + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset6] < c_b) + {} + else + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset6] < c_b) + {} + else + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(ptr[offset1] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset1] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset6] < c_b) + {} + else + if(ptr[offset13] < c_b) + {} + else + continue; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset12] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset6] > cb) + {} + else + if(ptr[offset15] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset3] < c_b) + {} + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + {} + else + continue; + else + continue; + else + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset11] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset6] > cb) + if(ptr[offset5] > cb) + {} + else + if(ptr[offset14] > cb) + {} + else + continue; + else + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + if(ptr[offset1] < c_b) + {} + else + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + {} + else + continue; + else + continue; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset5] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset1] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset9] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset6] > cb) + if(ptr[offset5] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + {} + else + if(ptr[offset12] > cb) + {} + else + continue; + else + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + {} + else + continue; + else + continue; + else + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + {} + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + {} + else + continue; + else + continue; + else + if(ptr[offset5] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(ptr[offset4] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset1] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset6] > cb) + if(ptr[offset5] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + if(ptr[offset2] > cb) + if(ptr[offset1] > cb) + {} + else + if(ptr[offset10] > cb) + {} + else + continue; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + {} + else + continue; + else + continue; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset1] < c_b) + {} + else + if(ptr[offset10] < c_b) + {} + else + continue; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + {} + else + continue; + else + continue; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + } + if(total == nExpectedCorners) + { + if(nExpectedCorners == 0) + { + nExpectedCorners = 512; + keypoints.reserve(nExpectedCorners); + } + else + { + nExpectedCorners *= 2; + keypoints.reserve(nExpectedCorners); + } + } + keypoints.push_back(KeyPoint(Point2f((float)x, (float)y), 1.0f)); + total++; + } + } +} + + +void AGAST(InputArray _img, std::vector& keypoints, int threshold, bool nonmax_suppression) +{ + AGAST(_img, keypoints, threshold, nonmax_suppression, AgastFeatureDetector::OAST_9_16); +} + + +class AgastFeatureDetector_Impl : public AgastFeatureDetector +{ +public: + AgastFeatureDetector_Impl( int _threshold, bool _nonmaxSuppression, int _type ) + : threshold(_threshold), nonmaxSuppression(_nonmaxSuppression), type((short)_type) + {} + + void detect( InputArray _image, std::vector& keypoints, InputArray _mask ) + { + Mat mask = _mask.getMat(), grayImage; + UMat ugrayImage; + _InputArray gray = _image; + if( _image.type() != CV_8U ) + { + _OutputArray ogray = _image.isUMat() ? _OutputArray(ugrayImage) : _OutputArray(grayImage); + cvtColor( _image, ogray, COLOR_BGR2GRAY ); + gray = ogray; + } + AGAST( gray, keypoints, threshold, nonmaxSuppression, type ); + KeyPointsFilter::runByPixelsMask( keypoints, mask ); + } + + void set(int prop, double value) + { + if(prop == THRESHOLD) + threshold = cvRound(value); + else if(prop == NONMAX_SUPPRESSION) + nonmaxSuppression = value != 0; + else + CV_Error(Error::StsBadArg, ""); + } + + double get(int prop) const + { + if(prop == THRESHOLD) + return threshold; + if(prop == NONMAX_SUPPRESSION) + return nonmaxSuppression; + CV_Error(Error::StsBadArg, ""); + return 0; + } + + void setThreshold(int threshold_) { threshold = threshold_; } + int getThreshold() const { return threshold; } + + void setNonmaxSuppression(bool f) { nonmaxSuppression = f; } + bool getNonmaxSuppression() const { return nonmaxSuppression; } + + void setType(int type_) { type = type_; } + int getType() const { return type; } + + int threshold; + bool nonmaxSuppression; + int type; +}; + +Ptr AgastFeatureDetector::create( int threshold, bool nonmaxSuppression, int type ) +{ + return makePtr(threshold, nonmaxSuppression, type); +} + +void AGAST(InputArray _img, std::vector& keypoints, int threshold, bool nonmax_suppression, int type) +{ + // detect + switch(type) { + case AgastFeatureDetector::AGAST_5_8: + AGAST_5_8(_img, keypoints, threshold); + break; + case AgastFeatureDetector::AGAST_7_12d: + AGAST_7_12d(_img, keypoints, threshold); + break; + case AgastFeatureDetector::AGAST_7_12s: + AGAST_7_12s(_img, keypoints, threshold); + break; + case AgastFeatureDetector::OAST_9_16: + OAST_9_16(_img, keypoints, threshold); + break; + } + + cv::Mat img = _img.getMat(); + + // score + int pixel_[16]; + makeAgastOffsets(pixel_, (int)img.step, type); + + std::vector::iterator kpt; + for(kpt = keypoints.begin(); kpt != keypoints.end(); kpt++) + { + switch(type) { + case AgastFeatureDetector::AGAST_5_8: + kpt->response = (float)agast_cornerScore + (&img.at((int)kpt->pt.y, (int)kpt->pt.x), pixel_, threshold); + break; + case AgastFeatureDetector::AGAST_7_12d: + kpt->response = (float)agast_cornerScore + (&img.at((int)kpt->pt.y, (int)kpt->pt.x), pixel_, threshold); + break; + case AgastFeatureDetector::AGAST_7_12s: + kpt->response = (float)agast_cornerScore + (&img.at((int)kpt->pt.y, (int)kpt->pt.x), pixel_, threshold); + break; + case AgastFeatureDetector::OAST_9_16: + kpt->response = (float)agast_cornerScore + (&img.at((int)kpt->pt.y, (int)kpt->pt.x), pixel_, threshold); + break; + } + } + // suppression + if(nonmax_suppression) + { + size_t j; + size_t curr_idx; + size_t lastRow = 0, next_lastRow = 0; + size_t num_Corners = keypoints.size(); + size_t lastRowCorner_ind = 0, next_lastRowCorner_ind = 0; + + std::vector nmsFlags; + std::vector::iterator nmsFlags_p; + std::vector::iterator currCorner_nms; + std::vector::const_iterator currCorner; + + currCorner = keypoints.begin(); + + nmsFlags.resize((int)num_Corners); + nmsFlags_p = nmsFlags.begin(); + + // set all flags to MAXIMUM + for(j = num_Corners; j > 0; j--) + *nmsFlags_p++ = -1; + nmsFlags_p = nmsFlags.begin(); + + for(curr_idx = 0; curr_idx < num_Corners; curr_idx++) + { + int t; + // check above + if(lastRow + 1 < currCorner->pt.y) + { + lastRow = next_lastRow; + lastRowCorner_ind = next_lastRowCorner_ind; + } + if(next_lastRow != currCorner->pt.y) + { + next_lastRow = (size_t) currCorner->pt.y; + next_lastRowCorner_ind = curr_idx; + } + if(lastRow + 1 == currCorner->pt.y) + { + // find the corner above the current one + while( (keypoints[lastRowCorner_ind].pt.x < currCorner->pt.x) + && (keypoints[lastRowCorner_ind].pt.y == lastRow) ) + lastRowCorner_ind++; + + if( (keypoints[lastRowCorner_ind].pt.x == currCorner->pt.x) + && (lastRowCorner_ind != curr_idx) ) + { + size_t w = lastRowCorner_ind; + // find the maximum in this block + while(nmsFlags[w] != -1) + w = nmsFlags[w]; + + if(keypoints[curr_idx].response < keypoints[w].response) + nmsFlags[curr_idx] = (int)w; + else + nmsFlags[w] = (int)curr_idx; + } + } + + // check left + t = (int)curr_idx - 1; + if( (curr_idx != 0) && (keypoints[t].pt.y == currCorner->pt.y) + && (keypoints[t].pt.x + 1 == currCorner->pt.x) ) + { + int currCornerMaxAbove_ind = nmsFlags[curr_idx]; + // find the maximum in that area + while(nmsFlags[t] != -1) + t = nmsFlags[t]; + // no maximum above + if(currCornerMaxAbove_ind == -1) + { + if((size_t)t != curr_idx) + { + if ( keypoints[curr_idx].response < keypoints[t].response ) + nmsFlags[curr_idx] = t; + else + nmsFlags[t] = (int)curr_idx; + } + } + else // maximum above + { + if(t != currCornerMaxAbove_ind) + { + if(keypoints[currCornerMaxAbove_ind].response < keypoints[t].response) + { + nmsFlags[currCornerMaxAbove_ind] = t; + nmsFlags[curr_idx] = t; + } + else + { + nmsFlags[t] = currCornerMaxAbove_ind; + nmsFlags[curr_idx] = currCornerMaxAbove_ind; + } + } + } + } + currCorner++; + } + + // removing non-maximum corners + for(curr_idx = 0; curr_idx < num_Corners; curr_idx++) + { + if(*nmsFlags_p++ != -1) + keypoints.erase(keypoints.begin() + curr_idx); + } + } +} + +} // END NAMESPACE CV diff --git a/modules/features2d/src/agast_score.cpp b/modules/features2d/src/agast_score.cpp new file mode 100644 index 0000000000..6b4c869c38 --- /dev/null +++ b/modules/features2d/src/agast_score.cpp @@ -0,0 +1,9375 @@ +/* This is AGAST and OAST, an optimal and accelerated corner detector + based on the accelerated segment tests + Below is the original copyright and the references */ + +/* +Copyright (C) 2010 Elmar Mair +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + *Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + *Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + *Neither the name of the University of Cambridge nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* +The references are: + * Adaptive and Generic Corner Detection Based on the Accelerated Segment Test, + Elmar Mair and Gregory D. Hager and Darius Burschka + and Michael Suppa and Gerhard Hirzinger ECCV 2010 + URL: http://www6.in.tum.de/Main/ResearchAgast +*/ + +#include "agast_score.hpp" + +#ifdef _WIN32 +#pragma warning( disable : 4127 ) +#endif + +namespace cv +{ + +void makeAgastOffsets(int pixel[16], int rowStride, int type) +{ + static const int offsets16[][2] = + { + {-3, 0}, {-3, -1}, {-2, -2}, {-1, -3}, {0, -3}, { 1, -3}, { 2, -2}, { 3, -1}, + { 3, 0}, { 3, 1}, { 2, 2}, { 1, 3}, {0, 3}, {-1, 3}, {-2, 2}, {-3, 1} + }; + + static const int offsets12d[][2] = + { + {-3, 0}, {-2, -1}, {-1, -2}, {0, -3}, { 1, -2}, { 2, -1}, + { 3, 0}, { 2, 1}, { 1, 2}, {0, 3}, {-1, 2}, {-2, 1} + }; + + static const int offsets12s[][2] = + { + {-2, 0}, {-2, -1}, {-1, -2}, {0, -2}, { 1, -2}, { 2, -1}, + { 2, 0}, { 2, 1}, { 1, 2}, {0, 2}, {-1, 2}, {-2, 1} + }; + + static const int offsets8[][2] = + { + {-1, 0}, {-1, -1}, {0, -1}, { 1, -1}, + { 1, 0}, { 1, 1}, {0, 1}, {-1, 1} + }; + + const int (*offsets)[2] = type == AgastFeatureDetector::OAST_9_16 ? offsets16 : + type == AgastFeatureDetector::AGAST_7_12d ? offsets12d : + type == AgastFeatureDetector::AGAST_7_12s ? offsets12s : + type == AgastFeatureDetector::AGAST_5_8 ? offsets8 : 0; + + CV_Assert(pixel && offsets); + + int k = 0; + for( ; k < 16; k++ ) + pixel[k] = offsets[k][0] + offsets[k][1] * rowStride; +} + +// 16 pixel mask +template<> +int agast_cornerScore(const uchar* ptr, const int pixel[], int threshold) +{ + int bmin = threshold; + int bmax = 255; + int b_test = (bmax + bmin) / 2; + + register short offset0 = (short) pixel[0]; + register short offset1 = (short) pixel[1]; + register short offset2 = (short) pixel[2]; + register short offset3 = (short) pixel[3]; + register short offset4 = (short) pixel[4]; + register short offset5 = (short) pixel[5]; + register short offset6 = (short) pixel[6]; + register short offset7 = (short) pixel[7]; + register short offset8 = (short) pixel[8]; + register short offset9 = (short) pixel[9]; + register short offset10 = (short) pixel[10]; + register short offset11 = (short) pixel[11]; + register short offset12 = (short) pixel[12]; + register short offset13 = (short) pixel[13]; + register short offset14 = (short) pixel[14]; + register short offset15 = (short) pixel[15]; + + while(true) + { + register const int cb = *pixel + b_test; + register const int c_b = *pixel - b_test; + if(ptr[offset0] > cb) + if(ptr[offset2] > cb) + if(ptr[offset4] > cb) + if(ptr[offset5] > cb) + if(ptr[offset7] > cb) + if(ptr[offset3] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + goto is_a_corner; + else + if(ptr[offset15] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset6] > cb) + goto is_a_corner; + else + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset6] > cb) + goto is_a_corner; + else + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset7] < c_b) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + if(ptr[offset6] > cb) + goto is_a_corner; + else + if(ptr[offset13] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset14] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset6] < c_b) + goto is_a_corner; + else + if(ptr[offset15] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + if(ptr[offset6] > cb) + goto is_a_corner; + else + if(ptr[offset13] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset5] < c_b) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset12] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset6] < c_b) + goto is_a_corner; + else + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset12] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset6] < c_b) + goto is_a_corner; + else + if(ptr[offset15] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset4] < c_b) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset10] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + if(ptr[offset1] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset11] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset12] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset10] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + if(ptr[offset1] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset11] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset5] < c_b) + goto is_a_corner; + else + if(ptr[offset14] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset2] < c_b) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset8] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + goto is_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset4] > cb) + if(ptr[offset5] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset5] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset9] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset1] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset8] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + goto is_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset4] > cb) + if(ptr[offset5] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset5] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset9] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset12] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset0] < c_b) + if(ptr[offset2] > cb) + if(ptr[offset9] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset6] > cb) + if(ptr[offset5] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + if(ptr[offset1] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + goto is_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset4] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset2] < c_b) + if(ptr[offset4] > cb) + if(ptr[offset11] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset6] > cb) + if(ptr[offset5] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset12] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + if(ptr[offset1] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset4] < c_b) + if(ptr[offset5] > cb) + if(ptr[offset12] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset13] > cb) + if(ptr[offset6] > cb) + goto is_a_corner; + else + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset5] < c_b) + if(ptr[offset7] > cb) + if(ptr[offset14] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset6] > cb) + goto is_a_corner; + else + if(ptr[offset15] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset6] < c_b) + goto is_a_corner; + else + if(ptr[offset13] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset7] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + goto is_a_corner; + else + if(ptr[offset15] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset6] < c_b) + goto is_a_corner; + else + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset6] < c_b) + goto is_a_corner; + else + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset6] < c_b) + goto is_a_corner; + else + if(ptr[offset13] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset12] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset6] > cb) + goto is_a_corner; + else + if(ptr[offset15] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset11] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset10] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset6] > cb) + if(ptr[offset5] > cb) + goto is_a_corner; + else + if(ptr[offset14] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + if(ptr[offset1] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset6] > cb) + if(ptr[offset5] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset12] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset9] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + goto is_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset4] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset9] > cb) + if(ptr[offset6] > cb) + if(ptr[offset5] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + if(ptr[offset2] > cb) + if(ptr[offset1] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset12] > cb) + if(ptr[offset13] > cb) + if(ptr[offset14] > cb) + if(ptr[offset15] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset1] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset12] < c_b) + if(ptr[offset13] < c_b) + if(ptr[offset14] < c_b) + if(ptr[offset15] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + + is_a_corner: + bmin = b_test; + goto end; + + is_not_a_corner: + bmax = b_test; + goto end; + + end: + + if(bmin == bmax - 1 || bmin == bmax) + return bmin; + b_test = (bmin + bmax) / 2; + } +} + +// 12 pixel mask in diamond format +template<> +int agast_cornerScore(const uchar* ptr, const int pixel[], int threshold) +{ + int bmin = threshold; + int bmax = 255; + int b_test = (bmax + bmin)/2; + + register short offset0 = (short) pixel[0]; + register short offset1 = (short) pixel[1]; + register short offset2 = (short) pixel[2]; + register short offset3 = (short) pixel[3]; + register short offset4 = (short) pixel[4]; + register short offset5 = (short) pixel[5]; + register short offset6 = (short) pixel[6]; + register short offset7 = (short) pixel[7]; + register short offset8 = (short) pixel[8]; + register short offset9 = (short) pixel[9]; + register short offset10 = (short) pixel[10]; + register short offset11 = (short) pixel[11]; + + while(true) + { + register const int cb = *pixel + b_test; + register const int c_b = *pixel - b_test; + if(ptr[offset0] > cb) + if(ptr[offset5] > cb) + if(ptr[offset2] > cb) + if(ptr[offset9] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + if(ptr[offset4] > cb) + if(ptr[offset7] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_a_corner; + else + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset1] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] < c_b) + if(ptr[offset9] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset11] > cb) + if(ptr[offset1] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset2] > cb) + goto is_a_corner; + else + if(ptr[offset7] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset11] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset1] > cb) + if(ptr[offset2] > cb) + goto is_a_corner; + else + if(ptr[offset7] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset11] > cb) + if(ptr[offset10] > cb) + if(ptr[offset3] > cb) + if(ptr[offset1] > cb) + if(ptr[offset2] > cb) + goto is_a_corner; + else + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset1] > cb) + if(ptr[offset2] > cb) + goto is_a_corner; + else + if(ptr[offset7] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] < c_b) + if(ptr[offset2] > cb) + if(ptr[offset1] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset3] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] > cb) + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset9] > cb) + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset1] > cb) + goto is_a_corner; + else + if(ptr[offset6] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset0] < c_b) + if(ptr[offset2] > cb) + if(ptr[offset5] > cb) + if(ptr[offset7] > cb) + if(ptr[offset6] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + if(ptr[offset1] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + goto is_a_corner; + else + if(ptr[offset6] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset1] < c_b) + goto is_a_corner; + else + if(ptr[offset6] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] < c_b) + if(ptr[offset9] > cb) + if(ptr[offset5] > cb) + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset11] > cb) + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_a_corner; + else + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + if(ptr[offset4] < c_b) + if(ptr[offset7] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_a_corner; + else + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset1] < c_b) + goto is_a_corner; + else + if(ptr[offset6] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] > cb) + if(ptr[offset9] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] > cb) + if(ptr[offset9] > cb) + if(ptr[offset6] > cb) + if(ptr[offset7] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + if(ptr[offset8] > cb) + goto is_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset2] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset11] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset7] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset8] < c_b) + goto is_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset2] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset11] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + + is_a_corner: + bmin = b_test; + goto end; + + is_not_a_corner: + bmax = b_test; + goto end; + + end: + + if(bmin == bmax - 1 || bmin == bmax) + return bmin; + b_test = (bmin + bmax) / 2; + } +} + +//12 pixel mask in square format +template<> +int agast_cornerScore(const uchar* ptr, const int pixel[], int threshold) +{ + int bmin = threshold; + int bmax = 255; + int b_test = (bmax + bmin)/2; + + register short offset0 = (short) pixel[0]; + register short offset1 = (short) pixel[1]; + register short offset2 = (short) pixel[2]; + register short offset3 = (short) pixel[3]; + register short offset4 = (short) pixel[4]; + register short offset5 = (short) pixel[5]; + register short offset6 = (short) pixel[6]; + register short offset7 = (short) pixel[7]; + register short offset8 = (short) pixel[8]; + register short offset9 = (short) pixel[9]; + register short offset10 = (short) pixel[10]; + register short offset11 = (short) pixel[11]; + + while(true) + { + register const int cb = *pixel + b_test; + register const int c_b = *pixel - b_test; + if(ptr[offset0] > cb) + if(ptr[offset5] > cb) + if(ptr[offset2] < c_b) + if(ptr[offset7] > cb) + if(ptr[offset9] < c_b) + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] < c_b) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] > cb) + if(ptr[offset7] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset1] < c_b) + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset1] < c_b) + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] < c_b) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] < c_b) + if(ptr[offset7] > cb) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] > cb) + if(ptr[offset9] > cb) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] < c_b) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset1] < c_b) + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] < c_b) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] > cb) + if(ptr[offset9] < c_b) + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] < c_b) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset7] > cb) + if(ptr[offset2] < c_b) + goto is_not_a_corner; + else + if(ptr[offset2] > cb) + if(ptr[offset1] < c_b) + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] > cb) + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset3] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] < c_b) + goto is_not_a_corner; + else + if(ptr[offset2] > cb) + if(ptr[offset1] < c_b) + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset7] < c_b) + if(ptr[offset2] > cb) + if(ptr[offset1] < c_b) + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] > cb) + if(ptr[offset2] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] > cb) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] < c_b) + goto is_not_a_corner; + else + if(ptr[offset2] > cb) + if(ptr[offset1] < c_b) + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] < c_b) + if(ptr[offset7] > cb) + goto is_not_a_corner; + else + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] > cb) + if(ptr[offset7] > cb) + if(ptr[offset1] < c_b) + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] < c_b) + if(ptr[offset1] < c_b) + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] < c_b) + if(ptr[offset7] > cb) + if(ptr[offset9] < c_b) + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] > cb) + if(ptr[offset7] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset1] < c_b) + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset1] < c_b) + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] < c_b) + if(ptr[offset7] > cb) + if(ptr[offset1] < c_b) + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] > cb) + if(ptr[offset9] > cb) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset1] < c_b) + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] > cb) + if(ptr[offset9] < c_b) + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset0] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset9] > cb) + if(ptr[offset2] > cb) + goto is_not_a_corner; + else + if(ptr[offset2] < c_b) + if(ptr[offset7] > cb) + if(ptr[offset1] > cb) + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] < c_b) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] < c_b) + if(ptr[offset7] > cb) + if(ptr[offset2] > cb) + goto is_not_a_corner; + else + if(ptr[offset2] < c_b) + if(ptr[offset1] > cb) + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] < c_b) + if(ptr[offset2] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] < c_b) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] > cb) + goto is_not_a_corner; + else + if(ptr[offset2] < c_b) + if(ptr[offset1] > cb) + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] > cb) + goto is_not_a_corner; + else + if(ptr[offset2] < c_b) + if(ptr[offset7] > cb) + if(ptr[offset1] > cb) + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] < c_b) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] > cb) + if(ptr[offset2] > cb) + if(ptr[offset7] < c_b) + if(ptr[offset9] > cb) + goto is_not_a_corner; + else + if(ptr[offset9] < c_b) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] > cb) + if(ptr[offset9] < c_b) + if(ptr[offset1] > cb) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset9] > cb) + if(ptr[offset1] > cb) + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] < c_b) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] > cb) + if(ptr[offset9] < c_b) + if(ptr[offset1] > cb) + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset4] < c_b) + if(ptr[offset10] > cb) + if(ptr[offset8] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset1] > cb) + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] < c_b) + if(ptr[offset1] > cb) + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] > cb) + if(ptr[offset9] < c_b) + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] > cb) + if(ptr[offset7] < c_b) + if(ptr[offset9] > cb) + goto is_not_a_corner; + else + if(ptr[offset9] < c_b) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] < c_b) + if(ptr[offset7] > cb) + if(ptr[offset9] > cb) + if(ptr[offset1] > cb) + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] < c_b) + if(ptr[offset1] > cb) + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset7] < c_b) + if(ptr[offset1] > cb) + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] < c_b) + if(ptr[offset9] < c_b) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] < c_b) + if(ptr[offset1] > cb) + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] < c_b) + if(ptr[offset9] > cb) + goto is_not_a_corner; + else + if(ptr[offset9] < c_b) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] < c_b) + if(ptr[offset7] > cb) + goto is_not_a_corner; + else + if(ptr[offset7] < c_b) + if(ptr[offset2] > cb) + if(ptr[offset9] > cb) + goto is_not_a_corner; + else + if(ptr[offset9] < c_b) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] < c_b) + if(ptr[offset9] > cb) + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] < c_b) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] < c_b) + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset8] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + goto is_not_a_corner; + else + if(ptr[offset9] < c_b) + if(ptr[offset1] > cb) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset8] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset3] < c_b) + goto is_a_corner; + else + if(ptr[offset10] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] < c_b) + if(ptr[offset11] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] > cb) + if(ptr[offset7] > cb) + if(ptr[offset2] < c_b) + if(ptr[offset9] < c_b) + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset2] > cb) + if(ptr[offset9] < c_b) + if(ptr[offset1] > cb) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset8] > cb) + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset8] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset9] < c_b) + goto is_not_a_corner; + else + if(ptr[offset9] > cb) + if(ptr[offset1] > cb) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + goto is_not_a_corner; + else + if(ptr[offset6] > cb) + if(ptr[offset8] > cb) + if(ptr[offset4] > cb) + if(ptr[offset3] > cb) + goto is_a_corner; + else + if(ptr[offset10] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset10] > cb) + if(ptr[offset11] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + + is_a_corner: + bmin = b_test; + goto end; + + is_not_a_corner: + bmax = b_test; + goto end; + + end: + + if(bmin == bmax - 1 || bmin == bmax) + return bmin; + b_test = (bmin + bmax) / 2; + } +} + +// 8 pixel mask +template<> +int agast_cornerScore(const uchar* ptr, const int pixel[], int threshold) +{ + int bmin = threshold; + int bmax = 255; + int b_test = (bmax + bmin)/2; + + register short offset0 = (short) pixel[0]; + register short offset1 = (short) pixel[1]; + register short offset2 = (short) pixel[2]; + register short offset3 = (short) pixel[3]; + register short offset4 = (short) pixel[4]; + register short offset5 = (short) pixel[5]; + register short offset6 = (short) pixel[6]; + register short offset7 = (short) pixel[7]; + + while(true) + { + register const int cb = *pixel + b_test; + register const int c_b = *pixel - b_test; + if(ptr[offset0] > cb) + if(ptr[offset2] > cb) + if(ptr[offset3] > cb) + if(ptr[offset5] > cb) + if(ptr[offset1] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + if(ptr[offset7] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset4] > cb) + if(ptr[offset6] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + if(ptr[offset7] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] > cb) + if(ptr[offset6] > cb) + if(ptr[offset5] > cb) + if(ptr[offset1] > cb) + goto is_a_corner; + else + if(ptr[offset4] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] > cb) + if(ptr[offset7] > cb) + if(ptr[offset6] > cb) + if(ptr[offset1] > cb) + goto is_a_corner; + else + if(ptr[offset4] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if(ptr[offset0] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset7] > cb) + if(ptr[offset3] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] > cb) + if(ptr[offset3] > cb) + if(ptr[offset4] > cb) + if(ptr[offset6] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] < c_b) + if(ptr[offset3] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + goto is_a_corner; + else + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset6] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + goto is_a_corner; + else + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] > cb) + if(ptr[offset3] > cb) + if(ptr[offset2] > cb) + if(ptr[offset1] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset4] > cb) + if(ptr[offset6] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] > cb) + if(ptr[offset4] > cb) + if(ptr[offset6] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset5] < c_b) + if(ptr[offset7] < c_b) + if(ptr[offset6] < c_b) + if(ptr[offset1] < c_b) + goto is_a_corner; + else + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] > cb) + if(ptr[offset5] > cb) + if(ptr[offset2] > cb) + if(ptr[offset1] > cb) + if(ptr[offset4] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset4] > cb) + if(ptr[offset6] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] > cb) + if(ptr[offset4] > cb) + if(ptr[offset6] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset3] < c_b) + if(ptr[offset5] < c_b) + if(ptr[offset2] < c_b) + if(ptr[offset1] < c_b) + if(ptr[offset4] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if(ptr[offset7] < c_b) + if(ptr[offset4] < c_b) + if(ptr[offset6] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + + is_a_corner: + bmin=b_test; + goto end; + + is_not_a_corner: + bmax=b_test; + goto end; + + end: + + if(bmin == bmax - 1 || bmin == bmax) + return bmin; + b_test = (bmin + bmax) / 2; + } +} + +} // namespace cv diff --git a/modules/features2d/src/agast_score.hpp b/modules/features2d/src/agast_score.hpp new file mode 100644 index 0000000000..bd5ddb3338 --- /dev/null +++ b/modules/features2d/src/agast_score.hpp @@ -0,0 +1,62 @@ +/* This is AGAST and OAST, an optimal and accelerated corner detector + based on the accelerated segment tests + Below is the original copyright and the references */ + +/* +Copyright (C) 2010 Elmar Mair +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + *Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + *Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + *Neither the name of the University of Cambridge nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* +The references are: + * Adaptive and Generic Corner Detection Based on the Accelerated Segment Test, + Elmar Mair and Gregory D. Hager and Darius Burschka + and Michael Suppa and Gerhard Hirzinger ECCV 2010 + URL: http://www6.in.tum.de/Main/ResearchAgast +*/ + + +#ifndef __OPENCV_FEATURES_2D_AGAST_HPP__ +#define __OPENCV_FEATURES_2D_AGAST_HPP__ + +#ifdef __cplusplus + +#include "precomp.hpp" +namespace cv +{ + +void makeAgastOffsets(int pixel[16], int row_stride, int type); + +template +int agast_cornerScore(const uchar* ptr, const int pixel[], int threshold); + +} +#endif +#endif diff --git a/modules/features2d/src/brisk.cpp b/modules/features2d/src/brisk.cpp index c24d727911..3e80c5d9ed 100644 --- a/modules/features2d/src/brisk.cpp +++ b/modules/features2d/src/brisk.cpp @@ -46,7 +46,7 @@ #include #include -#include "fast_score.hpp" +#include "agast_score.hpp" namespace cv { @@ -157,7 +157,7 @@ public: // derive a layer BriskLayer(const BriskLayer& layer, int mode); - // Fast/Agast without non-max suppression + // Agast without non-max suppression void getAgastPoints(int threshold, std::vector& keypoints); @@ -204,13 +204,13 @@ private: value(const cv::Mat& mat, float xf, float yf, float scale) const; // the image cv::Mat img_; - // its Fast scores + // its Agast scores cv::Mat_ scores_; // coordinate transformation float scale_; float offset_; // agast - cv::Ptr fast_9_16_; + cv::Ptr oast_9_16_; int pixel_5_8_[25]; int pixel_9_16_[25]; }; @@ -618,8 +618,6 @@ BRISK_Impl::detectAndCompute( InputArray _image, InputArray _mask, std::vector& k std::vector > agastPoints; agastPoints.resize(layers_); - // go through the octaves and intra layers and calculate fast corner scores: + // go through the octaves and intra layers and calculate agast corner scores: for (int i = 0; i < layers_; i++) { // call OAST16_9 without nms @@ -2067,9 +2072,9 @@ BriskLayer::BriskLayer(const cv::Mat& img_in, float scale_in, float offset_in) scale_ = scale_in; offset_ = offset_in; // create an agast detector - fast_9_16_ = FastFeatureDetector::create(1, true, FastFeatureDetector::TYPE_9_16); - makeOffsets(pixel_5_8_, (int)img_.step, 8); - makeOffsets(pixel_9_16_, (int)img_.step, 16); + oast_9_16_ = AgastFeatureDetector::create(1, false, AgastFeatureDetector::OAST_9_16); + makeAgastOffsets(pixel_5_8_, (int)img_.step, AgastFeatureDetector::AGAST_5_8); + makeAgastOffsets(pixel_9_16_, (int)img_.step, AgastFeatureDetector::OAST_9_16); } // derive a layer BriskLayer::BriskLayer(const BriskLayer& layer, int mode) @@ -2089,18 +2094,18 @@ BriskLayer::BriskLayer(const BriskLayer& layer, int mode) offset_ = 0.5f * scale_ - 0.5f; } scores_ = cv::Mat::zeros(img_.rows, img_.cols, CV_8U); - fast_9_16_ = FastFeatureDetector::create(1, false, FastFeatureDetector::TYPE_9_16); - makeOffsets(pixel_5_8_, (int)img_.step, 8); - makeOffsets(pixel_9_16_, (int)img_.step, 16); + oast_9_16_ = AgastFeatureDetector::create(1, false, AgastFeatureDetector::OAST_9_16); + makeAgastOffsets(pixel_5_8_, (int)img_.step, AgastFeatureDetector::AGAST_5_8); + makeAgastOffsets(pixel_9_16_, (int)img_.step, AgastFeatureDetector::OAST_9_16); } -// Fast/Agast +// Agast // wraps the agast class void BriskLayer::getAgastPoints(int threshold, std::vector& keypoints) { - fast_9_16_->setThreshold(threshold); - fast_9_16_->detect(img_, keypoints); + oast_9_16_->setThreshold(threshold); + oast_9_16_->detect(img_, keypoints); // also write scores const size_t num = keypoints.size(); @@ -2121,7 +2126,7 @@ BriskLayer::getAgastScore(int x, int y, int threshold) const { return score; } - score = (uchar)cornerScore<16>(&img_.at(y, x), pixel_9_16_, threshold - 1); + score = (uchar)agast_cornerScore(&img_.at(y, x), pixel_9_16_, threshold - 1); if (score < threshold) score = 0; return score; @@ -2134,7 +2139,7 @@ BriskLayer::getAgastScore_5_8(int x, int y, int threshold) const return 0; if (x >= img_.cols - 2 || y >= img_.rows - 2) return 0; - int score = cornerScore<8>(&img_.at(y, x), pixel_5_8_, threshold - 1); + int score = agast_cornerScore(&img_.at(y, x), pixel_5_8_, threshold - 1); if (score < threshold) score = 0; return score; diff --git a/modules/features2d/test/test_agast.cpp b/modules/features2d/test/test_agast.cpp new file mode 100644 index 0000000000..36f34df6a1 --- /dev/null +++ b/modules/features2d/test/test_agast.cpp @@ -0,0 +1,137 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +using namespace std; +using namespace cv; + +class CV_AgastTest : public cvtest::BaseTest +{ +public: + CV_AgastTest(); + ~CV_AgastTest(); +protected: + void run(int); +}; + +CV_AgastTest::CV_AgastTest() {} +CV_AgastTest::~CV_AgastTest() {} + +void CV_AgastTest::run( int ) +{ + for(int type=0; type <= 2; ++type) { + Mat image1 = imread(string(ts->get_data_path()) + "inpaint/orig.png"); + Mat image2 = imread(string(ts->get_data_path()) + "cameracalibration/chess9.png"); + string xml = string(ts->get_data_path()) + format("agast/result%d.xml", type); + + if (image1.empty() || image2.empty()) + { + ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA ); + return; + } + + Mat gray1, gray2; + cvtColor(image1, gray1, COLOR_BGR2GRAY); + cvtColor(image2, gray2, COLOR_BGR2GRAY); + + vector keypoints1; + vector keypoints2; + AGAST(gray1, keypoints1, 30, true, type); + AGAST(gray2, keypoints2, (type > 0 ? 30 : 20), true, type); + + for(size_t i = 0; i < keypoints1.size(); ++i) + { + const KeyPoint& kp = keypoints1[i]; + cv::circle(image1, kp.pt, cvRound(kp.size/2), Scalar(255, 0, 0)); + } + + for(size_t i = 0; i < keypoints2.size(); ++i) + { + const KeyPoint& kp = keypoints2[i]; + cv::circle(image2, kp.pt, cvRound(kp.size/2), Scalar(255, 0, 0)); + } + + Mat kps1(1, (int)(keypoints1.size() * sizeof(KeyPoint)), CV_8U, &keypoints1[0]); + Mat kps2(1, (int)(keypoints2.size() * sizeof(KeyPoint)), CV_8U, &keypoints2[0]); + + FileStorage fs(xml, FileStorage::READ); + if (!fs.isOpened()) + { + fs.open(xml, FileStorage::WRITE); + if (!fs.isOpened()) + { + ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); + return; + } + fs << "exp_kps1" << kps1; + fs << "exp_kps2" << kps2; + fs.release(); + fs.open(xml, FileStorage::READ); + if (!fs.isOpened()) + { + ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); + return; + } + } + + Mat exp_kps1, exp_kps2; + read( fs["exp_kps1"], exp_kps1, Mat() ); + read( fs["exp_kps2"], exp_kps2, Mat() ); + fs.release(); + + if ( exp_kps1.size != kps1.size || 0 != cvtest::norm(exp_kps1, kps1, NORM_L2) || + exp_kps2.size != kps2.size || 0 != cvtest::norm(exp_kps2, kps2, NORM_L2)) + { + ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); + return; + } + + /*cv::namedWindow("Img1"); cv::imshow("Img1", image1); + cv::namedWindow("Img2"); cv::imshow("Img2", image2); + cv::waitKey(0);*/ + } + + ts->set_failed_test_info(cvtest::TS::OK); +} + +TEST(Features2d_AGAST, regression) { CV_AgastTest test; test.safe_run(); } diff --git a/modules/features2d/test/test_detectors_regression.cpp b/modules/features2d/test/test_detectors_regression.cpp index e2d9f478db..58c0b6dbf0 100644 --- a/modules/features2d/test/test_detectors_regression.cpp +++ b/modules/features2d/test/test_detectors_regression.cpp @@ -259,6 +259,12 @@ TEST( Features2d_Detector_FAST, regression ) test.safe_run(); } +TEST( Features2d_Detector_AGAST, regression ) +{ + CV_FeatureDetectorTest test( "detector-agast", AgastFeatureDetector::create() ); + test.safe_run(); +} + TEST( Features2d_Detector_GFTT, regression ) { CV_FeatureDetectorTest test( "detector-gftt", GFTTDetector::create() ); diff --git a/modules/features2d/test/test_keypoints.cpp b/modules/features2d/test/test_keypoints.cpp index e9dafe3474..4f5f8a0836 100644 --- a/modules/features2d/test/test_keypoints.cpp +++ b/modules/features2d/test/test_keypoints.cpp @@ -131,6 +131,12 @@ TEST(Features2d_Detector_Keypoints_FAST, validation) test.safe_run(); } +TEST(Features2d_Detector_Keypoints_AGAST, validation) +{ + CV_FeatureDetectorKeypointsTest test(AgastFeatureDetector::create()); + test.safe_run(); +} + TEST(Features2d_Detector_Keypoints_HARRIS, validation) { From dee3a4b52800bb6a4eaf67f6e4f82824e8976b09 Mon Sep 17 00:00:00 2001 From: cbalint13 Date: Sat, 11 Apr 2015 17:43:28 +0300 Subject: [PATCH 040/109] Add missing opencv_contrib PR #202 patch. --- modules/features2d/src/agast_score.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/features2d/src/agast_score.cpp b/modules/features2d/src/agast_score.cpp index 6b4c869c38..33682354ca 100644 --- a/modules/features2d/src/agast_score.cpp +++ b/modules/features2d/src/agast_score.cpp @@ -116,8 +116,8 @@ int agast_cornerScore(const uchar* ptr, const i while(true) { - register const int cb = *pixel + b_test; - register const int c_b = *pixel - b_test; + register const int cb = *ptr + b_test; + register const int c_b = *ptr - b_test; if(ptr[offset0] > cb) if(ptr[offset2] > cb) if(ptr[offset4] > cb) @@ -2187,8 +2187,8 @@ int agast_cornerScore(const uchar* ptr, const while(true) { - register const int cb = *pixel + b_test; - register const int c_b = *pixel - b_test; + register const int cb = *ptr + b_test; + register const int c_b = *ptr - b_test; if(ptr[offset0] > cb) if(ptr[offset5] > cb) if(ptr[offset2] > cb) @@ -3399,8 +3399,8 @@ int agast_cornerScore(const uchar* ptr, const while(true) { - register const int cb = *pixel + b_test; - register const int c_b = *pixel - b_test; + register const int cb = *ptr + b_test; + register const int c_b = *ptr - b_test; if(ptr[offset0] > cb) if(ptr[offset5] > cb) if(ptr[offset2] < c_b) @@ -9029,8 +9029,8 @@ int agast_cornerScore(const uchar* ptr, const i while(true) { - register const int cb = *pixel + b_test; - register const int c_b = *pixel - b_test; + register const int cb = *ptr + b_test; + register const int c_b = *ptr - b_test; if(ptr[offset0] > cb) if(ptr[offset2] > cb) if(ptr[offset3] > cb) From 2f95acf273c2034fd01120bedb6fda1a40a49309 Mon Sep 17 00:00:00 2001 From: "S. Garrido" Date: Sat, 11 Apr 2015 19:03:17 +0200 Subject: [PATCH 041/109] completing and fixing gen_pattern.py --- doc/pattern_tools/gen_pattern.py | 63 +++++++++++++++----------------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/doc/pattern_tools/gen_pattern.py b/doc/pattern_tools/gen_pattern.py index 3643b6d3b2..fc1e74bbc3 100755 --- a/doc/pattern_tools/gen_pattern.py +++ b/doc/pattern_tools/gen_pattern.py @@ -1,13 +1,19 @@ #!/usr/bin/env python """gen_pattern.py -To run: --c 10 -r 12 -o out.svg --T type of pattern, circles, acircles, checkerboard --s --square_size size of squares in pattern --u --units mm, inches, px, m --w page width in units --h page height in units +Usage example: +python gen_pattern.py -o out.svg -r 11 -c 8 -T circles -s 20.0 -R 5.0 -u mm -w 216 -h 279 + +-o, --output - output file (default out.svg) +-r, --rows - pattern rows (default 11) +-c, --columns - pattern columns (default 8) +-T, --type - type of pattern, circles, acircles, checkerboard (default circles) +-s, --square_size - size of squares in pattern (default 20.0) +-R, --radius_rate - circles_radius = square_size/radius_rate (default 5.0) +-u, --units - mm, inches, px, m (default mm) +-w, --page_width - page width in units (default 216) +-h, --page_height - page height in units (default 279) +-H, --help - show help """ from svgfig import * @@ -16,18 +22,20 @@ import sys import getopt class PatternMaker: - def __init__(self, cols,rows,output,units,square_size,page_width,page_height): + def __init__(self, cols,rows,output,units,square_size,radius_rate,page_width,page_height): self.cols = cols self.rows = rows self.output = output self.units = units self.square_size = square_size + self.radius_rate = radius_rate self.width = page_width self.height = page_height self.g = SVG("g") # the svg group container + def makeCirclesPattern(self): spacing = self.square_size - r = spacing / 5.0 #radius is a 5th of the spacing TODO parameterize + r = spacing / self.radius_rate for x in range(1,self.cols+1): for y in range(1,self.rows+1): dot = SVG("circle", cx=x * spacing, cy=y * spacing, r=r, fill="black") @@ -35,7 +43,7 @@ class PatternMaker: def makeACirclesPattern(self): spacing = self.square_size - r = spacing / 5.0 + r = spacing / self.radius_rate for i in range(0,self.rows): for j in range(0,self.cols): dot = SVG("circle", cx= ((j*2 + i%2)*spacing) + spacing, cy=self.height - (i * spacing + spacing), r=r, fill="black") @@ -43,37 +51,23 @@ class PatternMaker: def makeCheckerboardPattern(self): spacing = self.square_size - r = spacing / 5.0 for x in range(1,self.cols+1): for y in range(1,self.rows+1): - #TODO make a checkerboard pattern - dot = SVG("circle", cx=x * spacing, cy=y * spacing, r=r, fill="black") - self.g.append(dot) + if x%2 == y%2: + dot = SVG("rect", x=x * spacing, y=y * spacing, width=spacing, height=spacing, stroke_width="0", fill="black") + self.g.append(dot) + def save(self): c = canvas(self.g,width="%d%s"%(self.width,self.units),height="%d%s"%(self.height,self.units),viewBox="0 0 %d %d"%(self.width,self.height)) c.inkview(self.output) -def makePattern(cols,rows,output,p_type,units,square_size,page_width,page_height): - width = page_width - spacing = square_size - height = page_height - r = spacing / 5.0 - g = SVG("g") # the svg group container - for x in range(1,cols+1): - for y in range(1,rows+1): - if "circle" in p_type: - dot = SVG("circle", cx=x * spacing, cy=y * spacing, r=r, fill="black") - g.append(dot) - c = canvas(g,width="%d%s"%(width,units),height="%d%s"%(height,units),viewBox="0 0 %d %d"%(width,height)) - c.inkview(output) - def main(): # parse command line options, TODO use argparse for better doc try: - opts, args = getopt.getopt(sys.argv[1:], "ho:c:r:T:u:s:w:h:", ["help","output","columns","rows", - "type","units","square_size","page_width", - "page_height"]) + opts, args = getopt.getopt(sys.argv[1:], "Ho:c:r:T:u:s:R:w:h:", ["help","output=","columns=","rows=", + "type=","units=","square_size=","radius_rate=", + "page_width=","page_height="]) except getopt.error, msg: print msg print "for help use --help" @@ -84,11 +78,12 @@ def main(): p_type = "circles" units = "mm" square_size = 20.0 + radius_rate = 5.0 page_width = 216 #8.5 inches page_height = 279 #11 inches # process options for o, a in opts: - if o in ("-h", "--help"): + if o in ("-H", "--help"): print __doc__ sys.exit(0) elif o in ("-r", "--rows"): @@ -103,11 +98,13 @@ def main(): units = a elif o in ("-s", "--square_size"): square_size = float(a) + elif o in ("-R", "--radius_rate"): + radius_rate = float(a) elif o in ("-w", "--page_width"): page_width = float(a) elif o in ("-h", "--page_height"): page_height = float(a) - pm = PatternMaker(columns,rows,output,units,square_size,page_width,page_height) + pm = PatternMaker(columns,rows,output,units,square_size,radius_rate,page_width,page_height) #dict for easy lookup of pattern type mp = {"circles":pm.makeCirclesPattern,"acircles":pm.makeACirclesPattern,"checkerboard":pm.makeCheckerboardPattern} mp[p_type]() From 3c797b0ca55b082c98a0d4dd8cc120d7279f3f20 Mon Sep 17 00:00:00 2001 From: ttagu99 Date: Tue, 14 Apr 2015 10:01:53 +0900 Subject: [PATCH 042/109] findcontour_example check image empty --- .../tutorial_code/ShapeDescriptors/findContours_demo.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp b/samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp index cd29b1c2e7..6a6de95394 100644 --- a/samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp +++ b/samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp @@ -27,8 +27,13 @@ void thresh_callback(int, void* ); */ int main( int, char** argv ) { - /// Load source image and convert it to gray - src = imread( argv[1], 1 ); + /// Load source image + src = imread(argv[1]); + if (src.empty()) + { + cerr << "No image supplied ..." << endl; + return -1; + } /// Convert image to gray and blur it cvtColor( src, src_gray, COLOR_BGR2GRAY ); From 3b177eaaa3bd2933e9910e21bfdf5a23af8e883d Mon Sep 17 00:00:00 2001 From: Yang Fan Date: Tue, 14 Apr 2015 13:39:00 +0800 Subject: [PATCH 043/109] ENH: explicitly declared outputFilename to surpress error C2668 --- samples/gpu/video_writer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/gpu/video_writer.cpp b/samples/gpu/video_writer.cpp index 5a48c69aab..6c5d1412d6 100644 --- a/samples/gpu/video_writer.cpp +++ b/samples/gpu/video_writer.cpp @@ -69,7 +69,8 @@ int main(int argc, const char* argv[]) { std::cout << "Open CUDA Writer" << std::endl; - d_writer = cv::cudacodec::createVideoWriter("output_gpu.avi", frame.size(), FPS); + const cv::String outputFilename = "output_gpu.avi"; + d_writer = cv::cudacodec::createVideoWriter(outputFilename, frame.size(), FPS); } d_frame.upload(frame); From 4686b935c172cc56707966f7e6e42372e8f709cf Mon Sep 17 00:00:00 2001 From: Daeyun Shin Date: Tue, 14 Apr 2015 07:44:32 -0500 Subject: [PATCH 044/109] Fix typo in documentation. F = K^-T * E * K^-1 --- modules/calib3d/include/opencv2/calib3d.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/calib3d/include/opencv2/calib3d.hpp b/modules/calib3d/include/opencv2/calib3d.hpp index 7b01a7bbcd..744ded305b 100644 --- a/modules/calib3d/include/opencv2/calib3d.hpp +++ b/modules/calib3d/include/opencv2/calib3d.hpp @@ -1200,7 +1200,7 @@ for the other points. The array is computed only in the RANSAC and LMedS methods This function estimates essential matrix based on the five-point algorithm solver in @cite Nister03 . @cite SteweniusCFS is also a related. The epipolar geometry is described by the following equation: -\f[[p_2; 1]^T K^T E K [p_1; 1] = 0 \\\f]\f[K = +\f[[p_2; 1]^T K^{-T} E K^{-1} [p_1; 1] = 0 \\\f]\f[K = \begin{bmatrix} f & 0 & x_{pp} \\ 0 & f & y_{pp} \\ From 17bedd72f03eb3c0df6f162c4d285add85a84724 Mon Sep 17 00:00:00 2001 From: Ilya Lavrenov Date: Tue, 14 Apr 2015 16:55:11 +0300 Subject: [PATCH 045/109] workaround for stange internal compiler error when cross-compiling with 4.6 --- modules/core/src/out.cpp | 46 ++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/modules/core/src/out.cpp b/modules/core/src/out.cpp index 89919715ec..2c6ba5396a 100644 --- a/modules/core/src/out.cpp +++ b/modules/core/src/out.cpp @@ -43,9 +43,9 @@ #include "precomp.hpp" -namespace +namespace cv { - class FormattedImpl : public cv::Formatted + class FormattedImpl : public Formatted { enum { STATE_PROLOGUE, STATE_EPILOGUE, STATE_INTERLUDE, STATE_ROW_OPEN, STATE_ROW_CLOSE, STATE_CN_OPEN, STATE_CN_CLOSE, STATE_VALUE, STATE_FINISHED, @@ -55,7 +55,7 @@ namespace char floatFormat[8]; char buf[32]; // enough for double with precision up to 20 - cv::Mat mtx; + Mat mtx; int mcn; // == mtx.channels() bool singleLine; bool alignOrder; // true when cn first order @@ -65,8 +65,8 @@ namespace int col; int cn; - cv::String prologue; - cv::String epilogue; + String prologue; + String epilogue; char braces[5]; void (FormattedImpl::*valueToStr)(); @@ -81,7 +81,7 @@ namespace public: - FormattedImpl(cv::String pl, cv::String el, cv::Mat m, char br[5], bool sLine, bool aOrder, int precision) + FormattedImpl(String pl, String el, Mat m, char br[5], bool sLine, bool aOrder, int precision) { CV_Assert(m.dims <= 2); @@ -253,7 +253,7 @@ namespace } }; - class FormatterBase : public cv::Formatter + class FormatterBase : public Formatter { public: FormatterBase() : prec32f(8), prec64f(16), multiline(true) {} @@ -278,14 +278,15 @@ namespace int prec64f; int multiline; }; + class DefaultFormatter : public FormatterBase { public: - cv::Ptr format(const cv::Mat& mtx) const + Ptr format(const Mat& mtx) const { char braces[5] = {'\0', '\0', ';', '\0', '\0'}; - return cv::makePtr("[", "]", mtx, &*braces, + return makePtr("[", "]", mtx, &*braces, mtx.rows == 1 || !multiline, false, mtx.depth() == CV_64F ? prec64f : prec32f ); } }; @@ -294,10 +295,10 @@ namespace { public: - cv::Ptr format(const cv::Mat& mtx) const + Ptr format(const Mat& mtx) const { char braces[5] = {'\0', '\0', ';', '\0', '\0'}; - return cv::makePtr("", "", mtx, &*braces, + return makePtr("", "", mtx, &*braces, mtx.rows == 1 || !multiline, true, mtx.depth() == CV_64F ? prec64f : prec32f ); } }; @@ -306,12 +307,12 @@ namespace { public: - cv::Ptr format(const cv::Mat& mtx) const + Ptr format(const Mat& mtx) const { char braces[5] = {'[', ']', '\0', '[', ']'}; if (mtx.cols == 1) braces[0] = braces[1] = '\0'; - return cv::makePtr("[", "]", mtx, &*braces, + return makePtr("[", "]", mtx, &*braces, mtx.rows == 1 || !multiline, false, mtx.depth() == CV_64F ? prec64f : prec32f ); } }; @@ -320,7 +321,7 @@ namespace { public: - cv::Ptr format(const cv::Mat& mtx) const + Ptr format(const Mat& mtx) const { static const char* numpyTypes[] = { @@ -329,7 +330,7 @@ namespace char braces[5] = {'[', ']', '\0', '[', ']'}; if (mtx.cols == 1) braces[0] = braces[1] = '\0'; - return cv::makePtr("array([", + return makePtr("array([", cv::format("], type='%s')", numpyTypes[mtx.depth()]), mtx, &*braces, mtx.rows == 1 || !multiline, false, mtx.depth() == CV_64F ? prec64f : prec32f ); } @@ -339,11 +340,11 @@ namespace { public: - cv::Ptr format(const cv::Mat& mtx) const + Ptr format(const Mat& mtx) const { char braces[5] = {'\0', '\0', '\0', '\0', '\0'}; - return cv::makePtr(cv::String(), - mtx.rows > 1 ? cv::String("\n") : cv::String(), mtx, &*braces, + return makePtr(String(), + mtx.rows > 1 ? String("\n") : String(), mtx, &*braces, mtx.rows == 1 || !multiline, false, mtx.depth() == CV_64F ? prec64f : prec32f ); } }; @@ -352,19 +353,14 @@ namespace { public: - cv::Ptr format(const cv::Mat& mtx) const + Ptr format(const Mat& mtx) const { char braces[5] = {'\0', '\0', ',', '\0', '\0'}; - return cv::makePtr("{", "}", mtx, &*braces, + return makePtr("{", "}", mtx, &*braces, mtx.rows == 1 || !multiline, false, mtx.depth() == CV_64F ? prec64f : prec32f ); } }; -} // namespace - - -namespace cv -{ Formatted::~Formatted() {} Formatter::~Formatter() {} From 723c317108a4a1e36f2dc098dab0cf111d46f2c2 Mon Sep 17 00:00:00 2001 From: berak Date: Tue, 14 Apr 2015 19:01:48 +0200 Subject: [PATCH 046/109] changed create function in tutorial --- doc/py_tutorials/py_calib3d/py_depthmap/py_depthmap.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/py_tutorials/py_calib3d/py_depthmap/py_depthmap.markdown b/doc/py_tutorials/py_calib3d/py_depthmap/py_depthmap.markdown index 5ef3380159..7d9a1258a9 100644 --- a/doc/py_tutorials/py_calib3d/py_depthmap/py_depthmap.markdown +++ b/doc/py_tutorials/py_calib3d/py_depthmap/py_depthmap.markdown @@ -44,7 +44,7 @@ from matplotlib import pyplot as plt imgL = cv2.imread('tsukuba_l.png',0) imgR = cv2.imread('tsukuba_r.png',0) -stereo = cv2.createStereoBM(numDisparities=16, blockSize=15) +stereo = cv2.StereoBM_create(numDisparities=16, blockSize=15) disparity = stereo.compute(imgL,imgR) plt.imshow(disparity,'gray') plt.show() From a2bba1b9e6771b8b27906bf9e3fcea6f2cd3bd2c Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Wed, 15 Apr 2015 00:36:27 +0300 Subject: [PATCH 047/109] HAL extensions: added initial version of universal intrinsics (C implementation and SSE2, NEON - TBD). added empty files where some functionality from core and imgproc will be moved to --- modules/core/include/opencv2/core/base.hpp | 131 - modules/core/include/opencv2/core/cvdef.h | 181 -- modules/core/include/opencv2/core/private.hpp | 8 - modules/core/include/opencv2/core/types_c.h | 16 - modules/hal/include/opencv2/hal.hpp | 45 +- modules/hal/include/opencv2/hal/defs.h | 391 ++- modules/hal/include/opencv2/hal/intrin.hpp | 2254 +++++++++++++++++ modules/hal/src/arithm.cpp | 47 + modules/hal/src/color.cpp | 47 + modules/hal/src/filter.cpp | 47 + modules/hal/src/mathfuncs.cpp | 47 + modules/hal/src/matrix.cpp | 47 + modules/hal/src/precomp.hpp | 42 + modules/hal/src/resize.cpp | 47 + modules/hal/src/{norm.cpp => stat.cpp} | 0 modules/hal/src/warp.cpp | 47 + 16 files changed, 3055 insertions(+), 342 deletions(-) create mode 100644 modules/hal/include/opencv2/hal/intrin.hpp create mode 100644 modules/hal/src/arithm.cpp create mode 100644 modules/hal/src/color.cpp create mode 100644 modules/hal/src/filter.cpp create mode 100644 modules/hal/src/mathfuncs.cpp create mode 100644 modules/hal/src/matrix.cpp create mode 100644 modules/hal/src/resize.cpp rename modules/hal/src/{norm.cpp => stat.cpp} (100%) create mode 100644 modules/hal/src/warp.cpp diff --git a/modules/core/include/opencv2/core/base.hpp b/modules/core/include/opencv2/core/base.hpp index 08a6642fba..83661a2fd6 100644 --- a/modules/core/include/opencv2/core/base.hpp +++ b/modules/core/include/opencv2/core/base.hpp @@ -400,136 +400,6 @@ configurations while CV_DbgAssert is only retained in the Debug configuration. # define CV_DbgAssert(expr) #endif - -/////////////// saturate_cast (used in image & signal processing) /////////////////// - -/** -Template function for accurate conversion from one primitive type to another. - -The functions saturate_cast resemble the standard C++ cast operations, such as static_cast\() -and others. They perform an efficient and accurate conversion from one primitive type to another -(see the introduction chapter). saturate in the name means that when the input value v is out of the -range of the target type, the result is not formed just by taking low bits of the input, but instead -the value is clipped. For example: -@code - uchar a = saturate_cast(-100); // a = 0 (UCHAR_MIN) - short b = saturate_cast(33333.33333); // b = 32767 (SHRT_MAX) -@endcode -Such clipping is done when the target type is unsigned char , signed char , unsigned short or -signed short . For 32-bit integers, no clipping is done. - -When the parameter is a floating-point value and the target type is an integer (8-, 16- or 32-bit), -the floating-point value is first rounded to the nearest integer and then clipped if needed (when -the target type is 8- or 16-bit). - -This operation is used in the simplest or most complex image processing functions in OpenCV. - -@param v Function parameter. -@sa add, subtract, multiply, divide, Mat::convertTo -*/ -template static inline _Tp saturate_cast(uchar v) { return _Tp(v); } -/** @overload */ -template static inline _Tp saturate_cast(schar v) { return _Tp(v); } -/** @overload */ -template static inline _Tp saturate_cast(ushort v) { return _Tp(v); } -/** @overload */ -template static inline _Tp saturate_cast(short v) { return _Tp(v); } -/** @overload */ -template static inline _Tp saturate_cast(unsigned v) { return _Tp(v); } -/** @overload */ -template static inline _Tp saturate_cast(int v) { return _Tp(v); } -/** @overload */ -template static inline _Tp saturate_cast(float v) { return _Tp(v); } -/** @overload */ -template static inline _Tp saturate_cast(double v) { return _Tp(v); } -/** @overload */ -template static inline _Tp saturate_cast(int64 v) { return _Tp(v); } -/** @overload */ -template static inline _Tp saturate_cast(uint64 v) { return _Tp(v); } - -//! @cond IGNORED - -template<> inline uchar saturate_cast(schar v) { return (uchar)std::max((int)v, 0); } -template<> inline uchar saturate_cast(ushort v) { return (uchar)std::min((unsigned)v, (unsigned)UCHAR_MAX); } -template<> inline uchar saturate_cast(int v) { return (uchar)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); } -template<> inline uchar saturate_cast(short v) { return saturate_cast((int)v); } -template<> inline uchar saturate_cast(unsigned v) { return (uchar)std::min(v, (unsigned)UCHAR_MAX); } -template<> inline uchar saturate_cast(float v) { int iv = cvRound(v); return saturate_cast(iv); } -template<> inline uchar saturate_cast(double v) { int iv = cvRound(v); return saturate_cast(iv); } -template<> inline uchar saturate_cast(int64 v) { return (uchar)((uint64)v <= (uint64)UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); } -template<> inline uchar saturate_cast(uint64 v) { return (uchar)std::min(v, (uint64)UCHAR_MAX); } - -template<> inline schar saturate_cast(uchar v) { return (schar)std::min((int)v, SCHAR_MAX); } -template<> inline schar saturate_cast(ushort v) { return (schar)std::min((unsigned)v, (unsigned)SCHAR_MAX); } -template<> inline schar saturate_cast(int v) { return (schar)((unsigned)(v-SCHAR_MIN) <= (unsigned)UCHAR_MAX ? v : v > 0 ? SCHAR_MAX : SCHAR_MIN); } -template<> inline schar saturate_cast(short v) { return saturate_cast((int)v); } -template<> inline schar saturate_cast(unsigned v) { return (schar)std::min(v, (unsigned)SCHAR_MAX); } -template<> inline schar saturate_cast(float v) { int iv = cvRound(v); return saturate_cast(iv); } -template<> inline schar saturate_cast(double v) { int iv = cvRound(v); return saturate_cast(iv); } -template<> inline schar saturate_cast(int64 v) { return (schar)((uint64)((int64)v-SCHAR_MIN) <= (uint64)UCHAR_MAX ? v : v > 0 ? SCHAR_MAX : SCHAR_MIN); } -template<> inline schar saturate_cast(uint64 v) { return (schar)std::min(v, (uint64)SCHAR_MAX); } - -template<> inline ushort saturate_cast(schar v) { return (ushort)std::max((int)v, 0); } -template<> inline ushort saturate_cast(short v) { return (ushort)std::max((int)v, 0); } -template<> inline ushort saturate_cast(int v) { return (ushort)((unsigned)v <= (unsigned)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); } -template<> inline ushort saturate_cast(unsigned v) { return (ushort)std::min(v, (unsigned)USHRT_MAX); } -template<> inline ushort saturate_cast(float v) { int iv = cvRound(v); return saturate_cast(iv); } -template<> inline ushort saturate_cast(double v) { int iv = cvRound(v); return saturate_cast(iv); } -template<> inline ushort saturate_cast(int64 v) { return (ushort)((uint64)v <= (uint64)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); } -template<> inline ushort saturate_cast(uint64 v) { return (ushort)std::min(v, (uint64)USHRT_MAX); } - -template<> inline short saturate_cast(ushort v) { return (short)std::min((int)v, SHRT_MAX); } -template<> inline short saturate_cast(int v) { return (short)((unsigned)(v - SHRT_MIN) <= (unsigned)USHRT_MAX ? v : v > 0 ? SHRT_MAX : SHRT_MIN); } -template<> inline short saturate_cast(unsigned v) { return (short)std::min(v, (unsigned)SHRT_MAX); } -template<> inline short saturate_cast(float v) { int iv = cvRound(v); return saturate_cast(iv); } -template<> inline short saturate_cast(double v) { int iv = cvRound(v); return saturate_cast(iv); } -template<> inline short saturate_cast(int64 v) { return (short)((uint64)((int64)v - SHRT_MIN) <= (uint64)USHRT_MAX ? v : v > 0 ? SHRT_MAX : SHRT_MIN); } -template<> inline short saturate_cast(uint64 v) { return (short)std::min(v, (uint64)SHRT_MAX); } - -template<> inline int saturate_cast(float v) { return cvRound(v); } -template<> inline int saturate_cast(double v) { return cvRound(v); } - -// we intentionally do not clip negative numbers, to make -1 become 0xffffffff etc. -template<> inline unsigned saturate_cast(float v) { return cvRound(v); } -template<> inline unsigned saturate_cast(double v) { return cvRound(v); } - -//! @endcond - -//////////////////////////////// low-level functions //////////////////////////////// - -CV_EXPORTS int LU(float* A, size_t astep, int m, float* b, size_t bstep, int n); -CV_EXPORTS int LU(double* A, size_t astep, int m, double* b, size_t bstep, int n); -CV_EXPORTS bool Cholesky(float* A, size_t astep, int m, float* b, size_t bstep, int n); -CV_EXPORTS bool Cholesky(double* A, size_t astep, int m, double* b, size_t bstep, int n); - -CV_EXPORTS int normL1_(const uchar* a, const uchar* b, int n); -CV_EXPORTS float normL1_(const float* a, const float* b, int n); -CV_EXPORTS float normL2Sqr_(const float* a, const float* b, int n); - -CV_EXPORTS void exp(const float* src, float* dst, int n); -CV_EXPORTS void log(const float* src, float* dst, int n); - -CV_EXPORTS void fastAtan2(const float* y, const float* x, float* dst, int n, bool angleInDegrees); -CV_EXPORTS void magnitude(const float* x, const float* y, float* dst, int n); - -/** @brief Computes the cube root of an argument. - -The function cubeRoot computes \f$\sqrt[3]{\texttt{val}}\f$. Negative arguments are handled correctly. -NaN and Inf are not handled. The accuracy approaches the maximum possible accuracy for -single-precision data. -@param val A function argument. - */ -CV_EXPORTS_W float cubeRoot(float val); - -/** @brief Calculates the angle of a 2D vector in degrees. - -The function fastAtan2 calculates the full-range angle of an input 2D vector. The angle is measured -in degrees and varies from 0 to 360 degrees. The accuracy is about 0.3 degrees. -@param x x-coordinate of the vector. -@param y y-coordinate of the vector. - */ -CV_EXPORTS_W float fastAtan2(float y, float x); - /* * Hamming distance functor - counts the bit differences between two strings - useful for the Brief descriptor * bit count of A exclusive XOR'ed with B @@ -549,7 +419,6 @@ typedef Hamming HammingLUT; /////////////////////////////////// inline norms //////////////////////////////////// - template static inline _AccTp normL2Sqr(const _Tp* a, int n) { diff --git a/modules/core/include/opencv2/core/cvdef.h b/modules/core/include/opencv2/core/cvdef.h index af0a271a41..1d933b5c30 100644 --- a/modules/core/include/opencv2/core/cvdef.h +++ b/modules/core/include/opencv2/core/cvdef.h @@ -70,16 +70,6 @@ # define CV_EXPORTS #endif -#ifndef CV_INLINE -# if defined __cplusplus -# define CV_INLINE static inline -# elif defined _MSC_VER -# define CV_INLINE __inline -# else -# define CV_INLINE static -# endif -#endif - #ifndef CV_EXTERN_C # ifdef __cplusplus # define CV_EXTERN_C extern "C" @@ -186,19 +176,6 @@ #define CV_ELEM_SIZE(type) \ (CV_MAT_CN(type) << ((((sizeof(size_t)/4+1)*16384|0x3a50) >> CV_MAT_DEPTH(type)*2) & 3)) - -/****************************************************************************************\ -* fast math * -\****************************************************************************************/ - -#if defined __BORLANDC__ -# include -#elif defined __cplusplus -# include -#else -# include -#endif - #ifndef MIN # define MIN(a,b) ((a) > (b) ? (b) : (a)) #endif @@ -207,164 +184,6 @@ # define MAX(a,b) ((a) < (b) ? (b) : (a)) #endif -#ifdef HAVE_TEGRA_OPTIMIZATION -# include "tegra_round.hpp" -#endif - -//! @addtogroup core_utils -//! @{ - -#if CV_VFP -// 1. general scheme -#define ARM_ROUND(_value, _asm_string) \ - int res; \ - float temp; \ - asm(_asm_string : [res] "=r" (res), [temp] "=w" (temp) : [value] "w" (_value)); \ - return res; -// 2. version for double -#ifdef __clang__ -#define ARM_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %[value] \n vmov %[res], %[temp]") -#else -#define ARM_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %P[value] \n vmov %[res], %[temp]") -#endif -// 3. version for float -#define ARM_ROUND_FLT(value) ARM_ROUND(value, "vcvtr.s32.f32 %[temp], %[value]\n vmov %[res], %[temp]") -#endif // CV_VFP - -/** @brief Rounds floating-point number to the nearest integer - -@param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the -result is not defined. - */ -CV_INLINE int cvRound( double value ) -{ -#if ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__) - __m128d t = _mm_set_sd( value ); - return _mm_cvtsd_si32(t); -#elif defined _MSC_VER && defined _M_IX86 - int t; - __asm - { - fld value; - fistp t; - } - return t; -#elif ((defined _MSC_VER && defined _M_ARM) || defined CV_ICC || defined __GNUC__) && defined HAVE_TEGRA_OPTIMIZATION - TEGRA_ROUND_DBL(value); -#elif defined CV_ICC || defined __GNUC__ -# if CV_VFP - ARM_ROUND_DBL(value) -# else - return (int)lrint(value); -# endif -#else - double intpart, fractpart; - fractpart = modf(value, &intpart); - if ((fabs(fractpart) != 0.5) || ((((int)intpart) % 2) != 0)) - return (int)(value + (value >= 0 ? 0.5 : -0.5)); - else - return (int)intpart; -#endif -} - -#ifdef __cplusplus - -/** @overload */ -CV_INLINE int cvRound(float value) -{ -#if defined ANDROID && (defined CV_ICC || defined __GNUC__) && defined HAVE_TEGRA_OPTIMIZATION - TEGRA_ROUND_FLT(value); -#elif CV_VFP && !defined HAVE_TEGRA_OPTIMIZATION - ARM_ROUND_FLT(value) -#else - return cvRound((double)value); -#endif -} - -/** @overload */ -CV_INLINE int cvRound(int value) -{ - return value; -} - -#endif // __cplusplus - -/** @brief Rounds floating-point number to the nearest integer not larger than the original. - -The function computes an integer i such that: -\f[i \le \texttt{value} < i+1\f] -@param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the -result is not defined. - */ -CV_INLINE int cvFloor( double value ) -{ -#if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__) - __m128d t = _mm_set_sd( value ); - int i = _mm_cvtsd_si32(t); - return i - _mm_movemask_pd(_mm_cmplt_sd(t, _mm_cvtsi32_sd(t,i))); -#elif defined __GNUC__ - int i = (int)value; - return i - (i > value); -#else - int i = cvRound(value); - float diff = (float)(value - i); - return i - (diff < 0); -#endif -} - -/** @brief Rounds floating-point number to the nearest integer not larger than the original. - -The function computes an integer i such that: -\f[i \le \texttt{value} < i+1\f] -@param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the -result is not defined. -*/ -CV_INLINE int cvCeil( double value ) -{ -#if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__&& !defined __APPLE__)) && !defined(__CUDACC__) - __m128d t = _mm_set_sd( value ); - int i = _mm_cvtsd_si32(t); - return i + _mm_movemask_pd(_mm_cmplt_sd(_mm_cvtsi32_sd(t,i), t)); -#elif defined __GNUC__ - int i = (int)value; - return i + (i < value); -#else - int i = cvRound(value); - float diff = (float)(i - value); - return i + (diff < 0); -#endif -} - -/** @brief Determines if the argument is Not A Number. - -@param value The input floating-point value - -The function returns 1 if the argument is Not A Number (as defined by IEEE754 standard), 0 -otherwise. */ -CV_INLINE int cvIsNaN( double value ) -{ - union { uint64 u; double f; } ieee754; - ieee754.f = value; - return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) + - ((unsigned)ieee754.u != 0) > 0x7ff00000; -} - -/** @brief Determines if the argument is Infinity. - -@param value The input floating-point value - -The function returns 1 if the argument is a plus or minus infinity (as defined by IEEE754 standard) -and 0 otherwise. */ -CV_INLINE int cvIsInf( double value ) -{ - union { uint64 u; double f; } ieee754; - ieee754.f = value; - return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 && - (unsigned)ieee754.u == 0; -} - -//! @} core_utils - /****************************************************************************************\ * exchange-add operation for atomic operations on reference counters * \****************************************************************************************/ diff --git a/modules/core/include/opencv2/core/private.hpp b/modules/core/include/opencv2/core/private.hpp index 58d78e5848..4f9f487778 100644 --- a/modules/core/include/opencv2/core/private.hpp +++ b/modules/core/include/opencv2/core/private.hpp @@ -136,14 +136,6 @@ namespace cv /* the alignment of all the allocated buffers */ #define CV_MALLOC_ALIGN 16 -#ifdef __GNUC__ -# define CV_DECL_ALIGNED(x) __attribute__ ((aligned (x))) -#elif defined _MSC_VER -# define CV_DECL_ALIGNED(x) __declspec(align(x)) -#else -# define CV_DECL_ALIGNED(x) -#endif - /* IEEE754 constants and macros */ #define CV_TOGGLE_FLT(x) ((x)^((int)(x) < 0 ? 0x7fffffff : 0)) #define CV_TOGGLE_DBL(x) ((x)^((int64)(x) < 0 ? CV_BIG_INT(0x7fffffffffffffff) : 0)) diff --git a/modules/core/include/opencv2/core/types_c.h b/modules/core/include/opencv2/core/types_c.h index 16e613053d..cb39587a9a 100644 --- a/modules/core/include/opencv2/core/types_c.h +++ b/modules/core/include/opencv2/core/types_c.h @@ -113,22 +113,6 @@ bytes of the header. In C++ interface the role of CvArr is played by InputArray */ typedef void CvArr; -typedef union Cv32suf -{ - int i; - unsigned u; - float f; -} -Cv32suf; - -typedef union Cv64suf -{ - int64 i; - uint64 u; - double f; -} -Cv64suf; - typedef int CVStatus; /** @see cv::Error::Code */ diff --git a/modules/hal/include/opencv2/hal.hpp b/modules/hal/include/opencv2/hal.hpp index d0e1350803..7641c46cad 100644 --- a/modules/hal/include/opencv2/hal.hpp +++ b/modules/hal/include/opencv2/hal.hpp @@ -55,7 +55,7 @@ namespace cv { namespace hal { namespace Error { -enum Code +enum { Ok = 0, Unknown = -1 @@ -63,11 +63,46 @@ enum Code } -Error::Code normHamming(const uchar* a, int n, int & result); -Error::Code normHamming(const uchar* a, const uchar* b, int n, int & result); +int normHamming(const uchar* a, int n); +int normHamming(const uchar* a, const uchar* b, int n); -Error::Code normHamming(const uchar* a, int n, int cellSize, int & result); -Error::Code normHamming(const uchar* a, const uchar* b, int n, int cellSize, int & result); +int normHamming(const uchar* a, int n, int cellSize); +int normHamming(const uchar* a, const uchar* b, int n, int cellSize); + +//////////////////////////////// low-level functions //////////////////////////////// + +int LU(float* A, size_t astep, int m, float* b, size_t bstep, int n); +int LU(double* A, size_t astep, int m, double* b, size_t bstep, int n); +bool Cholesky(float* A, size_t astep, int m, float* b, size_t bstep, int n); +bool Cholesky(double* A, size_t astep, int m, double* b, size_t bstep, int n); + +int normL1_(const uchar* a, const uchar* b, int n); +float normL1_(const float* a, const float* b, int n); +float normL2Sqr_(const float* a, const float* b, int n); + +void exp(const float* src, float* dst, int n); +void log(const float* src, float* dst, int n); + +void fastAtan2(const float* y, const float* x, float* dst, int n, bool angleInDegrees); +void magnitude(const float* x, const float* y, float* dst, int n); + +/** @brief Computes the cube root of an argument. + + The function cubeRoot computes \f$\sqrt[3]{\texttt{val}}\f$. Negative arguments are handled correctly. + NaN and Inf are not handled. The accuracy approaches the maximum possible accuracy for + single-precision data. + @param val A function argument. + */ +float cubeRoot(float val); + +/** @brief Calculates the angle of a 2D vector in degrees. + + The function fastAtan2 calculates the full-range angle of an input 2D vector. The angle is measured + in degrees and varies from 0 to 360 degrees. The accuracy is about 0.3 degrees. + @param x x-coordinate of the vector. + @param y y-coordinate of the vector. + */ +float fastAtan2(float y, float x); }} //cv::hal diff --git a/modules/hal/include/opencv2/hal/defs.h b/modules/hal/include/opencv2/hal/defs.h index 96595961f0..6e1ff2a0ad 100644 --- a/modules/hal/include/opencv2/hal/defs.h +++ b/modules/hal/include/opencv2/hal/defs.h @@ -1,3 +1,4 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// // // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. // @@ -48,6 +49,8 @@ # define _CRT_SECURE_NO_DEPRECATE /* to avoid multiple Visual Studio warnings */ #endif +#include + #if defined __ICL # define CV_ICC __ICL #elif defined __ICC @@ -60,12 +63,30 @@ # define CV_ICC __INTEL_COMPILER #endif +#ifndef CV_INLINE +# if defined __cplusplus +# define CV_INLINE static inline +# elif defined _MSC_VER +# define CV_INLINE __inline +# else +# define CV_INLINE static +# endif +#endif + #if defined CV_ICC && !defined CV_ENABLE_UNROLLED # define CV_ENABLE_UNROLLED 0 #else # define CV_ENABLE_UNROLLED 1 #endif +#ifdef __GNUC__ +# define CV_DECL_ALIGNED(x) __attribute__ ((aligned (x))) +#elif defined _MSC_VER +# define CV_DECL_ALIGNED(x) __declspec(align(x)) +#else +# define CV_DECL_ALIGNED(x) +#endif + /* CPU features and intrinsics support */ #define CV_CPU_NONE 0 #define CV_CPU_MMX 1 @@ -99,7 +120,7 @@ // do not include SSE/AVX/NEON headers for NVCC compiler #ifndef __CUDACC__ -#if defined __SSE2__ || defined _M_X64 || (defined _M_IX86_FP && _M_IX86_FP >= 2) +#if defined __SSE2__ || defined _M_X64 || (defined _M_IX86_FP && _M_IX86_FP >= 2) # include # define CV_MMX 1 # define CV_SSE 1 @@ -281,4 +302,372 @@ typedef signed char schar; #define CV_2PI 6.283185307179586476925286766559 #define CV_LOG2 0.69314718055994530941723212145818 +typedef union Cv32suf +{ + int i; + unsigned u; + float f; +} +Cv32suf; + +typedef union Cv64suf +{ + int64 i; + uint64 u; + double f; +} +Cv64suf; + + +/****************************************************************************************\ +* fast math * +\****************************************************************************************/ + +#if defined __BORLANDC__ +# include +#elif defined __cplusplus +# include +#else +# include +#endif + +#ifdef HAVE_TEGRA_OPTIMIZATION +# include "tegra_round.hpp" +#endif + +//! @addtogroup core_utils +//! @{ + +#if CV_VFP + // 1. general scheme + #define ARM_ROUND(_value, _asm_string) \ + int res; \ + float temp; \ + asm(_asm_string : [res] "=r" (res), [temp] "=w" (temp) : [value] "w" (_value)); \ + return res + // 2. version for double + #ifdef __clang__ + #define ARM_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %[value] \n vmov %[res], %[temp]") + #else + #define ARM_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %P[value] \n vmov %[res], %[temp]") + #endif + // 3. version for float + #define ARM_ROUND_FLT(value) ARM_ROUND(value, "vcvtr.s32.f32 %[temp], %[value]\n vmov %[res], %[temp]") +#endif // CV_VFP + +/** @brief Rounds floating-point number to the nearest integer + + @param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the + result is not defined. + */ +CV_INLINE int +cvRound( double value ) +{ +#if ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ \ + && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__) + __m128d t = _mm_set_sd( value ); + return _mm_cvtsd_si32(t); +#elif defined _MSC_VER && defined _M_IX86 + int t; + __asm + { + fld value; + fistp t; + } + return t; +#elif ((defined _MSC_VER && defined _M_ARM) || defined CV_ICC || \ + defined __GNUC__) && defined HAVE_TEGRA_OPTIMIZATION + TEGRA_ROUND_DBL(value); +#elif defined CV_ICC || defined __GNUC__ +# if CV_VFP + ARM_ROUND_DBL(value) +# else + return (int)lrint(value); +# endif +#else + /* it's ok if round does not comply with IEEE754 standard; + the tests should allow +/-1 difference when the tested functions use round */ + return (int)(value + (value >= 0 ? 0.5 : -0.5)); +#endif +} + + +/** @brief Rounds floating-point number to the nearest integer not larger than the original. + + The function computes an integer i such that: + \f[i \le \texttt{value} < i+1\f] + @param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the + result is not defined. + */ +CV_INLINE int cvFloor( double value ) +{ +#if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__) + __m128d t = _mm_set_sd( value ); + int i = _mm_cvtsd_si32(t); + return i - _mm_movemask_pd(_mm_cmplt_sd(t, _mm_cvtsi32_sd(t,i))); +#elif defined __GNUC__ + int i = (int)value; + return i - (i > value); +#else + int i = cvRound(value); + float diff = (float)(value - i); + return i - (diff < 0); +#endif +} + +/** @brief Rounds floating-point number to the nearest integer not larger than the original. + + The function computes an integer i such that: + \f[i \le \texttt{value} < i+1\f] + @param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the + result is not defined. + */ +CV_INLINE int cvCeil( double value ) +{ +#if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__&& !defined __APPLE__)) && !defined(__CUDACC__) + __m128d t = _mm_set_sd( value ); + int i = _mm_cvtsd_si32(t); + return i + _mm_movemask_pd(_mm_cmplt_sd(_mm_cvtsi32_sd(t,i), t)); +#elif defined __GNUC__ + int i = (int)value; + return i + (i < value); +#else + int i = cvRound(value); + float diff = (float)(i - value); + return i + (diff < 0); +#endif +} + +/** @brief Determines if the argument is Not A Number. + + @param value The input floating-point value + + The function returns 1 if the argument is Not A Number (as defined by IEEE754 standard), 0 + otherwise. */ +CV_INLINE int cvIsNaN( double value ) +{ + Cv64suf ieee754; + ieee754.f = value; + return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) + + ((unsigned)ieee754.u != 0) > 0x7ff00000; +} + +/** @brief Determines if the argument is Infinity. + + @param value The input floating-point value + + The function returns 1 if the argument is a plus or minus infinity (as defined by IEEE754 standard) + and 0 otherwise. */ +CV_INLINE int cvIsInf( double value ) +{ + Cv64suf ieee754; + ieee754.f = value; + return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 && + (unsigned)ieee754.u == 0; +} + +#ifdef __cplusplus + +/** @overload */ +CV_INLINE int cvRound(float value) +{ +#if ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ && \ + defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__) + __m128 t = _mm_set_ss( value ); + return _mm_cvtss_si32(t); +#elif defined _MSC_VER && defined _M_IX86 + int t; + __asm + { + fld value; + fistp t; + } + return t; +#elif ((defined _MSC_VER && defined _M_ARM) || defined CV_ICC || \ + defined __GNUC__) && defined HAVE_TEGRA_OPTIMIZATION + TEGRA_ROUND_FLT(value); +#elif defined CV_ICC || defined __GNUC__ +# if CV_VFP + ARM_ROUND_FLT(value) +# else + return (int)lrintf(value); +# endif +#else + /* it's ok if round does not comply with IEEE754 standard; + the tests should allow +/-1 difference when the tested functions use round */ + return (int)(value + (value >= 0 ? 0.5f : -0.5f)); +#endif +} + +/** @overload */ +CV_INLINE int cvRound( int value ) +{ + return value; +} + +/** @overload */ +CV_INLINE int cvFloor( float value ) +{ +#if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__) + __m128 t = _mm_set_ss( value ); + int i = _mm_cvtss_si32(t); + return i - _mm_movemask_ps(_mm_cmplt_ss(t, _mm_cvtsi32_ss(t,i))); +#elif defined __GNUC__ + int i = (int)value; + return i - (i > value); +#else + int i = cvRound(value); + float diff = (float)(value - i); + return i - (diff < 0); +#endif +} + +/** @overload */ +CV_INLINE int cvFloor( int value ) +{ + return value; +} + +/** @overload */ +CV_INLINE int cvCeil( float value ) +{ +#if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__&& !defined __APPLE__)) && !defined(__CUDACC__) + __m128 t = _mm_set_ss( value ); + int i = _mm_cvtss_si32(t); + return i + _mm_movemask_ps(_mm_cmplt_ss(_mm_cvtsi32_ss(t,i), t)); +#elif defined __GNUC__ + int i = (int)value; + return i + (i < value); +#else + int i = cvRound(value); + float diff = (float)(i - value); + return i + (diff < 0); +#endif +} + +/** @overload */ +CV_INLINE int cvCeil( int value ) +{ + return value; +} + +/** @overload */ +CV_INLINE int cvIsNaN( float value ) +{ + Cv32suf ieee754; + ieee754.f = value; + return (ieee754.u & 0x7fffffff) > 0x7f800000; +} + +/** @overload */ +CV_INLINE int cvIsInf( float value ) +{ + Cv32suf ieee754; + ieee754.f = value; + return (ieee754.u & 0x7fffffff) == 0x7f800000; +} + +#include + +namespace cv +{ + +/////////////// saturate_cast (used in image & signal processing) /////////////////// + +/** + Template function for accurate conversion from one primitive type to another. + + The functions saturate_cast resemble the standard C++ cast operations, such as static_cast\() + and others. They perform an efficient and accurate conversion from one primitive type to another + (see the introduction chapter). saturate in the name means that when the input value v is out of the + range of the target type, the result is not formed just by taking low bits of the input, but instead + the value is clipped. For example: + @code + uchar a = saturate_cast(-100); // a = 0 (UCHAR_MIN) + short b = saturate_cast(33333.33333); // b = 32767 (SHRT_MAX) + @endcode + Such clipping is done when the target type is unsigned char , signed char , unsigned short or + signed short . For 32-bit integers, no clipping is done. + + When the parameter is a floating-point value and the target type is an integer (8-, 16- or 32-bit), + the floating-point value is first rounded to the nearest integer and then clipped if needed (when + the target type is 8- or 16-bit). + + This operation is used in the simplest or most complex image processing functions in OpenCV. + + @param v Function parameter. + @sa add, subtract, multiply, divide, Mat::convertTo + */ +template static inline _Tp saturate_cast(uchar v) { return _Tp(v); } +/** @overload */ +template static inline _Tp saturate_cast(schar v) { return _Tp(v); } +/** @overload */ +template static inline _Tp saturate_cast(ushort v) { return _Tp(v); } +/** @overload */ +template static inline _Tp saturate_cast(short v) { return _Tp(v); } +/** @overload */ +template static inline _Tp saturate_cast(unsigned v) { return _Tp(v); } +/** @overload */ +template static inline _Tp saturate_cast(int v) { return _Tp(v); } +/** @overload */ +template static inline _Tp saturate_cast(float v) { return _Tp(v); } +/** @overload */ +template static inline _Tp saturate_cast(double v) { return _Tp(v); } +/** @overload */ +template static inline _Tp saturate_cast(int64 v) { return _Tp(v); } +/** @overload */ +template static inline _Tp saturate_cast(uint64 v) { return _Tp(v); } + +//! @cond IGNORED + +template<> inline uchar saturate_cast(schar v) { return (uchar)std::max((int)v, 0); } +template<> inline uchar saturate_cast(ushort v) { return (uchar)std::min((unsigned)v, (unsigned)UCHAR_MAX); } +template<> inline uchar saturate_cast(int v) { return (uchar)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); } +template<> inline uchar saturate_cast(short v) { return saturate_cast((int)v); } +template<> inline uchar saturate_cast(unsigned v) { return (uchar)std::min(v, (unsigned)UCHAR_MAX); } +template<> inline uchar saturate_cast(float v) { int iv = cvRound(v); return saturate_cast(iv); } +template<> inline uchar saturate_cast(double v) { int iv = cvRound(v); return saturate_cast(iv); } +template<> inline uchar saturate_cast(int64 v) { return (uchar)((uint64)v <= (uint64)UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); } +template<> inline uchar saturate_cast(uint64 v) { return (uchar)std::min(v, (uint64)UCHAR_MAX); } + +template<> inline schar saturate_cast(uchar v) { return (schar)std::min((int)v, SCHAR_MAX); } +template<> inline schar saturate_cast(ushort v) { return (schar)std::min((unsigned)v, (unsigned)SCHAR_MAX); } +template<> inline schar saturate_cast(int v) { return (schar)((unsigned)(v-SCHAR_MIN) <= (unsigned)UCHAR_MAX ? v : v > 0 ? SCHAR_MAX : SCHAR_MIN); } +template<> inline schar saturate_cast(short v) { return saturate_cast((int)v); } +template<> inline schar saturate_cast(unsigned v) { return (schar)std::min(v, (unsigned)SCHAR_MAX); } +template<> inline schar saturate_cast(float v) { int iv = cvRound(v); return saturate_cast(iv); } +template<> inline schar saturate_cast(double v) { int iv = cvRound(v); return saturate_cast(iv); } +template<> inline schar saturate_cast(int64 v) { return (schar)((uint64)((int64)v-SCHAR_MIN) <= (uint64)UCHAR_MAX ? v : v > 0 ? SCHAR_MAX : SCHAR_MIN); } +template<> inline schar saturate_cast(uint64 v) { return (schar)std::min(v, (uint64)SCHAR_MAX); } + +template<> inline ushort saturate_cast(schar v) { return (ushort)std::max((int)v, 0); } +template<> inline ushort saturate_cast(short v) { return (ushort)std::max((int)v, 0); } +template<> inline ushort saturate_cast(int v) { return (ushort)((unsigned)v <= (unsigned)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); } +template<> inline ushort saturate_cast(unsigned v) { return (ushort)std::min(v, (unsigned)USHRT_MAX); } +template<> inline ushort saturate_cast(float v) { int iv = cvRound(v); return saturate_cast(iv); } +template<> inline ushort saturate_cast(double v) { int iv = cvRound(v); return saturate_cast(iv); } +template<> inline ushort saturate_cast(int64 v) { return (ushort)((uint64)v <= (uint64)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); } +template<> inline ushort saturate_cast(uint64 v) { return (ushort)std::min(v, (uint64)USHRT_MAX); } + +template<> inline short saturate_cast(ushort v) { return (short)std::min((int)v, SHRT_MAX); } +template<> inline short saturate_cast(int v) { return (short)((unsigned)(v - SHRT_MIN) <= (unsigned)USHRT_MAX ? v : v > 0 ? SHRT_MAX : SHRT_MIN); } +template<> inline short saturate_cast(unsigned v) { return (short)std::min(v, (unsigned)SHRT_MAX); } +template<> inline short saturate_cast(float v) { int iv = cvRound(v); return saturate_cast(iv); } +template<> inline short saturate_cast(double v) { int iv = cvRound(v); return saturate_cast(iv); } +template<> inline short saturate_cast(int64 v) { return (short)((uint64)((int64)v - SHRT_MIN) <= (uint64)USHRT_MAX ? v : v > 0 ? SHRT_MAX : SHRT_MIN); } +template<> inline short saturate_cast(uint64 v) { return (short)std::min(v, (uint64)SHRT_MAX); } + +template<> inline int saturate_cast(float v) { return cvRound(v); } +template<> inline int saturate_cast(double v) { return cvRound(v); } + +// we intentionally do not clip negative numbers, to make -1 become 0xffffffff etc. +template<> inline unsigned saturate_cast(float v) { return cvRound(v); } +template<> inline unsigned saturate_cast(double v) { return cvRound(v); } + +//! @endcond + +} + +#endif // __cplusplus + #endif //__OPENCV_HAL_H__ diff --git a/modules/hal/include/opencv2/hal/intrin.hpp b/modules/hal/include/opencv2/hal/intrin.hpp new file mode 100644 index 0000000000..b7b147a199 --- /dev/null +++ b/modules/hal/include/opencv2/hal/intrin.hpp @@ -0,0 +1,2254 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Copyright (C) 2015, Itseez Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_HAL_INTRIN_HPP__ +#define __OPENCV_HAL_INTRIN_HPP__ + +#include +#include +#include + +#define OPENCV_HAL_ADD(a, b) ((a) + (b)) +#define OPENCV_HAL_AND(a, b) ((a) & (b)) +#define OPENCV_HAL_NOP(a) (a) +#define OPENCV_HAL_1ST(a, b) (a) + +namespace cv { namespace hal { + +template struct TypeTraits +{ + typedef _Tp int_type; + typedef _Tp uint_type; + typedef _Tp abs_type; + typedef _Tp sum_type; + + enum { delta = 0, shift = 0 }; + + static int_type reinterpret_int(_Tp x) { return x; } + static uint_type reinterpet_uint(_Tp x) { return x; } + static _Tp reinterpret_from_int(int_type x) { return (_Tp)x; } +}; + +template<> struct TypeTraits +{ + typedef uchar value_type; + typedef schar int_type; + typedef uchar uint_type; + typedef uchar abs_type; + typedef int sum_type; + + typedef ushort w_type; + + enum { delta = 128, shift = 8 }; + + static int_type reinterpret_int(value_type x) { return (int_type)x; } + static uint_type reinterpret_uint(value_type x) { return (uint_type)x; } + static value_type reinterpret_from_int(int_type x) { return (value_type)x; } +}; + +template<> struct TypeTraits +{ + typedef schar value_type; + typedef schar int_type; + typedef uchar uint_type; + typedef uchar abs_type; + typedef int sum_type; + + typedef short w_type; + + enum { delta = 128, shift = 8 }; + + static int_type reinterpret_int(value_type x) { return (int_type)x; } + static uint_type reinterpret_uint(value_type x) { return (uint_type)x; } + static value_type reinterpret_from_int(int_type x) { return (value_type)x; } +}; + +template<> struct TypeTraits +{ + typedef ushort value_type; + typedef short int_type; + typedef ushort uint_type; + typedef ushort abs_type; + typedef int sum_type; + + typedef unsigned w_type; + typedef uchar nu_type; + + enum { delta = 32768, shift = 16 }; + + static int_type reinterpret_int(value_type x) { return (int_type)x; } + static uint_type reinterpret_uint(value_type x) { return (uint_type)x; } + static value_type reinterpret_from_int(int_type x) { return (value_type)x; } +}; + +template<> struct TypeTraits +{ + typedef short value_type; + typedef short int_type; + typedef ushort uint_type; + typedef ushort abs_type; + typedef int sum_type; + + typedef int w_type; + typedef uchar nu_type; + typedef schar n_type; + + enum { delta = 128, shift = 8 }; + + static int_type reinterpret_int(value_type x) { return (int_type)x; } + static uint_type reinterpret_uint(value_type x) { return (uint_type)x; } + static value_type reinterpret_from_int(int_type x) { return (value_type)x; } +}; + +template<> struct TypeTraits +{ + typedef unsigned value_type; + typedef int int_type; + typedef unsigned uint_type; + typedef unsigned abs_type; + typedef unsigned sum_type; + + typedef ushort nu_type; + + static int_type reinterpret_int(value_type x) { return (int_type)x; } + static uint_type reinterpret_uint(value_type x) { return (uint_type)x; } + static value_type reinterpret_from_int(int_type x) { return (value_type)x; } +}; + +template<> struct TypeTraits +{ + typedef int value_type; + typedef int int_type; + typedef unsigned uint_type; + typedef unsigned abs_type; + typedef int sum_type; + + typedef short n_type; + typedef ushort nu_type; + + static int_type reinterpret_int(value_type x) { return (int_type)x; } + static uint_type reinterpret_uint(value_type x) { return (uint_type)x; } + static value_type reinterpret_from_int(int_type x) { return (value_type)x; } +}; + +template<> struct TypeTraits +{ + typedef float value_type; + typedef int int_type; + typedef unsigned uint_type; + typedef float abs_type; + typedef float sum_type; + + typedef double w_type; + + static int_type reinterpret_int(value_type x) + { + Cv32suf u; + u.f = x; + return u.i; + } + static uint_type reinterpet_uint(value_type x) + { + Cv32suf u; + u.f = x; + return u.u; + } + static value_type reinterpret_from_int(int_type x) + { + Cv32suf u; + u.i = x; + return u.f; + } +}; + +template<> struct TypeTraits +{ + typedef double value_type; + typedef int64 int_type; + typedef uint64 uint_type; + typedef double abs_type; + typedef double sum_type; + static int_type reinterpret_int(value_type x) + { + Cv64suf u; + u.f = x; + return u.i; + } + static uint_type reinterpet_uint(value_type x) + { + Cv64suf u; + u.f = x; + return u.u; + } + static value_type reinterpret_from_int(int_type x) + { + Cv64suf u; + u.i = x; + return u.f; + } +}; + +template struct v_reg +{ + typedef _Tp scalar_type; + typedef v_reg::int_type, n> int_vec; + typedef v_reg::abs_type, n> abs_vec; + enum { channels = n }; + + explicit v_reg(const _Tp* ptr) { for( int i = 0; i < n; i++ ) s[i] = ptr[i]; } + v_reg(_Tp s0, _Tp s1) { s[0] = s0; s[1] = s1; } + v_reg(_Tp s0, _Tp s1, _Tp s2, _Tp s3) { s[0] = s0; s[1] = s1; s[2] = s2; s[3] = s3; } + v_reg(_Tp s0, _Tp s1, _Tp s2, _Tp s3, + _Tp s4, _Tp s5, _Tp s6, _Tp s7) + { + s[0] = s0; s[1] = s1; s[2] = s2; s[3] = s3; + s[4] = s4; s[5] = s5; s[6] = s6; s[7] = s7; + } + v_reg(_Tp s0, _Tp s1, _Tp s2, _Tp s3, + _Tp s4, _Tp s5, _Tp s6, _Tp s7, + _Tp s8, _Tp s9, _Tp s10, _Tp s11, + _Tp s12, _Tp s13, _Tp s14, _Tp s15) + { + s[0] = s0; s[1] = s1; s[2] = s2; s[3] = s3; + s[4] = s4; s[5] = s5; s[6] = s6; s[7] = s7; + s[8] = s8; s[9] = s9; s[10] = s10; s[11] = s11; + s[12] = s12; s[13] = s13; s[14] = s14; s[15] = s15; + } + + v_reg() {} + v_reg(const v_reg<_Tp, n> & r) + { + for( int i = 0; i < n; i++ ) + s[i] = r.s[i]; + } + + _Tp get(const int i) const { return s[i]; } + _Tp get0() const { return s[0]; } + v_reg<_Tp, n> high() const + { + v_reg<_Tp, n> c; + int i; + for( i = 0; i < n/2; i++ ) + { + c.s[i] = s[i+(n/2)]; + c.s[i+(n/2)] = 0; + } + return c; + } + + static v_reg<_Tp, n> zero() + { + v_reg<_Tp, n> c; + for( int i = 0; i < n; i++ ) + c.s[i] = (_Tp)0; + return c; + } + + static v_reg<_Tp, n> all(_Tp s) + { + v_reg<_Tp, n> c; + for( int i = 0; i < n; i++ ) + c.s[i] = s; + return c; + } + + template static v_reg<_Tp2, n2> reinterpret_as(const v_reg<_Tp, n>& a) + { + size_t bytes = std::min(sizeof(_Tp2)*n2, sizeof(_Tp)*n); + v_reg<_Tp2, n2> c; + memcpy(&c.s[0], &a.s[0], bytes); + return c; + } + + _Tp s[n]; +}; + +#define OPENCV_HAL_IMPL_BIN_OP(bin_op) \ +template inline v_reg<_Tp, n> operator bin_op (const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ +{ \ + v_reg<_Tp, n> c; \ + for( int i = 0; i < n; i++ ) \ + c.s[i] = saturate_cast<_Tp>(a.s[i] bin_op b.s[i]); \ + return c; \ +} \ +template inline v_reg<_Tp, n>& operator bin_op##= (v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ +{ \ + for( int i = 0; i < n; i++ ) \ + a.s[i] = saturate_cast<_Tp>(a.s[i] bin_op b.s[i]); \ + return a; \ +} + +OPENCV_HAL_IMPL_BIN_OP(+) +OPENCV_HAL_IMPL_BIN_OP(-) +OPENCV_HAL_IMPL_BIN_OP(*) +OPENCV_HAL_IMPL_BIN_OP(/) + +#define OPENCV_HAL_IMPL_BIT_OP(bit_op) \ +template inline v_reg<_Tp, n> operator bit_op (const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ +{ \ + v_reg<_Tp, n> c; \ + typedef typename TypeTraits<_Tp>::int_type itype; \ + for( int i = 0; i < n; i++ ) \ + c.s[i] = TypeTraits<_Tp>::reinterpret_from_int((itype)(TypeTraits<_Tp>::reinterpret_int(a.s[i]) bit_op \ + TypeTraits<_Tp>::reinterpret_int(b.s[i]))); \ + return c; \ +} \ +template inline v_reg<_Tp, n>& operator bit_op##= (v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ +{ \ + typedef typename TypeTraits<_Tp>::int_type itype; \ + for( int i = 0; i < n; i++ ) \ + a.s[i] = TypeTraits<_Tp>::reinterpret_from_int((itype)(TypeTraits<_Tp>::reinterpret_int(a.s[i]) bit_op \ + TypeTraits<_Tp>::reinterpret_int(b.s[i]))); \ + return a; \ +} + +OPENCV_HAL_IMPL_BIT_OP(&) +OPENCV_HAL_IMPL_BIT_OP(|) +OPENCV_HAL_IMPL_BIT_OP(^) + +template inline v_reg<_Tp, n> operator ~ (const v_reg<_Tp, n>& a) +{ + v_reg<_Tp, n> c; + typedef typename TypeTraits<_Tp>::int_type itype; + for( int i = 0; i < n; i++ ) + c.s[i] = TypeTraits<_Tp>::reinterpret_from_int(~TypeTraits<_Tp>::reinterpret_int(a.s[i])); + return c; +} + +#define OPENCV_HAL_IMPL_MATH_FUNC(func, cfunc, _Tp2) \ +template inline v_reg<_Tp2, n> func(const v_reg<_Tp, n>& a) \ +{ \ + v_reg<_Tp2, n> c; \ + for( int i = 0; i < n; i++ ) \ + c.s[i] = cfunc(a.s[i]); \ + return c; \ +} + +OPENCV_HAL_IMPL_MATH_FUNC(v_sqrt, std::sqrt, _Tp) +OPENCV_HAL_IMPL_MATH_FUNC(v_sin, std::sin, _Tp) +OPENCV_HAL_IMPL_MATH_FUNC(v_cos, std::cos, _Tp) +OPENCV_HAL_IMPL_MATH_FUNC(v_exp, std::exp, _Tp) +OPENCV_HAL_IMPL_MATH_FUNC(v_log, std::log, _Tp) +OPENCV_HAL_IMPL_MATH_FUNC(v_abs, (typename TypeTraits<_Tp>::abs_type)std::abs, typename TypeTraits<_Tp>::abs_type) +OPENCV_HAL_IMPL_MATH_FUNC(v_round, cvRound, int) +OPENCV_HAL_IMPL_MATH_FUNC(v_floor, cvFloor, int) +OPENCV_HAL_IMPL_MATH_FUNC(v_ceil, cvCeil, int) +OPENCV_HAL_IMPL_MATH_FUNC(v_trunc, int, int) + +#define OPENCV_HAL_IMPL_MINMAX_FUNC(func, hfunc, cfunc) \ +template inline v_reg<_Tp, n> func(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ +{ \ + v_reg<_Tp, n> c; \ + for( int i = 0; i < n; i++ ) \ + c.s[i] = cfunc(a.s[i], b.s[i]); \ + return c; \ +} \ +template inline _Tp hfunc(const v_reg<_Tp, n>& a) \ +{ \ + _Tp c = a.s[0]; \ + for( int i = 1; i < n; i++ ) \ + c = cfunc(c, a.s[i]); \ + return c; \ +} + +OPENCV_HAL_IMPL_MINMAX_FUNC(v_min, v_reduce_min, std::min) +OPENCV_HAL_IMPL_MINMAX_FUNC(v_max, v_reduce_max, std::max) + +template inline void v_minmax(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b, + v_reg<_Tp, n>& minval, v_reg<_Tp, n>& maxval) +{ + for( int i = 0; i < n; i++ ) + { + minval.s[i] = std::min(a.s[i], b.s[i]); + maxval.s[i] = std::max(a.s[i], b.s[i]); + } +} + + +#define OPENCV_HAL_IMPL_CMP_OP(cmp_op) \ +template inline v_reg<_Tp, n> \ + operator cmp_op(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ +{ \ + typedef typename TypeTraits<_Tp>::int_type itype; \ + v_reg<_Tp, n> c; \ + for( int i = 0; i < n; i++ ) \ + c.s[i] = TypeTraits<_Tp>::reinterpret_from_int((itype)-(int)(a.s[i] cmp_op b.s[i])); \ + return c; \ +} + +OPENCV_HAL_IMPL_CMP_OP(<) +OPENCV_HAL_IMPL_CMP_OP(>) +OPENCV_HAL_IMPL_CMP_OP(<=) +OPENCV_HAL_IMPL_CMP_OP(>=) +OPENCV_HAL_IMPL_CMP_OP(==) +OPENCV_HAL_IMPL_CMP_OP(!=) + +#define OPENCV_HAL_IMPL_ADDSUB_OP(func, bin_op, cast_op, _Tp2) \ +template inline v_reg<_Tp2, n> func(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ +{ \ + typedef _Tp2 rtype; \ + v_reg c; \ + for( int i = 0; i < n; i++ ) \ + c.s[i] = cast_op(a.s[i] bin_op b.s[i]); \ + return c; \ +} + +OPENCV_HAL_IMPL_ADDSUB_OP(v_add_wrap, +, (_Tp), _Tp) +OPENCV_HAL_IMPL_ADDSUB_OP(v_sub_wrap, -, (_Tp), _Tp) +OPENCV_HAL_IMPL_ADDSUB_OP(v_absdiff, -, (rtype)std::abs, typename TypeTraits<_Tp>::abs_type) + +template inline v_reg<_Tp, n> v_magnitude(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) +{ + v_reg<_Tp, n> c; + for( int i = 0; i < n; i++ ) + c.s[i] = std::sqrt(a.s[i]*a.s[i] + b.s[i]*b.s[i]); + return c; +} + +template inline v_reg<_Tp, n> v_sqr_magnitude(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) +{ + v_reg<_Tp, n> c; + for( int i = 0; i < n; i++ ) + c.s[i] = a.s[i]*a.s[i] + b.s[i]*b.s[i]; + return c; +} + +template inline v_reg<_Tp, n> v_muladd(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b, + const v_reg<_Tp, n>& c) +{ + v_reg<_Tp, n> d; + for( int i = 0; i < n; i++ ) + d.s[i] = a.s[i]*b.s[i] + c.s[i]; + return d; +} + +template inline v_reg<_Tp, n> v_mullo(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) +{ + v_reg<_Tp, n> c; + for( int i = 0; i < n; i++ ) + c.s[i] = (_Tp)(a.s[i]*b.s[i]); + return c; +} + +template inline v_reg<_Tp, n> v_mulhi2(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) +{ + v_reg<_Tp, n> c; + for( int i = 0; i < n; i++ ) + c.s[i] = (_Tp)((a.s[i]*b.s[i]*2 + TypeTraits<_Tp>::delta) >> TypeTraits<_Tp>::shift); + return c; +} + +#define OPENCV_HAL_IMPL_SHIFT_OP(shift_op) \ +template inline v_reg<_Tp, n> operator shift_op(const v_reg<_Tp, n>& a, int imm) \ +{ \ + v_reg<_Tp, n> c; \ + for( int i = 0; i < n; i++ ) \ + c.s[i] = (_Tp)(a.s[i] shift_op imm); \ + return c; \ +} + +OPENCV_HAL_IMPL_SHIFT_OP(<<) +OPENCV_HAL_IMPL_SHIFT_OP(>>) + +template inline typename TypeTraits<_Tp>::sum_type v_reduce_sum(const v_reg<_Tp, n>& a) +{ + typename TypeTraits<_Tp>::sum_type c = a.s[0]; + for( int i = 1; i < n; i++ ) + c += a.s[i]; + return c; +} + +template inline int v_signmask(const v_reg<_Tp, n>& a) +{ + int mask = 0; + for( int i = 0; i < n; i++ ) + mask |= (TypeTraits<_Tp>::reinterpret_int(a.s[i]) < 0) << i; + return mask; +} + +template inline bool v_check_all(const v_reg<_Tp, n>& a) +{ + for( int i = 0; i < n; i++ ) + if( TypeTraits<_Tp>::reinterpret_int(a.s[i]) >= 0 ) + return false; + return true; +} + +template inline bool v_check_any(const v_reg<_Tp, n>& a) +{ + for( int i = 0; i < n; i++ ) + if( TypeTraits<_Tp>::reinterpret_int(a.s[i]) < 0 ) + return true; + return false; +} + +template inline v_reg<_Tp, n> v_select(const v_reg<_Tp, n>& mask, + const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) +{ + v_reg<_Tp, n> c; + for( int i = 0; i < n; i++ ) + c.s[i] = TypeTraits<_Tp>::reinterpret_int(mask.s[i]) < 0 ? b.s[i] : a.s[i]; + return c; +} + +template inline void v_expand(const v_reg<_Tp, n>& a, + v_reg::w_type, n/2>& b0, + v_reg::w_type, n/2>& b1) +{ + for( int i = 0; i < (n/2); i++ ) + { + b0.s[i] = a.s[i]; + b1.s[i] = a.s[i+(n/2)]; + } +} + +template inline v_reg::int_type, n> + v_reinterpret_int(const v_reg<_Tp, n>& a) +{ + v_reg::int_type, n> c; + for( int i = 0; i < n; i++ ) + c.s[i] = TypeTraits<_Tp>::reinterpret_int(a.s[i]); + return c; +} + +template inline v_reg::uint_type, n> + v_reinterpret_uint(const v_reg<_Tp, n>& a) +{ + v_reg::uint_type, n> c; + for( int i = 0; i < n; i++ ) + c.s[i] = TypeTraits<_Tp>::reinterpret_uint(a.s[i]); + return c; +} + +template inline void v_zip( const v_reg<_Tp, n>& a0, const v_reg<_Tp, n>& a1, + v_reg<_Tp, n>& b0, v_reg<_Tp, n>& b1 ) +{ + int i; + for( i = 0; i < n/2; i++ ) + { + b0.s[i*2] = a0.s[i]; + b0.s[i*2+1] = a1.s[i]; + } + for( ; i < n; i++ ) + { + b1.s[i*2-n] = a0.s[i]; + b1.s[i*2-n+1] = a1.s[i]; + } +} + +template inline v_reg<_Tp, n> v_load(const _Tp* ptr) +{ + return v_reg<_Tp, n>(ptr); +} + +template inline v_reg<_Tp, n> v_load_aligned(const _Tp* ptr) +{ + return v_reg<_Tp, n>(ptr); +} + +template inline void v_load_halves(const _Tp* loptr, const _Tp* hiptr) +{ + v_reg<_Tp, n> c; + for( int i = 0; i < n/2; i++ ) + { + c.s[i] = loptr[i]; + c.s[i+n/2] = hiptr[i]; + } + return c; +} + +template inline v_reg::w_type, n> v_load_expand(const _Tp* ptr) +{ + typedef typename TypeTraits<_Tp>::w_type w_type; + v_reg c; + for( int i = 0; i < n; i++ ) + { + c.s[i] = ptr[i]; + } + return c; +} + +template inline v_reg::w_type>::w_type, n> v_load_expand_q(const _Tp* ptr) +{ + typedef typename TypeTraits::w_type>::w_type w_type; + v_reg c; + for( int i = 0; i < n; i++ ) + { + c.s[i] = ptr[i]; + } + return c; +} + +template inline void v_load_deinterleave(const _Tp* ptr, v_reg<_Tp, n>& a, + v_reg<_Tp, n>& b, v_reg<_Tp, n>& c) +{ + int i, i3; + for( i = i3 = 0; i < n; i++, i3 += 3 ) + { + a.s[i] = ptr[i3]; + b.s[i] = ptr[i3+1]; + c.s[i] = ptr[i3+2]; + } +} + +template inline void v_load_deinterleave(const _Tp* ptr, v_reg<_Tp, n>& a, + v_reg<_Tp, n>& b, v_reg<_Tp, n>& c, + v_reg<_Tp, n>& d) +{ + int i, i4; + for( i = i4 = 0; i < n; i++, i4 += 4 ) + { + a.s[i] = ptr[i4]; + b.s[i] = ptr[i4+1]; + c.s[i] = ptr[i4+2]; + d.s[i] = ptr[i4+3]; + } +} + +template inline void v_store_interleave( _Tp* ptr, const v_reg<_Tp, n>& a, + const v_reg<_Tp, n>& b, const v_reg<_Tp, n>& c) +{ + int i, i3; + for( i = i3 = 0; i < n; i++, i3 += 3 ) + { + ptr[i3] = a.s[i]; + ptr[i3+1] = b.s[i]; + ptr[i3+2] = c.s[i]; + } +} + +template inline void v_store_interleave( _Tp* ptr, const v_reg<_Tp, n>& a, + const v_reg<_Tp, n>& b, const v_reg<_Tp, n>& c, + const v_reg<_Tp, n>& d) +{ + int i, i4; + for( i = i4 = 0; i < n; i++, i4 += 4 ) + { + ptr[i4] = a.s[i]; + ptr[i4+1] = b.s[i]; + ptr[i4+2] = c.s[i]; + ptr[i4+3] = d.s[i]; + } +} + +template inline void v_store(_Tp* ptr, const v_reg<_Tp, n>& a) +{ + for( int i = 0; i < n; i++ ) + ptr[i] = a.s[i]; +} + +template inline void v_store_low(_Tp* ptr, const v_reg<_Tp, n>& a) +{ + for( int i = 0; i < (n/2); i++ ) + ptr[i] = a.s[i]; +} + +template inline void v_store_high(_Tp* ptr, const v_reg<_Tp, n>& a) +{ + for( int i = 0; i < (n/2); i++ ) + ptr[i] = a.s[i+(n/2)]; +} + +template inline void v_store_aligned(_Tp* ptr, const v_reg<_Tp, n>& a) +{ + for( int i = 0; i < n; i++ ) + ptr[i] = a.s[i]; +} + +template inline v_reg<_Tp, n> v_combine_low(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) +{ + v_reg<_Tp, n> c; + for( int i = 0; i < (n/2); i++ ) + { + c.s[i] = a.s[i]; + c.s[i+(n/2)] = b.s[i]; + } +} + +template inline v_reg<_Tp, n> v_combine_high(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) +{ + v_reg<_Tp, n> c; + for( int i = 0; i < (n/2); i++ ) + { + c.s[i] = a.s[i+(n/2)]; + c.s[i+(n/2)] = b.s[i+(n/2)]; + } +} + +template inline void v_recombine(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b, + v_reg<_Tp, n>& low, v_reg<_Tp, n>& high) +{ + for( int i = 0; i < (n/2); i++ ) + { + low.s[i] = a.s[i]; + low.s[i+(n/2)] = b.s[i]; + high.s[i] = a.s[i+(n/2)]; + high.s[i+(n/2)] = b.s[i+(n/2)]; + } +} + +template inline v_reg v_round(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + c.s[i] = cvRound(a.s[i]); + return c; +} + +template inline v_reg v_floor(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + c.s[i] = cvFloor(a.s[i]); + return c; +} + +template inline v_reg v_ceil(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + c.s[i] = cvCeil(a.s[i]); + return c; +} + +template inline v_reg v_trunc(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + c.s[i] = (int)(a.s[i]); + return c; +} + +template inline v_reg v_round(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + { + c.s[i] = cvRound(a.s[i]); + c.s[i+n] = 0; + } + return c; +} + +template inline v_reg v_floor(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + { + c.s[i] = cvFloor(a.s[i]); + c.s[i+n] = 0; + } + return c; +} + +template inline v_reg v_ceil(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + { + c.s[i] = cvCeil(a.s[i]); + c.s[i+n] = 0; + } + return c; +} + +template inline v_reg v_trunc(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + { + c.s[i] = cvCeil(a.s[i]); + c.s[i+n] = 0; + } + return c; +} + +template inline v_reg v_cvt_f32(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + c.s[i] = (float)a.s[i]; + return c; +} + +template inline v_reg v_cvt_f64(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + c.s[i] = (double)a.s[i]; + return c; +} + +template inline v_reg v_cvt_f64(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + c.s[i] = (double)a.s[i]; + return c; +} + +template inline v_reg<_Tp2, n*2> v_cvtsat(const v_reg<_Tp, n>& a, + const v_reg<_Tp, n>& b) +{ + v_reg<_Tp2, n*2> c; + for( int i = 0; i < n; i++ ) + { + c.s[i] = saturate_cast<_Tp2>(a.s[i]); + c.s[i+n] = saturate_cast<_Tp2>(b.s[i]); + } + return c; +} + +template inline v_reg<_Tp2, n*2> v_cvtsat(const v_reg<_Tp, n>& a, + const v_reg<_Tp, n>& b, + int rshift) +{ + v_reg<_Tp2, n*2> c; + for( int i = 0; i < n; i++ ) + { + c.s[i] = saturate_cast<_Tp2>((a.s[i] + (1<<(rshift-1))) >> rshift); + c.s[i+n] = saturate_cast<_Tp2>((b.s[i] + (1<<(rshift-1))) >> rshift); + } + return c; +} + +template inline void v_storesat(_Tp2* ptr, const v_reg<_Tp, n>& a) +{ + for( int i = 0; i < n; i++ ) + { + ptr[i] = saturate_cast<_Tp2>(a.s[i]); + } +} + +template inline void v_storesat(_Tp2* ptr, const v_reg<_Tp, n>& a, int rshift) +{ + for( int i = 0; i < n; i++ ) + { + ptr[i] = saturate_cast<_Tp2>((a.s[i] + (1<<(rshift-1))) >> rshift); + } +} + +template inline void v_transpose4x4(const v_reg<_Tp, 4>& a0, const v_reg<_Tp, 4>& a1, + const v_reg<_Tp, 4>& a2, const v_reg<_Tp, 4>& a3, + v_reg<_Tp, 4>& b0, v_reg<_Tp, 4>& b1, + v_reg<_Tp, 4>& b2, v_reg<_Tp, 4>& b3) +{ + b0 = v_reg<_Tp, 4>(a0.s[0], a1.s[0], a2.s[0], a3.s[0]); + b1 = v_reg<_Tp, 4>(a0.s[1], a1.s[1], a2.s[1], a3.s[1]); + b2 = v_reg<_Tp, 4>(a0.s[2], a1.s[2], a2.s[2], a3.s[2]); + b3 = v_reg<_Tp, 4>(a0.s[3], a1.s[3], a2.s[3], a3.s[3]); +} + +#if CV_SSE2 + +#define CV_SIMD128 1 +#define CV_SIMD128_64F 1 + +struct v_uint8x16 +{ + explicit v_uint8x16(__m128i v) : val(v) {} + v_uint8x16(uchar v0, uchar v1, uchar v2, uchar v3, uchar v4, uchar v5, uchar v6, uchar v7, + uchar v8, uchar v9, uchar v10, uchar v11, uchar v12, uchar v13, uchar v14, uchar v15) + { + val = _mm_setr_epi8((char)v0, (char)v1, (char)v2, (char)v3, + (char)v4, (char)v5, (char)v6, (char)v7, + (char)v8, (char)v9, (char)v10, (char)v11, + (char)v12, (char)v13, (char)v14, (char)v15); + } + uchar get(const int i) const + { + return (uchar)(_mm_extract_epi16(val, i/2) >> ((i&1)*8)); + } + uchar get0() const + { + return (uchar)_mm_cvtsi128_si32(val); + } + + __m128i val; +}; + +struct v_int8x16 +{ + explicit v_int8x16(__m128i v) : val(v) {} + v_int8x16(schar v0, schar v1, schar v2, schar v3, schar v4, schar v5, schar v6, schar v7, + schar v8, schar v9, schar v10, schar v11, schar v12, schar v13, schar v14, schar v15) + { + val = _mm_setr_epi8((char)v0, (char)v1, (char)v2, (char)v3, + (char)v4, (char)v5, (char)v6, (char)v7, + (char)v8, (char)v9, (char)v10, (char)v11, + (char)v12, (char)v13, (char)v14, (char)v15); + } + schar get(const int i) const + { + return (schar)(_mm_extract_epi16(val, i/2) >> ((i&1)*8)); + } + schar get0() const + { + return (schar)_mm_cvtsi128_si32(val); + } + + __m128i val; +}; + +struct v_uint16x8 +{ + explicit v_uint16x8(__m128i v) : val(v) {} + v_uint16x8(ushort v0, ushort v1, ushort v2, ushort v3, ushort v4, ushort v5, ushort v6, ushort v7) + { + val = _mm_setr_epi16((short)v0, (short)v1, (short)v2, (short)v3, + (short)v4, (short)v5, (short)v6, (short)v7); + } + ushort get(const int i) const + { + return (ushort)_mm_extract_epi16(val, i); + } + uchar get0() const + { + return (ushort)_mm_cvtsi128_si32(val); + } + + __m128i val; +}; + +struct v_int16x8 +{ + explicit v_int16x8(__m128i v) : val(v) {} + v_int16x8(short v0, short v1, short v2, short v3, short v4, short v5, short v6, short v7) + { + val = _mm_setr_epi16((short)v0, (short)v1, (short)v2, (short)v3, + (short)v4, (short)v5, (short)v6, (short)v7); + } + short get(const int i) const + { + return (short)_mm_extract_epi16(val, i); + } + short get0() const + { + return (short)_mm_cvtsi128_si32(val); + } + __m128i val; +}; + +struct v_uint32x4 +{ + explicit v_uint32x4(__m128i v) : val(v) {} + v_uint32x4(unsigned v0, unsigned v1, unsigned v2, unsigned v3) + { + val = _mm_setr_epi32((int)v0, (int)v1, (int)v2, (int)v3); + } + unsigned get(const int i) const + { + unsigned CV_DECL_ALIGNED(16) buf[4]; + _mm_store_si128((__m128i*)buf, val); + return buf[i]; + } + unsigned get0() const + { + return (unsigned)_mm_cvtsi128_si32(val); + } + __m128i val; +}; + +struct v_int32x4 +{ + explicit v_int32x4(__m128i v) : val(v) {} + v_int32x4(int v0, int v1, int v2, int v3) + { + val = _mm_setr_epi32(v0, v1, v2, v3); + } + int get(int i) const + { + int CV_DECL_ALIGNED(16) buf[4]; + _mm_store_si128((__m128i*)buf, val); + return buf[i]; + } + int get0() const + { + return _mm_cvtsi128_si32(val); + } + __m128i val; +}; + +struct v_float32x4 +{ + explicit v_float32x4(__m128 v) : val(v) {} + v_float32x4(float v0, float v1, float v2, float v3) + { + val = _mm_setr_ps(v0, v1, v2, v3); + } + float get(int i) const + { + float CV_DECL_ALIGNED(16) buf[4]; + _mm_store_ps(buf, val); + return buf[i]; + } + float get0() const + { + return _mm_cvtss_f32(val); + } + __m128 val; +}; + +struct v_float64x2 +{ + explicit v_float64x2(__m128d v) : val(v) {} + v_float64x2(double v0, double v1) + { + val = _mm_setr_pd(v0, v1); + } + double get(int i) const + { + double CV_DECL_ALIGNED(16) buf[2]; + _mm_store_pd(buf, val); + return buf[i]; + } + double get0() const + { + return _mm_cvtsd_f64(val); + } + __m128d val; +}; + +inline v_uint8x16 v_setzero_u8() { return v_uint8x16(_mm_setzero_si128()); } +inline v_int8x16 v_setzero_s8() { return v_int8x16(_mm_setzero_si128()); } +inline v_uint16x8 v_setzero_u16() { return v_uint16x8(_mm_setzero_si128()); } +inline v_int16x8 v_setzero_s16() { return v_int16x8(_mm_setzero_si128()); } +inline v_uint32x4 v_setzero_u32() { return v_uint32x4(_mm_setzero_si128()); } +inline v_int32x4 v_setzero_s32() { return v_int32x4(_mm_setzero_si128()); } +inline v_float32x4 v_setzero_f32() { return v_float32x4(_mm_setzero_ps()); } +inline v_float64x2 v_setzero_f64() { return v_float64x2(_mm_setzero_pd()); } + +inline v_uint8x16 v_setall_u8(uchar v) { return v_uint8x16(_mm_set1_epi8((char)v)); } +inline v_int8x16 v_setall_s8(schar v) { return v_int8x16(_mm_set1_epi8((char)v)); } +inline v_uint16x8 v_setall_u16(ushort v) { return v_uint16x8(_mm_set1_epi16((short)v)); } +inline v_int16x8 v_setall_s16(short v) { return v_int16x8(_mm_set1_epi16((short)v)); } +inline v_uint32x4 v_setall_u32(unsigned v) { return v_uint32x4(_mm_set1_epi32((int)v)); } +inline v_int32x4 v_setall_s32(int v) { return v_int32x4(_mm_set1_epi32(v)); } +inline v_float32x4 v_setall_f32(float v) { return v_float32x4(_mm_set1_ps(v)); } +inline v_float64x2 v_setall_f64(double v) { return v_float64x2(_mm_set1_pd(v)); } + +template inline v_uint8x16 v_reinterpret_u8(const _Tpvec& a) +{ return v_uint8x16(a.val); } + +inline v_uint8x16 v_reinterpret_u8(const v_float32x4& a) +{ return v_uint8x16(_mm_castps_si128(a.val)); } + +inline v_uint8x16 v_reinterpret_u8(const v_float64x2& a) +{ return v_uint8x16(_mm_castpd_si128(a.val)); } + +template inline v_int8x16 v_reinterpret_s8(const _Tpvec& a) +{ return v_int8x16(a.val); } + +inline v_int8x16 v_reinterpret_s8(const v_float32x4& a) +{ return v_int8x16(_mm_castps_si128(a.val)); } + +inline v_int8x16 v_reinterpret_s8(const v_float64x2& a) +{ return v_int8x16(_mm_castpd_si128(a.val)); } + +template inline v_uint16x8 v_reinterpret_u16(const _Tpvec& a) +{ return v_uint16x8(a.val); } + +inline v_uint16x8 v_reinterpret_u16(const v_float32x4& a) +{ return v_uint16x8(_mm_castps_si128(a.val)); } + +inline v_uint16x8 v_reinterpret_u16(const v_float64x2& a) +{ return v_uint16x8(_mm_castpd_si128(a.val)); } + +template inline v_int16x8 v_reinterpret_s16(const _Tpvec& a) +{ return v_int16x8(a.val); } + +inline v_int16x8 v_reinterpret_s16(const v_float32x4& a) +{ return v_int16x8(_mm_castps_si128(a.val)); } + +inline v_int16x8 v_reinterpret_s16(const v_float64x2& a) +{ return v_int16x8(_mm_castpd_si128(a.val)); } + +template inline v_uint32x4 v_reinterpret_u32(const _Tpvec& a) +{ return v_uint32x4(a.val); } + +inline v_uint32x4 v_reinterpret_u32(const v_float32x4& a) +{ return v_uint32x4(_mm_castps_si128(a.val)); } + +inline v_uint32x4 v_reinterpret_u32(const v_float64x2& a) +{ return v_uint32x4(_mm_castpd_si128(a.val)); } + +template inline v_int32x4 v_reinterpret_s32(const _Tpvec& a) +{ return v_int32x4(a.val); } + +inline v_int32x4 v_reinterpret_s32(const v_float32x4& a) +{ return v_int32x4(_mm_castps_si128(a.val)); } + +inline v_int32x4 v_reinterpret_s32(const v_float64x2& a) +{ return v_int32x4(_mm_castpd_si128(a.val)); } + +template inline v_float32x4 v_reinterpret_f32(const _Tpvec& a) +{ return v_float32x4(_mm_castsi128_ps(a.val)); } + +inline v_float32x4 v_reinterpret_f32(const v_float64x2& a) +{ return v_float32x4(_mm_castpd_ps(a.val)); } + +template inline v_float64x2 v_reinterpret_f64(const _Tpvec& a) +{ return v_float64x2(_mm_castsi128_pd(a.val)); } + +inline v_float64x2 v_reinterpret_f64(const v_float64x2& a) +{ return v_float64x2(_mm_castps_pd(a.val)); } + +inline v_uint8x16 v_sat_u8(const v_uint16x8& a, const v_uint16x8& b) +{ + __m128i delta = _mm_set1_epi16(255); + return v_uint8x16(_mm_packus_epi16(_mm_adds_epu16(_mm_subs_epu16(a.val, delta), delta), + _mm_adds_epu16(_mm_subs_epu16(b.val, delta), delta))); +} +inline v_uint8x16 v_sat_u8(const v_uint16x8& a, const v_uint16x8& b, int n) +{ + // we assume that n > 0, and so the shifted 16-bit values can be treated as signed numbers. + __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); + return v_uint8x16(_mm_packus_epi16(_mm_srli_epi16(_mm_add_epi16(a.val, delta), n), + _mm_srli_epi16(_mm_add_epi16(b.val, delta), n))); +} + +inline v_uint8x16 v_sat_u8(const v_int16x8& a, const v_int16x8& b) +{ return v_uint8x16(_mm_packus_epi16(a.val, b.val)); } +inline v_uint8x16 v_sat_u8(const v_int16x8& a, const v_int16x8& b, int n) +{ + __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); + return v_uint8x16(_mm_packus_epi16(_mm_srai_epi16(_mm_add_epi16(a.val, delta), n), + _mm_srai_epi16(_mm_add_epi16(b.val, delta), n))); +} + +inline void v_storesat_u8(uchar* ptr, const v_uint16x8& a) +{ + __m128i delta = _mm_set1_epi16(255); + _mm_storel_epi64((__m128i*)ptr, + _mm_packus_epi16(_mm_adds_epu16(_mm_subs_epu16(a.val, delta), delta), delta)); +} + +inline void v_storesat_u8(uchar* ptr, const v_uint16x8& a, int n) +{ + __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); + _mm_storel_epi64((__m128i*)ptr, + _mm_packus_epi16(_mm_srli_epi16(_mm_add_epi16(a.val, delta), n), delta)); +} + +inline void v_storesat_u8(uchar* ptr, const v_int16x8& a) +{ _mm_storel_epi64((__m128i*)ptr, _mm_packus_epi16(a.val, a.val)); } + +inline void v_storesat_u8(uchar* ptr, const v_int16x8& a, int n) +{ + __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); + _mm_storel_epi64((__m128i*)ptr, + _mm_packus_epi16(_mm_srai_epi16(_mm_add_epi16(a.val, delta), n), delta)); +} + +inline v_int8x16 v_sat_s8(const v_uint16x8& a, const v_uint16x8& b) +{ + __m128i delta = _mm_set1_epi16(127); + return v_int8x16(_mm_packs_epi16(_mm_adds_epu16(_mm_subs_epu16(a.val, delta), delta), + _mm_adds_epu16(_mm_subs_epu16(b.val, delta), delta))); +} + +inline v_int8x16 v_sat_s8(const v_uint16x8& a, const v_uint16x8& b, int n) +{ + // we assume that n > 0, and so the shifted 16-bit values can be treated as signed numbers. + __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); + return v_int8x16(_mm_packs_epi16(_mm_srli_epi16(_mm_add_epi16(a.val, delta), n), + _mm_srli_epi16(_mm_add_epi16(b.val, delta), n))); +} + +inline v_int8x16 v_sat_s8(const v_int16x8& a, const v_int16x8& b) +{ return v_int8x16(_mm_packs_epi16(a.val, b.val)); } + +inline v_int8x16 v_sat_s8(const v_int16x8& a, const v_int16x8& b, int n) +{ + __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); + return v_int8x16(_mm_packs_epi16(_mm_srai_epi16(_mm_add_epi16(a.val, delta), n), + _mm_srai_epi16(_mm_add_epi16(b.val, delta), n))); +} + +inline void v_storesat_s8(schar* ptr, const v_uint16x8& a) +{ + __m128i delta = _mm_set1_epi16(127); + _mm_storel_epi64((__m128i*)ptr, + _mm_packs_epi16(_mm_adds_epu16(_mm_subs_epu16(a.val, delta), delta), delta)); +} + +inline void v_storesat_s8(schar* ptr, const v_uint16x8& a, int n) +{ + __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); + _mm_storel_epi64((__m128i*)ptr, + _mm_packs_epi16(_mm_srli_epi16(_mm_add_epi16(a.val, delta), n), delta)); +} +inline void v_storesat_s8(schar* ptr, const v_int16x8& a) +{ _mm_storel_epi64((__m128i*)ptr, _mm_packs_epi16(a.val, a.val)); } + +inline void v_storesat_s8(schar* ptr, const v_int16x8& a, int n) +{ + __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); + _mm_storel_epi64((__m128i*)ptr, + _mm_packs_epi16(_mm_srai_epi16(_mm_add_epi16(a.val, delta), n), delta)); +} + +// bit-wise "mask ? a : b" +inline __m128i v_select_si128(__m128i mask, __m128i a, __m128i b) +{ + return _mm_xor_si128(b, _mm_and_si128(_mm_xor_si128(a, b), mask)); +} + +inline v_uint16x8 v_sat_u16(const v_uint32x4& a, const v_uint32x4& b) +{ + __m128i z = _mm_setzero_si128(), maxval32 = _mm_set1_epi32(65535), delta32 = _mm_set1_epi32(32768); + __m128i a1 = _mm_sub_epi32(v_select_si128(_mm_cmpgt_epi32(z, a.val), maxval32, a.val), delta32); + __m128i b1 = _mm_sub_epi32(v_select_si128(_mm_cmpgt_epi32(z, b.val), maxval32, b.val), delta32); + __m128i r = _mm_packs_epi32(a1, b1); + return v_uint16x8(_mm_sub_epi16(r, _mm_set1_epi16(-32768))); +} +inline v_uint16x8 v_sat_u16(const v_uint32x4& a, const v_uint32x4& b, int n) +{ + __m128i delta = _mm_set1_epi32(1 << (n-1)), delta32 = _mm_set1_epi32(32768); + __m128i a1 = _mm_sub_epi32(_mm_srli_epi32(_mm_add_epi32(a.val, delta), n), delta32); + __m128i b1 = _mm_sub_epi32(_mm_srli_epi32(_mm_add_epi32(b.val, delta), n), delta32); + return v_uint16x8(_mm_sub_epi16(_mm_packs_epi32(a1, b1), _mm_set1_epi16(-32768))); +} +inline v_uint16x8 v_sat_u16(const v_int32x4& a, const v_int32x4& b) +{ + __m128i delta32 = _mm_set1_epi32(32768); + __m128i r = _mm_packs_epi32(_mm_sub_epi32(a.val, delta32), _mm_sub_epi32(b.val, delta32)); + return v_uint16x8(_mm_sub_epi16(r, _mm_set1_epi16(-32768))); +} +inline v_uint16x8 v_sat_u16(const v_int32x4& a, const v_int32x4& b, int n) +{ + __m128i delta = _mm_set1_epi32(1 << (n-1)), delta32 = _mm_set1_epi32(32768); + __m128i a1 = _mm_sub_epi32(_mm_srai_epi32(_mm_add_epi32(a.val, delta), n), delta32); + __m128i b1 = _mm_sub_epi32(_mm_srai_epi32(_mm_add_epi32(b.val, delta), n), delta32); + return v_uint16x8(_mm_sub_epi16(_mm_packs_epi32(a1, b1), _mm_set1_epi16(-32768))); +} + +inline void v_storesat_u16(ushort* ptr, const v_uint32x4& a) +{ + __m128i z = _mm_setzero_si128(), maxval32 = _mm_set1_epi32(65535), delta32 = _mm_set1_epi32(32768); + __m128i a1 = _mm_sub_epi32(v_select_si128(_mm_cmpgt_epi32(z, a.val), maxval32, a.val), delta32); + __m128i r = _mm_sub_epi16(_mm_packs_epi32(a1, delta32), _mm_set1_epi16(-32768)); + _mm_storel_epi64((__m128i*)ptr, r); +} +inline void v_storesat_u16(ushort* ptr, const v_uint32x4& a, int n) +{ + __m128i delta = _mm_set1_epi32(1 << (n-1)), delta32 = _mm_set1_epi32(32768); + __m128i a1 = _mm_sub_epi32(_mm_srli_epi32(_mm_add_epi32(a.val, delta), n), delta32); + __m128i r = _mm_sub_epi16(_mm_packs_epi32(a1, delta32), _mm_set1_epi16(-32768)); + _mm_storel_epi64((__m128i*)ptr, r); +} +inline void v_storesat_u16(ushort* ptr, const v_int32x4& a) +{ + __m128i delta32 = _mm_set1_epi32(32768); + __m128i a1 = _mm_sub_epi32(a.val, delta32); + __m128i r = _mm_sub_epi16(_mm_packs_epi32(a1, delta32), _mm_set1_epi16(-32768)); + _mm_storel_epi64((__m128i*)ptr, r); +} +inline void v_storesat_u16(ushort* ptr, const v_int32x4& a, int n) +{ + __m128i delta = _mm_set1_epi32(1 << (n-1)), delta32 = _mm_set1_epi32(32768); + __m128i a1 = _mm_sub_epi32(_mm_srai_epi32(_mm_add_epi32(a.val, delta), n), delta32); + __m128i r = _mm_sub_epi16(_mm_packs_epi32(a1, delta32), _mm_set1_epi16(-32768)); + _mm_storel_epi64((__m128i*)ptr, r); +} + +inline v_int16x8 v_sat_s16(const v_uint32x4& a, const v_uint32x4& b) +{ + __m128i z = _mm_setzero_si128(), maxval32 = _mm_set1_epi32(32767); + __m128i a1 = v_select_si128(_mm_cmpgt_epi32(z, a.val), maxval32, a.val); + __m128i b1 = v_select_si128(_mm_cmpgt_epi32(z, b.val), maxval32, b.val); + return v_int16x8(_mm_packs_epi32(a1, b1)); +} +inline v_int16x8 v_sat_s16(const v_uint32x4& a, const v_uint32x4& b, int n) +{ + __m128i delta = _mm_set1_epi32(1 << (n-1)); + return v_int16x8(_mm_packs_epi32(_mm_srli_epi32(_mm_add_epi32(a.val, delta), n), + _mm_srli_epi32(_mm_add_epi32(b.val, delta), n))); +} +inline v_int16x8 v_sat_s16(const v_int32x4& a, const v_int32x4& b) +{ return v_int16x8(_mm_packs_epi32(a.val, b.val)); } +inline v_int16x8 v_sat_s16(const v_int32x4& a, const v_int32x4& b, int n) +{ + __m128i delta = _mm_set1_epi32(1 << (n-1)); + return v_int16x8(_mm_packs_epi32(_mm_srai_epi32(_mm_add_epi32(a.val, delta), n), + _mm_srai_epi32(_mm_add_epi32(b.val, delta), n))); +} + +inline void v_storesat_s16(short* ptr, const v_uint32x4& a) +{ + __m128i z = _mm_setzero_si128(), maxval32 = _mm_set1_epi32(32767); + __m128i a1 = v_select_si128(_mm_cmpgt_epi32(z, a.val), maxval32, a.val); + _mm_storel_epi64((__m128i*)ptr, _mm_packs_epi32(a1, a1)); +} +inline void v_storesat_s16(short* ptr, const v_uint32x4& a, int n) +{ + __m128i delta = _mm_set1_epi32(1 << (n-1)); + __m128i a1 = _mm_srli_epi32(_mm_add_epi32(a.val, delta), n); + _mm_storel_epi64((__m128i*)ptr, _mm_packs_epi32(a1, a1)); +} +inline void v_storesat_s16(short* ptr, const v_int32x4& a) +{ + _mm_storel_epi64((__m128i*)ptr, _mm_packs_epi32(a.val, a.val)); +} +inline void v_storesat_s16(short* ptr, const v_int32x4& a, int n) +{ + __m128i delta = _mm_set1_epi32(1 << (n-1)); + __m128i a1 = _mm_srai_epi32(_mm_add_epi32(a.val, delta), n); + _mm_storel_epi64((__m128i*)ptr, _mm_packs_epi32(a1, a1)); +} + +inline v_float32x4 v_matmul(const v_float32x4& v, const v_float32x4& m0, + const v_float32x4& m1, const v_float32x4& m2, + const v_float32x4& m3) +{ + __m128 v0 = _mm_mul_ps(_mm_shuffle_ps(v.val, v.val, _MM_SHUFFLE(0, 0, 0, 0)), m0.val); + __m128 v1 = _mm_mul_ps(_mm_shuffle_ps(v.val, v.val, _MM_SHUFFLE(1, 1, 1, 1)), m1.val); + __m128 v2 = _mm_mul_ps(_mm_shuffle_ps(v.val, v.val, _MM_SHUFFLE(2, 2, 2, 2)), m2.val); + __m128 v3 = _mm_mul_ps(_mm_shuffle_ps(v.val, v.val, _MM_SHUFFLE(3, 3, 3, 3)), m3.val); + + return v_float32x4(_mm_add_ps(_mm_add_ps(v0, v1), _mm_add_ps(v2, v3))); +} + + +#define OPENCV_HAL_IMPL_SSE_BIN_OP(bin_op, _Tpvec, intrin) \ + inline _Tpvec operator bin_op (const _Tpvec& a, const _Tpvec& b) \ + { \ + return _Tpvec(intrin(a.val, b.val)); \ + } \ + inline _Tpvec& operator bin_op##= (_Tpvec& a, const _Tpvec& b) \ + { \ + a.val = intrin(a.val, b.val); \ + return a; \ + } + +OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_uint8x16, _mm_adds_epu8) +OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_uint8x16, _mm_subs_epu8) +OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_int8x16, _mm_adds_epi8) +OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_int8x16, _mm_subs_epi8) +OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_uint16x8, _mm_adds_epu16) +OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_uint16x8, _mm_subs_epu16) +OPENCV_HAL_IMPL_SSE_BIN_OP(*, v_uint16x8, _mm_mullo_epi16) +OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_int16x8, _mm_adds_epi16) +OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_int16x8, _mm_subs_epi16) +OPENCV_HAL_IMPL_SSE_BIN_OP(*, v_int16x8, _mm_mullo_epi16) +OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_int32x4, _mm_add_epi32) +OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_int32x4, _mm_sub_epi32) +OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_float32x4, _mm_add_ps) +OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_float32x4, _mm_sub_ps) +OPENCV_HAL_IMPL_SSE_BIN_OP(*, v_float32x4, _mm_mul_ps) +OPENCV_HAL_IMPL_SSE_BIN_OP(/, v_float32x4, _mm_div_ps) +OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_float64x2, _mm_add_pd) +OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_float64x2, _mm_sub_pd) +OPENCV_HAL_IMPL_SSE_BIN_OP(*, v_float64x2, _mm_mul_pd) +OPENCV_HAL_IMPL_SSE_BIN_OP(/, v_float64x2, _mm_div_pd) + +inline v_uint32x4 operator * (const v_uint32x4& a, const v_uint32x4& b) +{ + __m128i c0 = _mm_mul_epu32(a.val, b.val); + __m128i c1 = _mm_mul_epu32(_mm_srli_epi64(a.val, 32), _mm_srli_epi64(b.val, 32)); + __m128i d0 = _mm_unpacklo_epi32(c0, c1); + __m128i d1 = _mm_unpackhi_epi32(c0, c1); + return v_uint32x4(_mm_unpacklo_epi64(d0, d1)); +} +inline v_int32x4 operator * (const v_int32x4& a, const v_int32x4& b) +{ + __m128i c0 = _mm_mul_epu32(a.val, b.val); + __m128i c1 = _mm_mul_epu32(_mm_srli_epi64(a.val, 32), _mm_srli_epi64(b.val, 32)); + __m128i d0 = _mm_unpacklo_epi32(c0, c1); + __m128i d1 = _mm_unpackhi_epi32(c0, c1); + return v_int32x4(_mm_unpacklo_epi64(d0, d1)); +} + +#define OPENCV_HAL_IMPL_SSE_LOGIC_OP(_Tpvec, suffix, not_const) \ + OPENCV_HAL_IMPL_SSE_BIN_OP(&, _Tpvec, _mm_and_##suffix) \ + OPENCV_HAL_IMPL_SSE_BIN_OP(|, _Tpvec, _mm_or_##suffix) \ + OPENCV_HAL_IMPL_SSE_BIN_OP(^, _Tpvec, _mm_xor_##suffix) \ + inline _Tpvec operator ~ (const _Tpvec& a) \ + { \ + return _Tpvec(_mm_xor_##suffix(a.val, not_const)); \ + } + +OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_uint8x16, si128, _mm_set1_epi32(-1)) +OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_int8x16, si128, _mm_set1_epi32(-1)) +OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_uint16x8, si128, _mm_set1_epi32(-1)) +OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_int16x8, si128, _mm_set1_epi32(-1)) +OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_uint32x4, si128, _mm_set1_epi32(-1)) +OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_int32x4, si128, _mm_set1_epi32(-1)) +OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_float32x4, ps, _mm_castsi128_ps(_mm_set1_epi32(-1))) +OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_float64x2, pd, _mm_castsi128_pd(_mm_set1_epi32(-1))) + +inline v_float32x4 v_sqrt(v_float32x4 x) +{ return v_float32x4(_mm_sqrt_ps(x.val)); } +inline v_float64x2 v_sqrt(v_float64x2 x) +{ return v_float64x2(_mm_sqrt_pd(x.val)); } + +inline v_float32x4 v_abs(v_float32x4 x) +{ return v_float32x4(_mm_and_ps(x.val, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff)))); } +inline v_float64x2 v_abs(v_float64x2 x) +{ + return v_float64x2(_mm_and_pd(x.val, + _mm_castsi128_pd(_mm_srli_epi64(_mm_set1_epi32(-1), 1)))); +} + +// TODO: exp, log, sin, cos + +#define OPENCV_HAL_IMPL_SSE_BIN_FUNC(_Tpvec, func, intrin) \ +inline _Tpvec func(const _Tpvec& a, const _Tpvec& b) \ +{ \ + return _Tpvec(intrin(a.val, b.val)); \ +} + +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint8x16, v_min, _mm_min_epu8) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint8x16, v_max, _mm_max_epu8) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int16x8, v_min, _mm_min_epi16) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int16x8, v_max, _mm_max_epi16) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_float32x4, v_min, _mm_min_ps) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_float32x4, v_max, _mm_max_ps) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_float64x2, v_min, _mm_min_pd) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_float64x2, v_max, _mm_max_pd) + +inline v_int8x16 v_min(const v_int8x16& a, const v_int8x16& b) +{ + __m128i delta = _mm_set1_epi8((char)0x80); + return v_int8x16(_mm_xor_si128(delta, _mm_min_epu8(_mm_xor_si128(a.val, delta), + _mm_xor_si128(b.val, delta)))); +} +inline v_int8x16 v_max(const v_int8x16& a, const v_int8x16& b) +{ + __m128i delta = _mm_set1_epi8((char)0x80); + return v_int8x16(_mm_xor_si128(delta, _mm_max_epu8(_mm_xor_si128(a.val, delta), + _mm_xor_si128(b.val, delta)))); +} +inline v_uint16x8 v_min(const v_uint16x8& a, const v_uint16x8& b) +{ + return v_uint16x8(_mm_subs_epu16(a.val, _mm_subs_epu16(a.val, b.val))); +} +inline v_uint16x8 v_max(const v_uint16x8& a, const v_uint16x8& b) +{ + return v_uint16x8(_mm_adds_epu16(_mm_subs_epu16(a.val, b.val), b.val)); +} +inline v_uint32x4 v_min(const v_uint32x4& a, const v_uint32x4& b) +{ + __m128i delta = _mm_set1_epi32((int)0x80000000); + __m128i mask = _mm_cmpgt_epi32(_mm_xor_si128(a.val, delta), _mm_xor_si128(b.val, delta)); + return v_uint32x4(v_select_si128(mask, b.val, a.val)); +} +inline v_uint32x4 v_max(const v_uint32x4& a, const v_uint32x4& b) +{ + __m128i delta = _mm_set1_epi32((int)0x80000000); + __m128i mask = _mm_cmpgt_epi32(_mm_xor_si128(a.val, delta), _mm_xor_si128(b.val, delta)); + return v_uint32x4(v_select_si128(mask, a.val, b.val)); +} +inline v_int32x4 v_min(const v_int32x4& a, const v_int32x4& b) +{ + return v_int32x4(v_select_si128(_mm_cmpgt_epi32(a.val, b.val), b.val, a.val)); +} +inline v_int32x4 v_max(const v_int32x4& a, const v_int32x4& b) +{ + return v_int32x4(v_select_si128(_mm_cmpgt_epi32(a.val, b.val), a.val, b.val)); +} + +#define OPENCV_HAL_IMPL_SSE_INT_CMP_OP(_Tpuvec, _Tpsvec, suffix, sbit) \ +inline _Tpuvec operator == (const _Tpuvec& a, const _Tpuvec& b) \ +{ return _Tpuvec(_mm_cmpeq_##suffix(a.val, b.val)); } \ +inline _Tpuvec operator != (const _Tpuvec& a, const _Tpuvec& b) \ +{ \ + __m128i not_mask = _mm_set1_epi32(-1); \ + return _Tpuvec(_mm_xor_si128(_mm_cmpeq_##suffix(a.val, b.val), not_mask)); \ +} \ +inline _Tpsvec operator == (const _Tpsvec& a, const _Tpsvec& b) \ +{ return _Tpsvec(_mm_cmpeq_##suffix(a.val, b.val)); } \ +inline _Tpsvec operator != (const _Tpsvec& a, const _Tpsvec& b) \ +{ \ + __m128i not_mask = _mm_set1_epi32(-1); \ + return _Tpsvec(_mm_xor_si128(_mm_cmpeq_##suffix(a.val, b.val), not_mask)); \ +} \ +inline _Tpuvec operator < (const _Tpuvec& a, const _Tpuvec& b) \ +{ \ + __m128i smask = _mm_set1_##suffix(sbit); \ + return _Tpuvec(_mm_cmpgt_##suffix(_mm_xor_si128(b.val, smask), _mm_xor_si128(a.val, smask))); \ +} \ +inline _Tpuvec operator > (const _Tpuvec& a, const _Tpuvec& b) \ +{ \ + __m128i smask = _mm_set1_##suffix(sbit); \ + return _Tpuvec(_mm_cmpgt_##suffix(_mm_xor_si128(a.val, smask), _mm_xor_si128(b.val, smask))); \ +} \ +inline _Tpuvec operator <= (const _Tpuvec& a, const _Tpuvec& b) \ +{ \ + __m128i smask = _mm_set1_##suffix(sbit); \ + __m128i not_mask = _mm_set1_epi32(-1); \ + __m128i res = _mm_cmpgt_##suffix(_mm_xor_si128(a.val, smask), _mm_xor_si128(b.val, smask)); \ + return _Tpuvec(_mm_xor_si128(res, not_mask)); \ +} \ +inline _Tpuvec operator >= (const _Tpuvec& a, const _Tpuvec& b) \ +{ \ + __m128i smask = _mm_set1_##suffix(sbit); \ + __m128i not_mask = _mm_set1_epi32(-1); \ + __m128i res = _mm_cmpgt_##suffix(_mm_xor_si128(b.val, smask), _mm_xor_si128(a.val, smask)); \ + return _Tpuvec(_mm_xor_si128(res, not_mask)); \ +} \ +inline _Tpsvec operator < (const _Tpsvec& a, const _Tpsvec& b) \ +{ \ + return _Tpsvec(_mm_cmpgt_##suffix(b.val, a.val)); \ +} \ +inline _Tpsvec operator > (const _Tpsvec& a, const _Tpsvec& b) \ +{ \ + return _Tpsvec(_mm_cmpgt_##suffix(a.val, b.val)); \ +} \ +inline _Tpsvec operator <= (const _Tpsvec& a, const _Tpsvec& b) \ +{ \ + __m128i not_mask = _mm_set1_epi32(-1); \ + return _Tpsvec(_mm_xor_si128(_mm_cmpgt_##suffix(a.val, b.val), not_mask)); \ +} \ +inline _Tpsvec operator >= (const _Tpsvec& a, const _Tpsvec& b) \ +{ \ + __m128i not_mask = _mm_set1_epi32(-1); \ + return _Tpsvec(_mm_xor_si128(_mm_cmpgt_##suffix(b.val, a.val), not_mask)); \ +} + +OPENCV_HAL_IMPL_SSE_INT_CMP_OP(v_uint8x16, v_int8x16, epi8, (char)0x80) +OPENCV_HAL_IMPL_SSE_INT_CMP_OP(v_uint16x8, v_int16x8, epi16, (short)0x8000) +OPENCV_HAL_IMPL_SSE_INT_CMP_OP(v_uint32x4, v_int32x4, epi32, (int)0x80000000) + +#define OPENCV_HAL_IMPL_SSE_FLT_CMP_OP(_Tpvec, suffix) \ +inline _Tpvec operator == (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(_mm_cmpeq_##suffix(a.val, b.val)); } \ +inline _Tpvec operator != (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(_mm_cmpneq_##suffix(a.val, b.val)); } \ +inline _Tpvec operator < (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(_mm_cmplt_##suffix(a.val, b.val)); } \ +inline _Tpvec operator > (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(_mm_cmpgt_##suffix(a.val, b.val)); } \ +inline _Tpvec operator <= (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(_mm_cmple_##suffix(a.val, b.val)); } \ +inline _Tpvec operator >= (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(_mm_cmpge_##suffix(a.val, b.val)); } + +OPENCV_HAL_IMPL_SSE_FLT_CMP_OP(v_float32x4, ps) +OPENCV_HAL_IMPL_SSE_FLT_CMP_OP(v_float64x2, pd) + +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint8x16, v_add_wrap, _mm_add_epi8) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int8x16, v_add_wrap, _mm_add_epi8) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint16x8, v_add_wrap, _mm_add_epi16) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int16x8, v_add_wrap, _mm_add_epi16) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint8x16, v_sub_wrap, _mm_sub_epi8) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int8x16, v_sub_wrap, _mm_sub_epi8) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint16x8, v_sub_wrap, _mm_sub_epi16) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int16x8, v_sub_wrap, _mm_sub_epi16) + +#define OPENCV_HAL_IMPL_SSE_ABSDIFF_8_16(_Tpuvec, _Tpsvec, bits, sbit) \ +inline _Tpuvec v_absdiff(const _Tpuvec& a, const _Tpuvec& b) \ +{ \ + return _Tpuvec(_mm_add_epi##bits(_mm_subs_epu##bits(a.val, b.val), _mm_subs_epu##bits(b.val, a.val))); \ +} \ +inline _Tpuvec v_absdiff(const _Tpsvec& a, const _Tpsvec& b) \ +{ \ + __m128i smask = _mm_set1_epi8(sbit); \ + __m128i a1 = _mm_xor_si128(a.val, smask); \ + __m128i b1 = _mm_xor_si128(b.val, smask); \ + return _Tpuvec(_mm_add_epi##bits(_mm_subs_epu##bits(a1, b1), _mm_subs_epu##bits(b1, a1))); \ +} + +OPENCV_HAL_IMPL_SSE_ABSDIFF_8_16(v_uint8x16, v_int8x16, 8, (char)0x80) +OPENCV_HAL_IMPL_SSE_ABSDIFF_8_16(v_uint16x8, v_int16x8, 16, (char)0x8000) + +#define OPENCV_HAL_IMPL_SSE_MISC_FLT_OP(_Tpvec, _Tp, _Tpreg, suffix, absmask_vec) \ +inline _Tpvec v_absdiff(const _Tpvec& a, const _Tpvec& b) \ +{ \ + _Tpreg absmask = _mm_castsi128_##suffix(absmask_vec); \ + return _Tpvec(_mm_and_##suffix(_mm_sub_##suffix(a.val, b.val), absmask)); \ +} \ +inline _Tpvec v_magnitude(const _Tpvec& a, const _Tpvec& b) \ +{ \ + _Tpreg res = _mm_add_##suffix(_mm_mul_##suffix(a.val, a.val), _mm_mul_##suffix(b.val, b.val)); \ + return _Tpvec(_mm_sqrt_##suffix(res)); \ +} \ +inline _Tpvec v_sqr_magnitude(const _Tpvec& a, const _Tpvec& b) \ +{ \ + _Tpreg res = _mm_add_##suffix(_mm_mul_##suffix(a.val, a.val), _mm_mul_##suffix(b.val, b.val)); \ + return _Tpvec(res); \ +} \ +inline _Tpvec v_muladd(const _Tpvec& a, const _Tpvec& b, const _Tpvec& c) \ +{ \ + return _Tpvec(_mm_add_##suffix(_mm_mul_##suffix(a.val, b.val), c.val)); \ +} + +OPENCV_HAL_IMPL_SSE_MISC_FLT_OP(v_float32x4, float, __m128, ps, _mm_set1_epi32((int)0x7fffffff)) +OPENCV_HAL_IMPL_SSE_MISC_FLT_OP(v_float64x2, double, __m128d, pd, _mm_srli_epi64(_mm_set1_epi32(-1), 1)) + +#define OPENCV_HAL_IMPL_SSE_SHIFT_OP(_Tpuvec, _Tpsvec, suffix) \ +inline _Tpuvec operator << (const _Tpuvec& a, int imm) \ +{ \ + return _Tpuvec(_mm_slli_##suffix(a.val, imm)); \ +} \ +inline _Tpsvec operator << (const _Tpsvec& a, int imm) \ +{ \ + return _Tpsvec(_mm_slli_##suffix(a.val, imm)); \ +} \ +inline _Tpuvec operator >> (const _Tpuvec& a, int imm) \ +{ \ + return _Tpuvec(_mm_srli_##suffix(a.val, imm)); \ +} \ +inline _Tpsvec operator >> (const _Tpsvec& a, int imm) \ +{ \ + return _Tpsvec(_mm_srai_##suffix(a.val, imm)); \ +} + +OPENCV_HAL_IMPL_SSE_SHIFT_OP(v_uint16x8, v_int16x8, epi16) +OPENCV_HAL_IMPL_SSE_SHIFT_OP(v_uint32x4, v_int32x4, epi32) + +inline v_int16x8 v_mullo(const v_int16x8& a, const v_int16x8& b) +{ + return v_int16x8(_mm_mullo_epi16(a.val, b.val)); +} +inline v_uint16x8 v_mullo(const v_uint16x8& a, const v_uint16x8& b) +{ + return v_uint16x8(_mm_mullo_epi16(a.val, b.val)); +} +inline v_int16x8 v_mulhi2(const v_int16x8& a, const v_int16x8& b) +{ + return v_int16x8(_mm_slli_epi16(_mm_mulhi_epi16(a.val, b.val), 1)); +} +inline v_uint16x8 v_mulhi2(const v_uint16x8& a, const v_uint16x8& b) +{ + return v_uint16x8(_mm_slli_epi16(_mm_mulhi_epu16(a.val, b.val), 1)); +} + +#define OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(_Tpvec, _Tp) \ +inline _Tpvec v_load(const _Tp* ptr) \ +{ return _Tpvec(_mm_loadu_si128((const __m128i*)ptr)); } \ +inline _Tpvec v_load_aligned(const _Tp* ptr) \ +{ return _Tpvec(_mm_load_si128((const __m128i*)ptr)); } \ +inline _Tpvec v_load_halves(const _Tp* ptr0, const _Tp* ptr1) \ +{ \ + return _Tpvec(_mm_unpacklo_epi64(_mm_loadl_epi64((const __m128i*)ptr0), \ + _mm_loadl_epi64((const __m128i*)ptr1))); \ +} \ +inline void v_store(_Tp* ptr, const _Tpvec& a) \ +{ _mm_storeu_si128((__m128i*)ptr, a.val); } \ +inline void v_store_aligned(_Tp* ptr, const _Tpvec& a) \ +{ _mm_store_si128((__m128i*)ptr, a.val); } \ +inline void v_store_low(_Tp* ptr, const _Tpvec& a) \ +{ _mm_storel_epi64((__m128i*)ptr, a.val); } \ +inline void v_store_high(_Tp* ptr, const _Tpvec& a) \ +{ _mm_storel_epi64((__m128i*)ptr, _mm_unpackhi_epi64(a.val, a.val)); } + +OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_uint8x16, uchar) +OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_int8x16, schar) +OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_uint16x8, ushort) +OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_int16x8, short) +OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_uint32x4, unsigned) +OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_int32x4, int) + +#define OPENCV_HAL_IMPL_SSE_LOADSTORE_FLT_OP(_Tpvec, _Tp, suffix) \ +inline _Tpvec v_load(const _Tp* ptr) \ +{ return _Tpvec(_mm_loadu_##suffix(ptr)); } \ +inline _Tpvec v_load_aligned(const _Tp* ptr) \ +{ return _Tpvec(_mm_load_##suffix(ptr)); } \ +inline _Tpvec v_load_halves(const _Tp* ptr0, const _Tp* ptr1) \ +{ \ + return _Tpvec(_mm_castsi128_##suffix( \ + _mm_unpacklo_epi64(_mm_loadl_epi64((const __m128i*)ptr0), \ + _mm_loadl_epi64((const __m128i*)ptr1)))); \ +} \ +inline void v_store(_Tp* ptr, const _Tpvec& a) \ +{ _mm_storeu_##suffix(ptr, a.val); } \ +inline void v_store_aligned(_Tp* ptr, const _Tpvec& a) \ +{ _mm_store_##suffix(ptr, a.val); } \ +inline void v_store_low(_Tp* ptr, const _Tpvec& a) \ +{ _mm_storel_epi64((__m128i*)ptr, _mm_cast##suffix##_si128(a.val)); } \ +inline void v_store_high(_Tp* ptr, const _Tpvec& a) \ +{ \ + __m128i a1 = _mm_cast##suffix##_si128(a.val); \ + _mm_storel_epi64((__m128i*)ptr, _mm_unpackhi_epi64(a1, a1)); \ +} + +OPENCV_HAL_IMPL_SSE_LOADSTORE_FLT_OP(v_float32x4, float, ps) +OPENCV_HAL_IMPL_SSE_LOADSTORE_FLT_OP(v_float64x2, double, pd) + +#define OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(_Tpvec, scalartype, func, scalar_func) \ +inline scalartype v_reduce_##func(const _Tpvec& a) \ +{ \ + scalartype CV_DECL_ALIGNED(16) buf[4]; \ + v_store_aligned(buf, a); \ + scalartype s0 = scalar_func(buf[0], buf[1]); \ + scalartype s1 = scalar_func(buf[2], buf[3]); \ + return scalar_func(s0, s1); \ +} + +OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_uint32x4, unsigned, sum, OPENCV_HAL_ADD) +OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_uint32x4, unsigned, max, std::max) +OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_uint32x4, unsigned, min, std::min) +OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_int32x4, int, sum, OPENCV_HAL_ADD) +OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_int32x4, int, max, std::max) +OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_int32x4, int, min, std::min) +OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_float32x4, float, sum, OPENCV_HAL_ADD) +OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_float32x4, float, max, std::max) +OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_float32x4, float, min, std::min) + +#define OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(_Tpvec, suffix, pack_op, and_op, signmask, allmask) \ +inline bool v_signmask(const _Tpvec& a) \ +{ \ + return and_op(_mm_movemask_##suffix(pack_op(a.val)), signmask); \ +} \ +inline bool v_check_all(const _Tpvec& a) \ +{ return and_op(_mm_movemask_##suffix(a.val), allmask) == allmask; } \ +inline bool v_check_any(const _Tpvec& a) \ +{ return and_op(_mm_movemask_##suffix(a.val), allmask) != 0; } + +#define OPENCV_HAL_PACKS(a) _mm_packs_epi16(a, a) +inline __m128i v_packq_epi32(__m128i a) +{ + __m128i b = _mm_packs_epi32(a, a); + return _mm_packs_epi16(b, b); +} + +OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_uint8x16, epi8, OPENCV_HAL_NOP, OPENCV_HAL_1ST, 65535, 65535) +OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_int8x16, epi8, OPENCV_HAL_NOP, OPENCV_HAL_1ST, 65535, 65535) +OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_uint16x8, epi8, OPENCV_HAL_PACKS, OPENCV_HAL_AND, 255, (int)0xaaaa) +OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_int16x8, epi8, OPENCV_HAL_PACKS, OPENCV_HAL_AND, 255, (int)0xaaaa) +OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_uint32x4, epi8, v_packq_epi32, OPENCV_HAL_AND, 15, (int)0x8888) +OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_int32x4, epi8, v_packq_epi32, OPENCV_HAL_AND, 15, (int)0x8888) +OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_float32x4, ps, OPENCV_HAL_NOP, OPENCV_HAL_1ST, 15, 15) +OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_float64x2, pd, OPENCV_HAL_NOP, OPENCV_HAL_1ST, 3, 3) + +#define OPENCV_HAL_IMPL_SSE_SELECT(_Tpvec, suffix) \ +inline _Tpvec v_select(const _Tpvec& mask, const _Tpvec& a, const _Tpvec& b) \ +{ \ + return _Tpvec(_mm_xor_##suffix(b.val, _mm_and_##suffix(_mm_xor_##suffix(b.val, a.val), mask.val))); \ +} + +OPENCV_HAL_IMPL_SSE_SELECT(v_uint8x16, si128) +OPENCV_HAL_IMPL_SSE_SELECT(v_int8x16, si128) +OPENCV_HAL_IMPL_SSE_SELECT(v_uint16x8, si128) +OPENCV_HAL_IMPL_SSE_SELECT(v_int16x8, si128) +OPENCV_HAL_IMPL_SSE_SELECT(v_uint32x4, si128) +OPENCV_HAL_IMPL_SSE_SELECT(v_int32x4, si128) +OPENCV_HAL_IMPL_SSE_SELECT(v_float32x4, ps) +OPENCV_HAL_IMPL_SSE_SELECT(v_float64x2, pd) + +#define OPENCV_HAL_IMPL_SSE_EXPAND(_Tpuvec, _Tpwuvec, _Tpu, _Tpsvec, _Tpwsvec, _Tps, suffix, wsuffix, shift) \ +inline void v_expand(const _Tpuvec& a, _Tpwuvec& b0, _Tpwuvec& b1) \ +{ \ + __m128i z = _mm_setzero_si128(); \ + b0.val = _mm_unpacklo_##suffix(a.val, z); \ + b1.val = _mm_unpackhi_##suffix(a.val, z); \ +} \ +inline _Tpwuvec v_load_expand(const _Tpu* ptr) \ +{ \ + __m128i z = _mm_setzero_si128(); \ + return _Tpwuvec(_mm_unpacklo_##suffix(_mm_loadl_epi64((const __m128i*)ptr), z)); \ +} \ +inline void v_expand(const _Tpsvec& a, _Tpwsvec& b0, _Tpwsvec& b1) \ +{ \ + b0.val = _mm_srai_##wsuffix(_mm_unpacklo_##suffix(a.val, a.val), shift); \ + b1.val = _mm_srai_##wsuffix(_mm_unpackhi_##suffix(a.val, a.val), shift); \ +} \ +inline _Tpwsvec v_load_expand(const _Tps* ptr) \ +{ \ + __m128i a = _mm_loadl_epi64((const __m128i*)ptr); \ + return _Tpwsvec(_mm_srai_##wsuffix(_mm_unpacklo_##suffix(a, a), shift)); \ +} + +OPENCV_HAL_IMPL_SSE_EXPAND(v_uint8x16, v_uint16x8, uchar, v_int8x16, v_int16x8, schar, epi8, epi16, 8) +OPENCV_HAL_IMPL_SSE_EXPAND(v_uint16x8, v_uint32x4, ushort, v_int16x8, v_int32x4, short, epi16, epi32, 16) + +inline v_uint32x4 v_load_expand_q(const uchar* ptr) +{ + __m128i z = _mm_setzero_si128(); + __m128i a = _mm_cvtsi32_si128(*(const int*)ptr); + return v_uint32x4(_mm_unpacklo_epi16(_mm_unpacklo_epi8(a, z), z)); +} + +inline v_int32x4 v_load_expand_q(const schar* ptr) +{ + __m128i a = _mm_cvtsi32_si128(*(const int*)ptr); + a = _mm_unpacklo_epi8(a, a); + a = _mm_unpacklo_epi8(a, a); + return v_int32x4(_mm_srai_epi32(a, 24)); +} + +#define OPENCV_HAL_IMPL_SSE_UNPACKS(_Tpvec, suffix, cast_from, cast_to) \ +inline void v_zip(const _Tpvec& a0, const _Tpvec& a1, _Tpvec& b0, _Tpvec& b1) \ +{ \ + b0.val = _mm_unpacklo_##suffix(a0.val, a1.val); \ + b1.val = _mm_unpackhi_##suffix(a0.val, a1.val); \ +} \ +inline _Tpvec v_combine_low(const _Tpvec& a, const _Tpvec& b) \ +{ \ + __m128i a1 = cast_from(a.val), b1 = cast_from(b.val); \ + return _Tpvec(cast_to(_mm_unpacklo_epi64(a1, b1))); \ +} \ +inline _Tpvec v_combine_high(const _Tpvec& a, const _Tpvec& b) \ +{ \ + __m128i a1 = cast_from(a.val), b1 = cast_from(b.val); \ + return _Tpvec(cast_to(_mm_unpackhi_epi64(a1, b1))); \ +} \ +inline void v_recombine(const _Tpvec& a, const _Tpvec& b, _Tpvec& c, _Tpvec& d) \ +{ \ + __m128i a1 = cast_from(a.val), b1 = cast_from(b.val); \ + c.val = cast_to(_mm_unpacklo_epi64(a1, b1)); \ + d.val = cast_to(_mm_unpackhi_epi64(a1, b1)); \ +} + +OPENCV_HAL_IMPL_SSE_UNPACKS(v_uint8x16, epi8, OPENCV_HAL_NOP, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_UNPACKS(v_int8x16, epi8, OPENCV_HAL_NOP, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_UNPACKS(v_uint16x8, epi16, OPENCV_HAL_NOP, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_UNPACKS(v_int16x8, epi16, OPENCV_HAL_NOP, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_UNPACKS(v_uint32x4, epi32, OPENCV_HAL_NOP, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_UNPACKS(v_int32x4, epi32, OPENCV_HAL_NOP, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_UNPACKS(v_float32x4, ps, _mm_castps_si128, _mm_castsi128_ps) +OPENCV_HAL_IMPL_SSE_UNPACKS(v_float64x2, pd, _mm_castpd_si128, _mm_castsi128_pd) + +inline v_int32x4 v_round(const v_float32x4& a) +{ return v_int32x4(_mm_cvtps_epi32(a.val)); } + +inline v_int32x4 v_floor(const v_float32x4& a) +{ + __m128i a1 = _mm_cvtps_epi32(a.val); + __m128i mask = _mm_castps_si128(_mm_cmpgt_ps(_mm_cvtepi32_ps(a1), a.val)); + return v_int32x4(_mm_add_epi32(a1, mask)); +} + +inline v_int32x4 v_ceil(const v_float32x4& a) +{ + __m128i a1 = _mm_cvtps_epi32(a.val); + __m128i mask = _mm_castps_si128(_mm_cmpgt_ps(a.val, _mm_cvtepi32_ps(a1))); + return v_int32x4(_mm_sub_epi32(a1, mask)); +} + +inline v_int32x4 v_trunc(const v_float32x4& a) +{ return v_int32x4(_mm_cvttps_epi32(a.val)); } + +inline v_int32x4 v_round(const v_float64x2& a) +{ return v_int32x4(_mm_cvtpd_epi32(a.val)); } + +inline v_int32x4 v_floor(const v_float64x2& a) +{ + __m128i a1 = _mm_cvtpd_epi32(a.val); + __m128i mask = _mm_castpd_si128(_mm_cmpgt_pd(_mm_cvtepi32_pd(a1), a.val)); + mask = _mm_srli_si128(_mm_slli_si128(mask, 4), 8); // m0 m0 m1 m1 => m0 m1 0 0 + return v_int32x4(_mm_add_epi32(a1, mask)); +} + +inline v_int32x4 v_ceil(const v_float64x2& a) +{ + __m128i a1 = _mm_cvtpd_epi32(a.val); + __m128i mask = _mm_castpd_si128(_mm_cmpgt_pd(a.val, _mm_cvtepi32_pd(a1))); + mask = _mm_srli_si128(_mm_slli_si128(mask, 4), 8); // m0 m0 m1 m1 => m0 m1 0 0 + return v_int32x4(_mm_sub_epi32(a1, mask)); +} + +inline v_int32x4 v_trunc(const v_float64x2& a) +{ return v_int32x4(_mm_cvttpd_epi32(a.val)); } + +#define OPENCV_HAL_IMPL_SSE_TRANSPOSE4x4(_Tpvec, suffix, cast_from, cast_to) \ +inline void v_transpose4x4(const _Tpvec& a0, const _Tpvec& a1, \ + const _Tpvec& a2, const _Tpvec& a3, \ + _Tpvec& b0, _Tpvec& b1, \ + _Tpvec& b2, _Tpvec& b3) \ +{ \ + __m128i t0 = cast_from(_mm_unpacklo_##suffix(a0.val, a1.val)); \ + __m128i t1 = cast_from(_mm_unpacklo_##suffix(a2.val, a3.val)); \ + __m128i t2 = cast_from(_mm_unpackhi_##suffix(a0.val, a1.val)); \ + __m128i t3 = cast_from(_mm_unpacklo_##suffix(a2.val, a3.val)); \ +\ + b0.val = cast_to(_mm_unpacklo_epi64(t0, t1)); \ + b1.val = cast_to(_mm_unpackhi_epi64(t0, t1)); \ + b2.val = cast_to(_mm_unpacklo_epi64(t2, t3)); \ + b3.val = cast_to(_mm_unpackhi_epi64(t2, t3)); \ +} + +OPENCV_HAL_IMPL_SSE_TRANSPOSE4x4(v_uint32x4, epi32, OPENCV_HAL_NOP, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_TRANSPOSE4x4(v_int32x4, epi32, OPENCV_HAL_NOP, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_TRANSPOSE4x4(v_float32x4, ps, _mm_castps_si128, _mm_castsi128_ps) + +#if 0 +inline void v_load_deinterleave(const uchar*, v_uint8x16&, v_uint8x16&, v_uint8x16&) +{ + // !!! TODO !!! +} +#endif + +inline void v_load_deinterleave(const uchar* ptr, v_uint8x16& a, v_uint8x16& b, v_uint8x16& c, v_uint8x16& d) +{ + __m128i u0 = _mm_loadu_si128((const __m128i*)ptr); // a0 b0 c0 d0 a1 b1 c1 d1 ... + __m128i u1 = _mm_loadu_si128((const __m128i*)(ptr + 16)); // a4 b4 c4 d4 ... + __m128i u2 = _mm_loadu_si128((const __m128i*)(ptr + 32)); // a8 b8 c8 d8 ... + __m128i u3 = _mm_loadu_si128((const __m128i*)(ptr + 48)); // a12 b12 c12 d12 ... + + __m128 v0 = _mm_unpacklo_epi8(u0, u2); // a0 a8 b0 b8 ... + __m128 v1 = _mm_unpackhi_epi8(u0, u2); // a2 a10 b2 b10 ... + __m128 v2 = _mm_unpacklo_epi8(u1, u3); // a4 a12 b4 b12 ... + __m128 v3 = _mm_unpackhi_epi8(u1, u3); // a6 a14 b4 b14 ... + + u0 = _mm_unpacklo_epi8(v0, v2); // a0 a4 a8 a12 ... + u1 = _mm_unpacklo_epi8(v1, v3); // a2 a6 a10 a14 ... + u2 = _mm_unpackhi_epi8(v0, v2); // a1 a5 a9 a13 ... + u3 = _mm_unpackhi_epi8(v1, v3); // a3 a7 a11 a15 ... + + v0 = _mm_unpacklo_epi8(u0, u1); // a0 a2 a4 a6 ... + v1 = _mm_unpacklo_epi8(u2, u3); // a1 a3 a5 a7 ... + v2 = _mm_unpackhi_epi8(u0, u1); // b0 b2 b4 b6 ... + v3 = _mm_unpackhi_epi8(u2, u3); // b1 b3 b5 b7 ... + + a.val = _mm_unpacklo_epi8(v0, v1); + b.val = _mm_unpacklo_epi8(v2, v3); + c.val = _mm_unpackhi_epi8(v0, v1); + d.val = _mm_unpacklo_epi8(v2, v3); +} + +#if 0 +inline void v_load_deinterleave(const ushort*, v_uint16x8&, v_uint16x8&, v_uint16x8&) +{ + // !!! TODO !!! +} +#endif + +inline void v_load_deinterleave(const ushort* ptr, v_uint16x8& a, v_uint16x8& b, v_uint16x8& c, v_uint16x8& d) +{ + __m128i u0 = _mm_loadu_si128((const __m128i*)ptr); // a0 b0 c0 d0 a1 b1 c1 d1 + __m128i u1 = _mm_loadu_si128((const __m128i*)(ptr + 8)); // a2 b2 c2 d2 ... + __m128i u2 = _mm_loadu_si128((const __m128i*)(ptr + 16)); // a4 b4 c4 d4 ... + __m128i u3 = _mm_loadu_si128((const __m128i*)(ptr + 24)); // a6 b6 c6 d6 ... + + __m128 v0 = _mm_unpacklo_epi16(u0, u2); // a0 a4 b0 b4 ... + __m128 v1 = _mm_unpackhi_epi16(u0, u2); // a1 a5 b1 b5 ... + __m128 v2 = _mm_unpacklo_epi16(u1, u3); // a2 a6 b2 b6 ... + __m128 v3 = _mm_unpackhi_epi16(u1, u3); // a3 a7 b3 b7 ... + + u0 = _mm_unpacklo_epi16(v0, v2); // a0 a2 a4 a6 ... + u1 = _mm_unpacklo_epi16(v1, v3); // a1 a3 a5 a7 ... + u2 = _mm_unpackhi_epi16(v0, v2); // c0 c2 c4 c6 ... + u3 = _mm_unpackhi_epi16(v1, v3); // c1 c3 c5 c7 ... + + a.val = _mm_unpacklo_epi16(u0, u1); + b.val = _mm_unpackhi_epi16(u0, u1); + c.val = _mm_unpacklo_epi16(u2, u3); + d.val = _mm_unpackhi_epi16(u2, u3); +} + +#if 0 +inline void v_load_deinterleave(const unsigned*, v_uint32x4&, v_uint32x4&, v_uint32x4&) +{ + // !!! TODO !!! +} +#endif + +inline void v_load_deinterleave(const unsigned* ptr, v_uint32x4& a, v_uint32x4& b, v_uint32x4& c, v_uint32x4& d) +{ + v_uint32x4 u0(_mm_loadu_si128((const __m128i*)ptr)); // a0 b0 c0 d0 + v_uint32x4 u1(_mm_loadu_si128((const __m128i*)(ptr + 4))); // a1 b1 c1 d1 + v_uint32x4 u2(_mm_loadu_si128((const __m128i*)(ptr + 8))); // a2 b2 c2 d2 + v_uint32x4 u3(_mm_loadu_si128((const __m128i*)(ptr + 12))); // a3 b3 c3 d3 + + v_transpose4x4(u0, u1, u2, u3, a, b, c, d); +} + +inline void v_load_deinterleave(const float*, v_float32x4&, v_float32x4&, v_float32x4&) +{ + // !!! TODO !!! +} + +inline void v_load_deinterleave(const float* ptr, v_float32x4& a, v_float32x4& b, v_float32x4& c, v_float32x4& d) +{ + v_float32x4 u0(_mm_loadu_ps(ptr)); + v_float32x4 u1(_mm_loadu_ps(ptr + 4)); + v_float32x4 u2(_mm_loadu_ps(ptr + 8)); + v_float32x4 u3(_mm_loadu_ps(ptr + 12)); + + v_transpose4x4(u0, u1, u2, u3, a, b, c, d); +} + +inline void v_store_interleave( uchar* ptr, const v_uint8x16& a, const v_uint8x16& b, + const v_uint8x16& c, const v_uint8x16& d) +{ + // a0 a1 a2 a3 .... + // b0 b1 b2 b3 .... + // c0 c1 c2 c3 .... + // d0 d1 d2 d3 .... + __m128i u0 = _mm_unpacklo_epi8(a.val, c.val); // a0 c0 a1 c1 ... + __m128i u1 = _mm_unpackhi_epi8(a.val, c.val); // a8 c8 a9 c9 ... + __m128i u2 = _mm_unpacklo_epi8(b.val, d.val); // b0 d0 b1 d1 ... + __m128i u3 = _mm_unpackhi_epi8(b.val, d.val); // b8 d8 b9 d9 ... + + __m128i v0 = _mm_unpacklo_epi8(u0, u2); // a0 b0 c0 d0 ... + __m128i v1 = _mm_unpacklo_epi8(u1, u3); // a8 b8 c8 d8 ... + __m128i v2 = _mm_unpackhi_epi8(u0, u2); // a4 b4 c4 d4 ... + __m128i v3 = _mm_unpackhi_epi8(u1, u3); // a12 b12 c12 d12 ... + + _mm_storeu_si128((__m128i*)ptr, v0); + _mm_storeu_si128((__m128i*)(ptr + 16), v2); + _mm_storeu_si128((__m128i*)(ptr + 32), v1); + _mm_storeu_si128((__m128i*)(ptr + 48), v3); +} + +inline void v_store_interleave( ushort* ptr, const v_uint16x8& a, const v_uint16x8& b, + const v_uint16x8& c, const v_uint16x8& d) +{ + // a0 a1 a2 a3 .... + // b0 b1 b2 b3 .... + // c0 c1 c2 c3 .... + // d0 d1 d2 d3 .... + __m128i u0 = _mm_unpacklo_epi16(a.val, c.val); // a0 c0 a1 c1 ... + __m128i u1 = _mm_unpackhi_epi16(a.val, c.val); // a4 c4 a5 c5 ... + __m128i u2 = _mm_unpacklo_epi16(b.val, d.val); // b0 d0 b1 d1 ... + __m128i u3 = _mm_unpackhi_epi16(b.val, d.val); // b4 d4 b5 d5 ... + + __m128i v0 = _mm_unpacklo_epi16(u0, u2); // a0 b0 c0 d0 ... + __m128i v1 = _mm_unpacklo_epi16(u1, u3); // a4 b4 c4 d4 ... + __m128i v2 = _mm_unpackhi_epi16(u0, u2); // a2 b2 c2 d2 ... + __m128i v3 = _mm_unpackhi_epi16(u1, u3); // a6 b6 c6 d6 ... + + _mm_storeu_si128((__m128i*)ptr, v0); + _mm_storeu_si128((__m128i*)(ptr + 8), v2); + _mm_storeu_si128((__m128i*)(ptr + 16), v1); + _mm_storeu_si128((__m128i*)(ptr + 24), v3); +} + +inline v_float32x4 v_cvt_f32(const v_int32x4& a) +{ + return v_float32x4(_mm_cvtepi32_ps(a.val)); +} + +inline v_float32x4 v_cvt_f32(const v_float64x2& a) +{ + return v_float32x4(_mm_cvtpd_ps(a.val)); +} + +inline v_float64x2 v_cvt_f64(const v_int32x4& a) +{ + return v_float64x2(_mm_cvtepi32_pd(a.val)); +} + +inline v_float64x2 v_cvt_f64(const v_float32x4& a) +{ + return v_float64x2(_mm_cvtps_pd(a.val)); +} + +#elif CV_NEON + +#define CV_SIMD128 1 + +struct v_uint8x16 +{ + uint8x16_t val; +}; + +struct v_int8x16 +{ + int8x16_t val; +}; + +struct v_uint16x8 +{ + uint16x8_t val; +}; + +struct v_int16x8 +{ + int16x8_t val; +}; + +struct v_uint32x4 +{ + uint32x4_t val; +}; + +struct v_int32x4 +{ + int32x4_t val; +}; + +struct v_float32x4 +{ + float32x4_t val; +}; + +typedef v_reg v_float64x2; +typedef v_reg v_float64x4; + +#else + +typedef v_reg v_uint8x16; +typedef v_reg v_int8x16; +typedef v_reg v_uint16x8; +typedef v_reg v_int16x8; +typedef v_reg v_uint32x4; +typedef v_reg v_int32x4; +typedef v_reg v_float32x4; +typedef v_reg v_float32x8; +typedef v_reg v_float64x2; +typedef v_reg v_float64x4; + +inline v_uint8x16 v_setzero_u8() { return v_uint8x16::zero(); } +inline v_int8x16 v_setzero_s8() { return v_int8x16::zero(); } +inline v_uint16x8 v_setzero_u16() { return v_uint16x8::zero(); } +inline v_int16x8 v_setzero_s16() { return v_int16x8::zero(); } +inline v_uint32x4 v_setzero_u32() { return v_uint32x4::zero(); } +inline v_int32x4 v_setzero_s32() { return v_int32x4::zero(); } +inline v_float32x4 v_setzero_f32() { return v_float32x4::zero(); } +inline v_float64x2 v_setzero_f64() { return v_float64x2::zero(); } + +inline v_uint8x16 v_setall_u8(uchar v) { return v_uint8x16::all(v); } +inline v_int8x16 v_setall_s8(schar v) { return v_int8x16::all(v); } +inline v_uint16x8 v_setall_u16(ushort v) { return v_uint16x8::all(v); } +inline v_int16x8 v_setall_s16(short v) { return v_int16x8::all(v); } +inline v_uint32x4 v_setall_u32(unsigned v) { return v_uint32x4::all(v); } +inline v_int32x4 v_setall_s32(int v) { return v_int32x4::all(v); } +inline v_float32x4 v_setall_f32(float v) { return v_float32x4::all(v); } +inline v_float64x2 v_setall_f64(double v) { return v_float64x2::all(v); } + +template inline v_uint8x16 v_reinterpret_u8(const v_reg<_Tp, n>& a) +{ return v_reg<_Tp, n>::template reinterpret_as(a); } + +template inline v_int8x16 v_reinterpret_s8(const v_reg<_Tp, n>& a) +{ return v_reg<_Tp, n>::template reinterpret_as(a); } + +template inline v_uint16x8 v_reinterpret_u16(const v_reg<_Tp, n>& a) +{ return v_reg<_Tp, n>::template reinterpret_as(a); } + +template inline v_int16x8 v_reinterpret_s16(const v_reg<_Tp, n>& a) +{ return v_reg<_Tp, n>::template reinterpret_as(a); } + +template inline v_uint32x4 v_reinterpret_u32(const v_reg<_Tp, n>& a) +{ return v_reg<_Tp, n>::template reinterpret_as(a); } + +template inline v_int32x4 v_reinterpret_s32(const v_reg<_Tp, n>& a) +{ return v_reg<_Tp, n>::template reinterpret_as(a); } + +template inline v_float32x4 v_reinterpret_f32(const v_reg<_Tp, n>& a) +{ return v_reg<_Tp, n>::template reinterpret_as(a); } + +template inline v_float64x2 v_reinterpret_f64(const v_reg<_Tp, n>& a) +{ return v_reg<_Tp, n>::template reinterpret_as(a); } + +inline v_uint8x16 v_sat_u8(const v_uint16x8& a, const v_uint16x8& b) +{ return v_cvtsat(a, b); } +inline v_uint8x16 v_sat_u8(const v_uint16x8& a, const v_uint16x8& b, int n) +{ return v_cvtsat(a, b, n); } +inline v_uint8x16 v_sat_u8(const v_int16x8& a, const v_int16x8& b) +{ return v_cvtsat(a, b); } +inline v_uint8x16 v_sat_u8(const v_int16x8& a, const v_int16x8& b, int n) +{ return v_cvtsat(a, b, n); } + +inline void v_storesat_u8(uchar* ptr, const v_uint16x8& b) +{ return v_storesat(ptr, b); } +inline void v_storesat_u8(uchar* ptr, const v_uint16x8& b, int n) +{ return v_storesat(ptr, b, n); } +inline void v_storesat_u8(uchar* ptr, const v_int16x8& b) +{ return v_storesat(ptr, b); } +inline void v_storesat_u8(uchar* ptr, const v_int16x8& b, int n) +{ return v_storesat(ptr, b, n); } + +inline v_int8x16 v_sat_s8(const v_uint16x8& a, const v_uint16x8& b) +{ return v_cvtsat(a, b); } +inline v_int8x16 v_sat_s8(const v_uint16x8& a, const v_uint16x8& b, int n) +{ return v_cvtsat(a, b, n); } +inline v_int8x16 v_sat_s8(const v_int16x8& a, const v_int16x8& b) +{ return v_cvtsat(a, b); } +inline v_int8x16 v_sat_s8(const v_int16x8& a, const v_int16x8& b, int n) +{ return v_cvtsat(a, b, n); } + +inline void v_storesat_s8(schar* ptr, const v_uint16x8& b) +{ return v_storesat(ptr, b); } +inline void v_storesat_s8(schar* ptr, const v_uint16x8& b, int n) +{ return v_storesat(ptr, b, n); } +inline void v_storesat_s8(schar* ptr, const v_int16x8& b) +{ return v_storesat(ptr, b); } +inline void v_storesat_s8(schar* ptr, const v_int16x8& b, int n) +{ return v_storesat(ptr, b, n); } + +inline v_uint16x8 v_sat_u16(const v_uint32x4& a, const v_uint32x4& b) +{ return v_cvtsat(a, b); } +inline v_uint16x8 v_sat_u16(const v_uint32x4& a, const v_uint32x4& b, int n) +{ return v_cvtsat(a, b, n); } +inline v_uint16x8 v_sat_u16(const v_int32x4& a, const v_int32x4& b) +{ return v_cvtsat(a, b); } +inline v_uint16x8 v_sat_u16(const v_int32x4& a, const v_int32x4& b, int n) +{ return v_cvtsat(a, b, n); } + +inline void v_storesat_u16(ushort* ptr, const v_uint32x4& b) +{ return v_storesat(ptr, b); } +inline void v_storesat_u16(ushort* ptr, const v_uint32x4& b, int n) +{ return v_storesat(ptr, b, n); } +inline void v_storesat_u16(ushort* ptr, const v_int32x4& b) +{ return v_storesat(ptr, b); } +inline void v_storesat_u16(ushort* ptr, const v_int32x4& b, int n) +{ return v_storesat(ptr, b, n); } + +inline v_int16x8 v_sat_s16(const v_uint32x4& a, const v_uint32x4& b) +{ return v_cvtsat(a, b); } +inline v_int16x8 v_sat_s16(const v_uint32x4& a, const v_uint32x4& b, int n) +{ return v_cvtsat(a, b, n); } +inline v_int16x8 v_sat_s16(const v_int32x4& a, const v_int32x4& b) +{ return v_cvtsat(a, b); } +inline v_int16x8 v_sat_s16(const v_int32x4& a, const v_int32x4& b, int n) +{ return v_cvtsat(a, b, n); } + +inline void v_storesat_s16(short* ptr, const v_uint32x4& b) +{ return v_storesat(ptr, b); } +inline void v_storesat_s16(short* ptr, const v_uint32x4& b, int n) +{ return v_storesat(ptr, b, n); } +inline void v_storesat_s16(short* ptr, const v_int32x4& b) +{ return v_storesat(ptr, b); } +inline void v_storesat_s16(short* ptr, const v_int32x4& b, int n) +{ return v_storesat(ptr, b, n); } + +inline v_float32x4 v_matmul(const v_float32x4& v, const v_float32x4& m0, + const v_float32x4& m1, const v_float32x4& m2, + const v_float32x4& m3) +{ + return v_float32x4(v.s[0]*m0.s[0] + v.s[1]*m1.s[0] + v.s[2]*m2.s[0] + v.s[3]*m3.s[0], + v.s[0]*m0.s[1] + v.s[1]*m1.s[1] + v.s[2]*m2.s[1] + v.s[3]*m3.s[1], + v.s[0]*m0.s[2] + v.s[1]*m1.s[2] + v.s[2]*m2.s[2] + v.s[3]*m3.s[2], + v.s[0]*m0.s[3] + v.s[1]*m1.s[3] + v.s[2]*m2.s[3] + v.s[3]*m3.s[3]); +} + +#endif + +}} + +#endif diff --git a/modules/hal/src/arithm.cpp b/modules/hal/src/arithm.cpp new file mode 100644 index 0000000000..a3f69facca --- /dev/null +++ b/modules/hal/src/arithm.cpp @@ -0,0 +1,47 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +namespace cv { namespace hal { + +}} diff --git a/modules/hal/src/color.cpp b/modules/hal/src/color.cpp new file mode 100644 index 0000000000..a3f69facca --- /dev/null +++ b/modules/hal/src/color.cpp @@ -0,0 +1,47 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +namespace cv { namespace hal { + +}} diff --git a/modules/hal/src/filter.cpp b/modules/hal/src/filter.cpp new file mode 100644 index 0000000000..a3f69facca --- /dev/null +++ b/modules/hal/src/filter.cpp @@ -0,0 +1,47 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +namespace cv { namespace hal { + +}} diff --git a/modules/hal/src/mathfuncs.cpp b/modules/hal/src/mathfuncs.cpp new file mode 100644 index 0000000000..a3f69facca --- /dev/null +++ b/modules/hal/src/mathfuncs.cpp @@ -0,0 +1,47 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +namespace cv { namespace hal { + +}} diff --git a/modules/hal/src/matrix.cpp b/modules/hal/src/matrix.cpp new file mode 100644 index 0000000000..a3f69facca --- /dev/null +++ b/modules/hal/src/matrix.cpp @@ -0,0 +1,47 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +namespace cv { namespace hal { + +}} diff --git a/modules/hal/src/precomp.hpp b/modules/hal/src/precomp.hpp index 04ec378211..e6923fb897 100644 --- a/modules/hal/src/precomp.hpp +++ b/modules/hal/src/precomp.hpp @@ -1,2 +1,44 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ #include "opencv2/hal.hpp" +#include "opencv2/hal/intrin.hpp" diff --git a/modules/hal/src/resize.cpp b/modules/hal/src/resize.cpp new file mode 100644 index 0000000000..a3f69facca --- /dev/null +++ b/modules/hal/src/resize.cpp @@ -0,0 +1,47 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +namespace cv { namespace hal { + +}} diff --git a/modules/hal/src/norm.cpp b/modules/hal/src/stat.cpp similarity index 100% rename from modules/hal/src/norm.cpp rename to modules/hal/src/stat.cpp diff --git a/modules/hal/src/warp.cpp b/modules/hal/src/warp.cpp new file mode 100644 index 0000000000..a3f69facca --- /dev/null +++ b/modules/hal/src/warp.cpp @@ -0,0 +1,47 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +namespace cv { namespace hal { + +}} From cb00c7036f10b2b56d608113a3d1a433fab82bed Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Wed, 15 Apr 2015 15:46:07 +0300 Subject: [PATCH 048/109] Fix cache error during SVM train --- modules/ml/src/svm.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/ml/src/svm.cpp b/modules/ml/src/svm.cpp index 05994eb918..0012a33887 100644 --- a/modules/ml/src/svm.cpp +++ b/modules/ml/src/svm.cpp @@ -538,6 +538,8 @@ public: { kr.idx = cache_size; cache_size++; + if (!lru_last) + lru_last = i1+1; } else { @@ -546,6 +548,8 @@ public: last.idx = -1; lru_cache[last.prev].next = 0; lru_last = last.prev; + last.prev = 0; + last.next = 0; } kernel->calc( sample_count, var_count, samples.ptr(), samples.ptr(i1), lru_cache_data.ptr(kr.idx) ); @@ -561,6 +565,8 @@ public: else lru_first = kr.next; } + if (lru_first) + lru_cache[lru_first].prev = i1+1; kr.next = lru_first; kr.prev = 0; lru_first = i1+1; From a0bc0ab7cb7ee4eeb4e9f79cfbaace267fcf203e Mon Sep 17 00:00:00 2001 From: Nisarg Thakkar Date: Wed, 15 Apr 2015 23:49:01 +0530 Subject: [PATCH 049/109] Fix for Bug4243 --- modules/imgproc/src/morph.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/modules/imgproc/src/morph.cpp b/modules/imgproc/src/morph.cpp index 44eb3adfc0..78c0e4f0aa 100644 --- a/modules/imgproc/src/morph.cpp +++ b/modules/imgproc/src/morph.cpp @@ -1820,11 +1820,22 @@ static bool ocl_morphologyEx(InputArray _src, OutputArray _dst, int op, #endif void cv::morphologyEx( InputArray _src, OutputArray _dst, int op, - InputArray kernel, Point anchor, int iterations, + InputArray _kernel, Point anchor, int iterations, int borderType, const Scalar& borderValue ) { #ifdef HAVE_OPENCL - Size ksize = kernel.size(); + Size ksize = _kernel.size(); + Mat tempKernel; + if (ksize.height==0 || ksize.width==0) + { + tempKernel = getStructuringElement(MORPH_RECT, Size(3,3), Point(1,1)); + ksize = tempKernel.size(); + } + else + { + tempKernel = _kernel.getMat(); + } + InputArray kernel = InputArray(tempKernel); anchor = normalizeAnchor(anchor, ksize); CV_OCL_RUN(_dst.isUMat() && _src.dims() <= 2 && _src.channels() <= 4 && From 00094a879280f89acaad8f1d48bd8a873957e32b Mon Sep 17 00:00:00 2001 From: Nisarg Thakkar Date: Thu, 16 Apr 2015 00:22:08 +0530 Subject: [PATCH 050/109] Fix for Bug4243. Made changes relating to non OpenCL devices --- modules/imgproc/src/morph.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/modules/imgproc/src/morph.cpp b/modules/imgproc/src/morph.cpp index 78c0e4f0aa..f2d971bea3 100644 --- a/modules/imgproc/src/morph.cpp +++ b/modules/imgproc/src/morph.cpp @@ -1823,19 +1823,13 @@ void cv::morphologyEx( InputArray _src, OutputArray _dst, int op, InputArray _kernel, Point anchor, int iterations, int borderType, const Scalar& borderValue ) { + Mat kernel = _kernel.getMat(); + if (kernel.empty()) + { + kernel = getStructuringElement(MORPH_RECT, Size(3,3), Point(1,1)); + } #ifdef HAVE_OPENCL - Size ksize = _kernel.size(); - Mat tempKernel; - if (ksize.height==0 || ksize.width==0) - { - tempKernel = getStructuringElement(MORPH_RECT, Size(3,3), Point(1,1)); - ksize = tempKernel.size(); - } - else - { - tempKernel = _kernel.getMat(); - } - InputArray kernel = InputArray(tempKernel); + Size ksize = kernel.size(); anchor = normalizeAnchor(anchor, ksize); CV_OCL_RUN(_dst.isUMat() && _src.dims() <= 2 && _src.channels() <= 4 && From 2358c79db2465ffdaf333939eba4489b1f4790d6 Mon Sep 17 00:00:00 2001 From: Ahmatnurov Dinar Date: Thu, 16 Apr 2015 14:36:46 +0300 Subject: [PATCH 051/109] move 3265 to 3.0; --- modules/imgcodecs/test/test_drawing.cpp | 78 +++++++++++++++++++++++++ modules/imgproc/src/drawing.cpp | 56 ++++++++++++++++-- 2 files changed, 129 insertions(+), 5 deletions(-) diff --git a/modules/imgcodecs/test/test_drawing.cpp b/modules/imgcodecs/test/test_drawing.cpp index f4e157fb20..d6d76822b5 100644 --- a/modules/imgcodecs/test/test_drawing.cpp +++ b/modules/imgcodecs/test/test_drawing.cpp @@ -448,3 +448,81 @@ protected: }; TEST(Imgcodecs_Drawing, fillconvexpoly_clipping) { CV_FillConvexPolyTest test; test.safe_run(); } + +class CV_DrawingTest_UTF8 : public cvtest::BaseTest +{ +public: + CV_DrawingTest_UTF8() {} + ~CV_DrawingTest_UTF8() {} +protected: + void run(int) + { + vector lines; + lines.push_back("abcdefghijklmnopqrstuvwxyz1234567890"); + // cyrillic letters small + lines.push_back("\xD0\xB0\xD0\xB1\xD0\xB2\xD0\xB3\xD0\xB4\xD0\xB5\xD1\x91\xD0\xB6\xD0\xB7" + "\xD0\xB8\xD0\xB9\xD0\xBA\xD0\xBB\xD0\xBC\xD0\xBD\xD0\xBE\xD0\xBF\xD1\x80" + "\xD1\x81\xD1\x82\xD1\x83\xD1\x84\xD1\x85\xD1\x86\xD1\x87\xD1\x88\xD1\x89" + "\xD1\x8A\xD1\x8B\xD1\x8C\xD1\x8D\xD1\x8E\xD1\x8F"); + // cyrillic letters capital + lines.push_back("\xD0\x90\xD0\x91\xD0\x92\xD0\x93\xD0\x94\xD0\x95\xD0\x81\xD0\x96\xD0\x97" + "\xD0\x98\xD0\x99\xD0\x9A\xD0\x9B\xD0\x9C\xD0\x9D\xD0\x9E\xD0\x9F\xD0\xA0" + "\xD0\xA1\xD0\xA2\xD0\xA3\xD0\xA4\xD0\xA5\xD0\xA6\xD0\xA7\xD0\xA8\xD0\xA9" + "\xD0\xAA\xD0\xAB\xD0\xAC\xD0\xAD\xD0\xAE\xD0\xAF"); + // bounds + lines.push_back("-\xD0\x80-\xD0\x8E-\xD0\x8F-"); + lines.push_back("-\xD1\x90-\xD1\x91-\xD1\xBF-"); + // bad utf8 + lines.push_back("-\x81-\x82-\x83-"); + lines.push_back("--\xF0--"); + lines.push_back("-\xF0"); + + vector fonts; + fonts.push_back(FONT_HERSHEY_SIMPLEX); + fonts.push_back(FONT_HERSHEY_PLAIN); + fonts.push_back(FONT_HERSHEY_DUPLEX); + fonts.push_back(FONT_HERSHEY_COMPLEX); + fonts.push_back(FONT_HERSHEY_TRIPLEX); + fonts.push_back(FONT_HERSHEY_COMPLEX_SMALL); + fonts.push_back(FONT_HERSHEY_SCRIPT_SIMPLEX); + fonts.push_back(FONT_HERSHEY_SCRIPT_COMPLEX); + + vector results; + Size bigSize(0, 0); + for (vector::const_iterator font = fonts.begin(); font != fonts.end(); ++font) + { + for (int italic = 0; italic <= FONT_ITALIC; italic += FONT_ITALIC) + { + for (vector::const_iterator line = lines.begin(); line != lines.end(); ++line) + { + const float fontScale = 1; + const int thickness = 1; + const Scalar color(20,20,20); + int baseline = 0; + + Size textSize = getTextSize(*line, *font | italic, fontScale, thickness, &baseline); + Point textOrg(0, textSize.height + 2); + Mat img(textSize + Size(0, baseline), CV_8UC3, Scalar(255, 255, 255)); + putText(img, *line, textOrg, *font | italic, fontScale, color, thickness, CV_AA); + + results.push_back(img); + bigSize.width = max(bigSize.width, img.size().width); + bigSize.height += img.size().height + 1; + } + } + } + + int shift = 0; + Mat result(bigSize, CV_8UC3, Scalar(100, 100, 100)); + for (vector::const_iterator img = results.begin(); img != results.end(); ++img) + { + Rect roi(Point(0, shift), img->size()); + Mat sub(result, roi); + img->copyTo(sub); + shift += img->size().height + 1; + } + imwrite("/tmp/all_fonts.png", result); + } +}; + +TEST(Highgui_Drawing, utf8_support) { CV_DrawingTest_UTF8 test; test.safe_run(); } diff --git a/modules/imgproc/src/drawing.cpp b/modules/imgproc/src/drawing.cpp index 94aef348f0..27411b247a 100644 --- a/modules/imgproc/src/drawing.cpp +++ b/modules/imgproc/src/drawing.cpp @@ -1941,7 +1941,11 @@ static const int HersheyComplex[] = { 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2223, 2084, 2224, 2247, 587, 2249, 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111, 2112, 2113, 2114, 2115, 2116, 2117, 2118, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 2126, -2225, 2229, 2226, 2246 }; +2225, 2229, 2226, 2246, 2801, 2802, 2803, 2804, 2805, 2806, 2807, 2808, 2809, 2810, 2811, +2812, 2813, 2814, 2815, 2816, 2817, 2818, 2819, 2820, 2821, 2822, 2823, 2824, 2825, 2826, +2827, 2828, 2829, 2830, 2831, 2832, 2901, 2902, 2903, 2904, 2905, 2906, 2907, 2908, 2909, +2910, 2911, 2912, 2913, 2914, 2915, 2916, 2917, 2918, 2919, 2920, 2921, 2922, 2923, 2924, +2925, 2926, 2927, 2928, 2929, 2930, 2931, 2932}; static const int HersheyComplexItalic[] = { (9 + 12*16) + FONT_ITALIC_ALPHA + FONT_ITALIC_DIGIT + FONT_ITALIC_PUNCT + @@ -2033,6 +2037,50 @@ static const int* getFontData(int fontFace) return ascii; } +inline void readCheck(int &c, int &i, const String &text, int fontFace) +{ + + int leftBoundary = ' ', rightBoundary = 127; + + if(c >= 0x80 && fontFace == FONT_HERSHEY_COMPLEX) + { + if(c == 0xD0 && (uchar)text[i + 1] >= 0x90 && (uchar)text[i + 1] <= 0xBF) + { + c = (uchar)text[++i] - 17; + leftBoundary = 127; + rightBoundary = 175; + } + else if(c == 0xD1 && (uchar)text[i + 1] >= 0x80 && (uchar)text[i + 1] <= 0x8F) + { + c = (uchar)text[++i] + 47; + leftBoundary = 175; + rightBoundary = 191; + } + else + { + if(c >= 0xC0 && text[i+1] != 0) //2 bytes utf + i++; + + if(c >= 0xE0 && text[i+1] != 0) //3 bytes utf + i++; + + if(c >= 0xF0 && text[i+1] != 0) //4 bytes utf + i++; + + if(c >= 0xF8 && text[i+1] != 0) //5 bytes utf + i++; + + if(c >= 0xFC && text[i+1] != 0) //6 bytes utf + i++; + + c = '?'; + } + } + + if(c >= rightBoundary || c < leftBoundary) + c = '?'; +} + extern const char* g_HersheyGlyphs[]; void putText( InputOutputArray _img, const String& text, Point org, @@ -2066,8 +2114,7 @@ void putText( InputOutputArray _img, const String& text, Point org, int c = (uchar)text[i]; Point p; - if( c >= 127 || c < ' ' ) - c = '?'; + readCheck(c, i, text, fontFace); const char* ptr = faces[ascii[(c-' ')+1]]; p.x = (uchar)ptr[0] - 'R'; @@ -2114,8 +2161,7 @@ Size getTextSize( const String& text, int fontFace, double fontScale, int thickn int c = (uchar)text[i]; Point p; - if( c >= 127 || c < ' ' ) - c = '?'; + readCheck(c, i, text, fontFace); const char* ptr = faces[ascii[(c-' ')+1]]; p.x = (uchar)ptr[0] - 'R'; From bb0631a365bd09cda1045c5f4a5bac3ff6ef0f9c Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Thu, 16 Apr 2015 17:33:38 +0300 Subject: [PATCH 052/109] Add sample cmake project --- samples/cpp/example_cmake/CMakeLists.txt | 28 +++++++++++++ samples/cpp/example_cmake/example.cpp | 50 ++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 samples/cpp/example_cmake/CMakeLists.txt create mode 100644 samples/cpp/example_cmake/example.cpp diff --git a/samples/cpp/example_cmake/CMakeLists.txt b/samples/cpp/example_cmake/CMakeLists.txt new file mode 100644 index 0000000000..fe7e629812 --- /dev/null +++ b/samples/cpp/example_cmake/CMakeLists.txt @@ -0,0 +1,28 @@ +# cmake needs this line +cmake_minimum_required(VERSION 2.8) + +# Define project name +project(opencv_example_project) + +# Find OpenCV, you may need to set OpenCV_DIR variable +# to the absolute path to the directory containing OpenCVConfig.cmake file +# via the command line or GUI +find_package(OpenCV REQUIRED) + +# If the package has been found, several variables will +# be set, you can find the full list with descriptions +# in the OpenCVConfig.cmake file. +# Print some message showing some of them +message(STATUS "OpenCV library status:") +message(STATUS " version: ${OpenCV_VERSION}") +message(STATUS " libraries: ${OpenCV_LIBS}") +message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}") + +# Add OpenCV headers location to your include paths +include_directories(${OpenCV_INCLUDE_DIRS}) + +# Declare the executable target built from your sources +add_executable(opencv_example example.cpp) + +# Link your application with OpenCV libraries +target_link_libraries(opencv_example ${OpenCV_LIBS}) diff --git a/samples/cpp/example_cmake/example.cpp b/samples/cpp/example_cmake/example.cpp new file mode 100644 index 0000000000..cac5050b2d --- /dev/null +++ b/samples/cpp/example_cmake/example.cpp @@ -0,0 +1,50 @@ +#include "opencv2/core.hpp" +#include "opencv2/imgproc.hpp" +#include "opencv2/highgui.hpp" +#include "opencv2/videoio.hpp" +#include + +using namespace cv; +using namespace std; + +void drawText(Mat & image); + +int main() +{ + cout << "Built with OpenCV " << CV_VERSION << endl; + Mat image; + VideoCapture capture; + capture.open(0); + if(capture.isOpened()) + { + cout << "Capture is opened" << endl; + for(;;) + { + capture >> image; + if(image.empty()) + break; + drawText(image); + imshow("Sample", image); + if(waitKey(10) >= 0) + break; + } + } + else + { + cout << "No capture" << endl; + image = Mat::zeros(480, 640, CV_8UC1); + drawText(image); + imshow("Sample", image); + waitKey(0); + } + return 0; +} + +void drawText(Mat & image) +{ + putText(image, "Hello OpenCV", + Point(20, 50), + FONT_HERSHEY_COMPLEX, 1, // font face and scale + Scalar(255, 255, 255), // white + 1, LINE_AA); // line thickness and type +} From b80142be69dcad9aacc0de40d7c89fb11e3f232f Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Thu, 16 Apr 2015 17:34:15 +0300 Subject: [PATCH 053/109] Fix an issue in cmake tutorial --- .../introduction/linux_gcc_cmake/linux_gcc_cmake.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/tutorials/introduction/linux_gcc_cmake/linux_gcc_cmake.markdown b/doc/tutorials/introduction/linux_gcc_cmake/linux_gcc_cmake.markdown index 4f4adbed88..fd447307a7 100644 --- a/doc/tutorials/introduction/linux_gcc_cmake/linux_gcc_cmake.markdown +++ b/doc/tutorials/introduction/linux_gcc_cmake/linux_gcc_cmake.markdown @@ -53,9 +53,9 @@ Now you have to create your CMakeLists.txt file. It should look like this: cmake_minimum_required(VERSION 2.8) project( DisplayImage ) find_package( OpenCV REQUIRED ) -include_directories( \f${OpenCV_INCLUDE_DIRS} ) +include_directories( ${OpenCV_INCLUDE_DIRS} ) add_executable( DisplayImage DisplayImage.cpp ) -target_link_libraries( DisplayImage \f${OpenCV_LIBS} ) +target_link_libraries( DisplayImage ${OpenCV_LIBS} ) @endcode ### Generate the executable From 103336c76e4c4352193182ed441a40b89a9eb75d Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Thu, 16 Apr 2015 11:59:05 -0400 Subject: [PATCH 054/109] Fix Bug #3989: correctly identify ellipse with its axes parallel to x-y axes during semi-major axis calculation --- modules/imgproc/src/shapedescr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/imgproc/src/shapedescr.cpp b/modules/imgproc/src/shapedescr.cpp index 5e0c432d9c..65eddfd1af 100644 --- a/modules/imgproc/src/shapedescr.cpp +++ b/modules/imgproc/src/shapedescr.cpp @@ -447,9 +447,9 @@ cv::RotatedRect cv::fitEllipse( InputArray _points ) // store angle and radii rp[4] = -0.5 * atan2(gfp[2], gfp[1] - gfp[0]); // convert from APP angle usage t = sin(-2.0 * rp[4]); - if( fabs(t) > fabs(gfp[2])*min_eps ) + if( fabs(t) > min_eps ) t = gfp[2]/t; - else + else // ellipse is rotated by an integer multiple of pi/2 t = gfp[1] - gfp[0]; rp[2] = fabs(gfp[0] + gfp[1] - t); if( rp[2] > min_eps ) From ee11a2d266343e4af94875543503ad39ea2d2f4e Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Thu, 16 Apr 2015 23:00:26 +0300 Subject: [PATCH 055/109] fully implemented SSE and NEON cases of intrin.hpp; extended the HAL with some basic math functions --- modules/calib3d/test/test_fisheye.cpp | 2 +- modules/core/include/opencv2/core/base.hpp | 47 +- modules/core/include/opencv2/core/matx.hpp | 2 +- .../core/include/opencv2/core/operations.hpp | 4 +- modules/core/src/kmeans.cpp | 8 +- modules/core/src/lapack.cpp | 182 +- modules/core/src/mathfuncs.cpp | 1489 +---------------- modules/core/src/stat.cpp | 166 +- modules/features2d/src/kaze/AKAZEFeatures.cpp | 2 +- modules/hal/include/opencv2/hal.hpp | 25 +- modules/hal/include/opencv2/hal/defs.h | 4 +- modules/hal/include/opencv2/hal/intrin.hpp | 901 ++++++++-- modules/hal/src/mathfuncs.cpp | 1305 +++++++++++++++ modules/hal/src/matrix.cpp | 161 ++ modules/hal/src/precomp.hpp | 4 + modules/hal/src/stat.cpp | 154 +- modules/photo/src/arrays.hpp | 5 + modules/stitching/src/autocalib.cpp | 2 +- 18 files changed, 2460 insertions(+), 2003 deletions(-) diff --git a/modules/calib3d/test/test_fisheye.cpp b/modules/calib3d/test/test_fisheye.cpp index 553b81c39b..d4212e94fc 100644 --- a/modules/calib3d/test/test_fisheye.cpp +++ b/modules/calib3d/test/test_fisheye.cpp @@ -381,7 +381,7 @@ TEST_F(fisheyeTest, EtimateUncertainties) EXPECT_MAT_NEAR(errors.c, cv::Vec2d(0.890439368129246, 0.816096854937896), 1e-10); EXPECT_MAT_NEAR(errors.k, cv::Vec4d(0.00516248605191506, 0.0168181467500934, 0.0213118690274604, 0.00916010877545648), 1e-10); EXPECT_MAT_NEAR(err_std, cv::Vec2d(0.187475975266883, 0.185678953263995), 1e-10); - CV_Assert(abs(rms - 0.263782587133546) < 1e-10); + CV_Assert(fabs(rms - 0.263782587133546) < 1e-10); CV_Assert(errors.alpha == 0); } diff --git a/modules/core/include/opencv2/core/base.hpp b/modules/core/include/opencv2/core/base.hpp index 83661a2fd6..e4efe0fb9b 100644 --- a/modules/core/include/opencv2/core/base.hpp +++ b/modules/core/include/opencv2/core/base.hpp @@ -53,6 +53,7 @@ #include "opencv2/core/cvdef.h" #include "opencv2/core/cvstd.hpp" +#include "opencv2/hal.hpp" namespace cv { @@ -419,6 +420,12 @@ typedef Hamming HammingLUT; /////////////////////////////////// inline norms //////////////////////////////////// +template inline _Tp cv_abs(_Tp x) { return std::abs(x); } +inline int cv_abs(uchar x) { return x; } +inline int cv_abs(schar x) { return std::abs(x); } +inline int cv_abs(ushort x) { return x; } +inline int cv_abs(short x) { return std::abs(x); } + template static inline _AccTp normL2Sqr(const _Tp* a, int n) { @@ -447,12 +454,12 @@ _AccTp normL1(const _Tp* a, int n) #if CV_ENABLE_UNROLLED for(; i <= n - 4; i += 4 ) { - s += (_AccTp)std::abs(a[i]) + (_AccTp)std::abs(a[i+1]) + - (_AccTp)std::abs(a[i+2]) + (_AccTp)std::abs(a[i+3]); + s += (_AccTp)cv_abs(a[i]) + (_AccTp)cv_abs(a[i+1]) + + (_AccTp)cv_abs(a[i+2]) + (_AccTp)cv_abs(a[i+3]); } #endif for( ; i < n; i++ ) - s += std::abs(a[i]); + s += cv_abs(a[i]); return s; } @@ -461,7 +468,7 @@ _AccTp normInf(const _Tp* a, int n) { _AccTp s = 0; for( int i = 0; i < n; i++ ) - s = std::max(s, (_AccTp)std::abs(a[i])); + s = std::max(s, (_AccTp)cv_abs(a[i])); return s; } @@ -485,11 +492,10 @@ _AccTp normL2Sqr(const _Tp* a, const _Tp* b, int n) return s; } -template<> inline -float normL2Sqr(const float* a, const float* b, int n) +inline float normL2Sqr(const float* a, const float* b, int n) { if( n >= 8 ) - return normL2Sqr_(a, b, n); + return hal::normL2Sqr_(a, b, n); float s = 0; for( int i = 0; i < n; i++ ) { @@ -519,11 +525,10 @@ _AccTp normL1(const _Tp* a, const _Tp* b, int n) return s; } -template<> inline -float normL1(const float* a, const float* b, int n) +inline float normL1(const float* a, const float* b, int n) { if( n >= 8 ) - return normL1_(a, b, n); + return hal::normL1_(a, b, n); float s = 0; for( int i = 0; i < n; i++ ) { @@ -533,10 +538,9 @@ float normL1(const float* a, const float* b, int n) return s; } -template<> inline -int normL1(const uchar* a, const uchar* b, int n) +inline int normL1(const uchar* a, const uchar* b, int n) { - return normL1_(a, b, n); + return hal::normL1_(a, b, n); } template static inline @@ -551,6 +555,23 @@ _AccTp normInf(const _Tp* a, const _Tp* b, int n) return s; } +/** @brief Computes the cube root of an argument. + + The function cubeRoot computes \f$\sqrt[3]{\texttt{val}}\f$. Negative arguments are handled correctly. + NaN and Inf are not handled. The accuracy approaches the maximum possible accuracy for + single-precision data. + @param val A function argument. + */ +CV_EXPORTS_W float cubeRoot(float val); + +/** @brief Calculates the angle of a 2D vector in degrees. + + The function fastAtan2 calculates the full-range angle of an input 2D vector. The angle is measured + in degrees and varies from 0 to 360 degrees. The accuracy is about 0.3 degrees. + @param x x-coordinate of the vector. + @param y y-coordinate of the vector. + */ +CV_EXPORTS_W float fastAtan2(float y, float x); ////////////////// forward declarations for important OpenCV types ////////////////// diff --git a/modules/core/include/opencv2/core/matx.hpp b/modules/core/include/opencv2/core/matx.hpp index 6cc5d06251..e9023243e8 100644 --- a/modules/core/include/opencv2/core/matx.hpp +++ b/modules/core/include/opencv2/core/matx.hpp @@ -427,7 +427,7 @@ template struct Matx_DetOp double operator ()(const Matx<_Tp, m, m>& a) const { Matx<_Tp, m, m> temp = a; - double p = LU(temp.val, m*sizeof(_Tp), m, 0, 0, 0); + double p = hal::LU(temp.val, m*sizeof(_Tp), m, 0, 0, 0); if( p == 0 ) return p; for( int i = 0; i < m; i++ ) diff --git a/modules/core/include/opencv2/core/operations.hpp b/modules/core/include/opencv2/core/operations.hpp index bced1a7559..2c42e1f3a3 100644 --- a/modules/core/include/opencv2/core/operations.hpp +++ b/modules/core/include/opencv2/core/operations.hpp @@ -72,9 +72,9 @@ template struct Matx_FastInvOp b(i, i) = (_Tp)1; if( method == DECOMP_CHOLESKY ) - return Cholesky(temp.val, m*sizeof(_Tp), m, b.val, m*sizeof(_Tp), m); + return hal::Cholesky(temp.val, m*sizeof(_Tp), m, b.val, m*sizeof(_Tp), m); - return LU(temp.val, m*sizeof(_Tp), m, b.val, m*sizeof(_Tp), m) != 0; + return hal::LU(temp.val, m*sizeof(_Tp), m, b.val, m*sizeof(_Tp), m) != 0; } }; diff --git a/modules/core/src/kmeans.cpp b/modules/core/src/kmeans.cpp index cc86d2972d..fe5a0cf6e9 100644 --- a/modules/core/src/kmeans.cpp +++ b/modules/core/src/kmeans.cpp @@ -79,7 +79,7 @@ public: for ( int i = begin; i(k); - const double dist = normL2Sqr_(sample, center, dims); + const double dist = normL2Sqr(sample, center, dims); if( min_dist > dist ) { @@ -384,7 +384,7 @@ double cv::kmeans( InputArray _data, int K, if( labels[i] != max_k ) continue; sample = data.ptr(i); - double dist = normL2Sqr_(sample, _old_center, dims); + double dist = normL2Sqr(sample, _old_center, dims); if( max_dist <= dist ) { diff --git a/modules/core/src/lapack.cpp b/modules/core/src/lapack.cpp index a766e5f2ed..dea25dd64c 100644 --- a/modules/core/src/lapack.cpp +++ b/modules/core/src/lapack.cpp @@ -50,168 +50,6 @@ namespace cv { -/****************************************************************************************\ -* LU & Cholesky implementation for small matrices * -\****************************************************************************************/ - -template static inline int -LUImpl(_Tp* A, size_t astep, int m, _Tp* b, size_t bstep, int n) -{ - int i, j, k, p = 1; - astep /= sizeof(A[0]); - bstep /= sizeof(b[0]); - - for( i = 0; i < m; i++ ) - { - k = i; - - for( j = i+1; j < m; j++ ) - if( std::abs(A[j*astep + i]) > std::abs(A[k*astep + i]) ) - k = j; - - if( std::abs(A[k*astep + i]) < std::numeric_limits<_Tp>::epsilon() ) - return 0; - - if( k != i ) - { - for( j = i; j < m; j++ ) - std::swap(A[i*astep + j], A[k*astep + j]); - if( b ) - for( j = 0; j < n; j++ ) - std::swap(b[i*bstep + j], b[k*bstep + j]); - p = -p; - } - - _Tp d = -1/A[i*astep + i]; - - for( j = i+1; j < m; j++ ) - { - _Tp alpha = A[j*astep + i]*d; - - for( k = i+1; k < m; k++ ) - A[j*astep + k] += alpha*A[i*astep + k]; - - if( b ) - for( k = 0; k < n; k++ ) - b[j*bstep + k] += alpha*b[i*bstep + k]; - } - - A[i*astep + i] = -d; - } - - if( b ) - { - for( i = m-1; i >= 0; i-- ) - for( j = 0; j < n; j++ ) - { - _Tp s = b[i*bstep + j]; - for( k = i+1; k < m; k++ ) - s -= A[i*astep + k]*b[k*bstep + j]; - b[i*bstep + j] = s*A[i*astep + i]; - } - } - - return p; -} - - -int LU(float* A, size_t astep, int m, float* b, size_t bstep, int n) -{ - return LUImpl(A, astep, m, b, bstep, n); -} - - -int LU(double* A, size_t astep, int m, double* b, size_t bstep, int n) -{ - return LUImpl(A, astep, m, b, bstep, n); -} - - -template static inline bool -CholImpl(_Tp* A, size_t astep, int m, _Tp* b, size_t bstep, int n) -{ - _Tp* L = A; - int i, j, k; - double s; - astep /= sizeof(A[0]); - bstep /= sizeof(b[0]); - - for( i = 0; i < m; i++ ) - { - for( j = 0; j < i; j++ ) - { - s = A[i*astep + j]; - for( k = 0; k < j; k++ ) - s -= L[i*astep + k]*L[j*astep + k]; - L[i*astep + j] = (_Tp)(s*L[j*astep + j]); - } - s = A[i*astep + i]; - for( k = 0; k < j; k++ ) - { - double t = L[i*astep + k]; - s -= t*t; - } - if( s < std::numeric_limits<_Tp>::epsilon() ) - return false; - L[i*astep + i] = (_Tp)(1./std::sqrt(s)); - } - - if( !b ) - return true; - - // LLt x = b - // 1: L y = b - // 2. Lt x = y - - /* - [ L00 ] y0 b0 - [ L10 L11 ] y1 = b1 - [ L20 L21 L22 ] y2 b2 - [ L30 L31 L32 L33 ] y3 b3 - - [ L00 L10 L20 L30 ] x0 y0 - [ L11 L21 L31 ] x1 = y1 - [ L22 L32 ] x2 y2 - [ L33 ] x3 y3 - */ - - for( i = 0; i < m; i++ ) - { - for( j = 0; j < n; j++ ) - { - s = b[i*bstep + j]; - for( k = 0; k < i; k++ ) - s -= L[i*astep + k]*b[k*bstep + j]; - b[i*bstep + j] = (_Tp)(s*L[i*astep + i]); - } - } - - for( i = m-1; i >= 0; i-- ) - { - for( j = 0; j < n; j++ ) - { - s = b[i*bstep + j]; - for( k = m-1; k > i; k-- ) - s -= L[k*astep + i]*b[k*bstep + j]; - b[i*bstep + j] = (_Tp)(s*L[i*astep + i]); - } - } - - return true; -} - - -bool Cholesky(float* A, size_t astep, int m, float* b, size_t bstep, int n) -{ - return CholImpl(A, astep, m, b, bstep, n); -} - -bool Cholesky(double* A, size_t astep, int m, double* b, size_t bstep, int n) -{ - return CholImpl(A, astep, m, b, bstep, n); -} - - template static inline _Tp hypot(_Tp a, _Tp b) { a = std::abs(a); @@ -882,7 +720,7 @@ double cv::determinant( InputArray _mat ) Mat a(rows, rows, CV_32F, (uchar*)buffer); mat.copyTo(a); - result = LU(a.ptr(), a.step, rows, 0, 0, 0); + result = hal::LU(a.ptr(), a.step, rows, 0, 0, 0); if( result ) { for( int i = 0; i < rows; i++ ) @@ -906,7 +744,7 @@ double cv::determinant( InputArray _mat ) Mat a(rows, rows, CV_64F, (uchar*)buffer); mat.copyTo(a); - result = LU(a.ptr(), a.step, rows, 0, 0, 0); + result = hal::LU(a.ptr(), a.step, rows, 0, 0, 0); if( result ) { for( int i = 0; i < rows; i++ ) @@ -1169,13 +1007,13 @@ double cv::invert( InputArray _src, OutputArray _dst, int method ) setIdentity(dst); if( method == DECOMP_LU && type == CV_32F ) - result = LU(src1.ptr(), src1.step, n, dst.ptr(), dst.step, n) != 0; + result = hal::LU(src1.ptr(), src1.step, n, dst.ptr(), dst.step, n) != 0; else if( method == DECOMP_LU && type == CV_64F ) - result = LU(src1.ptr(), src1.step, n, dst.ptr(), dst.step, n) != 0; + result = hal::LU(src1.ptr(), src1.step, n, dst.ptr(), dst.step, n) != 0; else if( method == DECOMP_CHOLESKY && type == CV_32F ) - result = Cholesky(src1.ptr(), src1.step, n, dst.ptr(), dst.step, n); + result = hal::Cholesky(src1.ptr(), src1.step, n, dst.ptr(), dst.step, n); else - result = Cholesky(src1.ptr(), src1.step, n, dst.ptr(), dst.step, n); + result = hal::Cholesky(src1.ptr(), src1.step, n, dst.ptr(), dst.step, n); if( !result ) dst = Scalar(0); @@ -1407,16 +1245,16 @@ bool cv::solve( InputArray _src, InputArray _src2arg, OutputArray _dst, int meth if( method == DECOMP_LU ) { if( type == CV_32F ) - result = LU(a.ptr(), a.step, n, dst.ptr(), dst.step, nb) != 0; + result = hal::LU(a.ptr(), a.step, n, dst.ptr(), dst.step, nb) != 0; else - result = LU(a.ptr(), a.step, n, dst.ptr(), dst.step, nb) != 0; + result = hal::LU(a.ptr(), a.step, n, dst.ptr(), dst.step, nb) != 0; } else if( method == DECOMP_CHOLESKY ) { if( type == CV_32F ) - result = Cholesky(a.ptr(), a.step, n, dst.ptr(), dst.step, nb); + result = hal::Cholesky(a.ptr(), a.step, n, dst.ptr(), dst.step, nb); else - result = Cholesky(a.ptr(), a.step, n, dst.ptr(), dst.step, nb); + result = hal::Cholesky(a.ptr(), a.step, n, dst.ptr(), dst.step, nb); } else { diff --git a/modules/core/src/mathfuncs.cpp b/modules/core/src/mathfuncs.cpp index 446b62731b..e96eaeb41a 100644 --- a/modules/core/src/mathfuncs.cpp +++ b/modules/core/src/mathfuncs.cpp @@ -121,107 +121,6 @@ float fastAtan2( float y, float x ) return a; } -static void FastAtan2_32f(const float *Y, const float *X, float *angle, int len, bool angleInDegrees=true ) -{ - int i = 0; - float scale = angleInDegrees ? 1 : (float)(CV_PI/180); - -#ifdef HAVE_TEGRA_OPTIMIZATION - if (tegra::useTegra() && tegra::FastAtan2_32f(Y, X, angle, len, scale)) - return; -#endif - -#if CV_SSE2 - if( USE_SSE2 ) - { - Cv32suf iabsmask; iabsmask.i = 0x7fffffff; - __m128 eps = _mm_set1_ps((float)DBL_EPSILON), absmask = _mm_set1_ps(iabsmask.f); - __m128 _90 = _mm_set1_ps(90.f), _180 = _mm_set1_ps(180.f), _360 = _mm_set1_ps(360.f); - __m128 z = _mm_setzero_ps(), scale4 = _mm_set1_ps(scale); - __m128 p1 = _mm_set1_ps(atan2_p1), p3 = _mm_set1_ps(atan2_p3); - __m128 p5 = _mm_set1_ps(atan2_p5), p7 = _mm_set1_ps(atan2_p7); - - for( ; i <= len - 4; i += 4 ) - { - __m128 x = _mm_loadu_ps(X + i), y = _mm_loadu_ps(Y + i); - __m128 ax = _mm_and_ps(x, absmask), ay = _mm_and_ps(y, absmask); - __m128 mask = _mm_cmplt_ps(ax, ay); - __m128 tmin = _mm_min_ps(ax, ay), tmax = _mm_max_ps(ax, ay); - __m128 c = _mm_div_ps(tmin, _mm_add_ps(tmax, eps)); - __m128 c2 = _mm_mul_ps(c, c); - __m128 a = _mm_mul_ps(c2, p7); - a = _mm_mul_ps(_mm_add_ps(a, p5), c2); - a = _mm_mul_ps(_mm_add_ps(a, p3), c2); - a = _mm_mul_ps(_mm_add_ps(a, p1), c); - - __m128 b = _mm_sub_ps(_90, a); - a = _mm_xor_ps(a, _mm_and_ps(_mm_xor_ps(a, b), mask)); - - b = _mm_sub_ps(_180, a); - mask = _mm_cmplt_ps(x, z); - a = _mm_xor_ps(a, _mm_and_ps(_mm_xor_ps(a, b), mask)); - - b = _mm_sub_ps(_360, a); - mask = _mm_cmplt_ps(y, z); - a = _mm_xor_ps(a, _mm_and_ps(_mm_xor_ps(a, b), mask)); - - a = _mm_mul_ps(a, scale4); - _mm_storeu_ps(angle + i, a); - } - } -#elif CV_NEON - float32x4_t eps = vdupq_n_f32((float)DBL_EPSILON); - float32x4_t _90 = vdupq_n_f32(90.f), _180 = vdupq_n_f32(180.f), _360 = vdupq_n_f32(360.f); - float32x4_t z = vdupq_n_f32(0.0f), scale4 = vdupq_n_f32(scale); - float32x4_t p1 = vdupq_n_f32(atan2_p1), p3 = vdupq_n_f32(atan2_p3); - float32x4_t p5 = vdupq_n_f32(atan2_p5), p7 = vdupq_n_f32(atan2_p7); - - for( ; i <= len - 4; i += 4 ) - { - float32x4_t x = vld1q_f32(X + i), y = vld1q_f32(Y + i); - float32x4_t ax = vabsq_f32(x), ay = vabsq_f32(y); - float32x4_t tmin = vminq_f32(ax, ay), tmax = vmaxq_f32(ax, ay); - float32x4_t c = vmulq_f32(tmin, cv_vrecpq_f32(vaddq_f32(tmax, eps))); - float32x4_t c2 = vmulq_f32(c, c); - float32x4_t a = vmulq_f32(c2, p7); - a = vmulq_f32(vaddq_f32(a, p5), c2); - a = vmulq_f32(vaddq_f32(a, p3), c2); - a = vmulq_f32(vaddq_f32(a, p1), c); - - a = vbslq_f32(vcgeq_f32(ax, ay), a, vsubq_f32(_90, a)); - a = vbslq_f32(vcltq_f32(x, z), vsubq_f32(_180, a), a); - a = vbslq_f32(vcltq_f32(y, z), vsubq_f32(_360, a), a); - - vst1q_f32(angle + i, vmulq_f32(a, scale4)); - } -#endif - - for( ; i < len; i++ ) - { - float x = X[i], y = Y[i]; - float ax = std::abs(x), ay = std::abs(y); - float a, c, c2; - if( ax >= ay ) - { - c = ay/(ax + (float)DBL_EPSILON); - c2 = c*c; - a = (((atan2_p7*c2 + atan2_p5)*c2 + atan2_p3)*c2 + atan2_p1)*c; - } - else - { - c = ax/(ay + (float)DBL_EPSILON); - c2 = c*c; - a = 90.f - (((atan2_p7*c2 + atan2_p5)*c2 + atan2_p3)*c2 + atan2_p1)*c; - } - if( x < 0 ) - a = 180.f - a; - if( y < 0 ) - a = 360.f - a; - angle[i] = (float)(a*scale); - } -} - - /* ************************************************************************** *\ Fast cube root by Ken Turkowski (http://www.worldserver.com/turk/computergraphics/papers.html) @@ -263,255 +162,6 @@ float cubeRoot( float value ) return v.f; } -static void Magnitude_32f(const float* x, const float* y, float* mag, int len) -{ -#if defined HAVE_IPP && 0 - CV_IPP_CHECK() - { - IppStatus status = ippsMagnitude_32f(x, y, mag, len); - if (status >= 0) - { - CV_IMPL_ADD(CV_IMPL_IPP); - return; - } - setIppErrorStatus(); - } -#endif - - int i = 0; - -#if CV_SSE - if( USE_SSE2 ) - { - for( ; i <= len - 8; i += 8 ) - { - __m128 x0 = _mm_loadu_ps(x + i), x1 = _mm_loadu_ps(x + i + 4); - __m128 y0 = _mm_loadu_ps(y + i), y1 = _mm_loadu_ps(y + i + 4); - x0 = _mm_add_ps(_mm_mul_ps(x0, x0), _mm_mul_ps(y0, y0)); - x1 = _mm_add_ps(_mm_mul_ps(x1, x1), _mm_mul_ps(y1, y1)); - x0 = _mm_sqrt_ps(x0); x1 = _mm_sqrt_ps(x1); - _mm_storeu_ps(mag + i, x0); _mm_storeu_ps(mag + i + 4, x1); - } - } -#elif CV_NEON - for( ; i <= len - 4; i += 4 ) - { - float32x4_t v_x = vld1q_f32(x + i), v_y = vld1q_f32(y + i); - vst1q_f32(mag + i, cv_vsqrtq_f32(vmlaq_f32(vmulq_f32(v_x, v_x), v_y, v_y))); - } - for( ; i <= len - 2; i += 2 ) - { - float32x2_t v_x = vld1_f32(x + i), v_y = vld1_f32(y + i); - vst1_f32(mag + i, cv_vsqrt_f32(vmla_f32(vmul_f32(v_x, v_x), v_y, v_y))); - } -#endif - - for( ; i < len; i++ ) - { - float x0 = x[i], y0 = y[i]; - mag[i] = std::sqrt(x0*x0 + y0*y0); - } -} - -static void Magnitude_64f(const double* x, const double* y, double* mag, int len) -{ -#if defined(HAVE_IPP) - CV_IPP_CHECK() - { - IppStatus status = ippsMagnitude_64f(x, y, mag, len); - if (status >= 0) - { - CV_IMPL_ADD(CV_IMPL_IPP); - return; - } - setIppErrorStatus(); - } -#endif - - int i = 0; - -#if CV_SSE2 - if( USE_SSE2 ) - { - for( ; i <= len - 4; i += 4 ) - { - __m128d x0 = _mm_loadu_pd(x + i), x1 = _mm_loadu_pd(x + i + 2); - __m128d y0 = _mm_loadu_pd(y + i), y1 = _mm_loadu_pd(y + i + 2); - x0 = _mm_add_pd(_mm_mul_pd(x0, x0), _mm_mul_pd(y0, y0)); - x1 = _mm_add_pd(_mm_mul_pd(x1, x1), _mm_mul_pd(y1, y1)); - x0 = _mm_sqrt_pd(x0); x1 = _mm_sqrt_pd(x1); - _mm_storeu_pd(mag + i, x0); _mm_storeu_pd(mag + i + 2, x1); - } - } -#endif - - for( ; i < len; i++ ) - { - double x0 = x[i], y0 = y[i]; - mag[i] = std::sqrt(x0*x0 + y0*y0); - } -} - - -static void InvSqrt_32f(const float* src, float* dst, int len) -{ -#if defined(HAVE_IPP) - CV_IPP_CHECK() - { - if (ippsInvSqrt_32f_A21(src, dst, len) >= 0) - { - CV_IMPL_ADD(CV_IMPL_IPP); - return; - } - setIppErrorStatus(); - } -#endif - - int i = 0; - -#if CV_SSE - if( USE_SSE2 ) - { - __m128 _0_5 = _mm_set1_ps(0.5f), _1_5 = _mm_set1_ps(1.5f); - if( (((size_t)src|(size_t)dst) & 15) == 0 ) - for( ; i <= len - 8; i += 8 ) - { - __m128 t0 = _mm_load_ps(src + i), t1 = _mm_load_ps(src + i + 4); - __m128 h0 = _mm_mul_ps(t0, _0_5), h1 = _mm_mul_ps(t1, _0_5); - t0 = _mm_rsqrt_ps(t0); t1 = _mm_rsqrt_ps(t1); - t0 = _mm_mul_ps(t0, _mm_sub_ps(_1_5, _mm_mul_ps(_mm_mul_ps(t0,t0),h0))); - t1 = _mm_mul_ps(t1, _mm_sub_ps(_1_5, _mm_mul_ps(_mm_mul_ps(t1,t1),h1))); - _mm_store_ps(dst + i, t0); _mm_store_ps(dst + i + 4, t1); - } - else - for( ; i <= len - 8; i += 8 ) - { - __m128 t0 = _mm_loadu_ps(src + i), t1 = _mm_loadu_ps(src + i + 4); - __m128 h0 = _mm_mul_ps(t0, _0_5), h1 = _mm_mul_ps(t1, _0_5); - t0 = _mm_rsqrt_ps(t0); t1 = _mm_rsqrt_ps(t1); - t0 = _mm_mul_ps(t0, _mm_sub_ps(_1_5, _mm_mul_ps(_mm_mul_ps(t0,t0),h0))); - t1 = _mm_mul_ps(t1, _mm_sub_ps(_1_5, _mm_mul_ps(_mm_mul_ps(t1,t1),h1))); - _mm_storeu_ps(dst + i, t0); _mm_storeu_ps(dst + i + 4, t1); - } - } -#elif CV_NEON - for ( ; i <= len - 8; i += 8) - { - vst1q_f32(dst + i, cv_vrsqrtq_f32(vld1q_f32(src + i))); - vst1q_f32(dst + i + 4, cv_vrsqrtq_f32(vld1q_f32(src + i + 4))); - } -#endif - - for( ; i < len; i++ ) - dst[i] = 1/std::sqrt(src[i]); -} - - -static void InvSqrt_64f(const double* src, double* dst, int len) -{ - int i = 0; - -#if CV_SSE2 - if (USE_SSE2) - { - __m128d v_1 = _mm_set1_pd(1.0); - for ( ; i <= len - 2; i += 2) - _mm_storeu_pd(dst + i, _mm_div_pd(v_1, _mm_sqrt_pd(_mm_loadu_pd(src + i)))); - } -#endif - - for( ; i < len; i++ ) - dst[i] = 1/std::sqrt(src[i]); -} - - -static void Sqrt_32f(const float* src, float* dst, int len) -{ -#if defined(HAVE_IPP) - CV_IPP_CHECK() - { - if (ippsSqrt_32f_A21(src, dst, len) >= 0) - { - CV_IMPL_ADD(CV_IMPL_IPP); - return; - } - setIppErrorStatus(); - } -#endif - int i = 0; - -#if CV_SSE - if( USE_SSE2 ) - { - if( (((size_t)src|(size_t)dst) & 15) == 0 ) - for( ; i <= len - 8; i += 8 ) - { - __m128 t0 = _mm_load_ps(src + i), t1 = _mm_load_ps(src + i + 4); - t0 = _mm_sqrt_ps(t0); t1 = _mm_sqrt_ps(t1); - _mm_store_ps(dst + i, t0); _mm_store_ps(dst + i + 4, t1); - } - else - for( ; i <= len - 8; i += 8 ) - { - __m128 t0 = _mm_loadu_ps(src + i), t1 = _mm_loadu_ps(src + i + 4); - t0 = _mm_sqrt_ps(t0); t1 = _mm_sqrt_ps(t1); - _mm_storeu_ps(dst + i, t0); _mm_storeu_ps(dst + i + 4, t1); - } - } -#elif CV_NEON - for ( ; i <= len - 8; i += 8) - { - vst1q_f32(dst + i, cv_vsqrtq_f32(vld1q_f32(src + i))); - vst1q_f32(dst + i + 4, cv_vsqrtq_f32(vld1q_f32(src + i + 4))); - } -#endif - - for( ; i < len; i++ ) - dst[i] = std::sqrt(src[i]); -} - - -static void Sqrt_64f(const double* src, double* dst, int len) -{ -#if defined(HAVE_IPP) - CV_IPP_CHECK() - { - if (ippsSqrt_64f_A50(src, dst, len) >= 0) - { - CV_IMPL_ADD(CV_IMPL_IPP); - return; - } - setIppErrorStatus(); - } -#endif - - int i = 0; - -#if CV_SSE2 - if( USE_SSE2 ) - { - if( (((size_t)src|(size_t)dst) & 15) == 0 ) - for( ; i <= len - 4; i += 4 ) - { - __m128d t0 = _mm_load_pd(src + i), t1 = _mm_load_pd(src + i + 2); - t0 = _mm_sqrt_pd(t0); t1 = _mm_sqrt_pd(t1); - _mm_store_pd(dst + i, t0); _mm_store_pd(dst + i + 2, t1); - } - else - for( ; i <= len - 4; i += 4 ) - { - __m128d t0 = _mm_loadu_pd(src + i), t1 = _mm_loadu_pd(src + i + 2); - t0 = _mm_sqrt_pd(t0); t1 = _mm_sqrt_pd(t1); - _mm_storeu_pd(dst + i, t0); _mm_storeu_pd(dst + i + 2, t1); - } - } -#endif - - for( ; i < len; i++ ) - dst[i] = std::sqrt(src[i]); -} - - /****************************************************************************************\ * Cartezian -> Polar * \****************************************************************************************/ @@ -539,13 +189,13 @@ void magnitude( InputArray src1, InputArray src2, OutputArray dst ) { const float *x = (const float*)ptrs[0], *y = (const float*)ptrs[1]; float *mag = (float*)ptrs[2]; - Magnitude_32f( x, y, mag, len ); + hal::magnitude( x, y, mag, len ); } else { const double *x = (const double*)ptrs[0], *y = (const double*)ptrs[1]; double *mag = (double*)ptrs[2]; - Magnitude_64f( x, y, mag, len ); + hal::magnitude( x, y, mag, len ); } } } @@ -588,7 +238,7 @@ void phase( InputArray src1, InputArray src2, OutputArray dst, bool angleInDegre { const float *x = (const float*)ptrs[0], *y = (const float*)ptrs[1]; float *angle = (float*)ptrs[2]; - FastAtan2_32f( y, x, angle, len, angleInDegrees ); + hal::fastAtan2( y, x, angle, len, angleInDegrees ); } else { @@ -618,7 +268,7 @@ void phase( InputArray src1, InputArray src2, OutputArray dst, bool angleInDegre buf[1][k] = (float)y[k]; } - FastAtan2_32f( buf[1], buf[0], buf[0], len, angleInDegrees ); + hal::fastAtan2( buf[1], buf[0], buf[0], len, angleInDegrees ); k = 0; #if CV_SSE2 @@ -722,15 +372,15 @@ void cartToPolar( InputArray src1, InputArray src2, { const float *x = (const float*)ptrs[0], *y = (const float*)ptrs[1]; float *mag = (float*)ptrs[2], *angle = (float*)ptrs[3]; - Magnitude_32f( x, y, mag, len ); - FastAtan2_32f( y, x, angle, len, angleInDegrees ); + hal::magnitude( x, y, mag, len ); + hal::fastAtan2( y, x, angle, len, angleInDegrees ); } else { const double *x = (const double*)ptrs[0], *y = (const double*)ptrs[1]; double *angle = (double*)ptrs[3]; - Magnitude_64f(x, y, (double*)ptrs[2], len); + hal::magnitude(x, y, (double*)ptrs[2], len); k = 0; #if CV_SSE2 @@ -755,7 +405,7 @@ void cartToPolar( InputArray src1, InputArray src2, buf[1][k] = (float)y[k]; } - FastAtan2_32f( buf[1], buf[0], buf[0], len, angleInDegrees ); + hal::fastAtan2( buf[1], buf[0], buf[0], len, angleInDegrees ); k = 0; #if CV_SSE2 @@ -1096,482 +746,6 @@ void polarToCart( InputArray src1, InputArray src2, * E X P * \****************************************************************************************/ -typedef union -{ - struct { -#if ( defined( WORDS_BIGENDIAN ) && !defined( OPENCV_UNIVERSAL_BUILD ) ) || defined( __BIG_ENDIAN__ ) - int hi; - int lo; -#else - int lo; - int hi; -#endif - } i; - double d; -} -DBLINT; - -#define EXPTAB_SCALE 6 -#define EXPTAB_MASK ((1 << EXPTAB_SCALE) - 1) - -#define EXPPOLY_32F_A0 .9670371139572337719125840413672004409288e-2 - -static const double expTab[] = { - 1.0 * EXPPOLY_32F_A0, - 1.0108892860517004600204097905619 * EXPPOLY_32F_A0, - 1.0218971486541166782344801347833 * EXPPOLY_32F_A0, - 1.0330248790212284225001082839705 * EXPPOLY_32F_A0, - 1.0442737824274138403219664787399 * EXPPOLY_32F_A0, - 1.0556451783605571588083413251529 * EXPPOLY_32F_A0, - 1.0671404006768236181695211209928 * EXPPOLY_32F_A0, - 1.0787607977571197937406800374385 * EXPPOLY_32F_A0, - 1.0905077326652576592070106557607 * EXPPOLY_32F_A0, - 1.1023825833078409435564142094256 * EXPPOLY_32F_A0, - 1.1143867425958925363088129569196 * EXPPOLY_32F_A0, - 1.126521618608241899794798643787 * EXPPOLY_32F_A0, - 1.1387886347566916537038302838415 * EXPPOLY_32F_A0, - 1.151189229952982705817759635202 * EXPPOLY_32F_A0, - 1.1637248587775775138135735990922 * EXPPOLY_32F_A0, - 1.1763969916502812762846457284838 * EXPPOLY_32F_A0, - 1.1892071150027210667174999705605 * EXPPOLY_32F_A0, - 1.2021567314527031420963969574978 * EXPPOLY_32F_A0, - 1.2152473599804688781165202513388 * EXPPOLY_32F_A0, - 1.2284805361068700056940089577928 * EXPPOLY_32F_A0, - 1.2418578120734840485936774687266 * EXPPOLY_32F_A0, - 1.2553807570246910895793906574423 * EXPPOLY_32F_A0, - 1.2690509571917332225544190810323 * EXPPOLY_32F_A0, - 1.2828700160787782807266697810215 * EXPPOLY_32F_A0, - 1.2968395546510096659337541177925 * EXPPOLY_32F_A0, - 1.3109612115247643419229917863308 * EXPPOLY_32F_A0, - 1.3252366431597412946295370954987 * EXPPOLY_32F_A0, - 1.3396675240533030053600306697244 * EXPPOLY_32F_A0, - 1.3542555469368927282980147401407 * EXPPOLY_32F_A0, - 1.3690024229745906119296011329822 * EXPPOLY_32F_A0, - 1.3839098819638319548726595272652 * EXPPOLY_32F_A0, - 1.3989796725383111402095281367152 * EXPPOLY_32F_A0, - 1.4142135623730950488016887242097 * EXPPOLY_32F_A0, - 1.4296133383919700112350657782751 * EXPPOLY_32F_A0, - 1.4451808069770466200370062414717 * EXPPOLY_32F_A0, - 1.4609177941806469886513028903106 * EXPPOLY_32F_A0, - 1.476826145939499311386907480374 * EXPPOLY_32F_A0, - 1.4929077282912648492006435314867 * EXPPOLY_32F_A0, - 1.5091644275934227397660195510332 * EXPPOLY_32F_A0, - 1.5255981507445383068512536895169 * EXPPOLY_32F_A0, - 1.5422108254079408236122918620907 * EXPPOLY_32F_A0, - 1.5590044002378369670337280894749 * EXPPOLY_32F_A0, - 1.5759808451078864864552701601819 * EXPPOLY_32F_A0, - 1.5931421513422668979372486431191 * EXPPOLY_32F_A0, - 1.6104903319492543081795206673574 * EXPPOLY_32F_A0, - 1.628027421857347766848218522014 * EXPPOLY_32F_A0, - 1.6457554781539648445187567247258 * EXPPOLY_32F_A0, - 1.6636765803267364350463364569764 * EXPPOLY_32F_A0, - 1.6817928305074290860622509524664 * EXPPOLY_32F_A0, - 1.7001063537185234695013625734975 * EXPPOLY_32F_A0, - 1.7186192981224779156293443764563 * EXPPOLY_32F_A0, - 1.7373338352737062489942020818722 * EXPPOLY_32F_A0, - 1.7562521603732994831121606193753 * EXPPOLY_32F_A0, - 1.7753764925265212525505592001993 * EXPPOLY_32F_A0, - 1.7947090750031071864277032421278 * EXPPOLY_32F_A0, - 1.8142521755003987562498346003623 * EXPPOLY_32F_A0, - 1.8340080864093424634870831895883 * EXPPOLY_32F_A0, - 1.8539791250833855683924530703377 * EXPPOLY_32F_A0, - 1.8741676341102999013299989499544 * EXPPOLY_32F_A0, - 1.8945759815869656413402186534269 * EXPPOLY_32F_A0, - 1.9152065613971472938726112702958 * EXPPOLY_32F_A0, - 1.9360617934922944505980559045667 * EXPPOLY_32F_A0, - 1.9571441241754002690183222516269 * EXPPOLY_32F_A0, - 1.9784560263879509682582499181312 * EXPPOLY_32F_A0, -}; - - -// the code below uses _mm_cast* intrinsics, which are not avialable on VS2005 -#if (defined _MSC_VER && _MSC_VER < 1500) || \ - (!defined __APPLE__ && defined __GNUC__ && __GNUC__*100 + __GNUC_MINOR__ < 402) -#undef CV_SSE2 -#define CV_SSE2 0 -#endif - -static const double exp_prescale = 1.4426950408889634073599246810019 * (1 << EXPTAB_SCALE); -static const double exp_postscale = 1./(1 << EXPTAB_SCALE); -static const double exp_max_val = 3000.*(1 << EXPTAB_SCALE); // log10(DBL_MAX) < 3000 - -static void Exp_32f( const float *_x, float *y, int n ) -{ - static const float - A4 = (float)(1.000000000000002438532970795181890933776 / EXPPOLY_32F_A0), - A3 = (float)(.6931471805521448196800669615864773144641 / EXPPOLY_32F_A0), - A2 = (float)(.2402265109513301490103372422686535526573 / EXPPOLY_32F_A0), - A1 = (float)(.5550339366753125211915322047004666939128e-1 / EXPPOLY_32F_A0); - -#undef EXPPOLY -#define EXPPOLY(x) \ - (((((x) + A1)*(x) + A2)*(x) + A3)*(x) + A4) - - int i = 0; - const Cv32suf* x = (const Cv32suf*)_x; - Cv32suf buf[4]; - -#if CV_SSE2 - if( n >= 8 && USE_SSE2 ) - { - static const __m128d prescale2 = _mm_set1_pd(exp_prescale); - static const __m128 postscale4 = _mm_set1_ps((float)exp_postscale); - static const __m128 maxval4 = _mm_set1_ps((float)(exp_max_val/exp_prescale)); - static const __m128 minval4 = _mm_set1_ps((float)(-exp_max_val/exp_prescale)); - - static const __m128 mA1 = _mm_set1_ps(A1); - static const __m128 mA2 = _mm_set1_ps(A2); - static const __m128 mA3 = _mm_set1_ps(A3); - static const __m128 mA4 = _mm_set1_ps(A4); - bool y_aligned = (size_t)(void*)y % 16 == 0; - - ushort CV_DECL_ALIGNED(16) tab_idx[8]; - - for( ; i <= n - 8; i += 8 ) - { - __m128 xf0, xf1; - xf0 = _mm_loadu_ps(&x[i].f); - xf1 = _mm_loadu_ps(&x[i+4].f); - __m128i xi0, xi1, xi2, xi3; - - xf0 = _mm_min_ps(_mm_max_ps(xf0, minval4), maxval4); - xf1 = _mm_min_ps(_mm_max_ps(xf1, minval4), maxval4); - - __m128d xd0 = _mm_cvtps_pd(xf0); - __m128d xd2 = _mm_cvtps_pd(_mm_movehl_ps(xf0, xf0)); - __m128d xd1 = _mm_cvtps_pd(xf1); - __m128d xd3 = _mm_cvtps_pd(_mm_movehl_ps(xf1, xf1)); - - xd0 = _mm_mul_pd(xd0, prescale2); - xd2 = _mm_mul_pd(xd2, prescale2); - xd1 = _mm_mul_pd(xd1, prescale2); - xd3 = _mm_mul_pd(xd3, prescale2); - - xi0 = _mm_cvtpd_epi32(xd0); - xi2 = _mm_cvtpd_epi32(xd2); - - xi1 = _mm_cvtpd_epi32(xd1); - xi3 = _mm_cvtpd_epi32(xd3); - - xd0 = _mm_sub_pd(xd0, _mm_cvtepi32_pd(xi0)); - xd2 = _mm_sub_pd(xd2, _mm_cvtepi32_pd(xi2)); - xd1 = _mm_sub_pd(xd1, _mm_cvtepi32_pd(xi1)); - xd3 = _mm_sub_pd(xd3, _mm_cvtepi32_pd(xi3)); - - xf0 = _mm_movelh_ps(_mm_cvtpd_ps(xd0), _mm_cvtpd_ps(xd2)); - xf1 = _mm_movelh_ps(_mm_cvtpd_ps(xd1), _mm_cvtpd_ps(xd3)); - - xf0 = _mm_mul_ps(xf0, postscale4); - xf1 = _mm_mul_ps(xf1, postscale4); - - xi0 = _mm_unpacklo_epi64(xi0, xi2); - xi1 = _mm_unpacklo_epi64(xi1, xi3); - xi0 = _mm_packs_epi32(xi0, xi1); - - _mm_store_si128((__m128i*)tab_idx, _mm_and_si128(xi0, _mm_set1_epi16(EXPTAB_MASK))); - - xi0 = _mm_add_epi16(_mm_srai_epi16(xi0, EXPTAB_SCALE), _mm_set1_epi16(127)); - xi0 = _mm_max_epi16(xi0, _mm_setzero_si128()); - xi0 = _mm_min_epi16(xi0, _mm_set1_epi16(255)); - xi1 = _mm_unpackhi_epi16(xi0, _mm_setzero_si128()); - xi0 = _mm_unpacklo_epi16(xi0, _mm_setzero_si128()); - - __m128d yd0 = _mm_unpacklo_pd(_mm_load_sd(expTab + tab_idx[0]), _mm_load_sd(expTab + tab_idx[1])); - __m128d yd1 = _mm_unpacklo_pd(_mm_load_sd(expTab + tab_idx[2]), _mm_load_sd(expTab + tab_idx[3])); - __m128d yd2 = _mm_unpacklo_pd(_mm_load_sd(expTab + tab_idx[4]), _mm_load_sd(expTab + tab_idx[5])); - __m128d yd3 = _mm_unpacklo_pd(_mm_load_sd(expTab + tab_idx[6]), _mm_load_sd(expTab + tab_idx[7])); - - __m128 yf0 = _mm_movelh_ps(_mm_cvtpd_ps(yd0), _mm_cvtpd_ps(yd1)); - __m128 yf1 = _mm_movelh_ps(_mm_cvtpd_ps(yd2), _mm_cvtpd_ps(yd3)); - - yf0 = _mm_mul_ps(yf0, _mm_castsi128_ps(_mm_slli_epi32(xi0, 23))); - yf1 = _mm_mul_ps(yf1, _mm_castsi128_ps(_mm_slli_epi32(xi1, 23))); - - __m128 zf0 = _mm_add_ps(xf0, mA1); - __m128 zf1 = _mm_add_ps(xf1, mA1); - - zf0 = _mm_add_ps(_mm_mul_ps(zf0, xf0), mA2); - zf1 = _mm_add_ps(_mm_mul_ps(zf1, xf1), mA2); - - zf0 = _mm_add_ps(_mm_mul_ps(zf0, xf0), mA3); - zf1 = _mm_add_ps(_mm_mul_ps(zf1, xf1), mA3); - - zf0 = _mm_add_ps(_mm_mul_ps(zf0, xf0), mA4); - zf1 = _mm_add_ps(_mm_mul_ps(zf1, xf1), mA4); - - zf0 = _mm_mul_ps(zf0, yf0); - zf1 = _mm_mul_ps(zf1, yf1); - - if( y_aligned ) - { - _mm_store_ps(y + i, zf0); - _mm_store_ps(y + i + 4, zf1); - } - else - { - _mm_storeu_ps(y + i, zf0); - _mm_storeu_ps(y + i + 4, zf1); - } - } - } - else -#endif - for( ; i <= n - 4; i += 4 ) - { - double x0 = x[i].f * exp_prescale; - double x1 = x[i + 1].f * exp_prescale; - double x2 = x[i + 2].f * exp_prescale; - double x3 = x[i + 3].f * exp_prescale; - int val0, val1, val2, val3, t; - - if( ((x[i].i >> 23) & 255) > 127 + 10 ) - x0 = x[i].i < 0 ? -exp_max_val : exp_max_val; - - if( ((x[i+1].i >> 23) & 255) > 127 + 10 ) - x1 = x[i+1].i < 0 ? -exp_max_val : exp_max_val; - - if( ((x[i+2].i >> 23) & 255) > 127 + 10 ) - x2 = x[i+2].i < 0 ? -exp_max_val : exp_max_val; - - if( ((x[i+3].i >> 23) & 255) > 127 + 10 ) - x3 = x[i+3].i < 0 ? -exp_max_val : exp_max_val; - - val0 = cvRound(x0); - val1 = cvRound(x1); - val2 = cvRound(x2); - val3 = cvRound(x3); - - x0 = (x0 - val0)*exp_postscale; - x1 = (x1 - val1)*exp_postscale; - x2 = (x2 - val2)*exp_postscale; - x3 = (x3 - val3)*exp_postscale; - - t = (val0 >> EXPTAB_SCALE) + 127; - t = !(t & ~255) ? t : t < 0 ? 0 : 255; - buf[0].i = t << 23; - - t = (val1 >> EXPTAB_SCALE) + 127; - t = !(t & ~255) ? t : t < 0 ? 0 : 255; - buf[1].i = t << 23; - - t = (val2 >> EXPTAB_SCALE) + 127; - t = !(t & ~255) ? t : t < 0 ? 0 : 255; - buf[2].i = t << 23; - - t = (val3 >> EXPTAB_SCALE) + 127; - t = !(t & ~255) ? t : t < 0 ? 0 : 255; - buf[3].i = t << 23; - - x0 = buf[0].f * expTab[val0 & EXPTAB_MASK] * EXPPOLY( x0 ); - x1 = buf[1].f * expTab[val1 & EXPTAB_MASK] * EXPPOLY( x1 ); - - y[i] = (float)x0; - y[i + 1] = (float)x1; - - x2 = buf[2].f * expTab[val2 & EXPTAB_MASK] * EXPPOLY( x2 ); - x3 = buf[3].f * expTab[val3 & EXPTAB_MASK] * EXPPOLY( x3 ); - - y[i + 2] = (float)x2; - y[i + 3] = (float)x3; - } - - for( ; i < n; i++ ) - { - double x0 = x[i].f * exp_prescale; - int val0, t; - - if( ((x[i].i >> 23) & 255) > 127 + 10 ) - x0 = x[i].i < 0 ? -exp_max_val : exp_max_val; - - val0 = cvRound(x0); - t = (val0 >> EXPTAB_SCALE) + 127; - t = !(t & ~255) ? t : t < 0 ? 0 : 255; - - buf[0].i = t << 23; - x0 = (x0 - val0)*exp_postscale; - - y[i] = (float)(buf[0].f * expTab[val0 & EXPTAB_MASK] * EXPPOLY(x0)); - } -} - - -static void Exp_64f( const double *_x, double *y, int n ) -{ - static const double - A5 = .99999999999999999998285227504999 / EXPPOLY_32F_A0, - A4 = .69314718055994546743029643825322 / EXPPOLY_32F_A0, - A3 = .24022650695886477918181338054308 / EXPPOLY_32F_A0, - A2 = .55504108793649567998466049042729e-1 / EXPPOLY_32F_A0, - A1 = .96180973140732918010002372686186e-2 / EXPPOLY_32F_A0, - A0 = .13369713757180123244806654839424e-2 / EXPPOLY_32F_A0; - -#undef EXPPOLY -#define EXPPOLY(x) (((((A0*(x) + A1)*(x) + A2)*(x) + A3)*(x) + A4)*(x) + A5) - - int i = 0; - Cv64suf buf[4]; - const Cv64suf* x = (const Cv64suf*)_x; - -#if CV_SSE2 - if( USE_SSE2 ) - { - static const __m128d prescale2 = _mm_set1_pd(exp_prescale); - static const __m128d postscale2 = _mm_set1_pd(exp_postscale); - static const __m128d maxval2 = _mm_set1_pd(exp_max_val); - static const __m128d minval2 = _mm_set1_pd(-exp_max_val); - - static const __m128d mA0 = _mm_set1_pd(A0); - static const __m128d mA1 = _mm_set1_pd(A1); - static const __m128d mA2 = _mm_set1_pd(A2); - static const __m128d mA3 = _mm_set1_pd(A3); - static const __m128d mA4 = _mm_set1_pd(A4); - static const __m128d mA5 = _mm_set1_pd(A5); - - int CV_DECL_ALIGNED(16) tab_idx[4]; - - for( ; i <= n - 4; i += 4 ) - { - __m128d xf0 = _mm_loadu_pd(&x[i].f), xf1 = _mm_loadu_pd(&x[i+2].f); - __m128i xi0, xi1; - xf0 = _mm_min_pd(_mm_max_pd(xf0, minval2), maxval2); - xf1 = _mm_min_pd(_mm_max_pd(xf1, minval2), maxval2); - xf0 = _mm_mul_pd(xf0, prescale2); - xf1 = _mm_mul_pd(xf1, prescale2); - - xi0 = _mm_cvtpd_epi32(xf0); - xi1 = _mm_cvtpd_epi32(xf1); - xf0 = _mm_mul_pd(_mm_sub_pd(xf0, _mm_cvtepi32_pd(xi0)), postscale2); - xf1 = _mm_mul_pd(_mm_sub_pd(xf1, _mm_cvtepi32_pd(xi1)), postscale2); - - xi0 = _mm_unpacklo_epi64(xi0, xi1); - _mm_store_si128((__m128i*)tab_idx, _mm_and_si128(xi0, _mm_set1_epi32(EXPTAB_MASK))); - - xi0 = _mm_add_epi32(_mm_srai_epi32(xi0, EXPTAB_SCALE), _mm_set1_epi32(1023)); - xi0 = _mm_packs_epi32(xi0, xi0); - xi0 = _mm_max_epi16(xi0, _mm_setzero_si128()); - xi0 = _mm_min_epi16(xi0, _mm_set1_epi16(2047)); - xi0 = _mm_unpacklo_epi16(xi0, _mm_setzero_si128()); - xi1 = _mm_unpackhi_epi32(xi0, _mm_setzero_si128()); - xi0 = _mm_unpacklo_epi32(xi0, _mm_setzero_si128()); - - __m128d yf0 = _mm_unpacklo_pd(_mm_load_sd(expTab + tab_idx[0]), _mm_load_sd(expTab + tab_idx[1])); - __m128d yf1 = _mm_unpacklo_pd(_mm_load_sd(expTab + tab_idx[2]), _mm_load_sd(expTab + tab_idx[3])); - yf0 = _mm_mul_pd(yf0, _mm_castsi128_pd(_mm_slli_epi64(xi0, 52))); - yf1 = _mm_mul_pd(yf1, _mm_castsi128_pd(_mm_slli_epi64(xi1, 52))); - - __m128d zf0 = _mm_add_pd(_mm_mul_pd(mA0, xf0), mA1); - __m128d zf1 = _mm_add_pd(_mm_mul_pd(mA0, xf1), mA1); - - zf0 = _mm_add_pd(_mm_mul_pd(zf0, xf0), mA2); - zf1 = _mm_add_pd(_mm_mul_pd(zf1, xf1), mA2); - - zf0 = _mm_add_pd(_mm_mul_pd(zf0, xf0), mA3); - zf1 = _mm_add_pd(_mm_mul_pd(zf1, xf1), mA3); - - zf0 = _mm_add_pd(_mm_mul_pd(zf0, xf0), mA4); - zf1 = _mm_add_pd(_mm_mul_pd(zf1, xf1), mA4); - - zf0 = _mm_add_pd(_mm_mul_pd(zf0, xf0), mA5); - zf1 = _mm_add_pd(_mm_mul_pd(zf1, xf1), mA5); - - zf0 = _mm_mul_pd(zf0, yf0); - zf1 = _mm_mul_pd(zf1, yf1); - - _mm_storeu_pd(y + i, zf0); - _mm_storeu_pd(y + i + 2, zf1); - } - } - else -#endif - for( ; i <= n - 4; i += 4 ) - { - double x0 = x[i].f * exp_prescale; - double x1 = x[i + 1].f * exp_prescale; - double x2 = x[i + 2].f * exp_prescale; - double x3 = x[i + 3].f * exp_prescale; - - double y0, y1, y2, y3; - int val0, val1, val2, val3, t; - - t = (int)(x[i].i >> 52); - if( (t & 2047) > 1023 + 10 ) - x0 = t < 0 ? -exp_max_val : exp_max_val; - - t = (int)(x[i+1].i >> 52); - if( (t & 2047) > 1023 + 10 ) - x1 = t < 0 ? -exp_max_val : exp_max_val; - - t = (int)(x[i+2].i >> 52); - if( (t & 2047) > 1023 + 10 ) - x2 = t < 0 ? -exp_max_val : exp_max_val; - - t = (int)(x[i+3].i >> 52); - if( (t & 2047) > 1023 + 10 ) - x3 = t < 0 ? -exp_max_val : exp_max_val; - - val0 = cvRound(x0); - val1 = cvRound(x1); - val2 = cvRound(x2); - val3 = cvRound(x3); - - x0 = (x0 - val0)*exp_postscale; - x1 = (x1 - val1)*exp_postscale; - x2 = (x2 - val2)*exp_postscale; - x3 = (x3 - val3)*exp_postscale; - - t = (val0 >> EXPTAB_SCALE) + 1023; - t = !(t & ~2047) ? t : t < 0 ? 0 : 2047; - buf[0].i = (int64)t << 52; - - t = (val1 >> EXPTAB_SCALE) + 1023; - t = !(t & ~2047) ? t : t < 0 ? 0 : 2047; - buf[1].i = (int64)t << 52; - - t = (val2 >> EXPTAB_SCALE) + 1023; - t = !(t & ~2047) ? t : t < 0 ? 0 : 2047; - buf[2].i = (int64)t << 52; - - t = (val3 >> EXPTAB_SCALE) + 1023; - t = !(t & ~2047) ? t : t < 0 ? 0 : 2047; - buf[3].i = (int64)t << 52; - - y0 = buf[0].f * expTab[val0 & EXPTAB_MASK] * EXPPOLY( x0 ); - y1 = buf[1].f * expTab[val1 & EXPTAB_MASK] * EXPPOLY( x1 ); - - y[i] = y0; - y[i + 1] = y1; - - y2 = buf[2].f * expTab[val2 & EXPTAB_MASK] * EXPPOLY( x2 ); - y3 = buf[3].f * expTab[val3 & EXPTAB_MASK] * EXPPOLY( x3 ); - - y[i + 2] = y2; - y[i + 3] = y3; - } - - for( ; i < n; i++ ) - { - double x0 = x[i].f * exp_prescale; - int val0, t; - - t = (int)(x[i].i >> 52); - if( (t & 2047) > 1023 + 10 ) - x0 = t < 0 ? -exp_max_val : exp_max_val; - - val0 = cvRound(x0); - t = (val0 >> EXPTAB_SCALE) + 1023; - t = !(t & ~2047) ? t : t < 0 ? 0 : 2047; - - buf[0].i = (int64)t << 52; - x0 = (x0 - val0)*exp_postscale; - - y[i] = buf[0].f * expTab[val0 & EXPTAB_MASK] * EXPPOLY( x0 ); - } -} - -#undef EXPTAB_SCALE -#undef EXPTAB_MASK -#undef EXPPOLY_32F_A0 - #ifdef HAVE_IPP static void Exp_32f_ipp(const float *x, float *y, int n) { @@ -1584,7 +758,7 @@ static void Exp_32f_ipp(const float *x, float *y, int n) } setIppErrorStatus(); } - Exp_32f(x, y, n); + hal::exp(x, y, n); } static void Exp_64f_ipp(const double *x, double *y, int n) @@ -1598,11 +772,14 @@ static void Exp_64f_ipp(const double *x, double *y, int n) } setIppErrorStatus(); } - Exp_64f(x, y, n); + hal::exp(x, y, n); } #define Exp_32f Exp_32f_ipp #define Exp_64f Exp_64f_ipp +#else +#define Exp_32f hal::exp +#define Exp_64f hal::exp #endif @@ -1637,613 +814,6 @@ void exp( InputArray _src, OutputArray _dst ) * L O G * \****************************************************************************************/ -#define LOGTAB_SCALE 8 -#define LOGTAB_MASK ((1 << LOGTAB_SCALE) - 1) -#define LOGTAB_MASK2 ((1 << (20 - LOGTAB_SCALE)) - 1) -#define LOGTAB_MASK2_32F ((1 << (23 - LOGTAB_SCALE)) - 1) - -static const double CV_DECL_ALIGNED(16) icvLogTab[] = { -0.0000000000000000000000000000000000000000, 1.000000000000000000000000000000000000000, -.00389864041565732288852075271279318258166, .9961089494163424124513618677042801556420, -.00778214044205494809292034119607706088573, .9922480620155038759689922480620155038760, -.01165061721997527263705585198749759001657, .9884169884169884169884169884169884169884, -.01550418653596525274396267235488267033361, .9846153846153846153846153846153846153846, -.01934296284313093139406447562578250654042, .9808429118773946360153256704980842911877, -.02316705928153437593630670221500622574241, .9770992366412213740458015267175572519084, -.02697658769820207233514075539915211265906, .9733840304182509505703422053231939163498, -.03077165866675368732785500469617545604706, .9696969696969696969696969696969696969697, -.03455238150665972812758397481047722976656, .9660377358490566037735849056603773584906, -.03831886430213659461285757856785494368522, .9624060150375939849624060150375939849624, -.04207121392068705056921373852674150839447, .9588014981273408239700374531835205992509, -.04580953603129420126371940114040626212953, .9552238805970149253731343283582089552239, -.04953393512227662748292900118940451648088, .9516728624535315985130111524163568773234, -.05324451451881227759255210685296333394944, .9481481481481481481481481481481481481481, -.05694137640013842427411105973078520037234, .9446494464944649446494464944649446494465, -.06062462181643483993820353816772694699466, .9411764705882352941176470588235294117647, -.06429435070539725460836422143984236754475, .9377289377289377289377289377289377289377, -.06795066190850773679699159401934593915938, .9343065693430656934306569343065693430657, -.07159365318700880442825962290953611955044, .9309090909090909090909090909090909090909, -.07522342123758751775142172846244648098944, .9275362318840579710144927536231884057971, -.07884006170777602129362549021607264876369, .9241877256317689530685920577617328519856, -.08244366921107458556772229485432035289706, .9208633093525179856115107913669064748201, -.08603433734180314373940490213499288074675, .9175627240143369175627240143369175627240, -.08961215868968712416897659522874164395031, .9142857142857142857142857142857142857143, -.09317722485418328259854092721070628613231, .9110320284697508896797153024911032028470, -.09672962645855109897752299730200320482256, .9078014184397163120567375886524822695035, -.10026945316367513738597949668474029749630, .9045936395759717314487632508833922261484, -.10379679368164355934833764649738441221420, .9014084507042253521126760563380281690141, -.10731173578908805021914218968959175981580, .8982456140350877192982456140350877192982, -.11081436634029011301105782649756292812530, .8951048951048951048951048951048951048951, -.11430477128005862852422325204315711744130, .8919860627177700348432055749128919860627, -.11778303565638344185817487641543266363440, .8888888888888888888888888888888888888889, -.12124924363286967987640707633545389398930, .8858131487889273356401384083044982698962, -.12470347850095722663787967121606925502420, .8827586206896551724137931034482758620690, -.12814582269193003360996385708858724683530, .8797250859106529209621993127147766323024, -.13157635778871926146571524895989568904040, .8767123287671232876712328767123287671233, -.13499516453750481925766280255629681050780, .8737201365187713310580204778156996587031, -.13840232285911913123754857224412262439730, .8707482993197278911564625850340136054422, -.14179791186025733629172407290752744302150, .8677966101694915254237288135593220338983, -.14518200984449788903951628071808954700830, .8648648648648648648648648648648648648649, -.14855469432313711530824207329715136438610, .8619528619528619528619528619528619528620, -.15191604202584196858794030049466527998450, .8590604026845637583892617449664429530201, -.15526612891112392955683674244937719777230, .8561872909698996655518394648829431438127, -.15860503017663857283636730244325008243330, .8533333333333333333333333333333333333333, -.16193282026931324346641360989451641216880, .8504983388704318936877076411960132890365, -.16524957289530714521497145597095368430010, .8476821192052980132450331125827814569536, -.16855536102980664403538924034364754334090, .8448844884488448844884488448844884488449, -.17185025692665920060697715143760433420540, .8421052631578947368421052631578947368421, -.17513433212784912385018287750426679849630, .8393442622950819672131147540983606557377, -.17840765747281828179637841458315961062910, .8366013071895424836601307189542483660131, -.18167030310763465639212199675966985523700, .8338762214983713355048859934853420195440, -.18492233849401198964024217730184318497780, .8311688311688311688311688311688311688312, -.18816383241818296356839823602058459073300, .8284789644012944983818770226537216828479, -.19139485299962943898322009772527962923050, .8258064516129032258064516129032258064516, -.19461546769967164038916962454095482826240, .8231511254019292604501607717041800643087, -.19782574332991986754137769821682013571260, .8205128205128205128205128205128205128205, -.20102574606059073203390141770796617493040, .8178913738019169329073482428115015974441, -.20421554142869088876999228432396193966280, .8152866242038216560509554140127388535032, -.20739519434607056602715147164417430758480, .8126984126984126984126984126984126984127, -.21056476910734961416338251183333341032260, .8101265822784810126582278481012658227848, -.21372432939771812687723695489694364368910, .8075709779179810725552050473186119873817, -.21687393830061435506806333251006435602900, .8050314465408805031446540880503144654088, -.22001365830528207823135744547471404075630, .8025078369905956112852664576802507836991, -.22314355131420973710199007200571941211830, .8000000000000000000000000000000000000000, -.22626367865045338145790765338460914790630, .7975077881619937694704049844236760124611, -.22937410106484582006380890106811420992010, .7950310559006211180124223602484472049689, -.23247487874309405442296849741978803649550, .7925696594427244582043343653250773993808, -.23556607131276688371634975283086532726890, .7901234567901234567901234567901234567901, -.23864773785017498464178231643018079921600, .7876923076923076923076923076923076923077, -.24171993688714515924331749374687206000090, .7852760736196319018404907975460122699387, -.24478272641769091566565919038112042471760, .7828746177370030581039755351681957186544, -.24783616390458124145723672882013488560910, .7804878048780487804878048780487804878049, -.25088030628580937353433455427875742316250, .7781155015197568389057750759878419452888, -.25391520998096339667426946107298135757450, .7757575757575757575757575757575757575758, -.25694093089750041913887912414793390780680, .7734138972809667673716012084592145015106, -.25995752443692604627401010475296061486000, .7710843373493975903614457831325301204819, -.26296504550088134477547896494797896593800, .7687687687687687687687687687687687687688, -.26596354849713793599974565040611196309330, .7664670658682634730538922155688622754491, -.26895308734550393836570947314612567424780, .7641791044776119402985074626865671641791, -.27193371548364175804834985683555714786050, .7619047619047619047619047619047619047619, -.27490548587279922676529508862586226314300, .7596439169139465875370919881305637982196, -.27786845100345625159121709657483734190480, .7573964497041420118343195266272189349112, -.28082266290088775395616949026589281857030, .7551622418879056047197640117994100294985, -.28376817313064456316240580235898960381750, .7529411764705882352941176470588235294118, -.28670503280395426282112225635501090437180, .7507331378299120234604105571847507331378, -.28963329258304265634293983566749375313530, .7485380116959064327485380116959064327485, -.29255300268637740579436012922087684273730, .7463556851311953352769679300291545189504, -.29546421289383584252163927885703742504130, .7441860465116279069767441860465116279070, -.29836697255179722709783618483925238251680, .7420289855072463768115942028985507246377, -.30126133057816173455023545102449133992200, .7398843930635838150289017341040462427746, -.30414733546729666446850615102448500692850, .7377521613832853025936599423631123919308, -.30702503529491181888388950937951449304830, .7356321839080459770114942528735632183908, -.30989447772286465854207904158101882785550, .7335243553008595988538681948424068767908, -.31275571000389684739317885942000430077330, .7314285714285714285714285714285714285714, -.31560877898630329552176476681779604405180, .7293447293447293447293447293447293447293, -.31845373111853458869546784626436419785030, .7272727272727272727272727272727272727273, -.32129061245373424782201254856772720813750, .7252124645892351274787535410764872521246, -.32411946865421192853773391107097268104550, .7231638418079096045197740112994350282486, -.32694034499585328257253991068864706903700, .7211267605633802816901408450704225352113, -.32975328637246797969240219572384376078850, .7191011235955056179775280898876404494382, -.33255833730007655635318997155991382896900, .7170868347338935574229691876750700280112, -.33535554192113781191153520921943709254280, .7150837988826815642458100558659217877095, -.33814494400871636381467055798566434532400, .7130919220055710306406685236768802228412, -.34092658697059319283795275623560883104800, .7111111111111111111111111111111111111111, -.34370051385331840121395430287520866841080, .7091412742382271468144044321329639889197, -.34646676734620857063262633346312213689100, .7071823204419889502762430939226519337017, -.34922538978528827602332285096053965389730, .7052341597796143250688705234159779614325, -.35197642315717814209818925519357435405250, .7032967032967032967032967032967032967033, -.35471990910292899856770532096561510115850, .7013698630136986301369863013698630136986, -.35745588892180374385176833129662554711100, .6994535519125683060109289617486338797814, -.36018440357500774995358483465679455548530, .6975476839237057220708446866485013623978, -.36290549368936841911903457003063522279280, .6956521739130434782608695652173913043478, -.36561919956096466943762379742111079394830, .6937669376693766937669376693766937669377, -.36832556115870762614150635272380895912650, .6918918918918918918918918918918918918919, -.37102461812787262962487488948681857436900, .6900269541778975741239892183288409703504, -.37371640979358405898480555151763837784530, .6881720430107526881720430107526881720430, -.37640097516425302659470730759494472295050, .6863270777479892761394101876675603217158, -.37907835293496944251145919224654790014030, .6844919786096256684491978609625668449198, -.38174858149084833769393299007788300514230, .6826666666666666666666666666666666666667, -.38441169891033200034513583887019194662580, .6808510638297872340425531914893617021277, -.38706774296844825844488013899535872042180, .6790450928381962864721485411140583554377, -.38971675114002518602873692543653305619950, .6772486772486772486772486772486772486772, -.39235876060286384303665840889152605086580, .6754617414248021108179419525065963060686, -.39499380824086893770896722344332374632350, .6736842105263157894736842105263157894737, -.39762193064713846624158577469643205404280, .6719160104986876640419947506561679790026, -.40024316412701266276741307592601515352730, .6701570680628272251308900523560209424084, -.40285754470108348090917615991202183067800, .6684073107049608355091383812010443864230, -.40546510810816432934799991016916465014230, .6666666666666666666666666666666666666667, -.40806588980822172674223224930756259709600, .6649350649350649350649350649350649350649, -.41065992498526837639616360320360399782650, .6632124352331606217616580310880829015544, -.41324724855021932601317757871584035456180, .6614987080103359173126614987080103359173, -.41582789514371093497757669865677598863850, .6597938144329896907216494845360824742268, -.41840189913888381489925905043492093682300, .6580976863753213367609254498714652956298, -.42096929464412963239894338585145305842150, .6564102564102564102564102564102564102564, -.42353011550580327293502591601281892508280, .6547314578005115089514066496163682864450, -.42608439531090003260516141381231136620050, .6530612244897959183673469387755102040816, -.42863216738969872610098832410585600882780, .6513994910941475826972010178117048346056, -.43117346481837132143866142541810404509300, .6497461928934010152284263959390862944162, -.43370832042155937902094819946796633303180, .6481012658227848101265822784810126582278, -.43623676677491801667585491486534010618930, .6464646464646464646464646464646464646465, -.43875883620762790027214350629947148263450, .6448362720403022670025188916876574307305, -.44127456080487520440058801796112675219780, .6432160804020100502512562814070351758794, -.44378397241030093089975139264424797147500, .6416040100250626566416040100250626566416, -.44628710262841947420398014401143882423650, .6400000000000000000000000000000000000000, -.44878398282700665555822183705458883196130, .6384039900249376558603491271820448877805, -.45127464413945855836729492693848442286250, .6368159203980099502487562189054726368159, -.45375911746712049854579618113348260521900, .6352357320099255583126550868486352357320, -.45623743348158757315857769754074979573500, .6336633663366336633663366336633663366337, -.45870962262697662081833982483658473938700, .6320987654320987654320987654320987654321, -.46117571512217014895185229761409573256980, .6305418719211822660098522167487684729064, -.46363574096303250549055974261136725544930, .6289926289926289926289926289926289926290, -.46608972992459918316399125615134835243230, .6274509803921568627450980392156862745098, -.46853771156323925639597405279346276074650, .6259168704156479217603911980440097799511, -.47097971521879100631480241645476780831830, .6243902439024390243902439024390243902439, -.47341577001667212165614273544633761048330, .6228710462287104622871046228710462287105, -.47584590486996386493601107758877333253630, .6213592233009708737864077669902912621359, -.47827014848147025860569669930555392056700, .6198547215496368038740920096852300242131, -.48068852934575190261057286988943815231330, .6183574879227053140096618357487922705314, -.48310107575113581113157579238759353756900, .6168674698795180722891566265060240963855, -.48550781578170076890899053978500887751580, .6153846153846153846153846153846153846154, -.48790877731923892879351001283794175833480, .6139088729016786570743405275779376498801, -.49030398804519381705802061333088204264650, .6124401913875598086124401913875598086124, -.49269347544257524607047571407747454941280, .6109785202863961813842482100238663484487, -.49507726679785146739476431321236304938800, .6095238095238095238095238095238095238095, -.49745538920281889838648226032091770321130, .6080760095011876484560570071258907363420, -.49982786955644931126130359189119189977650, .6066350710900473933649289099526066350711, -.50219473456671548383667413872899487614650, .6052009456264775413711583924349881796690, -.50455601075239520092452494282042607665050, .6037735849056603773584905660377358490566, -.50691172444485432801997148999362252652650, .6023529411764705882352941176470588235294, -.50926190178980790257412536448100581765150, .6009389671361502347417840375586854460094, -.51160656874906207391973111953120678663250, .5995316159250585480093676814988290398126, -.51394575110223428282552049495279788970950, .5981308411214953271028037383177570093458, -.51627947444845445623684554448118433356300, .5967365967365967365967365967365967365967, -.51860776420804555186805373523384332656850, .5953488372093023255813953488372093023256, -.52093064562418522900344441950437612831600, .5939675174013921113689095127610208816705, -.52324814376454775732838697877014055848100, .5925925925925925925925925925925925925926, -.52556028352292727401362526507000438869000, .5912240184757505773672055427251732101617, -.52786708962084227803046587723656557500350, .5898617511520737327188940092165898617512, -.53016858660912158374145519701414741575700, .5885057471264367816091954022988505747126, -.53246479886947173376654518506256863474850, .5871559633027522935779816513761467889908, -.53475575061602764748158733709715306758900, .5858123569794050343249427917620137299771, -.53704146589688361856929077475797384977350, .5844748858447488584474885844748858447489, -.53932196859560876944783558428753167390800, .5831435079726651480637813211845102505695, -.54159728243274429804188230264117009937750, .5818181818181818181818181818181818181818, -.54386743096728351609669971367111429572100, .5804988662131519274376417233560090702948, -.54613243759813556721383065450936555862450, .5791855203619909502262443438914027149321, -.54839232556557315767520321969641372561450, .5778781038374717832957110609480812641084, -.55064711795266219063194057525834068655950, .5765765765765765765765765765765765765766, -.55289683768667763352766542084282264113450, .5752808988764044943820224719101123595506, -.55514150754050151093110798683483153581600, .5739910313901345291479820627802690582960, -.55738115013400635344709144192165695130850, .5727069351230425055928411633109619686801, -.55961578793542265941596269840374588966350, .5714285714285714285714285714285714285714, -.56184544326269181269140062795486301183700, .5701559020044543429844097995545657015590, -.56407013828480290218436721261241473257550, .5688888888888888888888888888888888888889, -.56628989502311577464155334382667206227800, .5676274944567627494456762749445676274945, -.56850473535266865532378233183408156037350, .5663716814159292035398230088495575221239, -.57071468100347144680739575051120482385150, .5651214128035320088300220750551876379691, -.57291975356178548306473885531886480748650, .5638766519823788546255506607929515418502, -.57511997447138785144460371157038025558000, .5626373626373626373626373626373626373626, -.57731536503482350219940144597785547375700, .5614035087719298245614035087719298245614, -.57950594641464214795689713355386629700650, .5601750547045951859956236323851203501094, -.58169173963462239562716149521293118596100, .5589519650655021834061135371179039301310, -.58387276558098266665552955601015128195300, .5577342047930283224400871459694989106754, -.58604904500357812846544902640744112432000, .5565217391304347826086956521739130434783, -.58822059851708596855957011939608491957200, .5553145336225596529284164859002169197397, -.59038744660217634674381770309992134571100, .5541125541125541125541125541125541125541, -.59254960960667157898740242671919986605650, .5529157667386609071274298056155507559395, -.59470710774669277576265358220553025603300, .5517241379310344827586206896551724137931, -.59685996110779382384237123915227130055450, .5505376344086021505376344086021505376344, -.59900818964608337768851242799428291618800, .5493562231759656652360515021459227467811, -.60115181318933474940990890900138765573500, .5481798715203426124197002141327623126338, -.60329085143808425240052883964381180703650, .5470085470085470085470085470085470085470, -.60542532396671688843525771517306566238400, .5458422174840085287846481876332622601279, -.60755525022454170969155029524699784815300, .5446808510638297872340425531914893617021, -.60968064953685519036241657886421307921400, .5435244161358811040339702760084925690021, -.61180154110599282990534675263916142284850, .5423728813559322033898305084745762711864, -.61391794401237043121710712512140162289150, .5412262156448202959830866807610993657505, -.61602987721551394351138242200249806046500, .5400843881856540084388185654008438818565, -.61813735955507864705538167982012964785100, .5389473684210526315789473684210526315789, -.62024040975185745772080281312810257077200, .5378151260504201680672268907563025210084, -.62233904640877868441606324267922900617100, .5366876310272536687631027253668763102725, -.62443328801189346144440150965237990021700, .5355648535564853556485355648535564853556, -.62652315293135274476554741340805776417250, .5344467640918580375782881002087682672234, -.62860865942237409420556559780379757285100, .5333333333333333333333333333333333333333, -.63068982562619868570408243613201193511500, .5322245322245322245322245322245322245322, -.63276666957103777644277897707070223987100, .5311203319502074688796680497925311203320, -.63483920917301017716738442686619237065300, .5300207039337474120082815734989648033126, -.63690746223706917739093569252872839570050, .5289256198347107438016528925619834710744, -.63897144645792069983514238629140891134750, .5278350515463917525773195876288659793814, -.64103117942093124081992527862894348800200, .5267489711934156378600823045267489711934, -.64308667860302726193566513757104985415950, .5256673511293634496919917864476386036961, -.64513796137358470073053240412264131009600, .5245901639344262295081967213114754098361, -.64718504499530948859131740391603671014300, .5235173824130879345603271983640081799591, -.64922794662510974195157587018911726772800, .5224489795918367346938775510204081632653, -.65126668331495807251485530287027359008800, .5213849287169042769857433808553971486762, -.65330127201274557080523663898929953575150, .5203252032520325203252032520325203252033, -.65533172956312757406749369692988693714150, .5192697768762677484787018255578093306288, -.65735807270835999727154330685152672231200, .5182186234817813765182186234817813765182, -.65938031808912778153342060249997302889800, .5171717171717171717171717171717171717172, -.66139848224536490484126716182800009846700, .5161290322580645161290322580645161290323, -.66341258161706617713093692145776003599150, .5150905432595573440643863179074446680080, -.66542263254509037562201001492212526500250, .5140562248995983935742971887550200803213, -.66742865127195616370414654738851822912700, .5130260521042084168336673346693386773547, -.66943065394262923906154583164607174694550, .5120000000000000000000000000000000000000, -.67142865660530226534774556057527661323550, .5109780439121756487025948103792415169661, -.67342267521216669923234121597488410770900, .5099601593625498007968127490039840637450, -.67541272562017662384192817626171745359900, .5089463220675944333996023856858846918489, -.67739882359180603188519853574689477682100, .5079365079365079365079365079365079365079, -.67938098479579733801614338517538271844400, .5069306930693069306930693069306930693069, -.68135922480790300781450241629499942064300, .5059288537549407114624505928853754940711, -.68333355911162063645036823800182901322850, .5049309664694280078895463510848126232742, -.68530400309891936760919861626462079584600, .5039370078740157480314960629921259842520, -.68727057207096020619019327568821609020250, .5029469548133595284872298624754420432220, -.68923328123880889251040571252815425395950, .5019607843137254901960784313725490196078, -.69314718055994530941723212145818, 5.0e-01, -}; - - - -#define LOGTAB_TRANSLATE(x,h) (((x) - 1.)*icvLogTab[(h)+1]) -static const double ln_2 = 0.69314718055994530941723212145818; - -static void Log_32f( const float *_x, float *y, int n ) -{ - static const float shift[] = { 0, -1.f/512 }; - static const float - A0 = 0.3333333333333333333333333f, - A1 = -0.5f, - A2 = 1.f; - - #undef LOGPOLY - #define LOGPOLY(x) (((A0*(x) + A1)*(x) + A2)*(x)) - - int i = 0; - Cv32suf buf[4]; - const int* x = (const int*)_x; - -#if CV_SSE2 - if( USE_SSE2 ) - { - static const __m128d ln2_2 = _mm_set1_pd(ln_2); - static const __m128 _1_4 = _mm_set1_ps(1.f); - static const __m128 shift4 = _mm_set1_ps(-1.f/512); - - static const __m128 mA0 = _mm_set1_ps(A0); - static const __m128 mA1 = _mm_set1_ps(A1); - static const __m128 mA2 = _mm_set1_ps(A2); - - int CV_DECL_ALIGNED(16) idx[4]; - - for( ; i <= n - 4; i += 4 ) - { - __m128i h0 = _mm_loadu_si128((const __m128i*)(x + i)); - __m128i yi0 = _mm_sub_epi32(_mm_and_si128(_mm_srli_epi32(h0, 23), _mm_set1_epi32(255)), _mm_set1_epi32(127)); - __m128d yd0 = _mm_mul_pd(_mm_cvtepi32_pd(yi0), ln2_2); - __m128d yd1 = _mm_mul_pd(_mm_cvtepi32_pd(_mm_unpackhi_epi64(yi0,yi0)), ln2_2); - - __m128i xi0 = _mm_or_si128(_mm_and_si128(h0, _mm_set1_epi32(LOGTAB_MASK2_32F)), _mm_set1_epi32(127 << 23)); - - h0 = _mm_and_si128(_mm_srli_epi32(h0, 23 - LOGTAB_SCALE - 1), _mm_set1_epi32(LOGTAB_MASK*2)); - _mm_store_si128((__m128i*)idx, h0); - h0 = _mm_cmpeq_epi32(h0, _mm_set1_epi32(510)); - - __m128d t0, t1, t2, t3, t4; - t0 = _mm_load_pd(icvLogTab + idx[0]); - t2 = _mm_load_pd(icvLogTab + idx[1]); - t1 = _mm_unpackhi_pd(t0, t2); - t0 = _mm_unpacklo_pd(t0, t2); - t2 = _mm_load_pd(icvLogTab + idx[2]); - t4 = _mm_load_pd(icvLogTab + idx[3]); - t3 = _mm_unpackhi_pd(t2, t4); - t2 = _mm_unpacklo_pd(t2, t4); - - yd0 = _mm_add_pd(yd0, t0); - yd1 = _mm_add_pd(yd1, t2); - - __m128 yf0 = _mm_movelh_ps(_mm_cvtpd_ps(yd0), _mm_cvtpd_ps(yd1)); - - __m128 xf0 = _mm_sub_ps(_mm_castsi128_ps(xi0), _1_4); - xf0 = _mm_mul_ps(xf0, _mm_movelh_ps(_mm_cvtpd_ps(t1), _mm_cvtpd_ps(t3))); - xf0 = _mm_add_ps(xf0, _mm_and_ps(_mm_castsi128_ps(h0), shift4)); - - __m128 zf0 = _mm_mul_ps(xf0, mA0); - zf0 = _mm_mul_ps(_mm_add_ps(zf0, mA1), xf0); - zf0 = _mm_mul_ps(_mm_add_ps(zf0, mA2), xf0); - yf0 = _mm_add_ps(yf0, zf0); - - _mm_storeu_ps(y + i, yf0); - } - } - else -#endif - for( ; i <= n - 4; i += 4 ) - { - double x0, x1, x2, x3; - double y0, y1, y2, y3; - int h0, h1, h2, h3; - - h0 = x[i]; - h1 = x[i+1]; - buf[0].i = (h0 & LOGTAB_MASK2_32F) | (127 << 23); - buf[1].i = (h1 & LOGTAB_MASK2_32F) | (127 << 23); - - y0 = (((h0 >> 23) & 0xff) - 127) * ln_2; - y1 = (((h1 >> 23) & 0xff) - 127) * ln_2; - - h0 = (h0 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; - h1 = (h1 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; - - y0 += icvLogTab[h0]; - y1 += icvLogTab[h1]; - - h2 = x[i+2]; - h3 = x[i+3]; - - x0 = LOGTAB_TRANSLATE( buf[0].f, h0 ); - x1 = LOGTAB_TRANSLATE( buf[1].f, h1 ); - - buf[2].i = (h2 & LOGTAB_MASK2_32F) | (127 << 23); - buf[3].i = (h3 & LOGTAB_MASK2_32F) | (127 << 23); - - y2 = (((h2 >> 23) & 0xff) - 127) * ln_2; - y3 = (((h3 >> 23) & 0xff) - 127) * ln_2; - - h2 = (h2 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; - h3 = (h3 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; - - y2 += icvLogTab[h2]; - y3 += icvLogTab[h3]; - - x2 = LOGTAB_TRANSLATE( buf[2].f, h2 ); - x3 = LOGTAB_TRANSLATE( buf[3].f, h3 ); - - x0 += shift[h0 == 510]; - x1 += shift[h1 == 510]; - y0 += LOGPOLY( x0 ); - y1 += LOGPOLY( x1 ); - - y[i] = (float) y0; - y[i + 1] = (float) y1; - - x2 += shift[h2 == 510]; - x3 += shift[h3 == 510]; - y2 += LOGPOLY( x2 ); - y3 += LOGPOLY( x3 ); - - y[i + 2] = (float) y2; - y[i + 3] = (float) y3; - } - - for( ; i < n; i++ ) - { - int h0 = x[i]; - double y0; - float x0; - - y0 = (((h0 >> 23) & 0xff) - 127) * ln_2; - - buf[0].i = (h0 & LOGTAB_MASK2_32F) | (127 << 23); - h0 = (h0 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; - - y0 += icvLogTab[h0]; - x0 = (float)LOGTAB_TRANSLATE( buf[0].f, h0 ); - x0 += shift[h0 == 510]; - y0 += LOGPOLY( x0 ); - - y[i] = (float)y0; - } -} - - -static void Log_64f( const double *x, double *y, int n ) -{ - static const double shift[] = { 0, -1./512 }; - static const double - A7 = 1.0, - A6 = -0.5, - A5 = 0.333333333333333314829616256247390992939472198486328125, - A4 = -0.25, - A3 = 0.2, - A2 = -0.1666666666666666574148081281236954964697360992431640625, - A1 = 0.1428571428571428769682682968777953647077083587646484375, - A0 = -0.125; - - #undef LOGPOLY - #define LOGPOLY(x,k) ((x)+=shift[k], xq = (x)*(x),\ - (((A0*xq + A2)*xq + A4)*xq + A6)*xq + \ - (((A1*xq + A3)*xq + A5)*xq + A7)*(x)) - - int i = 0; - DBLINT buf[4]; - DBLINT *X = (DBLINT *) x; - -#if CV_SSE2 - if( USE_SSE2 ) - { - static const __m128d ln2_2 = _mm_set1_pd(ln_2); - static const __m128d _1_2 = _mm_set1_pd(1.); - static const __m128d shift2 = _mm_set1_pd(-1./512); - - static const __m128i log_and_mask2 = _mm_set_epi32(LOGTAB_MASK2, 0xffffffff, LOGTAB_MASK2, 0xffffffff); - static const __m128i log_or_mask2 = _mm_set_epi32(1023 << 20, 0, 1023 << 20, 0); - - static const __m128d mA0 = _mm_set1_pd(A0); - static const __m128d mA1 = _mm_set1_pd(A1); - static const __m128d mA2 = _mm_set1_pd(A2); - static const __m128d mA3 = _mm_set1_pd(A3); - static const __m128d mA4 = _mm_set1_pd(A4); - static const __m128d mA5 = _mm_set1_pd(A5); - static const __m128d mA6 = _mm_set1_pd(A6); - static const __m128d mA7 = _mm_set1_pd(A7); - - int CV_DECL_ALIGNED(16) idx[4]; - - for( ; i <= n - 4; i += 4 ) - { - __m128i h0 = _mm_loadu_si128((const __m128i*)(x + i)); - __m128i h1 = _mm_loadu_si128((const __m128i*)(x + i + 2)); - - __m128d xd0 = _mm_castsi128_pd(_mm_or_si128(_mm_and_si128(h0, log_and_mask2), log_or_mask2)); - __m128d xd1 = _mm_castsi128_pd(_mm_or_si128(_mm_and_si128(h1, log_and_mask2), log_or_mask2)); - - h0 = _mm_unpackhi_epi32(_mm_unpacklo_epi32(h0, h1), _mm_unpackhi_epi32(h0, h1)); - - __m128i yi0 = _mm_sub_epi32(_mm_and_si128(_mm_srli_epi32(h0, 20), - _mm_set1_epi32(2047)), _mm_set1_epi32(1023)); - __m128d yd0 = _mm_mul_pd(_mm_cvtepi32_pd(yi0), ln2_2); - __m128d yd1 = _mm_mul_pd(_mm_cvtepi32_pd(_mm_unpackhi_epi64(yi0, yi0)), ln2_2); - - h0 = _mm_and_si128(_mm_srli_epi32(h0, 20 - LOGTAB_SCALE - 1), _mm_set1_epi32(LOGTAB_MASK * 2)); - _mm_store_si128((__m128i*)idx, h0); - h0 = _mm_cmpeq_epi32(h0, _mm_set1_epi32(510)); - - __m128d t0, t1, t2, t3, t4; - t0 = _mm_load_pd(icvLogTab + idx[0]); - t2 = _mm_load_pd(icvLogTab + idx[1]); - t1 = _mm_unpackhi_pd(t0, t2); - t0 = _mm_unpacklo_pd(t0, t2); - t2 = _mm_load_pd(icvLogTab + idx[2]); - t4 = _mm_load_pd(icvLogTab + idx[3]); - t3 = _mm_unpackhi_pd(t2, t4); - t2 = _mm_unpacklo_pd(t2, t4); - - yd0 = _mm_add_pd(yd0, t0); - yd1 = _mm_add_pd(yd1, t2); - - xd0 = _mm_mul_pd(_mm_sub_pd(xd0, _1_2), t1); - xd1 = _mm_mul_pd(_mm_sub_pd(xd1, _1_2), t3); - - xd0 = _mm_add_pd(xd0, _mm_and_pd(_mm_castsi128_pd(_mm_unpacklo_epi32(h0, h0)), shift2)); - xd1 = _mm_add_pd(xd1, _mm_and_pd(_mm_castsi128_pd(_mm_unpackhi_epi32(h0, h0)), shift2)); - - __m128d zd0 = _mm_mul_pd(xd0, mA0); - __m128d zd1 = _mm_mul_pd(xd1, mA0); - zd0 = _mm_mul_pd(_mm_add_pd(zd0, mA1), xd0); - zd1 = _mm_mul_pd(_mm_add_pd(zd1, mA1), xd1); - zd0 = _mm_mul_pd(_mm_add_pd(zd0, mA2), xd0); - zd1 = _mm_mul_pd(_mm_add_pd(zd1, mA2), xd1); - zd0 = _mm_mul_pd(_mm_add_pd(zd0, mA3), xd0); - zd1 = _mm_mul_pd(_mm_add_pd(zd1, mA3), xd1); - zd0 = _mm_mul_pd(_mm_add_pd(zd0, mA4), xd0); - zd1 = _mm_mul_pd(_mm_add_pd(zd1, mA4), xd1); - zd0 = _mm_mul_pd(_mm_add_pd(zd0, mA5), xd0); - zd1 = _mm_mul_pd(_mm_add_pd(zd1, mA5), xd1); - zd0 = _mm_mul_pd(_mm_add_pd(zd0, mA6), xd0); - zd1 = _mm_mul_pd(_mm_add_pd(zd1, mA6), xd1); - zd0 = _mm_mul_pd(_mm_add_pd(zd0, mA7), xd0); - zd1 = _mm_mul_pd(_mm_add_pd(zd1, mA7), xd1); - - yd0 = _mm_add_pd(yd0, zd0); - yd1 = _mm_add_pd(yd1, zd1); - - _mm_storeu_pd(y + i, yd0); - _mm_storeu_pd(y + i + 2, yd1); - } - } - else -#endif - for( ; i <= n - 4; i += 4 ) - { - double xq; - double x0, x1, x2, x3; - double y0, y1, y2, y3; - int h0, h1, h2, h3; - - h0 = X[i].i.lo; - h1 = X[i + 1].i.lo; - buf[0].i.lo = h0; - buf[1].i.lo = h1; - - h0 = X[i].i.hi; - h1 = X[i + 1].i.hi; - buf[0].i.hi = (h0 & LOGTAB_MASK2) | (1023 << 20); - buf[1].i.hi = (h1 & LOGTAB_MASK2) | (1023 << 20); - - y0 = (((h0 >> 20) & 0x7ff) - 1023) * ln_2; - y1 = (((h1 >> 20) & 0x7ff) - 1023) * ln_2; - - h2 = X[i + 2].i.lo; - h3 = X[i + 3].i.lo; - buf[2].i.lo = h2; - buf[3].i.lo = h3; - - h0 = (h0 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; - h1 = (h1 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; - - y0 += icvLogTab[h0]; - y1 += icvLogTab[h1]; - - h2 = X[i + 2].i.hi; - h3 = X[i + 3].i.hi; - - x0 = LOGTAB_TRANSLATE( buf[0].d, h0 ); - x1 = LOGTAB_TRANSLATE( buf[1].d, h1 ); - - buf[2].i.hi = (h2 & LOGTAB_MASK2) | (1023 << 20); - buf[3].i.hi = (h3 & LOGTAB_MASK2) | (1023 << 20); - - y2 = (((h2 >> 20) & 0x7ff) - 1023) * ln_2; - y3 = (((h3 >> 20) & 0x7ff) - 1023) * ln_2; - - h2 = (h2 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; - h3 = (h3 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; - - y2 += icvLogTab[h2]; - y3 += icvLogTab[h3]; - - x2 = LOGTAB_TRANSLATE( buf[2].d, h2 ); - x3 = LOGTAB_TRANSLATE( buf[3].d, h3 ); - - y0 += LOGPOLY( x0, h0 == 510 ); - y1 += LOGPOLY( x1, h1 == 510 ); - - y[i] = y0; - y[i + 1] = y1; - - y2 += LOGPOLY( x2, h2 == 510 ); - y3 += LOGPOLY( x3, h3 == 510 ); - - y[i + 2] = y2; - y[i + 3] = y3; - } - - for( ; i < n; i++ ) - { - int h0 = X[i].i.hi; - double xq; - double x0, y0 = (((h0 >> 20) & 0x7ff) - 1023) * ln_2; - - buf[0].i.hi = (h0 & LOGTAB_MASK2) | (1023 << 20); - buf[0].i.lo = X[i].i.lo; - h0 = (h0 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; - - y0 += icvLogTab[h0]; - x0 = LOGTAB_TRANSLATE( buf[0].d, h0 ); - y0 += LOGPOLY( x0, h0 == 510 ); - y[i] = y0; - } -} - #ifdef HAVE_IPP static void Log_32f_ipp(const float *x, float *y, int n) { @@ -2256,7 +826,7 @@ static void Log_32f_ipp(const float *x, float *y, int n) } setIppErrorStatus(); } - Log_32f(x, y, n); + hal::log(x, y, n); } static void Log_64f_ipp(const double *x, double *y, int n) @@ -2270,11 +840,14 @@ static void Log_64f_ipp(const double *x, double *y, int n) } setIppErrorStatus(); } - Log_64f(x, y, n); + hal::log(x, y, n); } #define Log_32f Log_32f_ipp #define Log_64f Log_64f_ipp +#else +#define Log_32f hal::log +#define Log_64f hal::log #endif void log( InputArray _src, OutputArray _dst ) @@ -2651,6 +1224,11 @@ static bool ocl_pow(InputArray _src, double power, OutputArray _dst, #endif +static void InvSqrt_32f(const float* src, float* dst, int n) { hal::invSqrt(src, dst, n); } +static void InvSqrt_64f(const double* src, double* dst, int n) { hal::invSqrt(src, dst, n); } +static void Sqrt_32f(const float* src, float* dst, int n) { hal::sqrt(src, dst, n); } +static void Sqrt_64f(const double* src, double* dst, int n) { hal::sqrt(src, dst, n); } + void pow( InputArray _src, double power, OutputArray _dst ) { int type = _src.type(), depth = CV_MAT_DEPTH(type), @@ -3085,27 +1663,6 @@ void patchNaNs( InputOutputArray _a, double _val ) } } - -void exp(const float* src, float* dst, int n) -{ - Exp_32f(src, dst, n); -} - -void log(const float* src, float* dst, int n) -{ - Log_32f(src, dst, n); -} - -void fastAtan2(const float* y, const float* x, float* dst, int n, bool angleInDegrees) -{ - FastAtan2_32f(y, x, dst, n, angleInDegrees); -} - -void magnitude(const float* x, const float* y, float* dst, int n) -{ - Magnitude_32f(x, y, dst, n); -} - } CV_IMPL float cvCbrt(float value) { return cv::cubeRoot(value); } diff --git a/modules/core/src/stat.cpp b/modules/core/src/stat.cpp index ca707e78a4..e43df94448 100644 --- a/modules/core/src/stat.cpp +++ b/modules/core/src/stat.cpp @@ -2416,140 +2416,6 @@ void cv::minMaxLoc( InputArray _img, double* minVal, double* maxVal, namespace cv { -float normL2Sqr_(const float* a, const float* b, int n) -{ - int j = 0; float d = 0.f; -#if CV_SSE - if( USE_SSE2 ) - { - float CV_DECL_ALIGNED(16) buf[4]; - __m128 d0 = _mm_setzero_ps(), d1 = _mm_setzero_ps(); - - for( ; j <= n - 8; j += 8 ) - { - __m128 t0 = _mm_sub_ps(_mm_loadu_ps(a + j), _mm_loadu_ps(b + j)); - __m128 t1 = _mm_sub_ps(_mm_loadu_ps(a + j + 4), _mm_loadu_ps(b + j + 4)); - d0 = _mm_add_ps(d0, _mm_mul_ps(t0, t0)); - d1 = _mm_add_ps(d1, _mm_mul_ps(t1, t1)); - } - _mm_store_ps(buf, _mm_add_ps(d0, d1)); - d = buf[0] + buf[1] + buf[2] + buf[3]; - } - else -#endif - { - for( ; j <= n - 4; j += 4 ) - { - float t0 = a[j] - b[j], t1 = a[j+1] - b[j+1], t2 = a[j+2] - b[j+2], t3 = a[j+3] - b[j+3]; - d += t0*t0 + t1*t1 + t2*t2 + t3*t3; - } - } - - for( ; j < n; j++ ) - { - float t = a[j] - b[j]; - d += t*t; - } - return d; -} - - -float normL1_(const float* a, const float* b, int n) -{ - int j = 0; float d = 0.f; -#if CV_SSE - if( USE_SSE2 ) - { - float CV_DECL_ALIGNED(16) buf[4]; - static const int CV_DECL_ALIGNED(16) absbuf[4] = {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}; - __m128 d0 = _mm_setzero_ps(), d1 = _mm_setzero_ps(); - __m128 absmask = _mm_load_ps((const float*)absbuf); - - for( ; j <= n - 8; j += 8 ) - { - __m128 t0 = _mm_sub_ps(_mm_loadu_ps(a + j), _mm_loadu_ps(b + j)); - __m128 t1 = _mm_sub_ps(_mm_loadu_ps(a + j + 4), _mm_loadu_ps(b + j + 4)); - d0 = _mm_add_ps(d0, _mm_and_ps(t0, absmask)); - d1 = _mm_add_ps(d1, _mm_and_ps(t1, absmask)); - } - _mm_store_ps(buf, _mm_add_ps(d0, d1)); - d = buf[0] + buf[1] + buf[2] + buf[3]; - } - else -#elif CV_NEON - float32x4_t v_sum = vdupq_n_f32(0.0f); - for ( ; j <= n - 4; j += 4) - v_sum = vaddq_f32(v_sum, vabdq_f32(vld1q_f32(a + j), vld1q_f32(b + j))); - - float CV_DECL_ALIGNED(16) buf[4]; - vst1q_f32(buf, v_sum); - d = buf[0] + buf[1] + buf[2] + buf[3]; -#endif - { - for( ; j <= n - 4; j += 4 ) - { - d += std::abs(a[j] - b[j]) + std::abs(a[j+1] - b[j+1]) + - std::abs(a[j+2] - b[j+2]) + std::abs(a[j+3] - b[j+3]); - } - } - - for( ; j < n; j++ ) - d += std::abs(a[j] - b[j]); - return d; -} - -int normL1_(const uchar* a, const uchar* b, int n) -{ - int j = 0, d = 0; -#if CV_SSE - if( USE_SSE2 ) - { - __m128i d0 = _mm_setzero_si128(); - - for( ; j <= n - 16; j += 16 ) - { - __m128i t0 = _mm_loadu_si128((const __m128i*)(a + j)); - __m128i t1 = _mm_loadu_si128((const __m128i*)(b + j)); - - d0 = _mm_add_epi32(d0, _mm_sad_epu8(t0, t1)); - } - - for( ; j <= n - 4; j += 4 ) - { - __m128i t0 = _mm_cvtsi32_si128(*(const int*)(a + j)); - __m128i t1 = _mm_cvtsi32_si128(*(const int*)(b + j)); - - d0 = _mm_add_epi32(d0, _mm_sad_epu8(t0, t1)); - } - d = _mm_cvtsi128_si32(_mm_add_epi32(d0, _mm_unpackhi_epi64(d0, d0))); - } - else -#elif CV_NEON - uint32x4_t v_sum = vdupq_n_u32(0.0f); - for ( ; j <= n - 16; j += 16) - { - uint8x16_t v_dst = vabdq_u8(vld1q_u8(a + j), vld1q_u8(b + j)); - uint16x8_t v_low = vmovl_u8(vget_low_u8(v_dst)), v_high = vmovl_u8(vget_high_u8(v_dst)); - v_sum = vaddq_u32(v_sum, vaddl_u16(vget_low_u16(v_low), vget_low_u16(v_high))); - v_sum = vaddq_u32(v_sum, vaddl_u16(vget_high_u16(v_low), vget_high_u16(v_high))); - } - - uint CV_DECL_ALIGNED(16) buf[4]; - vst1q_u32(buf, v_sum); - d = buf[0] + buf[1] + buf[2] + buf[3]; -#endif - { - for( ; j <= n - 4; j += 4 ) - { - d += std::abs(a[j] - b[j]) + std::abs(a[j+1] - b[j+1]) + - std::abs(a[j+2] - b[j+2]) + std::abs(a[j+3] - b[j+3]); - } - } - for( ; j < n; j++ ) - d += std::abs(a[j] - b[j]); - return d; -} - template int normInf_(const T* src, const uchar* mask, ST* _result, int len, int cn) { @@ -2564,7 +2430,7 @@ normInf_(const T* src, const uchar* mask, ST* _result, int len, int cn) if( mask[i] ) { for( int k = 0; k < cn; k++ ) - result = std::max(result, ST(std::abs(src[k]))); + result = std::max(result, ST(cv_abs(src[k]))); } } *_result = result; @@ -2585,7 +2451,7 @@ normL1_(const T* src, const uchar* mask, ST* _result, int len, int cn) if( mask[i] ) { for( int k = 0; k < cn; k++ ) - result += std::abs(src[k]); + result += cv_abs(src[k]); } } *_result = result; @@ -2684,9 +2550,7 @@ normDiffL2_(const T* src1, const T* src2, const uchar* mask, ST* _result, int le Hamming::ResultType Hamming::operator()( const unsigned char* a, const unsigned char* b, int size ) const { - int result = 0; - cv::hal::normHamming(a, b, size, result); - return result; + return cv::hal::normHamming(a, b, size); } #define CV_DEF_NORM_FUNC(L, suffix, type, ntype) \ @@ -3037,16 +2901,12 @@ double cv::norm( InputArray _src, int normType, InputArray _mask ) if( normType == NORM_HAMMING ) { - int result = 0; - cv::hal::normHamming(data, (int)len, result); - return result; + return hal::normHamming(data, (int)len); } if( normType == NORM_HAMMING2 ) { - int result = 0; - hal::normHamming(data, (int)len, 2, result); - return result; + return hal::normHamming(data, (int)len, 2); } } } @@ -3072,9 +2932,7 @@ double cv::norm( InputArray _src, int normType, InputArray _mask ) for( size_t i = 0; i < it.nplanes; i++, ++it ) { - int one = 0; - cv::hal::normHamming(ptrs[0], total, cellSize, one); - result += one; + result += hal::normHamming(ptrs[0], total, cellSize); } return result; @@ -3558,9 +3416,7 @@ double cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _m for( size_t i = 0; i < it.nplanes; i++, ++it ) { - int one = 0; - hal::normHamming(ptrs[0], ptrs[1], total, cellSize, one); - result += one; + result += hal::normHamming(ptrs[0], ptrs[1], total, cellSize); } return result; @@ -3698,7 +3554,7 @@ static void batchDistHamming(const uchar* src1, const uchar* src2, size_t step2, if( !mask ) { for( int i = 0; i < nvecs; i++ ) - hal::normHamming(src1, src2 + step2*i, len, dist[i]); + dist[i] = hal::normHamming(src1, src2 + step2*i, len); } else { @@ -3706,7 +3562,7 @@ static void batchDistHamming(const uchar* src1, const uchar* src2, size_t step2, for( int i = 0; i < nvecs; i++ ) { if (mask[i]) - hal::normHamming(src1, src2 + step2*i, len, dist[i]); + dist[i] = hal::normHamming(src1, src2 + step2*i, len); else dist[i] = val0; } @@ -3720,7 +3576,7 @@ static void batchDistHamming2(const uchar* src1, const uchar* src2, size_t step2 if( !mask ) { for( int i = 0; i < nvecs; i++ ) - hal::normHamming(src1, src2 + step2*i, len, 2, dist[i]); + dist[i] = hal::normHamming(src1, src2 + step2*i, len, 2); } else { @@ -3728,7 +3584,7 @@ static void batchDistHamming2(const uchar* src1, const uchar* src2, size_t step2 for( int i = 0; i < nvecs; i++ ) { if (mask[i]) - hal::normHamming(src1, src2 + step2*i, len, 2, dist[i]); + dist[i] = hal::normHamming(src1, src2 + step2*i, len, 2); else dist[i] = val0; } diff --git a/modules/features2d/src/kaze/AKAZEFeatures.cpp b/modules/features2d/src/kaze/AKAZEFeatures.cpp index fd15345b29..d12656e994 100644 --- a/modules/features2d/src/kaze/AKAZEFeatures.cpp +++ b/modules/features2d/src/kaze/AKAZEFeatures.cpp @@ -812,7 +812,7 @@ void AKAZEFeatures::Compute_Main_Orientation(KeyPoint& kpt, const std::vector(float)(2.0*CV_PI) ? ang1 - (float)(5.0*CV_PI / 3.0) : ang1 + (float)(CV_PI / 3.0)); diff --git a/modules/hal/include/opencv2/hal.hpp b/modules/hal/include/opencv2/hal.hpp index 7641c46cad..95d1ac66c3 100644 --- a/modules/hal/include/opencv2/hal.hpp +++ b/modules/hal/include/opencv2/hal.hpp @@ -81,28 +81,17 @@ float normL1_(const float* a, const float* b, int n); float normL2Sqr_(const float* a, const float* b, int n); void exp(const float* src, float* dst, int n); +void exp(const double* src, double* dst, int n); void log(const float* src, float* dst, int n); +void log(const double* src, double* dst, int n); void fastAtan2(const float* y, const float* x, float* dst, int n, bool angleInDegrees); void magnitude(const float* x, const float* y, float* dst, int n); - -/** @brief Computes the cube root of an argument. - - The function cubeRoot computes \f$\sqrt[3]{\texttt{val}}\f$. Negative arguments are handled correctly. - NaN and Inf are not handled. The accuracy approaches the maximum possible accuracy for - single-precision data. - @param val A function argument. - */ -float cubeRoot(float val); - -/** @brief Calculates the angle of a 2D vector in degrees. - - The function fastAtan2 calculates the full-range angle of an input 2D vector. The angle is measured - in degrees and varies from 0 to 360 degrees. The accuracy is about 0.3 degrees. - @param x x-coordinate of the vector. - @param y y-coordinate of the vector. - */ -float fastAtan2(float y, float x); +void magnitude(const double* x, const double* y, double* dst, int n); +void sqrt(const float* src, float* dst, int len); +void sqrt(const double* src, double* dst, int len); +void invSqrt(const float* src, float* dst, int len); +void invSqrt(const double* src, double* dst, int len); }} //cv::hal diff --git a/modules/hal/include/opencv2/hal/defs.h b/modules/hal/include/opencv2/hal/defs.h index 6e1ff2a0ad..c011fe617e 100644 --- a/modules/hal/include/opencv2/hal/defs.h +++ b/modules/hal/include/opencv2/hal/defs.h @@ -380,7 +380,7 @@ cvRound( double value ) TEGRA_ROUND_DBL(value); #elif defined CV_ICC || defined __GNUC__ # if CV_VFP - ARM_ROUND_DBL(value) + ARM_ROUND_DBL(value); # else return (int)lrint(value); # endif @@ -488,7 +488,7 @@ CV_INLINE int cvRound(float value) TEGRA_ROUND_FLT(value); #elif defined CV_ICC || defined __GNUC__ # if CV_VFP - ARM_ROUND_FLT(value) + ARM_ROUND_FLT(value); # else return (int)lrintf(value); # endif diff --git a/modules/hal/include/opencv2/hal/intrin.hpp b/modules/hal/include/opencv2/hal/intrin.hpp index b7b147a199..c3c47e0594 100644 --- a/modules/hal/include/opencv2/hal/intrin.hpp +++ b/modules/hal/include/opencv2/hal/intrin.hpp @@ -438,6 +438,14 @@ OPENCV_HAL_IMPL_ADDSUB_OP(v_add_wrap, +, (_Tp), _Tp) OPENCV_HAL_IMPL_ADDSUB_OP(v_sub_wrap, -, (_Tp), _Tp) OPENCV_HAL_IMPL_ADDSUB_OP(v_absdiff, -, (rtype)std::abs, typename TypeTraits<_Tp>::abs_type) +template inline v_reg<_Tp, n> v_invsqrt(const v_reg<_Tp, n>& a) +{ + v_reg<_Tp, n> c; + for( int i = 0; i < n; i++ ) + c.s[i] = 1.f/std::sqrt(a.s[i]); + return c; +} + template inline v_reg<_Tp, n> v_magnitude(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) { v_reg<_Tp, n> c; @@ -446,6 +454,7 @@ template inline v_reg<_Tp, n> v_magnitude(const v_reg<_Tp, return c; } + template inline v_reg<_Tp, n> v_sqr_magnitude(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) { v_reg<_Tp, n> c; @@ -544,7 +553,7 @@ template inline void v_expand(const v_reg<_Tp, n>& a, } template inline v_reg::int_type, n> - v_reinterpret_int(const v_reg<_Tp, n>& a) + v_reinterpret_as_int(const v_reg<_Tp, n>& a) { v_reg::int_type, n> c; for( int i = 0; i < n; i++ ) @@ -553,7 +562,7 @@ template inline v_reg::int_type, n } template inline v_reg::uint_type, n> - v_reinterpret_uint(const v_reg<_Tp, n>& a) + v_reinterpret_as_uint(const v_reg<_Tp, n>& a) { v_reg::uint_type, n> c; for( int i = 0; i < n; i++ ) @@ -944,7 +953,7 @@ struct v_uint16x8 { return (ushort)_mm_extract_epi16(val, i); } - uchar get0() const + ushort get0() const { return (ushort)_mm_cvtsi128_si32(val); } @@ -1069,79 +1078,79 @@ inline v_int32x4 v_setall_s32(int v) { return v_int32x4(_mm_set1_epi32(v)); } inline v_float32x4 v_setall_f32(float v) { return v_float32x4(_mm_set1_ps(v)); } inline v_float64x2 v_setall_f64(double v) { return v_float64x2(_mm_set1_pd(v)); } -template inline v_uint8x16 v_reinterpret_u8(const _Tpvec& a) +template inline v_uint8x16 v_reinterpret_as_u8(const _Tpvec& a) { return v_uint8x16(a.val); } -inline v_uint8x16 v_reinterpret_u8(const v_float32x4& a) +inline v_uint8x16 v_reinterpret_as_u8(const v_float32x4& a) { return v_uint8x16(_mm_castps_si128(a.val)); } -inline v_uint8x16 v_reinterpret_u8(const v_float64x2& a) +inline v_uint8x16 v_reinterpret_as_u8(const v_float64x2& a) { return v_uint8x16(_mm_castpd_si128(a.val)); } -template inline v_int8x16 v_reinterpret_s8(const _Tpvec& a) +template inline v_int8x16 v_reinterpret_as_s8(const _Tpvec& a) { return v_int8x16(a.val); } -inline v_int8x16 v_reinterpret_s8(const v_float32x4& a) +inline v_int8x16 v_reinterpret_as_s8(const v_float32x4& a) { return v_int8x16(_mm_castps_si128(a.val)); } -inline v_int8x16 v_reinterpret_s8(const v_float64x2& a) +inline v_int8x16 v_reinterpret_as_s8(const v_float64x2& a) { return v_int8x16(_mm_castpd_si128(a.val)); } -template inline v_uint16x8 v_reinterpret_u16(const _Tpvec& a) +template inline v_uint16x8 v_reinterpret_as_u16(const _Tpvec& a) { return v_uint16x8(a.val); } -inline v_uint16x8 v_reinterpret_u16(const v_float32x4& a) +inline v_uint16x8 v_reinterpret_as_u16(const v_float32x4& a) { return v_uint16x8(_mm_castps_si128(a.val)); } -inline v_uint16x8 v_reinterpret_u16(const v_float64x2& a) +inline v_uint16x8 v_reinterpret_as_u16(const v_float64x2& a) { return v_uint16x8(_mm_castpd_si128(a.val)); } -template inline v_int16x8 v_reinterpret_s16(const _Tpvec& a) +template inline v_int16x8 v_reinterpret_as_s16(const _Tpvec& a) { return v_int16x8(a.val); } -inline v_int16x8 v_reinterpret_s16(const v_float32x4& a) +inline v_int16x8 v_reinterpret_as_s16(const v_float32x4& a) { return v_int16x8(_mm_castps_si128(a.val)); } -inline v_int16x8 v_reinterpret_s16(const v_float64x2& a) +inline v_int16x8 v_reinterpret_as_s16(const v_float64x2& a) { return v_int16x8(_mm_castpd_si128(a.val)); } -template inline v_uint32x4 v_reinterpret_u32(const _Tpvec& a) +template inline v_uint32x4 v_reinterpret_as_u32(const _Tpvec& a) { return v_uint32x4(a.val); } -inline v_uint32x4 v_reinterpret_u32(const v_float32x4& a) +inline v_uint32x4 v_reinterpret_as_u32(const v_float32x4& a) { return v_uint32x4(_mm_castps_si128(a.val)); } -inline v_uint32x4 v_reinterpret_u32(const v_float64x2& a) +inline v_uint32x4 v_reinterpret_as_u32(const v_float64x2& a) { return v_uint32x4(_mm_castpd_si128(a.val)); } -template inline v_int32x4 v_reinterpret_s32(const _Tpvec& a) +template inline v_int32x4 v_reinterpret_as_s32(const _Tpvec& a) { return v_int32x4(a.val); } -inline v_int32x4 v_reinterpret_s32(const v_float32x4& a) +inline v_int32x4 v_reinterpret_as_s32(const v_float32x4& a) { return v_int32x4(_mm_castps_si128(a.val)); } -inline v_int32x4 v_reinterpret_s32(const v_float64x2& a) +inline v_int32x4 v_reinterpret_as_s32(const v_float64x2& a) { return v_int32x4(_mm_castpd_si128(a.val)); } -template inline v_float32x4 v_reinterpret_f32(const _Tpvec& a) +template inline v_float32x4 v_reinterpret_as_f32(const _Tpvec& a) { return v_float32x4(_mm_castsi128_ps(a.val)); } -inline v_float32x4 v_reinterpret_f32(const v_float64x2& a) +inline v_float32x4 v_reinterpret_as_f32(const v_float64x2& a) { return v_float32x4(_mm_castpd_ps(a.val)); } -template inline v_float64x2 v_reinterpret_f64(const _Tpvec& a) +template inline v_float64x2 v_reinterpret_as_f64(const _Tpvec& a) { return v_float64x2(_mm_castsi128_pd(a.val)); } -inline v_float64x2 v_reinterpret_f64(const v_float64x2& a) +inline v_float64x2 v_reinterpret_as_f64(const v_float64x2& a) { return v_float64x2(_mm_castps_pd(a.val)); } -inline v_uint8x16 v_sat_u8(const v_uint16x8& a, const v_uint16x8& b) +inline v_uint8x16 v_cvtn_u16(const v_uint16x8& a, const v_uint16x8& b) { __m128i delta = _mm_set1_epi16(255); return v_uint8x16(_mm_packus_epi16(_mm_adds_epu16(_mm_subs_epu16(a.val, delta), delta), _mm_adds_epu16(_mm_subs_epu16(b.val, delta), delta))); } -inline v_uint8x16 v_sat_u8(const v_uint16x8& a, const v_uint16x8& b, int n) +inline v_uint8x16 v_shiftn_u16(const v_uint16x8& a, const v_uint16x8& b, int n) { // we assume that n > 0, and so the shifted 16-bit values can be treated as signed numbers. __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); @@ -1149,81 +1158,53 @@ inline v_uint8x16 v_sat_u8(const v_uint16x8& a, const v_uint16x8& b, int n) _mm_srli_epi16(_mm_add_epi16(b.val, delta), n))); } -inline v_uint8x16 v_sat_u8(const v_int16x8& a, const v_int16x8& b) +inline v_uint8x16 v_cvtun_s16(const v_int16x8& a, const v_int16x8& b) { return v_uint8x16(_mm_packus_epi16(a.val, b.val)); } -inline v_uint8x16 v_sat_u8(const v_int16x8& a, const v_int16x8& b, int n) +inline v_uint8x16 v_shiftun_s16(const v_int16x8& a, const v_int16x8& b, int n) { __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); return v_uint8x16(_mm_packus_epi16(_mm_srai_epi16(_mm_add_epi16(a.val, delta), n), _mm_srai_epi16(_mm_add_epi16(b.val, delta), n))); } -inline void v_storesat_u8(uchar* ptr, const v_uint16x8& a) +inline void v_storen_u16(uchar* ptr, const v_uint16x8& a) { __m128i delta = _mm_set1_epi16(255); _mm_storel_epi64((__m128i*)ptr, _mm_packus_epi16(_mm_adds_epu16(_mm_subs_epu16(a.val, delta), delta), delta)); } -inline void v_storesat_u8(uchar* ptr, const v_uint16x8& a, int n) +inline void v_shiftstoren_u16(uchar* ptr, const v_uint16x8& a, int n) { __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); _mm_storel_epi64((__m128i*)ptr, _mm_packus_epi16(_mm_srli_epi16(_mm_add_epi16(a.val, delta), n), delta)); } -inline void v_storesat_u8(uchar* ptr, const v_int16x8& a) +inline void v_storeun_s16(uchar* ptr, const v_int16x8& a) { _mm_storel_epi64((__m128i*)ptr, _mm_packus_epi16(a.val, a.val)); } -inline void v_storesat_u8(uchar* ptr, const v_int16x8& a, int n) +inline void v_shiftstoreun_s16(uchar* ptr, const v_int16x8& a, int n) { __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); _mm_storel_epi64((__m128i*)ptr, _mm_packus_epi16(_mm_srai_epi16(_mm_add_epi16(a.val, delta), n), delta)); } -inline v_int8x16 v_sat_s8(const v_uint16x8& a, const v_uint16x8& b) -{ - __m128i delta = _mm_set1_epi16(127); - return v_int8x16(_mm_packs_epi16(_mm_adds_epu16(_mm_subs_epu16(a.val, delta), delta), - _mm_adds_epu16(_mm_subs_epu16(b.val, delta), delta))); -} - -inline v_int8x16 v_sat_s8(const v_uint16x8& a, const v_uint16x8& b, int n) -{ - // we assume that n > 0, and so the shifted 16-bit values can be treated as signed numbers. - __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); - return v_int8x16(_mm_packs_epi16(_mm_srli_epi16(_mm_add_epi16(a.val, delta), n), - _mm_srli_epi16(_mm_add_epi16(b.val, delta), n))); -} - -inline v_int8x16 v_sat_s8(const v_int16x8& a, const v_int16x8& b) +inline v_int8x16 v_cvtn_s16(const v_int16x8& a, const v_int16x8& b) { return v_int8x16(_mm_packs_epi16(a.val, b.val)); } -inline v_int8x16 v_sat_s8(const v_int16x8& a, const v_int16x8& b, int n) +inline v_int8x16 v_shiftn_s16(const v_int16x8& a, const v_int16x8& b, int n) { __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); return v_int8x16(_mm_packs_epi16(_mm_srai_epi16(_mm_add_epi16(a.val, delta), n), _mm_srai_epi16(_mm_add_epi16(b.val, delta), n))); } -inline void v_storesat_s8(schar* ptr, const v_uint16x8& a) -{ - __m128i delta = _mm_set1_epi16(127); - _mm_storel_epi64((__m128i*)ptr, - _mm_packs_epi16(_mm_adds_epu16(_mm_subs_epu16(a.val, delta), delta), delta)); -} - -inline void v_storesat_s8(schar* ptr, const v_uint16x8& a, int n) -{ - __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); - _mm_storel_epi64((__m128i*)ptr, - _mm_packs_epi16(_mm_srli_epi16(_mm_add_epi16(a.val, delta), n), delta)); -} -inline void v_storesat_s8(schar* ptr, const v_int16x8& a) +inline void v_storen_s16(schar* ptr, const v_int16x8& a) { _mm_storel_epi64((__m128i*)ptr, _mm_packs_epi16(a.val, a.val)); } -inline void v_storesat_s8(schar* ptr, const v_int16x8& a, int n) +inline void v_shiftstoren_s16(schar* ptr, const v_int16x8& a, int n) { __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); _mm_storel_epi64((__m128i*)ptr, @@ -1236,7 +1217,7 @@ inline __m128i v_select_si128(__m128i mask, __m128i a, __m128i b) return _mm_xor_si128(b, _mm_and_si128(_mm_xor_si128(a, b), mask)); } -inline v_uint16x8 v_sat_u16(const v_uint32x4& a, const v_uint32x4& b) +inline v_uint16x8 v_cvtn_u32(const v_uint32x4& a, const v_uint32x4& b) { __m128i z = _mm_setzero_si128(), maxval32 = _mm_set1_epi32(65535), delta32 = _mm_set1_epi32(32768); __m128i a1 = _mm_sub_epi32(v_select_si128(_mm_cmpgt_epi32(z, a.val), maxval32, a.val), delta32); @@ -1244,20 +1225,20 @@ inline v_uint16x8 v_sat_u16(const v_uint32x4& a, const v_uint32x4& b) __m128i r = _mm_packs_epi32(a1, b1); return v_uint16x8(_mm_sub_epi16(r, _mm_set1_epi16(-32768))); } -inline v_uint16x8 v_sat_u16(const v_uint32x4& a, const v_uint32x4& b, int n) +inline v_uint16x8 v_shiftn_u32(const v_uint32x4& a, const v_uint32x4& b, int n) { __m128i delta = _mm_set1_epi32(1 << (n-1)), delta32 = _mm_set1_epi32(32768); __m128i a1 = _mm_sub_epi32(_mm_srli_epi32(_mm_add_epi32(a.val, delta), n), delta32); __m128i b1 = _mm_sub_epi32(_mm_srli_epi32(_mm_add_epi32(b.val, delta), n), delta32); return v_uint16x8(_mm_sub_epi16(_mm_packs_epi32(a1, b1), _mm_set1_epi16(-32768))); } -inline v_uint16x8 v_sat_u16(const v_int32x4& a, const v_int32x4& b) +inline v_uint16x8 v_cvtun_s32(const v_int32x4& a, const v_int32x4& b) { __m128i delta32 = _mm_set1_epi32(32768); __m128i r = _mm_packs_epi32(_mm_sub_epi32(a.val, delta32), _mm_sub_epi32(b.val, delta32)); return v_uint16x8(_mm_sub_epi16(r, _mm_set1_epi16(-32768))); } -inline v_uint16x8 v_sat_u16(const v_int32x4& a, const v_int32x4& b, int n) +inline v_uint16x8 v_shiftun_s32(const v_int32x4& a, const v_int32x4& b, int n) { __m128i delta = _mm_set1_epi32(1 << (n-1)), delta32 = _mm_set1_epi32(32768); __m128i a1 = _mm_sub_epi32(_mm_srai_epi32(_mm_add_epi32(a.val, delta), n), delta32); @@ -1265,28 +1246,28 @@ inline v_uint16x8 v_sat_u16(const v_int32x4& a, const v_int32x4& b, int n) return v_uint16x8(_mm_sub_epi16(_mm_packs_epi32(a1, b1), _mm_set1_epi16(-32768))); } -inline void v_storesat_u16(ushort* ptr, const v_uint32x4& a) +inline void v_storen_u32(ushort* ptr, const v_uint32x4& a) { __m128i z = _mm_setzero_si128(), maxval32 = _mm_set1_epi32(65535), delta32 = _mm_set1_epi32(32768); __m128i a1 = _mm_sub_epi32(v_select_si128(_mm_cmpgt_epi32(z, a.val), maxval32, a.val), delta32); __m128i r = _mm_sub_epi16(_mm_packs_epi32(a1, delta32), _mm_set1_epi16(-32768)); _mm_storel_epi64((__m128i*)ptr, r); } -inline void v_storesat_u16(ushort* ptr, const v_uint32x4& a, int n) +inline void v_shiftstoren_u32(ushort* ptr, const v_uint32x4& a, int n) { __m128i delta = _mm_set1_epi32(1 << (n-1)), delta32 = _mm_set1_epi32(32768); __m128i a1 = _mm_sub_epi32(_mm_srli_epi32(_mm_add_epi32(a.val, delta), n), delta32); __m128i r = _mm_sub_epi16(_mm_packs_epi32(a1, delta32), _mm_set1_epi16(-32768)); _mm_storel_epi64((__m128i*)ptr, r); } -inline void v_storesat_u16(ushort* ptr, const v_int32x4& a) +inline void v_storeun_s32(ushort* ptr, const v_int32x4& a) { __m128i delta32 = _mm_set1_epi32(32768); __m128i a1 = _mm_sub_epi32(a.val, delta32); __m128i r = _mm_sub_epi16(_mm_packs_epi32(a1, delta32), _mm_set1_epi16(-32768)); _mm_storel_epi64((__m128i*)ptr, r); } -inline void v_storesat_u16(ushort* ptr, const v_int32x4& a, int n) +inline void v_shiftstoreun_s32(ushort* ptr, const v_int32x4& a, int n) { __m128i delta = _mm_set1_epi32(1 << (n-1)), delta32 = _mm_set1_epi32(32768); __m128i a1 = _mm_sub_epi32(_mm_srai_epi32(_mm_add_epi32(a.val, delta), n), delta32); @@ -1294,45 +1275,20 @@ inline void v_storesat_u16(ushort* ptr, const v_int32x4& a, int n) _mm_storel_epi64((__m128i*)ptr, r); } -inline v_int16x8 v_sat_s16(const v_uint32x4& a, const v_uint32x4& b) -{ - __m128i z = _mm_setzero_si128(), maxval32 = _mm_set1_epi32(32767); - __m128i a1 = v_select_si128(_mm_cmpgt_epi32(z, a.val), maxval32, a.val); - __m128i b1 = v_select_si128(_mm_cmpgt_epi32(z, b.val), maxval32, b.val); - return v_int16x8(_mm_packs_epi32(a1, b1)); -} -inline v_int16x8 v_sat_s16(const v_uint32x4& a, const v_uint32x4& b, int n) -{ - __m128i delta = _mm_set1_epi32(1 << (n-1)); - return v_int16x8(_mm_packs_epi32(_mm_srli_epi32(_mm_add_epi32(a.val, delta), n), - _mm_srli_epi32(_mm_add_epi32(b.val, delta), n))); -} -inline v_int16x8 v_sat_s16(const v_int32x4& a, const v_int32x4& b) +inline v_int16x8 v_cvtn_s32(const v_int32x4& a, const v_int32x4& b) { return v_int16x8(_mm_packs_epi32(a.val, b.val)); } -inline v_int16x8 v_sat_s16(const v_int32x4& a, const v_int32x4& b, int n) +inline v_int16x8 v_shiftn_s32(const v_int32x4& a, const v_int32x4& b, int n) { __m128i delta = _mm_set1_epi32(1 << (n-1)); return v_int16x8(_mm_packs_epi32(_mm_srai_epi32(_mm_add_epi32(a.val, delta), n), _mm_srai_epi32(_mm_add_epi32(b.val, delta), n))); } -inline void v_storesat_s16(short* ptr, const v_uint32x4& a) -{ - __m128i z = _mm_setzero_si128(), maxval32 = _mm_set1_epi32(32767); - __m128i a1 = v_select_si128(_mm_cmpgt_epi32(z, a.val), maxval32, a.val); - _mm_storel_epi64((__m128i*)ptr, _mm_packs_epi32(a1, a1)); -} -inline void v_storesat_s16(short* ptr, const v_uint32x4& a, int n) -{ - __m128i delta = _mm_set1_epi32(1 << (n-1)); - __m128i a1 = _mm_srli_epi32(_mm_add_epi32(a.val, delta), n); - _mm_storel_epi64((__m128i*)ptr, _mm_packs_epi32(a1, a1)); -} -inline void v_storesat_s16(short* ptr, const v_int32x4& a) +inline void v_storen_s32(short* ptr, const v_int32x4& a) { _mm_storel_epi64((__m128i*)ptr, _mm_packs_epi32(a.val, a.val)); } -inline void v_storesat_s16(short* ptr, const v_int32x4& a, int n) +inline void v_shiftstoren_s32(short* ptr, const v_int32x4& a, int n) { __m128i delta = _mm_set1_epi32(1 << (n-1)); __m128i a1 = _mm_srai_epi32(_mm_add_epi32(a.val, delta), n); @@ -1373,6 +1329,8 @@ OPENCV_HAL_IMPL_SSE_BIN_OP(*, v_uint16x8, _mm_mullo_epi16) OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_int16x8, _mm_adds_epi16) OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_int16x8, _mm_subs_epi16) OPENCV_HAL_IMPL_SSE_BIN_OP(*, v_int16x8, _mm_mullo_epi16) +OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_uint32x4, _mm_add_epi32) +OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_uint32x4, _mm_sub_epi32) OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_int32x4, _mm_add_epi32) OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_int32x4, _mm_sub_epi32) OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_float32x4, _mm_add_ps) @@ -1421,9 +1379,26 @@ OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_float64x2, pd, _mm_castsi128_pd(_mm_set1_epi32(-1 inline v_float32x4 v_sqrt(v_float32x4 x) { return v_float32x4(_mm_sqrt_ps(x.val)); } + +inline v_float32x4 v_invsqrt(v_float32x4 x) +{ + static const __m128 _0_5 = _mm_set1_ps(0.5f), _1_5 = _mm_set1_ps(1.5f); + __m128 t = x.val; + __m128 h = _mm_mul_ps(t, _0_5); + t = _mm_rsqrt_ps(t); + t = _mm_mul_ps(t, _mm_sub_ps(_1_5, _mm_mul_ps(_mm_mul_ps(t, t), h))); + return v_float32x4(t); +} + inline v_float64x2 v_sqrt(v_float64x2 x) { return v_float64x2(_mm_sqrt_pd(x.val)); } +inline v_float64x2 v_invsqrt(v_float64x2 x) +{ + static const __m128d v_1 = _mm_set1_pd(1.); + return v_float64x2(_mm_div_pd(v_1, _mm_sqrt_pd(x.val))); +} + inline v_float32x4 v_abs(v_float32x4 x) { return v_float32x4(_mm_and_ps(x.val, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff)))); } inline v_float64x2 v_abs(v_float64x2 x) @@ -1893,7 +1868,7 @@ inline void v_transpose4x4(const _Tpvec& a0, const _Tpvec& a1, \ __m128i t0 = cast_from(_mm_unpacklo_##suffix(a0.val, a1.val)); \ __m128i t1 = cast_from(_mm_unpacklo_##suffix(a2.val, a3.val)); \ __m128i t2 = cast_from(_mm_unpackhi_##suffix(a0.val, a1.val)); \ - __m128i t3 = cast_from(_mm_unpacklo_##suffix(a2.val, a3.val)); \ + __m128i t3 = cast_from(_mm_unpackhi_##suffix(a2.val, a3.val)); \ \ b0.val = cast_to(_mm_unpacklo_epi64(t0, t1)); \ b1.val = cast_to(_mm_unpackhi_epi64(t0, t1)); \ @@ -2074,42 +2049,682 @@ inline v_float64x2 v_cvt_f64(const v_float32x4& a) struct v_uint8x16 { + explicit v_uint8x16(uint8x16_t v) : val(v) {} + v_uint8x16(uchar v0, uchar v1, uchar v2, uchar v3, uchar v4, uchar v5, uchar v6, uchar v7, + uchar v8, uchar v9, uchar v10, uchar v11, uchar v12, uchar v13, uchar v14, uchar v15) + { + uchar v[] = {v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15}; + val = vld1q_u8(v); + } + uchar get0() const + { + return vgetq_lane_u8(val, 0); + } + uint8x16_t val; }; struct v_int8x16 { + explicit v_int8x16(int8x16_t v) : val(v) {} + v_int8x16(schar v0, schar v1, schar v2, schar v3, schar v4, schar v5, schar v6, schar v7, + schar v8, schar v9, schar v10, schar v11, schar v12, schar v13, schar v14, schar v15) + { + schar v[] = {v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15}; + val = vld1q_s8(v); + } + schar get0() const + { + return vgetq_lane_s8(val, 0); + } + int8x16_t val; }; struct v_uint16x8 { + explicit v_uint16x8(uint16x8_t v) : val(v) {} + v_uint16x8(ushort v0, ushort v1, ushort v2, ushort v3, ushort v4, ushort v5, ushort v6, ushort v7) + { + ushort v[] = {v0, v1, v2, v3, v4, v5, v6, v7}; + val = vld1q_u16(v); + } + ushort get0() const + { + return vgetq_lane_u16(val, 0); + } + uint16x8_t val; }; struct v_int16x8 { + explicit v_int16x8(int16x8_t v) : val(v) {} + v_int16x8(short v0, short v1, short v2, short v3, short v4, short v5, short v6, short v7) + { + short v[] = {v0, v1, v2, v3, v4, v5, v6, v7}; + val = vld1q_s16(v); + } + short get0() const + { + return vgetq_lane_s16(val, 0); + } + int16x8_t val; }; struct v_uint32x4 { + explicit v_uint32x4(uint32x4_t v) : val(v) {} + v_uint32x4(unsigned v0, unsigned v1, unsigned v2, unsigned v3) + { + unsigned v[] = {v0, v1, v2, v3}; + val = vld1q_u32(v); + } + unsigned get0() const + { + return vgetq_lane_u32(val, 0); + } + uint32x4_t val; }; struct v_int32x4 { + explicit v_int32x4(int32x4_t v) : val(v) {} + v_int32x4(int v0, int v1, int v2, int v3) + { + int v[] = {v0, v1, v2, v3}; + val = vld1q_s32(v); + } + int get0() const + { + return vgetq_lane_s32(val, 0); + } int32x4_t val; }; struct v_float32x4 { + explicit v_float32x4(float32x4_t v) : val(v) {} + v_float32x4(float v0, float v1, float v2, float v3) + { + float v[] = {v0, v1, v2, v3}; + val = vld1q_f32(v); + } + float get0() const + { + return vgetq_lane_f32(val, 0); + } float32x4_t val; }; typedef v_reg v_float64x2; typedef v_reg v_float64x4; +#define OPENCV_HAL_IMPL_NEON_INIT(_Tpv, _Tp, suffix) \ +inline v_##_Tpv v_setzero_##suffix() { return v_##_Tpv(vdupq_n_##suffix((_Tp)0)); } \ +inline v_##_Tpv v_setall_##suffix(_Tp v) { return v_##_Tpv(vdupq_n_##suffix(v)); } \ +inline _Tpv##_t vreinterpretq_##suffix##_##suffix(_Tpv##_t v) { return v; } \ +inline v_uint8x16 v_reinterpret_as_u8(const v_##_Tpv& v) { return v_uint8x16(vreinterpretq_u8_##suffix(v.val)); } \ +inline v_int8x16 v_reinterpret_as_s8(const v_##_Tpv& v) { return v_int8x16(vreinterpretq_s8_##suffix(v.val)); } \ +inline v_uint16x8 v_reinterpret_as_u16(const v_##_Tpv& v) { return v_uint16x8(vreinterpretq_u16_##suffix(v.val)); } \ +inline v_int16x8 v_reinterpret_as_s16(const v_##_Tpv& v) { return v_int16x8(vreinterpretq_s16_##suffix(v.val)); } \ +inline v_uint32x4 v_reinterpret_as_u32(const v_##_Tpv& v) { return v_uint32x4(vreinterpretq_u32_##suffix(v.val)); } \ +inline v_int32x4 v_reinterpret_as_s32(const v_##_Tpv& v) { return v_int32x4(vreinterpretq_s32_##suffix(v.val)); } \ +inline v_float32x4 v_reinterpret_as_f32(const v_##_Tpv& v) { return v_float32x4(vreinterpretq_f32_##suffix(v.val)); } + +OPENCV_HAL_IMPL_NEON_INIT(uint8x16, uchar, u8) +OPENCV_HAL_IMPL_NEON_INIT(int8x16, schar, s8) +OPENCV_HAL_IMPL_NEON_INIT(uint16x8, ushort, u16) +OPENCV_HAL_IMPL_NEON_INIT(int16x8, short, s16) +OPENCV_HAL_IMPL_NEON_INIT(uint32x4, unsigned, u32) +OPENCV_HAL_IMPL_NEON_INIT(int32x4, int, s32) +OPENCV_HAL_IMPL_NEON_INIT(float32x4, float, f32) + +inline v_uint8x16 v_cvtn_u16(const v_uint16x8& a, const v_uint16x8& b) +{ + uint8x8_t a1 = vqmovn_u16(a.val), b1 = vqmovn_u16(b.val); + return v_uint8x16(vcombine_u8(a1, b1)); +} +inline v_uint8x16 v_cvtun_s16(const v_int16x8& a, const v_int16x8& b) +{ + uint8x8_t a1 = vqmovun_s16(a.val), b1 = vqmovun_s16(b.val); + return v_uint8x16(vcombine_u8(a1, b1)); +} +inline v_int8x16 v_cvtn_s16(const v_int16x8& a, const v_int16x8& b) +{ + int8x8_t a1 = vqmovn_s16(a.val), b1 = vqmovn_s16(b.val); + return v_int8x16(vcombine_s8(a1, b1)); +} +inline void v_storen_u16(uchar* ptr, const v_uint16x8& a) { vst1_u8(ptr, vqmovn_u16(a.val)); } +inline void v_storeun_s16(uchar* ptr, const v_int16x8& a) { vst1_u8(ptr, vqmovun_s16(a.val)); } +inline void v_storen_s16(schar* ptr, const v_int16x8& a) { vst1_s8(ptr, vqmovn_s16(a.val)); } + +inline v_uint16x8 v_cvtn_u32(const v_uint32x4& a, const v_uint32x4& b) +{ + uint16x4_t a1 = vqmovn_u32(a.val), b1 = vqmovn_u32(b.val); + return v_uint16x8(vcombine_u16(a1, b1)); +} +inline v_uint16x8 v_cvtun_s32(const v_int32x4& a, const v_int32x4& b) +{ + uint16x4_t a1 = vqmovun_s32(a.val), b1 = vqmovun_s32(b.val); + return v_uint16x8(vcombine_u16(a1, b1)); +} +inline v_int16x8 v_cvtn_s32(const v_int32x4& a, const v_int32x4& b) +{ + int16x4_t a1 = vqmovn_s32(a.val), b1 = vqmovn_s32(b.val); + return v_int16x8(vcombine_s16(a1, b1)); +} +inline void v_storen_u32(ushort* ptr, const v_uint32x4& a) { vst1_u16(ptr, vqmovn_u32(a.val)); } +inline void v_storeun_s32(ushort* ptr, const v_int32x4& a) { vst1_u16(ptr, vqmovun_s32(a.val)); } +inline void v_storen_s32(short* ptr, const v_int32x4& a) { vst1_s16(ptr, vqmovn_s32(a.val)); } + +#define v_shiftn_u16(a, b, n) v_uint8x16(vcombine_u8(vqrshrn_n_u16((a).val, (n)), vqrshrn_n_u16((b).val, (n)))) +#define v_shiftn_s16(a, b, n) v_int8x16(vcombine_s8(vqrshrn_n_s16((a).val, (n)), vqrshrn_n_s16((b).val, (n)))) +#define v_shiftn_u32(a, b, n) v_uint16x8(vcombine_u16(vqrshrn_n_u32((a).val, (n)), vqrshrn_n_u32((b).val, (n)))) +#define v_shiftn_s32(a, b, n) v_int16x8(vcombine_s16(vqrshrn_n_s32((a).val, (n)), vqrshrn_n_s32((b).val, (n)))) +#define v_shiftun_s16(a, b, n) v_uint8x16(vcombine_u8(vqrshrun_n_s16((a).val, (n)), vqrshrun_n_s16((b).val, (n)))) +#define v_shiftun_s32(a, b, n) v_uint16x8(vcombine_u16(vqrshrun_n_s32((a).val, (n)), vqrshrun_n_s32((b).val, (n)))) +#define v_shiftstoren_u16(a, n) vst1_u8(vqrshrn_n_u16((a).val, (n))) +#define v_shiftstoren_s16(a, n) vst1_s8(vqrshrn_n_s16((a).val, (n))) +#define v_shiftstoreun_s16(a, n) vst1_u8(vqrshrun_n_s16((a).val, (n))) +#define v_shiftstoren_u32(a, n) vst1_u16(vqrshrn_n_u32((a).val, (n))) +#define v_shiftstoren_s32(a, n) vst1_s16(vqrshrn_n_s32((a).val, (n))) +#define v_shiftstoreun_s32(a, n) vst1_u16(vqrshrun_n_s32((a).val, (n))) + +inline v_float32x4 v_matmul(const v_float32x4& v, const v_float32x4& m0, + const v_float32x4& m1, const v_float32x4& m2, + const v_float32x4& m3) +{ + float32x2_t vl = vget_low_f32(v.val), vh = vget_high_f32(v.val); + float32x4_t res = vmulq_lane_f32(m0.val, vl, 0); + res = vmlaq_lane_f32(res, m1.val, vl, 1); + res = vmlaq_lane_f32(res, m2.val, vh, 0); + res = vmlaq_lane_f32(res, m3.val, vh, 1); + return v_float32x4(res); +} + +#define OPENCV_HAL_IMPL_NEON_BIN_OP(bin_op, _Tpvec, intrin) \ +inline _Tpvec operator bin_op (const _Tpvec& a, const _Tpvec& b) \ +{ \ + return _Tpvec(intrin(a.val, b.val)); \ +} \ +inline _Tpvec& operator bin_op##= (_Tpvec& a, const _Tpvec& b) \ +{ \ + a.val = intrin(a.val, b.val); \ + return a; \ +} + +OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_uint8x16, vqaddq_u8) +OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_uint8x16, vqsubq_u8) +OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_int8x16, vqaddq_s8) +OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_int8x16, vqsubq_u8) +OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_uint16x8, vqaddq_u16) +OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_uint16x8, vqsubq_u16) +OPENCV_HAL_IMPL_NEON_BIN_OP(*, v_uint16x8, vmulq_u16) +OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_int16x8, vqaddq_s16) +OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_int16x8, vqsubq_s16) +OPENCV_HAL_IMPL_NEON_BIN_OP(*, v_int16x8, vmulq_s16) +OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_int32x4, vaddq_s32) +OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_int32x4, vsubq_s32) +OPENCV_HAL_IMPL_NEON_BIN_OP(*, v_int32x4, vmulq_s32) +OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_float32x4, vaddq_f32) +OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_float32x4, vsubq_f32) +OPENCV_HAL_IMPL_NEON_BIN_OP(*, v_float32x4, vmulq_f32) + +inline v_float32x4 operator / (const v_float32x4& a, const v_float32x4& b) +{ + float32x4_t reciprocal = vrecpeq_f32(b.val); + reciprocal = vmulq_f32(vrecpsq_f32(b.val, reciprocal), reciprocal); + reciprocal = vmulq_f32(vrecpsq_f32(b.val, reciprocal), reciprocal); + return v_float32x4(vmulq_f32(a.val, reciprocal)); +} +inline v_float32x4& operator /= (v_float32x4& a, const v_float32x4& b) +{ + float32x4_t reciprocal = vrecpeq_f32(b.val); + reciprocal = vmulq_f32(vrecpsq_f32(b.val, reciprocal), reciprocal); + reciprocal = vmulq_f32(vrecpsq_f32(b.val, reciprocal), reciprocal); + a.val = vmulq_f32(a.val, reciprocal); + return a; +} + +#define OPENCV_HAL_IMPL_NEON_LOGIC_OP(_Tpvec, suffix) \ + OPENCV_HAL_IMPL_NEON_BIN_OP(&, _Tpvec, vandq_##suffix) \ + OPENCV_HAL_IMPL_NEON_BIN_OP(|, _Tpvec, vorrq_##suffix) \ + OPENCV_HAL_IMPL_NEON_BIN_OP(^, _Tpvec, veorq_##suffix) \ + inline _Tpvec operator ~ (const _Tpvec& a) \ + { \ + return _Tpvec(vmvnq_##suffix(a.val)); \ + } + +OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_uint8x16, u8) +OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_int8x16, s8) +OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_uint16x8, u16) +OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_int16x8, s16) +OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_uint32x4, u32) +OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_int32x4, s32) + +#define OPENCV_HAL_IMPL_NEON_FLT_BIT_OP(bin_op, intrin) \ +inline v_float32x4 operator bin_op (const v_float32x4& a, const v_float32x4& b) \ +{ \ + return v_float32x4(vreinterpretq_f32_s32(intrin(vreinterpretq_s32_f32(a.val), vreinterpretq_s32_f32(b.val)))); \ +} \ +inline v_float32x4& operator bin_op##= (v_float32x4& a, const v_float32x4& b) \ +{ \ + a.val = vreinterpretq_f32_s32(intrin(vreinterpretq_s32_f32(a.val), vreinterpretq_s32_f32(b.val))); \ + return a; \ +} + +OPENCV_HAL_IMPL_NEON_FLT_BIT_OP(&, vandq_s32) +OPENCV_HAL_IMPL_NEON_FLT_BIT_OP(|, vorrq_s32) +OPENCV_HAL_IMPL_NEON_FLT_BIT_OP(^, veorq_s32) + +inline v_float32x4 operator ~ (const v_float32x4& a) +{ + return v_float32x4(vreinterpretq_f32_s32(vmvnq_s32(vreinterpretq_s32_f32(a.val)))); +} + +inline v_float32x4 v_sqrt(const v_float32x4& x) +{ + float32x4_t e = vrsqrteq_f32(x.val); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(e, e), x.val), e); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(e, e), x.val), e); + return v_float32x4(vmulq_f32(e, x.val)); +} + +inline v_float32x4 v_invsqrt(const v_float32x4& x) +{ + float32x4_t e = vrsqrteq_f32(x.val); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(e, e), x.val), e); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(e, e), x.val), e); + return v_float32x4(e); +} + +inline v_float32x4 v_abs(v_float32x4 x) +{ return v_float32x4(vabsq_f32(x.val)); } + +// TODO: exp, log, sin, cos + +#define OPENCV_HAL_IMPL_NEON_BIN_FUNC(_Tpvec, func, intrin) \ +inline _Tpvec func(const _Tpvec& a, const _Tpvec& b) \ +{ \ + return _Tpvec(intrin(a.val, b.val)); \ +} + +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_min, vminq_u8) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_max, vmaxq_u8) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int8x16, v_min, vminq_s8) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int8x16, v_max, vmaxq_s8) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_min, vminq_u16) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_max, vmaxq_u16) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int16x8, v_min, vminq_s16) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int16x8, v_max, vmaxq_s16) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint32x4, v_min, vminq_u32) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint32x4, v_max, vmaxq_u32) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int32x4, v_min, vminq_s32) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int32x4, v_max, vmaxq_s32) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float32x4, v_min, vminq_f32) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float32x4, v_max, vmaxq_f32) + + +#define OPENCV_HAL_IMPL_NEON_INT_CMP_OP(_Tpvec, cast, suffix, not_suffix) \ +inline _Tpvec operator == (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(cast(vceqq_##suffix(a.val, b.val))); } \ +inline _Tpvec operator != (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(cast(vmvnq_##not_suffix(vceqq_##suffix(a.val, b.val)))); } \ +inline _Tpvec operator < (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(cast(vcltq_##suffix(a.val, b.val))); } \ +inline _Tpvec operator > (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(cast(vcgtq_##suffix(a.val, b.val))); } \ +inline _Tpvec operator <= (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(cast(vcleq_##suffix(a.val, b.val))); } \ +inline _Tpvec operator >= (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(cast(vcgeq_##suffix(a.val, b.val))); } + +OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint8x16, OPENCV_HAL_NOP, u8, u8) +OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int8x16, OPENCV_HAL_NOP, s8, u8) +OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint16x8, OPENCV_HAL_NOP, u16, u16) +OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int16x8, OPENCV_HAL_NOP, s16, u16) +OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint32x4, OPENCV_HAL_NOP, u32, u32) +OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int32x4, OPENCV_HAL_NOP, s32, u32) +OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_float32x4, vreinterpretq_f32_u32, f32, u32) + +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_add_wrap, vaddq_u8) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int8x16, v_add_wrap, vaddq_s8) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_add_wrap, vaddq_u16) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int16x8, v_add_wrap, vaddq_s16) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_sub_wrap, vsubq_u8) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int8x16, v_sub_wrap, vsubq_s8) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_sub_wrap, vsubq_u16) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int16x8, v_sub_wrap, vsubq_s16) + +// TODO: absdiff for signed integers +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_absdiff, vabdq_u8) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_absdiff, vabdq_u16) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint32x4, v_absdiff, vabdq_u32) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float32x4, v_absdiff, vabdq_f32) + +inline v_float32x4 v_magnitude(const v_float32x4& a, const v_float32x4& b) +{ + v_float32x4 x(vmlaq_f32(vmulq_f32(a.val, a.val), b.val, b.val)); + return v_sqrt(x); +} + +inline v_float32x4 v_sqr_magnitude(const v_float32x4& a, const v_float32x4& b) +{ + return v_float32x4(vmlaq_f32(vmulq_f32(a.val, a.val), b.val, b.val)); +} + +inline v_float32x4 v_muladd(const v_float32x4& a, const v_float32x4& b, const v_float32x4& c) +{ + return v_float32x4(vmlaq_f32(c.val, a.val, b.val)); +} + +// trade efficiency for convenience +#define OPENCV_HAL_IMPL_NEON_SHIFT_OP(_Tpvec, _Tp, suffix) \ +inline _Tpvec operator << (const _Tpvec& a, int n) \ +{ return _Tpvec(vshlq_##suffix(a.val, vdupq_n_##suffix((_Tp)n))); } \ +inline _Tpvec operator >> (const _Tpvec& a, int n) \ +{ return _Tpvec(vshlq_##suffix(a.val, vdupq_n_##suffix((_Tp)-n))); } + +OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_uint8x16, uchar, u8) +OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_int8x16, schar, s8) +OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_uint16x8, ushort, u16) +OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_int16x8, short, s16) +OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_uint32x4, unsigned, u32) +OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_int32x4, int, s32) + +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_mullo, vmulq_u16) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int16x8, v_mullo, vmulq_s16) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int16x8, v_mulhi2, vqrdmulhq_s16) + +#define OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(_Tpvec, _Tp, suffix) \ +inline _Tpvec v_load(const _Tp* ptr) \ +{ return _Tpvec(vld1q_##suffix(ptr)); } \ +inline _Tpvec v_load_aligned(const _Tp* ptr) \ +{ return _Tpvec(vld1q_##suffix(ptr)); } \ +inline _Tpvec v_load_halves(const _Tp* ptr0, const _Tp* ptr1) \ +{ return _Tpvec(vcombine_##suffix(vld1_##suffix(ptr0), vld1_##suffix(ptr1))); } \ +inline void v_store(_Tp* ptr, const _Tpvec& a) \ +{ vst1q_##suffix(ptr, a.val); } \ +inline void v_store_aligned(_Tp* ptr, const _Tpvec& a) \ +{ vst1q_##suffix(ptr, a.val); } \ +inline void v_store_low(_Tp* ptr, const _Tpvec& a) \ +{ vst1_##suffix(ptr, vget_low_##suffix(a.val)); } \ +inline void v_store_high(_Tp* ptr, const _Tpvec& a) \ +{ vst1_##suffix(ptr, vget_high_##suffix(a.val)); } + +OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_uint8x16, uchar, u8) +OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_int8x16, schar, s8) +OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_uint16x8, ushort, u16) +OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_int16x8, short, s16) +OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_uint32x4, unsigned, u32) +OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_int32x4, int, s32) +OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_float32x4, float, f32) + +#define OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(_Tpvec, scalartype, func, scalar_func) \ +inline scalartype v_reduce_##func(const _Tpvec& a) \ +{ \ + scalartype CV_DECL_ALIGNED(16) buf[4]; \ + v_store_aligned(buf, a); \ + scalartype s0 = scalar_func(buf[0], buf[1]); \ + scalartype s1 = scalar_func(buf[2], buf[3]); \ + return scalar_func(s0, s1); \ +} + +OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_uint32x4, unsigned, sum, OPENCV_HAL_ADD) +OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_uint32x4, unsigned, max, std::max) +OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_uint32x4, unsigned, min, std::min) +OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_int32x4, int, sum, OPENCV_HAL_ADD) +OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_int32x4, int, max, std::max) +OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_int32x4, int, min, std::min) +OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_float32x4, float, sum, OPENCV_HAL_ADD) +OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_float32x4, float, max, std::max) +OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_float32x4, float, min, std::min) + +inline int v_signmask(const v_uint8x16& a) +{ + uint8x8_t m0 = vcreate_u8(CV_BIG_UINT(0x0706050403020100)); + uint8x16_t v0 = vshlq_u8(vshrq_n_u8(a.val, 7), vcombine_u8(m0, m0)); + uint64x2_t v1 = vpaddlq_u32(vpaddlq_u16(vpaddlq_u8(v0))); + return (int)vgetq_lane_u64(v1, 0) + ((int)vgetq_lane_u64(v1, 1) << 8); +} +inline int v_signmask(const v_int8x16& a) +{ return v_signmask(v_reinterpret_as_u8(a)); } + +inline int v_signmask(const v_uint16x8& a) +{ + uint16x4_t m0 = vcreate_u16(CV_BIG_UINT(0x0003000200010000)); + uint16x8_t v0 = vshlq_u16(vshrq_n_u16(a.val, 15), vcombine_u16(m0, m0)); + uint64x2_t v1 = vpaddlq_u32(vpaddlq_u16(v0)); + return (int)vgetq_lane_u64(v1, 0) + ((int)vgetq_lane_u64(v1, 1) << 4); +} +inline int v_signmask(const v_int16x8& a) +{ return v_signmask(v_reinterpret_as_u16(a)); } + +inline int v_signmask(const v_uint32x4& a) +{ + uint32x2_t m0 = vcreate_u32(CV_BIG_UINT(0x0000000100000000)); + uint32x4_t v0 = vshlq_u32(vshrq_n_u32(a.val, 31), vcombine_u32(m0, m0)); + uint64x2_t v1 = vpaddlq_u32(v0); + return (int)vgetq_lane_u64(v1, 0) + ((int)vgetq_lane_u64(v1, 1) << 2); +} +inline int v_signmask(const v_int32x4& a) +{ return v_signmask(v_reinterpret_as_u32(a)); } +inline int v_signmask(const v_float32x4& a) +{ return v_signmask(v_reinterpret_as_u32(a)); } + +#define OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(_Tpvec, suffix, shift) \ +inline bool v_check_all(const v_##_Tpvec& a) \ +{ \ + _Tpvec##_t v0 = vshrq_n_##suffix(vmvnq_##suffix(a.val), shift); \ + uint64x2_t v1 = vreinterpretq_u64_##suffix(v0); \ + return (vgetq_lane_u64(v1, 0) | vgetq_lane_u64(v1, 1)) == 0; \ +} \ +inline bool v_check_any(const v_##_Tpvec& a) \ +{ \ + _Tpvec##_t v0 = vshrq_n_##suffix(a.val, shift); \ + uint64x2_t v1 = vreinterpretq_u64_##suffix(v0); \ + return (vgetq_lane_u64(v1, 0) | vgetq_lane_u64(v1, 1)) != 0; \ +} + +OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(uint8x16, u8, 7) +OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(uint16x8, u16, 15) +OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(uint32x4, u32, 31) + +inline bool v_check_all(const v_int8x16& a) +{ return v_check_all(v_reinterpret_as_u8(a)); } +inline bool v_check_all(const v_int16x8& a) +{ return v_check_all(v_reinterpret_as_u16(a)); } +inline bool v_check_all(const v_int32x4& a) +{ return v_check_all(v_reinterpret_as_u32(a)); } +inline bool v_check_all(const v_float32x4& a) +{ return v_check_all(v_reinterpret_as_u32(a)); } + +inline bool v_check_any(const v_int8x16& a) +{ return v_check_all(v_reinterpret_as_u8(a)); } +inline bool v_check_any(const v_int16x8& a) +{ return v_check_all(v_reinterpret_as_u16(a)); } +inline bool v_check_any(const v_int32x4& a) +{ return v_check_all(v_reinterpret_as_u32(a)); } +inline bool v_check_any(const v_float32x4& a) +{ return v_check_all(v_reinterpret_as_u32(a)); } + +#define OPENCV_HAL_IMPL_NEON_SELECT(_Tpvec, suffix, usuffix) \ +inline _Tpvec v_select(const _Tpvec& mask, const _Tpvec& a, const _Tpvec& b) \ +{ \ + return _Tpvec(vbslq_##suffix(vreinterpretq_##usuffix##_##suffix(mask.val), a.val, b.val)); \ +} + +OPENCV_HAL_IMPL_NEON_SELECT(v_uint8x16, u8, u8) +OPENCV_HAL_IMPL_NEON_SELECT(v_int8x16, s8, u8) +OPENCV_HAL_IMPL_NEON_SELECT(v_uint16x8, u16, u16) +OPENCV_HAL_IMPL_NEON_SELECT(v_int16x8, s16, u16) +OPENCV_HAL_IMPL_NEON_SELECT(v_uint32x4, u32, u32) +OPENCV_HAL_IMPL_NEON_SELECT(v_int32x4, s32, u32) +OPENCV_HAL_IMPL_NEON_SELECT(v_float32x4, f32, u32) + +#define OPENCV_HAL_IMPL_NEON_EXPAND(_Tpvec, _Tpwvec, _Tp, suffix) \ +inline void v_expand(const _Tpvec& a, _Tpwvec& b0, _Tpwvec& b1) \ +{ \ + b0.val = vmovl_##suffix(vget_low_##suffix(a.val)); \ + b1.val = vmovl_##suffix(vget_high_##suffix(a.val)); \ +} \ +inline _Tpwvec v_load_expand(const _Tp* ptr) \ +{ \ + return _Tpwvec(vmovl_##suffix(vld1_##suffix(ptr))); \ +} + +OPENCV_HAL_IMPL_NEON_EXPAND(v_uint8x16, v_uint16x8, uchar, u8) +OPENCV_HAL_IMPL_NEON_EXPAND(v_int8x16, v_int16x8, schar, s8) +OPENCV_HAL_IMPL_NEON_EXPAND(v_uint16x8, v_uint32x4, ushort, u16) +OPENCV_HAL_IMPL_NEON_EXPAND(v_int16x8, v_int32x4, short, s16) + +inline v_uint32x4 v_load_expand_q(const uchar* ptr) +{ + uint8x8_t v0 = vcreate_u8(*(unsigned*)ptr); + uint16x4_t v1 = vget_low_u16(vmovl_u8(v0)); + return v_uint32x4(vmovl_u16(v1)); +} + +inline v_int32x4 v_load_expand_q(const schar* ptr) +{ + int8x8_t v0 = vcreate_s8(*(unsigned*)ptr); + int16x4_t v1 = vget_low_s16(vmovl_s8(v0)); + return v_int32x4(vmovl_s16(v1)); +} + +#define OPENCV_HAL_IMPL_NEON_UNPACKS(_Tpvec, suffix) \ +inline void v_zip(const v_##_Tpvec& a0, const v_##_Tpvec& a1, v_##_Tpvec& b0, v_##_Tpvec& b1) \ +{ \ + _Tpvec##x2_t p = vzipq_##suffix(a0.val, a1.val); \ + b0.val = p.val[0]; \ + b1.val = p.val[1]; \ +} \ +inline v_##_Tpvec v_combine_low(const v_##_Tpvec& a, const v_##_Tpvec& b) \ +{ \ + return v_##_Tpvec(vcombine_##suffix(vget_low_##suffix(a.val), vget_low_##suffix(b.val))); \ +} \ +inline v_##_Tpvec v_combine_high(const v_##_Tpvec& a, const v_##_Tpvec& b) \ +{ \ + return v_##_Tpvec(vcombine_##suffix(vget_high_##suffix(a.val), vget_high_##suffix(b.val))); \ +} \ +inline void v_recombine(const v_##_Tpvec& a, const v_##_Tpvec& b, v_##_Tpvec& c, v_##_Tpvec& d) \ +{ \ + c.val = vcombine_##suffix(vget_low_##suffix(a.val), vget_low_##suffix(b.val)); \ + d.val = vcombine_##suffix(vget_high_##suffix(a.val), vget_high_##suffix(b.val)); \ +} + +OPENCV_HAL_IMPL_NEON_UNPACKS(uint8x16, u8) +OPENCV_HAL_IMPL_NEON_UNPACKS(int8x16, s8) +OPENCV_HAL_IMPL_NEON_UNPACKS(uint16x8, u16) +OPENCV_HAL_IMPL_NEON_UNPACKS(int16x8, s16) +OPENCV_HAL_IMPL_NEON_UNPACKS(uint32x4, u32) +OPENCV_HAL_IMPL_NEON_UNPACKS(int32x4, s32) +OPENCV_HAL_IMPL_NEON_UNPACKS(float32x4, f32) + +inline v_int32x4 v_round(const v_float32x4& a) +{ + static const int32x4_t v_sign = vdupq_n_s32(1 << 31), + v_05 = vreinterpretq_s32_f32(vdupq_n_f32(0.5f)); + + int32x4_t v_addition = vorrq_s32(v_05, vandq_s32(v_sign, vreinterpretq_s32_f32(a.val))); + return v_int32x4(vcvtq_s32_f32(vaddq_f32(a.val, vreinterpretq_f32_s32(v_addition)))); +} + +inline v_int32x4 v_floor(const v_float32x4& a) +{ + int32x4_t a1 = vcvtq_s32_f32(a.val); + uint32x4_t mask = vcgtq_f32(vcvtq_f32_s32(a1), a.val); + return v_int32x4(vaddq_s32(a1, vreinterpretq_s32_u32(mask))); +} + +inline v_int32x4 v_ceil(const v_float32x4& a) +{ + int32x4_t a1 = vcvtq_s32_f32(a.val); + uint32x4_t mask = vcgtq_f32(a.val, vcvtq_f32_s32(a1)); + return v_int32x4(vsubq_s32(a1, vreinterpretq_s32_u32(mask))); +} + +inline v_int32x4 v_trunc(const v_float32x4& a) +{ return v_int32x4(vcvtq_s32_f32(a.val)); } + +#define OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(_Tpvec, suffix) \ +inline void transpose4x4(const v_##_Tpvec& a0, const v_##_Tpvec& a1, \ + const v_##_Tpvec& a2, const v_##_Tpvec& a3, \ + v_##_Tpvec& b0, v_##_Tpvec& b1, \ + v_##_Tpvec& b2, v_##_Tpvec& b3) \ +{ \ + /* m00 m01 m02 m03 */ \ + /* m10 m11 m12 m13 */ \ + /* m20 m21 m22 m23 */ \ + /* m30 m31 m32 m33 */ \ + _Tpvec##x2_t t0 = vtrnq_##suffix(a0.val, a1.val); \ + _Tpvec##x2_t t1 = vtrnq_##suffix(a2.val, a3.val); \ + /* m00 m10 m02 m12 */ \ + /* m01 m11 m03 m13 */ \ + /* m20 m30 m22 m32 */ \ + /* m21 m31 m23 m33 */ \ + b0.val = vcombine_##suffix(vget_low_##suffix(t0.val[0]), vget_low_##suffix(t1.val[0])); \ + b1.val = vcombine_##suffix(vget_low_##suffix(t0.val[1]), vget_low_##suffix(t1.val[1])); \ + b2.val = vcombine_##suffix(vget_high_##suffix(t0.val[0]), vget_high_##suffix(t1.val[0])); \ + b3.val = vcombine_##suffix(vget_high_##suffix(t0.val[1]), vget_high_##suffix(t1.val[1])); \ +} + +OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(uint32x4, u32) +OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(int32x4, s32) +OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(float32x4, f32) + +#define OPENCV_HAL_IMPL_NEON_INTERLEAVED(_Tpvec, _Tp, suffix) \ +inline void v_load_deinterleave(const _Tp* ptr, v_##_Tpvec& a, v_##_Tpvec& b, v_##_Tpvec& c) \ +{ \ + _Tpvec##x3_t v = vld3q_##suffix(ptr); \ + a.val = v.val[0]; \ + b.val = v.val[1]; \ + c.val = v.val[2]; \ +} \ +inline void v_load_deinterleave(const _Tp* ptr, v_##_Tpvec& a, v_##_Tpvec& b, \ + v_##_Tpvec& c, v_##_Tpvec& d) \ +{ \ + _Tpvec##x4_t v = vld4q_##suffix(ptr); \ + a.val = v.val[0]; \ + b.val = v.val[1]; \ + c.val = v.val[2]; \ + d.val = v.val[3]; \ +} \ +inline void v_store_interleave( _Tp* ptr, const v_##_Tpvec& a, const v_##_Tpvec& b, const v_##_Tpvec& c) \ +{ \ + _Tpvec##x3_t v; \ + v.val[0] = a.val; \ + v.val[1] = b.val; \ + v.val[2] = c.val; \ + vst3q_##suffix(ptr, v); \ +} \ +inline void v_store_interleave( _Tp* ptr, const v_##_Tpvec& a, const v_##_Tpvec& b, \ + const v_##_Tpvec& c, const v_##_Tpvec& d) \ +{ \ + _Tpvec##x4_t v; \ + v.val[0] = a.val; \ + v.val[1] = b.val; \ + v.val[2] = c.val; \ + v.val[3] = d.val; \ + vst4q_##suffix(ptr, v); \ +} + +OPENCV_HAL_IMPL_NEON_INTERLEAVED(uint8x16, uchar, u8) +OPENCV_HAL_IMPL_NEON_INTERLEAVED(int8x16, schar, s8) +OPENCV_HAL_IMPL_NEON_INTERLEAVED(uint16x8, ushort, u16) +OPENCV_HAL_IMPL_NEON_INTERLEAVED(int16x8, short, s16) +OPENCV_HAL_IMPL_NEON_INTERLEAVED(uint32x4, unsigned, u32) +OPENCV_HAL_IMPL_NEON_INTERLEAVED(int32x4, int, s32) +OPENCV_HAL_IMPL_NEON_INTERLEAVED(float32x4, float, f32) + +inline v_float32x4 v_cvt_f32(const v_int32x4& a) +{ + return v_float32x4(vcvtq_f32_s32(a.val)); +} + #else typedef v_reg v_uint8x16; @@ -2141,100 +2756,84 @@ inline v_int32x4 v_setall_s32(int v) { return v_int32x4::all(v); } inline v_float32x4 v_setall_f32(float v) { return v_float32x4::all(v); } inline v_float64x2 v_setall_f64(double v) { return v_float64x2::all(v); } -template inline v_uint8x16 v_reinterpret_u8(const v_reg<_Tp, n>& a) +template inline v_uint8x16 v_reinterpret_as_u8(const v_reg<_Tp, n>& a) { return v_reg<_Tp, n>::template reinterpret_as(a); } -template inline v_int8x16 v_reinterpret_s8(const v_reg<_Tp, n>& a) +template inline v_int8x16 v_reinterpret_as_s8(const v_reg<_Tp, n>& a) { return v_reg<_Tp, n>::template reinterpret_as(a); } -template inline v_uint16x8 v_reinterpret_u16(const v_reg<_Tp, n>& a) +template inline v_uint16x8 v_reinterpret_as_u16(const v_reg<_Tp, n>& a) { return v_reg<_Tp, n>::template reinterpret_as(a); } -template inline v_int16x8 v_reinterpret_s16(const v_reg<_Tp, n>& a) +template inline v_int16x8 v_reinterpret_as_s16(const v_reg<_Tp, n>& a) { return v_reg<_Tp, n>::template reinterpret_as(a); } -template inline v_uint32x4 v_reinterpret_u32(const v_reg<_Tp, n>& a) +template inline v_uint32x4 v_reinterpret_as_u32(const v_reg<_Tp, n>& a) { return v_reg<_Tp, n>::template reinterpret_as(a); } -template inline v_int32x4 v_reinterpret_s32(const v_reg<_Tp, n>& a) +template inline v_int32x4 v_reinterpret_as_s32(const v_reg<_Tp, n>& a) { return v_reg<_Tp, n>::template reinterpret_as(a); } -template inline v_float32x4 v_reinterpret_f32(const v_reg<_Tp, n>& a) +template inline v_float32x4 v_reinterpret_as_f32(const v_reg<_Tp, n>& a) { return v_reg<_Tp, n>::template reinterpret_as(a); } -template inline v_float64x2 v_reinterpret_f64(const v_reg<_Tp, n>& a) +template inline v_float64x2 v_reinterpret_as_f64(const v_reg<_Tp, n>& a) { return v_reg<_Tp, n>::template reinterpret_as(a); } -inline v_uint8x16 v_sat_u8(const v_uint16x8& a, const v_uint16x8& b) +inline v_uint8x16 v_cvtn_u16(const v_uint16x8& a, const v_uint16x8& b) { return v_cvtsat(a, b); } -inline v_uint8x16 v_sat_u8(const v_uint16x8& a, const v_uint16x8& b, int n) +inline v_uint8x16 v_shiftn_u16(const v_uint16x8& a, const v_uint16x8& b, int n) { return v_cvtsat(a, b, n); } -inline v_uint8x16 v_sat_u8(const v_int16x8& a, const v_int16x8& b) +inline v_uint8x16 v_cvtun_s16(const v_int16x8& a, const v_int16x8& b) { return v_cvtsat(a, b); } -inline v_uint8x16 v_sat_u8(const v_int16x8& a, const v_int16x8& b, int n) +inline v_uint8x16 v_shiftun_s16(const v_int16x8& a, const v_int16x8& b, int n) { return v_cvtsat(a, b, n); } -inline void v_storesat_u8(uchar* ptr, const v_uint16x8& b) +inline void v_storen_u16(uchar* ptr, const v_uint16x8& b) { return v_storesat(ptr, b); } -inline void v_storesat_u8(uchar* ptr, const v_uint16x8& b, int n) +inline void v_shiftstoren_u16(uchar* ptr, const v_uint16x8& b, int n) { return v_storesat(ptr, b, n); } -inline void v_storesat_u8(uchar* ptr, const v_int16x8& b) +inline void v_shiftstoreun_s16(uchar* ptr, const v_int16x8& b) { return v_storesat(ptr, b); } -inline void v_storesat_u8(uchar* ptr, const v_int16x8& b, int n) +inline void v_shiftstoreun_s16(uchar* ptr, const v_int16x8& b, int n) { return v_storesat(ptr, b, n); } -inline v_int8x16 v_sat_s8(const v_uint16x8& a, const v_uint16x8& b) -{ return v_cvtsat(a, b); } -inline v_int8x16 v_sat_s8(const v_uint16x8& a, const v_uint16x8& b, int n) -{ return v_cvtsat(a, b, n); } -inline v_int8x16 v_sat_s8(const v_int16x8& a, const v_int16x8& b) +inline v_int8x16 v_cvtn_s16(const v_int16x8& a, const v_int16x8& b) { return v_cvtsat(a, b); } -inline v_int8x16 v_sat_s8(const v_int16x8& a, const v_int16x8& b, int n) +inline v_int8x16 v_shiftn_s16(const v_int16x8& a, const v_int16x8& b, int n) { return v_cvtsat(a, b, n); } -inline void v_storesat_s8(schar* ptr, const v_uint16x8& b) +inline void v_storen_s16(schar* ptr, const v_int16x8& b) { return v_storesat(ptr, b); } -inline void v_storesat_s8(schar* ptr, const v_uint16x8& b, int n) -{ return v_storesat(ptr, b, n); } -inline void v_storesat_s8(schar* ptr, const v_int16x8& b) -{ return v_storesat(ptr, b); } -inline void v_storesat_s8(schar* ptr, const v_int16x8& b, int n) +inline void v_shiftstoren_s16(schar* ptr, const v_int16x8& b, int n) { return v_storesat(ptr, b, n); } -inline v_uint16x8 v_sat_u16(const v_uint32x4& a, const v_uint32x4& b) +inline v_uint16x8 v_cvtn_u32(const v_uint32x4& a, const v_uint32x4& b) { return v_cvtsat(a, b); } -inline v_uint16x8 v_sat_u16(const v_uint32x4& a, const v_uint32x4& b, int n) +inline v_uint16x8 v_shiftn_u32(const v_uint32x4& a, const v_uint32x4& b, int n) { return v_cvtsat(a, b, n); } -inline v_uint16x8 v_sat_u16(const v_int32x4& a, const v_int32x4& b) +inline v_uint16x8 v_cvtun_s32(const v_int32x4& a, const v_int32x4& b) { return v_cvtsat(a, b); } -inline v_uint16x8 v_sat_u16(const v_int32x4& a, const v_int32x4& b, int n) +inline v_uint16x8 v_shiftun_s32(const v_int32x4& a, const v_int32x4& b, int n) { return v_cvtsat(a, b, n); } -inline void v_storesat_u16(ushort* ptr, const v_uint32x4& b) +inline void v_storen_u32(ushort* ptr, const v_uint32x4& b) { return v_storesat(ptr, b); } -inline void v_storesat_u16(ushort* ptr, const v_uint32x4& b, int n) +inline void v_shiftstoren_u32(ushort* ptr, const v_uint32x4& b, int n) { return v_storesat(ptr, b, n); } -inline void v_storesat_u16(ushort* ptr, const v_int32x4& b) +inline void v_storeun_s32(ushort* ptr, const v_int32x4& b) { return v_storesat(ptr, b); } -inline void v_storesat_u16(ushort* ptr, const v_int32x4& b, int n) +inline void v_shiftstoreun_s32(ushort* ptr, const v_int32x4& b, int n) { return v_storesat(ptr, b, n); } -inline v_int16x8 v_sat_s16(const v_uint32x4& a, const v_uint32x4& b) -{ return v_cvtsat(a, b); } -inline v_int16x8 v_sat_s16(const v_uint32x4& a, const v_uint32x4& b, int n) -{ return v_cvtsat(a, b, n); } -inline v_int16x8 v_sat_s16(const v_int32x4& a, const v_int32x4& b) +inline v_int16x8 v_cvtn_s32(const v_int32x4& a, const v_int32x4& b) { return v_cvtsat(a, b); } -inline v_int16x8 v_sat_s16(const v_int32x4& a, const v_int32x4& b, int n) +inline v_int16x8 v_shiftn_s32(const v_int32x4& a, const v_int32x4& b, int n) { return v_cvtsat(a, b, n); } -inline void v_storesat_s16(short* ptr, const v_uint32x4& b) +inline void v_storen_s32(short* ptr, const v_int32x4& b) { return v_storesat(ptr, b); } -inline void v_storesat_s16(short* ptr, const v_uint32x4& b, int n) -{ return v_storesat(ptr, b, n); } -inline void v_storesat_s16(short* ptr, const v_int32x4& b) -{ return v_storesat(ptr, b); } -inline void v_storesat_s16(short* ptr, const v_int32x4& b, int n) +inline void v_shiftstoren_s32(short* ptr, const v_int32x4& b, int n) { return v_storesat(ptr, b, n); } inline v_float32x4 v_matmul(const v_float32x4& v, const v_float32x4& m0, diff --git a/modules/hal/src/mathfuncs.cpp b/modules/hal/src/mathfuncs.cpp index a3f69facca..e970cfedb8 100644 --- a/modules/hal/src/mathfuncs.cpp +++ b/modules/hal/src/mathfuncs.cpp @@ -44,4 +44,1309 @@ namespace cv { namespace hal { +///////////////////////////////////// ATAN2 //////////////////////////////////// +static const float atan2_p1 = 0.9997878412794807f*(float)(180/CV_PI); +static const float atan2_p3 = -0.3258083974640975f*(float)(180/CV_PI); +static const float atan2_p5 = 0.1555786518463281f*(float)(180/CV_PI); +static const float atan2_p7 = -0.04432655554792128f*(float)(180/CV_PI); + +#if CV_NEON +static inline float32x4_t cv_vrecpq_f32(float32x4_t val) +{ + float32x4_t reciprocal = vrecpeq_f32(val); + reciprocal = vmulq_f32(vrecpsq_f32(val, reciprocal), reciprocal); + reciprocal = vmulq_f32(vrecpsq_f32(val, reciprocal), reciprocal); + return reciprocal; +} +#endif + +void fastAtan2(const float *Y, const float *X, float *angle, int len, bool angleInDegrees ) +{ + int i = 0; + float scale = angleInDegrees ? 1 : (float)(CV_PI/180); + +#ifdef HAVE_TEGRA_OPTIMIZATION + if (tegra::useTegra() && tegra::FastAtan2_32f(Y, X, angle, len, scale)) + return; +#endif + +#if CV_SSE2 + Cv32suf iabsmask; iabsmask.i = 0x7fffffff; + __m128 eps = _mm_set1_ps((float)DBL_EPSILON), absmask = _mm_set1_ps(iabsmask.f); + __m128 _90 = _mm_set1_ps(90.f), _180 = _mm_set1_ps(180.f), _360 = _mm_set1_ps(360.f); + __m128 z = _mm_setzero_ps(), scale4 = _mm_set1_ps(scale); + __m128 p1 = _mm_set1_ps(atan2_p1), p3 = _mm_set1_ps(atan2_p3); + __m128 p5 = _mm_set1_ps(atan2_p5), p7 = _mm_set1_ps(atan2_p7); + + for( ; i <= len - 4; i += 4 ) + { + __m128 x = _mm_loadu_ps(X + i), y = _mm_loadu_ps(Y + i); + __m128 ax = _mm_and_ps(x, absmask), ay = _mm_and_ps(y, absmask); + __m128 mask = _mm_cmplt_ps(ax, ay); + __m128 tmin = _mm_min_ps(ax, ay), tmax = _mm_max_ps(ax, ay); + __m128 c = _mm_div_ps(tmin, _mm_add_ps(tmax, eps)); + __m128 c2 = _mm_mul_ps(c, c); + __m128 a = _mm_mul_ps(c2, p7); + a = _mm_mul_ps(_mm_add_ps(a, p5), c2); + a = _mm_mul_ps(_mm_add_ps(a, p3), c2); + a = _mm_mul_ps(_mm_add_ps(a, p1), c); + + __m128 b = _mm_sub_ps(_90, a); + a = _mm_xor_ps(a, _mm_and_ps(_mm_xor_ps(a, b), mask)); + + b = _mm_sub_ps(_180, a); + mask = _mm_cmplt_ps(x, z); + a = _mm_xor_ps(a, _mm_and_ps(_mm_xor_ps(a, b), mask)); + + b = _mm_sub_ps(_360, a); + mask = _mm_cmplt_ps(y, z); + a = _mm_xor_ps(a, _mm_and_ps(_mm_xor_ps(a, b), mask)); + + a = _mm_mul_ps(a, scale4); + _mm_storeu_ps(angle + i, a); + } +#elif CV_NEON + float32x4_t eps = vdupq_n_f32((float)DBL_EPSILON); + float32x4_t _90 = vdupq_n_f32(90.f), _180 = vdupq_n_f32(180.f), _360 = vdupq_n_f32(360.f); + float32x4_t z = vdupq_n_f32(0.0f), scale4 = vdupq_n_f32(scale); + float32x4_t p1 = vdupq_n_f32(atan2_p1), p3 = vdupq_n_f32(atan2_p3); + float32x4_t p5 = vdupq_n_f32(atan2_p5), p7 = vdupq_n_f32(atan2_p7); + + for( ; i <= len - 4; i += 4 ) + { + float32x4_t x = vld1q_f32(X + i), y = vld1q_f32(Y + i); + float32x4_t ax = vabsq_f32(x), ay = vabsq_f32(y); + float32x4_t tmin = vminq_f32(ax, ay), tmax = vmaxq_f32(ax, ay); + float32x4_t c = vmulq_f32(tmin, cv_vrecpq_f32(vaddq_f32(tmax, eps))); + float32x4_t c2 = vmulq_f32(c, c); + float32x4_t a = vmulq_f32(c2, p7); + a = vmulq_f32(vaddq_f32(a, p5), c2); + a = vmulq_f32(vaddq_f32(a, p3), c2); + a = vmulq_f32(vaddq_f32(a, p1), c); + + a = vbslq_f32(vcgeq_f32(ax, ay), a, vsubq_f32(_90, a)); + a = vbslq_f32(vcltq_f32(x, z), vsubq_f32(_180, a), a); + a = vbslq_f32(vcltq_f32(y, z), vsubq_f32(_360, a), a); + + vst1q_f32(angle + i, vmulq_f32(a, scale4)); + } +#endif + + for( ; i < len; i++ ) + { + float x = X[i], y = Y[i]; + float ax = std::abs(x), ay = std::abs(y); + float a, c, c2; + if( ax >= ay ) + { + c = ay/(ax + (float)DBL_EPSILON); + c2 = c*c; + a = (((atan2_p7*c2 + atan2_p5)*c2 + atan2_p3)*c2 + atan2_p1)*c; + } + else + { + c = ax/(ay + (float)DBL_EPSILON); + c2 = c*c; + a = 90.f - (((atan2_p7*c2 + atan2_p5)*c2 + atan2_p3)*c2 + atan2_p1)*c; + } + if( x < 0 ) + a = 180.f - a; + if( y < 0 ) + a = 360.f - a; + angle[i] = (float)(a*scale); + } +} + + +void magnitude(const float* x, const float* y, float* mag, int len) +{ + int i = 0; + +#if CV_SIMD128 + for( ; i <= len - 8; i += 8 ) + { + v_float32x4 x0 = v_load(x + i), x1 = v_load(x + i + 4); + v_float32x4 y0 = v_load(y + i), y1 = v_load(y + i + 4); + x0 = v_sqrt(v_muladd(x0, x0, y0*y0)); + x1 = v_sqrt(v_muladd(x1, x1, y1*y1)); + v_store(mag + i, x0); + v_store(mag + i + 4, x1); + } +#endif + + for( ; i < len; i++ ) + { + float x0 = x[i], y0 = y[i]; + mag[i] = std::sqrt(x0*x0 + y0*y0); + } +} + +void magnitude(const double* x, const double* y, double* mag, int len) +{ + int i = 0; + +#if defined CV_SIMD128_64F && CV_SIMD128_64F + for( ; i <= len - 4; i += 4 ) + { + v_float64x2 x0 = v_load(x + i), x1 = v_load(x + i + 2); + v_float64x2 y0 = v_load(y + i), y1 = v_load(y + i + 2); + x0 = v_sqrt(v_muladd(x0, x0, y0*y0)); + x1 = v_sqrt(v_muladd(x1, x1, y1*y1)); + v_store(mag + i, x0); + v_store(mag + i + 2, x1); + } +#endif + + for( ; i < len; i++ ) + { + double x0 = x[i], y0 = y[i]; + mag[i] = std::sqrt(x0*x0 + y0*y0); + } +} + + +void invSqrt(const float* src, float* dst, int len) +{ + int i = 0; + +#if CV_SIMD128 + for( ; i <= len - 8; i += 8 ) + { + v_float32x4 t0 = v_load(src + i), t1 = v_load(src + i + 4); + t0 = v_invsqrt(t0); + t1 = v_invsqrt(t1); + v_store(dst + i, t0); v_store(dst + i + 4, t1); + } +#endif + + for( ; i < len; i++ ) + dst[i] = 1/std::sqrt(src[i]); +} + + +void invSqrt(const double* src, double* dst, int len) +{ + int i = 0; + +#if CV_SSE2 + __m128d v_1 = _mm_set1_pd(1.0); + for ( ; i <= len - 2; i += 2) + _mm_storeu_pd(dst + i, _mm_div_pd(v_1, _mm_sqrt_pd(_mm_loadu_pd(src + i)))); +#endif + + for( ; i < len; i++ ) + dst[i] = 1/std::sqrt(src[i]); +} + + +void sqrt(const float* src, float* dst, int len) +{ + int i = 0; + +#if CV_SIMD128 + for( ; i <= len - 8; i += 8 ) + { + v_float32x4 t0 = v_load(src + i), t1 = v_load(src + i + 4); + t0 = v_sqrt(t0); + t1 = v_sqrt(t1); + v_store(dst + i, t0); v_store(dst + i + 4, t1); + } +#endif + + for( ; i < len; i++ ) + dst[i] = std::sqrt(src[i]); +} + + +void sqrt(const double* src, double* dst, int len) +{ + int i = 0; + +#if defined CV_SIMD128_64F && CV_SIMD128_64F + for( ; i <= len - 4; i += 4 ) + { + v_float64x2 t0 = v_load(src + i), t1 = v_load(src + i + 2); + t0 = v_sqrt(t0); + t1 = v_sqrt(t1); + v_store(dst + i, t0); v_store(dst + i + 2, t1); + } +#endif + + for( ; i < len; i++ ) + dst[i] = std::sqrt(src[i]); +} + +////////////////////////////////////// EXP ///////////////////////////////////// + +typedef union +{ + struct { +#if ( defined( WORDS_BIGENDIAN ) && !defined( OPENCV_UNIVERSAL_BUILD ) ) || defined( __BIG_ENDIAN__ ) + int hi; + int lo; +#else + int lo; + int hi; +#endif + } i; + double d; +} +DBLINT; + +#define EXPTAB_SCALE 6 +#define EXPTAB_MASK ((1 << EXPTAB_SCALE) - 1) + +#define EXPPOLY_32F_A0 .9670371139572337719125840413672004409288e-2 + +static const double expTab[] = { + 1.0 * EXPPOLY_32F_A0, + 1.0108892860517004600204097905619 * EXPPOLY_32F_A0, + 1.0218971486541166782344801347833 * EXPPOLY_32F_A0, + 1.0330248790212284225001082839705 * EXPPOLY_32F_A0, + 1.0442737824274138403219664787399 * EXPPOLY_32F_A0, + 1.0556451783605571588083413251529 * EXPPOLY_32F_A0, + 1.0671404006768236181695211209928 * EXPPOLY_32F_A0, + 1.0787607977571197937406800374385 * EXPPOLY_32F_A0, + 1.0905077326652576592070106557607 * EXPPOLY_32F_A0, + 1.1023825833078409435564142094256 * EXPPOLY_32F_A0, + 1.1143867425958925363088129569196 * EXPPOLY_32F_A0, + 1.126521618608241899794798643787 * EXPPOLY_32F_A0, + 1.1387886347566916537038302838415 * EXPPOLY_32F_A0, + 1.151189229952982705817759635202 * EXPPOLY_32F_A0, + 1.1637248587775775138135735990922 * EXPPOLY_32F_A0, + 1.1763969916502812762846457284838 * EXPPOLY_32F_A0, + 1.1892071150027210667174999705605 * EXPPOLY_32F_A0, + 1.2021567314527031420963969574978 * EXPPOLY_32F_A0, + 1.2152473599804688781165202513388 * EXPPOLY_32F_A0, + 1.2284805361068700056940089577928 * EXPPOLY_32F_A0, + 1.2418578120734840485936774687266 * EXPPOLY_32F_A0, + 1.2553807570246910895793906574423 * EXPPOLY_32F_A0, + 1.2690509571917332225544190810323 * EXPPOLY_32F_A0, + 1.2828700160787782807266697810215 * EXPPOLY_32F_A0, + 1.2968395546510096659337541177925 * EXPPOLY_32F_A0, + 1.3109612115247643419229917863308 * EXPPOLY_32F_A0, + 1.3252366431597412946295370954987 * EXPPOLY_32F_A0, + 1.3396675240533030053600306697244 * EXPPOLY_32F_A0, + 1.3542555469368927282980147401407 * EXPPOLY_32F_A0, + 1.3690024229745906119296011329822 * EXPPOLY_32F_A0, + 1.3839098819638319548726595272652 * EXPPOLY_32F_A0, + 1.3989796725383111402095281367152 * EXPPOLY_32F_A0, + 1.4142135623730950488016887242097 * EXPPOLY_32F_A0, + 1.4296133383919700112350657782751 * EXPPOLY_32F_A0, + 1.4451808069770466200370062414717 * EXPPOLY_32F_A0, + 1.4609177941806469886513028903106 * EXPPOLY_32F_A0, + 1.476826145939499311386907480374 * EXPPOLY_32F_A0, + 1.4929077282912648492006435314867 * EXPPOLY_32F_A0, + 1.5091644275934227397660195510332 * EXPPOLY_32F_A0, + 1.5255981507445383068512536895169 * EXPPOLY_32F_A0, + 1.5422108254079408236122918620907 * EXPPOLY_32F_A0, + 1.5590044002378369670337280894749 * EXPPOLY_32F_A0, + 1.5759808451078864864552701601819 * EXPPOLY_32F_A0, + 1.5931421513422668979372486431191 * EXPPOLY_32F_A0, + 1.6104903319492543081795206673574 * EXPPOLY_32F_A0, + 1.628027421857347766848218522014 * EXPPOLY_32F_A0, + 1.6457554781539648445187567247258 * EXPPOLY_32F_A0, + 1.6636765803267364350463364569764 * EXPPOLY_32F_A0, + 1.6817928305074290860622509524664 * EXPPOLY_32F_A0, + 1.7001063537185234695013625734975 * EXPPOLY_32F_A0, + 1.7186192981224779156293443764563 * EXPPOLY_32F_A0, + 1.7373338352737062489942020818722 * EXPPOLY_32F_A0, + 1.7562521603732994831121606193753 * EXPPOLY_32F_A0, + 1.7753764925265212525505592001993 * EXPPOLY_32F_A0, + 1.7947090750031071864277032421278 * EXPPOLY_32F_A0, + 1.8142521755003987562498346003623 * EXPPOLY_32F_A0, + 1.8340080864093424634870831895883 * EXPPOLY_32F_A0, + 1.8539791250833855683924530703377 * EXPPOLY_32F_A0, + 1.8741676341102999013299989499544 * EXPPOLY_32F_A0, + 1.8945759815869656413402186534269 * EXPPOLY_32F_A0, + 1.9152065613971472938726112702958 * EXPPOLY_32F_A0, + 1.9360617934922944505980559045667 * EXPPOLY_32F_A0, + 1.9571441241754002690183222516269 * EXPPOLY_32F_A0, + 1.9784560263879509682582499181312 * EXPPOLY_32F_A0, +}; + + +// the code below uses _mm_cast* intrinsics, which are not avialable on VS2005 +#if (defined _MSC_VER && _MSC_VER < 1500) || \ +(!defined __APPLE__ && defined __GNUC__ && __GNUC__*100 + __GNUC_MINOR__ < 402) +#undef CV_SSE2 +#define CV_SSE2 0 +#endif + +static const double exp_prescale = 1.4426950408889634073599246810019 * (1 << EXPTAB_SCALE); +static const double exp_postscale = 1./(1 << EXPTAB_SCALE); +static const double exp_max_val = 3000.*(1 << EXPTAB_SCALE); // log10(DBL_MAX) < 3000 + +void exp( const float *_x, float *y, int n ) +{ + static const float + A4 = (float)(1.000000000000002438532970795181890933776 / EXPPOLY_32F_A0), + A3 = (float)(.6931471805521448196800669615864773144641 / EXPPOLY_32F_A0), + A2 = (float)(.2402265109513301490103372422686535526573 / EXPPOLY_32F_A0), + A1 = (float)(.5550339366753125211915322047004666939128e-1 / EXPPOLY_32F_A0); + +#undef EXPPOLY +#define EXPPOLY(x) \ +(((((x) + A1)*(x) + A2)*(x) + A3)*(x) + A4) + + int i = 0; + const Cv32suf* x = (const Cv32suf*)_x; + Cv32suf buf[4]; + +#if CV_SSE2 + if( n >= 8 ) + { + static const __m128d prescale2 = _mm_set1_pd(exp_prescale); + static const __m128 postscale4 = _mm_set1_ps((float)exp_postscale); + static const __m128 maxval4 = _mm_set1_ps((float)(exp_max_val/exp_prescale)); + static const __m128 minval4 = _mm_set1_ps((float)(-exp_max_val/exp_prescale)); + + static const __m128 mA1 = _mm_set1_ps(A1); + static const __m128 mA2 = _mm_set1_ps(A2); + static const __m128 mA3 = _mm_set1_ps(A3); + static const __m128 mA4 = _mm_set1_ps(A4); + bool y_aligned = (size_t)(void*)y % 16 == 0; + + ushort CV_DECL_ALIGNED(16) tab_idx[8]; + + for( ; i <= n - 8; i += 8 ) + { + __m128 xf0, xf1; + xf0 = _mm_loadu_ps(&x[i].f); + xf1 = _mm_loadu_ps(&x[i+4].f); + __m128i xi0, xi1, xi2, xi3; + + xf0 = _mm_min_ps(_mm_max_ps(xf0, minval4), maxval4); + xf1 = _mm_min_ps(_mm_max_ps(xf1, minval4), maxval4); + + __m128d xd0 = _mm_cvtps_pd(xf0); + __m128d xd2 = _mm_cvtps_pd(_mm_movehl_ps(xf0, xf0)); + __m128d xd1 = _mm_cvtps_pd(xf1); + __m128d xd3 = _mm_cvtps_pd(_mm_movehl_ps(xf1, xf1)); + + xd0 = _mm_mul_pd(xd0, prescale2); + xd2 = _mm_mul_pd(xd2, prescale2); + xd1 = _mm_mul_pd(xd1, prescale2); + xd3 = _mm_mul_pd(xd3, prescale2); + + xi0 = _mm_cvtpd_epi32(xd0); + xi2 = _mm_cvtpd_epi32(xd2); + + xi1 = _mm_cvtpd_epi32(xd1); + xi3 = _mm_cvtpd_epi32(xd3); + + xd0 = _mm_sub_pd(xd0, _mm_cvtepi32_pd(xi0)); + xd2 = _mm_sub_pd(xd2, _mm_cvtepi32_pd(xi2)); + xd1 = _mm_sub_pd(xd1, _mm_cvtepi32_pd(xi1)); + xd3 = _mm_sub_pd(xd3, _mm_cvtepi32_pd(xi3)); + + xf0 = _mm_movelh_ps(_mm_cvtpd_ps(xd0), _mm_cvtpd_ps(xd2)); + xf1 = _mm_movelh_ps(_mm_cvtpd_ps(xd1), _mm_cvtpd_ps(xd3)); + + xf0 = _mm_mul_ps(xf0, postscale4); + xf1 = _mm_mul_ps(xf1, postscale4); + + xi0 = _mm_unpacklo_epi64(xi0, xi2); + xi1 = _mm_unpacklo_epi64(xi1, xi3); + xi0 = _mm_packs_epi32(xi0, xi1); + + _mm_store_si128((__m128i*)tab_idx, _mm_and_si128(xi0, _mm_set1_epi16(EXPTAB_MASK))); + + xi0 = _mm_add_epi16(_mm_srai_epi16(xi0, EXPTAB_SCALE), _mm_set1_epi16(127)); + xi0 = _mm_max_epi16(xi0, _mm_setzero_si128()); + xi0 = _mm_min_epi16(xi0, _mm_set1_epi16(255)); + xi1 = _mm_unpackhi_epi16(xi0, _mm_setzero_si128()); + xi0 = _mm_unpacklo_epi16(xi0, _mm_setzero_si128()); + + __m128d yd0 = _mm_unpacklo_pd(_mm_load_sd(expTab + tab_idx[0]), _mm_load_sd(expTab + tab_idx[1])); + __m128d yd1 = _mm_unpacklo_pd(_mm_load_sd(expTab + tab_idx[2]), _mm_load_sd(expTab + tab_idx[3])); + __m128d yd2 = _mm_unpacklo_pd(_mm_load_sd(expTab + tab_idx[4]), _mm_load_sd(expTab + tab_idx[5])); + __m128d yd3 = _mm_unpacklo_pd(_mm_load_sd(expTab + tab_idx[6]), _mm_load_sd(expTab + tab_idx[7])); + + __m128 yf0 = _mm_movelh_ps(_mm_cvtpd_ps(yd0), _mm_cvtpd_ps(yd1)); + __m128 yf1 = _mm_movelh_ps(_mm_cvtpd_ps(yd2), _mm_cvtpd_ps(yd3)); + + yf0 = _mm_mul_ps(yf0, _mm_castsi128_ps(_mm_slli_epi32(xi0, 23))); + yf1 = _mm_mul_ps(yf1, _mm_castsi128_ps(_mm_slli_epi32(xi1, 23))); + + __m128 zf0 = _mm_add_ps(xf0, mA1); + __m128 zf1 = _mm_add_ps(xf1, mA1); + + zf0 = _mm_add_ps(_mm_mul_ps(zf0, xf0), mA2); + zf1 = _mm_add_ps(_mm_mul_ps(zf1, xf1), mA2); + + zf0 = _mm_add_ps(_mm_mul_ps(zf0, xf0), mA3); + zf1 = _mm_add_ps(_mm_mul_ps(zf1, xf1), mA3); + + zf0 = _mm_add_ps(_mm_mul_ps(zf0, xf0), mA4); + zf1 = _mm_add_ps(_mm_mul_ps(zf1, xf1), mA4); + + zf0 = _mm_mul_ps(zf0, yf0); + zf1 = _mm_mul_ps(zf1, yf1); + + if( y_aligned ) + { + _mm_store_ps(y + i, zf0); + _mm_store_ps(y + i + 4, zf1); + } + else + { + _mm_storeu_ps(y + i, zf0); + _mm_storeu_ps(y + i + 4, zf1); + } + } + } + else +#endif + for( ; i <= n - 4; i += 4 ) + { + double x0 = x[i].f * exp_prescale; + double x1 = x[i + 1].f * exp_prescale; + double x2 = x[i + 2].f * exp_prescale; + double x3 = x[i + 3].f * exp_prescale; + int val0, val1, val2, val3, t; + + if( ((x[i].i >> 23) & 255) > 127 + 10 ) + x0 = x[i].i < 0 ? -exp_max_val : exp_max_val; + + if( ((x[i+1].i >> 23) & 255) > 127 + 10 ) + x1 = x[i+1].i < 0 ? -exp_max_val : exp_max_val; + + if( ((x[i+2].i >> 23) & 255) > 127 + 10 ) + x2 = x[i+2].i < 0 ? -exp_max_val : exp_max_val; + + if( ((x[i+3].i >> 23) & 255) > 127 + 10 ) + x3 = x[i+3].i < 0 ? -exp_max_val : exp_max_val; + + val0 = cvRound(x0); + val1 = cvRound(x1); + val2 = cvRound(x2); + val3 = cvRound(x3); + + x0 = (x0 - val0)*exp_postscale; + x1 = (x1 - val1)*exp_postscale; + x2 = (x2 - val2)*exp_postscale; + x3 = (x3 - val3)*exp_postscale; + + t = (val0 >> EXPTAB_SCALE) + 127; + t = !(t & ~255) ? t : t < 0 ? 0 : 255; + buf[0].i = t << 23; + + t = (val1 >> EXPTAB_SCALE) + 127; + t = !(t & ~255) ? t : t < 0 ? 0 : 255; + buf[1].i = t << 23; + + t = (val2 >> EXPTAB_SCALE) + 127; + t = !(t & ~255) ? t : t < 0 ? 0 : 255; + buf[2].i = t << 23; + + t = (val3 >> EXPTAB_SCALE) + 127; + t = !(t & ~255) ? t : t < 0 ? 0 : 255; + buf[3].i = t << 23; + + x0 = buf[0].f * expTab[val0 & EXPTAB_MASK] * EXPPOLY( x0 ); + x1 = buf[1].f * expTab[val1 & EXPTAB_MASK] * EXPPOLY( x1 ); + + y[i] = (float)x0; + y[i + 1] = (float)x1; + + x2 = buf[2].f * expTab[val2 & EXPTAB_MASK] * EXPPOLY( x2 ); + x3 = buf[3].f * expTab[val3 & EXPTAB_MASK] * EXPPOLY( x3 ); + + y[i + 2] = (float)x2; + y[i + 3] = (float)x3; + } + + for( ; i < n; i++ ) + { + double x0 = x[i].f * exp_prescale; + int val0, t; + + if( ((x[i].i >> 23) & 255) > 127 + 10 ) + x0 = x[i].i < 0 ? -exp_max_val : exp_max_val; + + val0 = cvRound(x0); + t = (val0 >> EXPTAB_SCALE) + 127; + t = !(t & ~255) ? t : t < 0 ? 0 : 255; + + buf[0].i = t << 23; + x0 = (x0 - val0)*exp_postscale; + + y[i] = (float)(buf[0].f * expTab[val0 & EXPTAB_MASK] * EXPPOLY(x0)); + } +} + +void exp( const double *_x, double *y, int n ) +{ + static const double + A5 = .99999999999999999998285227504999 / EXPPOLY_32F_A0, + A4 = .69314718055994546743029643825322 / EXPPOLY_32F_A0, + A3 = .24022650695886477918181338054308 / EXPPOLY_32F_A0, + A2 = .55504108793649567998466049042729e-1 / EXPPOLY_32F_A0, + A1 = .96180973140732918010002372686186e-2 / EXPPOLY_32F_A0, + A0 = .13369713757180123244806654839424e-2 / EXPPOLY_32F_A0; + +#undef EXPPOLY +#define EXPPOLY(x) (((((A0*(x) + A1)*(x) + A2)*(x) + A3)*(x) + A4)*(x) + A5) + + int i = 0; + Cv64suf buf[4]; + const Cv64suf* x = (const Cv64suf*)_x; + +#if CV_SSE2 + static const __m128d prescale2 = _mm_set1_pd(exp_prescale); + static const __m128d postscale2 = _mm_set1_pd(exp_postscale); + static const __m128d maxval2 = _mm_set1_pd(exp_max_val); + static const __m128d minval2 = _mm_set1_pd(-exp_max_val); + + static const __m128d mA0 = _mm_set1_pd(A0); + static const __m128d mA1 = _mm_set1_pd(A1); + static const __m128d mA2 = _mm_set1_pd(A2); + static const __m128d mA3 = _mm_set1_pd(A3); + static const __m128d mA4 = _mm_set1_pd(A4); + static const __m128d mA5 = _mm_set1_pd(A5); + + int CV_DECL_ALIGNED(16) tab_idx[4]; + + for( ; i <= n - 4; i += 4 ) + { + __m128d xf0 = _mm_loadu_pd(&x[i].f), xf1 = _mm_loadu_pd(&x[i+2].f); + __m128i xi0, xi1; + xf0 = _mm_min_pd(_mm_max_pd(xf0, minval2), maxval2); + xf1 = _mm_min_pd(_mm_max_pd(xf1, minval2), maxval2); + xf0 = _mm_mul_pd(xf0, prescale2); + xf1 = _mm_mul_pd(xf1, prescale2); + + xi0 = _mm_cvtpd_epi32(xf0); + xi1 = _mm_cvtpd_epi32(xf1); + xf0 = _mm_mul_pd(_mm_sub_pd(xf0, _mm_cvtepi32_pd(xi0)), postscale2); + xf1 = _mm_mul_pd(_mm_sub_pd(xf1, _mm_cvtepi32_pd(xi1)), postscale2); + + xi0 = _mm_unpacklo_epi64(xi0, xi1); + _mm_store_si128((__m128i*)tab_idx, _mm_and_si128(xi0, _mm_set1_epi32(EXPTAB_MASK))); + + xi0 = _mm_add_epi32(_mm_srai_epi32(xi0, EXPTAB_SCALE), _mm_set1_epi32(1023)); + xi0 = _mm_packs_epi32(xi0, xi0); + xi0 = _mm_max_epi16(xi0, _mm_setzero_si128()); + xi0 = _mm_min_epi16(xi0, _mm_set1_epi16(2047)); + xi0 = _mm_unpacklo_epi16(xi0, _mm_setzero_si128()); + xi1 = _mm_unpackhi_epi32(xi0, _mm_setzero_si128()); + xi0 = _mm_unpacklo_epi32(xi0, _mm_setzero_si128()); + + __m128d yf0 = _mm_unpacklo_pd(_mm_load_sd(expTab + tab_idx[0]), _mm_load_sd(expTab + tab_idx[1])); + __m128d yf1 = _mm_unpacklo_pd(_mm_load_sd(expTab + tab_idx[2]), _mm_load_sd(expTab + tab_idx[3])); + yf0 = _mm_mul_pd(yf0, _mm_castsi128_pd(_mm_slli_epi64(xi0, 52))); + yf1 = _mm_mul_pd(yf1, _mm_castsi128_pd(_mm_slli_epi64(xi1, 52))); + + __m128d zf0 = _mm_add_pd(_mm_mul_pd(mA0, xf0), mA1); + __m128d zf1 = _mm_add_pd(_mm_mul_pd(mA0, xf1), mA1); + + zf0 = _mm_add_pd(_mm_mul_pd(zf0, xf0), mA2); + zf1 = _mm_add_pd(_mm_mul_pd(zf1, xf1), mA2); + + zf0 = _mm_add_pd(_mm_mul_pd(zf0, xf0), mA3); + zf1 = _mm_add_pd(_mm_mul_pd(zf1, xf1), mA3); + + zf0 = _mm_add_pd(_mm_mul_pd(zf0, xf0), mA4); + zf1 = _mm_add_pd(_mm_mul_pd(zf1, xf1), mA4); + + zf0 = _mm_add_pd(_mm_mul_pd(zf0, xf0), mA5); + zf1 = _mm_add_pd(_mm_mul_pd(zf1, xf1), mA5); + + zf0 = _mm_mul_pd(zf0, yf0); + zf1 = _mm_mul_pd(zf1, yf1); + + _mm_storeu_pd(y + i, zf0); + _mm_storeu_pd(y + i + 2, zf1); + } +#endif + for( ; i <= n - 4; i += 4 ) + { + double x0 = x[i].f * exp_prescale; + double x1 = x[i + 1].f * exp_prescale; + double x2 = x[i + 2].f * exp_prescale; + double x3 = x[i + 3].f * exp_prescale; + + double y0, y1, y2, y3; + int val0, val1, val2, val3, t; + + t = (int)(x[i].i >> 52); + if( (t & 2047) > 1023 + 10 ) + x0 = t < 0 ? -exp_max_val : exp_max_val; + + t = (int)(x[i+1].i >> 52); + if( (t & 2047) > 1023 + 10 ) + x1 = t < 0 ? -exp_max_val : exp_max_val; + + t = (int)(x[i+2].i >> 52); + if( (t & 2047) > 1023 + 10 ) + x2 = t < 0 ? -exp_max_val : exp_max_val; + + t = (int)(x[i+3].i >> 52); + if( (t & 2047) > 1023 + 10 ) + x3 = t < 0 ? -exp_max_val : exp_max_val; + + val0 = cvRound(x0); + val1 = cvRound(x1); + val2 = cvRound(x2); + val3 = cvRound(x3); + + x0 = (x0 - val0)*exp_postscale; + x1 = (x1 - val1)*exp_postscale; + x2 = (x2 - val2)*exp_postscale; + x3 = (x3 - val3)*exp_postscale; + + t = (val0 >> EXPTAB_SCALE) + 1023; + t = !(t & ~2047) ? t : t < 0 ? 0 : 2047; + buf[0].i = (int64)t << 52; + + t = (val1 >> EXPTAB_SCALE) + 1023; + t = !(t & ~2047) ? t : t < 0 ? 0 : 2047; + buf[1].i = (int64)t << 52; + + t = (val2 >> EXPTAB_SCALE) + 1023; + t = !(t & ~2047) ? t : t < 0 ? 0 : 2047; + buf[2].i = (int64)t << 52; + + t = (val3 >> EXPTAB_SCALE) + 1023; + t = !(t & ~2047) ? t : t < 0 ? 0 : 2047; + buf[3].i = (int64)t << 52; + + y0 = buf[0].f * expTab[val0 & EXPTAB_MASK] * EXPPOLY( x0 ); + y1 = buf[1].f * expTab[val1 & EXPTAB_MASK] * EXPPOLY( x1 ); + + y[i] = y0; + y[i + 1] = y1; + + y2 = buf[2].f * expTab[val2 & EXPTAB_MASK] * EXPPOLY( x2 ); + y3 = buf[3].f * expTab[val3 & EXPTAB_MASK] * EXPPOLY( x3 ); + + y[i + 2] = y2; + y[i + 3] = y3; + } + + for( ; i < n; i++ ) + { + double x0 = x[i].f * exp_prescale; + int val0, t; + + t = (int)(x[i].i >> 52); + if( (t & 2047) > 1023 + 10 ) + x0 = t < 0 ? -exp_max_val : exp_max_val; + + val0 = cvRound(x0); + t = (val0 >> EXPTAB_SCALE) + 1023; + t = !(t & ~2047) ? t : t < 0 ? 0 : 2047; + + buf[0].i = (int64)t << 52; + x0 = (x0 - val0)*exp_postscale; + + y[i] = buf[0].f * expTab[val0 & EXPTAB_MASK] * EXPPOLY( x0 ); + } +} + +#undef EXPTAB_SCALE +#undef EXPTAB_MASK +#undef EXPPOLY_32F_A0 + +/////////////////////////////////////////// LOG /////////////////////////////////////// + +#define LOGTAB_SCALE 8 +#define LOGTAB_MASK ((1 << LOGTAB_SCALE) - 1) +#define LOGTAB_MASK2 ((1 << (20 - LOGTAB_SCALE)) - 1) +#define LOGTAB_MASK2_32F ((1 << (23 - LOGTAB_SCALE)) - 1) + +static const double CV_DECL_ALIGNED(16) icvLogTab[] = { + 0.0000000000000000000000000000000000000000, 1.000000000000000000000000000000000000000, + .00389864041565732288852075271279318258166, .9961089494163424124513618677042801556420, + .00778214044205494809292034119607706088573, .9922480620155038759689922480620155038760, + .01165061721997527263705585198749759001657, .9884169884169884169884169884169884169884, + .01550418653596525274396267235488267033361, .9846153846153846153846153846153846153846, + .01934296284313093139406447562578250654042, .9808429118773946360153256704980842911877, + .02316705928153437593630670221500622574241, .9770992366412213740458015267175572519084, + .02697658769820207233514075539915211265906, .9733840304182509505703422053231939163498, + .03077165866675368732785500469617545604706, .9696969696969696969696969696969696969697, + .03455238150665972812758397481047722976656, .9660377358490566037735849056603773584906, + .03831886430213659461285757856785494368522, .9624060150375939849624060150375939849624, + .04207121392068705056921373852674150839447, .9588014981273408239700374531835205992509, + .04580953603129420126371940114040626212953, .9552238805970149253731343283582089552239, + .04953393512227662748292900118940451648088, .9516728624535315985130111524163568773234, + .05324451451881227759255210685296333394944, .9481481481481481481481481481481481481481, + .05694137640013842427411105973078520037234, .9446494464944649446494464944649446494465, + .06062462181643483993820353816772694699466, .9411764705882352941176470588235294117647, + .06429435070539725460836422143984236754475, .9377289377289377289377289377289377289377, + .06795066190850773679699159401934593915938, .9343065693430656934306569343065693430657, + .07159365318700880442825962290953611955044, .9309090909090909090909090909090909090909, + .07522342123758751775142172846244648098944, .9275362318840579710144927536231884057971, + .07884006170777602129362549021607264876369, .9241877256317689530685920577617328519856, + .08244366921107458556772229485432035289706, .9208633093525179856115107913669064748201, + .08603433734180314373940490213499288074675, .9175627240143369175627240143369175627240, + .08961215868968712416897659522874164395031, .9142857142857142857142857142857142857143, + .09317722485418328259854092721070628613231, .9110320284697508896797153024911032028470, + .09672962645855109897752299730200320482256, .9078014184397163120567375886524822695035, + .10026945316367513738597949668474029749630, .9045936395759717314487632508833922261484, + .10379679368164355934833764649738441221420, .9014084507042253521126760563380281690141, + .10731173578908805021914218968959175981580, .8982456140350877192982456140350877192982, + .11081436634029011301105782649756292812530, .8951048951048951048951048951048951048951, + .11430477128005862852422325204315711744130, .8919860627177700348432055749128919860627, + .11778303565638344185817487641543266363440, .8888888888888888888888888888888888888889, + .12124924363286967987640707633545389398930, .8858131487889273356401384083044982698962, + .12470347850095722663787967121606925502420, .8827586206896551724137931034482758620690, + .12814582269193003360996385708858724683530, .8797250859106529209621993127147766323024, + .13157635778871926146571524895989568904040, .8767123287671232876712328767123287671233, + .13499516453750481925766280255629681050780, .8737201365187713310580204778156996587031, + .13840232285911913123754857224412262439730, .8707482993197278911564625850340136054422, + .14179791186025733629172407290752744302150, .8677966101694915254237288135593220338983, + .14518200984449788903951628071808954700830, .8648648648648648648648648648648648648649, + .14855469432313711530824207329715136438610, .8619528619528619528619528619528619528620, + .15191604202584196858794030049466527998450, .8590604026845637583892617449664429530201, + .15526612891112392955683674244937719777230, .8561872909698996655518394648829431438127, + .15860503017663857283636730244325008243330, .8533333333333333333333333333333333333333, + .16193282026931324346641360989451641216880, .8504983388704318936877076411960132890365, + .16524957289530714521497145597095368430010, .8476821192052980132450331125827814569536, + .16855536102980664403538924034364754334090, .8448844884488448844884488448844884488449, + .17185025692665920060697715143760433420540, .8421052631578947368421052631578947368421, + .17513433212784912385018287750426679849630, .8393442622950819672131147540983606557377, + .17840765747281828179637841458315961062910, .8366013071895424836601307189542483660131, + .18167030310763465639212199675966985523700, .8338762214983713355048859934853420195440, + .18492233849401198964024217730184318497780, .8311688311688311688311688311688311688312, + .18816383241818296356839823602058459073300, .8284789644012944983818770226537216828479, + .19139485299962943898322009772527962923050, .8258064516129032258064516129032258064516, + .19461546769967164038916962454095482826240, .8231511254019292604501607717041800643087, + .19782574332991986754137769821682013571260, .8205128205128205128205128205128205128205, + .20102574606059073203390141770796617493040, .8178913738019169329073482428115015974441, + .20421554142869088876999228432396193966280, .8152866242038216560509554140127388535032, + .20739519434607056602715147164417430758480, .8126984126984126984126984126984126984127, + .21056476910734961416338251183333341032260, .8101265822784810126582278481012658227848, + .21372432939771812687723695489694364368910, .8075709779179810725552050473186119873817, + .21687393830061435506806333251006435602900, .8050314465408805031446540880503144654088, + .22001365830528207823135744547471404075630, .8025078369905956112852664576802507836991, + .22314355131420973710199007200571941211830, .8000000000000000000000000000000000000000, + .22626367865045338145790765338460914790630, .7975077881619937694704049844236760124611, + .22937410106484582006380890106811420992010, .7950310559006211180124223602484472049689, + .23247487874309405442296849741978803649550, .7925696594427244582043343653250773993808, + .23556607131276688371634975283086532726890, .7901234567901234567901234567901234567901, + .23864773785017498464178231643018079921600, .7876923076923076923076923076923076923077, + .24171993688714515924331749374687206000090, .7852760736196319018404907975460122699387, + .24478272641769091566565919038112042471760, .7828746177370030581039755351681957186544, + .24783616390458124145723672882013488560910, .7804878048780487804878048780487804878049, + .25088030628580937353433455427875742316250, .7781155015197568389057750759878419452888, + .25391520998096339667426946107298135757450, .7757575757575757575757575757575757575758, + .25694093089750041913887912414793390780680, .7734138972809667673716012084592145015106, + .25995752443692604627401010475296061486000, .7710843373493975903614457831325301204819, + .26296504550088134477547896494797896593800, .7687687687687687687687687687687687687688, + .26596354849713793599974565040611196309330, .7664670658682634730538922155688622754491, + .26895308734550393836570947314612567424780, .7641791044776119402985074626865671641791, + .27193371548364175804834985683555714786050, .7619047619047619047619047619047619047619, + .27490548587279922676529508862586226314300, .7596439169139465875370919881305637982196, + .27786845100345625159121709657483734190480, .7573964497041420118343195266272189349112, + .28082266290088775395616949026589281857030, .7551622418879056047197640117994100294985, + .28376817313064456316240580235898960381750, .7529411764705882352941176470588235294118, + .28670503280395426282112225635501090437180, .7507331378299120234604105571847507331378, + .28963329258304265634293983566749375313530, .7485380116959064327485380116959064327485, + .29255300268637740579436012922087684273730, .7463556851311953352769679300291545189504, + .29546421289383584252163927885703742504130, .7441860465116279069767441860465116279070, + .29836697255179722709783618483925238251680, .7420289855072463768115942028985507246377, + .30126133057816173455023545102449133992200, .7398843930635838150289017341040462427746, + .30414733546729666446850615102448500692850, .7377521613832853025936599423631123919308, + .30702503529491181888388950937951449304830, .7356321839080459770114942528735632183908, + .30989447772286465854207904158101882785550, .7335243553008595988538681948424068767908, + .31275571000389684739317885942000430077330, .7314285714285714285714285714285714285714, + .31560877898630329552176476681779604405180, .7293447293447293447293447293447293447293, + .31845373111853458869546784626436419785030, .7272727272727272727272727272727272727273, + .32129061245373424782201254856772720813750, .7252124645892351274787535410764872521246, + .32411946865421192853773391107097268104550, .7231638418079096045197740112994350282486, + .32694034499585328257253991068864706903700, .7211267605633802816901408450704225352113, + .32975328637246797969240219572384376078850, .7191011235955056179775280898876404494382, + .33255833730007655635318997155991382896900, .7170868347338935574229691876750700280112, + .33535554192113781191153520921943709254280, .7150837988826815642458100558659217877095, + .33814494400871636381467055798566434532400, .7130919220055710306406685236768802228412, + .34092658697059319283795275623560883104800, .7111111111111111111111111111111111111111, + .34370051385331840121395430287520866841080, .7091412742382271468144044321329639889197, + .34646676734620857063262633346312213689100, .7071823204419889502762430939226519337017, + .34922538978528827602332285096053965389730, .7052341597796143250688705234159779614325, + .35197642315717814209818925519357435405250, .7032967032967032967032967032967032967033, + .35471990910292899856770532096561510115850, .7013698630136986301369863013698630136986, + .35745588892180374385176833129662554711100, .6994535519125683060109289617486338797814, + .36018440357500774995358483465679455548530, .6975476839237057220708446866485013623978, + .36290549368936841911903457003063522279280, .6956521739130434782608695652173913043478, + .36561919956096466943762379742111079394830, .6937669376693766937669376693766937669377, + .36832556115870762614150635272380895912650, .6918918918918918918918918918918918918919, + .37102461812787262962487488948681857436900, .6900269541778975741239892183288409703504, + .37371640979358405898480555151763837784530, .6881720430107526881720430107526881720430, + .37640097516425302659470730759494472295050, .6863270777479892761394101876675603217158, + .37907835293496944251145919224654790014030, .6844919786096256684491978609625668449198, + .38174858149084833769393299007788300514230, .6826666666666666666666666666666666666667, + .38441169891033200034513583887019194662580, .6808510638297872340425531914893617021277, + .38706774296844825844488013899535872042180, .6790450928381962864721485411140583554377, + .38971675114002518602873692543653305619950, .6772486772486772486772486772486772486772, + .39235876060286384303665840889152605086580, .6754617414248021108179419525065963060686, + .39499380824086893770896722344332374632350, .6736842105263157894736842105263157894737, + .39762193064713846624158577469643205404280, .6719160104986876640419947506561679790026, + .40024316412701266276741307592601515352730, .6701570680628272251308900523560209424084, + .40285754470108348090917615991202183067800, .6684073107049608355091383812010443864230, + .40546510810816432934799991016916465014230, .6666666666666666666666666666666666666667, + .40806588980822172674223224930756259709600, .6649350649350649350649350649350649350649, + .41065992498526837639616360320360399782650, .6632124352331606217616580310880829015544, + .41324724855021932601317757871584035456180, .6614987080103359173126614987080103359173, + .41582789514371093497757669865677598863850, .6597938144329896907216494845360824742268, + .41840189913888381489925905043492093682300, .6580976863753213367609254498714652956298, + .42096929464412963239894338585145305842150, .6564102564102564102564102564102564102564, + .42353011550580327293502591601281892508280, .6547314578005115089514066496163682864450, + .42608439531090003260516141381231136620050, .6530612244897959183673469387755102040816, + .42863216738969872610098832410585600882780, .6513994910941475826972010178117048346056, + .43117346481837132143866142541810404509300, .6497461928934010152284263959390862944162, + .43370832042155937902094819946796633303180, .6481012658227848101265822784810126582278, + .43623676677491801667585491486534010618930, .6464646464646464646464646464646464646465, + .43875883620762790027214350629947148263450, .6448362720403022670025188916876574307305, + .44127456080487520440058801796112675219780, .6432160804020100502512562814070351758794, + .44378397241030093089975139264424797147500, .6416040100250626566416040100250626566416, + .44628710262841947420398014401143882423650, .6400000000000000000000000000000000000000, + .44878398282700665555822183705458883196130, .6384039900249376558603491271820448877805, + .45127464413945855836729492693848442286250, .6368159203980099502487562189054726368159, + .45375911746712049854579618113348260521900, .6352357320099255583126550868486352357320, + .45623743348158757315857769754074979573500, .6336633663366336633663366336633663366337, + .45870962262697662081833982483658473938700, .6320987654320987654320987654320987654321, + .46117571512217014895185229761409573256980, .6305418719211822660098522167487684729064, + .46363574096303250549055974261136725544930, .6289926289926289926289926289926289926290, + .46608972992459918316399125615134835243230, .6274509803921568627450980392156862745098, + .46853771156323925639597405279346276074650, .6259168704156479217603911980440097799511, + .47097971521879100631480241645476780831830, .6243902439024390243902439024390243902439, + .47341577001667212165614273544633761048330, .6228710462287104622871046228710462287105, + .47584590486996386493601107758877333253630, .6213592233009708737864077669902912621359, + .47827014848147025860569669930555392056700, .6198547215496368038740920096852300242131, + .48068852934575190261057286988943815231330, .6183574879227053140096618357487922705314, + .48310107575113581113157579238759353756900, .6168674698795180722891566265060240963855, + .48550781578170076890899053978500887751580, .6153846153846153846153846153846153846154, + .48790877731923892879351001283794175833480, .6139088729016786570743405275779376498801, + .49030398804519381705802061333088204264650, .6124401913875598086124401913875598086124, + .49269347544257524607047571407747454941280, .6109785202863961813842482100238663484487, + .49507726679785146739476431321236304938800, .6095238095238095238095238095238095238095, + .49745538920281889838648226032091770321130, .6080760095011876484560570071258907363420, + .49982786955644931126130359189119189977650, .6066350710900473933649289099526066350711, + .50219473456671548383667413872899487614650, .6052009456264775413711583924349881796690, + .50455601075239520092452494282042607665050, .6037735849056603773584905660377358490566, + .50691172444485432801997148999362252652650, .6023529411764705882352941176470588235294, + .50926190178980790257412536448100581765150, .6009389671361502347417840375586854460094, + .51160656874906207391973111953120678663250, .5995316159250585480093676814988290398126, + .51394575110223428282552049495279788970950, .5981308411214953271028037383177570093458, + .51627947444845445623684554448118433356300, .5967365967365967365967365967365967365967, + .51860776420804555186805373523384332656850, .5953488372093023255813953488372093023256, + .52093064562418522900344441950437612831600, .5939675174013921113689095127610208816705, + .52324814376454775732838697877014055848100, .5925925925925925925925925925925925925926, + .52556028352292727401362526507000438869000, .5912240184757505773672055427251732101617, + .52786708962084227803046587723656557500350, .5898617511520737327188940092165898617512, + .53016858660912158374145519701414741575700, .5885057471264367816091954022988505747126, + .53246479886947173376654518506256863474850, .5871559633027522935779816513761467889908, + .53475575061602764748158733709715306758900, .5858123569794050343249427917620137299771, + .53704146589688361856929077475797384977350, .5844748858447488584474885844748858447489, + .53932196859560876944783558428753167390800, .5831435079726651480637813211845102505695, + .54159728243274429804188230264117009937750, .5818181818181818181818181818181818181818, + .54386743096728351609669971367111429572100, .5804988662131519274376417233560090702948, + .54613243759813556721383065450936555862450, .5791855203619909502262443438914027149321, + .54839232556557315767520321969641372561450, .5778781038374717832957110609480812641084, + .55064711795266219063194057525834068655950, .5765765765765765765765765765765765765766, + .55289683768667763352766542084282264113450, .5752808988764044943820224719101123595506, + .55514150754050151093110798683483153581600, .5739910313901345291479820627802690582960, + .55738115013400635344709144192165695130850, .5727069351230425055928411633109619686801, + .55961578793542265941596269840374588966350, .5714285714285714285714285714285714285714, + .56184544326269181269140062795486301183700, .5701559020044543429844097995545657015590, + .56407013828480290218436721261241473257550, .5688888888888888888888888888888888888889, + .56628989502311577464155334382667206227800, .5676274944567627494456762749445676274945, + .56850473535266865532378233183408156037350, .5663716814159292035398230088495575221239, + .57071468100347144680739575051120482385150, .5651214128035320088300220750551876379691, + .57291975356178548306473885531886480748650, .5638766519823788546255506607929515418502, + .57511997447138785144460371157038025558000, .5626373626373626373626373626373626373626, + .57731536503482350219940144597785547375700, .5614035087719298245614035087719298245614, + .57950594641464214795689713355386629700650, .5601750547045951859956236323851203501094, + .58169173963462239562716149521293118596100, .5589519650655021834061135371179039301310, + .58387276558098266665552955601015128195300, .5577342047930283224400871459694989106754, + .58604904500357812846544902640744112432000, .5565217391304347826086956521739130434783, + .58822059851708596855957011939608491957200, .5553145336225596529284164859002169197397, + .59038744660217634674381770309992134571100, .5541125541125541125541125541125541125541, + .59254960960667157898740242671919986605650, .5529157667386609071274298056155507559395, + .59470710774669277576265358220553025603300, .5517241379310344827586206896551724137931, + .59685996110779382384237123915227130055450, .5505376344086021505376344086021505376344, + .59900818964608337768851242799428291618800, .5493562231759656652360515021459227467811, + .60115181318933474940990890900138765573500, .5481798715203426124197002141327623126338, + .60329085143808425240052883964381180703650, .5470085470085470085470085470085470085470, + .60542532396671688843525771517306566238400, .5458422174840085287846481876332622601279, + .60755525022454170969155029524699784815300, .5446808510638297872340425531914893617021, + .60968064953685519036241657886421307921400, .5435244161358811040339702760084925690021, + .61180154110599282990534675263916142284850, .5423728813559322033898305084745762711864, + .61391794401237043121710712512140162289150, .5412262156448202959830866807610993657505, + .61602987721551394351138242200249806046500, .5400843881856540084388185654008438818565, + .61813735955507864705538167982012964785100, .5389473684210526315789473684210526315789, + .62024040975185745772080281312810257077200, .5378151260504201680672268907563025210084, + .62233904640877868441606324267922900617100, .5366876310272536687631027253668763102725, + .62443328801189346144440150965237990021700, .5355648535564853556485355648535564853556, + .62652315293135274476554741340805776417250, .5344467640918580375782881002087682672234, + .62860865942237409420556559780379757285100, .5333333333333333333333333333333333333333, + .63068982562619868570408243613201193511500, .5322245322245322245322245322245322245322, + .63276666957103777644277897707070223987100, .5311203319502074688796680497925311203320, + .63483920917301017716738442686619237065300, .5300207039337474120082815734989648033126, + .63690746223706917739093569252872839570050, .5289256198347107438016528925619834710744, + .63897144645792069983514238629140891134750, .5278350515463917525773195876288659793814, + .64103117942093124081992527862894348800200, .5267489711934156378600823045267489711934, + .64308667860302726193566513757104985415950, .5256673511293634496919917864476386036961, + .64513796137358470073053240412264131009600, .5245901639344262295081967213114754098361, + .64718504499530948859131740391603671014300, .5235173824130879345603271983640081799591, + .64922794662510974195157587018911726772800, .5224489795918367346938775510204081632653, + .65126668331495807251485530287027359008800, .5213849287169042769857433808553971486762, + .65330127201274557080523663898929953575150, .5203252032520325203252032520325203252033, + .65533172956312757406749369692988693714150, .5192697768762677484787018255578093306288, + .65735807270835999727154330685152672231200, .5182186234817813765182186234817813765182, + .65938031808912778153342060249997302889800, .5171717171717171717171717171717171717172, + .66139848224536490484126716182800009846700, .5161290322580645161290322580645161290323, + .66341258161706617713093692145776003599150, .5150905432595573440643863179074446680080, + .66542263254509037562201001492212526500250, .5140562248995983935742971887550200803213, + .66742865127195616370414654738851822912700, .5130260521042084168336673346693386773547, + .66943065394262923906154583164607174694550, .5120000000000000000000000000000000000000, + .67142865660530226534774556057527661323550, .5109780439121756487025948103792415169661, + .67342267521216669923234121597488410770900, .5099601593625498007968127490039840637450, + .67541272562017662384192817626171745359900, .5089463220675944333996023856858846918489, + .67739882359180603188519853574689477682100, .5079365079365079365079365079365079365079, + .67938098479579733801614338517538271844400, .5069306930693069306930693069306930693069, + .68135922480790300781450241629499942064300, .5059288537549407114624505928853754940711, + .68333355911162063645036823800182901322850, .5049309664694280078895463510848126232742, + .68530400309891936760919861626462079584600, .5039370078740157480314960629921259842520, + .68727057207096020619019327568821609020250, .5029469548133595284872298624754420432220, + .68923328123880889251040571252815425395950, .5019607843137254901960784313725490196078, + .69314718055994530941723212145818, 5.0e-01, +}; + + + +#define LOGTAB_TRANSLATE(x,h) (((x) - 1.)*icvLogTab[(h)+1]) +static const double ln_2 = 0.69314718055994530941723212145818; + +void log( const float *_x, float *y, int n ) +{ + static const float shift[] = { 0, -1.f/512 }; + static const float + A0 = 0.3333333333333333333333333f, + A1 = -0.5f, + A2 = 1.f; + +#undef LOGPOLY +#define LOGPOLY(x) (((A0*(x) + A1)*(x) + A2)*(x)) + + int i = 0; + Cv32suf buf[4]; + const int* x = (const int*)_x; + +#if CV_SSE2 + static const __m128d ln2_2 = _mm_set1_pd(ln_2); + static const __m128 _1_4 = _mm_set1_ps(1.f); + static const __m128 shift4 = _mm_set1_ps(-1.f/512); + + static const __m128 mA0 = _mm_set1_ps(A0); + static const __m128 mA1 = _mm_set1_ps(A1); + static const __m128 mA2 = _mm_set1_ps(A2); + + int CV_DECL_ALIGNED(16) idx[4]; + + for( ; i <= n - 4; i += 4 ) + { + __m128i h0 = _mm_loadu_si128((const __m128i*)(x + i)); + __m128i yi0 = _mm_sub_epi32(_mm_and_si128(_mm_srli_epi32(h0, 23), _mm_set1_epi32(255)), _mm_set1_epi32(127)); + __m128d yd0 = _mm_mul_pd(_mm_cvtepi32_pd(yi0), ln2_2); + __m128d yd1 = _mm_mul_pd(_mm_cvtepi32_pd(_mm_unpackhi_epi64(yi0,yi0)), ln2_2); + + __m128i xi0 = _mm_or_si128(_mm_and_si128(h0, _mm_set1_epi32(LOGTAB_MASK2_32F)), _mm_set1_epi32(127 << 23)); + + h0 = _mm_and_si128(_mm_srli_epi32(h0, 23 - LOGTAB_SCALE - 1), _mm_set1_epi32(LOGTAB_MASK*2)); + _mm_store_si128((__m128i*)idx, h0); + h0 = _mm_cmpeq_epi32(h0, _mm_set1_epi32(510)); + + __m128d t0, t1, t2, t3, t4; + t0 = _mm_load_pd(icvLogTab + idx[0]); + t2 = _mm_load_pd(icvLogTab + idx[1]); + t1 = _mm_unpackhi_pd(t0, t2); + t0 = _mm_unpacklo_pd(t0, t2); + t2 = _mm_load_pd(icvLogTab + idx[2]); + t4 = _mm_load_pd(icvLogTab + idx[3]); + t3 = _mm_unpackhi_pd(t2, t4); + t2 = _mm_unpacklo_pd(t2, t4); + + yd0 = _mm_add_pd(yd0, t0); + yd1 = _mm_add_pd(yd1, t2); + + __m128 yf0 = _mm_movelh_ps(_mm_cvtpd_ps(yd0), _mm_cvtpd_ps(yd1)); + + __m128 xf0 = _mm_sub_ps(_mm_castsi128_ps(xi0), _1_4); + xf0 = _mm_mul_ps(xf0, _mm_movelh_ps(_mm_cvtpd_ps(t1), _mm_cvtpd_ps(t3))); + xf0 = _mm_add_ps(xf0, _mm_and_ps(_mm_castsi128_ps(h0), shift4)); + + __m128 zf0 = _mm_mul_ps(xf0, mA0); + zf0 = _mm_mul_ps(_mm_add_ps(zf0, mA1), xf0); + zf0 = _mm_mul_ps(_mm_add_ps(zf0, mA2), xf0); + yf0 = _mm_add_ps(yf0, zf0); + + _mm_storeu_ps(y + i, yf0); + } +#endif + for( ; i <= n - 4; i += 4 ) + { + double x0, x1, x2, x3; + double y0, y1, y2, y3; + int h0, h1, h2, h3; + + h0 = x[i]; + h1 = x[i+1]; + buf[0].i = (h0 & LOGTAB_MASK2_32F) | (127 << 23); + buf[1].i = (h1 & LOGTAB_MASK2_32F) | (127 << 23); + + y0 = (((h0 >> 23) & 0xff) - 127) * ln_2; + y1 = (((h1 >> 23) & 0xff) - 127) * ln_2; + + h0 = (h0 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; + h1 = (h1 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; + + y0 += icvLogTab[h0]; + y1 += icvLogTab[h1]; + + h2 = x[i+2]; + h3 = x[i+3]; + + x0 = LOGTAB_TRANSLATE( buf[0].f, h0 ); + x1 = LOGTAB_TRANSLATE( buf[1].f, h1 ); + + buf[2].i = (h2 & LOGTAB_MASK2_32F) | (127 << 23); + buf[3].i = (h3 & LOGTAB_MASK2_32F) | (127 << 23); + + y2 = (((h2 >> 23) & 0xff) - 127) * ln_2; + y3 = (((h3 >> 23) & 0xff) - 127) * ln_2; + + h2 = (h2 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; + h3 = (h3 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; + + y2 += icvLogTab[h2]; + y3 += icvLogTab[h3]; + + x2 = LOGTAB_TRANSLATE( buf[2].f, h2 ); + x3 = LOGTAB_TRANSLATE( buf[3].f, h3 ); + + x0 += shift[h0 == 510]; + x1 += shift[h1 == 510]; + y0 += LOGPOLY( x0 ); + y1 += LOGPOLY( x1 ); + + y[i] = (float) y0; + y[i + 1] = (float) y1; + + x2 += shift[h2 == 510]; + x3 += shift[h3 == 510]; + y2 += LOGPOLY( x2 ); + y3 += LOGPOLY( x3 ); + + y[i + 2] = (float) y2; + y[i + 3] = (float) y3; + } + + for( ; i < n; i++ ) + { + int h0 = x[i]; + double y0; + float x0; + + y0 = (((h0 >> 23) & 0xff) - 127) * ln_2; + + buf[0].i = (h0 & LOGTAB_MASK2_32F) | (127 << 23); + h0 = (h0 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; + + y0 += icvLogTab[h0]; + x0 = (float)LOGTAB_TRANSLATE( buf[0].f, h0 ); + x0 += shift[h0 == 510]; + y0 += LOGPOLY( x0 ); + + y[i] = (float)y0; + } +} + +void log( const double *x, double *y, int n ) +{ + static const double shift[] = { 0, -1./512 }; + static const double + A7 = 1.0, + A6 = -0.5, + A5 = 0.333333333333333314829616256247390992939472198486328125, + A4 = -0.25, + A3 = 0.2, + A2 = -0.1666666666666666574148081281236954964697360992431640625, + A1 = 0.1428571428571428769682682968777953647077083587646484375, + A0 = -0.125; + +#undef LOGPOLY +#define LOGPOLY(x,k) ((x)+=shift[k], xq = (x)*(x),\ +(((A0*xq + A2)*xq + A4)*xq + A6)*xq + \ +(((A1*xq + A3)*xq + A5)*xq + A7)*(x)) + + int i = 0; + DBLINT buf[4]; + DBLINT *X = (DBLINT *) x; + +#if CV_SSE2 + static const __m128d ln2_2 = _mm_set1_pd(ln_2); + static const __m128d _1_2 = _mm_set1_pd(1.); + static const __m128d shift2 = _mm_set1_pd(-1./512); + + static const __m128i log_and_mask2 = _mm_set_epi32(LOGTAB_MASK2, 0xffffffff, LOGTAB_MASK2, 0xffffffff); + static const __m128i log_or_mask2 = _mm_set_epi32(1023 << 20, 0, 1023 << 20, 0); + + static const __m128d mA0 = _mm_set1_pd(A0); + static const __m128d mA1 = _mm_set1_pd(A1); + static const __m128d mA2 = _mm_set1_pd(A2); + static const __m128d mA3 = _mm_set1_pd(A3); + static const __m128d mA4 = _mm_set1_pd(A4); + static const __m128d mA5 = _mm_set1_pd(A5); + static const __m128d mA6 = _mm_set1_pd(A6); + static const __m128d mA7 = _mm_set1_pd(A7); + + int CV_DECL_ALIGNED(16) idx[4]; + + for( ; i <= n - 4; i += 4 ) + { + __m128i h0 = _mm_loadu_si128((const __m128i*)(x + i)); + __m128i h1 = _mm_loadu_si128((const __m128i*)(x + i + 2)); + + __m128d xd0 = _mm_castsi128_pd(_mm_or_si128(_mm_and_si128(h0, log_and_mask2), log_or_mask2)); + __m128d xd1 = _mm_castsi128_pd(_mm_or_si128(_mm_and_si128(h1, log_and_mask2), log_or_mask2)); + + h0 = _mm_unpackhi_epi32(_mm_unpacklo_epi32(h0, h1), _mm_unpackhi_epi32(h0, h1)); + + __m128i yi0 = _mm_sub_epi32(_mm_and_si128(_mm_srli_epi32(h0, 20), + _mm_set1_epi32(2047)), _mm_set1_epi32(1023)); + __m128d yd0 = _mm_mul_pd(_mm_cvtepi32_pd(yi0), ln2_2); + __m128d yd1 = _mm_mul_pd(_mm_cvtepi32_pd(_mm_unpackhi_epi64(yi0, yi0)), ln2_2); + + h0 = _mm_and_si128(_mm_srli_epi32(h0, 20 - LOGTAB_SCALE - 1), _mm_set1_epi32(LOGTAB_MASK * 2)); + _mm_store_si128((__m128i*)idx, h0); + h0 = _mm_cmpeq_epi32(h0, _mm_set1_epi32(510)); + + __m128d t0, t1, t2, t3, t4; + t0 = _mm_load_pd(icvLogTab + idx[0]); + t2 = _mm_load_pd(icvLogTab + idx[1]); + t1 = _mm_unpackhi_pd(t0, t2); + t0 = _mm_unpacklo_pd(t0, t2); + t2 = _mm_load_pd(icvLogTab + idx[2]); + t4 = _mm_load_pd(icvLogTab + idx[3]); + t3 = _mm_unpackhi_pd(t2, t4); + t2 = _mm_unpacklo_pd(t2, t4); + + yd0 = _mm_add_pd(yd0, t0); + yd1 = _mm_add_pd(yd1, t2); + + xd0 = _mm_mul_pd(_mm_sub_pd(xd0, _1_2), t1); + xd1 = _mm_mul_pd(_mm_sub_pd(xd1, _1_2), t3); + + xd0 = _mm_add_pd(xd0, _mm_and_pd(_mm_castsi128_pd(_mm_unpacklo_epi32(h0, h0)), shift2)); + xd1 = _mm_add_pd(xd1, _mm_and_pd(_mm_castsi128_pd(_mm_unpackhi_epi32(h0, h0)), shift2)); + + __m128d zd0 = _mm_mul_pd(xd0, mA0); + __m128d zd1 = _mm_mul_pd(xd1, mA0); + zd0 = _mm_mul_pd(_mm_add_pd(zd0, mA1), xd0); + zd1 = _mm_mul_pd(_mm_add_pd(zd1, mA1), xd1); + zd0 = _mm_mul_pd(_mm_add_pd(zd0, mA2), xd0); + zd1 = _mm_mul_pd(_mm_add_pd(zd1, mA2), xd1); + zd0 = _mm_mul_pd(_mm_add_pd(zd0, mA3), xd0); + zd1 = _mm_mul_pd(_mm_add_pd(zd1, mA3), xd1); + zd0 = _mm_mul_pd(_mm_add_pd(zd0, mA4), xd0); + zd1 = _mm_mul_pd(_mm_add_pd(zd1, mA4), xd1); + zd0 = _mm_mul_pd(_mm_add_pd(zd0, mA5), xd0); + zd1 = _mm_mul_pd(_mm_add_pd(zd1, mA5), xd1); + zd0 = _mm_mul_pd(_mm_add_pd(zd0, mA6), xd0); + zd1 = _mm_mul_pd(_mm_add_pd(zd1, mA6), xd1); + zd0 = _mm_mul_pd(_mm_add_pd(zd0, mA7), xd0); + zd1 = _mm_mul_pd(_mm_add_pd(zd1, mA7), xd1); + + yd0 = _mm_add_pd(yd0, zd0); + yd1 = _mm_add_pd(yd1, zd1); + + _mm_storeu_pd(y + i, yd0); + _mm_storeu_pd(y + i + 2, yd1); + } +#endif + for( ; i <= n - 4; i += 4 ) + { + double xq; + double x0, x1, x2, x3; + double y0, y1, y2, y3; + int h0, h1, h2, h3; + + h0 = X[i].i.lo; + h1 = X[i + 1].i.lo; + buf[0].i.lo = h0; + buf[1].i.lo = h1; + + h0 = X[i].i.hi; + h1 = X[i + 1].i.hi; + buf[0].i.hi = (h0 & LOGTAB_MASK2) | (1023 << 20); + buf[1].i.hi = (h1 & LOGTAB_MASK2) | (1023 << 20); + + y0 = (((h0 >> 20) & 0x7ff) - 1023) * ln_2; + y1 = (((h1 >> 20) & 0x7ff) - 1023) * ln_2; + + h2 = X[i + 2].i.lo; + h3 = X[i + 3].i.lo; + buf[2].i.lo = h2; + buf[3].i.lo = h3; + + h0 = (h0 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; + h1 = (h1 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; + + y0 += icvLogTab[h0]; + y1 += icvLogTab[h1]; + + h2 = X[i + 2].i.hi; + h3 = X[i + 3].i.hi; + + x0 = LOGTAB_TRANSLATE( buf[0].d, h0 ); + x1 = LOGTAB_TRANSLATE( buf[1].d, h1 ); + + buf[2].i.hi = (h2 & LOGTAB_MASK2) | (1023 << 20); + buf[3].i.hi = (h3 & LOGTAB_MASK2) | (1023 << 20); + + y2 = (((h2 >> 20) & 0x7ff) - 1023) * ln_2; + y3 = (((h3 >> 20) & 0x7ff) - 1023) * ln_2; + + h2 = (h2 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; + h3 = (h3 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; + + y2 += icvLogTab[h2]; + y3 += icvLogTab[h3]; + + x2 = LOGTAB_TRANSLATE( buf[2].d, h2 ); + x3 = LOGTAB_TRANSLATE( buf[3].d, h3 ); + + y0 += LOGPOLY( x0, h0 == 510 ); + y1 += LOGPOLY( x1, h1 == 510 ); + + y[i] = y0; + y[i + 1] = y1; + + y2 += LOGPOLY( x2, h2 == 510 ); + y3 += LOGPOLY( x3, h3 == 510 ); + + y[i + 2] = y2; + y[i + 3] = y3; + } + + for( ; i < n; i++ ) + { + int h0 = X[i].i.hi; + double xq; + double x0, y0 = (((h0 >> 20) & 0x7ff) - 1023) * ln_2; + + buf[0].i.hi = (h0 & LOGTAB_MASK2) | (1023 << 20); + buf[0].i.lo = X[i].i.lo; + h0 = (h0 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2; + + y0 += icvLogTab[h0]; + x0 = LOGTAB_TRANSLATE( buf[0].d, h0 ); + y0 += LOGPOLY( x0, h0 == 510 ); + y[i] = y0; + } +} + }} diff --git a/modules/hal/src/matrix.cpp b/modules/hal/src/matrix.cpp index a3f69facca..9506aaf478 100644 --- a/modules/hal/src/matrix.cpp +++ b/modules/hal/src/matrix.cpp @@ -44,4 +44,165 @@ namespace cv { namespace hal { +/****************************************************************************************\ +* LU & Cholesky implementation for small matrices * +\****************************************************************************************/ + +template static inline int +LUImpl(_Tp* A, size_t astep, int m, _Tp* b, size_t bstep, int n) +{ + int i, j, k, p = 1; + astep /= sizeof(A[0]); + bstep /= sizeof(b[0]); + + for( i = 0; i < m; i++ ) + { + k = i; + + for( j = i+1; j < m; j++ ) + if( std::abs(A[j*astep + i]) > std::abs(A[k*astep + i]) ) + k = j; + + if( std::abs(A[k*astep + i]) < std::numeric_limits<_Tp>::epsilon() ) + return 0; + + if( k != i ) + { + for( j = i; j < m; j++ ) + std::swap(A[i*astep + j], A[k*astep + j]); + if( b ) + for( j = 0; j < n; j++ ) + std::swap(b[i*bstep + j], b[k*bstep + j]); + p = -p; + } + + _Tp d = -1/A[i*astep + i]; + + for( j = i+1; j < m; j++ ) + { + _Tp alpha = A[j*astep + i]*d; + + for( k = i+1; k < m; k++ ) + A[j*astep + k] += alpha*A[i*astep + k]; + + if( b ) + for( k = 0; k < n; k++ ) + b[j*bstep + k] += alpha*b[i*bstep + k]; + } + + A[i*astep + i] = -d; + } + + if( b ) + { + for( i = m-1; i >= 0; i-- ) + for( j = 0; j < n; j++ ) + { + _Tp s = b[i*bstep + j]; + for( k = i+1; k < m; k++ ) + s -= A[i*astep + k]*b[k*bstep + j]; + b[i*bstep + j] = s*A[i*astep + i]; + } + } + + return p; +} + + +int LU(float* A, size_t astep, int m, float* b, size_t bstep, int n) +{ + return LUImpl(A, astep, m, b, bstep, n); +} + + +int LU(double* A, size_t astep, int m, double* b, size_t bstep, int n) +{ + return LUImpl(A, astep, m, b, bstep, n); +} + + +template static inline bool +CholImpl(_Tp* A, size_t astep, int m, _Tp* b, size_t bstep, int n) +{ + _Tp* L = A; + int i, j, k; + double s; + astep /= sizeof(A[0]); + bstep /= sizeof(b[0]); + + for( i = 0; i < m; i++ ) + { + for( j = 0; j < i; j++ ) + { + s = A[i*astep + j]; + for( k = 0; k < j; k++ ) + s -= L[i*astep + k]*L[j*astep + k]; + L[i*astep + j] = (_Tp)(s*L[j*astep + j]); + } + s = A[i*astep + i]; + for( k = 0; k < j; k++ ) + { + double t = L[i*astep + k]; + s -= t*t; + } + if( s < std::numeric_limits<_Tp>::epsilon() ) + return false; + L[i*astep + i] = (_Tp)(1./std::sqrt(s)); + } + + if( !b ) + return true; + + // LLt x = b + // 1: L y = b + // 2. Lt x = y + + /* + [ L00 ] y0 b0 + [ L10 L11 ] y1 = b1 + [ L20 L21 L22 ] y2 b2 + [ L30 L31 L32 L33 ] y3 b3 + + [ L00 L10 L20 L30 ] x0 y0 + [ L11 L21 L31 ] x1 = y1 + [ L22 L32 ] x2 y2 + [ L33 ] x3 y3 + */ + + for( i = 0; i < m; i++ ) + { + for( j = 0; j < n; j++ ) + { + s = b[i*bstep + j]; + for( k = 0; k < i; k++ ) + s -= L[i*astep + k]*b[k*bstep + j]; + b[i*bstep + j] = (_Tp)(s*L[i*astep + i]); + } + } + + for( i = m-1; i >= 0; i-- ) + { + for( j = 0; j < n; j++ ) + { + s = b[i*bstep + j]; + for( k = m-1; k > i; k-- ) + s -= L[k*astep + i]*b[k*bstep + j]; + b[i*bstep + j] = (_Tp)(s*L[i*astep + i]); + } + } + + return true; +} + + +bool Cholesky(float* A, size_t astep, int m, float* b, size_t bstep, int n) +{ + return CholImpl(A, astep, m, b, bstep, n); +} + +bool Cholesky(double* A, size_t astep, int m, double* b, size_t bstep, int n) +{ + return CholImpl(A, astep, m, b, bstep, n); +} + }} diff --git a/modules/hal/src/precomp.hpp b/modules/hal/src/precomp.hpp index e6923fb897..95ddac9bc8 100644 --- a/modules/hal/src/precomp.hpp +++ b/modules/hal/src/precomp.hpp @@ -42,3 +42,7 @@ #include "opencv2/hal.hpp" #include "opencv2/hal/intrin.hpp" +#include +#include +#include +#include diff --git a/modules/hal/src/stat.cpp b/modules/hal/src/stat.cpp index bdcf9ed727..ec3b8db5a1 100644 --- a/modules/hal/src/stat.cpp +++ b/modules/hal/src/stat.cpp @@ -80,10 +80,10 @@ static const uchar popCountTable4[] = 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }; -Error::Code normHamming(const uchar* a, int n, int & result) +int normHamming(const uchar* a, int n) { int i = 0; - result = 0; + int result = 0; #if CV_NEON { uint32x4_t bits = vmovq_n_u32(0); @@ -104,13 +104,13 @@ Error::Code normHamming(const uchar* a, int n, int & result) popCountTable[a[i+2]] + popCountTable[a[i+3]]; for( ; i < n; i++ ) result += popCountTable[a[i]]; - return Error::Ok; + return result; } -Error::Code normHamming(const uchar* a, const uchar* b, int n, int & result) +int normHamming(const uchar* a, const uchar* b, int n) { int i = 0; - result = 0; + int result = 0; #if CV_NEON { uint32x4_t bits = vmovq_n_u32(0); @@ -133,44 +133,44 @@ Error::Code normHamming(const uchar* a, const uchar* b, int n, int & result) popCountTable[a[i+2] ^ b[i+2]] + popCountTable[a[i+3] ^ b[i+3]]; for( ; i < n; i++ ) result += popCountTable[a[i] ^ b[i]]; - return Error::Ok; + return result; } -Error::Code normHamming(const uchar* a, int n, int cellSize, int & result) +int normHamming(const uchar* a, int n, int cellSize) { if( cellSize == 1 ) - return normHamming(a, n, result); + return normHamming(a, n); const uchar* tab = 0; if( cellSize == 2 ) tab = popCountTable2; else if( cellSize == 4 ) tab = popCountTable4; else - return Error::Unknown; + return -1; int i = 0; - result = 0; + int result = 0; #if CV_ENABLE_UNROLLED for( ; i <= n - 4; i += 4 ) result += tab[a[i]] + tab[a[i+1]] + tab[a[i+2]] + tab[a[i+3]]; #endif for( ; i < n; i++ ) result += tab[a[i]]; - return Error::Ok; + return result; } -Error::Code normHamming(const uchar* a, const uchar* b, int n, int cellSize, int & result) +int normHamming(const uchar* a, const uchar* b, int n, int cellSize) { if( cellSize == 1 ) - return normHamming(a, b, n, result); + return normHamming(a, b, n); const uchar* tab = 0; if( cellSize == 2 ) tab = popCountTable2; else if( cellSize == 4 ) tab = popCountTable4; else - return Error::Unknown; + return -1; int i = 0; - result = 0; + int result = 0; #if CV_ENABLE_UNROLLED for( ; i <= n - 4; i += 4 ) result += tab[a[i] ^ b[i]] + tab[a[i+1] ^ b[i+1]] + @@ -178,7 +178,129 @@ Error::Code normHamming(const uchar* a, const uchar* b, int n, int cellSize, int #endif for( ; i < n; i++ ) result += tab[a[i] ^ b[i]]; - return Error::Ok; + return result; +} + +float normL2Sqr_(const float* a, const float* b, int n) +{ + int j = 0; float d = 0.f; +#if CV_SSE + float CV_DECL_ALIGNED(16) buf[4]; + __m128 d0 = _mm_setzero_ps(), d1 = _mm_setzero_ps(); + + for( ; j <= n - 8; j += 8 ) + { + __m128 t0 = _mm_sub_ps(_mm_loadu_ps(a + j), _mm_loadu_ps(b + j)); + __m128 t1 = _mm_sub_ps(_mm_loadu_ps(a + j + 4), _mm_loadu_ps(b + j + 4)); + d0 = _mm_add_ps(d0, _mm_mul_ps(t0, t0)); + d1 = _mm_add_ps(d1, _mm_mul_ps(t1, t1)); + } + _mm_store_ps(buf, _mm_add_ps(d0, d1)); + d = buf[0] + buf[1] + buf[2] + buf[3]; +#endif + { + for( ; j <= n - 4; j += 4 ) + { + float t0 = a[j] - b[j], t1 = a[j+1] - b[j+1], t2 = a[j+2] - b[j+2], t3 = a[j+3] - b[j+3]; + d += t0*t0 + t1*t1 + t2*t2 + t3*t3; + } + } + + for( ; j < n; j++ ) + { + float t = a[j] - b[j]; + d += t*t; + } + return d; +} + + +float normL1_(const float* a, const float* b, int n) +{ + int j = 0; float d = 0.f; +#if CV_SSE + float CV_DECL_ALIGNED(16) buf[4]; + static const int CV_DECL_ALIGNED(16) absbuf[4] = {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}; + __m128 d0 = _mm_setzero_ps(), d1 = _mm_setzero_ps(); + __m128 absmask = _mm_load_ps((const float*)absbuf); + + for( ; j <= n - 8; j += 8 ) + { + __m128 t0 = _mm_sub_ps(_mm_loadu_ps(a + j), _mm_loadu_ps(b + j)); + __m128 t1 = _mm_sub_ps(_mm_loadu_ps(a + j + 4), _mm_loadu_ps(b + j + 4)); + d0 = _mm_add_ps(d0, _mm_and_ps(t0, absmask)); + d1 = _mm_add_ps(d1, _mm_and_ps(t1, absmask)); + } + _mm_store_ps(buf, _mm_add_ps(d0, d1)); + d = buf[0] + buf[1] + buf[2] + buf[3]; +#elif CV_NEON + float32x4_t v_sum = vdupq_n_f32(0.0f); + for ( ; j <= n - 4; j += 4) + v_sum = vaddq_f32(v_sum, vabdq_f32(vld1q_f32(a + j), vld1q_f32(b + j))); + + float CV_DECL_ALIGNED(16) buf[4]; + vst1q_f32(buf, v_sum); + d = buf[0] + buf[1] + buf[2] + buf[3]; +#endif + { + for( ; j <= n - 4; j += 4 ) + { + d += std::abs(a[j] - b[j]) + std::abs(a[j+1] - b[j+1]) + + std::abs(a[j+2] - b[j+2]) + std::abs(a[j+3] - b[j+3]); + } + } + + for( ; j < n; j++ ) + d += std::abs(a[j] - b[j]); + return d; +} + +int normL1_(const uchar* a, const uchar* b, int n) +{ + int j = 0, d = 0; +#if CV_SSE + __m128i d0 = _mm_setzero_si128(); + + for( ; j <= n - 16; j += 16 ) + { + __m128i t0 = _mm_loadu_si128((const __m128i*)(a + j)); + __m128i t1 = _mm_loadu_si128((const __m128i*)(b + j)); + + d0 = _mm_add_epi32(d0, _mm_sad_epu8(t0, t1)); + } + + for( ; j <= n - 4; j += 4 ) + { + __m128i t0 = _mm_cvtsi32_si128(*(const int*)(a + j)); + __m128i t1 = _mm_cvtsi32_si128(*(const int*)(b + j)); + + d0 = _mm_add_epi32(d0, _mm_sad_epu8(t0, t1)); + } + d = _mm_cvtsi128_si32(_mm_add_epi32(d0, _mm_unpackhi_epi64(d0, d0))); +#elif CV_NEON + uint32x4_t v_sum = vdupq_n_u32(0.0f); + for ( ; j <= n - 16; j += 16) + { + uint8x16_t v_dst = vabdq_u8(vld1q_u8(a + j), vld1q_u8(b + j)); + uint16x8_t v_low = vmovl_u8(vget_low_u8(v_dst)), v_high = vmovl_u8(vget_high_u8(v_dst)); + v_sum = vaddq_u32(v_sum, vaddl_u16(vget_low_u16(v_low), vget_low_u16(v_high))); + v_sum = vaddq_u32(v_sum, vaddl_u16(vget_high_u16(v_low), vget_high_u16(v_high))); + } + + uint CV_DECL_ALIGNED(16) buf[4]; + vst1q_u32(buf, v_sum); + d = buf[0] + buf[1] + buf[2] + buf[3]; +#endif + { + for( ; j <= n - 4; j += 4 ) + { + d += std::abs(a[j] - b[j]) + std::abs(a[j+1] - b[j+1]) + + std::abs(a[j+2] - b[j+2]) + std::abs(a[j+3] - b[j+3]); + } + } + for( ; j < n; j++ ) + d += std::abs(a[j] - b[j]); + return d; } }} //cv::hal diff --git a/modules/photo/src/arrays.hpp b/modules/photo/src/arrays.hpp index 4aec5f7a1e..cdd59a3286 100644 --- a/modules/photo/src/arrays.hpp +++ b/modules/photo/src/arrays.hpp @@ -44,6 +44,9 @@ #ifndef __OPENCV_DENOISING_ARRAYS_HPP__ #define __OPENCV_DENOISING_ARRAYS_HPP__ +namespace cv +{ + template struct Array2d { @@ -176,4 +179,6 @@ struct Array4d } }; +} + #endif diff --git a/modules/stitching/src/autocalib.cpp b/modules/stitching/src/autocalib.cpp index 56a9df57b8..91244bde15 100644 --- a/modules/stitching/src/autocalib.cpp +++ b/modules/stitching/src/autocalib.cpp @@ -49,7 +49,7 @@ namespace { template static inline bool decomposeCholesky(_Tp* A, size_t astep, int m) { - if (!Cholesky(A, astep, m, 0, 0, 0)) + if (!hal::Cholesky(A, astep, m, 0, 0, 0)) return false; astep /= sizeof(A[0]); for (int i = 0; i < m; ++i) From c7121e877202c44d4def8f9c1d5113c6ee646b39 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Thu, 16 Apr 2015 23:42:00 +0300 Subject: [PATCH 056/109] fixed compile warnings --- modules/hal/include/opencv2/hal/defs.h | 2 ++ modules/hal/include/opencv2/hal/intrin.hpp | 27 ++++++++++++++-------- modules/hal/src/mathfuncs.cpp | 4 ++-- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/modules/hal/include/opencv2/hal/defs.h b/modules/hal/include/opencv2/hal/defs.h index c011fe617e..18c1adc6ce 100644 --- a/modules/hal/include/opencv2/hal/defs.h +++ b/modules/hal/include/opencv2/hal/defs.h @@ -666,6 +666,8 @@ template<> inline unsigned saturate_cast(double v) { return cvRound(v) //! @endcond +//! @} core_utils + } #endif // __cplusplus diff --git a/modules/hal/include/opencv2/hal/intrin.hpp b/modules/hal/include/opencv2/hal/intrin.hpp index c3c47e0594..bfd41ad0d1 100644 --- a/modules/hal/include/opencv2/hal/intrin.hpp +++ b/modules/hal/include/opencv2/hal/intrin.hpp @@ -350,7 +350,6 @@ OPENCV_HAL_IMPL_BIT_OP(^) template inline v_reg<_Tp, n> operator ~ (const v_reg<_Tp, n>& a) { v_reg<_Tp, n> c; - typedef typename TypeTraits<_Tp>::int_type itype; for( int i = 0; i < n; i++ ) c.s[i] = TypeTraits<_Tp>::reinterpret_from_int(~TypeTraits<_Tp>::reinterpret_int(a.s[i])); return c; @@ -1426,13 +1425,13 @@ OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_float64x2, v_max, _mm_max_pd) inline v_int8x16 v_min(const v_int8x16& a, const v_int8x16& b) { - __m128i delta = _mm_set1_epi8((char)0x80); + __m128i delta = _mm_set1_epi8((char)-128); return v_int8x16(_mm_xor_si128(delta, _mm_min_epu8(_mm_xor_si128(a.val, delta), _mm_xor_si128(b.val, delta)))); } inline v_int8x16 v_max(const v_int8x16& a, const v_int8x16& b) { - __m128i delta = _mm_set1_epi8((char)0x80); + __m128i delta = _mm_set1_epi8((char)-128); return v_int8x16(_mm_xor_si128(delta, _mm_max_epu8(_mm_xor_si128(a.val, delta), _mm_xor_si128(b.val, delta)))); } @@ -1523,8 +1522,8 @@ inline _Tpsvec operator >= (const _Tpsvec& a, const _Tpsvec& b) \ return _Tpsvec(_mm_xor_si128(_mm_cmpgt_##suffix(b.val, a.val), not_mask)); \ } -OPENCV_HAL_IMPL_SSE_INT_CMP_OP(v_uint8x16, v_int8x16, epi8, (char)0x80) -OPENCV_HAL_IMPL_SSE_INT_CMP_OP(v_uint16x8, v_int16x8, epi16, (short)0x8000) +OPENCV_HAL_IMPL_SSE_INT_CMP_OP(v_uint8x16, v_int8x16, epi8, (char)-128) +OPENCV_HAL_IMPL_SSE_INT_CMP_OP(v_uint16x8, v_int16x8, epi16, (short)-32768) OPENCV_HAL_IMPL_SSE_INT_CMP_OP(v_uint32x4, v_int32x4, epi32, (int)0x80000000) #define OPENCV_HAL_IMPL_SSE_FLT_CMP_OP(_Tpvec, suffix) \ @@ -1553,21 +1552,21 @@ OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int8x16, v_sub_wrap, _mm_sub_epi8) OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint16x8, v_sub_wrap, _mm_sub_epi16) OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int16x8, v_sub_wrap, _mm_sub_epi16) -#define OPENCV_HAL_IMPL_SSE_ABSDIFF_8_16(_Tpuvec, _Tpsvec, bits, sbit) \ +#define OPENCV_HAL_IMPL_SSE_ABSDIFF_8_16(_Tpuvec, _Tpsvec, bits, smask32) \ inline _Tpuvec v_absdiff(const _Tpuvec& a, const _Tpuvec& b) \ { \ return _Tpuvec(_mm_add_epi##bits(_mm_subs_epu##bits(a.val, b.val), _mm_subs_epu##bits(b.val, a.val))); \ } \ inline _Tpuvec v_absdiff(const _Tpsvec& a, const _Tpsvec& b) \ { \ - __m128i smask = _mm_set1_epi8(sbit); \ + __m128i smask = _mm_set1_epi32(smask32); \ __m128i a1 = _mm_xor_si128(a.val, smask); \ __m128i b1 = _mm_xor_si128(b.val, smask); \ return _Tpuvec(_mm_add_epi##bits(_mm_subs_epu##bits(a1, b1), _mm_subs_epu##bits(b1, a1))); \ } -OPENCV_HAL_IMPL_SSE_ABSDIFF_8_16(v_uint8x16, v_int8x16, 8, (char)0x80) -OPENCV_HAL_IMPL_SSE_ABSDIFF_8_16(v_uint16x8, v_int16x8, 16, (char)0x8000) +OPENCV_HAL_IMPL_SSE_ABSDIFF_8_16(v_uint8x16, v_int8x16, 8, (int)0x80808080) +OPENCV_HAL_IMPL_SSE_ABSDIFF_8_16(v_uint16x8, v_int16x8, 16, (int)0x80008000) #define OPENCV_HAL_IMPL_SSE_MISC_FLT_OP(_Tpvec, _Tp, _Tpreg, suffix, absmask_vec) \ inline _Tpvec v_absdiff(const _Tpvec& a, const _Tpvec& b) \ @@ -1704,7 +1703,7 @@ OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_float32x4, float, max, std::max) OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_float32x4, float, min, std::min) #define OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(_Tpvec, suffix, pack_op, and_op, signmask, allmask) \ -inline bool v_signmask(const _Tpvec& a) \ +inline int v_signmask(const _Tpvec& a) \ { \ return and_op(_mm_movemask_##suffix(pack_op(a.val)), signmask); \ } \ @@ -2850,4 +2849,12 @@ inline v_float32x4 v_matmul(const v_float32x4& v, const v_float32x4& m0, }} +#ifndef CV_SIMD128 +#define CV_SIMD128 0 +#endif + +#ifndef CV_SIMD128_64F +#define CV_SIMD128_64F 0 +#endif + #endif diff --git a/modules/hal/src/mathfuncs.cpp b/modules/hal/src/mathfuncs.cpp index e970cfedb8..7d0199f00c 100644 --- a/modules/hal/src/mathfuncs.cpp +++ b/modules/hal/src/mathfuncs.cpp @@ -185,7 +185,7 @@ void magnitude(const double* x, const double* y, double* mag, int len) { int i = 0; -#if defined CV_SIMD128_64F && CV_SIMD128_64F +#if CV_SIMD128_64F for( ; i <= len - 4; i += 4 ) { v_float64x2 x0 = v_load(x + i), x1 = v_load(x + i + 2); @@ -262,7 +262,7 @@ void sqrt(const double* src, double* dst, int len) { int i = 0; -#if defined CV_SIMD128_64F && CV_SIMD128_64F +#if CV_SIMD128_64F for( ; i <= len - 4; i += 4 ) { v_float64x2 t0 = v_load(src + i), t1 = v_load(src + i + 2); From 1fcc83b84b7ff2a6c945d3a26cc487aae0352b70 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Thu, 16 Apr 2015 23:52:23 +0300 Subject: [PATCH 057/109] fixed some more compile warnings --- modules/hal/include/opencv2/hal/intrin.hpp | 18 +++++++++--------- modules/hal/src/precomp.hpp | 1 + 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/modules/hal/include/opencv2/hal/intrin.hpp b/modules/hal/include/opencv2/hal/intrin.hpp index bfd41ad0d1..adb95d6a12 100644 --- a/modules/hal/include/opencv2/hal/intrin.hpp +++ b/modules/hal/include/opencv2/hal/intrin.hpp @@ -1140,7 +1140,7 @@ inline v_float32x4 v_reinterpret_as_f32(const v_float64x2& a) template inline v_float64x2 v_reinterpret_as_f64(const _Tpvec& a) { return v_float64x2(_mm_castsi128_pd(a.val)); } -inline v_float64x2 v_reinterpret_as_f64(const v_float64x2& a) +inline v_float64x2 v_reinterpret_as_f64(const v_float32x4& a) { return v_float64x2(_mm_castps_pd(a.val)); } inline v_uint8x16 v_cvtn_u16(const v_uint16x8& a, const v_uint16x8& b) @@ -1893,10 +1893,10 @@ inline void v_load_deinterleave(const uchar* ptr, v_uint8x16& a, v_uint8x16& b, __m128i u2 = _mm_loadu_si128((const __m128i*)(ptr + 32)); // a8 b8 c8 d8 ... __m128i u3 = _mm_loadu_si128((const __m128i*)(ptr + 48)); // a12 b12 c12 d12 ... - __m128 v0 = _mm_unpacklo_epi8(u0, u2); // a0 a8 b0 b8 ... - __m128 v1 = _mm_unpackhi_epi8(u0, u2); // a2 a10 b2 b10 ... - __m128 v2 = _mm_unpacklo_epi8(u1, u3); // a4 a12 b4 b12 ... - __m128 v3 = _mm_unpackhi_epi8(u1, u3); // a6 a14 b4 b14 ... + __m128i v0 = _mm_unpacklo_epi8(u0, u2); // a0 a8 b0 b8 ... + __m128i v1 = _mm_unpackhi_epi8(u0, u2); // a2 a10 b2 b10 ... + __m128i v2 = _mm_unpacklo_epi8(u1, u3); // a4 a12 b4 b12 ... + __m128i v3 = _mm_unpackhi_epi8(u1, u3); // a6 a14 b4 b14 ... u0 = _mm_unpacklo_epi8(v0, v2); // a0 a4 a8 a12 ... u1 = _mm_unpacklo_epi8(v1, v3); // a2 a6 a10 a14 ... @@ -1928,10 +1928,10 @@ inline void v_load_deinterleave(const ushort* ptr, v_uint16x8& a, v_uint16x8& b, __m128i u2 = _mm_loadu_si128((const __m128i*)(ptr + 16)); // a4 b4 c4 d4 ... __m128i u3 = _mm_loadu_si128((const __m128i*)(ptr + 24)); // a6 b6 c6 d6 ... - __m128 v0 = _mm_unpacklo_epi16(u0, u2); // a0 a4 b0 b4 ... - __m128 v1 = _mm_unpackhi_epi16(u0, u2); // a1 a5 b1 b5 ... - __m128 v2 = _mm_unpacklo_epi16(u1, u3); // a2 a6 b2 b6 ... - __m128 v3 = _mm_unpackhi_epi16(u1, u3); // a3 a7 b3 b7 ... + __m128i v0 = _mm_unpacklo_epi16(u0, u2); // a0 a4 b0 b4 ... + __m128i v1 = _mm_unpackhi_epi16(u0, u2); // a1 a5 b1 b5 ... + __m128i v2 = _mm_unpacklo_epi16(u1, u3); // a2 a6 b2 b6 ... + __m128i v3 = _mm_unpackhi_epi16(u1, u3); // a3 a7 b3 b7 ... u0 = _mm_unpacklo_epi16(v0, v2); // a0 a2 a4 a6 ... u1 = _mm_unpacklo_epi16(v1, v3); // a1 a3 a5 a7 ... diff --git a/modules/hal/src/precomp.hpp b/modules/hal/src/precomp.hpp index 95ddac9bc8..630565bec3 100644 --- a/modules/hal/src/precomp.hpp +++ b/modules/hal/src/precomp.hpp @@ -45,4 +45,5 @@ #include #include #include +#include #include From bfbf864a73210112d49867632d60d23dc30a143f Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Fri, 17 Apr 2015 00:13:08 +0300 Subject: [PATCH 058/109] fixed some more compile warnings (2) --- modules/hal/include/opencv2/hal/defs.h | 4 +- modules/hal/include/opencv2/hal/intrin.hpp | 52 +++------------------- 2 files changed, 8 insertions(+), 48 deletions(-) diff --git a/modules/hal/include/opencv2/hal/defs.h b/modules/hal/include/opencv2/hal/defs.h index 18c1adc6ce..197533993b 100644 --- a/modules/hal/include/opencv2/hal/defs.h +++ b/modules/hal/include/opencv2/hal/defs.h @@ -666,10 +666,10 @@ template<> inline unsigned saturate_cast(double v) { return cvRound(v) //! @endcond -//! @} core_utils - } #endif // __cplusplus +//! @} core_utils + #endif //__OPENCV_HAL_H__ diff --git a/modules/hal/include/opencv2/hal/intrin.hpp b/modules/hal/include/opencv2/hal/intrin.hpp index adb95d6a12..3c53d60797 100644 --- a/modules/hal/include/opencv2/hal/intrin.hpp +++ b/modules/hal/include/opencv2/hal/intrin.hpp @@ -905,10 +905,6 @@ struct v_uint8x16 (char)v8, (char)v9, (char)v10, (char)v11, (char)v12, (char)v13, (char)v14, (char)v15); } - uchar get(const int i) const - { - return (uchar)(_mm_extract_epi16(val, i/2) >> ((i&1)*8)); - } uchar get0() const { return (uchar)_mm_cvtsi128_si32(val); @@ -928,10 +924,6 @@ struct v_int8x16 (char)v8, (char)v9, (char)v10, (char)v11, (char)v12, (char)v13, (char)v14, (char)v15); } - schar get(const int i) const - { - return (schar)(_mm_extract_epi16(val, i/2) >> ((i&1)*8)); - } schar get0() const { return (schar)_mm_cvtsi128_si32(val); @@ -948,10 +940,6 @@ struct v_uint16x8 val = _mm_setr_epi16((short)v0, (short)v1, (short)v2, (short)v3, (short)v4, (short)v5, (short)v6, (short)v7); } - ushort get(const int i) const - { - return (ushort)_mm_extract_epi16(val, i); - } ushort get0() const { return (ushort)_mm_cvtsi128_si32(val); @@ -968,10 +956,6 @@ struct v_int16x8 val = _mm_setr_epi16((short)v0, (short)v1, (short)v2, (short)v3, (short)v4, (short)v5, (short)v6, (short)v7); } - short get(const int i) const - { - return (short)_mm_extract_epi16(val, i); - } short get0() const { return (short)_mm_cvtsi128_si32(val); @@ -986,12 +970,6 @@ struct v_uint32x4 { val = _mm_setr_epi32((int)v0, (int)v1, (int)v2, (int)v3); } - unsigned get(const int i) const - { - unsigned CV_DECL_ALIGNED(16) buf[4]; - _mm_store_si128((__m128i*)buf, val); - return buf[i]; - } unsigned get0() const { return (unsigned)_mm_cvtsi128_si32(val); @@ -1006,12 +984,6 @@ struct v_int32x4 { val = _mm_setr_epi32(v0, v1, v2, v3); } - int get(int i) const - { - int CV_DECL_ALIGNED(16) buf[4]; - _mm_store_si128((__m128i*)buf, val); - return buf[i]; - } int get0() const { return _mm_cvtsi128_si32(val); @@ -1026,12 +998,6 @@ struct v_float32x4 { val = _mm_setr_ps(v0, v1, v2, v3); } - float get(int i) const - { - float CV_DECL_ALIGNED(16) buf[4]; - _mm_store_ps(buf, val); - return buf[i]; - } float get0() const { return _mm_cvtss_f32(val); @@ -1046,12 +1012,6 @@ struct v_float64x2 { val = _mm_setr_pd(v0, v1); } - double get(int i) const - { - double CV_DECL_ALIGNED(16) buf[2]; - _mm_store_pd(buf, val); - return buf[i]; - } double get0() const { return _mm_cvtsd_f64(val); @@ -1376,10 +1336,10 @@ OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_int32x4, si128, _mm_set1_epi32(-1)) OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_float32x4, ps, _mm_castsi128_ps(_mm_set1_epi32(-1))) OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_float64x2, pd, _mm_castsi128_pd(_mm_set1_epi32(-1))) -inline v_float32x4 v_sqrt(v_float32x4 x) +inline v_float32x4 v_sqrt(const v_float32x4& x) { return v_float32x4(_mm_sqrt_ps(x.val)); } -inline v_float32x4 v_invsqrt(v_float32x4 x) +inline v_float32x4 v_invsqrt(const v_float32x4& x) { static const __m128 _0_5 = _mm_set1_ps(0.5f), _1_5 = _mm_set1_ps(1.5f); __m128 t = x.val; @@ -1389,18 +1349,18 @@ inline v_float32x4 v_invsqrt(v_float32x4 x) return v_float32x4(t); } -inline v_float64x2 v_sqrt(v_float64x2 x) +inline v_float64x2 v_sqrt(const v_float64x2& x) { return v_float64x2(_mm_sqrt_pd(x.val)); } -inline v_float64x2 v_invsqrt(v_float64x2 x) +inline v_float64x2 v_invsqrt(const v_float64x2& x) { static const __m128d v_1 = _mm_set1_pd(1.); return v_float64x2(_mm_div_pd(v_1, _mm_sqrt_pd(x.val))); } -inline v_float32x4 v_abs(v_float32x4 x) +inline v_float32x4 v_abs(const v_float32x4& x) { return v_float32x4(_mm_and_ps(x.val, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff)))); } -inline v_float64x2 v_abs(v_float64x2 x) +inline v_float64x2 v_abs(const v_float64x2& x) { return v_float64x2(_mm_and_pd(x.val, _mm_castsi128_pd(_mm_srli_epi64(_mm_set1_epi32(-1), 1)))); From ce7590bd248a418eab6245ec6f9bf70b885904c6 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Fri, 17 Apr 2015 08:32:06 +0300 Subject: [PATCH 059/109] continuing fixing universal intrinsics --- modules/hal/include/opencv2/hal/intrin.hpp | 38 +++++++++++----------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/modules/hal/include/opencv2/hal/intrin.hpp b/modules/hal/include/opencv2/hal/intrin.hpp index 3c53d60797..e959a49cff 100644 --- a/modules/hal/include/opencv2/hal/intrin.hpp +++ b/modules/hal/include/opencv2/hal/intrin.hpp @@ -2218,7 +2218,7 @@ inline _Tpvec& operator bin_op##= (_Tpvec& a, const _Tpvec& b) \ OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_uint8x16, vqaddq_u8) OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_uint8x16, vqsubq_u8) OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_int8x16, vqaddq_s8) -OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_int8x16, vqsubq_u8) +OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_int8x16, vqsubq_s8) OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_uint16x8, vqaddq_u16) OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_uint16x8, vqsubq_u16) OPENCV_HAL_IMPL_NEON_BIN_OP(*, v_uint16x8, vmulq_u16) @@ -2342,11 +2342,11 @@ inline _Tpvec operator >= (const _Tpvec& a, const _Tpvec& b) \ { return _Tpvec(cast(vcgeq_##suffix(a.val, b.val))); } OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint8x16, OPENCV_HAL_NOP, u8, u8) -OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int8x16, OPENCV_HAL_NOP, s8, u8) +OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int8x16, vreinterpretq_s8_u8, s8, u8) OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint16x8, OPENCV_HAL_NOP, u16, u16) -OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int16x8, OPENCV_HAL_NOP, s16, u16) +OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int16x8, vreinterpretq_s16_u16, s16, u16) OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint32x4, OPENCV_HAL_NOP, u32, u32) -OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int32x4, OPENCV_HAL_NOP, s32, u32) +OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int32x4, vreinterpretq_s32_u32, s32, u32) OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_float32x4, vreinterpretq_f32_u32, f32, u32) OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_add_wrap, vaddq_u8) @@ -2381,18 +2381,18 @@ inline v_float32x4 v_muladd(const v_float32x4& a, const v_float32x4& b, const v_ } // trade efficiency for convenience -#define OPENCV_HAL_IMPL_NEON_SHIFT_OP(_Tpvec, _Tp, suffix) \ +#define OPENCV_HAL_IMPL_NEON_SHIFT_OP(_Tpvec, suffix, _Tps, ssuffix) \ inline _Tpvec operator << (const _Tpvec& a, int n) \ -{ return _Tpvec(vshlq_##suffix(a.val, vdupq_n_##suffix((_Tp)n))); } \ +{ return _Tpvec(vshlq_##suffix(a.val, vdupq_n_##ssuffix((_Tps)n))); } \ inline _Tpvec operator >> (const _Tpvec& a, int n) \ -{ return _Tpvec(vshlq_##suffix(a.val, vdupq_n_##suffix((_Tp)-n))); } +{ return _Tpvec(vshlq_##suffix(a.val, vdupq_n_##ssuffix((_Tps)-n))); } -OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_uint8x16, uchar, u8) -OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_int8x16, schar, s8) -OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_uint16x8, ushort, u16) -OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_int16x8, short, s16) -OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_uint32x4, unsigned, u32) -OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_int32x4, int, s32) +OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_uint8x16, u8, schar, s8) +OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_int8x16, s8, schar, s8) +OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_uint16x8, u16, short, s16) +OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_int16x8, s16, short, s16) +OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_uint32x4, u32, int, s32) +OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_int32x4, s32, int, s32) OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_mullo, vmulq_u16) OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int16x8, v_mullo, vmulq_s16) @@ -2444,8 +2444,8 @@ OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_float32x4, float, min, std::min) inline int v_signmask(const v_uint8x16& a) { - uint8x8_t m0 = vcreate_u8(CV_BIG_UINT(0x0706050403020100)); - uint8x16_t v0 = vshlq_u8(vshrq_n_u8(a.val, 7), vcombine_u8(m0, m0)); + int8x8_t m0 = vcreate_s8(CV_BIG_UINT(0x0706050403020100)); + uint8x16_t v0 = vshlq_u8(vshrq_n_u8(a.val, 7), vcombine_s8(m0, m0)); uint64x2_t v1 = vpaddlq_u32(vpaddlq_u16(vpaddlq_u8(v0))); return (int)vgetq_lane_u64(v1, 0) + ((int)vgetq_lane_u64(v1, 1) << 8); } @@ -2454,8 +2454,8 @@ inline int v_signmask(const v_int8x16& a) inline int v_signmask(const v_uint16x8& a) { - uint16x4_t m0 = vcreate_u16(CV_BIG_UINT(0x0003000200010000)); - uint16x8_t v0 = vshlq_u16(vshrq_n_u16(a.val, 15), vcombine_u16(m0, m0)); + int16x4_t m0 = vcreate_s16(CV_BIG_UINT(0x0003000200010000)); + uint16x8_t v0 = vshlq_u16(vshrq_n_u16(a.val, 15), vcombine_s16(m0, m0)); uint64x2_t v1 = vpaddlq_u32(vpaddlq_u16(v0)); return (int)vgetq_lane_u64(v1, 0) + ((int)vgetq_lane_u64(v1, 1) << 4); } @@ -2464,8 +2464,8 @@ inline int v_signmask(const v_int16x8& a) inline int v_signmask(const v_uint32x4& a) { - uint32x2_t m0 = vcreate_u32(CV_BIG_UINT(0x0000000100000000)); - uint32x4_t v0 = vshlq_u32(vshrq_n_u32(a.val, 31), vcombine_u32(m0, m0)); + int32x2_t m0 = vcreate_s32(CV_BIG_UINT(0x0000000100000000)); + uint32x4_t v0 = vshlq_u32(vshrq_n_u32(a.val, 31), vcombine_s32(m0, m0)); uint64x2_t v1 = vpaddlq_u32(v0); return (int)vgetq_lane_u64(v1, 0) + ((int)vgetq_lane_u64(v1, 1) << 2); } From 17675b4cb83810dcd582cca0eb0d1cd7ddb545e8 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Fri, 17 Apr 2015 10:51:49 +0300 Subject: [PATCH 060/109] trying to fix test failures --- modules/hal/include/opencv2/hal/intrin.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/hal/include/opencv2/hal/intrin.hpp b/modules/hal/include/opencv2/hal/intrin.hpp index e959a49cff..b067301d82 100644 --- a/modules/hal/include/opencv2/hal/intrin.hpp +++ b/modules/hal/include/opencv2/hal/intrin.hpp @@ -2287,16 +2287,16 @@ inline v_float32x4 operator ~ (const v_float32x4& a) inline v_float32x4 v_sqrt(const v_float32x4& x) { float32x4_t e = vrsqrteq_f32(x.val); - e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(e, e), x.val), e); - e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(e, e), x.val), e); - return v_float32x4(vmulq_f32(e, x.val)); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x.val, e), e), e); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x.val, e), e), e); + return v_float32x4(vmulq_f32(x.val, e)); } inline v_float32x4 v_invsqrt(const v_float32x4& x) { float32x4_t e = vrsqrteq_f32(x.val); - e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(e, e), x.val), e); - e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(e, e), x.val), e); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x.val, e), e), e); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x.val, e), e), e); return v_float32x4(e); } From 92f2ad0a1128f5559708359efe01899586c89c33 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Fri, 17 Apr 2015 11:32:20 +0300 Subject: [PATCH 061/109] trying to fix test failures (take 2) --- modules/hal/include/opencv2/hal/intrin.hpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/hal/include/opencv2/hal/intrin.hpp b/modules/hal/include/opencv2/hal/intrin.hpp index b067301d82..fc40cfda8d 100644 --- a/modules/hal/include/opencv2/hal/intrin.hpp +++ b/modules/hal/include/opencv2/hal/intrin.hpp @@ -47,6 +47,7 @@ #include #include +#include #include #define OPENCV_HAL_ADD(a, b) ((a) + (b)) @@ -2286,9 +2287,10 @@ inline v_float32x4 operator ~ (const v_float32x4& a) inline v_float32x4 v_sqrt(const v_float32x4& x) { - float32x4_t e = vrsqrteq_f32(x.val); - e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x.val, e), e), e); - e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x.val, e), e), e); + float32x4_t x1 = vmaxq_f32(x.val, vdupq_n_f32(FLT_MIN)); + float32x4_t e = vrsqrteq_f32(x1); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x1, e), e), e); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x1, e), e), e); return v_float32x4(vmulq_f32(x.val, e)); } From 316d76bdb6347fb530578cf0ea9208446bc5a5b8 Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Fri, 17 Apr 2015 16:00:33 +0300 Subject: [PATCH 062/109] Rename OpenCV Engine to org.opencv.engine3 for release candidate --- modules/java/CMakeLists.txt | 4 ++-- .../src/java/android+AsyncServiceHelper.java | 8 +++---- ...idl => engine3+OpenCVEngineInterface.aidl} | 2 +- .../service/engine/AndroidManifest.xml | 6 ++--- .../jni/JNIWrapper/HardwareDetector_jni.cpp | 8 +++---- .../jni/JNIWrapper/HardwareDetector_jni.h | 8 +++---- .../jni/JNIWrapper/OpenCVEngine_jni.cpp | 6 ++--- .../engine/jni/JNIWrapper/OpenCVEngine_jni.h | 6 ++--- .../jni/JNIWrapper/OpenCVLibraryInfo.cpp | 10 ++++----- .../engine/jni/JNIWrapper/OpenCVLibraryInfo.h | 10 ++++----- .../engine/jni/NativeService/PackageInfo.cpp | 2 +- .../service/engine/jni/include/EngineCommon.h | 4 ++-- .../{engine => engine3}/BinderConnector.java | 2 +- .../{engine => engine3}/HardwareDetector.java | 2 +- .../{engine => engine3}/MarketConnector.java | 4 ++-- .../OpenCVEngineInterface.aidl | 2 +- .../OpenCVEngineService.java | 2 +- .../OpenCVLibraryInfo.java | 2 +- .../manager/ManagerActivity.java | 22 +++++++++---------- .../manager/PackageListAdapter.java | 2 +- .../service/engine_test/AndroidManifest.xml | 6 ++--- .../test/EngineInterfaceTest.java | 16 +++++++------- 22 files changed, 67 insertions(+), 67 deletions(-) rename modules/java/generator/src/java/{engine+OpenCVEngineInterface.aidl => engine3+OpenCVEngineInterface.aidl} (97%) rename platforms/android/service/engine/src/org/opencv/{engine => engine3}/BinderConnector.java (97%) rename platforms/android/service/engine/src/org/opencv/{engine => engine3}/HardwareDetector.java (98%) rename platforms/android/service/engine/src/org/opencv/{engine => engine3}/MarketConnector.java (97%) rename platforms/android/service/engine/src/org/opencv/{engine => engine3}/OpenCVEngineInterface.aidl (97%) rename platforms/android/service/engine/src/org/opencv/{engine => engine3}/OpenCVEngineService.java (98%) rename platforms/android/service/engine/src/org/opencv/{engine => engine3}/OpenCVLibraryInfo.java (97%) rename platforms/android/service/engine/src/org/opencv/{engine => engine3}/manager/ManagerActivity.java (97%) rename platforms/android/service/engine/src/org/opencv/{engine => engine3}/manager/PackageListAdapter.java (96%) rename platforms/android/service/engine_test/src/org/opencv/{engine => engine3}/test/EngineInterfaceTest.java (91%) diff --git a/modules/java/CMakeLists.txt b/modules/java/CMakeLists.txt index 3ba9c54dcd..ce24daf79f 100644 --- a/modules/java/CMakeLists.txt +++ b/modules/java/CMakeLists.txt @@ -174,8 +174,8 @@ endforeach() file(REMOVE_RECURSE "${probe_dir}") if(NOT ANDROID) - ocv_list_filterout(handwritten_java_sources "/(engine|android)\\\\+") - ocv_list_filterout(handwritten_aidl_sources "/(engine|android)\\\\+") + ocv_list_filterout(handwritten_java_sources "/(engine3|android)\\\\+") + ocv_list_filterout(handwritten_aidl_sources "/(engine3|android)\\\\+") else() file(GLOB_RECURSE handwrittren_lib_project_files_rel RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/android_lib/" "${CMAKE_CURRENT_SOURCE_DIR}/android_lib/*") list(REMOVE_ITEM handwrittren_lib_project_files_rel "${ANDROID_MANIFEST_FILE}") diff --git a/modules/java/generator/src/java/android+AsyncServiceHelper.java b/modules/java/generator/src/java/android+AsyncServiceHelper.java index e18d5a5001..9fdf5ac1f9 100644 --- a/modules/java/generator/src/java/android+AsyncServiceHelper.java +++ b/modules/java/generator/src/java/android+AsyncServiceHelper.java @@ -4,7 +4,7 @@ import java.io.File; import java.util.StringTokenizer; import org.opencv.core.Core; -import org.opencv.engine.OpenCVEngineInterface; +import org.opencv.engine3.OpenCVEngineInterface; import android.content.ComponentName; import android.content.Context; @@ -21,8 +21,8 @@ class AsyncServiceHelper final LoaderCallbackInterface Callback) { AsyncServiceHelper helper = new AsyncServiceHelper(Version, AppContext, Callback); - Intent intent = new Intent("org.opencv.engine.BIND"); - intent.setPackage("org.opencv.engine"); + Intent intent = new Intent("org.opencv.engine3.BIND"); + intent.setPackage("org.opencv.engine3"); if (AppContext.bindService(intent, helper.mServiceConnection, Context.BIND_AUTO_CREATE)) { return true; @@ -151,7 +151,7 @@ class AsyncServiceHelper /** * URL of OpenCV Manager page on Google Play Market. */ - protected static final String OPEN_CV_SERVICE_URL = "market://details?id=org.opencv.engine"; + protected static final String OPEN_CV_SERVICE_URL = "market://details?id=org.opencv.engine3"; protected ServiceConnection mServiceConnection = new ServiceConnection() { diff --git a/modules/java/generator/src/java/engine+OpenCVEngineInterface.aidl b/modules/java/generator/src/java/engine3+OpenCVEngineInterface.aidl similarity index 97% rename from modules/java/generator/src/java/engine+OpenCVEngineInterface.aidl rename to modules/java/generator/src/java/engine3+OpenCVEngineInterface.aidl index 21fe5f716b..b84eaaafb0 100644 --- a/modules/java/generator/src/java/engine+OpenCVEngineInterface.aidl +++ b/modules/java/generator/src/java/engine3+OpenCVEngineInterface.aidl @@ -1,4 +1,4 @@ -package org.opencv.engine; +package org.opencv.engine3; /** * Class provides a Java interface for OpenCV Engine Service. It's synchronous with native OpenCVEngine class. diff --git a/platforms/android/service/engine/AndroidManifest.xml b/platforms/android/service/engine/AndroidManifest.xml index 4f78c314a8..40adb98d74 100644 --- a/platforms/android/service/engine/AndroidManifest.xml +++ b/platforms/android/service/engine/AndroidManifest.xml @@ -1,6 +1,6 @@ @@ -13,12 +13,12 @@ - + diff --git a/platforms/android/service/engine/jni/JNIWrapper/HardwareDetector_jni.cpp b/platforms/android/service/engine/jni/JNIWrapper/HardwareDetector_jni.cpp index 3e490a3160..0145abb8ce 100644 --- a/platforms/android/service/engine/jni/JNIWrapper/HardwareDetector_jni.cpp +++ b/platforms/android/service/engine/jni/JNIWrapper/HardwareDetector_jni.cpp @@ -3,23 +3,23 @@ #include #include -JNIEXPORT jint JNICALL Java_org_opencv_engine_HardwareDetector_GetCpuID(JNIEnv* , jclass) +JNIEXPORT jint JNICALL Java_org_opencv_engine3_HardwareDetector_GetCpuID(JNIEnv* , jclass) { return GetCpuID(); } -JNIEXPORT jstring JNICALL Java_org_opencv_engine_HardwareDetector_GetPlatformName(JNIEnv* env, jclass) +JNIEXPORT jstring JNICALL Java_org_opencv_engine3_HardwareDetector_GetPlatformName(JNIEnv* env, jclass) { std::string hardware_name = GetPlatformName(); return env->NewStringUTF(hardware_name.c_str()); } -JNIEXPORT jint JNICALL Java_org_opencv_engine_HardwareDetector_GetProcessorCount(JNIEnv* , jclass) +JNIEXPORT jint JNICALL Java_org_opencv_engine3_HardwareDetector_GetProcessorCount(JNIEnv* , jclass) { return GetProcessorCount(); } -JNIEXPORT jint JNICALL Java_org_opencv_engine_HardwareDetector_DetectKnownPlatforms(JNIEnv* , jclass) +JNIEXPORT jint JNICALL Java_org_opencv_engine3_HardwareDetector_DetectKnownPlatforms(JNIEnv* , jclass) { return DetectKnownPlatforms(); } diff --git a/platforms/android/service/engine/jni/JNIWrapper/HardwareDetector_jni.h b/platforms/android/service/engine/jni/JNIWrapper/HardwareDetector_jni.h index 43fad33c86..61f294e99f 100644 --- a/platforms/android/service/engine/jni/JNIWrapper/HardwareDetector_jni.h +++ b/platforms/android/service/engine/jni/JNIWrapper/HardwareDetector_jni.h @@ -14,7 +14,7 @@ extern "C" { * Method: GetCpuID * Signature: ()I */ -JNIEXPORT jint JNICALL Java_org_opencv_engine_HardwareDetector_GetCpuID +JNIEXPORT jint JNICALL Java_org_opencv_engine3_HardwareDetector_GetCpuID (JNIEnv *, jclass); /* @@ -22,7 +22,7 @@ JNIEXPORT jint JNICALL Java_org_opencv_engine_HardwareDetector_GetCpuID * Method: GetPlatformName * Signature: ()Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_org_opencv_engine_HardwareDetector_GetPlatformName +JNIEXPORT jstring JNICALL Java_org_opencv_engine3_HardwareDetector_GetPlatformName (JNIEnv *, jclass); /* @@ -30,7 +30,7 @@ JNIEXPORT jstring JNICALL Java_org_opencv_engine_HardwareDetector_GetPlatformNam * Method: GetProcessorCount * Signature: ()I */ -JNIEXPORT jint JNICALL Java_org_opencv_engine_HardwareDetector_GetProcessorCount +JNIEXPORT jint JNICALL Java_org_opencv_engine3_HardwareDetector_GetProcessorCount (JNIEnv *, jclass); /* @@ -38,7 +38,7 @@ JNIEXPORT jint JNICALL Java_org_opencv_engine_HardwareDetector_GetProcessorCount * Method: DetectKnownPlatforms * Signature: ()I */ -JNIEXPORT jint JNICALL Java_org_opencv_engine_HardwareDetector_DetectKnownPlatforms +JNIEXPORT jint JNICALL Java_org_opencv_engine3_HardwareDetector_DetectKnownPlatforms (JNIEnv *, jclass); #ifdef __cplusplus diff --git a/platforms/android/service/engine/jni/JNIWrapper/OpenCVEngine_jni.cpp b/platforms/android/service/engine/jni/JNIWrapper/OpenCVEngine_jni.cpp index dac4916563..1dd038125a 100644 --- a/platforms/android/service/engine/jni/JNIWrapper/OpenCVEngine_jni.cpp +++ b/platforms/android/service/engine/jni/JNIWrapper/OpenCVEngine_jni.cpp @@ -15,7 +15,7 @@ using namespace android; sp OpenCVEngineBinder = NULL; IPackageManager* PackageManager = NULL; -JNIEXPORT jobject JNICALL Java_org_opencv_engine_BinderConnector_Connect(JNIEnv* env, jobject) +JNIEXPORT jobject JNICALL Java_org_opencv_engine3_BinderConnector_Connect(JNIEnv* env, jobject) { LOGI("Creating new component"); if (NULL != OpenCVEngineBinder.get()) @@ -30,7 +30,7 @@ JNIEXPORT jobject JNICALL Java_org_opencv_engine_BinderConnector_Connect(JNIEnv* return javaObjectForIBinder(env, OpenCVEngineBinder); } -JNIEXPORT jboolean JNICALL Java_org_opencv_engine_BinderConnector_Init(JNIEnv* env, jobject , jobject market) +JNIEXPORT jboolean JNICALL Java_org_opencv_engine3_BinderConnector_Init(JNIEnv* env, jobject , jobject market) { LOGD("Java_org_opencv_engine_BinderConnector_Init"); @@ -58,7 +58,7 @@ JNIEXPORT jboolean JNICALL Java_org_opencv_engine_BinderConnector_Init(JNIEnv* e } } -JNIEXPORT void JNICALL Java_org_opencv_engine_BinderConnector_Final(JNIEnv *, jobject) +JNIEXPORT void JNICALL Java_org_opencv_engine3_BinderConnector_Final(JNIEnv *, jobject) { LOGD("Java_org_opencv_engine_BinderConnector_Final"); diff --git a/platforms/android/service/engine/jni/JNIWrapper/OpenCVEngine_jni.h b/platforms/android/service/engine/jni/JNIWrapper/OpenCVEngine_jni.h index cd0734eb07..bfeafb0498 100644 --- a/platforms/android/service/engine/jni/JNIWrapper/OpenCVEngine_jni.h +++ b/platforms/android/service/engine/jni/JNIWrapper/OpenCVEngine_jni.h @@ -12,7 +12,7 @@ extern "C" { * Method: Connect * Signature: ()Landroid/os/IBinder; */ -JNIEXPORT jobject JNICALL Java_org_opencv_engine_BinderConnector_Connect +JNIEXPORT jobject JNICALL Java_org_opencv_engine3_BinderConnector_Connect (JNIEnv *, jobject); /* @@ -20,7 +20,7 @@ JNIEXPORT jobject JNICALL Java_org_opencv_engine_BinderConnector_Connect * Method: Init * Signature: (Lorg/opencv/engine/MarketConnector;)Z */ -JNIEXPORT jboolean JNICALL Java_org_opencv_engine_BinderConnector_Init +JNIEXPORT jboolean JNICALL Java_org_opencv_engine3_BinderConnector_Init (JNIEnv *, jobject, jobject); /* @@ -28,7 +28,7 @@ JNIEXPORT jboolean JNICALL Java_org_opencv_engine_BinderConnector_Init * Method: Final * Signature: ()V */ -JNIEXPORT void JNICALL Java_org_opencv_engine_BinderConnector_Final +JNIEXPORT void JNICALL Java_org_opencv_engine3_BinderConnector_Final (JNIEnv *, jobject); #ifdef __cplusplus diff --git a/platforms/android/service/engine/jni/JNIWrapper/OpenCVLibraryInfo.cpp b/platforms/android/service/engine/jni/JNIWrapper/OpenCVLibraryInfo.cpp index e7dc6d2f14..f1c5ec19a8 100644 --- a/platforms/android/service/engine/jni/JNIWrapper/OpenCVLibraryInfo.cpp +++ b/platforms/android/service/engine/jni/JNIWrapper/OpenCVLibraryInfo.cpp @@ -3,7 +3,7 @@ #include #include -JNIEXPORT jlong JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_open +JNIEXPORT jlong JNICALL Java_org_opencv_engine3_OpenCVLibraryInfo_open (JNIEnv * env, jobject, jstring str) { const char* infoLibPath = env->GetStringUTFChars(str, NULL); @@ -21,7 +21,7 @@ JNIEXPORT jlong JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_open return (jlong)handle; } -JNIEXPORT jstring JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_getPackageName +JNIEXPORT jstring JNICALL Java_org_opencv_engine3_OpenCVLibraryInfo_getPackageName (JNIEnv* env, jobject, jlong handle) { InfoFunctionType info_func; @@ -41,7 +41,7 @@ JNIEXPORT jstring JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_getPackageNam return env->NewStringUTF(result); } -JNIEXPORT jstring JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_getLibraryList +JNIEXPORT jstring JNICALL Java_org_opencv_engine3_OpenCVLibraryInfo_getLibraryList (JNIEnv* env, jobject, jlong handle) { InfoFunctionType info_func; @@ -61,7 +61,7 @@ JNIEXPORT jstring JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_getLibraryLis return env->NewStringUTF(result); } -JNIEXPORT jstring JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_getVersionName +JNIEXPORT jstring JNICALL Java_org_opencv_engine3_OpenCVLibraryInfo_getVersionName (JNIEnv* env, jobject, jlong handle) { InfoFunctionType info_func; @@ -81,7 +81,7 @@ JNIEXPORT jstring JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_getVersionNam return env->NewStringUTF(result); } -JNIEXPORT void JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_close +JNIEXPORT void JNICALL Java_org_opencv_engine3_OpenCVLibraryInfo_close (JNIEnv*, jobject, jlong handle) { dlclose((void*)handle); diff --git a/platforms/android/service/engine/jni/JNIWrapper/OpenCVLibraryInfo.h b/platforms/android/service/engine/jni/JNIWrapper/OpenCVLibraryInfo.h index b02050ffde..574f0b4e0b 100644 --- a/platforms/android/service/engine/jni/JNIWrapper/OpenCVLibraryInfo.h +++ b/platforms/android/service/engine/jni/JNIWrapper/OpenCVLibraryInfo.h @@ -6,19 +6,19 @@ extern "C" { #endif -JNIEXPORT jlong JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_open +JNIEXPORT jlong JNICALL Java_org_opencv_engine3_OpenCVLibraryInfo_open (JNIEnv *, jobject, jstring); -JNIEXPORT jstring JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_getPackageName +JNIEXPORT jstring JNICALL Java_org_opencv_engine3_OpenCVLibraryInfo_getPackageName (JNIEnv *, jobject, jlong); -JNIEXPORT jstring JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_getLibraryList +JNIEXPORT jstring JNICALL Java_org_opencv_engine3_OpenCVLibraryInfo_getLibraryList (JNIEnv *, jobject, jlong); -JNIEXPORT jstring JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_getVersionName +JNIEXPORT jstring JNICALL Java_org_opencv_engine3_OpenCVLibraryInfo_getVersionName (JNIEnv *, jobject, jlong); -JNIEXPORT void JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_close +JNIEXPORT void JNICALL Java_org_opencv_engine3_OpenCVLibraryInfo_close (JNIEnv *, jobject, jlong); #ifdef __cplusplus diff --git a/platforms/android/service/engine/jni/NativeService/PackageInfo.cpp b/platforms/android/service/engine/jni/NativeService/PackageInfo.cpp index d831bf7a5c..d95f9f943e 100644 --- a/platforms/android/service/engine/jni/NativeService/PackageInfo.cpp +++ b/platforms/android/service/engine/jni/NativeService/PackageInfo.cpp @@ -27,7 +27,7 @@ map PackageInfo::InitPlatformNameMap() const map PackageInfo::PlatformNameMap = InitPlatformNameMap(); const string PackageInfo::BasePackageName = "org.opencv.lib"; -const string DEFAULT_ENGINE_INSTALL_PATH = "/data/data/org.opencv.engine"; +const string DEFAULT_ENGINE_INSTALL_PATH = "/data/data/org.opencv.engine3"; inline string JoinARMFeatures(int cpu_id) { diff --git a/platforms/android/service/engine/jni/include/EngineCommon.h b/platforms/android/service/engine/jni/include/EngineCommon.h index a03f02c68d..2948db8c1a 100644 --- a/platforms/android/service/engine/jni/include/EngineCommon.h +++ b/platforms/android/service/engine/jni/include/EngineCommon.h @@ -13,9 +13,9 @@ #define LIB_OPENCV_INFO_NAME "libopencv_info.so" // OpenCV Manager package name -#define OPENCV_ENGINE_PACKAGE "org.opencv.engine" +#define OPENCV_ENGINE_PACKAGE "org.opencv.engine3" // Class name of OpenCV engine binder object. Is needned for connection to service -#define OPECV_ENGINE_CLASSNAME "org.opencv.engine.OpenCVEngineInterface" +#define OPECV_ENGINE_CLASSNAME "org.opencv.engine3.OpenCVEngineInterface" typedef const char* (*InfoFunctionType)(); diff --git a/platforms/android/service/engine/src/org/opencv/engine/BinderConnector.java b/platforms/android/service/engine/src/org/opencv/engine3/BinderConnector.java similarity index 97% rename from platforms/android/service/engine/src/org/opencv/engine/BinderConnector.java rename to platforms/android/service/engine/src/org/opencv/engine3/BinderConnector.java index bde54d5b96..a54843354e 100644 --- a/platforms/android/service/engine/src/org/opencv/engine/BinderConnector.java +++ b/platforms/android/service/engine/src/org/opencv/engine3/BinderConnector.java @@ -1,4 +1,4 @@ -package org.opencv.engine; +package org.opencv.engine3; import android.os.IBinder; diff --git a/platforms/android/service/engine/src/org/opencv/engine/HardwareDetector.java b/platforms/android/service/engine/src/org/opencv/engine3/HardwareDetector.java similarity index 98% rename from platforms/android/service/engine/src/org/opencv/engine/HardwareDetector.java rename to platforms/android/service/engine/src/org/opencv/engine3/HardwareDetector.java index f115070aad..65ee243d3f 100644 --- a/platforms/android/service/engine/src/org/opencv/engine/HardwareDetector.java +++ b/platforms/android/service/engine/src/org/opencv/engine3/HardwareDetector.java @@ -1,4 +1,4 @@ -package org.opencv.engine; +package org.opencv.engine3; public class HardwareDetector { diff --git a/platforms/android/service/engine/src/org/opencv/engine/MarketConnector.java b/platforms/android/service/engine/src/org/opencv/engine3/MarketConnector.java similarity index 97% rename from platforms/android/service/engine/src/org/opencv/engine/MarketConnector.java rename to platforms/android/service/engine/src/org/opencv/engine3/MarketConnector.java index da595915f2..4e5f51acc5 100644 --- a/platforms/android/service/engine/src/org/opencv/engine/MarketConnector.java +++ b/platforms/android/service/engine/src/org/opencv/engine3/MarketConnector.java @@ -1,4 +1,4 @@ -package org.opencv.engine; +package org.opencv.engine3; import java.util.ArrayList; import java.util.Iterator; @@ -99,7 +99,7 @@ public class MarketConnector List AllPackages = mContext.getPackageManager().getInstalledPackages(PackageManager.GET_CONFIGURATIONS); List OpenCVPackages = new ArrayList(); try { - OpenCVPackages.add(mContext.getPackageManager().getPackageInfo("org.opencv.engine", PackageManager.GET_CONFIGURATIONS)); + OpenCVPackages.add(mContext.getPackageManager().getPackageInfo("org.opencv.engine3", PackageManager.GET_CONFIGURATIONS)); } catch (NameNotFoundException e) { Log.e(TAG, "OpenCV Manager package info was not found!"); e.printStackTrace(); diff --git a/platforms/android/service/engine/src/org/opencv/engine/OpenCVEngineInterface.aidl b/platforms/android/service/engine/src/org/opencv/engine3/OpenCVEngineInterface.aidl similarity index 97% rename from platforms/android/service/engine/src/org/opencv/engine/OpenCVEngineInterface.aidl rename to platforms/android/service/engine/src/org/opencv/engine3/OpenCVEngineInterface.aidl index 13e0f7f84f..2b957d4b07 100644 --- a/platforms/android/service/engine/src/org/opencv/engine/OpenCVEngineInterface.aidl +++ b/platforms/android/service/engine/src/org/opencv/engine3/OpenCVEngineInterface.aidl @@ -1,4 +1,4 @@ -package org.opencv.engine; +package org.opencv.engine3; /** * Class provides Java interface to OpenCV Engine Service. Is synchronious with native OpenCVEngine class. diff --git a/platforms/android/service/engine/src/org/opencv/engine/OpenCVEngineService.java b/platforms/android/service/engine/src/org/opencv/engine3/OpenCVEngineService.java similarity index 98% rename from platforms/android/service/engine/src/org/opencv/engine/OpenCVEngineService.java rename to platforms/android/service/engine/src/org/opencv/engine3/OpenCVEngineService.java index b3c4ea0575..c7df4a8117 100644 --- a/platforms/android/service/engine/src/org/opencv/engine/OpenCVEngineService.java +++ b/platforms/android/service/engine/src/org/opencv/engine3/OpenCVEngineService.java @@ -1,4 +1,4 @@ -package org.opencv.engine; +package org.opencv.engine3; import android.app.Service; import android.content.Intent; diff --git a/platforms/android/service/engine/src/org/opencv/engine/OpenCVLibraryInfo.java b/platforms/android/service/engine/src/org/opencv/engine3/OpenCVLibraryInfo.java similarity index 97% rename from platforms/android/service/engine/src/org/opencv/engine/OpenCVLibraryInfo.java rename to platforms/android/service/engine/src/org/opencv/engine3/OpenCVLibraryInfo.java index d0f67bfde0..cc36b152ad 100644 --- a/platforms/android/service/engine/src/org/opencv/engine/OpenCVLibraryInfo.java +++ b/platforms/android/service/engine/src/org/opencv/engine3/OpenCVLibraryInfo.java @@ -1,4 +1,4 @@ -package org.opencv.engine; +package org.opencv.engine3; public class OpenCVLibraryInfo { public OpenCVLibraryInfo(String packagePath) { diff --git a/platforms/android/service/engine/src/org/opencv/engine/manager/ManagerActivity.java b/platforms/android/service/engine/src/org/opencv/engine3/manager/ManagerActivity.java similarity index 97% rename from platforms/android/service/engine/src/org/opencv/engine/manager/ManagerActivity.java rename to platforms/android/service/engine/src/org/opencv/engine3/manager/ManagerActivity.java index b4e0be5a91..7308e848eb 100644 --- a/platforms/android/service/engine/src/org/opencv/engine/manager/ManagerActivity.java +++ b/platforms/android/service/engine/src/org/opencv/engine3/manager/ManagerActivity.java @@ -1,15 +1,15 @@ -package org.opencv.engine.manager; +package org.opencv.engine3.manager; import java.util.ArrayList; import java.util.HashMap; import java.util.StringTokenizer; -import org.opencv.engine.HardwareDetector; -import org.opencv.engine.MarketConnector; -import org.opencv.engine.OpenCVEngineInterface; -import org.opencv.engine.OpenCVEngineService; -import org.opencv.engine.OpenCVLibraryInfo; -import org.opencv.engine.R; +import org.opencv.engine3.HardwareDetector; +import org.opencv.engine3.MarketConnector; +import org.opencv.engine3.OpenCVEngineInterface; +import org.opencv.engine3.OpenCVEngineService; +import org.opencv.engine3.OpenCVLibraryInfo; +import org.opencv.engine3.R; import android.annotation.TargetApi; import android.app.Activity; import android.app.AlertDialog; @@ -161,7 +161,7 @@ public class ManagerActivity extends Activity mUpdateEngineButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { - if (!mMarket.InstallAppFromMarket("org.opencv.engine")) + if (!mMarket.InstallAppFromMarket("org.opencv.engine3")) { Toast toast = Toast.makeText(getApplicationContext(), "Google Play is not avaliable", Toast.LENGTH_SHORT); toast.show(); @@ -207,7 +207,7 @@ public class ManagerActivity extends Activity public void onItemClick(AdapterView adapter, View view, int position, long id) { //if (!mListViewItems.get((int) id).get("Name").equals("Built-in OpenCV library")); - if (!mInstalledPackageInfo[(int) id].packageName.equals("org.opencv.engine")) + if (!mInstalledPackageInfo[(int) id].packageName.equals("org.opencv.engine3")) { mInstalledPackageView.setTag(Integer.valueOf((int)id)); mActionDialog.show(); @@ -221,7 +221,7 @@ public class ManagerActivity extends Activity public void onReceive(Context context, Intent intent) { Log.d("OpenCVManager/Receiver", "Broadcast message " + intent.getAction() + " receiver"); Log.d("OpenCVManager/Receiver", "Filling package list on broadcast message"); - if (!bindService(new Intent("org.opencv.engine.BIND"), + if (!bindService(new Intent("org.opencv.engine3.BIND"), new OpenCVEngineServiceConnection(), Context.BIND_AUTO_CREATE)) { TextView EngineVersionView = (TextView)findViewById(R.id.EngineVersionValue); @@ -350,7 +350,7 @@ public class ManagerActivity extends Activity else NativeLibDir = "/data/data/" + mInstalledPackageInfo[i].packageName + "/lib"; - if (PackageName.equals("org.opencv.engine")) + if (PackageName.equals("org.opencv.engine3")) { OpenCVLibraryInfo NativeInfo = new OpenCVLibraryInfo(NativeLibDir); if (NativeInfo.status()) diff --git a/platforms/android/service/engine/src/org/opencv/engine/manager/PackageListAdapter.java b/platforms/android/service/engine/src/org/opencv/engine3/manager/PackageListAdapter.java similarity index 96% rename from platforms/android/service/engine/src/org/opencv/engine/manager/PackageListAdapter.java rename to platforms/android/service/engine/src/org/opencv/engine3/manager/PackageListAdapter.java index 17707efd36..4a929ae952 100644 --- a/platforms/android/service/engine/src/org/opencv/engine/manager/PackageListAdapter.java +++ b/platforms/android/service/engine/src/org/opencv/engine3/manager/PackageListAdapter.java @@ -1,4 +1,4 @@ -package org.opencv.engine.manager; +package org.opencv.engine3.manager; import java.util.List; import java.util.Map; diff --git a/platforms/android/service/engine_test/AndroidManifest.xml b/platforms/android/service/engine_test/AndroidManifest.xml index 5779d90a62..5ee354225a 100644 --- a/platforms/android/service/engine_test/AndroidManifest.xml +++ b/platforms/android/service/engine_test/AndroidManifest.xml @@ -1,6 +1,6 @@ @@ -8,7 +8,7 @@ + android:targetPackage="org.opencv.engine3" /> - \ No newline at end of file + diff --git a/platforms/android/service/engine_test/src/org/opencv/engine/test/EngineInterfaceTest.java b/platforms/android/service/engine_test/src/org/opencv/engine3/test/EngineInterfaceTest.java similarity index 91% rename from platforms/android/service/engine_test/src/org/opencv/engine/test/EngineInterfaceTest.java rename to platforms/android/service/engine_test/src/org/opencv/engine3/test/EngineInterfaceTest.java index d67f22faf2..b45af98a37 100644 --- a/platforms/android/service/engine_test/src/org/opencv/engine/test/EngineInterfaceTest.java +++ b/platforms/android/service/engine_test/src/org/opencv/engine3/test/EngineInterfaceTest.java @@ -1,7 +1,7 @@ -package org.opencv.engine.test; +package org.opencv.engine3.test; -import org.opencv.engine.OpenCVEngineInterface; -import org.opencv.engine.OpenCVEngineService; +import org.opencv.engine3.OpenCVEngineInterface; +import org.opencv.engine3.OpenCVEngineService; import android.content.Intent; import android.os.IBinder; @@ -18,7 +18,7 @@ public class EngineInterfaceTest extends ServiceTestCase public void testVersion() throws RemoteException { - IBinder ServiceBinder = bindService(new Intent("org.opencv.engine.BIND")); + IBinder ServiceBinder = bindService(new Intent("org.opencv.engine3.BIND")); assertNotNull(ServiceBinder); OpenCVEngineInterface ServiceObj = OpenCVEngineInterface.Stub.asInterface(ServiceBinder); assertNotNull(ServiceObj); @@ -28,7 +28,7 @@ public class EngineInterfaceTest extends ServiceTestCase public void testInstallVersion() throws RemoteException { - IBinder ServiceBinder = bindService(new Intent("org.opencv.engine")); + IBinder ServiceBinder = bindService(new Intent("org.opencv.engine3")); assertNotNull(ServiceBinder); OpenCVEngineInterface ServiceObj = OpenCVEngineInterface.Stub.asInterface(ServiceBinder); assertNotNull(ServiceObj); @@ -37,7 +37,7 @@ public class EngineInterfaceTest extends ServiceTestCase public void testGetPathForExistVersion() throws RemoteException { - IBinder ServiceBinder = bindService(new Intent("org.opencv.engine")); + IBinder ServiceBinder = bindService(new Intent("org.opencv.engine3")); assertNotNull(ServiceBinder); OpenCVEngineInterface ServiceObj = OpenCVEngineInterface.Stub.asInterface(ServiceBinder); assertNotNull(ServiceObj); @@ -46,7 +46,7 @@ public class EngineInterfaceTest extends ServiceTestCase public void testGetPathForUnExistVersion() throws RemoteException { - IBinder ServiceBinder = bindService(new Intent("org.opencv.engine")); + IBinder ServiceBinder = bindService(new Intent("org.opencv.engine3")); assertNotNull(ServiceBinder); OpenCVEngineInterface ServiceObj = OpenCVEngineInterface.Stub.asInterface(ServiceBinder); assertNotNull(ServiceObj); @@ -55,7 +55,7 @@ public class EngineInterfaceTest extends ServiceTestCase public void testInstallAndGetVersion() throws RemoteException { - IBinder ServiceBinder = bindService(new Intent("org.opencv.engine")); + IBinder ServiceBinder = bindService(new Intent("org.opencv.engine3")); assertNotNull(ServiceBinder); OpenCVEngineInterface ServiceObj = OpenCVEngineInterface.Stub.asInterface(ServiceBinder); assertNotNull(ServiceObj); From a362aca7839aa2b9656897b4423e96f5dd255fe1 Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Fri, 17 Apr 2015 16:59:52 +0300 Subject: [PATCH 063/109] Rename manager package to OpenCV3 Manager --- .../java/generator/src/java/android+AsyncServiceHelper.java | 4 ++-- platforms/android/service/engine/build.xml | 2 +- platforms/android/service/engine/res/values/strings.xml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/java/generator/src/java/android+AsyncServiceHelper.java b/modules/java/generator/src/java/android+AsyncServiceHelper.java index 9fdf5ac1f9..9882d60b58 100644 --- a/modules/java/generator/src/java/android+AsyncServiceHelper.java +++ b/modules/java/generator/src/java/android+AsyncServiceHelper.java @@ -77,7 +77,7 @@ class AsyncServiceHelper private LoaderCallbackInterface mUserAppCallback = Callback; public String getPackageName() { - return "OpenCV Manager"; + return "OpenCV3 Manager"; } public void install() { Log.d(TAG, "Trying to install OpenCV Manager via Google Play"); @@ -123,7 +123,7 @@ class AsyncServiceHelper private LoaderCallbackInterface mUserAppCallback = Callback; public String getPackageName() { - return "OpenCV Manager"; + return "OpenCV3 Manager"; } public void install() { diff --git a/platforms/android/service/engine/build.xml b/platforms/android/service/engine/build.xml index 98ddc3eac1..47a283d8f4 100644 --- a/platforms/android/service/engine/build.xml +++ b/platforms/android/service/engine/build.xml @@ -1,5 +1,5 @@ - +