Merge pull request #1263 from abidrahmank:pyCLAHE_24
authorRoman Donchenko <roman.donchenko@itseez.com>
Wed, 14 Aug 2013 08:10:21 +0000 (12:10 +0400)
committerOpenCV Buildbot <buildbot@opencv.org>
Wed, 14 Aug 2013 08:10:22 +0000 (12:10 +0400)
471 files changed:
.gitignore
3rdparty/ffmpeg/ffmpeg_version.cmake
3rdparty/lib/armeabi-v7a/libnative_camera_r2.2.0.so
3rdparty/lib/armeabi-v7a/libnative_camera_r2.3.3.so
3rdparty/lib/armeabi-v7a/libnative_camera_r3.0.1.so
3rdparty/lib/armeabi-v7a/libnative_camera_r4.0.0.so
3rdparty/lib/armeabi-v7a/libnative_camera_r4.0.3.so
3rdparty/lib/armeabi-v7a/libnative_camera_r4.1.1.so
3rdparty/lib/armeabi-v7a/libnative_camera_r4.2.0.so
3rdparty/lib/armeabi-v7a/libnative_camera_r4.3.0.so [new file with mode: 0755]
3rdparty/lib/armeabi/libnative_camera_r2.2.0.so
3rdparty/lib/armeabi/libnative_camera_r2.3.3.so
3rdparty/lib/armeabi/libnative_camera_r3.0.1.so
3rdparty/lib/armeabi/libnative_camera_r4.0.0.so
3rdparty/lib/armeabi/libnative_camera_r4.0.3.so
3rdparty/lib/armeabi/libnative_camera_r4.1.1.so
3rdparty/lib/armeabi/libnative_camera_r4.2.0.so
3rdparty/lib/armeabi/libnative_camera_r4.3.0.so [new file with mode: 0755]
3rdparty/lib/mips/libnative_camera_r4.0.3.so
3rdparty/lib/mips/libnative_camera_r4.1.1.so
3rdparty/lib/mips/libnative_camera_r4.2.0.so
3rdparty/lib/mips/libnative_camera_r4.3.0.so [new file with mode: 0755]
3rdparty/lib/x86/libnative_camera_r2.3.3.so
3rdparty/lib/x86/libnative_camera_r3.0.1.so
3rdparty/lib/x86/libnative_camera_r4.0.3.so
3rdparty/lib/x86/libnative_camera_r4.1.1.so
3rdparty/lib/x86/libnative_camera_r4.2.0.so
3rdparty/lib/x86/libnative_camera_r4.3.0.so [new file with mode: 0755]
3rdparty/tbb/CMakeLists.txt
CMakeLists.txt
README [deleted file]
README.md [new file with mode: 0644]
android/android.toolchain.cmake [deleted file]
android/readme.txt [deleted file]
cmake/OpenCVCRTLinkage.cmake
cmake/OpenCVDetectCUDA.cmake
cmake/OpenCVDetectOpenCL.cmake
cmake/OpenCVDetectPython.cmake
cmake/OpenCVFindIPP.cmake
cmake/OpenCVFindLibsGUI.cmake
cmake/OpenCVFindLibsGrfmt.cmake
cmake/OpenCVFindLibsVideo.cmake
cmake/OpenCVGenHeaders.cmake
cmake/OpenCVGenPkgconfig.cmake
cmake/OpenCVModule.cmake
cmake/OpenCVPCHSupport.cmake
cmake/checks/winrttest.cpp [new file with mode: 0644]
cmake/templates/cvconfig.h.cmake
cmake/templates/opencv-XXX.pc.cmake.in
doc/CMakeLists.txt
doc/_themes/blue/layout.html
doc/conf.py
doc/tutorials/calib3d/camera_calibration/camera_calibration.rst
doc/tutorials/definitions/noContent.rst
doc/tutorials/features2d/feature_detection/feature_detection.rst
doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.rst
doc/tutorials/features2d/feature_homography/feature_homography.rst
doc/tutorials/gpu/gpu-basics-similarity/gpu-basics-similarity.rst
doc/tutorials/introduction/android_binary_package/O4A_SDK.rst
doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.rst
doc/tutorials/introduction/how_to_write_a_tutorial/how_to_write_a_tutorial.rst
doc/tutorials/introduction/ios_install/ios_install.rst
doc/tutorials/introduction/windows_install/windows_install.rst
doc/tutorials/introduction/windows_visual_studio_Opencv/images/PropertySheetOpenCVInclude.jpg
doc/tutorials/introduction/windows_visual_studio_Opencv/windows_visual_studio_Opencv.rst
doc/tutorials/ml/introduction_to_svm/introduction_to_svm.rst
ios/configure-device_xcode.sh [deleted file]
ios/configure-simulator_xcode.sh [deleted file]
ios/readme.txt [deleted file]
modules/androidcamera/camera_wrapper/camera_wrapper.cpp
modules/androidcamera/src/camera_activity.cpp
modules/calib3d/doc/camera_calibration_and_3d_reconstruction.rst
modules/calib3d/include/opencv2/calib3d/calib3d.hpp
modules/calib3d/perf/perf_precomp.cpp [deleted file]
modules/calib3d/src/precomp.cpp [deleted file]
modules/calib3d/src/precomp.hpp
modules/calib3d/test/test_precomp.cpp [deleted file]
modules/contrib/doc/facerec/facerec_api.rst
modules/contrib/doc/openfabmap.rst
modules/contrib/doc/retina/index.rst
modules/contrib/src/ba.cpp
modules/contrib/src/featuretracker.cpp
modules/contrib/src/inputoutput.cpp
modules/contrib/src/precomp.cpp [deleted file]
modules/contrib/src/precomp.hpp
modules/contrib/test/test_precomp.cpp [deleted file]
modules/core/CMakeLists.txt
modules/core/doc/basic_structures.rst
modules/core/doc/clustering.rst
modules/core/doc/core.rst
modules/core/doc/drawing_functions.rst
modules/core/doc/opengl_interop.rst [new file with mode: 0644]
modules/core/doc/operations_on_arrays.rst
modules/core/doc/utility_and_system_functions_and_macros.rst
modules/core/doc/xml_yaml_persistence.rst
modules/core/include/opencv2/core/core.hpp
modules/core/include/opencv2/core/internal.hpp
modules/core/include/opencv2/core/types_c.h
modules/core/include/opencv2/core/version.hpp
modules/core/perf/perf_precomp.cpp [deleted file]
modules/core/perf/perf_stat.cpp
modules/core/src/alloc.cpp
modules/core/src/drawing.cpp
modules/core/src/dxt.cpp
modules/core/src/glob.cpp
modules/core/src/matrix.cpp
modules/core/src/parallel.cpp
modules/core/src/persistence.cpp
modules/core/src/precomp.cpp [deleted file]
modules/core/src/precomp.hpp
modules/core/src/rand.cpp
modules/core/src/stat.cpp
modules/core/src/system.cpp
modules/core/test/test_arithm.cpp
modules/core/test/test_main.cpp
modules/core/test/test_precomp.cpp [deleted file]
modules/features2d/doc/common_interfaces_of_descriptor_extractors.rst
modules/features2d/doc/common_interfaces_of_descriptor_matchers.rst
modules/features2d/doc/common_interfaces_of_feature_detectors.rst
modules/features2d/doc/common_interfaces_of_generic_descriptor_matchers.rst
modules/features2d/doc/feature_detection_and_description.rst
modules/features2d/doc/object_categorization.rst
modules/features2d/include/opencv2/features2d/features2d.hpp
modules/features2d/perf/perf_precomp.cpp [deleted file]
modules/features2d/src/bagofwords.cpp
modules/features2d/src/brisk.cpp
modules/features2d/src/descriptors.cpp
modules/features2d/src/precomp.cpp [deleted file]
modules/features2d/src/precomp.hpp
modules/features2d/test/test_precomp.cpp [deleted file]
modules/flann/include/opencv2/flann/dist.h
modules/flann/src/precomp.cpp [deleted file]
modules/flann/src/precomp.hpp
modules/flann/test/test_precomp.cpp [deleted file]
modules/gpu/CMakeLists.txt
modules/gpu/doc/camera_calibration_and_3d_reconstruction.rst
modules/gpu/doc/image_filtering.rst
modules/gpu/doc/image_processing.rst
modules/gpu/doc/object_detection.rst
modules/gpu/doc/video.rst
modules/gpu/include/opencv2/gpu/device/limits.hpp
modules/gpu/perf/perf_imgproc.cpp
modules/gpu/perf/perf_main.cpp
modules/gpu/perf/perf_precomp.cpp [deleted file]
modules/gpu/perf4au/main.cpp
modules/gpu/src/cuda/hist.cu
modules/gpu/src/cuda/imgproc.cu
modules/gpu/src/cuda/safe_call.hpp
modules/gpu/src/error.cpp
modules/gpu/src/imgproc.cpp
modules/gpu/src/nvidia/core/NCV.hpp
modules/gpu/src/nvidia/core/NCVPixelOperations.hpp
modules/gpu/src/precomp.hpp
modules/gpu/test/test_imgproc.cpp
modules/gpu/test/test_precomp.cpp [deleted file]
modules/highgui/CMakeLists.txt
modules/highgui/doc/reading_and_writing_images_and_video.rst
modules/highgui/doc/user_interface.rst
modules/highgui/include/opencv2/highgui/cap_ios.h
modules/highgui/include/opencv2/highgui/highgui_c.h
modules/highgui/include/opencv2/highgui/ios.h [moved from modules/nonfree/src/precomp.cpp with 90% similarity]
modules/highgui/perf/perf_input.cpp
modules/highgui/perf/perf_output.cpp
modules/highgui/perf/perf_precomp.cpp [deleted file]
modules/highgui/perf/perf_precomp.hpp
modules/highgui/src/cap.cpp
modules/highgui/src/cap_dc1394_v2.cpp
modules/highgui/src/cap_dshow.cpp
modules/highgui/src/cap_ffmpeg.cpp
modules/highgui/src/cap_ffmpeg_impl.hpp
modules/highgui/src/cap_ios_abstract_camera.mm
modules/highgui/src/cap_ios_video_camera.mm
modules/highgui/src/cap_libv4l.cpp
modules/highgui/src/cap_msmf.cpp
modules/highgui/src/cap_v4l.cpp
modules/highgui/src/cap_vfw.cpp
modules/highgui/src/cap_ximea.cpp
modules/highgui/src/grfmt_jpeg2000.cpp
modules/highgui/src/grfmt_png.cpp
modules/highgui/src/ios_conversions.mm [new file with mode: 0644]
modules/highgui/src/precomp.cpp [deleted file]
modules/highgui/src/precomp.hpp
modules/highgui/src/window_QT.cpp
modules/highgui/src/window_QT.h
modules/highgui/test/test_precomp.cpp [deleted file]
modules/highgui/test/test_precomp.hpp
modules/highgui/test/test_video_io.cpp
modules/imgproc/doc/feature_detection.rst
modules/imgproc/doc/filtering.rst
modules/imgproc/doc/geometric_transformations.rst
modules/imgproc/doc/histograms.rst
modules/imgproc/doc/miscellaneous_transformations.rst
modules/imgproc/doc/object_detection.rst
modules/imgproc/doc/structural_analysis_and_shape_descriptors.rst
modules/imgproc/perf/perf_cvt_color.cpp
modules/imgproc/perf/perf_histogram.cpp
modules/imgproc/perf/perf_precomp.cpp [deleted file]
modules/imgproc/perf/perf_resize.cpp
modules/imgproc/perf/perf_threshold.cpp
modules/imgproc/src/color.cpp
modules/imgproc/src/distransform.cpp
modules/imgproc/src/histogram.cpp
modules/imgproc/src/morph.cpp
modules/imgproc/src/precomp.cpp [deleted file]
modules/imgproc/src/precomp.hpp
modules/imgproc/src/samplers.cpp
modules/imgproc/src/shapedescr.cpp
modules/imgproc/src/smooth.cpp
modules/imgproc/src/sumpixels.cpp
modules/imgproc/src/templmatch.cpp
modules/imgproc/test/test_precomp.cpp [deleted file]
modules/java/android_test/src/org/opencv/test/OpenCVTestRunner.java
modules/java/android_test/src/org/opencv/test/calib3d/Calib3dTest.java
modules/java/android_test/src/org/opencv/test/core/CoreTest.java
modules/java/generator/src/cpp/Mat.cpp
modules/java/generator/src/java/android+JavaCameraView.java
modules/java/generator/src/java/android+OpenCVLoader.java
modules/java/generator/src/java/core+Mat.java
modules/java/generator/src/java/core+MatOfByte.java
modules/java/generator/src/java/core+MatOfDMatch.java
modules/java/generator/src/java/core+MatOfDouble.java
modules/java/generator/src/java/core+MatOfFloat.java
modules/java/generator/src/java/core+MatOfFloat4.java
modules/java/generator/src/java/core+MatOfFloat6.java
modules/java/generator/src/java/core+MatOfInt.java
modules/java/generator/src/java/core+MatOfInt4.java
modules/java/generator/src/java/core+MatOfKeyPoint.java
modules/java/generator/src/java/core+MatOfPoint.java
modules/java/generator/src/java/core+MatOfPoint2f.java
modules/java/generator/src/java/core+MatOfPoint3.java
modules/java/generator/src/java/core+MatOfPoint3f.java
modules/java/generator/src/java/core+MatOfRect.java
modules/java/generator/src/java/highgui+VideoCapture.java
modules/legacy/doc/expectation_maximization.rst
modules/legacy/doc/feature_detection_and_description.rst
modules/legacy/src/precomp.cpp [deleted file]
modules/legacy/src/precomp.hpp
modules/legacy/test/test_precomp.cpp [deleted file]
modules/ml/doc/k_nearest_neighbors.rst
modules/ml/doc/support_vector_machines.rst
modules/ml/src/precomp.cpp [deleted file]
modules/ml/src/precomp.hpp
modules/ml/test/test_precomp.cpp [deleted file]
modules/nonfree/doc/feature_detection.rst
modules/nonfree/perf/perf_main.cpp
modules/nonfree/perf/perf_precomp.cpp [deleted file]
modules/nonfree/src/precomp.hpp
modules/nonfree/test/test_features2d.cpp
modules/nonfree/test/test_precomp.cpp [deleted file]
modules/objdetect/doc/cascade_classification.rst
modules/objdetect/include/opencv2/objdetect/objdetect.hpp
modules/objdetect/perf/perf_precomp.cpp [deleted file]
modules/objdetect/src/cascadedetect.cpp
modules/objdetect/src/hog.cpp
modules/objdetect/src/precomp.cpp [deleted file]
modules/objdetect/src/precomp.hpp
modules/objdetect/test/test_latentsvmdetector.cpp
modules/objdetect/test/test_precomp.cpp [deleted file]
modules/ocl/doc/feature_detection_and_description.rst
modules/ocl/doc/image_processing.rst
modules/ocl/doc/object_detection.rst
modules/ocl/doc/operations_on_matrices.rst
modules/ocl/include/opencv2/ocl/matrix_operations.hpp
modules/ocl/include/opencv2/ocl/ocl.hpp
modules/ocl/perf/main.cpp
modules/ocl/perf/perf_arithm.cpp
modules/ocl/perf/perf_blend.cpp
modules/ocl/perf/perf_brute_force_matcher.cpp
modules/ocl/perf/perf_calib3d.cpp [moved from modules/ocl/test/test_pyrup.cpp with 64% similarity]
modules/ocl/perf/perf_canny.cpp
modules/ocl/perf/perf_color.cpp
modules/ocl/perf/perf_fft.cpp
modules/ocl/perf/perf_filters.cpp
modules/ocl/perf/perf_gemm.cpp
modules/ocl/perf/perf_gftt.cpp [moved from modules/ocl/src/precomp.cpp with 53% similarity]
modules/ocl/perf/perf_haar.cpp
modules/ocl/perf/perf_hog.cpp
modules/ocl/perf/perf_imgproc.cpp
modules/ocl/perf/perf_match_template.cpp
modules/ocl/perf/perf_matrix_operation.cpp
modules/ocl/perf/perf_moments.cpp [moved from modules/ocl/perf/perf_columnsum.cpp with 67% similarity]
modules/ocl/perf/perf_norm.cpp
modules/ocl/perf/perf_opticalflow.cpp
modules/ocl/perf/perf_precomp.cpp [moved from modules/ocl/perf/precomp.cpp with 97% similarity]
modules/ocl/perf/perf_precomp.hpp [moved from modules/ocl/perf/precomp.hpp with 98% similarity]
modules/ocl/perf/perf_pyramid.cpp
modules/ocl/perf/perf_split_merge.cpp
modules/ocl/src/color.cpp
modules/ocl/src/gftt.cpp [moved from modules/ocl/src/gfft.cpp with 97% similarity]
modules/ocl/src/haar.cpp
modules/ocl/src/hog.cpp
modules/ocl/src/imgproc.cpp
modules/ocl/src/initialization.cpp
modules/ocl/src/kmeans.cpp [new file with mode: 0644]
modules/ocl/src/matrix_operations.cpp
modules/ocl/src/mcwutil.cpp
modules/ocl/src/moments.cpp
modules/ocl/src/opencl/imgproc_gftt.cl [moved from modules/ocl/src/opencl/imgproc_gfft.cl with 100% similarity]
modules/ocl/src/opencl/kernel_radix_sort_by_key.cl [new file with mode: 0644]
modules/ocl/src/opencl/kernel_sort_by_key.cl [new file with mode: 0644]
modules/ocl/src/opencl/kernel_stablesort_by_key.cl [new file with mode: 0644]
modules/ocl/src/opencl/kmeans_kernel.cl [moved from modules/ocl/test/test_columnsum.cpp with 67% similarity]
modules/ocl/src/opencl/moments.cl
modules/ocl/src/opencl/objdetect_hog.cl
modules/ocl/src/opencl/optical_flow_farneback.cl [new file with mode: 0644]
modules/ocl/src/opencl/pyrlk.cl
modules/ocl/src/opencl/stereobm.cl
modules/ocl/src/opencl/stereobp.cl
modules/ocl/src/optical_flow_farneback.cpp [new file with mode: 0644]
modules/ocl/src/precomp.hpp
modules/ocl/src/sort_by_key.cpp [new file with mode: 0644]
modules/ocl/src/stereobp.cpp
modules/ocl/test/main.cpp
modules/ocl/test/precomp.cpp [deleted file]
modules/ocl/test/test_arithm.cpp
modules/ocl/test/test_blend.cpp
modules/ocl/test/test_brute_force_matcher.cpp
modules/ocl/test/test_calib3d.cpp
modules/ocl/test/test_canny.cpp
modules/ocl/test/test_color.cpp
modules/ocl/test/test_fft.cpp
modules/ocl/test/test_filters.cpp
modules/ocl/test/test_gemm.cpp
modules/ocl/test/test_haar.cpp [deleted file]
modules/ocl/test/test_hog.cpp [deleted file]
modules/ocl/test/test_imgproc.cpp
modules/ocl/test/test_kmeans.cpp [new file with mode: 0644]
modules/ocl/test/test_match_template.cpp
modules/ocl/test/test_matrix_operation.cpp
modules/ocl/test/test_moments.cpp
modules/ocl/test/test_objdetect.cpp [new file with mode: 0644]
modules/ocl/test/test_optflow.cpp
modules/ocl/test/test_precomp.hpp [moved from modules/ocl/test/precomp.hpp with 100% similarity]
modules/ocl/test/test_pyramids.cpp [moved from modules/ocl/test/test_pyrdown.cpp with 75% similarity]
modules/ocl/test/test_sort.cpp [new file with mode: 0644]
modules/ocl/test/test_split_merge.cpp
modules/ocl/test/utility.cpp
modules/ocl/test/utility.hpp
modules/photo/doc/inpainting.rst
modules/photo/perf/perf_precomp.cpp [deleted file]
modules/photo/src/precomp.cpp [deleted file]
modules/photo/src/precomp.hpp
modules/photo/test/test_precomp.cpp [deleted file]
modules/python/src2/cv2.cpp
modules/python/src2/cv2.cv.hpp
modules/python/test/test.py
modules/stitching/doc/high_level.rst
modules/stitching/perf/perf_precomp.cpp [deleted file]
modules/stitching/src/precomp.cpp [deleted file]
modules/stitching/src/precomp.hpp
modules/stitching/test/test_precomp.cpp [deleted file]
modules/superres/CMakeLists.txt
modules/superres/include/opencv2/superres/optical_flow.hpp
modules/superres/include/opencv2/superres/superres.hpp
modules/superres/perf/perf_main.cpp
modules/superres/perf/perf_precomp.cpp [deleted file]
modules/superres/perf/perf_precomp.hpp
modules/superres/perf/perf_superres_ocl.cpp [new file with mode: 0644]
modules/superres/src/btv_l1_ocl.cpp [new file with mode: 0644]
modules/superres/src/frame_source.cpp
modules/superres/src/input_array_utility.cpp
modules/superres/src/input_array_utility.hpp
modules/superres/src/opencl/superres_btvl1.cl [new file with mode: 0644]
modules/superres/src/optical_flow.cpp
modules/superres/src/precomp.cpp [deleted file]
modules/superres/src/precomp.hpp
modules/superres/test/test_precomp.cpp [deleted file]
modules/superres/test/test_precomp.hpp
modules/superres/test/test_superres.cpp
modules/ts/CMakeLists.txt
modules/ts/include/opencv2/ts/ts.hpp
modules/ts/include/opencv2/ts/ts_gtest.h
modules/ts/include/opencv2/ts/ts_perf.hpp
modules/ts/misc/testlog_parser.py
modules/ts/misc/xls-report.py [new file with mode: 0755]
modules/ts/src/precomp.cpp [deleted file]
modules/ts/src/precomp.hpp
modules/ts/src/ts_func.cpp
modules/ts/src/ts_gtest.cpp
modules/ts/src/ts_perf.cpp
modules/video/doc/motion_analysis_and_object_tracking.rst
modules/video/perf/perf_precomp.cpp [deleted file]
modules/video/src/precomp.cpp [deleted file]
modules/video/src/precomp.hpp
modules/video/test/test_precomp.cpp [deleted file]
modules/videostab/src/precomp.cpp [deleted file]
modules/videostab/src/precomp.hpp
modules/world/src/precomp.cpp [deleted file]
modules/world/src/precomp.hpp
platforms/android/service/doc/BaseLoaderCallback.rst
platforms/android/service/doc/JavaHelper.rst
platforms/android/service/engine/AndroidManifest.xml
platforms/android/service/engine/jni/BinderComponent/OpenCVEngine.cpp
platforms/android/service/readme.txt
platforms/ios/Info.plist.in [moved from ios/Info.plist.in with 93% similarity]
platforms/ios/build_framework.py [moved from ios/build_framework.py with 95% similarity]
platforms/ios/cmake/Modules/Platform/iOS.cmake [moved from ios/cmake/Modules/Platform/iOS.cmake with 100% similarity]
platforms/ios/cmake/Toolchains/Toolchain-iPhoneOS_Xcode.cmake [moved from ios/cmake/Toolchains/Toolchain-iPhoneOS_Xcode.cmake with 80% similarity]
platforms/ios/cmake/Toolchains/Toolchain-iPhoneSimulator_Xcode.cmake [moved from ios/cmake/Toolchains/Toolchain-iPhoneSimulator_Xcode.cmake with 80% similarity]
platforms/ios/readme.txt [new file with mode: 0644]
platforms/readme.txt
platforms/scripts/ABI_compat_generator.py
platforms/scripts/camera_build.conf
platforms/scripts/cmake_winrt.cmd
samples/android/CMakeLists.txt
samples/android/camera-calibration/.classpath [new file with mode: 0644]
samples/android/camera-calibration/.project [new file with mode: 0644]
samples/android/camera-calibration/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
samples/android/camera-calibration/AndroidManifest.xml [new file with mode: 0644]
samples/android/camera-calibration/CMakeLists.txt [new file with mode: 0644]
samples/android/camera-calibration/res/drawable/icon.png [new file with mode: 0644]
samples/android/camera-calibration/res/layout/camera_calibration_surface_view.xml [new file with mode: 0644]
samples/android/camera-calibration/res/menu/calibration.xml [new file with mode: 0644]
samples/android/camera-calibration/res/values/strings.xml [new file with mode: 0644]
samples/android/camera-calibration/src/org/opencv/samples/cameracalibration/CalibrationResult.java [new file with mode: 0644]
samples/android/camera-calibration/src/org/opencv/samples/cameracalibration/CameraCalibrationActivity.java [new file with mode: 0644]
samples/android/camera-calibration/src/org/opencv/samples/cameracalibration/CameraCalibrator.java [new file with mode: 0644]
samples/android/camera-calibration/src/org/opencv/samples/cameracalibration/OnCameraFrameRender.java [new file with mode: 0644]
samples/android/native-activity/.cproject
samples/android/native-activity/AndroidManifest.xml
samples/android/native-activity/jni/Android.mk
samples/android/native-activity/jni/native.cpp
samples/cpp/freak_demo.cpp
samples/cpp/latentsvm_multidetect.cpp
samples/cpp/stereo_calib.cpp
samples/ocl/CMakeLists.txt
samples/ocl/clahe.cpp [new file with mode: 0644]
samples/ocl/facedetect.cpp
samples/ocl/hog.cpp
samples/ocl/pyrlk_optical_flow.cpp
samples/ocl/squares.cpp
samples/ocl/stereo_match.cpp
samples/ocl/surf_matcher.cpp
samples/ocl/tvl1_optical_flow.cpp [new file with mode: 0644]
samples/winrt/ImageManipulations/AdvancedCapture.xaml [new file with mode: 0644]
samples/winrt/ImageManipulations/AdvancedCapture.xaml.cpp [new file with mode: 0644]
samples/winrt/ImageManipulations/AdvancedCapture.xaml.h [new file with mode: 0644]
samples/winrt/ImageManipulations/App.xaml [new file with mode: 0644]
samples/winrt/ImageManipulations/App.xaml.cpp [new file with mode: 0644]
samples/winrt/ImageManipulations/App.xaml.h [new file with mode: 0644]
samples/winrt/ImageManipulations/Constants.cpp [new file with mode: 0644]
samples/winrt/ImageManipulations/Constants.h [new file with mode: 0644]
samples/winrt/ImageManipulations/MainPage.xaml [new file with mode: 0644]
samples/winrt/ImageManipulations/MainPage.xaml.cpp [new file with mode: 0644]
samples/winrt/ImageManipulations/MainPage.xaml.h [new file with mode: 0644]
samples/winrt/ImageManipulations/MediaCapture.sln [new file with mode: 0644]
samples/winrt/ImageManipulations/MediaCapture.vcxproj [new file with mode: 0644]
samples/winrt/ImageManipulations/MediaExtensions/Common/AsyncCB.h [new file with mode: 0644]
samples/winrt/ImageManipulations/MediaExtensions/Common/BufferLock.h [new file with mode: 0644]
samples/winrt/ImageManipulations/MediaExtensions/Common/CritSec.h [new file with mode: 0644]
samples/winrt/ImageManipulations/MediaExtensions/Common/LinkList.h [new file with mode: 0644]
samples/winrt/ImageManipulations/MediaExtensions/Common/OpQueue.h [new file with mode: 0644]
samples/winrt/ImageManipulations/MediaExtensions/OcvTransform/OcvImageManipulations.idl [new file with mode: 0644]
samples/winrt/ImageManipulations/MediaExtensions/OcvTransform/OcvTransform.cpp [new file with mode: 0644]
samples/winrt/ImageManipulations/MediaExtensions/OcvTransform/OcvTransform.def [new file with mode: 0644]
samples/winrt/ImageManipulations/MediaExtensions/OcvTransform/OcvTransform.h [new file with mode: 0644]
samples/winrt/ImageManipulations/MediaExtensions/OcvTransform/OcvTransform.vcxproj [new file with mode: 0644]
samples/winrt/ImageManipulations/MediaExtensions/OcvTransform/dllmain.cpp [new file with mode: 0644]
samples/winrt/ImageManipulations/Package.appxmanifest [new file with mode: 0644]
samples/winrt/ImageManipulations/assets/opencv-logo-150.png [new file with mode: 0644]
samples/winrt/ImageManipulations/assets/opencv-logo-30.png [new file with mode: 0644]
samples/winrt/ImageManipulations/assets/splash-sdk.png [new file with mode: 0644]
samples/winrt/ImageManipulations/assets/windows-sdk.png [new file with mode: 0644]
samples/winrt/ImageManipulations/common/LayoutAwarePage.cpp [new file with mode: 0644]
samples/winrt/ImageManipulations/common/LayoutAwarePage.h [new file with mode: 0644]
samples/winrt/ImageManipulations/common/StandardStyles.xaml [new file with mode: 0644]
samples/winrt/ImageManipulations/common/suspensionmanager.cpp [new file with mode: 0644]
samples/winrt/ImageManipulations/common/suspensionmanager.h [new file with mode: 0644]
samples/winrt/ImageManipulations/pch.cpp [new file with mode: 0644]
samples/winrt/ImageManipulations/pch.h [new file with mode: 0644]
samples/winrt/ImageManipulations/sample-utils/SampleTemplateStyles.xaml [new file with mode: 0644]

index 0a19f3c..4fd406e 100644 (file)
@@ -2,6 +2,7 @@
 .DS_Store
 refman.rst
 OpenCV4Tegra/
+tegra/
 *.user
 .sw[a-z]
 .*.swp
index 3f27077..e35e8c7 100644 (file)
@@ -1,4 +1,3 @@
-set(NEW_FFMPEG 1)
 set(HAVE_FFMPEG_CODEC 1)
 set(HAVE_FFMPEG_FORMAT 1)
 set(HAVE_FFMPEG_UTIL 1)
index f62e596..6f28f2c 100755 (executable)
Binary files a/3rdparty/lib/armeabi-v7a/libnative_camera_r2.2.0.so and b/3rdparty/lib/armeabi-v7a/libnative_camera_r2.2.0.so differ
index c0237c1..010641e 100755 (executable)
Binary files a/3rdparty/lib/armeabi-v7a/libnative_camera_r2.3.3.so and b/3rdparty/lib/armeabi-v7a/libnative_camera_r2.3.3.so differ
index 2c235d8..5a145b2 100755 (executable)
Binary files a/3rdparty/lib/armeabi-v7a/libnative_camera_r3.0.1.so and b/3rdparty/lib/armeabi-v7a/libnative_camera_r3.0.1.so differ
index 4872588..a524b74 100755 (executable)
Binary files a/3rdparty/lib/armeabi-v7a/libnative_camera_r4.0.0.so and b/3rdparty/lib/armeabi-v7a/libnative_camera_r4.0.0.so differ
index 169d97e..a1802f1 100755 (executable)
Binary files a/3rdparty/lib/armeabi-v7a/libnative_camera_r4.0.3.so and b/3rdparty/lib/armeabi-v7a/libnative_camera_r4.0.3.so differ
index bdd09fb..089c7e9 100755 (executable)
Binary files a/3rdparty/lib/armeabi-v7a/libnative_camera_r4.1.1.so and b/3rdparty/lib/armeabi-v7a/libnative_camera_r4.1.1.so differ
index 74bfdea..a9ffa4b 100755 (executable)
Binary files a/3rdparty/lib/armeabi-v7a/libnative_camera_r4.2.0.so and b/3rdparty/lib/armeabi-v7a/libnative_camera_r4.2.0.so differ
diff --git a/3rdparty/lib/armeabi-v7a/libnative_camera_r4.3.0.so b/3rdparty/lib/armeabi-v7a/libnative_camera_r4.3.0.so
new file mode 100755 (executable)
index 0000000..8ff7177
Binary files /dev/null and b/3rdparty/lib/armeabi-v7a/libnative_camera_r4.3.0.so differ
index 7c061d9..b6ce0d5 100755 (executable)
Binary files a/3rdparty/lib/armeabi/libnative_camera_r2.2.0.so and b/3rdparty/lib/armeabi/libnative_camera_r2.2.0.so differ
index 686bdfb..635ce68 100755 (executable)
Binary files a/3rdparty/lib/armeabi/libnative_camera_r2.3.3.so and b/3rdparty/lib/armeabi/libnative_camera_r2.3.3.so differ
index 5a5c231..caacf39 100755 (executable)
Binary files a/3rdparty/lib/armeabi/libnative_camera_r3.0.1.so and b/3rdparty/lib/armeabi/libnative_camera_r3.0.1.so differ
index 694cfb8..fff4a80 100755 (executable)
Binary files a/3rdparty/lib/armeabi/libnative_camera_r4.0.0.so and b/3rdparty/lib/armeabi/libnative_camera_r4.0.0.so differ
index c6cc8ab..3119265 100755 (executable)
Binary files a/3rdparty/lib/armeabi/libnative_camera_r4.0.3.so and b/3rdparty/lib/armeabi/libnative_camera_r4.0.3.so differ
index 94966c8..7c18baf 100755 (executable)
Binary files a/3rdparty/lib/armeabi/libnative_camera_r4.1.1.so and b/3rdparty/lib/armeabi/libnative_camera_r4.1.1.so differ
index 8251510..8bb093a 100755 (executable)
Binary files a/3rdparty/lib/armeabi/libnative_camera_r4.2.0.so and b/3rdparty/lib/armeabi/libnative_camera_r4.2.0.so differ
diff --git a/3rdparty/lib/armeabi/libnative_camera_r4.3.0.so b/3rdparty/lib/armeabi/libnative_camera_r4.3.0.so
new file mode 100755 (executable)
index 0000000..a05f179
Binary files /dev/null and b/3rdparty/lib/armeabi/libnative_camera_r4.3.0.so differ
index c8c9e2c..b950044 100755 (executable)
Binary files a/3rdparty/lib/mips/libnative_camera_r4.0.3.so and b/3rdparty/lib/mips/libnative_camera_r4.0.3.so differ
index 6845d71..d11dcf0 100755 (executable)
Binary files a/3rdparty/lib/mips/libnative_camera_r4.1.1.so and b/3rdparty/lib/mips/libnative_camera_r4.1.1.so differ
index b148d16..b06a681 100755 (executable)
Binary files a/3rdparty/lib/mips/libnative_camera_r4.2.0.so and b/3rdparty/lib/mips/libnative_camera_r4.2.0.so differ
diff --git a/3rdparty/lib/mips/libnative_camera_r4.3.0.so b/3rdparty/lib/mips/libnative_camera_r4.3.0.so
new file mode 100755 (executable)
index 0000000..844b806
Binary files /dev/null and b/3rdparty/lib/mips/libnative_camera_r4.3.0.so differ
index d940063..0dd8904 100755 (executable)
Binary files a/3rdparty/lib/x86/libnative_camera_r2.3.3.so and b/3rdparty/lib/x86/libnative_camera_r2.3.3.so differ
index cf2e990..105a19d 100755 (executable)
Binary files a/3rdparty/lib/x86/libnative_camera_r3.0.1.so and b/3rdparty/lib/x86/libnative_camera_r3.0.1.so differ
index 420ec81..b01a4bd 100755 (executable)
Binary files a/3rdparty/lib/x86/libnative_camera_r4.0.3.so and b/3rdparty/lib/x86/libnative_camera_r4.0.3.so differ
index 5468d20..a59ae39 100755 (executable)
Binary files a/3rdparty/lib/x86/libnative_camera_r4.1.1.so and b/3rdparty/lib/x86/libnative_camera_r4.1.1.so differ
index 9923310..b90b826 100755 (executable)
Binary files a/3rdparty/lib/x86/libnative_camera_r4.2.0.so and b/3rdparty/lib/x86/libnative_camera_r4.2.0.so differ
diff --git a/3rdparty/lib/x86/libnative_camera_r4.3.0.so b/3rdparty/lib/x86/libnative_camera_r4.3.0.so
new file mode 100755 (executable)
index 0000000..6607e5d
Binary files /dev/null and b/3rdparty/lib/x86/libnative_camera_r4.3.0.so differ
index af15813..c728440 100644 (file)
@@ -1,12 +1,39 @@
 #Cross compile TBB from source
 project(tbb)
 
+if (WIN32 AND NOT ARM)
+  message(FATAL_ERROR "BUILD_TBB option supports Windows on ARM only!\nUse regular official TBB build instead of the BUILD_TBB option!")
+endif()
+
+if (WIN32 AND ARM)
+  # 4.1 update 4 - The first release that supports Windows RT. Hangs on some Android devices
+  set(tbb_ver "tbb41_20130613oss")
+  set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb41_20130613oss_src.tgz")
+  set(tbb_md5 "108c8c1e481b0aaea61878289eb28b6a")
+  set(tbb_version_file "version_string.ver")
+  ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4702)
+else()
+  # 4.1 update 2 - works fine
+  set(tbb_ver "tbb41_20130116oss")
+  set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb41_20130116oss_src.tgz")
+  set(tbb_md5 "3809790e1001a1b32d59c9fee590ee85")
+  set(tbb_version_file "version_string.ver")
+  ocv_warnings_disable(CMAKE_CXX_FLAGS -Wshadow)
+endif()
+
+# 4.1 update 3 dev - Hangs on some Android devices
+#set(tbb_ver "tbb41_20130401oss")
+#set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb41_20130401oss_src.tgz")
+#set(tbb_md5 "f2f591a0d2ca8f801e221ce7d9ea84bb")
+#set(tbb_version_file "version_string.ver")
+#ocv_warnings_disable(CMAKE_CXX_FLAGS -Wshadow)
+
 # 4.1 update 2 - works fine
-set(tbb_ver "tbb41_20130116oss")
-set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb41_20130116oss_src.tgz")
-set(tbb_md5 "3809790e1001a1b32d59c9fee590ee85")
-set(tbb_version_file "version_string.ver")
-ocv_warnings_disable(CMAKE_CXX_FLAGS -Wshadow)
+#set(tbb_ver "tbb41_20130116oss")
+#set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb41_20130116oss_src.tgz")
+#set(tbb_md5 "3809790e1001a1b32d59c9fee590ee85")
+#set(tbb_version_file "version_string.ver")
+#ocv_warnings_disable(CMAKE_CXX_FLAGS -Wshadow)
 
 # 4.1 update 1 - works fine
 #set(tbb_ver "tbb41_20121003oss")
@@ -107,7 +134,7 @@ if(NOT EXISTS "${tbb_src_dir}")
               RESULT_VARIABLE tbb_untar_RESULT)
 
   if(NOT tbb_untar_RESULT EQUAL 0 OR NOT EXISTS "${tbb_src_dir}")
-    message(FATAL_ERROR "Failed to unpack TBB sources")
+    message(FATAL_ERROR "Failed to unpack TBB sources from ${tbb_tarball} to ${tbb_src_dir} with error ${tbb_untar_RESULT}")
   endif()
 endif()
 
@@ -123,13 +150,22 @@ file(GLOB lib_hdrs "${tbb_src_dir}/src/tbb/*.h")
 list(APPEND lib_srcs "${tbb_src_dir}/src/rml/client/rml_tbb.cpp")
 
 if (WIN32)
-  add_definitions(-D__TBB_DYNAMIC_LOAD_ENABLED=0
-                -D__TBB_BUILD=1
-                -D_UNICODE
-                -DUNICODE
-                -DWINAPI_FAMILY=WINAPI_FAMILY_APP
-                -DDO_ITT_NOTIFY=0
+  add_definitions(/D__TBB_DYNAMIC_LOAD_ENABLED=0
+                  /D__TBB_BUILD=1
+                  /DTBB_NO_LEGACY=1
+                  /D_UNICODE
+                  /DUNICODE
+                  /DWINAPI_FAMILY=WINAPI_FAMILY_APP
+                  /DDO_ITT_NOTIFY=0
+                  /DUSE_WINTHREAD
                ) # defines were copied from windows.cl.inc
+
+  if (ARM)
+    add_definitions(/D_WIN32_WINNT=0x0602
+                    /D__TBB_WIN32_USE_CL_BUILTINS
+                   )
+  endif()
+
 set(CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} /APPCONTAINER")
 else()
   add_definitions(-D__TBB_DYNAMIC_LOAD_ENABLED=0         #required
@@ -173,15 +209,38 @@ endif()
 set(TBB_SOURCE_FILES ${TBB_SOURCE_FILES} "${CMAKE_CURRENT_SOURCE_DIR}/${tbb_version_file}")
 
 add_library(tbb ${TBB_SOURCE_FILES})
-target_link_libraries(tbb c m dl)
+
+if (WIN32)
+  if (ARM)
+    set(platform_macro /D_M_ARM=1)
+  endif()
+
+  add_custom_command(TARGET tbb
+                     PRE_BUILD
+                     COMMAND ${CMAKE_C_COMPILER} /nologo /TC /EP ${tbb_src_dir}\\src\\tbb\\win32-tbb-export.def /DTBB_NO_LEGACY=1 /D_CRT_SECURE_NO_DEPRECATE /D__TBB_BUILD=1 ${platform_macro} /I${tbb_src_dir}\\src /I${tbb_src_dir}\\include > "${tbb_src_dir}\\src\\tbb\\tbb.def"
+                     WORKING_DIRECTORY ${tbb_src_dir}\\src\\tbb
+                     COMMENT "Generating tbb.def file" VERBATIM
+                    )
+
+  set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DEF:${tbb_src_dir}/src/tbb/tbb.def /DLL /MAP /fixed:no /INCREMENTAL:NO")
+else()
+  target_link_libraries(tbb c m dl)
+endif()
 
 ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef -Wmissing-declarations)
 string(REPLACE "-Werror=non-virtual-dtor" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
 
+if (WIN32)
+  set(tbb_debug_postfix "_debug") # to fit pragmas in _windef.h inside TBB
+else()
+  set(tbb_debug_postfix ${OPENCV_DEBUG_POSTFIX})
+endif()
+
 set_target_properties(tbb
   PROPERTIES OUTPUT_NAME tbb
-  DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
+  DEBUG_POSTFIX "${tbb_debug_postfix}"
   ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH}
+  RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
   )
 
 if(ENABLE_SOLUTION_FOLDERS)
index f464b22..46881c4 100644 (file)
@@ -212,7 +212,7 @@ OCV_OPTION(ENABLE_SSE42               "Enable SSE4.2 instructions"
 OCV_OPTION(ENABLE_AVX                 "Enable AVX instructions"                                  OFF  IF ((MSVC OR CMAKE_COMPILER_IS_GNUCXX) AND (X86 OR X86_64)) )
 OCV_OPTION(ENABLE_NOISY_WARNINGS      "Show all warnings even if they are too noisy"             OFF )
 OCV_OPTION(OPENCV_WARNINGS_ARE_ERRORS "Treat warnings as errors"                                 OFF )
-
+OCV_OPTION(ENABLE_WINRT_MODE          "Build with Windows Runtime support"                       OFF  IF WIN32 )
 
 # uncategorized options
 # ===================================================
@@ -296,7 +296,6 @@ endif()
 #  Path for build/platform -specific headers
 # ----------------------------------------------------------------------------
 set(OPENCV_CONFIG_FILE_INCLUDE_DIR "${CMAKE_BINARY_DIR}/" CACHE PATH "Where to create the platform-dependant cvconfig.h")
-add_definitions(-DHAVE_CVCONFIG_H)
 ocv_include_directories(${OPENCV_CONFIG_FILE_INCLUDE_DIR})
 
 # ----------------------------------------------------------------------------
@@ -370,9 +369,6 @@ if(UNIX)
   include(CheckIncludeFile)
 
   if(NOT APPLE)
-    CHECK_INCLUDE_FILE(alloca.h HAVE_ALLOCA_H)
-    CHECK_FUNCTION_EXISTS(alloca HAVE_ALLOCA)
-    CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H)
     CHECK_INCLUDE_FILE(pthread.h HAVE_LIBPTHREAD)
     if(ANDROID)
       set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} dl m log)
@@ -382,7 +378,7 @@ if(UNIX)
       set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} dl m pthread rt)
     endif()
   else()
-    add_definitions(-DHAVE_ALLOCA -DHAVE_ALLOCA_H -DHAVE_LIBPTHREAD -DHAVE_UNISTD_H)
+    set(HAVE_LIBPTHREAD YES)
   endif()
 endif()
 
@@ -607,6 +603,16 @@ if(ANDROID)
   status("    Android examples:"    BUILD_ANDROID_EXAMPLES AND CAN_BUILD_ANDROID_PROJECTS         THEN YES ELSE NO)
 endif()
 
+# ================== Windows RT features ==================
+if(WIN32)
+status("")
+    status("  Windows RT support:" HAVE_WINRT THEN YES ELSE NO)
+    if (ENABLE_WINRT_MODE)
+      status("    Windows SDK v8.0:" ${WINDOWS_SDK_PATH})
+      status("    Visual Studio 2012:" ${VISUAL_STUDIO_PATH})
+    endif()
+endif(WIN32)
+
 # ========================== GUI ==========================
 status("")
 status("  GUI: ")
diff --git a/README b/README
deleted file mode 100644 (file)
index 0799dff..0000000
--- a/README
+++ /dev/null
@@ -1,17 +0,0 @@
-OpenCV: open source computer vision library
-
-Homepage:    http://opencv.org
-Online docs: http://docs.opencv.org
-Q&A forum:   http://answers.opencv.org
-Dev zone:    http://code.opencv.org
-
-Please read before starting work on a pull request:
-  http://code.opencv.org/projects/opencv/wiki/How_to_contribute
-
-Summary of guidelines:
-
-* One pull request per issue;
-* Choose the right base branch;
-* Include tests and documentation;
-* Clean up "oops" commits before submitting;
-* Follow the coding style guide.
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..403f118
--- /dev/null
+++ b/README.md
@@ -0,0 +1,23 @@
+### OpenCV: Open Source Computer Vision Library
+
+#### Resources
+
+* Homepage: <http://opencv.org>
+* Docs: <http://docs.opencv.org>
+* Q&A forum: <http://answers.opencv.org>
+* Issue tracking: <http://code.opencv.org>
+
+#### Contributing
+
+Please read before starting work on a pull request: <http://code.opencv.org/projects/opencv/wiki/How_to_contribute>
+
+Summary of guidelines:
+
+* One pull request per issue;
+* Choose the right base branch;
+* Include tests and documentation;
+* Clean up "oops" commits before submitting;
+* Follow the coding style guide.
+
+[![Donate OpenCV project](http://opencv.org/wp-content/uploads/2013/07/gittip1.png)](https://www.gittip.com/OpenCV/)
+[![Donate OpenCV project](http://opencv.org/wp-content/uploads/2013/07/paypal-donate-button.png)](https://www.paypal.com/cgi-bin/webscr?item_name=Donation+to+OpenCV&cmd=_donations&business=accountant%40opencv.org)
\ No newline at end of file
diff --git a/android/android.toolchain.cmake b/android/android.toolchain.cmake
deleted file mode 100644 (file)
index 9db174a..0000000
+++ /dev/null
@@ -1,1747 +0,0 @@
-message(STATUS "Android toolchain was moved to platfroms/android!")
-message(STATUS "This file is depricated and will be removed!")
-
-# Copyright (c) 2010-2011, Ethan Rublee
-# Copyright (c) 2011-2013, Andrey Kamaev
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-# 1.  Redistributions of source code must retain the above copyright notice,
-#     this list of conditions and the following disclaimer.
-#
-# 2.  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.
-#
-# 3.  The name of the copyright holders 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 HOLDER 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.
-
-# ------------------------------------------------------------------------------
-#  Android CMake toolchain file, for use with the Android NDK r5-r8
-#  Requires cmake 2.6.3 or newer (2.8.5 or newer is recommended).
-#  See home page: https://github.com/taka-no-me/android-cmake
-#
-#  The file is mantained by the OpenCV project. The latest version can be get at
-#  http://code.opencv.org/projects/opencv/repository/revisions/master/changes/android/android.toolchain.cmake
-#
-#  Usage Linux:
-#   $ export ANDROID_NDK=/absolute/path/to/the/android-ndk
-#   $ mkdir build && cd build
-#   $ cmake -DCMAKE_TOOLCHAIN_FILE=path/to/the/android.toolchain.cmake ..
-#   $ make -j8
-#
-#  Usage Linux (using standalone toolchain):
-#   $ export ANDROID_STANDALONE_TOOLCHAIN=/absolute/path/to/android-toolchain
-#   $ mkdir build && cd build
-#   $ cmake -DCMAKE_TOOLCHAIN_FILE=path/to/the/android.toolchain.cmake ..
-#   $ make -j8
-#
-#  Usage Windows:
-#     You need native port of make to build your project.
-#     Android NDK r7 (or newer) already has make.exe on board.
-#     For older NDK you have to install it separately.
-#     For example, this one: http://gnuwin32.sourceforge.net/packages/make.htm
-#
-#   $ SET ANDROID_NDK=C:\absolute\path\to\the\android-ndk
-#   $ mkdir build && cd build
-#   $ cmake.exe -G"MinGW Makefiles"
-#       -DCMAKE_TOOLCHAIN_FILE=path\to\the\android.toolchain.cmake
-#       -DCMAKE_MAKE_PROGRAM="%ANDROID_NDK%\prebuilt\windows\bin\make.exe" ..
-#   $ cmake.exe --build .
-#
-#
-#  Options (can be set as cmake parameters: -D<option_name>=<value>):
-#    ANDROID_NDK=/opt/android-ndk - path to the NDK root.
-#      Can be set as environment variable. Can be set only at first cmake run.
-#
-#    ANDROID_STANDALONE_TOOLCHAIN=/opt/android-toolchain - path to the
-#      standalone toolchain. This option is not used if full NDK is found
-#      (ignored if ANDROID_NDK is set).
-#      Can be set as environment variable. Can be set only at first cmake run.
-#
-#    ANDROID_ABI=armeabi-v7a - specifies the target Application Binary
-#      Interface (ABI). This option nearly matches to the APP_ABI variable
-#      used by ndk-build tool from Android NDK.
-#
-#      Possible targets are:
-#        "armeabi" - matches to the NDK ABI with the same name.
-#           See ${ANDROID_NDK}/docs/CPU-ARCH-ABIS.html for the documentation.
-#        "armeabi-v7a" - matches to the NDK ABI with the same name.
-#           See ${ANDROID_NDK}/docs/CPU-ARCH-ABIS.html for the documentation.
-#        "armeabi-v7a with NEON" - same as armeabi-v7a, but
-#            sets NEON as floating-point unit
-#        "armeabi-v7a with VFPV3" - same as armeabi-v7a, but
-#            sets VFPV3 as floating-point unit (has 32 registers instead of 16).
-#        "armeabi-v6 with VFP" - tuned for ARMv6 processors having VFP.
-#        "x86" - matches to the NDK ABI with the same name.
-#            See ${ANDROID_NDK}/docs/CPU-ARCH-ABIS.html for the documentation.
-#        "mips" - matches to the NDK ABI with the same name
-#            (It is not tested on real devices by the authos of this toolchain)
-#            See ${ANDROID_NDK}/docs/CPU-ARCH-ABIS.html for the documentation.
-#
-#    ANDROID_NATIVE_API_LEVEL=android-8 - level of Android API compile for.
-#      Option is read-only when standalone toolchain is used.
-#
-#    ANDROID_TOOLCHAIN_NAME=arm-linux-androideabi-4.6 - the name of compiler
-#      toolchain to be used. The list of possible values depends on the NDK
-#      version. For NDK r8c the possible values are:
-#
-#        * arm-linux-androideabi-4.4.3
-#        * arm-linux-androideabi-4.6
-#        * arm-linux-androideabi-clang3.1
-#        * mipsel-linux-android-4.4.3
-#        * mipsel-linux-android-4.6
-#        * mipsel-linux-android-clang3.1
-#        * x86-4.4.3
-#        * x86-4.6
-#        * x86-clang3.1
-#
-#    ANDROID_FORCE_ARM_BUILD=OFF - set ON to generate 32-bit ARM instructions
-#      instead of Thumb. Is not available for "x86" (inapplicable) and
-#      "armeabi-v6 with VFP" (is forced to be ON) ABIs.
-#
-#    ANDROID_NO_UNDEFINED=ON - set ON to show all undefined symbols as linker
-#      errors even if they are not used.
-#
-#    ANDROID_SO_UNDEFINED=OFF - set ON to allow undefined symbols in shared
-#      libraries. Automatically turned for NDK r5x and r6x due to GLESv2
-#      problems.
-#
-#    LIBRARY_OUTPUT_PATH_ROOT=${CMAKE_SOURCE_DIR} - where to output binary
-#      files. See additional details below.
-#
-#    ANDROID_SET_OBSOLETE_VARIABLES=ON - if set, then toolchain defines some
-#      obsolete variables which were used by previous versions of this file for
-#      backward compatibility.
-#
-#    ANDROID_STL=gnustl_static - specify the runtime to use.
-#
-#      Possible values are:
-#        none           -> Do not configure the runtime.
-#        system         -> Use the default minimal system C++ runtime library.
-#                          Implies -fno-rtti -fno-exceptions.
-#                          Is not available for standalone toolchain.
-#        system_re      -> Use the default minimal system C++ runtime library.
-#                          Implies -frtti -fexceptions.
-#                          Is not available for standalone toolchain.
-#        gabi++_static  -> Use the GAbi++ runtime as a static library.
-#                          Implies -frtti -fno-exceptions.
-#                          Available for NDK r7 and newer.
-#                          Is not available for standalone toolchain.
-#        gabi++_shared  -> Use the GAbi++ runtime as a shared library.
-#                          Implies -frtti -fno-exceptions.
-#                          Available for NDK r7 and newer.
-#                          Is not available for standalone toolchain.
-#        stlport_static -> Use the STLport runtime as a static library.
-#                          Implies -fno-rtti -fno-exceptions for NDK before r7.
-#                          Implies -frtti -fno-exceptions for NDK r7 and newer.
-#                          Is not available for standalone toolchain.
-#        stlport_shared -> Use the STLport runtime as a shared library.
-#                          Implies -fno-rtti -fno-exceptions for NDK before r7.
-#                          Implies -frtti -fno-exceptions for NDK r7 and newer.
-#                          Is not available for standalone toolchain.
-#        gnustl_static  -> Use the GNU STL as a static library.
-#                          Implies -frtti -fexceptions.
-#        gnustl_shared  -> Use the GNU STL as a shared library.
-#                          Implies -frtti -fno-exceptions.
-#                          Available for NDK r7b and newer.
-#                          Silently degrades to gnustl_static if not available.
-#
-#    ANDROID_STL_FORCE_FEATURES=ON - turn rtti and exceptions support based on
-#      chosen runtime. If disabled, then the user is responsible for settings
-#      these options.
-#
-#  What?:
-#    android-cmake toolchain searches for NDK/toolchain in the following order:
-#      ANDROID_NDK - cmake parameter
-#      ANDROID_NDK - environment variable
-#      ANDROID_STANDALONE_TOOLCHAIN - cmake parameter
-#      ANDROID_STANDALONE_TOOLCHAIN - environment variable
-#      ANDROID_NDK - default locations
-#      ANDROID_STANDALONE_TOOLCHAIN - default locations
-#
-#    Make sure to do the following in your scripts:
-#      SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${my_cxx_flags}" )
-#      SET( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${my_cxx_flags}" )
-#    The flags will be prepopulated with critical flags, so don't loose them.
-#    Also be aware that toolchain also sets configuration-specific compiler
-#    flags and linker flags.
-#
-#    ANDROID and BUILD_ANDROID will be set to true, you may test any of these
-#    variables to make necessary Android-specific configuration changes.
-#
-#    Also ARMEABI or ARMEABI_V7A or X86 or MIPS will be set true, mutually
-#    exclusive. NEON option will be set true if VFP is set to NEON.
-#
-#    LIBRARY_OUTPUT_PATH_ROOT should be set in cache to determine where Android
-#    libraries will be installed.
-#    Default is ${CMAKE_SOURCE_DIR}, and the android libs will always be
-#    under the ${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}
-#    (depending on the target ABI). This is convenient for Android packaging.
-#
-#  Change Log:
-#   - initial version December 2010
-#   - April 2011
-#     [+] added possibility to build with NDK (without standalone toolchain)
-#     [+] support cross-compilation on Windows (native, no cygwin support)
-#     [+] added compiler option to force "char" type to be signed
-#     [+] added toolchain option to compile to 32-bit ARM instructions
-#     [+] added toolchain option to disable SWIG search
-#     [+] added platform "armeabi-v7a with VFPV3"
-#     [~] ARM_TARGETS renamed to ARM_TARGET
-#     [+] EXECUTABLE_OUTPUT_PATH is set by toolchain (required on Windows)
-#     [~] Fixed bug with ANDROID_API_LEVEL variable
-#     [~] turn off SWIG search if it is not found first time
-#   - May 2011
-#     [~] ANDROID_LEVEL is renamed to ANDROID_API_LEVEL
-#     [+] ANDROID_API_LEVEL is detected by toolchain if not specified
-#     [~] added guard to prevent changing of output directories on the first
-#         cmake pass
-#     [~] toolchain exits with error if ARM_TARGET is not recognized
-#   - June 2011
-#     [~] default NDK path is updated for version r5c
-#     [+] variable CMAKE_SYSTEM_PROCESSOR is set based on ARM_TARGET
-#     [~] toolchain install directory is added to linker paths
-#     [-] removed SWIG-related stuff from toolchain
-#     [+] added macro find_host_package, find_host_program to search
-#         packages/programs on the host system
-#     [~] fixed path to STL library
-#   - July 2011
-#     [~] fixed options caching
-#     [~] search for all supported NDK versions
-#     [~] allowed spaces in NDK path
-#   - September 2011
-#     [~] updated for NDK r6b
-#   - November 2011
-#     [*] rewritten for NDK r7
-#     [+] x86 toolchain support (experimental)
-#     [+] added "armeabi-v6 with VFP" ABI for ARMv6 processors.
-#     [~] improved compiler and linker flags management
-#     [+] support different build flags for Release and Debug configurations
-#     [~] by default compiler flags the same as used by ndk-build (but only
-#         where reasonable)
-#     [~] ANDROID_NDK_TOOLCHAIN_ROOT is splitted to ANDROID_STANDALONE_TOOLCHAIN
-#         and ANDROID_TOOLCHAIN_ROOT
-#     [~] ARM_TARGET is renamed to ANDROID_ABI
-#     [~] ARMEABI_NDK_NAME is renamed to ANDROID_NDK_ABI_NAME
-#     [~] ANDROID_API_LEVEL is renamed to ANDROID_NATIVE_API_LEVEL
-#   - January 2012
-#     [+] added stlport_static support (experimental)
-#     [+] added special check for cygwin
-#     [+] filtered out hidden files (starting with .) while globbing inside NDK
-#     [+] automatically applied GLESv2 linkage fix for NDK revisions 5-6
-#     [+] added ANDROID_GET_ABI_RAWNAME to get NDK ABI names by CMake flags
-#   - February 2012
-#     [+] updated for NDK r7b
-#     [~] fixed cmake try_compile() command
-#     [~] Fix for missing install_name_tool on OS X
-#   - March 2012
-#     [~] fixed incorrect C compiler flags
-#     [~] fixed CMAKE_SYSTEM_PROCESSOR change on ANDROID_ABI change
-#     [+] improved toolchain loading speed
-#     [+] added assembler language support (.S)
-#     [+] allowed preset search paths and extra search suffixes
-#   - April 2012
-#     [+] updated for NDK r7c
-#     [~] fixed most of problems with compiler/linker flags and caching
-#     [+] added option ANDROID_FUNCTION_LEVEL_LINKING
-#   - May 2012
-#     [+] updated for NDK r8
-#     [+] added mips architecture support
-#   - August 2012
-#     [+] updated for NDK r8b
-#     [~] all intermediate files generated by toolchain are moved to CMakeFiles
-#     [~] libstdc++ and libsupc are removed from explicit link libraries
-#     [+] added CCache support (via NDK_CCACHE environment or cmake variable)
-#     [+] added gold linker support for NDK r8b
-#     [~] fixed mips linker flags for NDK r8b
-#   - September 2012
-#     [+] added NDK release name detection (see ANDROID_NDK_RELEASE)
-#     [+] added support for all C++ runtimes from NDK
-#         (system, gabi++, stlport, gnustl)
-#     [+] improved warnings on known issues of NDKs
-#     [~] use gold linker as default if available (NDK r8b)
-#     [~] globally turned off rpath
-#     [~] compiler options are aligned with NDK r8b
-#   - October 2012
-#     [~] fixed C++ linking: explicitly link with math library (OpenCV #2426)
-#   - November 2012
-#     [+] updated for NDK r8c
-#     [+] added support for clang compiler
-#   - December 2012
-#     [+] suppress warning about unused CMAKE_TOOLCHAIN_FILE variable
-#     [+] adjust API level to closest compatible as NDK does
-#     [~] fixed ccache full path search
-#     [+] updated for NDK r8d
-#     [~] compiler options are aligned with NDK r8d
-#   - March 2013
-#     [+] updated for NDK r8e (x86 version)
-#     [+] support x86_64 version of NDK
-#   - April 2013
-#     [+] support non-release NDK layouts (from Linaro git and Android git)
-#     [~] automatically detect if explicit link to crtbegin_*.o is needed
-# ------------------------------------------------------------------------------
-
-cmake_minimum_required( VERSION 2.6.3 )
-
-if( DEFINED CMAKE_CROSSCOMPILING )
- # subsequent toolchain loading is not really needed
- return()
-endif()
-
-if( CMAKE_TOOLCHAIN_FILE )
- # touch toolchain variable only to suppress "unused variable" warning
-endif()
-
-get_property( _CMAKE_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE )
-if( _CMAKE_IN_TRY_COMPILE )
- include( "${CMAKE_CURRENT_SOURCE_DIR}/../android.toolchain.config.cmake" OPTIONAL )
-endif()
-
-# this one is important
-set( CMAKE_SYSTEM_NAME Linux )
-# this one not so much
-set( CMAKE_SYSTEM_VERSION 1 )
-
-# rpath makes low sence for Android
-set( CMAKE_SKIP_RPATH TRUE CACHE BOOL "If set, runtime paths are not added when using shared libraries." )
-
-set( ANDROID_SUPPORTED_NDK_VERSIONS ${ANDROID_EXTRA_NDK_VERSIONS} -r8e -r8d -r8c -r8b -r8 -r7c -r7b -r7 -r6b -r6 -r5c -r5b -r5 "" )
-if(NOT DEFINED ANDROID_NDK_SEARCH_PATHS)
- if( CMAKE_HOST_WIN32 )
-  file( TO_CMAKE_PATH "$ENV{PROGRAMFILES}" ANDROID_NDK_SEARCH_PATHS )
-  set( ANDROID_NDK_SEARCH_PATHS "${ANDROID_NDK_SEARCH_PATHS}/android-ndk" "$ENV{SystemDrive}/NVPACK/android-ndk" )
- else()
-  file( TO_CMAKE_PATH "$ENV{HOME}" ANDROID_NDK_SEARCH_PATHS )
-  set( ANDROID_NDK_SEARCH_PATHS /opt/android-ndk "${ANDROID_NDK_SEARCH_PATHS}/NVPACK/android-ndk" )
- endif()
-endif()
-if(NOT DEFINED ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH)
- set( ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH /opt/android-toolchain )
-endif()
-
-set( ANDROID_SUPPORTED_ABIS_arm "armeabi-v7a;armeabi;armeabi-v7a with NEON;armeabi-v7a with VFPV3;armeabi-v6 with VFP" )
-set( ANDROID_SUPPORTED_ABIS_x86 "x86" )
-set( ANDROID_SUPPORTED_ABIS_mipsel "mips" )
-
-set( ANDROID_DEFAULT_NDK_API_LEVEL 8 )
-set( ANDROID_DEFAULT_NDK_API_LEVEL_x86 9 )
-set( ANDROID_DEFAULT_NDK_API_LEVEL_mips 9 )
-
-
-macro( __LIST_FILTER listvar regex )
- if( ${listvar} )
-  foreach( __val ${${listvar}} )
-   if( __val MATCHES "${regex}" )
-    list( REMOVE_ITEM ${listvar} "${__val}" )
-   endif()
-  endforeach()
- endif()
-endmacro()
-
-macro( __INIT_VARIABLE var_name )
- set( __test_path 0 )
- foreach( __var ${ARGN} )
-  if( __var STREQUAL "PATH" )
-   set( __test_path 1 )
-   break()
-  endif()
- endforeach()
- if( __test_path AND NOT EXISTS "${${var_name}}" )
-  unset( ${var_name} CACHE )
- endif()
- if( "${${var_name}}" STREQUAL "" )
-  set( __values 0 )
-  foreach( __var ${ARGN} )
-   if( __var STREQUAL "VALUES" )
-    set( __values 1 )
-   elseif( NOT __var STREQUAL "PATH" )
-    set( __obsolete 0 )
-    if( __var MATCHES "^OBSOLETE_.*$" )
-     string( REPLACE "OBSOLETE_" "" __var "${__var}" )
-     set( __obsolete 1 )
-    endif()
-    if( __var MATCHES "^ENV_.*$" )
-     string( REPLACE "ENV_" "" __var "${__var}" )
-     set( __value "$ENV{${__var}}" )
-    elseif( DEFINED ${__var} )
-     set( __value "${${__var}}" )
-    else()
-     if( __values )
-      set( __value "${__var}" )
-     else()
-      set( __value "" )
-     endif()
-    endif()
-    if( NOT "${__value}" STREQUAL "" )
-     if( __test_path )
-      if( EXISTS "${__value}" )
-       file( TO_CMAKE_PATH "${__value}" ${var_name} )
-       if( __obsolete AND NOT _CMAKE_IN_TRY_COMPILE )
-        message( WARNING "Using value of obsolete variable ${__var} as initial value for ${var_name}. Please note, that ${__var} can be completely removed in future versions of the toolchain." )
-       endif()
-       break()
-      endif()
-     else()
-      set( ${var_name} "${__value}" )
-       if( __obsolete AND NOT _CMAKE_IN_TRY_COMPILE )
-        message( WARNING "Using value of obsolete variable ${__var} as initial value for ${var_name}. Please note, that ${__var} can be completely removed in future versions of the toolchain." )
-       endif()
-      break()
-     endif()
-    endif()
-   endif()
-  endforeach()
-  unset( __value )
-  unset( __values )
-  unset( __obsolete )
- elseif( __test_path )
-  file( TO_CMAKE_PATH "${${var_name}}" ${var_name} )
- endif()
- unset( __test_path )
-endmacro()
-
-macro( __DETECT_NATIVE_API_LEVEL _var _path )
- SET( __ndkApiLevelRegex "^[\t ]*#define[\t ]+__ANDROID_API__[\t ]+([0-9]+)[\t ]*$" )
- FILE( STRINGS ${_path} __apiFileContent REGEX "${__ndkApiLevelRegex}" )
- if( NOT __apiFileContent )
-  message( SEND_ERROR "Could not get Android native API level. Probably you have specified invalid level value, or your copy of NDK/toolchain is broken." )
- endif()
- string( REGEX REPLACE "${__ndkApiLevelRegex}" "\\1" ${_var} "${__apiFileContent}" )
- unset( __apiFileContent )
- unset( __ndkApiLevelRegex )
-endmacro()
-
-macro( __DETECT_TOOLCHAIN_MACHINE_NAME _var _root )
- if( EXISTS "${_root}" )
-  file( GLOB __gccExePath RELATIVE "${_root}/bin/" "${_root}/bin/*-gcc${TOOL_OS_SUFFIX}" )
-  __LIST_FILTER( __gccExePath "^[.].*" )
-  list( LENGTH __gccExePath __gccExePathsCount )
-  if( NOT __gccExePathsCount EQUAL 1  AND NOT _CMAKE_IN_TRY_COMPILE )
-   message( WARNING "Could not determine machine name for compiler from ${_root}" )
-   set( ${_var} "" )
-  else()
-   get_filename_component( __gccExeName "${__gccExePath}" NAME_WE )
-   string( REPLACE "-gcc" "" ${_var} "${__gccExeName}" )
-  endif()
-  unset( __gccExePath )
-  unset( __gccExePathsCount )
-  unset( __gccExeName )
- else()
-  set( ${_var} "" )
- endif()
-endmacro()
-
-
-# fight against cygwin
-set( ANDROID_FORBID_SYGWIN TRUE CACHE BOOL "Prevent cmake from working under cygwin and using cygwin tools")
-mark_as_advanced( ANDROID_FORBID_SYGWIN )
-if( ANDROID_FORBID_SYGWIN )
- if( CYGWIN )
-  message( FATAL_ERROR "Android NDK and android-cmake toolchain are not welcome Cygwin. It is unlikely that this cmake toolchain will work under cygwin. But if you want to try then you can set cmake variable ANDROID_FORBID_SYGWIN to FALSE and rerun cmake." )
- endif()
-
- if( CMAKE_HOST_WIN32 )
-  # remove cygwin from PATH
-  set( __new_path "$ENV{PATH}")
-  __LIST_FILTER( __new_path "cygwin" )
-  set(ENV{PATH} "${__new_path}")
-  unset(__new_path)
- endif()
-endif()
-
-
-# detect current host platform
-if( NOT DEFINED ANDROID_NDK_HOST_X64 AND CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "amd64|x86_64|AMD64")
- set( ANDROID_NDK_HOST_X64 1 CACHE BOOL "Try to use 64-bit compiler toolchain" )
- mark_as_advanced( ANDROID_NDK_HOST_X64 )
-endif()
-
-set( TOOL_OS_SUFFIX "" )
-if( CMAKE_HOST_APPLE )
- set( ANDROID_NDK_HOST_SYSTEM_NAME "darwin-x86_64" )
- set( ANDROID_NDK_HOST_SYSTEM_NAME2 "darwin-x86" )
-elseif( CMAKE_HOST_WIN32 )
- set( ANDROID_NDK_HOST_SYSTEM_NAME "windows-x86_64" )
- set( ANDROID_NDK_HOST_SYSTEM_NAME2 "windows" )
- set( TOOL_OS_SUFFIX ".exe" )
-elseif( CMAKE_HOST_UNIX )
- set( ANDROID_NDK_HOST_SYSTEM_NAME "linux-x86_64" )
- set( ANDROID_NDK_HOST_SYSTEM_NAME2 "linux-x86" )
-else()
- message( FATAL_ERROR "Cross-compilation on your platform is not supported by this cmake toolchain" )
-endif()
-
-if( NOT ANDROID_NDK_HOST_X64 )
- set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} )
-endif()
-
-# see if we have path to Android NDK
-__INIT_VARIABLE( ANDROID_NDK PATH ENV_ANDROID_NDK )
-if( NOT ANDROID_NDK )
- # see if we have path to Android standalone toolchain
- __INIT_VARIABLE( ANDROID_STANDALONE_TOOLCHAIN PATH ENV_ANDROID_STANDALONE_TOOLCHAIN OBSOLETE_ANDROID_NDK_TOOLCHAIN_ROOT OBSOLETE_ENV_ANDROID_NDK_TOOLCHAIN_ROOT )
-
- if( NOT ANDROID_STANDALONE_TOOLCHAIN )
-  #try to find Android NDK in one of the the default locations
-  set( __ndkSearchPaths )
-  foreach( __ndkSearchPath ${ANDROID_NDK_SEARCH_PATHS} )
-   foreach( suffix ${ANDROID_SUPPORTED_NDK_VERSIONS} )
-    list( APPEND __ndkSearchPaths "${__ndkSearchPath}${suffix}" )
-   endforeach()
-  endforeach()
-  __INIT_VARIABLE( ANDROID_NDK PATH VALUES ${__ndkSearchPaths} )
-  unset( __ndkSearchPaths )
-
-  if( ANDROID_NDK )
-   message( STATUS "Using default path for Android NDK: ${ANDROID_NDK}" )
-   message( STATUS "  If you prefer to use a different location, please define a cmake or environment variable: ANDROID_NDK" )
-  else()
-   #try to find Android standalone toolchain in one of the the default locations
-   __INIT_VARIABLE( ANDROID_STANDALONE_TOOLCHAIN PATH ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH )
-
-   if( ANDROID_STANDALONE_TOOLCHAIN )
-    message( STATUS "Using default path for standalone toolchain ${ANDROID_STANDALONE_TOOLCHAIN}" )
-    message( STATUS "  If you prefer to use a different location, please define the variable: ANDROID_STANDALONE_TOOLCHAIN" )
-   endif( ANDROID_STANDALONE_TOOLCHAIN )
-  endif( ANDROID_NDK )
- endif( NOT ANDROID_STANDALONE_TOOLCHAIN )
-endif( NOT ANDROID_NDK )
-
-# remember found paths
-if( ANDROID_NDK )
- get_filename_component( ANDROID_NDK "${ANDROID_NDK}" ABSOLUTE )
- set( ANDROID_NDK "${ANDROID_NDK}" CACHE INTERNAL "Path of the Android NDK" FORCE )
- set( BUILD_WITH_ANDROID_NDK True )
- if( EXISTS "${ANDROID_NDK}/RELEASE.TXT" )
-  file( STRINGS "${ANDROID_NDK}/RELEASE.TXT" ANDROID_NDK_RELEASE_FULL LIMIT_COUNT 1 REGEX r[0-9]+[a-z]? )
-  string( REGEX MATCH r[0-9]+[a-z]? ANDROID_NDK_RELEASE "${ANDROID_NDK_RELEASE_FULL}" )
- else()
-  set( ANDROID_NDK_RELEASE "r1x" )
-  set( ANDROID_NDK_RELEASE_FULL "unreleased" )
- endif()
-elseif( ANDROID_STANDALONE_TOOLCHAIN )
- get_filename_component( ANDROID_STANDALONE_TOOLCHAIN "${ANDROID_STANDALONE_TOOLCHAIN}" ABSOLUTE )
- # try to detect change
- if( CMAKE_AR )
-  string( LENGTH "${ANDROID_STANDALONE_TOOLCHAIN}" __length )
-  string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidStandaloneToolchainPreviousPath )
-  if( NOT __androidStandaloneToolchainPreviousPath STREQUAL ANDROID_STANDALONE_TOOLCHAIN )
-   message( FATAL_ERROR "It is not possible to change path to the Android standalone toolchain on subsequent run." )
-  endif()
-  unset( __androidStandaloneToolchainPreviousPath )
-  unset( __length )
- endif()
- set( ANDROID_STANDALONE_TOOLCHAIN "${ANDROID_STANDALONE_TOOLCHAIN}" CACHE INTERNAL "Path of the Android standalone toolchain" FORCE )
- set( BUILD_WITH_STANDALONE_TOOLCHAIN True )
-else()
- list(GET ANDROID_NDK_SEARCH_PATHS 0 ANDROID_NDK_SEARCH_PATH)
- message( FATAL_ERROR "Could not find neither Android NDK nor Android standalone toolchain.
-    You should either set an environment variable:
-      export ANDROID_NDK=~/my-android-ndk
-    or
-      export ANDROID_STANDALONE_TOOLCHAIN=~/my-android-toolchain
-    or put the toolchain or NDK in the default path:
-      sudo ln -s ~/my-android-ndk ${ANDROID_NDK_SEARCH_PATH}
-      sudo ln -s ~/my-android-toolchain ${ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH}" )
-endif()
-
-# android NDK layout
-if( BUILD_WITH_ANDROID_NDK )
- if( NOT DEFINED ANDROID_NDK_LAYOUT )
-  # try to automatically detect the layout
-  if( EXISTS "${ANDROID_NDK}/RELEASE.TXT")
-   set( ANDROID_NDK_LAYOUT "RELEASE" )
-  elseif( EXISTS "${ANDROID_NDK}/../../linux-x86/toolchain/" )
-   set( ANDROID_NDK_LAYOUT "LINARO" )
-  elseif( EXISTS "${ANDROID_NDK}/../../gcc/" )
-   set( ANDROID_NDK_LAYOUT "ANDROID" )
-  endif()
- endif()
- set( ANDROID_NDK_LAYOUT "${ANDROID_NDK_LAYOUT}" CACHE STRING "The inner layout of NDK" )
- mark_as_advanced( ANDROID_NDK_LAYOUT )
- if( ANDROID_NDK_LAYOUT STREQUAL "LINARO" )
-  set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) # only 32-bit at the moment
-  set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/../../${ANDROID_NDK_HOST_SYSTEM_NAME}/toolchain" )
-  set( ANDROID_NDK_TOOLCHAINS_SUBPATH  "" )
-  set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "" )
- elseif( ANDROID_NDK_LAYOUT STREQUAL "ANDROID" )
-  set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) # only 32-bit at the moment
-  set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/../../gcc/${ANDROID_NDK_HOST_SYSTEM_NAME}/arm" )
-  set( ANDROID_NDK_TOOLCHAINS_SUBPATH  "" )
-  set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "" )
- else() # ANDROID_NDK_LAYOUT STREQUAL "RELEASE"
-  set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/toolchains" )
-  set( ANDROID_NDK_TOOLCHAINS_SUBPATH  "/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" )
-  set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME2}" )
- endif()
- get_filename_component( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK_TOOLCHAINS_PATH}" ABSOLUTE )
-
- # try to detect change of NDK
- if( CMAKE_AR )
-  string( LENGTH "${ANDROID_NDK_TOOLCHAINS_PATH}" __length )
-  string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidNdkPreviousPath )
-  if( NOT __androidNdkPreviousPath STREQUAL ANDROID_NDK_TOOLCHAINS_PATH )
-   message( FATAL_ERROR "It is not possible to change the path to the NDK on subsequent CMake run. You must remove all generated files from your build folder first.
-   " )
-  endif()
-  unset( __androidNdkPreviousPath )
-  unset( __length )
- endif()
-endif()
-
-
-# get all the details about standalone toolchain
-if( BUILD_WITH_STANDALONE_TOOLCHAIN )
- __DETECT_NATIVE_API_LEVEL( ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot/usr/include/android/api-level.h" )
- set( ANDROID_STANDALONE_TOOLCHAIN_API_LEVEL ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} )
- set( __availableToolchains "standalone" )
- __DETECT_TOOLCHAIN_MACHINE_NAME( __availableToolchainMachines "${ANDROID_STANDALONE_TOOLCHAIN}" )
- if( NOT __availableToolchainMachines )
-  message( FATAL_ERROR "Could not determine machine name of your toolchain. Probably your Android standalone toolchain is broken." )
- endif()
- if( __availableToolchainMachines MATCHES i686 )
-  set( __availableToolchainArchs "x86" )
- elseif( __availableToolchainMachines MATCHES arm )
-  set( __availableToolchainArchs "arm" )
- elseif( __availableToolchainMachines MATCHES mipsel )
-  set( __availableToolchainArchs "mipsel" )
- endif()
- execute_process( COMMAND "${ANDROID_STANDALONE_TOOLCHAIN}/bin/${__availableToolchainMachines}-gcc${TOOL_OS_SUFFIX}" -dumpversion
-                  OUTPUT_VARIABLE __availableToolchainCompilerVersions OUTPUT_STRIP_TRAILING_WHITESPACE )
- string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9]+)?" __availableToolchainCompilerVersions "${__availableToolchainCompilerVersions}" )
- if( EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/bin/clang${TOOL_OS_SUFFIX}" )
-  list( APPEND __availableToolchains "standalone-clang" )
-  list( APPEND __availableToolchainMachines ${__availableToolchainMachines} )
-  list( APPEND __availableToolchainArchs ${__availableToolchainArchs} )
-  list( APPEND __availableToolchainCompilerVersions ${__availableToolchainCompilerVersions} )
- endif()
-endif()
-
-macro( __GLOB_NDK_TOOLCHAINS __availableToolchainsVar __availableToolchainsLst __toolchain_subpath )
- foreach( __toolchain ${${__availableToolchainsLst}} )
-  if( "${__toolchain}" MATCHES "-clang3[.][0-9]$" AND NOT EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/${__toolchain}${__toolchain_subpath}" )
-   string( REGEX REPLACE "-clang3[.][0-9]$" "-4.6" __gcc_toolchain "${__toolchain}" )
-  else()
-   set( __gcc_toolchain "${__toolchain}" )
-  endif()
-  __DETECT_TOOLCHAIN_MACHINE_NAME( __machine "${ANDROID_NDK_TOOLCHAINS_PATH}/${__gcc_toolchain}${__toolchain_subpath}" )
-  if( __machine )
-   string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9x]+)?$" __version "${__gcc_toolchain}" )
-   if( __machine MATCHES i686 )
-    set( __arch "x86" )
-   elseif( __machine MATCHES arm )
-    set( __arch "arm" )
-   elseif( __machine MATCHES mipsel )
-    set( __arch "mipsel" )
-   endif()
-   list( APPEND __availableToolchainMachines "${__machine}" )
-   list( APPEND __availableToolchainArchs "${__arch}" )
-   list( APPEND __availableToolchainCompilerVersions "${__version}" )
-   list( APPEND ${__availableToolchainsVar} "${__toolchain}" )
-  endif()
-  unset( __gcc_toolchain )
- endforeach()
-endmacro()
-
-# get all the details about NDK
-if( BUILD_WITH_ANDROID_NDK )
- file( GLOB ANDROID_SUPPORTED_NATIVE_API_LEVELS RELATIVE "${ANDROID_NDK}/platforms" "${ANDROID_NDK}/platforms/android-*" )
- string( REPLACE "android-" "" ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_SUPPORTED_NATIVE_API_LEVELS}" )
- set( __availableToolchains "" )
- set( __availableToolchainMachines "" )
- set( __availableToolchainArchs "" )
- set( __availableToolchainCompilerVersions "" )
- if( ANDROID_TOOLCHAIN_NAME AND EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_TOOLCHAIN_NAME}/" )
-  # do not go through all toolchains if we know the name
-  set( __availableToolchainsLst "${ANDROID_TOOLCHAIN_NAME}" )
-  __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH}" )
-  if( NOT __availableToolchains AND NOT ANDROID_NDK_TOOLCHAINS_SUBPATH STREQUAL ANDROID_NDK_TOOLCHAINS_SUBPATH2 )
-   __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH2}" )
-   if( __availableToolchains )
-    set( ANDROID_NDK_TOOLCHAINS_SUBPATH ${ANDROID_NDK_TOOLCHAINS_SUBPATH2} )
-   endif()
-  endif()
- endif()
- if( NOT __availableToolchains )
-  file( GLOB __availableToolchainsLst RELATIVE "${ANDROID_NDK_TOOLCHAINS_PATH}" "${ANDROID_NDK_TOOLCHAINS_PATH}/*" )
-  if( __availableToolchains )
-   list(SORT __availableToolchainsLst) # we need clang to go after gcc
-  endif()
-  __LIST_FILTER( __availableToolchainsLst "^[.]" )
-  __LIST_FILTER( __availableToolchainsLst "llvm" )
-  __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH}" )
-  if( NOT __availableToolchains AND NOT ANDROID_NDK_TOOLCHAINS_SUBPATH STREQUAL ANDROID_NDK_TOOLCHAINS_SUBPATH2 )
-   __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH2}" )
-   if( __availableToolchains )
-    set( ANDROID_NDK_TOOLCHAINS_SUBPATH ${ANDROID_NDK_TOOLCHAINS_SUBPATH2} )
-   endif()
-  endif()
- endif()
- if( NOT __availableToolchains )
-  message( FATAL_ERROR "Could not find any working toolchain in the NDK. Probably your Android NDK is broken." )
- endif()
-endif()
-
-# build list of available ABIs
-set( ANDROID_SUPPORTED_ABIS "" )
-set( __uniqToolchainArchNames ${__availableToolchainArchs} )
-list( REMOVE_DUPLICATES __uniqToolchainArchNames )
-list( SORT __uniqToolchainArchNames )
-foreach( __arch ${__uniqToolchainArchNames} )
- list( APPEND ANDROID_SUPPORTED_ABIS ${ANDROID_SUPPORTED_ABIS_${__arch}} )
-endforeach()
-unset( __uniqToolchainArchNames )
-if( NOT ANDROID_SUPPORTED_ABIS )
- message( FATAL_ERROR "No one of known Android ABIs is supported by this cmake toolchain." )
-endif()
-
-# choose target ABI
-__INIT_VARIABLE( ANDROID_ABI OBSOLETE_ARM_TARGET OBSOLETE_ARM_TARGETS VALUES ${ANDROID_SUPPORTED_ABIS} )
-# verify that target ABI is supported
-list( FIND ANDROID_SUPPORTED_ABIS "${ANDROID_ABI}" __androidAbiIdx )
-if( __androidAbiIdx EQUAL -1 )
- string( REPLACE ";" "\", \"", PRINTABLE_ANDROID_SUPPORTED_ABIS  "${ANDROID_SUPPORTED_ABIS}" )
- message( FATAL_ERROR "Specified ANDROID_ABI = \"${ANDROID_ABI}\" is not supported by this cmake toolchain or your NDK/toolchain.
-   Supported values are: \"${PRINTABLE_ANDROID_SUPPORTED_ABIS}\"
-   " )
-endif()
-unset( __androidAbiIdx )
-
-# set target ABI options
-if( ANDROID_ABI STREQUAL "x86" )
- set( X86 true )
- set( ANDROID_NDK_ABI_NAME "x86" )
- set( ANDROID_ARCH_NAME "x86" )
- set( ANDROID_ARCH_FULLNAME "x86" )
- set( ANDROID_LLVM_TRIPLE "i686-none-linux-android" )
- set( CMAKE_SYSTEM_PROCESSOR "i686" )
-elseif( ANDROID_ABI STREQUAL "mips" )
- set( MIPS true )
- set( ANDROID_NDK_ABI_NAME "mips" )
- set( ANDROID_ARCH_NAME "mips" )
- set( ANDROID_ARCH_FULLNAME "mipsel" )
- set( ANDROID_LLVM_TRIPLE "mipsel-none-linux-android" )
- set( CMAKE_SYSTEM_PROCESSOR "mips" )
-elseif( ANDROID_ABI STREQUAL "armeabi" )
- set( ARMEABI true )
- set( ANDROID_NDK_ABI_NAME "armeabi" )
- set( ANDROID_ARCH_NAME "arm" )
- set( ANDROID_ARCH_FULLNAME "arm" )
- set( ANDROID_LLVM_TRIPLE "armv5te-none-linux-androideabi" )
- set( CMAKE_SYSTEM_PROCESSOR "armv5te" )
-elseif( ANDROID_ABI STREQUAL "armeabi-v6 with VFP" )
- set( ARMEABI_V6 true )
- set( ANDROID_NDK_ABI_NAME "armeabi" )
- set( ANDROID_ARCH_NAME "arm" )
- set( ANDROID_ARCH_FULLNAME "arm" )
- set( ANDROID_LLVM_TRIPLE "armv5te-none-linux-androideabi" )
- set( CMAKE_SYSTEM_PROCESSOR "armv6" )
- # need always fallback to older platform
- set( ARMEABI true )
-elseif( ANDROID_ABI STREQUAL "armeabi-v7a")
- set( ARMEABI_V7A true )
- set( ANDROID_NDK_ABI_NAME "armeabi-v7a" )
- set( ANDROID_ARCH_NAME "arm" )
- set( ANDROID_ARCH_FULLNAME "arm" )
- set( ANDROID_LLVM_TRIPLE "armv7-none-linux-androideabi" )
- set( CMAKE_SYSTEM_PROCESSOR "armv7-a" )
-elseif( ANDROID_ABI STREQUAL "armeabi-v7a with VFPV3" )
- set( ARMEABI_V7A true )
- set( ANDROID_NDK_ABI_NAME "armeabi-v7a" )
- set( ANDROID_ARCH_NAME "arm" )
- set( ANDROID_ARCH_FULLNAME "arm" )
- set( ANDROID_LLVM_TRIPLE "armv7-none-linux-androideabi" )
- set( CMAKE_SYSTEM_PROCESSOR "armv7-a" )
- set( VFPV3 true )
-elseif( ANDROID_ABI STREQUAL "armeabi-v7a with NEON" )
- set( ARMEABI_V7A true )
- set( ANDROID_NDK_ABI_NAME "armeabi-v7a" )
- set( ANDROID_ARCH_NAME "arm" )
- set( ANDROID_ARCH_FULLNAME "arm" )
- set( ANDROID_LLVM_TRIPLE "armv7-none-linux-androideabi" )
- set( CMAKE_SYSTEM_PROCESSOR "armv7-a" )
- set( VFPV3 true )
- set( NEON true )
-else()
- message( SEND_ERROR "Unknown ANDROID_ABI=\"${ANDROID_ABI}\" is specified." )
-endif()
-
-if( CMAKE_BINARY_DIR AND EXISTS "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeSystem.cmake" )
- # really dirty hack
- # it is not possible to change CMAKE_SYSTEM_PROCESSOR after the first run...
- file( APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeSystem.cmake" "SET(CMAKE_SYSTEM_PROCESSOR \"${CMAKE_SYSTEM_PROCESSOR}\")\n" )
-endif()
-
-if( ANDROID_ARCH_NAME STREQUAL "arm" AND NOT ARMEABI_V6 )
- __INIT_VARIABLE( ANDROID_FORCE_ARM_BUILD OBSOLETE_FORCE_ARM VALUES OFF )
- set( ANDROID_FORCE_ARM_BUILD ${ANDROID_FORCE_ARM_BUILD} CACHE BOOL "Use 32-bit ARM instructions instead of Thumb-1" FORCE )
- mark_as_advanced( ANDROID_FORCE_ARM_BUILD )
-else()
- unset( ANDROID_FORCE_ARM_BUILD CACHE )
-endif()
-
-# choose toolchain
-if( ANDROID_TOOLCHAIN_NAME )
- list( FIND __availableToolchains "${ANDROID_TOOLCHAIN_NAME}" __toolchainIdx )
- if( __toolchainIdx EQUAL -1 )
-  list( SORT __availableToolchains )
-  string( REPLACE ";" "\n  * " toolchains_list "${__availableToolchains}" )
-  set( toolchains_list "  * ${toolchains_list}")
-  message( FATAL_ERROR "Specified toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is missing in your NDK or broken. Please verify that your NDK is working or select another compiler toolchain.
-To configure the toolchain set CMake variable ANDROID_TOOLCHAIN_NAME to one of the following values:\n${toolchains_list}\n" )
- endif()
- list( GET __availableToolchainArchs ${__toolchainIdx} __toolchainArch )
- if( NOT __toolchainArch STREQUAL ANDROID_ARCH_FULLNAME )
-  message( SEND_ERROR "Selected toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is not able to compile binaries for the \"${ANDROID_ARCH_NAME}\" platform." )
- endif()
-else()
- set( __toolchainIdx -1 )
- set( __applicableToolchains "" )
- set( __toolchainMaxVersion "0.0.0" )
- list( LENGTH __availableToolchains __availableToolchainsCount )
- math( EXPR __availableToolchainsCount "${__availableToolchainsCount}-1" )
- foreach( __idx RANGE ${__availableToolchainsCount} )
-  list( GET __availableToolchainArchs ${__idx} __toolchainArch )
-  if( __toolchainArch STREQUAL ANDROID_ARCH_FULLNAME )
-   list( GET __availableToolchainCompilerVersions ${__idx} __toolchainVersion )
-   string( REPLACE "x" "99" __toolchainVersion "${__toolchainVersion}")
-   if( __toolchainVersion VERSION_GREATER __toolchainMaxVersion )
-    set( __toolchainMaxVersion "${__toolchainVersion}" )
-    set( __toolchainIdx ${__idx} )
-   endif()
-  endif()
- endforeach()
- unset( __availableToolchainsCount )
- unset( __toolchainMaxVersion )
- unset( __toolchainVersion )
-endif()
-unset( __toolchainArch )
-if( __toolchainIdx EQUAL -1 )
- message( FATAL_ERROR "No one of available compiler toolchains is able to compile for ${ANDROID_ARCH_NAME} platform." )
-endif()
-list( GET __availableToolchains ${__toolchainIdx} ANDROID_TOOLCHAIN_NAME )
-list( GET __availableToolchainMachines ${__toolchainIdx} ANDROID_TOOLCHAIN_MACHINE_NAME )
-list( GET __availableToolchainCompilerVersions ${__toolchainIdx} ANDROID_COMPILER_VERSION )
-
-unset( __toolchainIdx )
-unset( __availableToolchains )
-unset( __availableToolchainMachines )
-unset( __availableToolchainArchs )
-unset( __availableToolchainCompilerVersions )
-
-# choose native API level
-__INIT_VARIABLE( ANDROID_NATIVE_API_LEVEL ENV_ANDROID_NATIVE_API_LEVEL ANDROID_API_LEVEL ENV_ANDROID_API_LEVEL ANDROID_STANDALONE_TOOLCHAIN_API_LEVEL ANDROID_DEFAULT_NDK_API_LEVEL_${ANDROID_ARCH_NAME} ANDROID_DEFAULT_NDK_API_LEVEL )
-string( REGEX MATCH "[0-9]+" ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" )
-# adjust API level
-set( __real_api_level ${ANDROID_DEFAULT_NDK_API_LEVEL_${ANDROID_ARCH_NAME}} )
-foreach( __level ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} )
- if( NOT __level GREATER ANDROID_NATIVE_API_LEVEL AND NOT __level LESS __real_api_level )
-  set( __real_api_level ${__level} )
- endif()
-endforeach()
-if( __real_api_level AND NOT ANDROID_NATIVE_API_LEVEL EQUAL __real_api_level )
- message( STATUS "Adjusting Android API level 'android-${ANDROID_NATIVE_API_LEVEL}' to 'android-${__real_api_level}'")
- set( ANDROID_NATIVE_API_LEVEL ${__real_api_level} )
-endif()
-unset(__real_api_level)
-# validate
-list( FIND ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_NATIVE_API_LEVEL}" __levelIdx )
-if( __levelIdx EQUAL -1 )
- message( SEND_ERROR "Specified Android native API level 'android-${ANDROID_NATIVE_API_LEVEL}' is not supported by your NDK/toolchain." )
-else()
- if( BUILD_WITH_ANDROID_NDK )
-  __DETECT_NATIVE_API_LEVEL( __realApiLevel "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}/usr/include/android/api-level.h" )
-  if( NOT __realApiLevel EQUAL ANDROID_NATIVE_API_LEVEL )
-   message( SEND_ERROR "Specified Android API level (${ANDROID_NATIVE_API_LEVEL}) does not match to the level found (${__realApiLevel}). Probably your copy of NDK is broken." )
-  endif()
-  unset( __realApiLevel )
- endif()
- set( ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" CACHE STRING "Android API level for native code" FORCE )
- if( CMAKE_VERSION VERSION_GREATER "2.8" )
-  list( SORT ANDROID_SUPPORTED_NATIVE_API_LEVELS )
-  set_property( CACHE ANDROID_NATIVE_API_LEVEL PROPERTY STRINGS ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} )
- endif()
-endif()
-unset( __levelIdx )
-
-
-# remember target ABI
-set( ANDROID_ABI "${ANDROID_ABI}" CACHE STRING "The target ABI for Android. If arm, then armeabi-v7a is recommended for hardware floating point." FORCE )
-if( CMAKE_VERSION VERSION_GREATER "2.8" )
- list( SORT ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_FULLNAME} )
- set_property( CACHE ANDROID_ABI PROPERTY STRINGS ${ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_FULLNAME}} )
-endif()
-
-
-# runtime choice (STL, rtti, exceptions)
-if( NOT ANDROID_STL )
- # honor legacy ANDROID_USE_STLPORT
- if( DEFINED ANDROID_USE_STLPORT )
-  if( ANDROID_USE_STLPORT )
-   set( ANDROID_STL stlport_static )
-  endif()
-  message( WARNING "You are using an obsolete variable ANDROID_USE_STLPORT to select the STL variant. Use -DANDROID_STL=stlport_static instead." )
- endif()
- if( NOT ANDROID_STL )
-  set( ANDROID_STL gnustl_static )
- endif()
-endif()
-set( ANDROID_STL "${ANDROID_STL}" CACHE STRING "C++ runtime" )
-set( ANDROID_STL_FORCE_FEATURES ON CACHE BOOL "automatically configure rtti and exceptions support based on C++ runtime" )
-mark_as_advanced( ANDROID_STL ANDROID_STL_FORCE_FEATURES )
-
-if( BUILD_WITH_ANDROID_NDK )
- if( NOT "${ANDROID_STL}" MATCHES "^(none|system|system_re|gabi\\+\\+_static|gabi\\+\\+_shared|stlport_static|stlport_shared|gnustl_static|gnustl_shared)$")
-  message( FATAL_ERROR "ANDROID_STL is set to invalid value \"${ANDROID_STL}\".
-The possible values are:
-  none           -> Do not configure the runtime.
-  system         -> Use the default minimal system C++ runtime library.
-  system_re      -> Same as system but with rtti and exceptions.
-  gabi++_static  -> Use the GAbi++ runtime as a static library.
-  gabi++_shared  -> Use the GAbi++ runtime as a shared library.
-  stlport_static -> Use the STLport runtime as a static library.
-  stlport_shared -> Use the STLport runtime as a shared library.
-  gnustl_static  -> (default) Use the GNU STL as a static library.
-  gnustl_shared  -> Use the GNU STL as a shared library.
-" )
- endif()
-elseif( BUILD_WITH_STANDALONE_TOOLCHAIN )
- if( NOT "${ANDROID_STL}" MATCHES "^(none|gnustl_static|gnustl_shared)$")
-  message( FATAL_ERROR "ANDROID_STL is set to invalid value \"${ANDROID_STL}\".
-The possible values are:
-  none           -> Do not configure the runtime.
-  gnustl_static  -> (default) Use the GNU STL as a static library.
-  gnustl_shared  -> Use the GNU STL as a shared library.
-" )
- endif()
-endif()
-
-unset( ANDROID_RTTI )
-unset( ANDROID_EXCEPTIONS )
-unset( ANDROID_STL_INCLUDE_DIRS )
-unset( __libstl )
-unset( __libsupcxx )
-
-if( NOT _CMAKE_IN_TRY_COMPILE AND ANDROID_NDK_RELEASE STREQUAL "r7b" AND ARMEABI_V7A AND NOT VFPV3 AND ANDROID_STL MATCHES "gnustl" )
- message( WARNING  "The GNU STL armeabi-v7a binaries from NDK r7b can crash non-NEON devices. The files provided with NDK r7b were not configured properly, resulting in crashes on Tegra2-based devices and others when trying to use certain floating-point functions (e.g., cosf, sinf, expf).
-You are strongly recommended to switch to another NDK release.
-" )
-endif()
-
-if( NOT _CMAKE_IN_TRY_COMPILE AND X86 AND ANDROID_STL MATCHES "gnustl" AND ANDROID_NDK_RELEASE STREQUAL "r6" )
-  message( WARNING  "The x86 system header file from NDK r6 has incorrect definition for ptrdiff_t. You are recommended to upgrade to a newer NDK release or manually patch the header:
-See https://android.googlesource.com/platform/development.git f907f4f9d4e56ccc8093df6fee54454b8bcab6c2
-  diff --git a/ndk/platforms/android-9/arch-x86/include/machine/_types.h b/ndk/platforms/android-9/arch-x86/include/machine/_types.h
-  index 5e28c64..65892a1 100644
-  --- a/ndk/platforms/android-9/arch-x86/include/machine/_types.h
-  +++ b/ndk/platforms/android-9/arch-x86/include/machine/_types.h
-  @@ -51,7 +51,11 @@ typedef long int       ssize_t;
-   #endif
-   #ifndef _PTRDIFF_T
-   #define _PTRDIFF_T
-  -typedef long           ptrdiff_t;
-  +#  ifdef __ANDROID__
-  +     typedef int            ptrdiff_t;
-  +#  else
-  +     typedef long           ptrdiff_t;
-  +#  endif
-   #endif
-" )
-endif()
-
-
-# setup paths and STL for standalone toolchain
-if( BUILD_WITH_STANDALONE_TOOLCHAIN )
- set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_STANDALONE_TOOLCHAIN}" )
- set( ANDROID_CLANG_TOOLCHAIN_ROOT "${ANDROID_STANDALONE_TOOLCHAIN}" )
- set( ANDROID_SYSROOT "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot" )
-
- if( NOT ANDROID_STL STREQUAL "none" )
-  set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}" )
-  if( ARMEABI_V7A AND EXISTS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}/bits" )
-   list( APPEND ANDROID_STL_INCLUDE_DIRS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}" )
-  elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/thumb/bits" )
-   list( APPEND ANDROID_STL_INCLUDE_DIRS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/thumb" )
-  else()
-   list( APPEND ANDROID_STL_INCLUDE_DIRS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}" )
-  endif()
-  # always search static GNU STL to get the location of libsupc++.a
-  if( ARMEABI_V7A AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb/libstdc++.a" )
-   set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb" )
-  elseif( ARMEABI_V7A AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libstdc++.a" )
-   set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}" )
-  elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libstdc++.a" )
-   set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb" )
-  elseif( EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libstdc++.a" )
-   set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib" )
-  endif()
-  if( __libstl )
-   set( __libsupcxx "${__libstl}/libsupc++.a" )
-   set( __libstl    "${__libstl}/libstdc++.a" )
-  endif()
-  if( NOT EXISTS "${__libsupcxx}" )
-   message( FATAL_ERROR "The required libstdsupc++.a is missing in your standalone toolchain.
- Usually it happens because of bug in make-standalone-toolchain.sh script from NDK r7, r7b and r7c.
- You need to either upgrade to newer NDK or manually copy
-     $ANDROID_NDK/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a
- to
-     ${__libsupcxx}
-   " )
-  endif()
-  if( ANDROID_STL STREQUAL "gnustl_shared" )
-   if( ARMEABI_V7A AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libgnustl_shared.so" )
-    set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libgnustl_shared.so" )
-   elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libgnustl_shared.so" )
-    set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libgnustl_shared.so" )
-   elseif( EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libgnustl_shared.so" )
-    set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libgnustl_shared.so" )
-   endif()
-  endif()
- endif()
-endif()
-
-# clang
-if( "${ANDROID_TOOLCHAIN_NAME}" STREQUAL "standalone-clang" )
- set( ANDROID_COMPILER_IS_CLANG 1 )
- execute_process( COMMAND "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/clang${TOOL_OS_SUFFIX}" --version OUTPUT_VARIABLE ANDROID_CLANG_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE )
- string( REGEX MATCH "[0-9]+[.][0-9]+" ANDROID_CLANG_VERSION "${ANDROID_CLANG_VERSION}")
-elseif( "${ANDROID_TOOLCHAIN_NAME}" MATCHES "-clang3[.][0-9]?$" )
- string( REGEX MATCH "3[.][0-9]$" ANDROID_CLANG_VERSION "${ANDROID_TOOLCHAIN_NAME}")
- string( REGEX REPLACE "-clang${ANDROID_CLANG_VERSION}$" "-4.6" ANDROID_GCC_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" )
- if( NOT EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/llvm-${ANDROID_CLANG_VERSION}${ANDROID_NDK_TOOLCHAINS_SUBPATH}/bin/clang${TOOL_OS_SUFFIX}" )
-  message( FATAL_ERROR "Could not find the Clang compiler driver" )
- endif()
- set( ANDROID_COMPILER_IS_CLANG 1 )
- set( ANDROID_CLANG_TOOLCHAIN_ROOT "${ANDROID_NDK_TOOLCHAINS_PATH}/llvm-${ANDROID_CLANG_VERSION}${ANDROID_NDK_TOOLCHAINS_SUBPATH}" )
-else()
- set( ANDROID_GCC_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" )
- unset( ANDROID_COMPILER_IS_CLANG CACHE )
-endif()
-
-string( REPLACE "." "" _clang_name "clang${ANDROID_CLANG_VERSION}" )
-if( NOT EXISTS "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}${TOOL_OS_SUFFIX}" )
- set( _clang_name "clang" )
-endif()
-
-
-# setup paths and STL for NDK
-if( BUILD_WITH_ANDROID_NDK )
- set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}${ANDROID_NDK_TOOLCHAINS_SUBPATH}" )
- set( ANDROID_SYSROOT "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}" )
-
- if( ANDROID_STL STREQUAL "none" )
-  # do nothing
- elseif( ANDROID_STL STREQUAL "system" )
-  set( ANDROID_RTTI             OFF )
-  set( ANDROID_EXCEPTIONS       OFF )
-  set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/system/include" )
- elseif( ANDROID_STL STREQUAL "system_re" )
-  set( ANDROID_RTTI             ON )
-  set( ANDROID_EXCEPTIONS       ON )
-  set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/system/include" )
- elseif( ANDROID_STL MATCHES "gabi" )
-  if( ANDROID_NDK_RELEASE STRLESS "r7" )
-   message( FATAL_ERROR "gabi++ is not awailable in your NDK. You have to upgrade to NDK r7 or newer to use gabi++.")
-  endif()
-  set( ANDROID_RTTI             ON )
-  set( ANDROID_EXCEPTIONS       OFF )
-  set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/gabi++/include" )
-  set( __libstl                 "${ANDROID_NDK}/sources/cxx-stl/gabi++/libs/${ANDROID_NDK_ABI_NAME}/libgabi++_static.a" )
- elseif( ANDROID_STL MATCHES "stlport" )
-  if( NOT ANDROID_NDK_RELEASE STRLESS "r8d" )
-   set( ANDROID_EXCEPTIONS       ON )
-  else()
-   set( ANDROID_EXCEPTIONS       OFF )
-  endif()
-  if( ANDROID_NDK_RELEASE STRLESS "r7" )
-   set( ANDROID_RTTI            OFF )
-  else()
-   set( ANDROID_RTTI            ON )
-  endif()
-  set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/stlport/stlport" )
-  set( __libstl                 "${ANDROID_NDK}/sources/cxx-stl/stlport/libs/${ANDROID_NDK_ABI_NAME}/libstlport_static.a" )
- elseif( ANDROID_STL MATCHES "gnustl" )
-  set( ANDROID_EXCEPTIONS       ON )
-  set( ANDROID_RTTI             ON )
-  if( EXISTS "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}" )
-   if( ARMEABI_V7A AND ANDROID_COMPILER_VERSION VERSION_EQUAL "4.7" AND ANDROID_NDK_RELEASE STREQUAL "r8d" )
-    # gnustl binary for 4.7 compiler is buggy :(
-    # TODO: look for right fix
-    set( __libstl                "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/4.6" )
-   else()
-    set( __libstl                "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}" )
-   endif()
-  else()
-   set( __libstl                "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++" )
-  endif()
-  set( ANDROID_STL_INCLUDE_DIRS "${__libstl}/include" "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/include" )
-  if( EXISTS "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libgnustl_static.a" )
-   set( __libstl                "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libgnustl_static.a" )
-  else()
-   set( __libstl                "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libstdc++.a" )
-  endif()
- else()
-  message( FATAL_ERROR "Unknown runtime: ${ANDROID_STL}" )
- endif()
- # find libsupc++.a - rtti & exceptions
- if( ANDROID_STL STREQUAL "system_re" OR ANDROID_STL MATCHES "gnustl" )
-  set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" ) # r8b or newer
-  if( NOT EXISTS "${__libsupcxx}" )
-   set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" ) # r7-r8
-  endif()
-  if( NOT EXISTS "${__libsupcxx}" ) # before r7
-   if( ARMEABI_V7A )
-    if( ANDROID_FORCE_ARM_BUILD )
-     set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libsupc++.a" )
-    else()
-     set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb/libsupc++.a" )
-    endif()
-   elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD )
-    set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libsupc++.a" )
-   else()
-    set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libsupc++.a" )
-   endif()
-  endif()
-  if( NOT EXISTS "${__libsupcxx}")
-   message( ERROR "Could not find libsupc++.a for a chosen platform. Either your NDK is not supported or is broken.")
-  endif()
- endif()
-endif()
-
-
-# case of shared STL linkage
-if( ANDROID_STL MATCHES "shared" AND DEFINED __libstl )
- string( REPLACE "_static.a" "_shared.so" __libstl "${__libstl}" )
- if( NOT _CMAKE_IN_TRY_COMPILE AND __libstl MATCHES "[.]so$" )
-  get_filename_component( __libstlname "${__libstl}" NAME )
-  execute_process( COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${__libstl}" "${LIBRARY_OUTPUT_PATH}/${__libstlname}" RESULT_VARIABLE __fileCopyProcess )
-  if( NOT __fileCopyProcess EQUAL 0 OR NOT EXISTS "${LIBRARY_OUTPUT_PATH}/${__libstlname}")
-   message( SEND_ERROR "Failed copying of ${__libstl} to the ${LIBRARY_OUTPUT_PATH}/${__libstlname}" )
-  endif()
-  unset( __fileCopyProcess )
-  unset( __libstlname )
- endif()
-endif()
-
-
-# ccache support
-__INIT_VARIABLE( _ndk_ccache NDK_CCACHE ENV_NDK_CCACHE )
-if( _ndk_ccache )
- if( DEFINED NDK_CCACHE AND NOT EXISTS NDK_CCACHE )
-  unset( NDK_CCACHE CACHE )
- endif()
- find_program( NDK_CCACHE "${_ndk_ccache}" DOC "The path to ccache binary")
-else()
- unset( NDK_CCACHE CACHE )
-endif()
-unset( _ndk_ccache )
-
-
-# setup the cross-compiler
-if( NOT CMAKE_C_COMPILER )
- if( NDK_CCACHE AND NOT ANDROID_SYSROOT MATCHES "[ ;\"]" )
-  set( CMAKE_C_COMPILER   "${NDK_CCACHE}" CACHE PATH "ccache as C compiler" )
-  set( CMAKE_CXX_COMPILER "${NDK_CCACHE}" CACHE PATH "ccache as C++ compiler" )
-  if( ANDROID_COMPILER_IS_CLANG )
-   set( CMAKE_C_COMPILER_ARG1   "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}${TOOL_OS_SUFFIX}"   CACHE PATH "C compiler")
-   set( CMAKE_CXX_COMPILER_ARG1 "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler")
-  else()
-   set( CMAKE_C_COMPILER_ARG1   "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "C compiler")
-   set( CMAKE_CXX_COMPILER_ARG1 "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler")
-  endif()
- else()
-  if( ANDROID_COMPILER_IS_CLANG )
-   set( CMAKE_C_COMPILER   "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}${TOOL_OS_SUFFIX}"   CACHE PATH "C compiler")
-   set( CMAKE_CXX_COMPILER "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler")
-  else()
-   set( CMAKE_C_COMPILER   "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}"    CACHE PATH "C compiler" )
-   set( CMAKE_CXX_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++${TOOL_OS_SUFFIX}"    CACHE PATH "C++ compiler" )
-  endif()
- endif()
- set( CMAKE_ASM_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}"     CACHE PATH "assembler" )
- set( CMAKE_STRIP        "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-strip${TOOL_OS_SUFFIX}"   CACHE PATH "strip" )
- set( CMAKE_AR           "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ar${TOOL_OS_SUFFIX}"      CACHE PATH "archive" )
- set( CMAKE_LINKER       "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ld${TOOL_OS_SUFFIX}"      CACHE PATH "linker" )
- set( CMAKE_NM           "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-nm${TOOL_OS_SUFFIX}"      CACHE PATH "nm" )
- set( CMAKE_OBJCOPY      "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-objcopy${TOOL_OS_SUFFIX}" CACHE PATH "objcopy" )
- set( CMAKE_OBJDUMP      "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-objdump${TOOL_OS_SUFFIX}" CACHE PATH "objdump" )
- set( CMAKE_RANLIB       "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ranlib${TOOL_OS_SUFFIX}"  CACHE PATH "ranlib" )
-endif()
-
-set( _CMAKE_TOOLCHAIN_PREFIX "${ANDROID_TOOLCHAIN_MACHINE_NAME}-" )
-if( CMAKE_VERSION VERSION_LESS 2.8.5 )
- set( CMAKE_ASM_COMPILER_ARG1 "-c" )
-endif()
-if( APPLE )
- find_program( CMAKE_INSTALL_NAME_TOOL NAMES install_name_tool )
- if( NOT CMAKE_INSTALL_NAME_TOOL )
-  message( FATAL_ERROR "Could not find install_name_tool, please check your installation." )
- endif()
- mark_as_advanced( CMAKE_INSTALL_NAME_TOOL )
-endif()
-
-# Force set compilers because standard identification works badly for us
-include( CMakeForceCompiler )
-CMAKE_FORCE_C_COMPILER( "${CMAKE_C_COMPILER}" GNU )
-if( ANDROID_COMPILER_IS_CLANG )
- set( CMAKE_C_COMPILER_ID Clang)
-endif()
-set( CMAKE_C_PLATFORM_ID Linux )
-set( CMAKE_C_SIZEOF_DATA_PTR 4 )
-set( CMAKE_C_HAS_ISYSROOT 1 )
-set( CMAKE_C_COMPILER_ABI ELF )
-CMAKE_FORCE_CXX_COMPILER( "${CMAKE_CXX_COMPILER}" GNU )
-if( ANDROID_COMPILER_IS_CLANG )
- set( CMAKE_CXX_COMPILER_ID Clang)
-endif()
-set( CMAKE_CXX_PLATFORM_ID Linux )
-set( CMAKE_CXX_SIZEOF_DATA_PTR 4 )
-set( CMAKE_CXX_HAS_ISYSROOT 1 )
-set( CMAKE_CXX_COMPILER_ABI ELF )
-set( CMAKE_CXX_SOURCE_FILE_EXTENSIONS cc cp cxx cpp CPP c++ C )
-# force ASM compiler (required for CMake < 2.8.5)
-set( CMAKE_ASM_COMPILER_ID_RUN TRUE )
-set( CMAKE_ASM_COMPILER_ID GNU )
-set( CMAKE_ASM_COMPILER_WORKS TRUE )
-set( CMAKE_ASM_COMPILER_FORCED TRUE )
-set( CMAKE_COMPILER_IS_GNUASM 1)
-set( CMAKE_ASM_SOURCE_FILE_EXTENSIONS s S asm )
-
-# flags and definitions
-remove_definitions( -DANDROID )
-add_definitions( -DANDROID )
-
-if( ANDROID_SYSROOT MATCHES "[ ;\"]" )
- if( CMAKE_HOST_WIN32 )
-  # try to convert path to 8.3 form
-  file( WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cvt83.cmd" "@echo %~s1" )
-  execute_process( COMMAND "$ENV{ComSpec}" /c "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cvt83.cmd" "${ANDROID_SYSROOT}"
-                   OUTPUT_VARIABLE __path OUTPUT_STRIP_TRAILING_WHITESPACE
-                   RESULT_VARIABLE __result ERROR_QUIET )
-  if( __result EQUAL 0 )
-   file( TO_CMAKE_PATH "${__path}" ANDROID_SYSROOT )
-   set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT}" )
-  else()
-   set( ANDROID_CXX_FLAGS "--sysroot=\"${ANDROID_SYSROOT}\"" )
-  endif()
- else()
-  set( ANDROID_CXX_FLAGS "'--sysroot=${ANDROID_SYSROOT}'" )
- endif()
- if( NOT _CMAKE_IN_TRY_COMPILE )
-  # quotes can break try_compile and compiler identification
-  message(WARNING "Path to your Android NDK (or toolchain) has non-alphanumeric symbols.\nThe build might be broken.\n")
- endif()
-else()
- set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT}" )
-endif()
-
-# NDK flags
-if( ARMEABI OR ARMEABI_V7A )
- set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fpic -funwind-tables" )
- if( NOT ANDROID_FORCE_ARM_BUILD AND NOT ARMEABI_V6 )
-  set( ANDROID_CXX_FLAGS_RELEASE "-mthumb -fomit-frame-pointer -fno-strict-aliasing" )
-  set( ANDROID_CXX_FLAGS_DEBUG   "-marm -fno-omit-frame-pointer -fno-strict-aliasing" )
-  if( NOT ANDROID_COMPILER_IS_CLANG )
-   set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -finline-limit=64" )
-  endif()
- else()
-  # always compile ARMEABI_V6 in arm mode; otherwise there is no difference from ARMEABI
-  set( ANDROID_CXX_FLAGS_RELEASE "-marm -fomit-frame-pointer -fstrict-aliasing" )
-  set( ANDROID_CXX_FLAGS_DEBUG   "-marm -fno-omit-frame-pointer -fno-strict-aliasing" )
-  if( NOT ANDROID_COMPILER_IS_CLANG )
-   set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funswitch-loops -finline-limit=300" )
-  endif()
- endif()
-elseif( X86 )
- set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funwind-tables" )
- if( NOT ANDROID_COMPILER_IS_CLANG )
-  set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funswitch-loops -finline-limit=300" )
- else()
-  set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fPIC" )
- endif()
- set( ANDROID_CXX_FLAGS_RELEASE "-fomit-frame-pointer -fstrict-aliasing" )
- set( ANDROID_CXX_FLAGS_DEBUG   "-fno-omit-frame-pointer -fno-strict-aliasing" )
-elseif( MIPS )
- set( ANDROID_CXX_FLAGS         "${ANDROID_CXX_FLAGS} -fpic -fno-strict-aliasing -finline-functions -ffunction-sections -funwind-tables -fmessage-length=0" )
- set( ANDROID_CXX_FLAGS_RELEASE "-fomit-frame-pointer" )
- set( ANDROID_CXX_FLAGS_DEBUG   "-fno-omit-frame-pointer" )
- if( NOT ANDROID_COMPILER_IS_CLANG )
-  set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers" )
-  set( ANDROID_CXX_FLAGS_RELEASE "${ANDROID_CXX_FLAGS_RELEASE} -funswitch-loops -finline-limit=300" )
- endif()
-elseif()
- set( ANDROID_CXX_FLAGS_RELEASE "" )
- set( ANDROID_CXX_FLAGS_DEBUG   "" )
-endif()
-
-set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fsigned-char" ) # good/necessary when porting desktop libraries
-
-if( NOT X86 AND NOT ANDROID_COMPILER_IS_CLANG )
- set( ANDROID_CXX_FLAGS "-Wno-psabi ${ANDROID_CXX_FLAGS}" )
-endif()
-
-if( NOT ANDROID_COMPILER_VERSION VERSION_LESS "4.6" )
- set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -no-canonical-prefixes" ) # see https://android-review.googlesource.com/#/c/47564/
-endif()
-
-# ABI-specific flags
-if( ARMEABI_V7A )
- set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv7-a -mfloat-abi=softfp" )
- if( NEON )
-  set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=neon" )
- elseif( VFPV3 )
-  set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=vfpv3" )
- else()
-  set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=vfpv3-d16" )
- endif()
-elseif( ARMEABI_V6 )
- set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv6 -mfloat-abi=softfp -mfpu=vfp" ) # vfp == vfpv2
-elseif( ARMEABI )
- set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv5te -mtune=xscale -msoft-float" )
-endif()
-
-if( ANDROID_STL MATCHES "gnustl" AND (EXISTS "${__libstl}" OR EXISTS "${__libsupcxx}") )
- set( CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
- set( CMAKE_CXX_CREATE_SHARED_MODULE  "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
- set( CMAKE_CXX_LINK_EXECUTABLE       "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>" )
-else()
- set( CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
- set( CMAKE_CXX_CREATE_SHARED_MODULE  "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
- set( CMAKE_CXX_LINK_EXECUTABLE       "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>" )
-endif()
-
-# STL
-if( EXISTS "${__libstl}" OR EXISTS "${__libsupcxx}" )
- if( EXISTS "${__libstl}" )
-  set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${__libstl}\"" )
-  set( CMAKE_CXX_CREATE_SHARED_MODULE  "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${__libstl}\"" )
-  set( CMAKE_CXX_LINK_EXECUTABLE       "${CMAKE_CXX_LINK_EXECUTABLE} \"${__libstl}\"" )
- endif()
- if( EXISTS "${__libsupcxx}" )
-  set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${__libsupcxx}\"" )
-  set( CMAKE_CXX_CREATE_SHARED_MODULE  "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${__libsupcxx}\"" )
-  set( CMAKE_CXX_LINK_EXECUTABLE       "${CMAKE_CXX_LINK_EXECUTABLE} \"${__libsupcxx}\"" )
-  # C objects:
-  set( CMAKE_C_CREATE_SHARED_LIBRARY "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_C_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_C_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
-  set( CMAKE_C_CREATE_SHARED_MODULE  "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_C_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_C_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" )
-  set( CMAKE_C_LINK_EXECUTABLE       "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>" )
-  set( CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_C_CREATE_SHARED_LIBRARY} \"${__libsupcxx}\"" )
-  set( CMAKE_C_CREATE_SHARED_MODULE  "${CMAKE_C_CREATE_SHARED_MODULE} \"${__libsupcxx}\"" )
-  set( CMAKE_C_LINK_EXECUTABLE       "${CMAKE_C_LINK_EXECUTABLE} \"${__libsupcxx}\"" )
- endif()
- if( ANDROID_STL MATCHES "gnustl" )
-  if( NOT EXISTS "${ANDROID_LIBM_PATH}" )
-   set( ANDROID_LIBM_PATH -lm )
-  endif()
-  set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} ${ANDROID_LIBM_PATH}" )
-  set( CMAKE_CXX_CREATE_SHARED_MODULE  "${CMAKE_CXX_CREATE_SHARED_MODULE} ${ANDROID_LIBM_PATH}" )
-  set( CMAKE_CXX_LINK_EXECUTABLE       "${CMAKE_CXX_LINK_EXECUTABLE} ${ANDROID_LIBM_PATH}" )
- endif()
-endif()
-
-# variables controlling optional build flags
-if (ANDROID_NDK_RELEASE STRLESS "r7")
- # libGLESv2.so in NDK's prior to r7 refers to missing external symbols.
- # So this flag option is required for all projects using OpenGL from native.
- __INIT_VARIABLE( ANDROID_SO_UNDEFINED                      VALUES ON )
-else()
- __INIT_VARIABLE( ANDROID_SO_UNDEFINED                      VALUES OFF )
-endif()
-__INIT_VARIABLE( ANDROID_NO_UNDEFINED OBSOLETE_NO_UNDEFINED VALUES ON )
-__INIT_VARIABLE( ANDROID_FUNCTION_LEVEL_LINKING             VALUES ON )
-__INIT_VARIABLE( ANDROID_GOLD_LINKER                        VALUES ON )
-__INIT_VARIABLE( ANDROID_NOEXECSTACK                        VALUES ON )
-__INIT_VARIABLE( ANDROID_RELRO                              VALUES ON )
-
-set( ANDROID_NO_UNDEFINED           ${ANDROID_NO_UNDEFINED}           CACHE BOOL "Show all undefined symbols as linker errors" )
-set( ANDROID_SO_UNDEFINED           ${ANDROID_SO_UNDEFINED}           CACHE BOOL "Allows or disallows undefined symbols in shared libraries" )
-set( ANDROID_FUNCTION_LEVEL_LINKING ${ANDROID_FUNCTION_LEVEL_LINKING} CACHE BOOL "Allows or disallows undefined symbols in shared libraries" )
-set( ANDROID_GOLD_LINKER            ${ANDROID_GOLD_LINKER}            CACHE BOOL "Enables gold linker (only avaialble for NDK r8b for ARM and x86 architectures on linux-86 and darwin-x86 hosts)" )
-set( ANDROID_NOEXECSTACK            ${ANDROID_NOEXECSTACK}            CACHE BOOL "Allows or disallows undefined symbols in shared libraries" )
-set( ANDROID_RELRO                  ${ANDROID_RELRO}                  CACHE BOOL "Enables RELRO - a memory corruption mitigation technique" )
-mark_as_advanced( ANDROID_NO_UNDEFINED ANDROID_SO_UNDEFINED ANDROID_FUNCTION_LEVEL_LINKING ANDROID_GOLD_LINKER ANDROID_NOEXECSTACK ANDROID_RELRO )
-
-# linker flags
-set( ANDROID_LINKER_FLAGS "" )
-
-if( ARMEABI_V7A )
- # this is *required* to use the following linker flags that routes around
- # a CPU bug in some Cortex-A8 implementations:
- set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--fix-cortex-a8" )
-endif()
-
-if( ANDROID_NO_UNDEFINED )
- if( MIPS )
-  # there is some sysroot-related problem in mips linker...
-  if( NOT ANDROID_SYSROOT MATCHES "[ ;\"]" )
-   set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--no-undefined -Wl,-rpath-link,${ANDROID_SYSROOT}/usr/lib" )
-  endif()
- else()
-  set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--no-undefined" )
- endif()
-endif()
-
-if( ANDROID_SO_UNDEFINED )
- set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,-allow-shlib-undefined" )
-endif()
-
-if( ANDROID_FUNCTION_LEVEL_LINKING )
- set( ANDROID_CXX_FLAGS    "${ANDROID_CXX_FLAGS} -fdata-sections -ffunction-sections" )
- set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--gc-sections" )
-endif()
-
-if( ANDROID_COMPILER_VERSION VERSION_EQUAL "4.6" )
- if( ANDROID_GOLD_LINKER AND (CMAKE_HOST_UNIX OR ANDROID_NDK_RELEASE STRGREATER "r8b") AND (ARMEABI OR ARMEABI_V7A OR X86) )
-  set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -fuse-ld=gold" )
- elseif( ANDROID_NDK_RELEASE STRGREATER "r8b")
-  set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -fuse-ld=bfd" )
- elseif( ANDROID_NDK_RELEASE STREQUAL "r8b" AND ARMEABI AND NOT _CMAKE_IN_TRY_COMPILE )
-  message( WARNING "The default bfd linker from arm GCC 4.6 toolchain can fail with 'unresolvable R_ARM_THM_CALL relocation' error message. See https://code.google.com/p/android/issues/detail?id=35342
-  On Linux and OS X host platform you can workaround this problem using gold linker (default).
-  Rerun cmake with -DANDROID_GOLD_LINKER=ON option in case of problems.
-" )
- endif()
-endif() # version 4.6
-
-if( ANDROID_NOEXECSTACK )
- if( ANDROID_COMPILER_IS_CLANG )
-  set( ANDROID_CXX_FLAGS    "${ANDROID_CXX_FLAGS} -Xclang -mnoexecstack" )
- else()
-  set( ANDROID_CXX_FLAGS    "${ANDROID_CXX_FLAGS} -Wa,--noexecstack" )
- endif()
- set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,-z,noexecstack" )
-endif()
-
-if( ANDROID_RELRO )
- set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,-z,relro -Wl,-z,now" )
-endif()
-
-if( ANDROID_COMPILER_IS_CLANG )
- set( ANDROID_CXX_FLAGS "-Qunused-arguments ${ANDROID_CXX_FLAGS}" )
- if( ARMEABI_V7A AND NOT ANDROID_FORCE_ARM_BUILD )
-  set( ANDROID_CXX_FLAGS_RELEASE "-target thumbv7-none-linux-androideabi ${ANDROID_CXX_FLAGS_RELEASE}" )
-  set( ANDROID_CXX_FLAGS_DEBUG   "-target ${ANDROID_LLVM_TRIPLE} ${ANDROID_CXX_FLAGS_DEBUG}" )
- else()
-  set( ANDROID_CXX_FLAGS "-target ${ANDROID_LLVM_TRIPLE} ${ANDROID_CXX_FLAGS}" )
- endif()
- if( BUILD_WITH_ANDROID_NDK )
-  set( ANDROID_CXX_FLAGS "-gcc-toolchain ${ANDROID_TOOLCHAIN_ROOT} ${ANDROID_CXX_FLAGS}" )
- endif()
-endif()
-
-# cache flags
-set( CMAKE_CXX_FLAGS           ""                        CACHE STRING "c++ flags" )
-set( CMAKE_C_FLAGS             ""                        CACHE STRING "c flags" )
-set( CMAKE_CXX_FLAGS_RELEASE   "-O3 -DNDEBUG"            CACHE STRING "c++ Release flags" )
-set( CMAKE_C_FLAGS_RELEASE     "-O3 -DNDEBUG"            CACHE STRING "c Release flags" )
-set( CMAKE_CXX_FLAGS_DEBUG     "-O0 -g -DDEBUG -D_DEBUG" CACHE STRING "c++ Debug flags" )
-set( CMAKE_C_FLAGS_DEBUG       "-O0 -g -DDEBUG -D_DEBUG" CACHE STRING "c Debug flags" )
-set( CMAKE_SHARED_LINKER_FLAGS ""                        CACHE STRING "shared linker flags" )
-set( CMAKE_MODULE_LINKER_FLAGS ""                        CACHE STRING "module linker flags" )
-set( CMAKE_EXE_LINKER_FLAGS    "-Wl,-z,nocopyreloc"      CACHE STRING "executable linker flags" )
-
-# put flags to cache (for debug purpose only)
-set( ANDROID_CXX_FLAGS         "${ANDROID_CXX_FLAGS}"         CACHE INTERNAL "Android specific c/c++ flags" )
-set( ANDROID_CXX_FLAGS_RELEASE "${ANDROID_CXX_FLAGS_RELEASE}" CACHE INTERNAL "Android specific c/c++ Release flags" )
-set( ANDROID_CXX_FLAGS_DEBUG   "${ANDROID_CXX_FLAGS_DEBUG}"   CACHE INTERNAL "Android specific c/c++ Debug flags" )
-set( ANDROID_LINKER_FLAGS      "${ANDROID_LINKER_FLAGS}"      CACHE INTERNAL "Android specific c/c++ linker flags" )
-
-# finish flags
-set( CMAKE_CXX_FLAGS           "${ANDROID_CXX_FLAGS} ${CMAKE_CXX_FLAGS}" )
-set( CMAKE_C_FLAGS             "${ANDROID_CXX_FLAGS} ${CMAKE_C_FLAGS}" )
-set( CMAKE_CXX_FLAGS_RELEASE   "${ANDROID_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_RELEASE}" )
-set( CMAKE_C_FLAGS_RELEASE     "${ANDROID_CXX_FLAGS_RELEASE} ${CMAKE_C_FLAGS_RELEASE}" )
-set( CMAKE_CXX_FLAGS_DEBUG     "${ANDROID_CXX_FLAGS_DEBUG} ${CMAKE_CXX_FLAGS_DEBUG}" )
-set( CMAKE_C_FLAGS_DEBUG       "${ANDROID_CXX_FLAGS_DEBUG} ${CMAKE_C_FLAGS_DEBUG}" )
-set( CMAKE_SHARED_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}" )
-set( CMAKE_MODULE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FLAGS}" )
-set( CMAKE_EXE_LINKER_FLAGS    "${ANDROID_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" )
-
-if( MIPS AND BUILD_WITH_ANDROID_NDK AND ANDROID_NDK_RELEASE STREQUAL "r8" )
- set( CMAKE_SHARED_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_SHARED_LINKER_FLAGS}" )
- set( CMAKE_MODULE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_MODULE_LINKER_FLAGS}" )
- set( CMAKE_EXE_LINKER_FLAGS    "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.x ${CMAKE_EXE_LINKER_FLAGS}" )
-endif()
-
-# configure rtti
-if( DEFINED ANDROID_RTTI AND ANDROID_STL_FORCE_FEATURES )
- if( ANDROID_RTTI )
-  set( CMAKE_CXX_FLAGS "-frtti ${CMAKE_CXX_FLAGS}" )
- else()
-  set( CMAKE_CXX_FLAGS "-fno-rtti ${CMAKE_CXX_FLAGS}" )
- endif()
-endif()
-
-# configure exceptios
-if( DEFINED ANDROID_EXCEPTIONS AND ANDROID_STL_FORCE_FEATURES )
- if( ANDROID_EXCEPTIONS )
-  set( CMAKE_CXX_FLAGS "-fexceptions ${CMAKE_CXX_FLAGS}" )
-  set( CMAKE_C_FLAGS "-fexceptions ${CMAKE_C_FLAGS}" )
- else()
-  set( CMAKE_CXX_FLAGS "-fno-exceptions ${CMAKE_CXX_FLAGS}" )
-  set( CMAKE_C_FLAGS "-fno-exceptions ${CMAKE_C_FLAGS}" )
- endif()
-endif()
-
-# global includes and link directories
-include_directories( SYSTEM "${ANDROID_SYSROOT}/usr/include" ${ANDROID_STL_INCLUDE_DIRS} )
-link_directories( "${CMAKE_INSTALL_PREFIX}/libs/${ANDROID_NDK_ABI_NAME}" )
-
-# detect if need link crtbegin_so.o explicitly
-if( NOT DEFINED ANDROID_EXPLICIT_CRT_LINK )
- set( __cmd "${CMAKE_CXX_CREATE_SHARED_LIBRARY}" )
- string( REPLACE "<CMAKE_CXX_COMPILER>" "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" __cmd "${__cmd}" )
- string( REPLACE "<CMAKE_C_COMPILER>"   "${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}"   __cmd "${__cmd}" )
- string( REPLACE "<CMAKE_SHARED_LIBRARY_CXX_FLAGS>" "${CMAKE_CXX_FLAGS}" __cmd "${__cmd}" )
- string( REPLACE "<LANGUAGE_COMPILE_FLAGS>" "" __cmd "${__cmd}" )
- string( REPLACE "<LINK_FLAGS>" "${CMAKE_SHARED_LINKER_FLAGS}" __cmd "${__cmd}" )
- string( REPLACE "<CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS>" "-shared" __cmd "${__cmd}" )
- string( REPLACE "<CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG>" "" __cmd "${__cmd}" )
- string( REPLACE "<TARGET_SONAME>" "" __cmd "${__cmd}" )
- string( REPLACE "<TARGET>" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/toolchain_crtlink_test.so" __cmd "${__cmd}" )
- string( REPLACE "<OBJECTS>" "\"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" __cmd "${__cmd}" )
- string( REPLACE "<LINK_LIBRARIES>" "" __cmd "${__cmd}" )
- separate_arguments( __cmd )
- foreach( __var ANDROID_NDK ANDROID_NDK_TOOLCHAINS_PATH ANDROID_STANDALONE_TOOLCHAIN )
-  if( ${__var} )
-   set( __tmp "${${__var}}" )
-   separate_arguments( __tmp )
-   string( REPLACE "${__tmp}" "${${__var}}" __cmd "${__cmd}")
-  endif()
- endforeach()
- string( REPLACE "'" "" __cmd "${__cmd}" )
- string( REPLACE "\"" "" __cmd "${__cmd}" )
- execute_process( COMMAND ${__cmd} RESULT_VARIABLE __cmd_result OUTPUT_QUIET ERROR_QUIET )
- if( __cmd_result EQUAL 0 )
-  set( ANDROID_EXPLICIT_CRT_LINK ON )
- else()
-  set( ANDROID_EXPLICIT_CRT_LINK OFF )
- endif()
-endif()
-
-if( ANDROID_EXPLICIT_CRT_LINK )
- set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" )
- set( CMAKE_CXX_CREATE_SHARED_MODULE  "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" )
-endif()
-
-# setup output directories
-set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_SOURCE_DIR} CACHE PATH "root for library output, set this to change where android libs are installed to" )
-set( CMAKE_INSTALL_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/user" CACHE STRING "path for installing" )
-
-if(NOT _CMAKE_IN_TRY_COMPILE)
- if( EXISTS "${CMAKE_SOURCE_DIR}/jni/CMakeLists.txt" )
-  set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin/${ANDROID_NDK_ABI_NAME}" CACHE PATH "Output directory for applications" )
- else()
-  set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin" CACHE PATH "Output directory for applications" )
- endif()
- set( LIBRARY_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}" CACHE PATH "path for android libs" )
-endif()
-
-# set these global flags for cmake client scripts to change behavior
-set( ANDROID True )
-set( BUILD_ANDROID True )
-
-# where is the target environment
-set( CMAKE_FIND_ROOT_PATH "${ANDROID_TOOLCHAIN_ROOT}/bin" "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}" "${ANDROID_SYSROOT}" "${CMAKE_INSTALL_PREFIX}" "${CMAKE_INSTALL_PREFIX}/share" )
-
-# only search for libraries and includes in the ndk toolchain
-set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY )
-set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
-set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
-
-
-# macro to find packages on the host OS
-macro( find_host_package )
- set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )
- set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER )
- set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER )
- if( CMAKE_HOST_WIN32 )
-  SET( WIN32 1 )
-  SET( UNIX )
- elseif( CMAKE_HOST_APPLE )
-  SET( APPLE 1 )
-  SET( UNIX )
- endif()
- find_package( ${ARGN} )
- SET( WIN32 )
- SET( APPLE )
- SET( UNIX 1 )
- set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY )
- set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
- set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
-endmacro()
-
-
-# macro to find programs on the host OS
-macro( find_host_program )
- set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )
- set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER )
- set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER )
- if( CMAKE_HOST_WIN32 )
-  SET( WIN32 1 )
-  SET( UNIX )
- elseif( CMAKE_HOST_APPLE )
-  SET( APPLE 1 )
-  SET( UNIX )
- endif()
- find_program( ${ARGN} )
- SET( WIN32 )
- SET( APPLE )
- SET( UNIX 1 )
- set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY )
- set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
- set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
-endmacro()
-
-
-macro( ANDROID_GET_ABI_RAWNAME TOOLCHAIN_FLAG VAR )
- if( "${TOOLCHAIN_FLAG}" STREQUAL "ARMEABI" )
-  set( ${VAR} "armeabi" )
- elseif( "${TOOLCHAIN_FLAG}" STREQUAL "ARMEABI_V7A" )
-  set( ${VAR} "armeabi-v7a" )
- elseif( "${TOOLCHAIN_FLAG}" STREQUAL "X86" )
-  set( ${VAR} "x86" )
- elseif( "${TOOLCHAIN_FLAG}" STREQUAL "MIPS" )
-  set( ${VAR} "mips" )
- else()
-  set( ${VAR} "unknown" )
- endif()
-endmacro()
-
-
-# export toolchain settings for the try_compile() command
-if( NOT PROJECT_NAME STREQUAL "CMAKE_TRY_COMPILE" )
- set( __toolchain_config "")
- foreach( __var NDK_CCACHE  LIBRARY_OUTPUT_PATH_ROOT  ANDROID_FORBID_SYGWIN  ANDROID_SET_OBSOLETE_VARIABLES
-                ANDROID_NDK_HOST_X64
-                ANDROID_NDK
-                ANDROID_NDK_LAYOUT
-                ANDROID_STANDALONE_TOOLCHAIN
-                ANDROID_TOOLCHAIN_NAME
-                ANDROID_ABI
-                ANDROID_NATIVE_API_LEVEL
-                ANDROID_STL
-                ANDROID_STL_FORCE_FEATURES
-                ANDROID_FORCE_ARM_BUILD
-                ANDROID_NO_UNDEFINED
-                ANDROID_SO_UNDEFINED
-                ANDROID_FUNCTION_LEVEL_LINKING
-                ANDROID_GOLD_LINKER
-                ANDROID_NOEXECSTACK
-                ANDROID_RELRO
-                ANDROID_LIBM_PATH
-                ANDROID_EXPLICIT_CRT_LINK
-                )
-  if( DEFINED ${__var} )
-   if( "${__var}" MATCHES " ")
-    set( __toolchain_config "${__toolchain_config}set( ${__var} \"${${__var}}\" CACHE INTERNAL \"\" )\n" )
-   else()
-    set( __toolchain_config "${__toolchain_config}set( ${__var} ${${__var}} CACHE INTERNAL \"\" )\n" )
-   endif()
-  endif()
- endforeach()
- file( WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/android.toolchain.config.cmake" "${__toolchain_config}" )
- unset( __toolchain_config )
-endif()
-
-
-# set some obsolete variables for backward compatibility
-set( ANDROID_SET_OBSOLETE_VARIABLES ON CACHE BOOL "Define obsolete Andrid-specific cmake variables" )
-mark_as_advanced( ANDROID_SET_OBSOLETE_VARIABLES )
-if( ANDROID_SET_OBSOLETE_VARIABLES )
- set( ANDROID_API_LEVEL ${ANDROID_NATIVE_API_LEVEL} )
- set( ARM_TARGET "${ANDROID_ABI}" )
- set( ARMEABI_NDK_NAME "${ANDROID_NDK_ABI_NAME}" )
-endif()
-
-
-# Variables controlling behavior or set by cmake toolchain:
-#   ANDROID_ABI : "armeabi-v7a" (default), "armeabi", "armeabi-v7a with NEON", "armeabi-v7a with VFPV3", "armeabi-v6 with VFP", "x86", "mips"
-#   ANDROID_NATIVE_API_LEVEL : 3,4,5,8,9,14 (depends on NDK version)
-#   ANDROID_STL : gnustl_static/gnustl_shared/stlport_static/stlport_shared/gabi++_static/gabi++_shared/system_re/system/none
-#   ANDROID_FORBID_SYGWIN : ON/OFF
-#   ANDROID_NO_UNDEFINED : ON/OFF
-#   ANDROID_SO_UNDEFINED : OFF/ON  (default depends on NDK version)
-#   ANDROID_FUNCTION_LEVEL_LINKING : ON/OFF
-#   ANDROID_GOLD_LINKER : ON/OFF
-#   ANDROID_NOEXECSTACK : ON/OFF
-#   ANDROID_RELRO : ON/OFF
-#   ANDROID_FORCE_ARM_BUILD : ON/OFF
-#   ANDROID_STL_FORCE_FEATURES : ON/OFF
-#   ANDROID_SET_OBSOLETE_VARIABLES : ON/OFF
-# Can be set only at the first run:
-#   ANDROID_NDK
-#   ANDROID_STANDALONE_TOOLCHAIN
-#   ANDROID_TOOLCHAIN_NAME : the NDK name of compiler toolchain
-#   ANDROID_NDK_HOST_X64 : try to use x86_64 toolchain (default for x64 host systems)
-#   ANDROID_NDK_LAYOUT : the inner NDK structure (RELEASE, LINARO, ANDROID)
-#   LIBRARY_OUTPUT_PATH_ROOT : <any valid path>
-#   NDK_CCACHE : <path to your ccache executable>
-# Obsolete:
-#   ANDROID_API_LEVEL : superseded by ANDROID_NATIVE_API_LEVEL
-#   ARM_TARGET : superseded by ANDROID_ABI
-#   ARM_TARGETS : superseded by ANDROID_ABI (can be set only)
-#   ANDROID_NDK_TOOLCHAIN_ROOT : superseded by ANDROID_STANDALONE_TOOLCHAIN (can be set only)
-#   ANDROID_USE_STLPORT : superseded by ANDROID_STL=stlport_static
-#   ANDROID_LEVEL : superseded by ANDROID_NATIVE_API_LEVEL (completely removed)
-#
-# Primary read-only variables:
-#   ANDROID : always TRUE
-#   ARMEABI : TRUE for arm v6 and older devices
-#   ARMEABI_V6 : TRUE for arm v6
-#   ARMEABI_V7A : TRUE for arm v7a
-#   NEON : TRUE if NEON unit is enabled
-#   VFPV3 : TRUE if VFP version 3 is enabled
-#   X86 : TRUE if configured for x86
-#   MIPS : TRUE if configured for mips
-#   BUILD_ANDROID : always TRUE
-#   BUILD_WITH_ANDROID_NDK : TRUE if NDK is used
-#   BUILD_WITH_STANDALONE_TOOLCHAIN : TRUE if standalone toolchain is used
-#   ANDROID_NDK_HOST_SYSTEM_NAME : "windows", "linux-x86" or "darwin-x86" depending on host platform
-#   ANDROID_NDK_ABI_NAME : "armeabi", "armeabi-v7a", "x86" or "mips" depending on ANDROID_ABI
-#   ANDROID_NDK_RELEASE : one of r5, r5b, r5c, r6, r6b, r7, r7b, r7c, r8, r8b, r8c, r8d, r8e; set only for NDK
-#   ANDROID_ARCH_NAME : "arm" or "x86" or "mips" depending on ANDROID_ABI
-#   ANDROID_SYSROOT : path to the compiler sysroot
-#   TOOL_OS_SUFFIX : "" or ".exe" depending on host platform
-#   ANDROID_COMPILER_IS_CLANG : TRUE if clang compiler is used
-# Obsolete:
-#   ARMEABI_NDK_NAME : superseded by ANDROID_NDK_ABI_NAME
-#
-# Secondary (less stable) read-only variables:
-#   ANDROID_COMPILER_VERSION : GCC version used
-#   ANDROID_CXX_FLAGS : C/C++ compiler flags required by Android platform
-#   ANDROID_SUPPORTED_ABIS : list of currently allowed values for ANDROID_ABI
-#   ANDROID_TOOLCHAIN_MACHINE_NAME : "arm-linux-androideabi", "arm-eabi" or "i686-android-linux"
-#   ANDROID_TOOLCHAIN_ROOT : path to the top level of toolchain (standalone or placed inside NDK)
-#   ANDROID_CLANG_TOOLCHAIN_ROOT : path to clang tools
-#   ANDROID_SUPPORTED_NATIVE_API_LEVELS : list of native API levels found inside NDK
-#   ANDROID_STL_INCLUDE_DIRS : stl include paths
-#   ANDROID_RTTI : if rtti is enabled by the runtime
-#   ANDROID_EXCEPTIONS : if exceptions are enabled by the runtime
-#   ANDROID_GCC_TOOLCHAIN_NAME : read-only, differs from ANDROID_TOOLCHAIN_NAME only if clang is used
-#   ANDROID_CLANG_VERSION : version of clang compiler if clang is used
-#   ANDROID_LIBM_PATH : path to libm.so (set to something like $(TOP)/out/target/product/<product_name>/obj/lib/libm.so) to workaround unresolved `sincos`
-#
-# Defaults:
-#   ANDROID_DEFAULT_NDK_API_LEVEL
-#   ANDROID_DEFAULT_NDK_API_LEVEL_${ARCH}
-#   ANDROID_NDK_SEARCH_PATHS
-#   ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH
-#   ANDROID_SUPPORTED_ABIS_${ARCH}
-#   ANDROID_SUPPORTED_NDK_VERSIONS
diff --git a/android/readme.txt b/android/readme.txt
deleted file mode 100644 (file)
index 2d5f396..0000000
+++ /dev/null
@@ -1 +0,0 @@
-All Android specific sources are moved to platforms/android.
\ No newline at end of file
index 7514285..295b914 100644 (file)
@@ -2,6 +2,40 @@ if(NOT MSVC)
   message(FATAL_ERROR "CRT options are available only for MSVC")
 endif()
 
+#INCLUDE (CheckIncludeFiles)
+
+if (ENABLE_WINRT_MODE)
+  set(HAVE_WINRT True)
+
+  # search Windows Platform SDK
+  message(STATUS "Checking for Windows Platfrom SDK")
+  GET_FILENAME_COMPONENT(WINDOWS_SDK_PATH  "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v8.0;InstallationFolder]" ABSOLUTE CACHE)
+  if (WINDOWS_SDK_PATH STREQUAL "")
+    message(ERROR "Windows Platform SDK 8.0 was not found!")
+    set(HAVE_WINRT False)
+  endif()
+
+  #search for Visual Studio 11.0 install directory
+  message(STATUS "Checking for Visual Studio 2012")
+  GET_FILENAME_COMPONENT(VISUAL_STUDIO_PATH [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0\\Setup\\VS;ProductDir] REALPATH CACHE)
+  if (VISUAL_STUDIO_PATH STREQUAL "")
+    message(ERROR "Visual Studio 2012 was not found!")
+    set(HAVE_WINRT False)
+  endif()
+
+  if (HAVE_WINRT)
+    TRY_COMPILE(HAVE_WINRT
+      "${OPENCV_BINARY_DIR}/CMakeFiles/CMakeTmp"
+      "${OpenCV_SOURCE_DIR}/cmake/checks/winrttest.cpp"
+      CMAKE_FLAGS "\"kernel.lib\" \"user32.lib\""
+      OUTPUT_VARIABLE OUTPUT)
+  endif()
+
+  if (HAVE_WINRT)
+    add_definitions(/DWINVER=0x0602 /DNTDDI_VERSION=NTDDI_WIN8 /D_WIN32_WINNT=0x0602)
+  endif()
+endif(ENABLE_WINRT_MODE)
+
 if(NOT BUILD_SHARED_LIBS AND BUILD_WITH_STATIC_CRT)
   foreach(flag_var
           CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
index 8db6677..212d344 100644 (file)
@@ -29,10 +29,42 @@ if(CUDA_FOUND)
   if(${CUDA_VERSION} VERSION_LESS "5.5")
     find_cuda_helper_libs(npp)
   else()
-    find_cuda_helper_libs(nppc)
-    find_cuda_helper_libs(nppi)
-    find_cuda_helper_libs(npps)
-    set(CUDA_npp_LIBRARY ${CUDA_nppc_LIBRARY} ${CUDA_nppi_LIBRARY} ${CUDA_npps_LIBRARY})
+    # hack for CUDA 5.5
+    if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm")
+      unset(CUDA_TOOLKIT_INCLUDE CACHE)
+      unset(CUDA_CUDART_LIBRARY CACHE)
+      unset(CUDA_cublas_LIBRARY CACHE)
+      unset(CUDA_cufft_LIBRARY CACHE)
+      unset(CUDA_npp_LIBRARY CACHE)
+
+      if(SOFTFP)
+        set(cuda_arm_path "${CUDA_TOOLKIT_ROOT_DIR}/targets/armv7-linux-gnueabi")
+      else()
+        set(cuda_arm_path "${CUDA_TOOLKIT_ROOT_DIR}/targets/armv7-linux-gnueabihf")
+      endif()
+
+      set(CUDA_TOOLKIT_INCLUDE "${cuda_arm_path}/include" CACHE PATH "include path")
+      set(CUDA_INCLUDE_DIRS ${CUDA_TOOLKIT_INCLUDE})
+
+      set(cuda_arm_library_path "${cuda_arm_path}/lib")
+
+      set(CUDA_CUDART_LIBRARY "${cuda_arm_library_path}/libcudart.so" CACHE FILEPATH "cudart library")
+      set(CUDA_LIBRARIES ${CUDA_CUDART_LIBRARY})
+      set(CUDA_cublas_LIBRARY "${cuda_arm_library_path}/libcublas.so" CACHE FILEPATH "cublas library")
+      set(CUDA_cufft_LIBRARY "${cuda_arm_library_path}/libcufft.so" CACHE FILEPATH "cufft library")
+      set(CUDA_nppc_LIBRARY "${cuda_arm_library_path}/libnppc.so" CACHE FILEPATH "nppc library")
+      set(CUDA_nppi_LIBRARY "${cuda_arm_library_path}/libnppi.so" CACHE FILEPATH "nppi library")
+      set(CUDA_npps_LIBRARY "${cuda_arm_library_path}/libnpps.so" CACHE FILEPATH "npps library")
+      set(CUDA_npp_LIBRARY "${CUDA_nppc_LIBRARY};${CUDA_nppi_LIBRARY};${CUDA_npps_LIBRARY}" CACHE STRING "npp library")
+    else()
+      unset(CUDA_npp_LIBRARY CACHE)
+
+      find_cuda_helper_libs(nppc)
+      find_cuda_helper_libs(nppi)
+      find_cuda_helper_libs(npps)
+
+      set(CUDA_npp_LIBRARY "${CUDA_nppc_LIBRARY};${CUDA_nppi_LIBRARY};${CUDA_npps_LIBRARY}" CACHE STRING "npp library")
+    endif()
   endif()
 
   if(WITH_NVCUVID)
@@ -64,7 +96,11 @@ if(CUDA_FOUND)
   if(CUDA_GENERATION STREQUAL "Fermi")
     set(__cuda_arch_bin "2.0 2.1(2.0)")
   elseif(CUDA_GENERATION STREQUAL "Kepler")
-    set(__cuda_arch_bin "3.0")
+    if(${CUDA_VERSION} VERSION_LESS "5.0")
+      set(__cuda_arch_bin "3.0")
+    else()
+      set(__cuda_arch_bin "3.0 3.5")
+    endif()
   elseif(CUDA_GENERATION STREQUAL "Auto")
     execute_process( COMMAND "${CUDA_NVCC_EXECUTABLE}" "${OpenCV_SOURCE_DIR}/cmake/checks/OpenCVDetectCudaArch.cu" "--run"
                      WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
@@ -78,8 +114,12 @@ if(CUDA_FOUND)
   endif()
 
   if(NOT DEFINED __cuda_arch_bin)
-    set(__cuda_arch_bin "1.1 1.2 1.3 2.0 2.1(2.0) 3.0")
-    set(__cuda_arch_ptx "2.0 3.0")
+    if(${CUDA_VERSION} VERSION_LESS "5.0")
+      set(__cuda_arch_bin "1.1 1.2 1.3 2.0 2.1(2.0) 3.0")
+    else()
+      set(__cuda_arch_bin "1.1 1.2 1.3 2.0 2.1(2.0) 3.0 3.5")
+    endif()
+    set(__cuda_arch_ptx "3.0")
   endif()
 
   set(CUDA_ARCH_BIN ${__cuda_arch_bin} CACHE STRING "Specify 'real' GPU architectures to build binaries for, BIN(PTX) format is supported")
index a1e8bba..2c96274 100644 (file)
@@ -44,7 +44,7 @@ if(OPENCL_FOUND)
   set(OPENCL_INCLUDE_DIRS ${OPENCL_INCLUDE_DIR})
   set(OPENCL_LIBRARIES    ${OPENCL_LIBRARY})
 
-  if(WIN64)
+  if(WIN32 AND X86_64)
     set(CLAMD_POSSIBLE_LIB_SUFFIXES lib64/import)
   elseif(WIN32)
     set(CLAMD_POSSIBLE_LIB_SUFFIXES lib32/import)
index debaaec..54ddac1 100644 (file)
@@ -108,7 +108,7 @@ if(PYTHON_EXECUTABLE)
                         OUTPUT_QUIET
                         ERROR_VARIABLE SPHINX_OUTPUT
                         OUTPUT_STRIP_TRAILING_WHITESPACE)
-        if(SPHINX_OUTPUT MATCHES "^Sphinx v([0-9][^ \n]*)")
+        if(SPHINX_OUTPUT MATCHES "Sphinx v([0-9][^ \n]*)")
           set(SPHINX_VERSION "${CMAKE_MATCH_1}")
           set(HAVE_SPHINX 1)
           message(STATUS "Found Sphinx ${SPHINX_VERSION}: ${SPHINX_BUILD}")
index d1af605..9921d25 100644 (file)
@@ -138,9 +138,14 @@ endfunction()
 # This is auxiliary function called from set_ipp_variables()
 # to set IPP_LIBRARIES variable in IPP 7.x style
 # ------------------------------------------------------------------------
-function(set_ipp_new_libraries)
+function(set_ipp_new_libraries _LATEST_VERSION)
     set(IPP_PREFIX "ipp")
-    set(IPP_SUFFIX "_l")       # static not threaded libs suffix
+    
+    if(${_LATEST_VERSION} VERSION_LESS "8.0")
+        set(IPP_SUFFIX "_l")       # static not threaded libs suffix
+    else()
+        set(IPP_SUFFIX "")       # static not threaded libs suffix
+    endif()
     set(IPP_THRD   "_t")       # static threaded libs suffix
     set(IPPCORE    "core")     # core functionality
     set(IPPSP      "s")        # signal processing
@@ -199,7 +204,9 @@ function(set_ipp_variables _LATEST_VERSION)
         # set INCLUDE and LIB folders
         set(IPP_INCLUDE_DIRS ${IPP_ROOT_DIR}/include PARENT_SCOPE)
 
-        if (IPP_X64)
+        if (APPLE)
+            set(IPP_LIBRARY_DIRS ${IPP_ROOT_DIR}/lib PARENT_SCOPE)
+        elseif (IPP_X64)
             if(NOT EXISTS ${IPP_ROOT_DIR}/lib/intel64)
                 message(SEND_ERROR "IPP EM64T libraries not found")
             endif()
@@ -212,7 +219,7 @@ function(set_ipp_variables _LATEST_VERSION)
         endif()
 
         # set IPP_LIBRARIES variable (7.x lib names)
-        set_ipp_new_libraries()
+        set_ipp_new_libraries(${_LATEST_VERSION})
         set(IPP_LIBRARIES ${IPP_LIBRARIES} PARENT_SCOPE)
         message(STATUS "IPP libs: ${IPP_LIBRARIES}")
 
index 59ce1cd..270853a 100644 (file)
@@ -24,7 +24,6 @@ if(WITH_QT)
     if(Qt5Core_FOUND AND Qt5Gui_FOUND AND Qt5Widgets_FOUND AND Qt5Test_FOUND AND Qt5Concurrent_FOUND)
       set(HAVE_QT5 ON)
       set(HAVE_QT  ON)
-      add_definitions(-DHAVE_QT)
       find_package(Qt5OpenGL)
       if(Qt5OpenGL_FOUND)
         set(QT_QTOPENGL_FOUND ON)
@@ -36,7 +35,6 @@ if(WITH_QT)
     find_package(Qt4 REQUIRED QtCore QtGui QtTest)
     if(QT4_FOUND)
       set(HAVE_QT TRUE)
-      add_definitions(-DHAVE_QT) # We need to define the macro this way, using cvconfig.h does not work
     endif()
   endif()
 endif()
@@ -61,10 +59,18 @@ if(WITH_OPENGL)
       list(APPEND OPENCV_LINKER_LIBS ${OPENGL_LIBRARIES})
       if(QT_QTOPENGL_FOUND)
         set(HAVE_QT_OPENGL TRUE)
-        add_definitions(-DHAVE_QT_OPENGL)
       else()
         ocv_include_directories(${OPENGL_INCLUDE_DIR})
       endif()
     endif()
   endif()
 endif(WITH_OPENGL)
+
+# --- Carbon & Cocoa ---
+if(APPLE)
+  if(WITH_CARBON)
+    set(HAVE_CARBON YES)
+  elseif(NOT IOS)
+    set(HAVE_COCOA YES)
+  endif()
+endif()
index 33e428b..9381350 100644 (file)
@@ -36,56 +36,58 @@ if(WITH_TIFF)
       ocv_parse_header("${TIFF_INCLUDE_DIR}/tiff.h" TIFF_VERSION_LINES TIFF_VERSION_CLASSIC TIFF_VERSION_BIG TIFF_VERSION TIFF_BIGTIFF_VERSION)
     endif()
   endif()
-endif()
 
-if(WITH_TIFF AND NOT TIFF_FOUND)
-  ocv_clear_vars(TIFF_LIBRARY TIFF_LIBRARIES TIFF_INCLUDE_DIR)
+  if(NOT TIFF_FOUND)
+    ocv_clear_vars(TIFF_LIBRARY TIFF_LIBRARIES TIFF_INCLUDE_DIR)
 
-  set(TIFF_LIBRARY libtiff)
-  set(TIFF_LIBRARIES ${TIFF_LIBRARY})
-  add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libtiff")
-  set(TIFF_INCLUDE_DIR "${${TIFF_LIBRARY}_SOURCE_DIR}" "${${TIFF_LIBRARY}_BINARY_DIR}")
-  ocv_parse_header("${${TIFF_LIBRARY}_SOURCE_DIR}/tiff.h" TIFF_VERSION_LINES TIFF_VERSION_CLASSIC TIFF_VERSION_BIG TIFF_VERSION TIFF_BIGTIFF_VERSION)
-endif()
+    set(TIFF_LIBRARY libtiff)
+    set(TIFF_LIBRARIES ${TIFF_LIBRARY})
+    add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libtiff")
+    set(TIFF_INCLUDE_DIR "${${TIFF_LIBRARY}_SOURCE_DIR}" "${${TIFF_LIBRARY}_BINARY_DIR}")
+    ocv_parse_header("${${TIFF_LIBRARY}_SOURCE_DIR}/tiff.h" TIFF_VERSION_LINES TIFF_VERSION_CLASSIC TIFF_VERSION_BIG TIFF_VERSION TIFF_BIGTIFF_VERSION)
+  endif()
 
-if(TIFF_VERSION_CLASSIC AND NOT TIFF_VERSION)
-  set(TIFF_VERSION ${TIFF_VERSION_CLASSIC})
-endif()
+  if(TIFF_VERSION_CLASSIC AND NOT TIFF_VERSION)
+    set(TIFF_VERSION ${TIFF_VERSION_CLASSIC})
+  endif()
 
-if(TIFF_BIGTIFF_VERSION AND NOT TIFF_VERSION_BIG)
-  set(TIFF_VERSION_BIG ${TIFF_BIGTIFF_VERSION})
-endif()
+  if(TIFF_BIGTIFF_VERSION AND NOT TIFF_VERSION_BIG)
+    set(TIFF_VERSION_BIG ${TIFF_BIGTIFF_VERSION})
+  endif()
 
-if(NOT TIFF_VERSION_STRING AND TIFF_INCLUDE_DIR)
-  list(GET TIFF_INCLUDE_DIR 0 _TIFF_INCLUDE_DIR)
-  if(EXISTS "${_TIFF_INCLUDE_DIR}/tiffvers.h")
-    file(STRINGS "${_TIFF_INCLUDE_DIR}/tiffvers.h" tiff_version_str REGEX "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version .*")
-    string(REGEX REPLACE "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version +([^ \\n]*).*" "\\1" TIFF_VERSION_STRING "${tiff_version_str}")
-    unset(tiff_version_str)
+  if(NOT TIFF_VERSION_STRING AND TIFF_INCLUDE_DIR)
+    list(GET TIFF_INCLUDE_DIR 0 _TIFF_INCLUDE_DIR)
+    if(EXISTS "${_TIFF_INCLUDE_DIR}/tiffvers.h")
+      file(STRINGS "${_TIFF_INCLUDE_DIR}/tiffvers.h" tiff_version_str REGEX "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version .*")
+      string(REGEX REPLACE "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version +([^ \\n]*).*" "\\1" TIFF_VERSION_STRING "${tiff_version_str}")
+      unset(tiff_version_str)
+    endif()
+    unset(_TIFF_INCLUDE_DIR)
   endif()
-  unset(_TIFF_INCLUDE_DIR)
+
+  set(HAVE_TIFF YES)
 endif()
 
 # --- libjpeg (optional) ---
-if(WITH_JPEG AND NOT IOS)
+if(WITH_JPEG)
   if(BUILD_JPEG)
     ocv_clear_vars(JPEG_FOUND)
   else()
     include(FindJPEG)
   endif()
-endif()
 
-if(WITH_JPEG AND NOT JPEG_FOUND)
-  ocv_clear_vars(JPEG_LIBRARY JPEG_LIBRARIES JPEG_INCLUDE_DIR)
-
-  set(JPEG_LIBRARY libjpeg)
-  set(JPEG_LIBRARIES ${JPEG_LIBRARY})
-  add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libjpeg")
-  set(JPEG_INCLUDE_DIR "${${JPEG_LIBRARY}_SOURCE_DIR}")
-endif()
+  if(NOT JPEG_FOUND)
+    ocv_clear_vars(JPEG_LIBRARY JPEG_LIBRARIES JPEG_INCLUDE_DIR)
 
-ocv_parse_header("${JPEG_INCLUDE_DIR}/jpeglib.h" JPEG_VERSION_LINES JPEG_LIB_VERSION)
+    set(JPEG_LIBRARY libjpeg)
+    set(JPEG_LIBRARIES ${JPEG_LIBRARY})
+    add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libjpeg")
+    set(JPEG_INCLUDE_DIR "${${JPEG_LIBRARY}_SOURCE_DIR}")
+  endif()
 
+  ocv_parse_header("${JPEG_INCLUDE_DIR}/jpeglib.h" JPEG_VERSION_LINES JPEG_LIB_VERSION)
+  set(HAVE_JPEG YES)
+endif()
 
 # --- libjasper (optional, should be searched after libjpeg) ---
 if(WITH_JASPER)
@@ -94,19 +96,21 @@ if(WITH_JASPER)
   else()
     include(FindJasper)
   endif()
-endif()
 
-if(WITH_JASPER AND NOT JASPER_FOUND)
-  ocv_clear_vars(JASPER_LIBRARY JASPER_LIBRARIES JASPER_INCLUDE_DIR)
+  if(NOT JASPER_FOUND)
+    ocv_clear_vars(JASPER_LIBRARY JASPER_LIBRARIES JASPER_INCLUDE_DIR)
 
-  set(JASPER_LIBRARY libjasper)
-  set(JASPER_LIBRARIES ${JASPER_LIBRARY})
-  add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libjasper")
-  set(JASPER_INCLUDE_DIR "${${JASPER_LIBRARY}_SOURCE_DIR}")
-endif()
+    set(JASPER_LIBRARY libjasper)
+    set(JASPER_LIBRARIES ${JASPER_LIBRARY})
+    add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libjasper")
+    set(JASPER_INCLUDE_DIR "${${JASPER_LIBRARY}_SOURCE_DIR}")
+  endif()
+
+  set(HAVE_JASPER YES)
 
-if(NOT JASPER_VERSION_STRING)
-  ocv_parse_header2(JASPER "${JASPER_INCLUDE_DIR}/jasper/jas_config.h" JAS_VERSION "")
+  if(NOT JASPER_VERSION_STRING)
+    ocv_parse_header2(JASPER "${JASPER_INCLUDE_DIR}/jasper/jas_config.h" JAS_VERSION "")
+  endif()
 endif()
 
 # --- libpng (optional, should be searched after zlib) ---
@@ -117,29 +121,29 @@ if(WITH_PNG AND NOT IOS)
     include(FindPNG)
     if(PNG_FOUND)
       include(CheckIncludeFile)
-      check_include_file("${PNG_PNG_INCLUDE_DIR}/png.h"        HAVE_PNG_H)
       check_include_file("${PNG_PNG_INCLUDE_DIR}/libpng/png.h" HAVE_LIBPNG_PNG_H)
-      if(HAVE_PNG_H)
-        ocv_parse_header("${PNG_PNG_INCLUDE_DIR}/png.h" PNG_VERSION_LINES PNG_LIBPNG_VER_MAJOR PNG_LIBPNG_VER_MINOR PNG_LIBPNG_VER_RELEASE)
-      elseif(HAVE_LIBPNG_PNG_H)
+      if(HAVE_LIBPNG_PNG_H)
         ocv_parse_header("${PNG_PNG_INCLUDE_DIR}/libpng/png.h" PNG_VERSION_LINES PNG_LIBPNG_VER_MAJOR PNG_LIBPNG_VER_MINOR PNG_LIBPNG_VER_RELEASE)
+      else()
+        ocv_parse_header("${PNG_PNG_INCLUDE_DIR}/png.h" PNG_VERSION_LINES PNG_LIBPNG_VER_MAJOR PNG_LIBPNG_VER_MINOR PNG_LIBPNG_VER_RELEASE)
       endif()
     endif()
   endif()
-endif()
 
-if(WITH_PNG AND NOT PNG_FOUND)
-  ocv_clear_vars(PNG_LIBRARY PNG_LIBRARIES PNG_INCLUDE_DIR PNG_PNG_INCLUDE_DIR HAVE_PNG_H HAVE_LIBPNG_PNG_H PNG_DEFINITIONS)
+  if(NOT PNG_FOUND)
+    ocv_clear_vars(PNG_LIBRARY PNG_LIBRARIES PNG_INCLUDE_DIR PNG_PNG_INCLUDE_DIR HAVE_LIBPNG_PNG_H PNG_DEFINITIONS)
 
-  set(PNG_LIBRARY libpng)
-  set(PNG_LIBRARIES ${PNG_LIBRARY})
-  add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libpng")
-  set(PNG_INCLUDE_DIR "${${PNG_LIBRARY}_SOURCE_DIR}")
-  set(PNG_DEFINITIONS "")
-  ocv_parse_header("${PNG_INCLUDE_DIR}/png.h" PNG_VERSION_LINES PNG_LIBPNG_VER_MAJOR PNG_LIBPNG_VER_MINOR PNG_LIBPNG_VER_RELEASE)
-endif()
+    set(PNG_LIBRARY libpng)
+    set(PNG_LIBRARIES ${PNG_LIBRARY})
+    add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libpng")
+    set(PNG_INCLUDE_DIR "${${PNG_LIBRARY}_SOURCE_DIR}")
+    set(PNG_DEFINITIONS "")
+    ocv_parse_header("${PNG_INCLUDE_DIR}/png.h" PNG_VERSION_LINES PNG_LIBPNG_VER_MAJOR PNG_LIBPNG_VER_MINOR PNG_LIBPNG_VER_RELEASE)
+  endif()
 
-set(PNG_VERSION "${PNG_LIBPNG_VER_MAJOR}.${PNG_LIBPNG_VER_MINOR}.${PNG_LIBPNG_VER_RELEASE}")
+  set(HAVE_PNG YES)
+  set(PNG_VERSION "${PNG_LIBPNG_VER_MAJOR}.${PNG_LIBPNG_VER_MINOR}.${PNG_LIBPNG_VER_RELEASE}")
+endif()
 
 # --- OpenEXR (optional) ---
 if(WITH_OPENEXR)
@@ -148,17 +152,24 @@ if(WITH_OPENEXR)
   else()
     include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindOpenEXR.cmake")
   endif()
-endif()
 
-if(WITH_OPENEXR AND NOT OPENEXR_FOUND)
-  ocv_clear_vars(OPENEXR_INCLUDE_PATHS OPENEXR_LIBRARIES OPENEXR_ILMIMF_LIBRARY OPENEXR_VERSION)
+  if(NOT OPENEXR_FOUND)
+    ocv_clear_vars(OPENEXR_INCLUDE_PATHS OPENEXR_LIBRARIES OPENEXR_ILMIMF_LIBRARY OPENEXR_VERSION)
+
+    set(OPENEXR_LIBRARIES IlmImf)
+    set(OPENEXR_ILMIMF_LIBRARY IlmImf)
+    add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/openexr")
+  endif()
 
-  set(OPENEXR_LIBRARIES IlmImf)
-  set(OPENEXR_ILMIMF_LIBRARY IlmImf)
-  add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/openexr")
+  set(HAVE_OPENEXR YES)
 endif()
 
 #cmake 2.8.2 bug - it fails to determine zlib version
 if(ZLIB_FOUND)
   ocv_parse_header2(ZLIB "${ZLIB_INCLUDE_DIR}/zlib.h" ZLIB_VERSION)
-endif()
\ No newline at end of file
+endif()
+
+# --- Apple ImageIO ---
+if(WITH_IMAGEIO)
+  set(HAVE_IMAGEIO YES)
+endif()
index 0ca4828..027b536 100644 (file)
@@ -58,7 +58,14 @@ if(WITH_PVAPI)
       set(_PVAPI_LIBRARY "${_PVAPI_LIBRARY}/${CMAKE_OPENCV_GCC_VERSION_MAJOR}.${CMAKE_OPENCV_GCC_VERSION_MINOR}")
     endif()
 
-    set(PVAPI_LIBRARY "${_PVAPI_LIBRARY}/${CMAKE_STATIC_LIBRARY_PREFIX}PvAPI${CMAKE_STATIC_LIBRARY_SUFFIX}" CACHE PATH "The PvAPI library")
+    if(WIN32)
+      if(MINGW)
+        set(PVAPI_DEFINITIONS "-DPVDECL=__stdcall")
+      endif(MINGW)
+      set(PVAPI_LIBRARY "${_PVAPI_LIBRARY}/PvAPI.lib" CACHE PATH "The PvAPI library")
+    else(WIN32)
+      set(PVAPI_LIBRARY "${_PVAPI_LIBRARY}/${CMAKE_STATIC_LIBRARY_PREFIX}PvAPI${CMAKE_STATIC_LIBRARY_SUFFIX}" CACHE PATH "The PvAPI library")
+    endif(WIN32)
     if(EXISTS "${PVAPI_LIBRARY}")
       set(HAVE_PVAPI TRUE)
     endif()
@@ -228,3 +235,13 @@ if(WIN32)
     list(APPEND HIGHGUI_LIBRARIES winmm)
   endif()
 endif(WIN32)
+
+# --- Apple AV Foundation ---
+if(WITH_AVFOUNDATION)
+  set(HAVE_AVFOUNDATION YES)
+endif()
+
+# --- QuickTime ---
+if(WITH_QUICKTIME)
+  set(HAVE_QUICKTIME YES)
+endif()
index d2d38c9..c7129fe 100644 (file)
@@ -1,13 +1,3 @@
-# ----------------------------------------------------------------------------
-#  Variables for cvconfig.h.cmake
-# ----------------------------------------------------------------------------
-set(PACKAGE "opencv")
-set(PACKAGE_BUGREPORT "opencvlibrary-devel@lists.sourceforge.net")
-set(PACKAGE_NAME "opencv")
-set(PACKAGE_STRING "${PACKAGE} ${OPENCV_VERSION}")
-set(PACKAGE_TARNAME "${PACKAGE}")
-set(PACKAGE_VERSION "${OPENCV_VERSION}")
-
 # platform-specific config file
 configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/cvconfig.h.cmake" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/cvconfig.h")
 
index 49d6707..7bfc7bc 100644 (file)
@@ -12,7 +12,6 @@ set(prefix      "${CMAKE_INSTALL_PREFIX}")
 set(exec_prefix "\${prefix}")
 set(libdir      "") #TODO: need link paths for OpenCV_EXTRA_COMPONENTS
 set(includedir  "\${prefix}/${OPENCV_INCLUDE_INSTALL_PATH}")
-set(VERSION     ${OPENCV_VERSION})
 
 if(CMAKE_BUILD_TYPE MATCHES "Release")
   set(ocv_optkind OPT)
index 81340bd..44e43fc 100644 (file)
@@ -470,8 +470,16 @@ endmacro()
 #   ocv_create_module(<extra link dependencies>)
 #   ocv_create_module(SKIP_LINK)
 macro(ocv_create_module)
+  # The condition we ought to be testing here is whether ocv_add_precompiled_headers will
+  # be called at some point in the future. We can't look into the future, though,
+  # so this will have to do.
+  if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/precomp.hpp")
+    get_native_precompiled_header(${the_module} precomp.hpp)
+  endif()
+
   add_library(${the_module} ${OPENCV_MODULE_TYPE} ${OPENCV_MODULE_${the_module}_HEADERS} ${OPENCV_MODULE_${the_module}_SOURCES}
-    "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/cvconfig.h" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp")
+    "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/cvconfig.h" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp"
+    ${${the_module}_pch})
 
   if(NOT "${ARGN}" STREQUAL "SKIP_LINK")
     target_link_libraries(${the_module} ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_MODULE_${the_module}_DEPS_EXT} ${OPENCV_LINKER_LIBS} ${IPP_LIBS} ${ARGN})
@@ -508,7 +516,8 @@ macro(ocv_create_module)
     )
   endif()
 
-  if(BUILD_SHARED_LIBS)
+  if((NOT DEFINED OPENCV_MODULE_TYPE AND BUILD_SHARED_LIBS)
+      OR (DEFINED OPENCV_MODULE_TYPE AND OPENCV_MODULE_TYPE STREQUAL SHARED))
     if(MSVC)
       set_target_properties(${the_module} PROPERTIES DEFINE_SYMBOL CVAPI_EXPORTS)
     else()
@@ -636,7 +645,9 @@ function(ocv_add_perf_tests)
         set(OPENCV_PERF_${the_module}_SOURCES ${perf_srcs} ${perf_hdrs})
       endif()
 
-      add_executable(${the_target} ${OPENCV_PERF_${the_module}_SOURCES})
+      get_native_precompiled_header(${the_target} test_precomp.hpp)
+
+      add_executable(${the_target} ${OPENCV_PERF_${the_module}_SOURCES} ${${the_target}_pch})
       target_link_libraries(${the_target} ${OPENCV_MODULE_${the_module}_DEPS} ${perf_deps} ${OPENCV_LINKER_LIBS})
       add_dependencies(opencv_perf_tests ${the_target})
 
@@ -684,7 +695,9 @@ function(ocv_add_accuracy_tests)
         set(OPENCV_TEST_${the_module}_SOURCES ${test_srcs} ${test_hdrs})
       endif()
 
-      add_executable(${the_target} ${OPENCV_TEST_${the_module}_SOURCES})
+      get_native_precompiled_header(${the_target} test_precomp.hpp)
+
+      add_executable(${the_target} ${OPENCV_TEST_${the_module}_SOURCES} ${${the_target}_pch})
       target_link_libraries(${the_target} ${OPENCV_MODULE_${the_module}_DEPS} ${test_deps} ${OPENCV_LINKER_LIBS})
       add_dependencies(opencv_tests ${the_target})
 
index cfc4bfa..9b849eb 100644 (file)
@@ -272,12 +272,9 @@ ENDMACRO(ADD_PRECOMPILED_HEADER)
 MACRO(GET_NATIVE_PRECOMPILED_HEADER _targetName _input)
 
     if(CMAKE_GENERATOR MATCHES "^Visual.*$")
-        SET(_dummy_str "#include \"${_input}\"\n"
-"// This is required to suppress LNK4221.  Very annoying.\n"
-"void *g_${_targetName}Dummy = 0\;\n")
+        set(_dummy_str "#include \"${_input}\"\n")
 
-        # Use of cxx extension for generated files (as Qt does)
-        SET(${_targetName}_pch ${CMAKE_CURRENT_BINARY_DIR}/${_targetName}_pch.cxx)
+        set(${_targetName}_pch ${CMAKE_CURRENT_BINARY_DIR}/${_targetName}_pch.cpp)
         if(EXISTS ${${_targetName}_pch})
             # Check if contents is the same, if not rewrite
             # todo
@@ -337,11 +334,7 @@ ENDMACRO(ADD_NATIVE_PRECOMPILED_HEADER)
 
 macro(ocv_add_precompiled_header_to_target the_target pch_header)
   if(PCHSupport_FOUND AND ENABLE_PRECOMPILED_HEADERS AND EXISTS "${pch_header}")
-    if(CMAKE_GENERATOR MATCHES Visual)
-      string(REGEX REPLACE "hpp$" "cpp" ${the_target}_pch "${pch_header}")
-      add_native_precompiled_header(${the_target} ${pch_header})
-      unset(${the_target}_pch)
-    elseif(CMAKE_GENERATOR MATCHES Xcode)
+    if(CMAKE_GENERATOR MATCHES "^Visual" OR CMAKE_GENERATOR MATCHES Xcode)
       add_native_precompiled_header(${the_target} ${pch_header})
     elseif(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_GENERATOR MATCHES "Makefiles|Ninja")
       add_precompiled_header(${the_target} ${pch_header})
diff --git a/cmake/checks/winrttest.cpp b/cmake/checks/winrttest.cpp
new file mode 100644 (file)
index 0000000..4172afe
--- /dev/null
@@ -0,0 +1,6 @@
+#include <wrl/client.h>
+
+int main(int, char**)
+{
+       return 0;
+}
\ No newline at end of file
index db46af4..7587eef 100644 (file)
@@ -1,20 +1,20 @@
-/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
-   systems. This function is required for `alloca.c' support on those systems.
-   */
-#cmakedefine  CRAY_STACKSEG_END
+/* OpenCV compiled as static or dynamic libs */
+#cmakedefine BUILD_SHARED_LIBS
 
-/* Define to 1 if using `alloca.c'. */
-#cmakedefine C_ALLOCA
+/* Compile for 'real' NVIDIA GPU architectures */
+#define CUDA_ARCH_BIN "${OPENCV_CUDA_ARCH_BIN}"
 
-/* Define to 1 if you have `alloca', as a function or macro. */
-#cmakedefine HAVE_ALLOCA 1
+/* Create PTX or BIN for 1.0 compute capability */
+#cmakedefine CUDA_ARCH_BIN_OR_PTX_10
 
-/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
-   */
-#cmakedefine HAVE_ALLOCA_H 1
+/* NVIDIA GPU features are used */
+#define CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES}"
 
-/* Video for Windows support */
-#cmakedefine HAVE_VFW
+/* Compile for 'virtual' NVIDIA PTX architectures */
+#define CUDA_ARCH_PTX "${OPENCV_CUDA_ARCH_PTX}"
+
+/* AVFoundation video libraries */
+#cmakedefine HAVE_AVFOUNDATION
 
 /* V4L capturing support */
 #cmakedefine HAVE_CAMV4L
 /* V4L2 capturing support */
 #cmakedefine HAVE_CAMV4L2
 
-/* V4L2 capturing support in videoio.h */
-#cmakedefine HAVE_VIDEOIO
-
-/* V4L/V4L2 capturing support via libv4l */
-#cmakedefine HAVE_LIBV4L
-
 /* Carbon windowing environment */
 #cmakedefine HAVE_CARBON
 
+/* AMD's Basic Linear Algebra Subprograms Library*/
+#cmakedefine HAVE_CLAMDBLAS
+
+/* AMD's OpenCL Fast Fourier Transform Library*/
+#cmakedefine HAVE_CLAMDFFT
+
+/* Cocoa API */
+#cmakedefine HAVE_COCOA
+
+/* C= */
+#cmakedefine HAVE_CSTRIPES
+
+/* NVidia Cuda Basic Linear Algebra Subprograms (BLAS) API*/
+#cmakedefine HAVE_CUBLAS
+
+/* NVidia Cuda Runtime API*/
+#cmakedefine HAVE_CUDA
+
+/* NVidia Cuda Fast Fourier Transform (FFT) API*/
+#cmakedefine HAVE_CUFFT
+
 /* IEEE1394 capturing support */
 #cmakedefine HAVE_DC1394
 
 /* IEEE1394 capturing support - libdc1394 v2.x */
 #cmakedefine HAVE_DC1394_2
 
-/* ffmpeg in Gentoo */
-#cmakedefine HAVE_GENTOO_FFMPEG
+/* DirectShow Video Capture library */
+#cmakedefine HAVE_DSHOW
 
-/* FFMpeg video library */
-#cmakedefine  HAVE_FFMPEG
+/* Eigen Matrix & Linear Algebra Library */
+#cmakedefine HAVE_EIGEN
 
-/* FFMpeg version flag */
-#cmakedefine  NEW_FFMPEG
+/* FFMpeg video library */
+#cmakedefine HAVE_FFMPEG
 
 /* ffmpeg's libswscale */
-#cmakedefine  HAVE_FFMPEG_SWSCALE
+#cmakedefine HAVE_FFMPEG_SWSCALE
+
+/* ffmpeg in Gentoo */
+#cmakedefine HAVE_GENTOO_FFMPEG
 
 /* GStreamer multimedia framework */
-#cmakedefine  HAVE_GSTREAMER
+#cmakedefine HAVE_GSTREAMER
 
 /* GTK+ 2.0 Thread support */
-#cmakedefine  HAVE_GTHREAD
+#cmakedefine HAVE_GTHREAD
+
+/* Windows Runtime support */
+#cmakedefine HAVE_WINRT
 
 /* Win32 UI */
 #cmakedefine HAVE_WIN32UI
 
 /* GTK+ 2.x toolkit */
-#cmakedefine  HAVE_GTK
-
-/* OpenEXR codec */
-#cmakedefine  HAVE_ILMIMF
+#cmakedefine HAVE_GTK
 
 /* Apple ImageIO Framework */
-#cmakedefine  HAVE_IMAGEIO
+#cmakedefine HAVE_IMAGEIO
 
-/* Define to 1 if you have the <inttypes.h> header file. */
-#cmakedefine  HAVE_INTTYPES_H 1
+/* Intel Integrated Performance Primitives */
+#cmakedefine HAVE_IPP
 
 /* JPEG-2000 codec */
-#cmakedefine  HAVE_JASPER
+#cmakedefine HAVE_JASPER
 
 /* IJG JPEG codec */
-#cmakedefine  HAVE_JPEG
-
-/* Define to 1 if you have the `dl' library (-ldl). */
-#cmakedefine  HAVE_LIBDL 1
-
-/* Define to 1 if you have the `gomp' library (-lgomp). */
-#cmakedefine  HAVE_LIBGOMP 1
-
-/* Define to 1 if you have the `m' library (-lm). */
-#cmakedefine  HAVE_LIBM 1
+#cmakedefine HAVE_JPEG
 
 /* libpng/png.h needs to be included */
-#cmakedefine  HAVE_LIBPNG_PNG_H
+#cmakedefine HAVE_LIBPNG_PNG_H
 
-/* Define to 1 if you have the `pthread' library (-lpthread). */
-#cmakedefine  HAVE_LIBPTHREAD 1
-
-/* Define to 1 if you have the `lrint' function. */
-#cmakedefine  HAVE_LRINT 1
-
-/* PNG codec */
-#cmakedefine  HAVE_PNG
-
-/* Define to 1 if you have the `png_get_valid' function. */
-#cmakedefine  HAVE_PNG_GET_VALID 1
-
-/* png.h needs to be included */
-#cmakedefine  HAVE_PNG_H
-
-/* Define to 1 if you have the `png_set_tRNS_to_alpha' function. */
-#cmakedefine  HAVE_PNG_SET_TRNS_TO_ALPHA 1
-
-/* QuickTime video libraries */
-#cmakedefine  HAVE_QUICKTIME
+/* V4L/V4L2 capturing support via libv4l */
+#cmakedefine HAVE_LIBV4L
 
-/* AVFoundation video libraries */
-#cmakedefine  HAVE_AVFOUNDATION
+/* Microsoft Media Foundation Capture library */
+#cmakedefine HAVE_MSMF
 
-/* TIFF codec */
-#cmakedefine  HAVE_TIFF
+/* NVidia Video Decoding API*/
+#cmakedefine HAVE_NVCUVID
 
-/* Unicap video capture library */
-#cmakedefine  HAVE_UNICAP
+/* OpenCL Support */
+#cmakedefine HAVE_OPENCL
 
-/* Define to 1 if you have the <unistd.h> header file. */
-#cmakedefine  HAVE_UNISTD_H 1
+/* OpenEXR codec */
+#cmakedefine HAVE_OPENEXR
 
-/* Xine video library */
-#cmakedefine  HAVE_XINE
+/* OpenGL support*/
+#cmakedefine HAVE_OPENGL
 
 /* OpenNI library */
-#cmakedefine  HAVE_OPENNI
-
-/* LZ77 compression/decompression library (used for PNG) */
-#cmakedefine  HAVE_ZLIB
-
-/* Intel Integrated Performance Primitives */
-#cmakedefine  HAVE_IPP
-
-/* OpenCV compiled as static or dynamic libs */
-#cmakedefine  BUILD_SHARED_LIBS
-
-/* Name of package */
-#define  PACKAGE "${PACKAGE}"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define  PACKAGE_BUGREPORT "${PACKAGE_BUGREPORT}"
-
-/* Define to the full name of this package. */
-#define  PACKAGE_NAME "${PACKAGE_NAME}"
-
-/* Define to the full name and version of this package. */
-#define  PACKAGE_STRING "${PACKAGE_STRING}"
+#cmakedefine HAVE_OPENNI
 
-/* Define to the one symbol short name of this package. */
-#define  PACKAGE_TARNAME "${PACKAGE_TARNAME}"
-
-/* Define to the version of this package. */
-#define  PACKAGE_VERSION "${PACKAGE_VERSION}"
+/* PNG codec */
+#cmakedefine HAVE_PNG
 
-/* If using the C implementation of alloca, define if you know the
-   direction of stack growth for your system; otherwise it will be
-   automatically deduced at runtime.
-    STACK_DIRECTION > 0 => grows toward higher addresses
-    STACK_DIRECTION < 0 => grows toward lower addresses
-    STACK_DIRECTION = 0 => direction of growth unknown */
-#cmakedefine  STACK_DIRECTION
+/* Qt support */
+#cmakedefine HAVE_QT
 
-/* Version number of package */
-#define  VERSION "${PACKAGE_VERSION}"
+/* Qt OpenGL support */
+#cmakedefine HAVE_QT_OPENGL
 
-/* Define to 1 if your processor stores words with the most significant byte
-   first (like Motorola and SPARC, unlike Intel and VAX). */
-#cmakedefine  WORDS_BIGENDIAN
+/* QuickTime video libraries */
+#cmakedefine HAVE_QUICKTIME
 
 /* Intel Threading Building Blocks */
-#cmakedefine  HAVE_TBB
-
-/* C= */
-#cmakedefine  HAVE_CSTRIPES
-
-/* Eigen Matrix & Linear Algebra Library */
-#cmakedefine  HAVE_EIGEN
-
-/* NVidia Cuda Runtime API*/
-#cmakedefine HAVE_CUDA
-
-/* NVidia Cuda Fast Fourier Transform (FFT) API*/
-#cmakedefine HAVE_CUFFT
-
-/* NVidia Cuda Basic Linear Algebra Subprograms (BLAS) API*/
-#cmakedefine HAVE_CUBLAS
+#cmakedefine HAVE_TBB
 
-/* NVidia Video Decoding API*/
-#cmakedefine HAVE_NVCUVID
-
-/* Compile for 'real' NVIDIA GPU architectures */
-#define CUDA_ARCH_BIN "${OPENCV_CUDA_ARCH_BIN}"
-
-/* Compile for 'virtual' NVIDIA PTX architectures */
-#define CUDA_ARCH_PTX "${OPENCV_CUDA_ARCH_PTX}"
-
-/* NVIDIA GPU features are used */
-#define CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES}"
-
-/* Create PTX or BIN for 1.0 compute capability */
-#cmakedefine CUDA_ARCH_BIN_OR_PTX_10
-
-/* OpenCL Support */
-#cmakedefine HAVE_OPENCL
+/* TIFF codec */
+#cmakedefine HAVE_TIFF
 
-/* AMD's OpenCL Fast Fourier Transform Library*/
-#cmakedefine HAVE_CLAMDFFT
+/* Unicap video capture library */
+#cmakedefine HAVE_UNICAP
 
-/* AMD's Basic Linear Algebra Subprograms Library*/
-#cmakedefine HAVE_CLAMDBLAS
+/* Video for Windows support */
+#cmakedefine HAVE_VFW
 
-/* DirectShow Video Capture library */
-#cmakedefine HAVE_DSHOW
+/* V4L2 capturing support in videoio.h */
+#cmakedefine HAVE_VIDEOIO
 
-/* Microsoft Media Foundation Capture library */
-#cmakedefine HAVE_MSMF
+/* Win32 UI */
+#cmakedefine HAVE_WIN32UI
 
 /* XIMEA camera support */
 #cmakedefine HAVE_XIMEA
 
-/* OpenGL support*/
-#cmakedefine HAVE_OPENGL
+/* Xine video library */
+#cmakedefine HAVE_XINE
+
+/* Define to 1 if your processor stores words with the most significant byte
+   first (like Motorola and SPARC, unlike Intel and VAX). */
+#cmakedefine WORDS_BIGENDIAN
 
-/* Clp support */
-#cmakedefine HAVE_CLP
index 4f6415c..c9dedb0 100644 (file)
@@ -8,6 +8,6 @@ includedir_new=@includedir@
 
 Name: OpenCV
 Description: Open Source Computer Vision Library
-Version: @VERSION@
+Version: @OPENCV_VERSION@
 Libs: @OpenCV_LIB_COMPONENTS@
 Cflags: -I${includedir_old} -I${includedir_new}
index 70f4809..63f3a45 100644 (file)
@@ -49,7 +49,7 @@ if(BUILD_DOCS AND HAVE_SPHINX)
     set(toc_file "${OPENCV_MODULE_opencv_${mod}_LOCATION}/doc/${mod}.rst")
     if(EXISTS "${toc_file}")
       file(RELATIVE_PATH toc_file "${OpenCV_SOURCE_DIR}/modules" "${toc_file}")
-      set(OPENCV_REFMAN_TOC "${OPENCV_REFMAN_TOC}   ${toc_file}\r\n")
+      set(OPENCV_REFMAN_TOC "${OPENCV_REFMAN_TOC}   ${toc_file}\n")
     endif()
   endforeach()
 
index a376c97..d0d4303 100644 (file)
                   {% if theme_lang == 'c' %}
                   {% endif %}
                   {% if theme_lang == 'cpp' %}
-                    <li>Try the <a href="http://docs.opencv.org/trunk/opencv_cheatsheet.pdf">Cheatsheet</a>.</li>
+                    <li>Try the <a href="http://docs.opencv.org/opencv_cheatsheet.pdf">Cheatsheet</a>.</li>
                   {% endif %}
                   {% if theme_lang == 'py' %}
                     <li>Try the <a href="cookbook.html">Cookbook</a>.</li>
index f3f7aec..312a1c2 100755 (executable)
@@ -284,120 +284,122 @@ latex_domain_indices = True
 # (source start file, name, description, authors, manual section).
 man_pages = [
     ('index', 'opencv', u'The OpenCV Reference Manual',
-     [u'opencv-dev@itseez.com'], 1)
+     [u'admin@opencv.org'], 1)
 ]
 
 # ---- External links for tutorials -----------------
 extlinks = {
-            'basicstructures' : ('http://opencv.itseez.com/modules/core/doc/basic_structures.html#%s', None),
-            'oldbasicstructures' : ('http://opencv.itseez.com/modules/core/doc/old_basic_structures.html#%s', None),
-            'readwriteimagevideo' : ('http://opencv.itseez.com/modules/highgui/doc/reading_and_writing_images_and_video.html#%s', None),
-            'operationsonarrays' : ('http://opencv.itseez.com/modules/core/doc/operations_on_arrays.html#%s', None),
-            'utilitysystemfunctions':('http://opencv.itseez.com/modules/core/doc/utility_and_system_functions_and_macros.html#%s', None),
-            'imgprocfilter':('http://opencv.itseez.com/modules/imgproc/doc/filtering.html#%s', None),
-            'svms':('http://opencv.itseez.com/modules/ml/doc/support_vector_machines.html#%s', None),
-            'drawingfunc':('http://opencv.itseez.com/modules/core/doc/drawing_functions.html#%s', None),
-            'xmlymlpers':('http://opencv.itseez.com/modules/core/doc/xml_yaml_persistence.html#%s', None),
-            'hgvideo' : ('http://opencv.itseez.com/modules/highgui/doc/reading_and_writing_images_and_video.html#%s', None),
-            'gpuinit' : ('http://opencv.itseez.com/modules/gpu/doc/initalization_and_information.html#%s', None),
-            'gpudatastructure' : ('http://opencv.itseez.com/modules/gpu/doc/data_structures.html#%s', None),
-            'gpuopmatrices' : ('http://opencv.itseez.com/modules/gpu/doc/operations_on_matrices.html#%s', None),
-            'gpuperelement' : ('http://opencv.itseez.com/modules/gpu/doc/per_element_operations.html#%s', None),
-            'gpuimgproc' : ('http://opencv.itseez.com/modules/gpu/doc/image_processing.html#%s', None),
-            'gpumatrixreduct' : ('http://opencv.itseez.com/modules/gpu/doc/matrix_reductions.html#%s', None),
-            'filtering':('http://opencv.itseez.com/modules/imgproc/doc/filtering.html#%s', None),
-            'flann' : ('http://opencv.itseez.com/modules/flann/doc/flann_fast_approximate_nearest_neighbor_search.html#%s', None ),
-            'calib3d' : ('http://opencv.itseez.com/trunk/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#%s', None ),
-            'feature2d' : ('http://opencv.itseez.com/trunk/modules/imgproc/doc/feature_detection.html#%s', None ),
-            'imgproc_geometric' : ('http://opencv.itseez.com/trunk/modules/imgproc/doc/geometric_transformations.html#%s', None ),
-
-            'opencv_group' : ('http://tech.groups.yahoo.com/group/OpenCV/%s', None),
-
-            'cvt_color': ('http://opencv.itseez.com/modules/imgproc/doc/miscellaneous_transformations.html?highlight=cvtcolor#cvtcolor%s', None),
-            'imread':    ('http://opencv.itseez.com/modules/highgui/doc/reading_and_writing_images_and_video.html?highlight=imread#imread%s', None),
-            'imwrite':   ('http://opencv.itseez.com/modules/highgui/doc/reading_and_writing_images_and_video.html?highlight=imwrite#imwrite%s', None),
-            'imshow':    ('http://opencv.itseez.com/modules/highgui/doc/user_interface.html?highlight=imshow#imshow%s', None),
-            'named_window': ('http://opencv.itseez.com/modules/highgui/doc/user_interface.html?highlight=namedwindow#namedwindow%s', None),
-            'wait_key': ('http://opencv.itseez.com/modules/highgui/doc/user_interface.html?highlight=waitkey#waitkey%s', None),
-            'add_weighted': ('http://opencv.itseez.com/modules/core/doc/operations_on_arrays.html?highlight=addweighted#addweighted%s', None),
-            'saturate_cast': ('http://opencv.itseez.com/modules/core/doc/utility_and_system_functions_and_macros.html?highlight=saturate_cast#saturate-cast%s', None),
-            'mat_zeros': ('http://opencv.itseez.com/modules/core/doc/basic_structures.html?highlight=zeros#mat-zeros%s', None),
-            'convert_to': ('http://opencv.itseez.com/modules/core/doc/basic_structures.html#mat-convertto%s', None),
-            'create_trackbar': ('http://opencv.itseez.com/modules/highgui/doc/user_interface.html?highlight=createtrackbar#createtrackbar%s', None),
-            'point': ('http://opencv.itseez.com/modules/core/doc/basic_structures.html#point%s', None),
-            'scalar': ('http://opencv.itseez.com/modules/core/doc/basic_structures.html#scalar%s', None),
-            'line': ('http://opencv.itseez.com/modules/core/doc/drawing_functions.html#line%s', None),
-            'ellipse': ('http://opencv.itseez.com/modules/core/doc/drawing_functions.html#ellipse%s', None),
-            'rectangle': ('http://opencv.itseez.com/modules/core/doc/drawing_functions.html#rectangle%s', None),
-            'circle': ('http://opencv.itseez.com/modules/core/doc/drawing_functions.html#circle%s', None),
-            'fill_poly': ('http://opencv.itseez.com/modules/core/doc/drawing_functions.html#fillpoly%s', None),
-            'rng': ('http://opencv.itseez.com/modules/core/doc/operations_on_arrays.html?highlight=rng#rng%s', None),
-            'put_text': ('http://opencv.itseez.com/modules/core/doc/drawing_functions.html#puttext%s', None),
-            'gaussian_blur': ('http://opencv.itseez.com/modules/imgproc/doc/filtering.html?highlight=gaussianblur#gaussianblur%s', None),
-            'blur': ('http://opencv.itseez.com/modules/imgproc/doc/filtering.html?highlight=blur#blur%s', None),
-            'median_blur': ('http://opencv.itseez.com/modules/imgproc/doc/filtering.html?highlight=medianblur#medianblur%s', None),
-            'bilateral_filter': ('http://opencv.itseez.com/modules/imgproc/doc/filtering.html?highlight=bilateralfilter#bilateralfilter%s', None),
-            'erode': ('http://opencv.itseez.com/modules/imgproc/doc/filtering.html?highlight=erode#erode%s', None),
-            'dilate': ('http://opencv.itseez.com/modules/imgproc/doc/filtering.html?highlight=dilate#dilate%s', None),
-            'get_structuring_element': ('http://opencv.itseez.com/modules/imgproc/doc/filtering.html?highlight=getstructuringelement#getstructuringelement%s', None),
-            'flood_fill': ( 'http://opencv.itseez.com/modules/imgproc/doc/miscellaneous_transformations.html?highlight=floodfill#floodfill%s', None),
-            'morphology_ex': ('http://opencv.itseez.com/modules/imgproc/doc/filtering.html?highlight=morphologyex#morphologyex%s', None),
-            'pyr_down': ('http://opencv.itseez.com/modules/imgproc/doc/filtering.html?highlight=pyrdown#pyrdown%s', None),
-            'pyr_up': ('http://opencv.itseez.com/modules/imgproc/doc/filtering.html?highlight=pyrup#pyrup%s', None),
-            'resize': ('http://opencv.itseez.com/modules/imgproc/doc/geometric_transformations.html?highlight=resize#resize%s', None),
-            'threshold': ('http://opencv.itseez.com/modules/imgproc/doc/miscellaneous_transformations.html?highlight=threshold#threshold%s', None),
-            'filter2d': ('http://opencv.itseez.com/modules/imgproc/doc/filtering.html?highlight=filter2d#filter2d%s', None),
-            'copy_make_border': ('http://opencv.itseez.com/modules/imgproc/doc/filtering.html?highlight=copymakeborder#copymakeborder%s', None),
-            'sobel': ('http://opencv.itseez.com/modules/imgproc/doc/filtering.html?highlight=sobel#sobel%s', None),
-            'scharr': ('http://opencv.itseez.com/modules/imgproc/doc/filtering.html?highlight=scharr#scharr%s', None),
-            'laplacian': ('http://opencv.itseez.com/modules/imgproc/doc/filtering.html?highlight=laplacian#laplacian%s', None),
-            'canny': ('http://opencv.itseez.com/modules/imgproc/doc/feature_detection.html?highlight=canny#canny%s', None),
-            'copy_to': ('http://opencv.itseez.com/modules/core/doc/basic_structures.html?highlight=copyto#mat-copyto%s', None),
-            'hough_lines' : ('http://opencv.itseez.com/modules/imgproc/doc/feature_detection.html?highlight=houghlines#houghlines%s', None),
-            'hough_lines_p' : ('http://opencv.itseez.com/modules/imgproc/doc/feature_detection.html?highlight=houghlinesp#houghlinesp%s', None),
-            'hough_circles' : ('http://opencv.itseez.com/modules/imgproc/doc/feature_detection.html?highlight=houghcircles#houghcircles%s', None),
-            'remap' : ('http://opencv.itseez.com/modules/imgproc/doc/geometric_transformations.html?highlight=remap#remap%s', None),
-            'warp_affine' : ('http://opencv.itseez.com/modules/imgproc/doc/geometric_transformations.html?highlight=warpaffine#warpaffine%s' , None),
-            'get_rotation_matrix_2d' : ('http://opencv.itseez.com/modules/imgproc/doc/geometric_transformations.html?highlight=getrotationmatrix2d#getrotationmatrix2d%s', None),
-            'get_affine_transform' : ('http://opencv.itseez.com/modules/imgproc/doc/geometric_transformations.html?highlight=getaffinetransform#getaffinetransform%s', None),
-            'equalize_hist' : ('http://opencv.itseez.com/modules/imgproc/doc/histograms.html?highlight=equalizehist#equalizehist%s', None),
-            'split' : ('http://opencv.itseez.com/modules/core/doc/operations_on_arrays.html?highlight=split#split%s', None),
-            'calc_hist' : ('http://opencv.itseez.com/modules/imgproc/doc/histograms.html?highlight=calchist#calchist%s', None),
-            'normalize' : ('http://opencv.itseez.com/modules/core/doc/operations_on_arrays.html?highlight=normalize#normalize%s', None),
-            'match_template' : ('http://opencv.itseez.com/modules/imgproc/doc/object_detection.html?highlight=matchtemplate#matchtemplate%s', None),
-            'min_max_loc' : ('http://opencv.itseez.com/modules/core/doc/operations_on_arrays.html?highlight=minmaxloc#minmaxloc%s', None),
-            'mix_channels' : ( 'http://opencv.itseez.com/modules/core/doc/operations_on_arrays.html?highlight=mixchannels#mixchannels%s', None),
-            'calc_back_project' : ('http://opencv.itseez.com/modules/imgproc/doc/histograms.html?highlight=calcbackproject#calcbackproject%s', None),
-            'compare_hist' : ('http://opencv.itseez.com/modules/imgproc/doc/histograms.html?highlight=comparehist#comparehist%s', None),
-            'corner_harris' : ('http://opencv.itseez.com/modules/imgproc/doc/feature_detection.html?highlight=cornerharris#cornerharris%s', None),
-            'good_features_to_track' : ('http://opencv.itseez.com/modules/imgproc/doc/feature_detection.html?highlight=goodfeaturestotrack#goodfeaturestotrack%s', None),
-            'corner_min_eigenval' : ('http://opencv.itseez.com/modules/imgproc/doc/feature_detection.html?highlight=cornermineigenval#cornermineigenval%s', None),
-            'corner_eigenvals_and_vecs' : ('http://opencv.itseez.com/modules/imgproc/doc/feature_detection.html?highlight=cornereigenvalsandvecs#cornereigenvalsandvecs%s', None),
-            'corner_sub_pix' : ('http://opencv.itseez.com/modules/imgproc/doc/feature_detection.html?highlight=cornersubpix#cornersubpix%s', None),
-            'find_contours' : ('http://opencv.itseez.com/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=findcontours#findcontours%s', None),
-            'convex_hull' : ('http://opencv.itseez.com/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=convexhull#convexhull%s', None),
-            'draw_contours' : ('http://opencv.itseez.com/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=drawcontours#drawcontours%s', None),
-            'bounding_rect' : ('http://opencv.itseez.com/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=boundingrect#boundingrect%s', None),
-            'min_enclosing_circle' : ('http://opencv.itseez.com/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=minenclosingcircle#minenclosingcircle%s', None),
-            'min_area_rect' : ('http://opencv.itseez.com/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=minarearect#minarearect%s', None),
-            'fit_ellipse' : ('http://opencv.itseez.com/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=fitellipse#fitellipse%s', None),
-            'moments' : ('http://opencv.itseez.com/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=moments#moments%s', None),
-            'contour_area' : ('http://opencv.itseez.com/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=contourarea#contourarea%s', None),
-            'arc_length' : ('http://opencv.itseez.com/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=arclength#arclength%s', None),
-            'point_polygon_test' : ('http://opencv.itseez.com/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=pointpolygontest#pointpolygontest%s', None),
-            'feature_detector' : ( 'http://opencv.itseez.com/modules/features2d/doc/common_interfaces_of_feature_detectors.html?highlight=featuredetector#FeatureDetector%s', None),
-            'feature_detector_detect' : ('http://opencv.itseez.com/modules/features2d/doc/common_interfaces_of_feature_detectors.html?highlight=detect#featuredetector-detect%s', None ),
-            'surf_feature_detector' : ('http://opencv.itseez.com/modules/features2d/doc/common_interfaces_of_feature_detectors.html?highlight=surffeaturedetector#surffeaturedetector%s', None ),
-            'draw_keypoints' : ('http://opencv.itseez.com/modules/features2d/doc/drawing_function_of_keypoints_and_matches.html?highlight=drawkeypoints#drawkeypoints%s', None ),
-            'descriptor_extractor': ( 'http://opencv.itseez.com/modules/features2d/doc/common_interfaces_of_descriptor_extractors.html?highlight=descriptorextractor#descriptorextractor%s', None ),
-            'descriptor_extractor_compute' : ( 'http://opencv.itseez.com/modules/features2d/doc/common_interfaces_of_descriptor_extractors.html?highlight=compute#descriptorextractor-compute%s', None ),
-            'surf_descriptor_extractor' : ( 'http://opencv.itseez.com/modules/features2d/doc/common_interfaces_of_descriptor_extractors.html?highlight=surfdescriptorextractor#surfdescriptorextractor%s', None ),
-            'draw_matches' : ( 'http://opencv.itseez.com/modules/features2d/doc/drawing_function_of_keypoints_and_matches.html?highlight=drawmatches#drawmatches%s', None ),
-            'find_homography' : ('http://opencv.itseez.com/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html?highlight=findhomography#findhomography%s', None),
-            'perspective_transform' : ('http://opencv.itseez.com/modules/core/doc/operations_on_arrays.html?highlight=perspectivetransform#perspectivetransform%s', None ),
-            'flann_based_matcher' : ('http://opencv.itseez.com/modules/features2d/doc/common_interfaces_of_descriptor_matchers.html?highlight=flannbasedmatcher#flannbasedmatcher%s', None),
-            'brute_force_matcher' : ('http://opencv.itseez.com/modules/features2d/doc/common_interfaces_of_descriptor_matchers.html?highlight=bruteforcematcher#bruteforcematcher%s', None ),
-            'cascade_classifier' : ('http://opencv.itseez.com/modules/objdetect/doc/cascade_classification.html?highlight=cascadeclassifier#cascadeclassifier%s', None ),
-            'cascade_classifier_load' : ('http://opencv.itseez.com/modules/objdetect/doc/cascade_classification.html?highlight=load#cascadeclassifier-load%s', None ),
-            'cascade_classifier_detect_multiscale' : ('http://opencv.itseez.com/modules/objdetect/doc/cascade_classification.html?highlight=detectmultiscale#cascadeclassifier-detectmultiscale%s', None )
+            'basicstructures' : ('http://docs.opencv.org/modules/core/doc/basic_structures.html#%s', None),
+            'oldbasicstructures' : ('http://docs.opencv.org/modules/core/doc/old_basic_structures.html#%s', None),
+            'readwriteimagevideo' : ('http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html#%s', None),
+            'operationsonarrays' : ('http://docs.opencv.org/modules/core/doc/operations_on_arrays.html#%s', None),
+            'utilitysystemfunctions':('http://docs.opencv.org/modules/core/doc/utility_and_system_functions_and_macros.html#%s', None),
+            'imgprocfilter':('http://docs.opencv.org/modules/imgproc/doc/filtering.html#%s', None),
+            'svms':('http://docs.opencv.org/modules/ml/doc/support_vector_machines.html#%s', None),
+            'drawingfunc':('http://docs.opencv.org/modules/core/doc/drawing_functions.html#%s', None),
+            'xmlymlpers':('http://docs.opencv.org/modules/core/doc/xml_yaml_persistence.html#%s', None),
+            'hgvideo' : ('http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html#%s', None),
+            'gpuinit' : ('http://docs.opencv.org/modules/gpu/doc/initalization_and_information.html#%s', None),
+            'gpudatastructure' : ('http://docs.opencv.org/modules/gpu/doc/data_structures.html#%s', None),
+            'gpuopmatrices' : ('http://docs.opencv.org/modules/gpu/doc/operations_on_matrices.html#%s', None),
+            'gpuperelement' : ('http://docs.opencv.org/modules/gpu/doc/per_element_operations.html#%s', None),
+            'gpuimgproc' : ('http://docs.opencv.org/modules/gpu/doc/image_processing.html#%s', None),
+            'gpumatrixreduct' : ('http://docs.opencv.org/modules/gpu/doc/matrix_reductions.html#%s', None),
+            'filtering':('http://docs.opencv.org/modules/imgproc/doc/filtering.html#%s', None),
+            'flann' : ('http://docs.opencv.org/modules/flann/doc/flann_fast_approximate_nearest_neighbor_search.html#%s', None ),
+            'calib3d' : ('http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#%s', None ),
+            'feature2d' : ('http://docs.opencv.org/modules/imgproc/doc/feature_detection.html#%s', None ),
+            'imgproc_geometric' : ('http://docs.opencv.org/modules/imgproc/doc/geometric_transformations.html#%s', None ),
+
+            # 'opencv_group' : ('http://answers.opencv.org/%s', None),
+            'opencv_qa' : ('http://answers.opencv.org/%s', None),
+            'how_to_contribute' : ('http://code.opencv.org/projects/opencv/wiki/How_to_contribute/%s', None),
+
+            'cvt_color': ('http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html?highlight=cvtcolor#cvtcolor%s', None),
+            'imread':    ('http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html?highlight=imread#imread%s', None),
+            'imwrite':   ('http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html?highlight=imwrite#imwrite%s', None),
+            'imshow':    ('http://docs.opencv.org/modules/highgui/doc/user_interface.html?highlight=imshow#imshow%s', None),
+            'named_window': ('http://docs.opencv.org/modules/highgui/doc/user_interface.html?highlight=namedwindow#namedwindow%s', None),
+            'wait_key': ('http://docs.opencv.org/modules/highgui/doc/user_interface.html?highlight=waitkey#waitkey%s', None),
+            'add_weighted': ('http://docs.opencv.org/modules/core/doc/operations_on_arrays.html?highlight=addweighted#addweighted%s', None),
+            'saturate_cast': ('http://docs.opencv.org/modules/core/doc/utility_and_system_functions_and_macros.html?highlight=saturate_cast#saturate-cast%s', None),
+            'mat_zeros': ('http://docs.opencv.org/modules/core/doc/basic_structures.html?highlight=zeros#mat-zeros%s', None),
+            'convert_to': ('http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-convertto%s', None),
+            'create_trackbar': ('http://docs.opencv.org/modules/highgui/doc/user_interface.html?highlight=createtrackbar#createtrackbar%s', None),
+            'point': ('http://docs.opencv.org/modules/core/doc/basic_structures.html#point%s', None),
+            'scalar': ('http://docs.opencv.org/modules/core/doc/basic_structures.html#scalar%s', None),
+            'line': ('http://docs.opencv.org/modules/core/doc/drawing_functions.html#line%s', None),
+            'ellipse': ('http://docs.opencv.org/modules/core/doc/drawing_functions.html#ellipse%s', None),
+            'rectangle': ('http://docs.opencv.org/modules/core/doc/drawing_functions.html#rectangle%s', None),
+            'circle': ('http://docs.opencv.org/modules/core/doc/drawing_functions.html#circle%s', None),
+            'fill_poly': ('http://docs.opencv.org/modules/core/doc/drawing_functions.html#fillpoly%s', None),
+            'rng': ('http://docs.opencv.org/modules/core/doc/operations_on_arrays.html?highlight=rng#rng%s', None),
+            'put_text': ('http://docs.opencv.org/modules/core/doc/drawing_functions.html#puttext%s', None),
+            'gaussian_blur': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=gaussianblur#gaussianblur%s', None),
+            'blur': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=blur#blur%s', None),
+            'median_blur': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=medianblur#medianblur%s', None),
+            'bilateral_filter': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=bilateralfilter#bilateralfilter%s', None),
+            'erode': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=erode#erode%s', None),
+            'dilate': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=dilate#dilate%s', None),
+            'get_structuring_element': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=getstructuringelement#getstructuringelement%s', None),
+            'flood_fill': ( 'http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html?highlight=floodfill#floodfill%s', None),
+            'morphology_ex': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=morphologyex#morphologyex%s', None),
+            'pyr_down': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=pyrdown#pyrdown%s', None),
+            'pyr_up': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=pyrup#pyrup%s', None),
+            'resize': ('http://docs.opencv.org/modules/imgproc/doc/geometric_transformations.html?highlight=resize#resize%s', None),
+            'threshold': ('http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html?highlight=threshold#threshold%s', None),
+            'filter2d': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=filter2d#filter2d%s', None),
+            'copy_make_border': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=copymakeborder#copymakeborder%s', None),
+            'sobel': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=sobel#sobel%s', None),
+            'scharr': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=scharr#scharr%s', None),
+            'laplacian': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=laplacian#laplacian%s', None),
+            'canny': ('http://docs.opencv.org/modules/imgproc/doc/feature_detection.html?highlight=canny#canny%s', None),
+            'copy_to': ('http://docs.opencv.org/modules/core/doc/basic_structures.html?highlight=copyto#mat-copyto%s', None),
+            'hough_lines' : ('http://docs.opencv.org/modules/imgproc/doc/feature_detection.html?highlight=houghlines#houghlines%s', None),
+            'hough_lines_p' : ('http://docs.opencv.org/modules/imgproc/doc/feature_detection.html?highlight=houghlinesp#houghlinesp%s', None),
+            'hough_circles' : ('http://docs.opencv.org/modules/imgproc/doc/feature_detection.html?highlight=houghcircles#houghcircles%s', None),
+            'remap' : ('http://docs.opencv.org/modules/imgproc/doc/geometric_transformations.html?highlight=remap#remap%s', None),
+            'warp_affine' : ('http://docs.opencv.org/modules/imgproc/doc/geometric_transformations.html?highlight=warpaffine#warpaffine%s' , None),
+            'get_rotation_matrix_2d' : ('http://docs.opencv.org/modules/imgproc/doc/geometric_transformations.html?highlight=getrotationmatrix2d#getrotationmatrix2d%s', None),
+            'get_affine_transform' : ('http://docs.opencv.org/modules/imgproc/doc/geometric_transformations.html?highlight=getaffinetransform#getaffinetransform%s', None),
+            'equalize_hist' : ('http://docs.opencv.org/modules/imgproc/doc/histograms.html?highlight=equalizehist#equalizehist%s', None),
+            'split' : ('http://docs.opencv.org/modules/core/doc/operations_on_arrays.html?highlight=split#split%s', None),
+            'calc_hist' : ('http://docs.opencv.org/modules/imgproc/doc/histograms.html?highlight=calchist#calchist%s', None),
+            'normalize' : ('http://docs.opencv.org/modules/core/doc/operations_on_arrays.html?highlight=normalize#normalize%s', None),
+            'match_template' : ('http://docs.opencv.org/modules/imgproc/doc/object_detection.html?highlight=matchtemplate#matchtemplate%s', None),
+            'min_max_loc' : ('http://docs.opencv.org/modules/core/doc/operations_on_arrays.html?highlight=minmaxloc#minmaxloc%s', None),
+            'mix_channels' : ( 'http://docs.opencv.org/modules/core/doc/operations_on_arrays.html?highlight=mixchannels#mixchannels%s', None),
+            'calc_back_project' : ('http://docs.opencv.org/modules/imgproc/doc/histograms.html?highlight=calcbackproject#calcbackproject%s', None),
+            'compare_hist' : ('http://docs.opencv.org/modules/imgproc/doc/histograms.html?highlight=comparehist#comparehist%s', None),
+            'corner_harris' : ('http://docs.opencv.org/modules/imgproc/doc/feature_detection.html?highlight=cornerharris#cornerharris%s', None),
+            'good_features_to_track' : ('http://docs.opencv.org/modules/imgproc/doc/feature_detection.html?highlight=goodfeaturestotrack#goodfeaturestotrack%s', None),
+            'corner_min_eigenval' : ('http://docs.opencv.org/modules/imgproc/doc/feature_detection.html?highlight=cornermineigenval#cornermineigenval%s', None),
+            'corner_eigenvals_and_vecs' : ('http://docs.opencv.org/modules/imgproc/doc/feature_detection.html?highlight=cornereigenvalsandvecs#cornereigenvalsandvecs%s', None),
+            'corner_sub_pix' : ('http://docs.opencv.org/modules/imgproc/doc/feature_detection.html?highlight=cornersubpix#cornersubpix%s', None),
+            'find_contours' : ('http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=findcontours#findcontours%s', None),
+            'convex_hull' : ('http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=convexhull#convexhull%s', None),
+            'draw_contours' : ('http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=drawcontours#drawcontours%s', None),
+            'bounding_rect' : ('http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=boundingrect#boundingrect%s', None),
+            'min_enclosing_circle' : ('http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=minenclosingcircle#minenclosingcircle%s', None),
+            'min_area_rect' : ('http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=minarearect#minarearect%s', None),
+            'fit_ellipse' : ('http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=fitellipse#fitellipse%s', None),
+            'moments' : ('http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=moments#moments%s', None),
+            'contour_area' : ('http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=contourarea#contourarea%s', None),
+            'arc_length' : ('http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=arclength#arclength%s', None),
+            'point_polygon_test' : ('http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=pointpolygontest#pointpolygontest%s', None),
+            'feature_detector' : ( 'http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_feature_detectors.html?highlight=featuredetector#FeatureDetector%s', None),
+            'feature_detector_detect' : ('http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_feature_detectors.html?highlight=detect#featuredetector-detect%s', None ),
+            'surf_feature_detector' : ('http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_feature_detectors.html?highlight=surffeaturedetector#surffeaturedetector%s', None ),
+            'draw_keypoints' : ('http://docs.opencv.org/modules/features2d/doc/drawing_function_of_keypoints_and_matches.html?highlight=drawkeypoints#drawkeypoints%s', None ),
+            'descriptor_extractor': ( 'http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_descriptor_extractors.html?highlight=descriptorextractor#descriptorextractor%s', None ),
+            'descriptor_extractor_compute' : ( 'http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_descriptor_extractors.html?highlight=compute#descriptorextractor-compute%s', None ),
+            'surf_descriptor_extractor' : ( 'http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_descriptor_extractors.html?highlight=surfdescriptorextractor#surfdescriptorextractor%s', None ),
+            'draw_matches' : ( 'http://docs.opencv.org/modules/features2d/doc/drawing_function_of_keypoints_and_matches.html?highlight=drawmatches#drawmatches%s', None ),
+            'find_homography' : ('http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html?highlight=findhomography#findhomography%s', None),
+            'perspective_transform' : ('http://docs.opencv.org/modules/core/doc/operations_on_arrays.html?highlight=perspectivetransform#perspectivetransform%s', None ),
+            'flann_based_matcher' : ('http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_descriptor_matchers.html?highlight=flannbasedmatcher#flannbasedmatcher%s', None),
+            'brute_force_matcher' : ('http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_descriptor_matchers.html?highlight=bruteforcematcher#bruteforcematcher%s', None ),
+            'cascade_classifier' : ('http://docs.opencv.org/modules/objdetect/doc/cascade_classification.html?highlight=cascadeclassifier#cascadeclassifier%s', None ),
+            'cascade_classifier_load' : ('http://docs.opencv.org/modules/objdetect/doc/cascade_classification.html?highlight=load#cascadeclassifier-load%s', None ),
+            'cascade_classifier_detect_multiscale' : ('http://docs.opencv.org/modules/objdetect/doc/cascade_classification.html?highlight=detectmultiscale#cascadeclassifier-detectmultiscale%s', None )
            }
index 6637e25..0e2c764 100644 (file)
@@ -3,42 +3,42 @@
 Camera calibration With OpenCV
 ******************************
 
-Cameras have been around for a long-long time. However, with the introduction of the cheap *pinhole* cameras in the late 20th century, they became a common occurrence in our everyday life. Unfortunately, this cheapness comes with its price: significant distortion. Luckily, these are constants and with a calibration and some remapping we can correct this. Furthermore, with calibration you may also determinate the relation between the camera's natural units (pixels) and the real world units (for example millimeters). 
+Cameras have been around for a long-long time. However, with the introduction of the cheap *pinhole* cameras in the late 20th century, they became a common occurrence in our everyday life. Unfortunately, this cheapness comes with its price: significant distortion. Luckily, these are constants and with a calibration and some remapping we can correct this. Furthermore, with calibration you may also determine the relation between the camera's natural units (pixels) and the real world units (for example millimeters). 
 
 Theory
 ======
 
-For the distortion OpenCV takes into account the radial and tangential factors. For the radial one uses the following formula: 
+For the distortion OpenCV takes into account the radial and tangential factors. For the radial factor one uses the following formula: 
 
 .. math:: 
 
    x_{corrected} = x( 1 + k_1 r^2 + k_2 r^4 + k_3 r^6) \\
    y_{corrected} = y( 1 + k_1 r^2 + k_2 r^4 + k_3 r^6)
 
-So for an old pixel point at :math:`(x,y)` coordinate in the input image, for a corrected output image its position will be :math:`(x_{corrected} y_{corrected})` . The presence of the radial distortion manifests in form of the "barrel" or "fish-eye" effect. 
+So for an old pixel point at :math:`(x,y)` coordinates in the input image, its position on the corrected output image will be :math:`(x_{corrected} y_{corrected})`. The presence of the radial distortion manifests in form of the "barrel" or "fish-eye" effect. 
 
-Tangential distortion occurs because the image taking lenses are not perfectly parallel to the imaging plane. Correcting this is made via the formulas: 
+Tangential distortion occurs because the image taking lenses are not perfectly parallel to the imaging plane. It can be corrected via the formulas: 
 
 .. math:: 
 
    x_{corrected} = x + [ 2p_1xy + p_2(r^2+2x^2)] \\
    y_{corrected} = y + [ p_1(r^2+ 2y^2)+ 2p_2xy]
 
-So we have five distortion parameters, which in OpenCV are organized in a 5 column one row matrix
+So we have five distortion parameters which in OpenCV are presented as one row matrix with 5 columns
 
 .. math:: 
 
   Distortion_{coefficients}=(k_1 \hspace{10pt} k_2 \hspace{10pt} p_1 \hspace{10pt} p_2 \hspace{10pt} k_3)
 
-Now for the unit conversion, we use the following formula:
+Now for the unit conversion we use the following formula:
 
 .. math::
 
    \left [  \begin{matrix}   x \\   y \\  w \end{matrix} \right ] = \left [ \begin{matrix}   f_x & 0 & c_x \\  0 & f_y & c_y \\   0 & 0 & 1 \end{matrix} \right ] \left [ \begin{matrix}  X \\  Y \\   Z \end{matrix} \right ]
 
-Here the presence of the :math:`w` is cause we use a homography coordinate system (and :math:`w=Z`). The unknown parameters are :math:`f_x` and :math:`f_y` (camera focal lengths) and :math:`(c_x, c_y)` what are the optical centers expressed in pixels coordinates. If for both axes a common focal length is used with a given :math:`a` aspect ratio (usually 1), then :math:`f_y=f_x*a` and in the upper formula we will have a single :math:`f` focal length. The matrix containing these four parameters is referred to as the *camera matrix*. While the distortion coefficients are the same regardless of the camera resolutions used, these should be scaled along with the current resolution from the calibrated resolution.
+Here the presence of :math:`w` is explained by the use of homography coordinate system (and :math:`w=Z`). The unknown parameters are :math:`f_x` and :math:`f_y` (camera focal lengths) and :math:`(c_x, c_y)` which are the optical centers expressed in pixels coordinates. If for both axes a common focal length is used with a given :math:`a` aspect ratio (usually 1), then :math:`f_y=f_x*a` and in the upper formula we will have a single focal length :math:`f`. The matrix containing these four parameters is referred to as the *camera matrix*. While the distortion coefficients are the same regardless of the camera resolutions used, these should be scaled along with the current resolution from the calibrated resolution.
 
-The process of determining these two matrices is the calibration. Calculating these parameters is done by some basic geometrical equations. The equations used depend on the calibrating objects used. Currently OpenCV supports three types of object for calibration: 
+The process of determining these two matrices is the calibration. Calculation of these parameters is done through basic geometrical equations. The equations used depend on the chosen calibrating objects. Currently OpenCV supports three types of objects for calibration: 
 
 .. container:: enumeratevisibleitemswithsquare
 
@@ -46,7 +46,7 @@ The process of determining these two matrices is the calibration. Calculating th
    + Symmetrical circle pattern
    + Asymmetrical circle pattern
 
-Basically, you need to take snapshots of these patterns with your camera and let OpenCV find them. Each found pattern equals in a new equation. To solve the equation you need at least a predetermined number of pattern snapshots to form a well-posed equation system. This number is higher for the chessboard pattern and less for the circle ones. For example, in theory the chessboard one requires at least two. However, in practice we have a good amount of noise present in our input images, so for good results you will probably want at least 10 good snapshots of the input pattern in different position. 
+Basically, you need to take snapshots of these patterns with your camera and let OpenCV find them. Each found pattern results in a new equation. To solve the equation you need at least a predetermined number of pattern snapshots to form a well-posed equation system. This number is higher for the chessboard pattern and less for the circle ones. For example, in theory the chessboard pattern requires at least two snapshots. However, in practice we have a good amount of noise present in our input images, so for good results you will probably need at least 10 good snapshots of the input pattern in different positions.
 
 Goal
 ====
@@ -55,19 +55,19 @@ The sample application will:
 
 .. container:: enumeratevisibleitemswithsquare
 
-   + Determinate the distortion matrix
-   + Determinate the camera matrix
-   + Input from Camera, Video and Image file list
-   + Configuration from XML/YAML file
+   + Determine the distortion matrix
+   + Determine the camera matrix
+   + Take input from Camera, Video and Image file list
+   + Read configuration from XML/YAML file
    + Save the results into XML/YAML file
    + Calculate re-projection error
 
 Source code
 ===========
 
-You may also find the source code in the :file:`samples/cpp/tutorial_code/calib3d/camera_calibration/` folder of the OpenCV source library or :download:`download it from here <../../../../samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp>`. The program has a single argument. The name of its configuration file. If none given it will try to open the one named "default.xml". :download:`Here's a sample configuration file <../../../../samples/cpp/tutorial_code/calib3d/camera_calibration/in_VID5.xml>` in XML format. In the configuration file you may choose to use as input a camera, a video file or an image list. If you opt for the later one, you need to create a configuration file where you enumerate the images to use. Here's :download:`an example of this <../../../../samples/cpp/tutorial_code/calib3d/camera_calibration/VID5.xml>`. The important part to remember is that the images needs to be specified using the absolute path or the relative one from your applications working directory. You may find all this in the beforehand mentioned directory.
+You may also find the source code in the :file:`samples/cpp/tutorial_code/calib3d/camera_calibration/` folder of the OpenCV source library or :download:`download it from here <../../../../samples/cpp/tutorial_code/calib3d/camera_calibration/camera_calibration.cpp>`. The program has a single argument: the name of its configuration file. If none is given then it will try to open the one named "default.xml". :download:`Here's a sample configuration file <../../../../samples/cpp/tutorial_code/calib3d/camera_calibration/in_VID5.xml>` in XML format. In the configuration file you may choose to use camera as an input, a video file or an image list. If you opt for the last one, you will need to create a configuration file where you enumerate the images to use. Here's :download:`an example of this <../../../../samples/cpp/tutorial_code/calib3d/camera_calibration/VID5.xml>`. The important part to remember is that the images need to be specified using the absolute path or the relative one from your application's working directory. You may find all this in the samples directory mentioned above.
 
-The application starts up with reading the settings from the configuration file. Although, this is an important part of it, it has nothing to do with the subject of this tutorial: *camera calibration*. Therefore, I've chosen to do not post here the code part for that. The technical background on how to do this you can find in the :ref:`fileInputOutputXMLYAML` tutorial. 
+The application starts up with reading the settings from the configuration file. Although, this is an important part of it, it has nothing to do with the subject of this tutorial: *camera calibration*. Therefore, I've chosen not to post the code for that part here. Technical background on how to do this you can find in the :ref:`fileInputOutputXMLYAML` tutorial. 
 
 Explanation
 ===========
@@ -93,9 +93,9 @@ Explanation
             return -1;
       }
 
-   For this I've used simple OpenCV class input operation. After reading the file I've an additional post-process function that checks for the validity of the input. Only if all of them are good will be the *goodInput* variable true.
+   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 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 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 *CALIBRATED* one. 
+#. **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-block:: cpp
 
@@ -125,7 +125,7 @@ Explanation
 
    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 consists of finding the major patterns in the input: in case of the chessboard this is their corners of the squares and for the circles, well, the circles itself. The position of these will form the result and is collected into the *pointBuf* vector.
+#. **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-block:: cpp
 
@@ -146,9 +146,9 @@ Explanation
         break;
       }
 
-   Depending on the type of the input pattern you use either the :calib3d:`findChessboardCorners <findchessboardcorners>` or the :calib3d:`findCirclesGrid <findcirclesgrid>` function. For both of them you pass on the current image, the size of the board and you'll get back the positions of the patterns. Furthermore, they return a boolean variable that states if in the input we could find or not the pattern (we only need to take into account images where this is true!). 
+   Depending on the type of the input pattern you use either the :calib3d:`findChessboardCorners <findchessboardcorners>` or the :calib3d:`findCirclesGrid <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 variable which states if the pattern was found in the input (we only need to take into account those images where this is true!). 
 
-   Then again in case of cameras we only take camera images after an input delay time passed. This is in order to allow for the user to move the chessboard around and as getting different images. Same images mean same equations, and same equations at the calibration will form an ill-posed problem, so the calibration will fail. For square images the position of the corners are only approximate. We may improve this by calling the :feature2d:`cornerSubPix <cornersubpix>` function. This way will get a better calibration result. After this we add a valid inputs result to the *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 with the :calib3d:`findChessboardCorners <drawchessboardcorners>` function. 
+   Then again in case of cameras we only take camera images when an input delay time is passed. This is done in order to allow user moving the chessboard around and getting different images. Similar images result in similar equations, and similar equations at the calibration step will form an ill-posed problem, so the calibration will fail. For square images the positions of the corners are only approximate. We may improve this by calling the :feature2d:`cornerSubPix <cornersubpix>` function. It will produce better calibration result. After this we add a valid inputs result to the *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 :calib3d:`findChessboardCorners <drawchessboardcorners>` function. 
 
    .. code-block:: cpp
 
@@ -175,7 +175,7 @@ Explanation
               drawChessboardCorners( view, s.boardSize, Mat(pointBuf), found );
         }
 
-#. **Show state and result for the user, plus command line control of the application**. The showing part consists of a text output on the live feed, and for video or camera input to show the "capturing" frame we simply bitwise negate the input image. 
+#. **Show state and result to the user, plus command line control of the application**. This  part shows text output on the image. 
 
    .. code-block:: cpp
 
@@ -199,7 +199,7 @@ Explanation
       if( blinkOutput )
          bitwise_not(view, view);
 
-   If we only ran the calibration and got the camera matrix plus the distortion coefficients we may just as correct the image with the :imgproc_geometric:`undistort <undistort>` function: 
+   If we ran calibration and got camera's matrix with the distortion coefficients we may want to correct the image using :imgproc_geometric:`undistort <undistort>` function: 
 
    .. code-block:: cpp
 
@@ -212,7 +212,7 @@ Explanation
       //------------------------------ Show image and check for input commands -------------------
       imshow("Image View", view);
 
-   Then we wait for an input key and if this is *u* we toggle the distortion removal, if it is *g* we start all over the detection process (or simply start it), and finally for the *ESC* key quit the application:
+   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-block:: cpp
 
@@ -229,7 +229,7 @@ Explanation
         imagePoints.clear();
       }
 
-#. **Show the distortion removal for the images too**. When you work with an image list it is not possible to remove the distortion inside the loop. Therefore, you must append this after the loop. Taking advantage of this now I'll expand the :imgproc_geometric:`undistort <undistort>` function, which is in fact first a call of the :imgproc_geometric:`initUndistortRectifyMap <initundistortrectifymap>` to find out the transformation matrices and then doing the transformation with the :imgproc_geometric:`remap <remap>` function. Because, after a successful calibration the map calculation needs to be done only once, by using this expanded form you may speed up your application: 
+#. **Show the distortion removal for the images too**. 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 :imgproc_geometric:`undistort <undistort>` function, which is in fact first calls :imgproc_geometric:`initUndistortRectifyMap <initundistortrectifymap>` to find transformation matrices and then performs transformation using :imgproc_geometric:`remap <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-block:: cpp
 
@@ -256,7 +256,7 @@ Explanation
 The calibration and save
 ========================
 
-Because the calibration needs to be only once per camera it makes sense to save them after a successful calibration. This way later on you can just load these values into your program. Due to this we first make the calibration, and if it succeeds we save the result into an OpenCV style XML or YAML file, depending on the extension you give in the configuration file. 
+Because the calibration needs to be done only once per camera, it makes sense to save it after a successful calibration. This way later on you can just load these values into your program. Due to this we first make the calibration, and if it succeeds we save the result into an OpenCV style XML or YAML file, depending on the extension you give in the configuration file. 
 
 Therefore in the first function we just split up these two processes. Because we want to save many 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: 
 
@@ -280,7 +280,7 @@ Therefore in the first function we just split up these two processes. Because we
     return ok;
    }
 
-We do the calibration with the help of the :calib3d:`calibrateCamera <calibratecamera>` function. This has the following parameters: 
+We do the calibration with the help of the :calib3d:`calibrateCamera <calibratecamera>` function. It has the following parameters: 
 
 .. container:: enumeratevisibleitemswithsquare
 
@@ -318,11 +318,11 @@ We do the calibration with the help of the :calib3d:`calibrateCamera <calibratec
         calcBoardCornerPositions(s.boardSize, s.squareSize, objectPoints[0], s.calibrationPattern);
         objectPoints.resize(imagePoints.size(),objectPoints[0]); 
 
-   + The image points. This is a vector of *Point2f* vector that for each input image contains where the important points (corners for chessboard, and center of circles for the circle patterns) were found. We already collected this from what the :calib3d:`findChessboardCorners <findchessboardcorners>` or the :calib3d:`findCirclesGrid <findcirclesgrid>` function returned. We just need to pass it on. 
+   + The image points. This is a vector of *Point2f* vector which for each input image contains coordinates of the important points (corners for chessboard and centers of the circles for the circle pattern). We have already collected this from :calib3d:`findChessboardCorners <findchessboardcorners>` or :calib3d:`findCirclesGrid <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 fix aspect ratio option we need to set the :math:`f_x` to zero: 
+   + The camera matrix. If we used the fixed aspect ratio option we need to set the :math:`f_x` to zero: 
 
      .. code-block:: cpp
 
@@ -336,16 +336,16 @@ We do the calibration with the help of the :calib3d:`calibrateCamera <calibratec
 
         distCoeffs = Mat::zeros(8, 1, CV_64F);
 
-   + The function will calculate for all the views the rotation and translation vector that transform the object points (given in the model coordinate space) to the image points (given in the world coordinate space). The 7th and 8th parameters are an output vector of matrices containing in the ith position the rotation and translation vector for the ith object point to the ith image point. 
+   + For all the views the function will calculate rotation and translation vectors which transform the object points (given in the model coordinate space) to the image points (given in the world coordinate space). The 7-th and 8-th parameters are the output vector of matrices containing in the i-th position the rotation and translation vector for the i-th object point to the i-th image point. 
 
-   + The final argument is a flag. You need to specify here options like fix the aspect ratio for the focal length, assume zero tangential distortion or to fix the principal point. 
+   + The final argument is the flag. You need to specify here options like fix the aspect ratio for the focal length, assume zero tangential distortion or to fix the principal point. 
 
    .. code-block:: cpp
 
      double rms = calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix,
                                  distCoeffs, rvecs, tvecs, s.flag|CV_CALIB_FIX_K4|CV_CALIB_FIX_K5);
 
-   + The function returns the average re-projection error. This number gives a good estimation of just how exact is the found parameters. This should be as close to zero as possible. Given the intrinsic, distortion, rotation and translation matrices we may calculate the error for one view by using the :calib3d:`projectPoints <projectpoints>` to first transform the object point to image point. Then we 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 calculate for all the calibration images. 
+   + The function returns the average re-projection error. This number gives a good estimation of precision of the found parameters. This should be as close to zero as possible. Given the intrinsic, distortion, rotation and translation matrices we may calculate the error for one view by using the :calib3d:`projectPoints <projectpoints>` to first transform the object point to image point. Then we 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-block:: cpp 
 
@@ -378,25 +378,25 @@ We do the calibration with the help of the :calib3d:`calibrateCamera <calibratec
 Results
 =======
 
-Let there be :download:`this input chessboard pattern <../../../pattern.png>` that has a size of 9 X 6. I've used an AXIS IP camera to create a couple of snapshots of the board and saved it into a VID5 directory. I've put this inside the :file:`images/CameraCalibraation` folder of my working directory and created the following :file:`VID5.XML` file that describes which images to use: 
+Let there be :download:`this input chessboard pattern <../../../pattern.png>` which has a size of 9 X 6. I've used an AXIS IP camera to create a couple of snapshots of the board and saved it into VID5 directory. I've put this inside the :file:`images/CameraCalibration` folder of my working directory and created the following :file:`VID5.XML` file that describes which images to use: 
 
 .. code-block:: xml
 
    <?xml version="1.0"?>
    <opencv_storage>
    <images>
-   images/CameraCalibraation/VID5/xx1.jpg
-   images/CameraCalibraation/VID5/xx2.jpg
-   images/CameraCalibraation/VID5/xx3.jpg
-   images/CameraCalibraation/VID5/xx4.jpg
-   images/CameraCalibraation/VID5/xx5.jpg
-   images/CameraCalibraation/VID5/xx6.jpg
-   images/CameraCalibraation/VID5/xx7.jpg
-   images/CameraCalibraation/VID5/xx8.jpg
+   images/CameraCalibration/VID5/xx1.jpg
+   images/CameraCalibration/VID5/xx2.jpg
+   images/CameraCalibration/VID5/xx3.jpg
+   images/CameraCalibration/VID5/xx4.jpg
+   images/CameraCalibration/VID5/xx5.jpg
+   images/CameraCalibration/VID5/xx6.jpg
+   images/CameraCalibration/VID5/xx7.jpg
+   images/CameraCalibration/VID5/xx8.jpg
    </images>
    </opencv_storage>
 
-Then specified the :file:`images/CameraCalibraation/VID5/VID5.XML` as input in the configuration file. Here's a chessboard pattern found during the runtime of the application: 
+Then passed :file:`images/CameraCalibration/VID5/VID5.XML` as an input in the configuration file. Here's a chessboard pattern found during the runtime of the application: 
 
 .. image:: images/fileListImage.jpg 
    :alt: A found chessboard
@@ -433,7 +433,7 @@ In both cases in the specified output XML/YAML file you'll find the camera and d
     -4.1802327176423804e-001 5.0715244063187526e-001 0. 0.
     -5.7843597214487474e-001</data></Distortion_Coefficients>
 
-Add these values as constants to your program, call the :imgproc_geometric:`initUndistortRectifyMap <initundistortrectifymap>` and the :imgproc_geometric:`remap <remap>` function to remove distortion and enjoy distortion free inputs with cheap and low quality cameras. 
+Add these values as constants to your program, call the :imgproc_geometric:`initUndistortRectifyMap <initundistortrectifymap>` and the :imgproc_geometric:`remap <remap>` function to remove distortion and enjoy distortion free inputs for cheap and low quality cameras. 
 
 You may observe a runtime instance of this on the `YouTube here <https://www.youtube.com/watch?v=ViPN810E0SU>`_. 
 
index 35f9b2a..a273a9a 100644 (file)
@@ -1,3 +1,3 @@
 
 .. note::
-   Unfortunetly we have no tutorials into this section. Nevertheless, our tutorial writting team is working on it. If you have a tutorial suggestion or you have writen yourself a tutorial (or coded a sample code) that you would like to see here please contact us via our :opencv_group:`user group <>`. 
\ No newline at end of file
+   Unfortunetly we have no tutorials into this section. And you can help us with that, since OpenCV is a community effort. If you have a tutorial suggestion or you have written a tutorial yourself (or coded a sample code) that you would like to see here, please contact follow these instructions: :ref:`howToWriteTutorial` and :how_to_contribute:`How to contribute <>`.
\ No newline at end of file
index 26798f8..1051fe5 100644 (file)
@@ -31,6 +31,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
    #include "opencv2/core/core.hpp"
    #include "opencv2/features2d/features2d.hpp"
    #include "opencv2/highgui/highgui.hpp"
+   #include "opencv2/nonfree/nonfree.hpp"
 
    using namespace cv;
 
index 54d2889..3bf757f 100644 (file)
@@ -28,6 +28,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
    #include "opencv2/core/core.hpp"
    #include "opencv2/features2d/features2d.hpp"
    #include "opencv2/highgui/highgui.hpp"
+   #include "opencv2/nonfree/nonfree.hpp"
 
    using namespace cv;
 
index ad764ce..eb06083 100644 (file)
@@ -30,6 +30,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
    #include "opencv2/features2d/features2d.hpp"
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/calib3d/calib3d.hpp"
+   #include "opencv2/nonfree/nonfree.hpp"
 
    using namespace cv;
 
index 9983098..715ffdf 100644 (file)
@@ -62,7 +62,7 @@ The GPU has its own memory. When you read data from the hard drive with OpenCV i
 
    I1 = gI1;       // Download, gI1.download(I1) will work too
 
-Once you have your data up in the GPU memory you may call GPU enabled functions of OpenCV. Most of the functions keep the same name just as on the CPU, with the difference that they only accept *GpuMat* inputs. A full list of these you will find in the documentation: `online here <http://opencv.itseez.com/modules/gpu/doc/gpu.html>`_ or the OpenCV reference manual that comes with the source code.
+Once you have your data up in the GPU memory you may call GPU enabled functions of OpenCV. Most of the functions keep the same name just as on the CPU, with the difference that they only accept *GpuMat* inputs. A full list of these you will find in the documentation: `online here <http://docs.opencv.org/modules/gpu/doc/gpu.html>`_ or the OpenCV reference manual that comes with the source code.
 
 Another thing to keep in mind is that not for all channel numbers you can make efficient algorithms on the GPU. Generally, I found that the input images for the GPU images need to be either one or four channel ones and one of the char or float type for the item sizes. No double support on the GPU, sorry. Passing other types of objects for some functions will result in an exception thrown, and an error message on the error output. The documentation details in most of the places the types accepted for the inputs. If you have three channel images as an input you can do two things: either adds a new channel (and use char elements) or split up the image and call the function for each image. The first one isn't really recommended as you waste memory.
 
index b6c859d..78566e7 100644 (file)
@@ -48,10 +48,10 @@ The structure of package contents looks as follows:
 
 ::
 
-    OpenCV-2.4.5-android-sdk
+    OpenCV-2.4.6-android-sdk
     |_ apk
-    |   |_ OpenCV_2.4.5_binary_pack_armv7a.apk
-    |   |_ OpenCV_2.4.5_Manager_2.7_XXX.apk
+    |   |_ OpenCV_2.4.6_binary_pack_armv7a.apk
+    |   |_ OpenCV_2.4.6_Manager_2.9_XXX.apk
     |
     |_ doc
     |_ samples
@@ -98,7 +98,7 @@ The structure of package contents looks as follows:
 * :file:`doc` folder contains various OpenCV documentation in PDF format.
   It's also available online at http://docs.opencv.org.
 
-  .. note:: The most recent docs (nightly build) are at http://docs.opencv.org/trunk/.
+  .. note:: The most recent docs (nightly build) are at http://docs.opencv.org/2.4.
             Generally, it's more up-to-date, but can refer to not-yet-released functionality.
 
 .. TODO: I'm not sure that this is the best place to talk about OpenCV Manager
@@ -157,10 +157,10 @@ Get the OpenCV4Android SDK
 
    .. code-block:: bash
 
-      unzip ~/Downloads/OpenCV-2.4.5-android-sdk.zip
+      unzip ~/Downloads/OpenCV-2.4.6-android-sdk.zip
 
-.. |opencv_android_bin_pack| replace:: :file:`OpenCV-2.4.5-android-sdk.zip`
-.. _opencv_android_bin_pack_url: http://sourceforge.net/projects/opencvlibrary/files/opencv-android/2.4.5/OpenCV-2.4.5-android-sdk.zip/download
+.. |opencv_android_bin_pack| replace:: :file:`OpenCV-2.4.6-android-sdk.zip`
+.. _opencv_android_bin_pack_url: http://sourceforge.net/projects/opencvlibrary/files/opencv-android/2.4.6/OpenCV-2.4.6-android-sdk.zip/download
 .. |opencv_android_bin_pack_url| replace:: |opencv_android_bin_pack|
 .. |seven_zip| replace:: 7-Zip
 .. _seven_zip: http://www.7-zip.org/
@@ -295,7 +295,7 @@ Well, running samples from Eclipse is very simple:
   .. code-block:: sh
     :linenos:
 
-    <Android SDK path>/platform-tools/adb install <OpenCV4Android SDK path>/apk/OpenCV_2.4.5_Manager_2.7_armv7a-neon.apk
+    <Android SDK path>/platform-tools/adb install <OpenCV4Android SDK path>/apk/OpenCV_2.4.6_Manager_2.9_armv7a-neon.apk
 
   .. note:: ``armeabi``, ``armv7a-neon``, ``arm7a-neon-android8``, ``mips`` and ``x86`` stand for
             platform targets:
index 5709b64..368c3b2 100644 (file)
@@ -55,14 +55,14 @@ Manager to access OpenCV libraries externally installed in the target system.
    :guilabel:`File -> Import -> Existing project in your workspace`.
 
    Press :guilabel:`Browse`  button and locate OpenCV4Android SDK 
-   (:file:`OpenCV-2.4.5-android-sdk/sdk`).
+   (:file:`OpenCV-2.4.6-android-sdk/sdk`).
 
    .. image:: images/eclipse_opencv_dependency0.png
         :alt: Add dependency from OpenCV library
         :align: center
 
 #. In application project add a reference to the OpenCV Java SDK in 
-   :guilabel:`Project -> Properties -> Android -> Library -> Add` select ``OpenCV Library - 2.4.5``.
+   :guilabel:`Project -> Properties -> Android -> Library -> Add` select ``OpenCV Library - 2.4.6``.
 
    .. image:: images/eclipse_opencv_dependency1.png
         :alt: Add dependency from OpenCV library
@@ -101,7 +101,7 @@ See the "15-puzzle" OpenCV sample for details.
         public void onResume()
         {
             super.onResume();
-            OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_5, this, mLoaderCallback);
+            OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_6, this, mLoaderCallback);
         }
 
         ...
@@ -128,27 +128,27 @@ described above.
 #. Add the OpenCV library project to your workspace the same way as for the async initialization 
    above. Use menu :guilabel:`File -> Import -> Existing project in your workspace`, 
    press :guilabel:`Browse` button and select OpenCV SDK path 
-   (:file:`OpenCV-2.4.5-android-sdk/sdk`).
+   (:file:`OpenCV-2.4.6-android-sdk/sdk`).
 
    .. image:: images/eclipse_opencv_dependency0.png
         :alt: Add dependency from OpenCV library
         :align: center
 
 #. In the application project add a reference to the OpenCV4Android SDK in 
-   :guilabel:`Project -> Properties -> Android -> Library -> Add` select ``OpenCV Library - 2.4.5``;
+   :guilabel:`Project -> Properties -> Android -> Library -> Add` select ``OpenCV Library - 2.4.6``;
 
    .. image:: images/eclipse_opencv_dependency1.png
        :alt: Add dependency from OpenCV library
        :align: center
 
 #. If your application project **doesn't have a JNI part**, just copy the corresponding OpenCV 
-   native libs from :file:`<OpenCV-2.4.5-android-sdk>/sdk/native/libs/<target_arch>` to your
+   native libs from :file:`<OpenCV-2.4.6-android-sdk>/sdk/native/libs/<target_arch>` to your
    project directory to folder :file:`libs/<target_arch>`.
 
    In case of the application project **with a JNI part**, instead of manual libraries copying you 
    need to modify your ``Android.mk`` file:
    add the following two code lines after the ``"include $(CLEAR_VARS)"`` and before 
-   ``"include path_to_OpenCV-2.4.5-android-sdk/sdk/native/jni/OpenCV.mk"``
+   ``"include path_to_OpenCV-2.4.6-android-sdk/sdk/native/jni/OpenCV.mk"``
 
    .. code-block:: make
       :linenos:
@@ -221,7 +221,7 @@ taken:
 
    .. code-block:: make
 
-      include C:\Work\OpenCV4Android\OpenCV-2.4.5-android-sdk\sdk\native\jni\OpenCV.mk
+      include C:\Work\OpenCV4Android\OpenCV-2.4.6-android-sdk\sdk\native\jni\OpenCV.mk
 
    Should be inserted into the :file:`jni/Android.mk` file **after** this line:
 
@@ -379,7 +379,7 @@ result.
        public void onResume()
        {
            super.onResume();
-           OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
+           OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_6, this, mLoaderCallback);
        }
 
 #. Defines that your activity implements ``CvViewFrameListener2`` interface and fix activity related
index e1815ed..ee89a4e 100644 (file)
@@ -1,9 +1,22 @@
 .. _howToWriteTutorial:
 
-How to write a tutorial for OpenCV?
-***********************************
-
-Okay, so assume you have just finished a project of yours implementing something based on OpenCV and you want to present/share it with the community. Luckily, OpenCV is an *open source project*. This means that in theory anyone has access to the full source code and may extend it. While making a robust and practical library (like OpenCV) is great, the success of a library also depends on how user friendly it is. To improve on this aspect, the OpenCV team has already been listening to user feedback from its :opencv_group:`Yahoo user group <>` and by making samples you can find in the source directories sample folder. The addition of the tutorials (in both online and PDF format) is an extension of these efforts.
+How to write a tutorial for OpenCV
+**********************************
+
+Okay, so assume you have just finished a project of yours implementing something
+based on OpenCV and you want to present/share it with the community. Luckily, OpenCV
+is an *open source project*. This means that anyone has access to the full source
+code and may propose extensions. And a good tutorial is a valuable addition to the
+library! Please read instructions on contribution process here:
+http://opencv.org/contribute.html. You may also find this page helpful:
+:how_to_contribute:`How to contribute <>`.
+
+While making a robust and practical library (like OpenCV) is great, the success of a
+library also depends on how user friendly it is. To improve on this aspect, the
+OpenCV team has already been listening to user feedback at :opencv_qa:`OpenCV Q&A
+forum <>` and by making samples you can find in the source directories
+:file:`samples` folder. The addition of the tutorials (in both online and PDF format)
+is an extension of these efforts.
 
 Goal
 ====
@@ -15,7 +28,17 @@ Goal
 
 .. _Sphinx: http://sphinx.pocoo.org/
 
-The tutorials are just as an important part of the library as  the implementation of those crafty data structures and algorithms you can find in OpenCV. Therefore, the source codes for the tutorials are part of the library. And yes, I meant source codes. The reason for this formulation is that the tutorials are written by using the |Sphinx|_ documentation generation system. This is based on the popular python documentation system called |reST|_ (reST). ReStructuredText is a really neat language that by using a few simple conventions (indentation, directives) and emulating old school e-mail writing techniques (text only) tries to offer a simple way to create and edit documents. Sphinx extends this with some new features and creates the resulting document in both HTML (for web) and PDF (for offline usage) format.
+The tutorials are just as an important part of the library as the implementation of
+those crafty data structures and algorithms you can find in OpenCV. Therefore, the
+source codes for the tutorials are part of the library. And yes, I meant source
+codes. The reason for this formulation is that the tutorials are written by using the
+|Sphinx|_ documentation generation system. This is based on the popular Python
+documentation system called |reST|_ (reST). ReStructuredText is a really neat
+language that by using a few simple conventions (indentation, directives) and
+emulating old school email writing techniques (text only) tries to offer a simple
+way to create and edit documents. Sphinx extends this with some new features and
+creates the resulting document in both HTML (for web) and PDF (for offline usage)
+format.
 
 Usually, an OpenCV tutorial has the following parts:
 
@@ -36,14 +59,17 @@ Usually, an OpenCV tutorial has the following parts:
     #. For more complex demonstrations you may create a video.
 
 As you can see you will need at least some basic knowledge of the *reST* system in order to complete the task at hand with success. However, don't worry *reST* (and *Sphinx*) was made with simplicity in mind. It is easy to grasp its basics. I found that the `OpenAlea documentations introduction on this subject <http://openalea.gforge.inria.fr/doc/openalea/doc/_build/html/source/tutorial/rest_syntax.html>`_ (or the `Thomas Cokelaer one <http://thomas-cokelaer.info/tutorials/sphinx/rest_syntax.html>`_ ) should enough for this. If for some directive or feature you need a more in-depth description look it up in the official |reST|_ help files or at the |Sphinx|_ documentation.
+
 In our world achieving some tasks is possible in multiple ways. However, some of the roads to take may have obvious or hidden advantages over others. Then again, in some other cases it may come down to just simple user preference. Here, I'll present how I decided to write the tutorials, based on my personal experience. If for some of them you know a better solution and you can back it up feel free to use that. I've nothing against it, as long as it gets the job done in an elegant fashion.
+
 Now the best would be if you could make the integration yourself. For this you need first to have the source code. I recommend following the guides for your operating system on acquiring OpenCV sources. For Linux users look :ref:`here <Linux-Installation>` and for :ref:`Windows here <Windows_Installation>`. You must also install python and sphinx with its dependencies in order to be able to build the documentation.
-Once you have downloaded the repository to your hard drive you can take a look in the OpenCV directory to make sure you have both the samples and doc folder present. Anyone may download the trunk source files from  :file:`git://code.opencv.org/opencv.git` . Nevertheless, not everyone has upload (commit/submit) rights. This is to protect the integrity of the library. If you plan doing more than one tutorial, and would like to have an account with commit user rights you should first register an account at http://code.opencv.org/ and then contact dr. Gary Bradski at -delete-bradski@-delete-willowgarage.com. Otherwise, you can just send the resulting files to us via the :opencv_group:`Yahoo user group <>` or to me at -delete-bernat@-delete-primeranks.net and I'll add it. If you have questions, suggestions or constructive critics I will gladly listen to them. If you send it to the OpenCV group please tag its subject with a **[Tutorial]** entry.
+
+Once you have downloaded the repository to your hard drive you can take a look in the OpenCV directory to make sure you have both the samples and doc folder present. Anyone may download the latest source files from :file:`git://github.com/Itseez/opencv.git` . Nevertheless, not everyone has upload (commit/submit) rights. This is to protect the integrity of the library. If you plan doing more than one tutorial, and would like to have an account with commit user rights you should first register an account at http://code.opencv.org/ and then contact OpenCV administrator -delete-admin@-delete-opencv.org. Otherwise, you can just send the resulting files to us at -delete-admin@-delete-opencv.org and we'll add it.
 
 Format the Source Code
 ======================
 
-Before I start this let it be clear: the main goal is to have a working sample code. However, for your tutorial to be of a top notch quality you should follow a few guide lines I am going to present here. In case you have an application by using the older interface (with *IplImage*, *CVMat*, *cvLoadImage* and such) consider migrating it to the new C++ interface. The tutorials are intended to be an up to date help for our users. And as of OpenCV 2 the OpenCV emphasis on using the less error prone and clearer C++ interface. Therefore, if possible please convert your code to the C++ interface. For this it may help to read the :ref:`InteroperabilityWithOpenCV1` tutorial. However, once you have an OpenCV 2 working code, then you should make your source code snippet as easy to read as possible. Here're a couple of advices for this:
+Before I start this let it be clear: the main goal is to have a working sample code. However, for your tutorial to be of a top notch quality you should follow a few guide lines I am going to present here. In case you have an application by using the older interface (with *IplImage*, *cvMat*, *cvLoadImage* and such) consider migrating it to the new C++ interface. The tutorials are intended to be an up to date help for our users. And as of OpenCV 2 the OpenCV emphasis on using the less error prone and clearer C++ interface. Therefore, if possible please convert your code to the C++ interface. For this it may help to read the :ref:`InteroperabilityWithOpenCV1` tutorial. However, once you have an OpenCV 2 working code, then you should make your source code snippet as easy to read as possible. Here're a couple of advices for this:
 
 .. container:: enumeratevisibleitemswithsquare
 
@@ -102,6 +128,7 @@ Navigate to the :file:`opencv/doc/tutorials/section/table_of_content_section` fo
       \pagebreak
 
 The first line is a reference to the section title in the reST system. The section title will be a link and you may refer to it via the ``:ref:`` directive. The *include* directive imports the template text from the definitions directories *noContent.rst* file. *Sphinx* does not creates the PDF from scratch. It does this by first creating a latex file. Then creates the PDF from the latex file. With the *raw* directive you can directly add to this output commands. Its unique argument is for what kind of output to add the content of the directive. For the PDFs it may happen that multiple sections will overlap on a single page. To avoid this at the end of the TOC we add a *pagebreak* latex command, that hints to the LATEX system that the next line should be on a new page.
+
 If you have one of this, try to transform it to the following form:
 
 .. include:: ../../definitions/tocDefinitions.rst
@@ -157,6 +184,7 @@ Until the *raw* directive what you can see is a TOC tree entry. Here's how a TOC
                    :width:  90pt
 
 As you can see we have an image to the left and a description box to the right. To create two boxes we use a table with two columns and a single row. In the left column is the image and in the right one the description. However, the image directive is way too long to fit in a column. Therefore, we need to use the substitution definition system. We add this definition after the TOC tree. All images for the TOC tree are to be put in the images folder near its |reST|_ file. We use the point measurement system because we are also creating PDFs. PDFs are printable documents, where there is no such thing that pixels (px), just points (pt). And while generally space is no problem for web pages (we have monitors with **huge** resolutions) the size of the paper (A4 or letter) is constant and will be for a long time in the future. Therefore, size constrains come in play more like for the PDF, than the generated HTML code.
+
 Now your images should be as small as possible, while still offering the intended information for the user. Remember that the tutorial will become part of the OpenCV source code. If you add large images (that manifest in form of large image size) it will just increase the size of the repository pointlessly. If someone wants to download it later, its download time will be that much longer. Not to mention the larger PDF size for the tutorials and the longer load time for the web pages. In terms of pixels a TOC image should not be larger than 120 X 120 pixels. Resize your images if they are larger!
 
 .. note:: If you add a larger image and specify a smaller image size, *Sphinx* will not resize that. At build time will add the full size image and the resize will be done by your browser after the image is loaded. A 120 X 120 image is somewhere below 10KB. If you add a 110KB image, you have just pointlessly added a 100KB extra data to transfer over the internet for every user!
@@ -189,7 +217,9 @@ Now before each TOC entry you need to add the three lines of:
      .. cssclass:: toctableopencv
 
 The plus sign (+) is to enumerate tutorials by using bullet points. So for every TOC entry we have a corresponding bullet point represented by the +. Sphinx is highly indenting sensitive. Indentation is used to express from which point until to which point does a construction last. Un-indentation means end of that construction. So to keep all the bullet points to the same group the following TOC entries (until the next +) should be indented by two spaces.
+
 Here, I should also mention that **always** prefer using spaces instead of tabs. Working with only spaces makes possible that if we both use monotype fonts we will see the same thing. Tab size is text editor dependent and as should be avoided. *Sphinx* translates all tabs into 8 spaces before interpreting it.
+
 It turns out that the automatic formatting of both the HTML and PDF(LATEX) system messes up our tables. Therefore, we need to help them out a little. For the PDF generation we add the ``.. tabularcolumns:: m{100pt} m{300pt}`` directive. This means that the first column should be 100 points wide and middle aligned. For the HTML look we simply name the following table of a *toctableopencv* class type. Then, we can modify the look of the table by modifying the CSS of our web page. The CSS definitions go into the :file:`opencv/doc/_themes/blue/static/default.css_t` file.
 
 .. code-block:: css
@@ -221,12 +251,14 @@ However, you should not need to modify this. Just add these three lines (plus ke
       ../mat - the basic image container/mat - the basic image container
 
 The page break entry comes for separating sections and should be only one in a TOC tree |reST|_ file. Finally, at the end of the TOC tree we need to add our tutorial to the *Sphinx* TOC tree system. *Sphinx* will generate from this the previous-next-up information for the HTML file and add items to the PDF according to the order here. By default this TOC tree directive generates a simple table of contents. However, we already created a fancy looking one so we no longer need this basic one. Therefore, we add the *hidden* option to do not show it.
+
 The path is of a relative type. We step back in the file system and then go into the :file:`mat - the basic image container` directory for the :file:`mat - the basic image container.rst` file. Putting out the *rst* extension for the file is optional.
 
 Write the tutorial
 ==================
 
 Create a folder with the name of your tutorial. Preferably, use small letters only. Then create a text file in this folder with *rst* extension and the same name. If you have images for the tutorial create an :file:`images` folder and add your images there. When creating your images follow the guidelines described in the previous part!
+
 Now here's our recommendation for the structure of the tutorial (although, remember that this is not carved in the stone; if you have a better idea, use it!):
 
 .. container:: enumeratevisibleitemswithsquare
@@ -278,13 +310,13 @@ Now here's our recommendation for the structure of the tutorial (although, remem
 
      After the directive you specify a relative path to the file from what to import. It has four options: the language to use, if you add the ``:linenos:`` the line numbers will be shown, you can specify the tab size with the ``:tab-width:`` and you do not need to load the whole file, you can show just the important lines. Use the *lines* option to do not show redundant information (such as the *help* function). Here basically you specify ranges, if the second range line number is missing than that means that until the end of the file. The ranges specified here do no need to be in an ascending order, you may even reorganize the structure of how you want to show your sample inside the tutorial.
    + The tutorial. Well here goes the explanation for why and what have you used. Try to be short, clear, concise and yet a thorough one. There's no magic formula. Look into a few already made tutorials and start out from there. Try to mix sample OpenCV code with your explanations. If with words is hard to describe something do not hesitate to add in a reasonable size image, to overcome this issue.
-     When you present OpenCV functionality it's a good idea to give a link to the used OpenCV data structure or function. Because the OpenCV tutorials and reference manual are in separate PDF files it is not possible to make this link work for the PDF format. Therefore, we use here only web page links to the **opencv.itseez.com** website. The OpenCV functions and data structures may be used for multiple tasks. Nevertheless, we want to avoid that every users creates its own reference to a commonly used function. So for this we use the global link collection of *Sphinx*. This is defined in the file:`opencv/doc/conf.py` configuration file. Open it and go all the way down to the last entry:
+     When you present OpenCV functionality it's a good idea to give a link to the used OpenCV data structure or function. Because the OpenCV tutorials and reference manual are in separate PDF files it is not possible to make this link work for the PDF format. Therefore, we use here only web page links to the http://docs.opencv.org website. The OpenCV functions and data structures may be used for multiple tasks. Nevertheless, we want to avoid that every users creates its own reference to a commonly used function. So for this we use the global link collection of *Sphinx*. This is defined in the file:`opencv/doc/conf.py` configuration file. Open it and go all the way down to the last entry:
 
      .. code-block:: py
 
        # ---- External links for tutorials -----------------
        extlinks = {
-           'hgvideo' : ('http://opencv.itseez.com/modules/highgui/doc/reading_and_writing_images_and_video.html#%s', None)
+           'hgvideo' : ('http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html#%s', None)
            }
 
      In short here we defined a new **hgvideo** directive that refers to an external webpage link. Its usage is:
@@ -293,7 +325,7 @@ Now here's our recommendation for the structure of the tutorial (although, remem
 
        A sample function of the highgui modules image write and read page is the :hgvideo:`imread() function <imread>`.
 
-     Which turns to: A sample function of the highgui modules image write and read page is the :hgvideo:`imread() function <imread>`. The argument you give between the <> will be put in place of the ``%s`` in the upper definition, and as the link will anchor to the correct function. To find out the anchor of a given function just open up a web page, search for the function and click on it. In the address bar it should appear like: ``http://opencv.itseez.com/modules/highgui/doc/reading_and_writing_images_and_video.html#imread`` .  Look here for the name of the directives for each page of the OpenCV reference manual. If none present for one of them feel free to add one for it.
+     Which turns to: A sample function of the highgui modules image write and read page is the :hgvideo:`imread() function <imread>`. The argument you give between the <> will be put in place of the ``%s`` in the upper definition, and as the link will anchor to the correct function. To find out the anchor of a given function just open up a web page, search for the function and click on it. In the address bar it should appear like: ``http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html#imread`` .  Look here for the name of the directives for each page of the OpenCV reference manual. If none present for one of them feel free to add one for it.
      For formulas you can add LATEX code that will translate in the web pages into images. You do this by using the *math* directive. A usage tip:
 
      .. code-block:: latex
@@ -339,6 +371,17 @@ Now here's our recommendation for the structure of the tutorial (although, remem
 Take home the pride and joy of a job well done!
 ===============================================
 
-Once you are done contact me or dr. Gary Bradski with the tutorial. We may submit the tutorial ourselves to the trunk branch of our repository or ask you to do so.
-Now, to see your work **live** you may need to wait some time. The PDFs are updated usually at the launch of a new OpenCV version. The web pages are a little more diverse. They are automatically rebuilt in each evening. However, the **opencv.itseez.com** website contains only the most recent **stable branch** of OpenCV. Currently this is 2.3. When we add something new (like a tutorial) that first goes to the **trunk branch** of our repository. A build of this you may find on the **opencv.itseez.com/trunk** website. Although, we try to make a build every night occasionally we might freeze any of the branches to fix upcoming issues. During this it may take a little longer to see your work *live*, however if you submited it, be sure that eventually it will show up.
-If you have any questions or advices relating to this tutorial you can contact me at -delete-bernat@-delete-primeranks.net. Of course, delete the -delete- parts of that e-mail address.
\ No newline at end of file
+Once you are done please make a GitHub pull request with the tutorial. Now, to see
+your work **live** you may need to wait some time. The PDFs are updated usually at
+the launch of a new OpenCV version. The web pages are a little more diverse. They are
+automatically rebuilt nightly. Currently we use ``2.4`` and ``master`` branches for
+daily builds. So, if your pull request was merged to any of these branches, your
+material will be published at `docs.opencv.org/2.4 <http:/docs.opencv.org/2.4>`_ or
+`docs.opencv.org/master <http:/docs.opencv.org/master>`_ correspondingly. Everything
+that was added to ``2.4`` is merged to ``master`` branch every week. Although, we try
+to make a build every night, occasionally we might freeze any of the branches to fix
+upcoming issues. During this it may take a little longer to see your work online,
+however if you submitted it, be sure that eventually it will show up.
+
+If you have any questions or advices relating to this tutorial you can contact us at
+-delete-admin@-delete-opencv.org (delete the -delete- parts of that email address).
\ No newline at end of file
index ace657b..8d117a0 100644 (file)
@@ -37,7 +37,7 @@ Building OpenCV from Source, using CMake and Command Line
     .. code-block:: bash
 
        cd ~/<my_working_directory>
-       python opencv/ios/build_framework.py ios
+       python opencv/platforms/ios/build_framework.py ios
 
 If everything's fine, a few minutes later you will get ~/<my_working_directory>/ios/opencv2.framework. You can add this framework to your Xcode projects.
 
index d1ae8fa..8ed8419 100644 (file)
@@ -292,7 +292,7 @@ Building the library
 
    This will create an *Install* directory inside the *Build* one collecting all the built binaries into a single place. Use this only after you built both the *Release* and *Debug* versions.
 
-   To test your build just go into the :file:`Build/bin/Debug` or :file:`Build/bin/Release` directory and start a couple of applications like the *contours.exe*. If they run, you are done. Otherwise, something definitely went awfully wrong. In this case you should contact us via our :opencv_group:`user group <>`.
+   To test your build just go into the :file:`Build/bin/Debug` or :file:`Build/bin/Release` directory and start a couple of applications like the *contours.exe*. If they run, you are done. Otherwise, something definitely went awfully wrong. In this case you should contact us at our :opencv_qa:`Q&A forum <>`.
    If everything is okay the *contours.exe* output should resemble the following image (if built with Qt support):
 
    .. image:: images/WindowsQtContoursOutput.png
@@ -312,9 +312,13 @@ First we set an enviroment variable to make easier our work. This will hold the
 
 ::
 
-   setx -m OPENCV_DIR D:\OpenCV\Build\x86\vc10
-
-Here the directory is where you have your OpenCV binaries (*extracted* or *built*). You can have different platform (e.g. x64 instead of x86) or compiler type, so substitute appropriate value. Inside this you should have folders like *bin* and *include*. The -m should be added if you wish to make the settings computer wise, instead of user wise.
+   setx -m OPENCV_DIR D:\OpenCV\Build\x86\vc10     (suggested for Visual Studio 2010 - 32 bit Windows)
+   setx -m OPENCV_DIR D:\OpenCV\Build\x64\vc10     (suggested for Visual Studio 2010 - 64 bit Windows)
+   
+   setx -m OPENCV_DIR D:\OpenCV\Build\x86\vc11     (suggested for Visual Studio 2012 - 32 bit Windows)
+   setx -m OPENCV_DIR D:\OpenCV\Build\x64\vc11     (suggested for Visual Studio 2012 - 64 bit Windows)
+   
+Here the directory is where you have your OpenCV binaries (*extracted* or *built*). You can have different platform (e.g. x64 instead of x86) or compiler type, so substitute appropriate value. Inside this you should have two folders called *lib* and *bin*. The -m should be added if you wish to make the settings computer wise, instead of user wise.
 
 If you built static libraries then you are done. Otherwise, you need to add the *bin* folders path to the systems path. This is cause you will use the OpenCV library in form of *\"Dynamic-link libraries\"* (also known as **DLL**). Inside these are stored all the algorithms and information the OpenCV library contains. The operating system will load them only on demand, during runtime. However, to do this he needs to know where they are. The systems **PATH** contains a list of folders where DLLs can be found. Add the OpenCV library path to this and the OS will know where to look if he ever needs the OpenCV binaries. Otherwise, you will need to copy the used DLLs right beside the applications executable file (*exe*) for the OS to find it, which is highly unpleasent if you work on many projects. To do this start up again the |PathEditor|_ and add the following new entry (right click in the application to bring up the menu):
 
index 5826f4d..bc61d33 100644 (file)
Binary files a/doc/tutorials/introduction/windows_visual_studio_Opencv/images/PropertySheetOpenCVInclude.jpg and b/doc/tutorials/introduction/windows_visual_studio_Opencv/images/PropertySheetOpenCVInclude.jpg differ
index 71be06f..ccf35eb 100644 (file)
@@ -52,7 +52,7 @@ Use for example the *OpenCV_Debug* name. Then by selecting the sheet :menuselect
 
 .. code-block:: bash
 
-   $(OPENCV_DIR)\include
+   $(OPENCV_DIR)\..\..\include
 
 .. image:: images/PropertySheetOpenCVInclude.jpg
    :alt: Add the include dir like this. 
@@ -64,7 +64,7 @@ Next go to the :menuselection:`Linker --> General` and under the *"Additional Li
 
 .. code-block:: bash
 
-   $(OPENCV_DIR)\libs
+   $(OPENCV_DIR)\lib
 
 .. image:: images/PropertySheetOpenCVLib.jpg
    :alt: Add the library folder like this. 
@@ -86,7 +86,7 @@ The names of the libraries are as follow:
 
    opencv_(The Name of the module)(The version Number of the library you use)d.lib
 
-A full list, for the currently latest trunk version would contain:
+A full list, for the latest version would contain:
 
 .. code-block:: bash
 
index cdad3de..6cd66e5 100644 (file)
@@ -129,7 +129,7 @@ Explanation
 
 3. **Train the SVM**
 
-   We call the method `CvSVM::train <http://opencv.itseez.com/modules/ml/doc/support_vector_machines.html#cvsvm-train>`_ to build the SVM model.
+   We call the method `CvSVM::train <http://docs.opencv.org/modules/ml/doc/support_vector_machines.html#cvsvm-train>`_ to build the SVM model.
 
    .. code-block:: cpp
 
diff --git a/ios/configure-device_xcode.sh b/ios/configure-device_xcode.sh
deleted file mode 100755 (executable)
index 8c28a3e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-cmake -GXcode -DCMAKE_TOOLCHAIN_FILE=../opencv/ios/cmake/Toolchains/Toolchain-iPhoneOS_Xcode.cmake -DCMAKE_INSTALL_PREFIX=../OpenCV_iPhoneOS ../opencv 
diff --git a/ios/configure-simulator_xcode.sh b/ios/configure-simulator_xcode.sh
deleted file mode 100755 (executable)
index 50e0026..0000000
+++ /dev/null
@@ -1 +0,0 @@
-cmake -GXcode -DCMAKE_TOOLCHAIN_FILE=../opencv/ios/cmake/Toolchains/Toolchain-iPhoneSimulator_Xcode.cmake -DCMAKE_INSTALL_PREFIX=../OpenCV_iPhoneSimulator ../opencv 
diff --git a/ios/readme.txt b/ios/readme.txt
deleted file mode 100644 (file)
index 1441b24..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-Assuming that your build directory is on the same level that opencv source,
-From the build directory run
-  ../opencv/ios/configure-device_xcode.sh
-or
-  ../opencv/ios/configure-simulator_xcode.sh
-
-Then from the same folder invoke
-
-xcodebuild -sdk iphoneos -configuration Release -target ALL_BUILD
-xcodebuild -sdk iphoneos -configuration Release -target install install
-
-or
-
-xcodebuild -sdk iphonesimulator -configuration Release -target ALL_BUILD
-xcodebuild -sdk iphonesimulator -configuration Release -target install install
\ No newline at end of file
index 2d0ebc7..ca631fc 100644 (file)
@@ -1,5 +1,8 @@
-#if !defined(ANDROID_r2_2_0) && !defined(ANDROID_r2_3_3) && !defined(ANDROID_r3_0_1) && !defined(ANDROID_r4_0_0) && !defined(ANDROID_r4_0_3) && !defined(ANDROID_r4_1_1) && !defined(ANDROID_r4_2_0)
-# error Building camera wrapper for your version of Android is not supported by OpenCV. You need to modify OpenCV sources in order to compile camera wrapper for your version of Android.
+#if !defined(ANDROID_r2_2_0) && !defined(ANDROID_r2_3_3) && !defined(ANDROID_r3_0_1) && \
+ !defined(ANDROID_r4_0_0) && !defined(ANDROID_r4_0_3) && !defined(ANDROID_r4_1_1) && \
+ !defined(ANDROID_r4_2_0) && !defined(ANDROID_r4_3_0)
+# error Building camera wrapper for your version of Android is not supported by OpenCV.\
+ You need to modify OpenCV sources in order to compile camera wrapper for your version of Android.
 #endif
 
 #include <camera/Camera.h>
 //Include SurfaceTexture.h file with the SurfaceTexture class
 # include <gui/SurfaceTexture.h>
 # define MAGIC_OPENCV_TEXTURE_ID (0x10)
-#else // defined(ANDROID_r3_0_1) || defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3)
-//TODO: This is either 2.2 or 2.3. Include the headers for ISurface.h access
-#if defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0)
-#include <gui/ISurface.h>
-#include <gui/BufferQueue.h>
+#elif defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0)
+# include <gui/ISurface.h>
+# include <gui/BufferQueue.h>
+#elif defined(ANDROID_r4_3_0)
+# include <gui/IGraphicBufferProducer.h>
+# include <gui/BufferQueue.h>
 #else
 # include <surfaceflinger/ISurface.h>
-#endif  // defined(ANDROID_r4_1_1)
-#endif  // defined(ANDROID_r3_0_1) || defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3)
+#endif
 
 #include <string>
+#include <fstream>
 
 //undef logging macro from /system/core/libcutils/loghack.h
 #ifdef LOGD
@@ -45,7 +49,6 @@
 # undef LOGE
 #endif
 
-
 // LOGGING
 #include <android/log.h>
 #define CAMERA_LOG_TAG "OpenCV_NativeCamera"
@@ -60,7 +63,7 @@ using namespace android;
 
 void debugShowFPS();
 
-#if defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0)
+#if defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0) || defined(ANDROID_r4_3_0)
 class ConsumerListenerStub: public BufferQueue::ConsumerListener
 {
 public:
@@ -73,6 +76,29 @@ public:
 };
 #endif
 
+std::string getProcessName()
+{
+    std::string result;
+    std::ifstream f;
+
+    f.open("/proc/self/cmdline");
+    if (f.is_open())
+    {
+        std::string fullPath;
+        std::getline(f, fullPath, '\0');
+        if (!fullPath.empty())
+        {
+            int i = fullPath.size()-1;
+            while ((i >= 0) && (fullPath[i] != '/')) i--;
+            result = fullPath.substr(i+1, std::string::npos);
+        }
+    }
+
+    f.close();
+
+    return result;
+}
+
 void debugShowFPS()
 {
     static int mFrameCount = 0;
@@ -280,7 +306,7 @@ public:
     }
 
     virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr
-    #if defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3) || defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0)
+    #if defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3) || defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0) || defined(ANDROID_r4_3_0)
                           ,camera_frame_metadata_t*
 #endif
                           )
@@ -361,7 +387,9 @@ CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback,
     typedef sp<Camera> (*Android22ConnectFuncType)();
     typedef sp<Camera> (*Android23ConnectFuncType)(int);
     typedef sp<Camera> (*Android3DConnectFuncType)(int, int);
+    typedef sp<Camera> (*Android43ConnectFuncType)(int, const String16&, int);
 
+    const int ANY_CAMERA_INDEX = -1;
     const int BACK_CAMERA_INDEX = 99;
     const int FRONT_CAMERA_INDEX = 98;
 
@@ -372,14 +400,24 @@ CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback,
     CAMERA_SUPPORT_MODE_ZSL = 0x08 /* Camera Sensor supports ZSL mode. */
     };
 
+    // used for Android 4.3
+    enum {
+        USE_CALLING_UID = -1
+    };
+
     const char Android22ConnectName[] = "_ZN7android6Camera7connectEv";
     const char Android23ConnectName[] = "_ZN7android6Camera7connectEi";
     const char Android3DConnectName[] = "_ZN7android6Camera7connectEii";
+    const char Android43ConnectName[] = "_ZN7android6Camera7connectEiRKNS_8String16Ei";
 
     int localCameraIndex = cameraId;
 
+    if (cameraId == ANY_CAMERA_INDEX)
+    {
+        localCameraIndex = 0;
+    }
 #if !defined(ANDROID_r2_2_0)
-    if (cameraId == BACK_CAMERA_INDEX)
+    else if (cameraId == BACK_CAMERA_INDEX)
     {
         LOGD("Back camera selected");
         for (int i = 0; i < Camera::getNumberOfCameras(); i++)
@@ -450,6 +488,12 @@ CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback,
         LOGD("Connecting to CameraService v 3D");
         camera = Android3DConnect(localCameraIndex, CAMERA_SUPPORT_MODE_2D);
     }
+    else if (Android43ConnectFuncType Android43Connect = (Android43ConnectFuncType)dlsym(CameraHALHandle, Android43ConnectName))
+    {
+        std::string currentProcName = getProcessName();
+        LOGD("Current process name for camera init: %s", currentProcName.c_str());
+        camera = Android43Connect(localCameraIndex, String16(currentProcName.c_str()), USE_CALLING_UID);
+    }
     else
     {
         dlclose(CameraHALHandle);
@@ -471,7 +515,7 @@ CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback,
     handler->camera = camera;
     handler->cameraId = localCameraIndex;
 
-    if (prevCameraParameters != 0)
+    if (prevCameraParameters != NULL)
     {
         LOGI("initCameraConnect: Setting paramers from previous camera handler");
         camera->setParameters(prevCameraParameters->flatten());
@@ -503,11 +547,11 @@ CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback,
         const char* available_focus_modes = handler->params.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES);
         if (available_focus_modes != 0)
         {
-        if (strstr(available_focus_modes, "continuous-video") != NULL)
-        {
-        handler->params.set(CameraParameters::KEY_FOCUS_MODE, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO);
+            if (strstr(available_focus_modes, "continuous-video") != NULL)
+            {
+                handler->params.set(CameraParameters::KEY_FOCUS_MODE, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO);
 
-        status_t resParams = handler->camera->setParameters(handler->params.flatten());
+                status_t resParams = handler->camera->setParameters(handler->params.flatten());
 
                 if (resParams != 0)
                 {
@@ -517,8 +561,8 @@ CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback,
                 {
                     LOGD("initCameraConnect: autofocus is set to mode \"continuous-video\"");
                 }
+            }
         }
-    }
 #endif
 
         //check if yuv420sp format available. Set this format as preview format.
@@ -560,26 +604,25 @@ CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback,
         }
     }
 
-    status_t pdstatus;
+    status_t bufferStatus;
 #if defined(ANDROID_r2_2_0)
-    pdstatus = camera->setPreviewDisplay(sp<ISurface>(0 /*new DummySurface*/));
-    if (pdstatus != 0)
-        LOGE("initCameraConnect: failed setPreviewDisplay(0) call; camera migth not work correctly on some devices");
+    bufferStatus = camera->setPreviewDisplay(sp<ISurface>(0 /*new DummySurface*/));
+    if (bufferStatus != 0)
+        LOGE("initCameraConnect: failed setPreviewDisplay(0) call (status %d); camera might not work correctly on some devices", bufferStatus);
 #elif defined(ANDROID_r2_3_3)
     /* Do nothing in case of 2.3 for now */
-
 #elif defined(ANDROID_r3_0_1) || defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3)
     sp<SurfaceTexture> surfaceTexture = new SurfaceTexture(MAGIC_OPENCV_TEXTURE_ID);
-    pdstatus = camera->setPreviewTexture(surfaceTexture);
-    if (pdstatus != 0)
-        LOGE("initCameraConnect: failed setPreviewTexture call; camera migth not work correctly");
-#elif defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0)
+    bufferStatus = camera->setPreviewTexture(surfaceTexture);
+    if (bufferStatus != 0)
+        LOGE("initCameraConnect: failed setPreviewTexture call (status %d); camera might not work correctly", bufferStatus);
+#elif defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0) || defined(ANDROID_r4_3_0)
     sp<BufferQueue> bufferQueue = new BufferQueue();
     sp<BufferQueue::ConsumerListener> queueListener = new ConsumerListenerStub();
     bufferQueue->consumerConnect(queueListener);
-    pdstatus = camera->setPreviewTexture(bufferQueue);
-    if (pdstatus != 0)
-    LOGE("initCameraConnect: failed setPreviewTexture call; camera migth not work correctly");
+    bufferStatus = camera->setPreviewTexture(bufferQueue);
+    if (bufferStatus != 0)
+        LOGE("initCameraConnect: failed setPreviewTexture call; camera might not work correctly");
 #endif
 
 #if (defined(ANDROID_r2_2_0) || defined(ANDROID_r2_3_3) || defined(ANDROID_r3_0_1))
@@ -595,9 +638,9 @@ CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback,
 #endif //!(defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3))
 
     LOGD("Starting preview");
-    status_t resStart = camera->startPreview();
+    status_t previewStatus = camera->startPreview();
 
-    if (resStart != 0)
+    if (previewStatus != 0)
     {
         LOGE("initCameraConnect: startPreview() fails. Closing camera connection...");
         handler->closeCameraConnect();
@@ -605,7 +648,7 @@ CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback,
     }
     else
     {
-    LOGD("Preview started successfully");
+        LOGD("Preview started successfully");
     }
 
     return handler;
@@ -620,9 +663,11 @@ void CameraHandler::closeCameraConnect()
     }
 
     camera->stopPreview();
+#if defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3) || defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0) || defined(ANDROID_r4_3_0)
+    camera->setPreviewCallbackFlags(CAMERA_FRAME_CALLBACK_FLAG_NOOP);
+#endif
     camera->disconnect();
     camera.clear();
-
     camera=NULL;
     // ATTENTION!!!!!!!!!!!!!!!!!!!!!!!!!!
     // When we set
@@ -863,14 +908,60 @@ void CameraHandler::applyProperties(CameraHandler** ppcameraHandler)
 
     if (*ppcameraHandler == 0)
     {
-        LOGE("applyProperties: Passed null *ppcameraHandler");
+        LOGE("applyProperties: Passed NULL *ppcameraHandler");
         return;
     }
 
-    LOGD("CameraHandler::applyProperties()");
-    CameraHandler* previousCameraHandler=*ppcameraHandler;
-    CameraParameters curCameraParameters(previousCameraHandler->params.flatten());
+    CameraParameters curCameraParameters((*ppcameraHandler)->params.flatten());
+
+#if defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3) || defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0) || defined(ANDROID_r4_3_0)
+    CameraHandler* handler=*ppcameraHandler;
+
+    handler->camera->stopPreview();
+    handler->camera->setPreviewCallbackFlags(CAMERA_FRAME_CALLBACK_FLAG_NOOP);
+
+    status_t reconnectStatus = handler->camera->reconnect();
+    if (reconnectStatus != 0)
+    {
+        LOGE("applyProperties: failed to reconnect camera (status %d)", reconnectStatus);
+        return;
+    }
+
+    handler->camera->setParameters(curCameraParameters.flatten());
+    handler->params.unflatten(curCameraParameters.flatten());
+
+    status_t bufferStatus;
+# if defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3)
+    sp<SurfaceTexture> surfaceTexture = new SurfaceTexture(MAGIC_OPENCV_TEXTURE_ID);
+    bufferStatus = handler->camera->setPreviewTexture(surfaceTexture);
+    if (bufferStatus != 0)
+        LOGE("applyProperties: failed setPreviewTexture call (status %d); camera might not work correctly", bufferStatus);
+# elif defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0) || defined(ANDROID_r4_3_0)
+    sp<BufferQueue> bufferQueue = new BufferQueue();
+    sp<BufferQueue::ConsumerListener> queueListener = new ConsumerListenerStub();
+    bufferQueue->consumerConnect(queueListener);
+    bufferStatus = handler->camera->setPreviewTexture(bufferQueue);
+    if (bufferStatus != 0)
+        LOGE("applyProperties: failed setPreviewTexture call; camera might not work correctly");
+# endif
 
+    handler->camera->setPreviewCallbackFlags( CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK | CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK);//with copy
+
+    LOGD("Starting preview");
+    status_t previewStatus = handler->camera->startPreview();
+
+    if (previewStatus != 0)
+    {
+        LOGE("initCameraConnect: startPreview() fails. Closing camera connection...");
+        handler->closeCameraConnect();
+        handler = NULL;
+    }
+    else
+    {
+        LOGD("Preview started successfully");
+    }
+#else
+    CameraHandler* previousCameraHandler=*ppcameraHandler;
     CameraCallback cameraCallback=previousCameraHandler->cameraCallback;
     void* userData=previousCameraHandler->userData;
     int cameraId=previousCameraHandler->cameraId;
@@ -879,7 +970,6 @@ void CameraHandler::applyProperties(CameraHandler** ppcameraHandler)
     previousCameraHandler->closeCameraConnect();
     LOGD("CameraHandler::applyProperties(): after previousCameraHandler->closeCameraConnect");
 
-
     LOGD("CameraHandler::applyProperties(): before initCameraConnect");
     CameraHandler* handler=initCameraConnect(cameraCallback, cameraId, userData, &curCameraParameters);
     LOGD("CameraHandler::applyProperties(): after initCameraConnect, handler=0x%x", (int)handler);
@@ -892,6 +982,7 @@ void CameraHandler::applyProperties(CameraHandler** ppcameraHandler)
         }
     }
     (*ppcameraHandler)=handler;
+#endif
 }
 
 
index 508159b..84db3e1 100644 (file)
@@ -431,14 +431,14 @@ void CameraActivity::applyProperties()
 int CameraActivity::getFrameWidth()
 {
     if (frameWidth <= 0)
-    frameWidth = getProperty(ANDROID_CAMERA_PROPERTY_FRAMEWIDTH);
+        frameWidth = getProperty(ANDROID_CAMERA_PROPERTY_FRAMEWIDTH);
     return frameWidth;
 }
 
 int CameraActivity::getFrameHeight()
 {
     if (frameHeight <= 0)
-    frameHeight = getProperty(ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT);
+        frameHeight = getProperty(ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT);
     return frameHeight;
 }
 
index b90fba7..11a0802 100644 (file)
@@ -105,7 +105,16 @@ The functions below use the above model to do the following:
 
  * Estimate the relative position and orientation of the stereo camera "heads" and compute the *rectification* transformation that makes the camera optical axes parallel.
 
+.. note::
+
+   * A calibration sample for 3 cameras in horizontal position can be found at opencv_source_code/samples/cpp/3calibration.cpp
+   * A calibration sample based on a sequence of images can be found at opencv_source_code/samples/cpp/calibration.cpp
+   * A calibration sample in order to do 3D reconstruction can be found at opencv_source_code/samples/cpp/build3dmodel.cpp
+   * A calibration sample of an artificially generated camera and chessboard patterns can be found at opencv_source_code/samples/cpp/calibration_artificial.cpp
+   * A calibration example on stereo calibration can be found at opencv_source_code/samples/cpp/stereo_calib.cpp
+   * A calibration example on stereo matching can be found at opencv_source_code/samples/cpp/stereo_match.cpp
 
+   * (Python) A camera calibration sample can be found at opencv_source_code/samples/python2/calibrate.py
 
 calibrateCamera
 ---------------
@@ -579,7 +588,9 @@ Finds an object pose from 3D-2D point correspondences.
 
 The function estimates the object pose given a set of object points, their corresponding image projections, as well as the camera matrix and the distortion coefficients.
 
+.. note::
 
+   * An example of how to use solvePNP for planar augmented reality can be found at opencv_source_code/samples/python2/plane_ar.py
 
 solvePnPRansac
 ------------------
@@ -766,6 +777,9 @@ Homography matrix is determined up to a scale. Thus, it is normalized so that
     :ocv:func:`warpPerspective`,
     :ocv:func:`perspectiveTransform`
 
+.. note::
+
+   * A example on calculating a homography for image matching can be found at opencv_source_code/samples/cpp/video_homography.cpp
 
 estimateAffine3D
 --------------------
@@ -1072,6 +1086,9 @@ Class for computing stereo correspondence using the block matching algorithm. ::
 The class is a C++ wrapper for the associated functions. In particular, :ocv:funcx:`StereoBM::operator()` is the wrapper for
 :ocv:cfunc:`cvFindStereoCorrespondenceBM`.
 
+.. Sample code:
+
+   (Ocl) An example for using the stereoBM matching algorithm can be found at opencv_source_code/samples/ocl/stereo_match.cpp
 
 StereoBM::StereoBM
 ------------------
@@ -1171,7 +1188,9 @@ The class implements the modified H. Hirschmuller algorithm [HH08]_ that differs
 
  * Some pre- and post- processing steps from K. Konolige algorithm :ocv:funcx:`StereoBM::operator()`  are included, for example: pre-filtering (``CV_STEREO_BM_XSOBEL`` type) and post-filtering (uniqueness check, quadratic interpolation and speckle filtering).
 
+.. note::
 
+   * (Python) An example illustrating the use of the StereoSGBM matching algorithm can be found at opencv_source_code/samples/python2/stereo_match.py
 
 StereoSGBM::StereoSGBM
 --------------------------
index 0d1cc46..f213a11 100644 (file)
@@ -639,9 +639,9 @@ CV_EXPORTS Mat findFundamentalMat( InputArray points1, InputArray points2,
                                    double param1=3., double param2=0.99);
 
 //! finds coordinates of epipolar lines corresponding the specified points
-CV_EXPORTS void computeCorrespondEpilines( InputArray points,
-                                           int whichImage, InputArray F,
-                                           OutputArray lines );
+CV_EXPORTS_W void computeCorrespondEpilines( InputArray points,
+                                             int whichImage, InputArray F,
+                                             OutputArray lines );
 
 CV_EXPORTS_W void triangulatePoints( InputArray projMatr1, InputArray projMatr2,
                                      InputArray projPoints1, InputArray projPoints2,
diff --git a/modules/calib3d/perf/perf_precomp.cpp b/modules/calib3d/perf/perf_precomp.cpp
deleted file mode 100644 (file)
index 8552ac3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "perf_precomp.hpp"
diff --git a/modules/calib3d/src/precomp.cpp b/modules/calib3d/src/precomp.cpp
deleted file mode 100644 (file)
index 3e0ec42..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*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 "precomp.hpp"
-
-/* End of file. */
index 9b1f433..e96ba53 100644 (file)
@@ -42,9 +42,7 @@
 #ifndef __OPENCV_PRECOMP_H__
 #define __OPENCV_PRECOMP_H__
 
-#ifdef HAVE_CVCONFIG_H
 #include "cvconfig.h"
-#endif
 
 #include "opencv2/calib3d/calib3d.hpp"
 #include "opencv2/imgproc/imgproc.hpp"
diff --git a/modules/calib3d/test/test_precomp.cpp b/modules/calib3d/test/test_precomp.cpp
deleted file mode 100644 (file)
index 5956e13..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "test_precomp.hpp"
index 8bea707..9e8170d 100644 (file)
@@ -3,6 +3,12 @@ FaceRecognizer
 
 .. highlight:: cpp
 
+.. Sample code::
+
+   * An example using the FaceRecognizer class can be found at opencv_source_code/samples/cpp/facerec_demo.cpp
+
+   * (Python)  An example using the FaceRecognizer class can be found at opencv_source_code/samples/python2/facerec_demo.py
+
 FaceRecognizer
 --------------
 
index 2f2ad40..e2f157a 100644 (file)
@@ -9,6 +9,10 @@ FAB-MAP is an approach to appearance-based place recognition. FAB-MAP compares i
 
 openFABMAP requires training data (e.g. a collection of images from a similar but not identical environment) to construct a visual vocabulary for the visual bag-of-words model, along with a Chow-Liu tree representation of feature likelihood and for use in the Sampled new place method (see below).
 
+.. note::
+
+   * An example using the openFABMAP package can be found at opencv_source_code/samples/cpp/fabmap_sample.cpp
+
 of2::FabMap
 --------------------
 
index a3a5bc8..3d1f59c 100644 (file)
@@ -63,6 +63,11 @@ The retina can be settled up with various parameters, by default, the retina can
     void activateContoursProcessing (const bool activate);
   };
 
+.. Sample code::
+
+   * An example on retina tone mapping can be found at opencv_source_code/samples/cpp/OpenEXRimages_HighDynamicRange_Retina_toneMapping.cpp
+   * An example on retina tone mapping on video input can be found at opencv_source_code/samples/cpp/OpenEXRimages_HighDynamicRange_Retina_toneMapping.cpp
+   * A complete example illustrating the retina interface can be found at opencv_source_code/samples/cpp/retinaDemo.cpp
 
 Description
 +++++++++++
index 8004787..0e2afd9 100644 (file)
@@ -744,7 +744,7 @@ static void fjac(int /*i*/, int /*j*/, CvMat *point_params, CvMat* cam_params, C
   CvMat* _mp = cvCreateMat(1, 1, CV_64FC2 ); //projection of the point
 
   //split camera params into different matrices
-  CvMat _ri, _ti, _k;
+  CvMat _ri, _ti, _k = cvMat(0, 0, CV_64F, NULL); // dummy initialization to fix warning of cl.exe
   cvGetRows( cam_params, &_ri, 0, 3 );
   cvGetRows( cam_params, &_ti, 3, 6 );
 
index 44d5610..87cccf4 100644 (file)
@@ -59,6 +59,7 @@ CvFeatureTracker::CvFeatureTracker(CvFeatureTrackerParams _params) :
         dd->set("nOctaveLayers", 5);
         dd->set("contrastThreshold", 0.04);
         dd->set("edgeThreshold", 10.7);
+        break;
     case CvFeatureTrackerParams::SURF:
         dd = Algorithm::create<Feature2D>("Feature2D.SURF");
         if( dd.empty() )
@@ -66,8 +67,10 @@ CvFeatureTracker::CvFeatureTracker(CvFeatureTrackerParams _params) :
         dd->set("hessianThreshold", 400);
         dd->set("nOctaves", 3);
         dd->set("nOctaveLayers", 4);
+        break;
     default:
         CV_Error(CV_StsBadArg, "Unknown feature type");
+        break;
     }
 
     matcher = new BFMatcher(NORM_L2);
index d10d884..e04740f 100644 (file)
@@ -1,7 +1,8 @@
 
 #include "opencv2/contrib/contrib.hpp"
+#include <cvconfig.h>
 
-#ifdef WIN32
+#if defined(WIN32) || defined(_WIN32)
     #include <windows.h>
     #include <tchar.h>
 #else
@@ -16,10 +17,22 @@ namespace cv
         list.clear();
         std::string path_f = path + "/" + exten;
         #ifdef WIN32
-            WIN32_FIND_DATA FindFileData;
-            HANDLE hFind;
-
-            hFind = FindFirstFile((LPCSTR)path_f.c_str(), &FindFileData);
+        #ifdef HAVE_WINRT
+            WIN32_FIND_DATAW FindFileData;
+        #else
+            WIN32_FIND_DATAA FindFileData;
+        #endif
+        HANDLE hFind;
+
+        #ifdef HAVE_WINRT
+            size_t size = mbstowcs(NULL, path_f.c_str(), path_f.size());
+            Ptr<wchar_t> wpath = new wchar_t[size+1];
+            wpath[size] = 0;
+            mbstowcs(wpath, path_f.c_str(), path_f.size());
+            hFind = FindFirstFileExW(wpath, FindExInfoStandard, &FindFileData, FindExSearchNameMatch, NULL, 0);
+        #else
+            hFind = FindFirstFileA((LPCSTR)path_f.c_str(), &FindFileData);
+        #endif
             if (hFind == INVALID_HANDLE_VALUE)
             {
                 return list;
@@ -34,13 +47,26 @@ namespace cv
                         FindFileData.dwFileAttributes == FILE_ATTRIBUTE_SYSTEM  ||
                         FindFileData.dwFileAttributes == FILE_ATTRIBUTE_READONLY)
                     {
+                        cv::Ptr<char> fname;
+                    #ifdef HAVE_WINRT
+                        size_t asize = wcstombs(NULL, FindFileData.cFileName, 0);
+                        fname = new char[asize+1];
+                        fname[asize] = 0;
+                        wcstombs(fname, FindFileData.cFileName, asize);
+                    #else
+                        fname = FindFileData.cFileName;
+                    #endif
                         if (addPath)
-                            list.push_back(path + "/" + FindFileData.cFileName);
+                            list.push_back(path + "/" + std::string(fname));
                         else
-                            list.push_back(FindFileData.cFileName);
+                            list.push_back(std::string(fname));
                     }
                 }
-                while(FindNextFile(hFind, &FindFileData));
+            #ifdef HAVE_WINRT
+                while(FindNextFileW(hFind, &FindFileData));
+            #else
+                while(FindNextFileA(hFind, &FindFileData));
+            #endif
                 FindClose(hFind);
             }
         #else
@@ -75,10 +101,22 @@ namespace cv
         std::string path_f = path + "/" + exten;
         list.clear();
         #ifdef WIN32
-            WIN32_FIND_DATA FindFileData;
+        #ifdef HAVE_WINRT
+            WIN32_FIND_DATAW FindFileData;
+        #else
+            WIN32_FIND_DATAA FindFileData;
+        #endif
             HANDLE hFind;
 
-            hFind = FindFirstFile((LPCSTR)path_f.c_str(), &FindFileData);
+        #ifdef HAVE_WINRT
+            size_t size = mbstowcs(NULL, path_f.c_str(), path_f.size());
+            Ptr<wchar_t> wpath = new wchar_t[size+1];
+            wpath[size] = 0;
+            mbstowcs(wpath, path_f.c_str(), path_f.size());
+            hFind = FindFirstFileExW(wpath, FindExInfoStandard, &FindFileData, FindExSearchNameMatch, NULL, 0);
+        #else
+            hFind = FindFirstFileA((LPCSTR)path_f.c_str(), &FindFileData);
+        #endif
             if (hFind == INVALID_HANDLE_VALUE)
             {
                 return list;
@@ -87,17 +125,37 @@ namespace cv
             {
                 do
                 {
+#ifdef HAVE_WINRT
+                    if (FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY &&
+                        wcscmp(FindFileData.cFileName, L".") != 0 &&
+                        wcscmp(FindFileData.cFileName, L"..") != 0)
+#else
                     if (FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY &&
                         strcmp(FindFileData.cFileName, ".") != 0 &&
                         strcmp(FindFileData.cFileName, "..") != 0)
+#endif
                     {
+                        cv::Ptr<char> fname;
+                    #ifdef HAVE_WINRT
+                        size_t asize = wcstombs(NULL, FindFileData.cFileName, 0);
+                        fname = new char[asize+1];
+                        fname[asize] = 0;
+                        wcstombs(fname, FindFileData.cFileName, asize);
+                    #else
+                        fname = FindFileData.cFileName;
+                    #endif
+
                         if (addPath)
-                            list.push_back(path + "/" + FindFileData.cFileName);
+                            list.push_back(path + "/" + std::string(fname));
                         else
-                            list.push_back(FindFileData.cFileName);
+                            list.push_back(std::string(fname));
                     }
                 }
-                while(FindNextFile(hFind, &FindFileData));
+            #ifdef HAVE_WINRT
+                while(FindNextFileW(hFind, &FindFileData));
+            #else
+                while(FindNextFileA(hFind, &FindFileData));
+            #endif
                 FindClose(hFind);
             }
 
diff --git a/modules/contrib/src/precomp.cpp b/modules/contrib/src/precomp.cpp
deleted file mode 100644 (file)
index 3e0ec42..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*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 "precomp.hpp"
-
-/* End of file. */
index 7c8e6bd..30232f7 100644 (file)
@@ -43,9 +43,7 @@
 #ifndef __OPENCV_PRECOMP_H__
 #define __OPENCV_PRECOMP_H__
 
-#ifdef HAVE_CVCONFIG_H
 #include "cvconfig.h"
-#endif
 
 #include "opencv2/contrib/contrib.hpp"
 #include "opencv2/features2d/features2d.hpp"
diff --git a/modules/contrib/test/test_precomp.cpp b/modules/contrib/test/test_precomp.cpp
deleted file mode 100644 (file)
index 5956e13..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "test_precomp.hpp"
index dc62a88..fe13daa 100644 (file)
@@ -2,6 +2,10 @@ set(the_description "The Core Functionality")
 ocv_add_module(core ${ZLIB_LIBRARIES})
 ocv_module_include_directories(${ZLIB_INCLUDE_DIR})
 
+if (HAVE_WINRT)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /ZW /GS /Gm- /AI\"${WINDOWS_SDK_PATH}/References/CommonConfiguration/Neutral\" /AI\"${VISUAL_STUDIO_PATH}/vcpackages\"")
+endif()
+
 if(HAVE_CUDA)
   ocv_include_directories("${OpenCV_SOURCE_DIR}/modules/gpu/include")
   ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef)
index acfbb91..981ac5c 100644 (file)
@@ -489,6 +489,9 @@ Various Ptr constructors.
 .. ocv:function:: Ptr::Ptr(_Tp* _obj)
 .. ocv:function:: Ptr::Ptr(const Ptr& ptr)
 
+    :param _obj: Object for copy.
+    :param ptr: Object for copy.
+
 Ptr::~Ptr
 ---------
 The Ptr destructor.
@@ -501,6 +504,8 @@ Assignment operator.
 
 .. ocv:function:: Ptr& Ptr::operator = (const Ptr& ptr)
 
+    :param ptr: Object for assignment.
+
 Decrements own reference counter (with ``release()``) and increments ptr's reference counter.
 
 Ptr::addref
@@ -798,6 +803,9 @@ Finally, there are STL-style iterators that are smart enough to skip gaps betwee
 
 The matrix iterators are random-access iterators, so they can be passed to any STL algorithm, including ``std::sort()`` .
 
+.. note::
+
+   * An example demonstrating the serial out capabilities of cv::Mat can be found at opencv_source_code/samples/cpp/cout_mat.cpp
 
 .. _MatrixExpressions:
 
@@ -1465,6 +1473,7 @@ Adds elements to the bottom of the matrix.
 .. ocv:function:: void Mat::push_back( const Mat& m )
 
     :param elem: Added element(s).
+    :param m: Added line(s).
 
 The methods add one or more elements to the bottom of the matrix. They emulate the corresponding method of the STL vector class. When ``elem`` is ``Mat`` , its type and the number of columns must be the same as in the container matrix.
 
@@ -2160,7 +2169,6 @@ Various SparseMat constructors.
     :param dims: Array dimensionality.
     :param _sizes: Sparce matrix size on all dementions.
     :param _type: Sparse matrix data type.
-    :param try1d: if try1d is true and matrix is a single-column matrix (Nx1), then the sparse matrix will be 1-dimensional.
 
 SparseMat::~SparseMat
 ---------------------
@@ -2175,6 +2183,8 @@ Provides sparse matrix assignment operators.
 .. ocv:function:: SparseMat& SparseMat::operator = (const SparseMat& m)
 .. ocv:function:: SparseMat& SparseMat::operator = (const Mat& m)
 
+    :param m: Matrix for assignment.
+
 The last variant is equivalent to the corresponding constructor with try1d=false.
 
 
@@ -2202,6 +2212,10 @@ Convert sparse matrix with possible type change and scaling.
 .. ocv:function:: void SparseMat::convertTo( SparseMat& m, int rtype, double alpha=1 ) const
 .. ocv:function:: void SparseMat::convertTo( Mat& m, int rtype, double alpha=1, double beta=0 ) const
 
+    :param m: Destination matrix.
+    :param rtype: Destination matrix type.
+    :param alpha: Conversion multiplier.
+
 The first version converts arbitrary sparse matrix to dense matrix and multiplies all the matrix elements by the specified scalar.
 The second versiob converts sparse matrix to dense matrix with optional type conversion and scaling.
 When rtype=-1, the destination element type will be the same as the sparse matrix element type.
@@ -2294,7 +2308,7 @@ The method returns the number of matrix channels.
 
 SparseMat::size
 ---------------
-Returns the array of sizes or matrix size by i dimention and 0 if the matrix is not allocated.
+Returns the array of sizes or matrix size by i dimension and 0 if the matrix is not allocated.
 
 .. ocv:function:: const int* SparseMat::size() const
 .. ocv:function:: int SparseMat::size(int i) const
@@ -2322,6 +2336,11 @@ Compute element hash value from the element indices.
 .. ocv:function:: size_t SparseMat::hash(int i0, int i1, int i2) const
 .. ocv:function:: size_t SparseMat::hash(const int* idx) const
 
+    :param i0: The first dimension index.
+    :param i1: The second dimension index.
+    :param i2: The third dimension index.
+    :param idx: Array of element indices for multidimensional matices.
+
 SparseMat::ptr
 --------------
 Low-level element-access functions, special variants for 1D, 2D, 3D cases, and the generic one for n-D case.
@@ -2331,6 +2350,12 @@ Low-level element-access functions, special variants for 1D, 2D, 3D cases, and t
 .. ocv:function:: uchar* SparseMat::ptr(int i0, int i1, int i2, bool createMissing, size_t* hashval=0)
 .. ocv:function:: uchar* SparseMat::ptr(const int* idx, bool createMissing, size_t* hashval=0)
 
+    :param i0: The first dimension index.
+    :param i1: The second dimension index.
+    :param i2: The third dimension index.
+    :param idx: Array of element indices for multidimensional matices.
+    :param createMissing: Create new element with 0 value if it does not exist in SparseMat.
+
 Return pointer to the matrix element. If the element is there (it is non-zero), the pointer to it is returned.
 If it is not there and ``createMissing=false``, NULL pointer is returned. If it is not there and ``createMissing=true``,
 the new elementis created and initialized with 0. Pointer to it is returned. If the optional hashval pointer is not ``NULL``,
@@ -2344,6 +2369,11 @@ Erase the specified matrix element. When there is no such an element, the method
 .. ocv:function:: void SparseMat::erase(int i0, int i1, int i2, size_t* hashval=0)
 .. ocv:function:: void SparseMat::erase(const int* idx, size_t* hashval=0)
 
+    :param i0: The first dimension index.
+    :param i1: The second dimension index.
+    :param i2: The third dimension index.
+    :param idx: Array of element indices for multidimensional matices.
+
 SparseMat\_
 -----------
 .. ocv:class:: SparseMat_
index 46130bc..090a75d 100644 (file)
@@ -17,12 +17,18 @@ Finds centers of clusters and groups input samples around the clusters.
 
     :param samples: Floating-point matrix of input samples, one row per sample.
 
+    :param data: Data for clustering.
+
     :param cluster_count: Number of clusters to split the set by.
 
+    :param K: Number of clusters to split the set by.
+
     :param labels: Input/output integer array that stores the cluster indices for every sample.
 
     :param criteria: The algorithm termination criteria, that is, the maximum number of iterations and/or the desired accuracy. The accuracy is specified as ``criteria.epsilon``. As soon as each of the cluster centers moves by less than ``criteria.epsilon`` on some iteration, the algorithm stops.
 
+    :param termcrit: The algorithm termination criteria, that is, the maximum number of iterations and/or the desired accuracy.
+
     :param attempts: Flag to specify the number of times the algorithm is executed using different initial labellings. The algorithm returns the labels that yield the best compactness (see the last function parameter).
 
     :param rng: CvRNG state initialized by RNG().
@@ -37,6 +43,8 @@ Finds centers of clusters and groups input samples around the clusters.
 
     :param centers: Output matrix of the cluster centers, one row per each cluster center.
 
+    :param _centers: Output matrix of the cluster centers, one row per each cluster center.
+
     :param compactness: The returned value that is described below.
 
 The function ``kmeans`` implements a k-means algorithm that finds the
@@ -58,6 +66,12 @@ Basically, you can use only the core of the function, set the number of
 attempts to 1, initialize labels each time using a custom algorithm, pass them with the
 ( ``flags`` = ``KMEANS_USE_INITIAL_LABELS`` ) flag, and then choose the best (most-compact) clustering.
 
+.. note::
+
+   * An example on K-means clustering can be found at opencv_source_code/samples/cpp/kmeans.cpp
+
+   * (Python) An example on K-means clustering can be found at opencv_source_code/samples/python2/kmeans.py
+
 partition
 -------------
 Splits an element set into equivalency classes.
index 7eb4e3e..fc1afa6 100644 (file)
@@ -14,4 +14,5 @@ core. The Core Functionality
     old_xml_yaml_persistence
     clustering
     utility_and_system_functions_and_macros
+    opengl_interop
 
index 24328f9..472ebfd 100644 (file)
@@ -26,6 +26,10 @@ If a drawn figure is partially or completely outside the image, the drawing func
 
 .. note:: The functions do not support alpha-transparency when the target image is 4-channel. In this case, the ``color[3]`` is simply copied to the repainted pixels. Thus, if you want to paint semi-transparent shapes, you can paint them in a separate buffer and then blend it with the main image.
 
+.. note::
+
+   * An example on using variate drawing functions like line, rectangle, ... can be found at opencv_source_code/samples/cpp/drawing.cpp
+
 circle
 ----------
 Draws a circle.
@@ -234,6 +238,8 @@ Calculates the width and height of a text string.
 
     :param text: Input text string.
 
+    :param text_string: Input text string in C format.
+
     :param fontFace: Font to use. See the  :ocv:func:`putText` for details.
 
     :param fontScale: Font scale. See the  :ocv:func:`putText`  for details.
@@ -242,6 +248,12 @@ Calculates the width and height of a text string.
 
     :param baseLine: Output parameter - y-coordinate of the baseline relative to the bottom-most text point.
 
+    :param baseline: Output parameter - y-coordinate of the baseline relative to the bottom-most text point.
+
+    :param font: Font description in terms of old C API.
+
+    :param text_size: Output parameter - The size of a box that contains the specified text.
+
 The function ``getTextSize`` calculates and returns the size of a box that contains the specified text.
 That is, the following code renders some text, the tight box surrounding it, and the baseline: ::
 
diff --git a/modules/core/doc/opengl_interop.rst b/modules/core/doc/opengl_interop.rst
new file mode 100644 (file)
index 0000000..e0db36a
--- /dev/null
@@ -0,0 +1,543 @@
+OpenGL interoperability
+=======================
+
+.. highlight:: cpp
+
+
+
+General Information
+-------------------
+This section describes OpenGL interoperability.
+
+To enable OpenGL support, configure OpenCV using ``CMake`` with ``WITH_OPENGL=ON`` .
+Currently OpenGL is supported only with WIN32, GTK and Qt backends on Windows and Linux (MacOS and Android are not supported).
+For GTK backend ``gtkglext-1.0`` library is required.
+
+To use OpenGL functionality you should first create OpenGL context (window or frame buffer).
+You can do this with :ocv:func:`namedWindow` function or with other OpenGL toolkit (GLUT, for example).
+
+
+
+ogl::Buffer
+-----------
+Smart pointer for OpenGL buffer object with reference counting.
+
+.. ocv:class:: ogl::Buffer
+
+Buffer Objects are OpenGL objects that store an array of unformatted memory allocated by the OpenGL context.
+These can be used to store vertex data, pixel data retrieved from images or the framebuffer, and a variety of other things.
+
+``ogl::Buffer`` has interface similar with :ocv:class:`Mat` interface and represents 2D array memory.
+
+``ogl::Buffer`` supports memory transfers between host and device and also can be mapped to CUDA memory.
+
+
+
+ogl::Buffer::Target
+-------------------
+The target defines how you intend to use the buffer object.
+
+.. ocv:enum:: ogl::Buffer::Target
+
+    .. ocv:emember:: ARRAY_BUFFER
+
+        The buffer will be used as a source for vertex data.
+
+    .. ocv:emember:: ELEMENT_ARRAY_BUFFER
+
+        The buffer will be used for indices (in ``glDrawElements`` or :ocv:func:`ogl::render`, for example).
+
+    .. ocv:emember:: PIXEL_PACK_BUFFER
+
+        The buffer will be used for reading from OpenGL textures.
+
+    .. ocv:emember:: PIXEL_UNPACK_BUFFER
+
+        The buffer will be used for writing to OpenGL textures.
+
+
+
+ogl::Buffer::Buffer
+-------------------
+The constructors.
+
+.. ocv:function:: ogl::Buffer::Buffer()
+
+.. ocv:function:: ogl::Buffer::Buffer(int arows, int acols, int atype, unsigned int abufId, bool autoRelease = false)
+
+.. ocv:function:: ogl::Buffer::Buffer(Size asize, int atype, unsigned int abufId, bool autoRelease = false)
+
+.. ocv:function:: ogl::Buffer::Buffer(int arows, int acols, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false)
+
+.. ocv:function:: ogl::Buffer::Buffer(Size asize, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false)
+
+.. ocv:function:: ogl::Buffer::Buffer(InputArray arr, Target target = ARRAY_BUFFER, bool autoRelease = false)
+
+    :param arows: Number of rows in a 2D array.
+
+    :param acols: Number of columns in a 2D array.
+
+    :param asize: 2D array size.
+
+    :param atype: Array type ( ``CV_8UC1, ..., CV_64FC4`` ). See :ocv:class:`Mat` for details.
+
+    :param abufId: Buffer object name.
+
+    :param arr: Input array (host or device memory, it can be :ocv:class:`Mat` , :ocv:class:`gpu::GpuMat` or ``std::vector`` ).
+
+    :param target: Buffer usage. See :ocv:enum:`ogl::Buffer::Target` .
+
+    :param autoRelease: Auto release mode (if true, release will be called in object's destructor).
+
+Creates empty ``ogl::Buffer`` object, creates ``ogl::Buffer`` object from existed buffer ( ``abufId`` parameter),
+allocates memory for ``ogl::Buffer`` object or copies from host/device memory.
+
+
+
+ogl::Buffer::create
+-------------------
+Allocates memory for ``ogl::Buffer`` object.
+
+.. ocv:function:: void ogl::Buffer::create(int arows, int acols, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false)
+
+.. ocv:function:: void ogl::Buffer::create(Size asize, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false)
+
+    :param arows: Number of rows in a 2D array.
+
+    :param acols: Number of columns in a 2D array.
+
+    :param asize: 2D array size.
+
+    :param atype: Array type ( ``CV_8UC1, ..., CV_64FC4`` ). See :ocv:class:`Mat` for details.
+
+    :param target: Buffer usage. See :ocv:enum:`ogl::Buffer::Target` .
+
+    :param autoRelease: Auto release mode (if true, release will be called in object's destructor).
+
+
+
+ogl::Buffer::release
+--------------------
+Decrements the reference counter and destroys the buffer object if needed.
+
+.. ocv:function:: void ogl::Buffer::release()
+
+
+
+ogl::Buffer::setAutoRelease
+---------------------------
+Sets auto release mode.
+
+.. ocv:function:: void ogl::Buffer::setAutoRelease(bool flag)
+
+    :param flag: Auto release mode (if true, release will be called in object's destructor).
+
+The lifetime of the OpenGL object is tied to the lifetime of the context.
+If OpenGL context was bound to a window it could be released at any time (user can close a window).
+If object's destructor is called after destruction of the context it will cause an error.
+Thus ``ogl::Buffer`` doesn't destroy OpenGL object in destructor by default (all OpenGL resources will be released with OpenGL context).
+This function can force ``ogl::Buffer`` destructor to destroy OpenGL object.
+
+
+
+ogl::Buffer::copyFrom
+---------------------
+Copies from host/device memory to OpenGL buffer.
+
+.. ocv:function:: void ogl::Buffer::copyFrom(InputArray arr, Target target = ARRAY_BUFFER, bool autoRelease = false)
+
+    :param arr: Input array (host or device memory, it can be :ocv:class:`Mat` , :ocv:class:`gpu::GpuMat` or ``std::vector`` ).
+
+    :param target: Buffer usage. See :ocv:enum:`ogl::Buffer::Target` .
+
+    :param autoRelease: Auto release mode (if true, release will be called in object's destructor).
+
+
+
+ogl::Buffer::copyTo
+-------------------
+Copies from OpenGL buffer to host/device memory or another OpenGL buffer object.
+
+.. ocv:function:: void ogl::Buffer::copyTo(OutputArray arr, Target target = ARRAY_BUFFER, bool autoRelease = false) const
+
+    :param arr: Destination array (host or device memory, can be :ocv:class:`Mat` , :ocv:class:`gpu::GpuMat` , ``std::vector`` or ``ogl::Buffer`` ).
+
+    :param target: Buffer usage for destination buffer (if ``arr`` is OpenGL buffer).
+
+    :param autoRelease: Auto release mode for destination buffer (if ``arr`` is OpenGL buffer).
+
+
+
+ogl::Buffer::clone
+------------------
+Creates a full copy of the buffer object and the underlying data.
+
+.. ocv:function:: Buffer ogl::Buffer::clone(Target target = ARRAY_BUFFER, bool autoRelease = false) const
+
+    :param target: Buffer usage for destination buffer.
+
+    :param autoRelease: Auto release mode for destination buffer.
+
+
+
+ogl::Buffer::bind
+-----------------
+Binds OpenGL buffer to the specified buffer binding point.
+
+.. ocv:function:: void ogl::Buffer::bind(Target target) const
+
+    :param target: Binding point. See :ocv:enum:`ogl::Buffer::Target` .
+
+
+
+ogl::Buffer::unbind
+-------------------
+Unbind any buffers from the specified binding point.
+
+.. ocv:function:: static void ogl::Buffer::unbind(Target target)
+
+    :param target: Binding point. See :ocv:enum:`ogl::Buffer::Target` .
+
+
+
+ogl::Buffer::mapHost
+--------------------
+Maps OpenGL buffer to host memory.
+
+.. ocv:function:: Mat ogl::Buffer::mapHost(Access access)
+
+    :param access: Access policy, indicating whether it will be possible to read from, write to, or both read from and write to the buffer object's mapped data store. The symbolic constant must be ``ogl::Buffer::READ_ONLY`` , ``ogl::Buffer::WRITE_ONLY`` or ``ogl::Buffer::READ_WRITE`` .
+
+``mapHost`` maps to the client's address space the entire data store of the buffer object.
+The data can then be directly read and/or written relative to the returned pointer, depending on the specified ``access`` policy.
+
+A mapped data store must be unmapped with :ocv:func:`ogl::Buffer::unmapHost` before its buffer object is used.
+
+This operation can lead to memory transfers between host and device.
+
+Only one buffer object can be mapped at a time.
+
+
+
+ogl::Buffer::unmapHost
+----------------------
+Unmaps OpenGL buffer.
+
+.. ocv:function:: void ogl::Buffer::unmapHost()
+
+
+
+ogl::Buffer::mapDevice
+----------------------
+Maps OpenGL buffer to CUDA device memory.
+
+.. ocv:function:: gpu::GpuMat ogl::Buffer::mapDevice()
+
+This operatation doesn't copy data.
+Several buffer objects can be mapped to CUDA memory at a time.
+
+A mapped data store must be unmapped with :ocv:func:`ogl::Buffer::unmapDevice` before its buffer object is used.
+
+
+
+ogl::Buffer::unmapDevice
+------------------------
+Unmaps OpenGL buffer.
+
+.. ocv:function:: void ogl::Buffer::unmapDevice()
+
+
+
+ogl::Texture2D
+--------------
+Smart pointer for OpenGL 2D texture memory with reference counting.
+
+.. ocv:class:: ogl::Texture2D
+
+
+
+ogl::Texture2D::Format
+----------------------
+An Image Format describes the way that the images in Textures store their data.
+
+.. ocv:enum:: ogl::Texture2D::Format
+
+    .. ocv:emember:: NONE
+    .. ocv:emember:: DEPTH_COMPONENT
+    .. ocv:emember:: RGB
+    .. ocv:emember:: RGBA
+
+
+
+ogl::Texture2D::Texture2D
+-------------------------
+The constructors.
+
+.. ocv:function:: ogl::Texture2D::Texture2D()
+
+.. ocv:function:: ogl::Texture2D::Texture2D(int arows, int acols, Format aformat, unsigned int atexId, bool autoRelease = false)
+
+.. ocv:function:: ogl::Texture2D::Texture2D(Size asize, Format aformat, unsigned int atexId, bool autoRelease = false)
+
+.. ocv:function:: ogl::Texture2D::Texture2D(int arows, int acols, Format aformat, bool autoRelease = false)
+
+.. ocv:function:: ogl::Texture2D::Texture2D(Size asize, Format aformat, bool autoRelease = false)
+
+.. ocv:function:: ogl::Texture2D::Texture2D(InputArray arr, bool autoRelease = false)
+
+    :param arows: Number of rows.
+
+    :param acols: Number of columns.
+
+    :param asize: 2D array size.
+
+    :param aformat: Image format. See :ocv:enum:`ogl::Texture2D::Format` .
+
+    :param arr: Input array (host or device memory, it can be :ocv:class:`Mat` , :ocv:class:`gpu::GpuMat` or :ocv:class:`ogl::Buffer` ).
+
+    :param autoRelease: Auto release mode (if true, release will be called in object's destructor).
+
+Creates empty ``ogl::Texture2D`` object, allocates memory for ``ogl::Texture2D`` object or copies from host/device memory.
+
+
+
+ogl::Texture2D::create
+----------------------
+Allocates memory for ``ogl::Texture2D`` object.
+
+.. ocv:function:: void ogl::Texture2D::create(int arows, int acols, Format aformat, bool autoRelease = false)
+
+.. ocv:function:: void ogl::Texture2D::create(Size asize, Format aformat, bool autoRelease = false)
+
+    :param arows: Number of rows.
+
+    :param acols: Number of columns.
+
+    :param asize: 2D array size.
+
+    :param aformat: Image format. See :ocv:enum:`ogl::Texture2D::Format` .
+
+    :param autoRelease: Auto release mode (if true, release will be called in object's destructor).
+
+
+
+ogl::Texture2D::release
+-----------------------
+Decrements the reference counter and destroys the texture object if needed.
+
+.. ocv:function:: void ogl::Texture2D::release()
+
+
+
+ogl::Texture2D::setAutoRelease
+------------------------------
+Sets auto release mode.
+
+.. ocv:function:: void ogl::Texture2D::setAutoRelease(bool flag)
+
+    :param flag: Auto release mode (if true, release will be called in object's destructor).
+
+The lifetime of the OpenGL object is tied to the lifetime of the context.
+If OpenGL context was bound to a window it could be released at any time (user can close a window).
+If object's destructor is called after destruction of the context it will cause an error.
+Thus ``ogl::Texture2D`` doesn't destroy OpenGL object in destructor by default (all OpenGL resources will be released with OpenGL context).
+This function can force ``ogl::Texture2D`` destructor to destroy OpenGL object.
+
+
+
+ogl::Texture2D::copyFrom
+------------------------
+Copies from host/device memory to OpenGL texture.
+
+.. ocv:function:: void ogl::Texture2D::copyFrom(InputArray arr, bool autoRelease = false)
+
+    :param arr: Input array (host or device memory, it can be :ocv:class:`Mat` , :ocv:class:`gpu::GpuMat` or :ocv:class:`ogl::Buffer` ).
+
+    :param autoRelease: Auto release mode (if true, release will be called in object's destructor).
+
+
+
+ogl::Texture2D::copyTo
+----------------------
+Copies from OpenGL texture to host/device memory or another OpenGL texture object.
+
+.. ocv:function:: void ogl::Texture2D::copyTo(OutputArray arr, int ddepth = CV_32F, bool autoRelease = false) const
+
+    :param arr: Destination array (host or device memory, can be :ocv:class:`Mat` , :ocv:class:`gpu::GpuMat` , :ocv:class:`ogl::Buffer` or ``ogl::Texture2D`` ).
+
+    :param ddepth: Destination depth.
+
+    :param autoRelease: Auto release mode for destination buffer (if ``arr`` is OpenGL buffer or texture).
+
+
+
+ogl::Texture2D::bind
+--------------------
+Binds texture to current active texture unit for ``GL_TEXTURE_2D`` target.
+
+.. ocv:function:: void ogl::Texture2D::bind() const
+
+
+
+ogl::Arrays
+-----------
+Wrapper for OpenGL Client-Side Vertex arrays.
+
+.. ocv:class:: ogl::Arrays
+
+``ogl::Arrays`` stores vertex data in :ocv:class:`ogl::Buffer` objects.
+
+
+
+ogl::Arrays::setVertexArray
+---------------------------
+Sets an array of vertex coordinates.
+
+.. ocv:function:: void ogl::Arrays::setVertexArray(InputArray vertex)
+
+    :param vertex: array with vertex coordinates, can be both host and device memory.
+
+
+
+ogl::Arrays::resetVertexArray
+-----------------------------
+Resets vertex coordinates.
+
+.. ocv:function:: void ogl::Arrays::resetVertexArray()
+
+
+
+ogl::Arrays::setColorArray
+--------------------------
+Sets an array of vertex colors.
+
+.. ocv:function:: void ogl::Arrays::setColorArray(InputArray color)
+
+    :param color: array with vertex colors, can be both host and device memory.
+
+
+
+ogl::Arrays::resetColorArray
+----------------------------
+Resets vertex colors.
+
+.. ocv:function:: void ogl::Arrays::resetColorArray()
+
+
+
+ogl::Arrays::setNormalArray
+---------------------------
+Sets an array of vertex normals.
+
+.. ocv:function:: void ogl::Arrays::setNormalArray(InputArray normal)
+
+    :param normal: array with vertex normals, can be both host and device memory.
+
+
+
+ogl::Arrays::resetNormalArray
+-----------------------------
+Resets vertex normals.
+
+.. ocv:function:: void ogl::Arrays::resetNormalArray()
+
+
+
+ogl::Arrays::setTexCoordArray
+-----------------------------
+Sets an array of vertex texture coordinates.
+
+.. ocv:function:: void ogl::Arrays::setTexCoordArray(InputArray texCoord)
+
+    :param texCoord: array with vertex texture coordinates, can be both host and device memory.
+
+
+
+ogl::Arrays::resetTexCoordArray
+-------------------------------
+Resets vertex texture coordinates.
+
+.. ocv:function:: void ogl::Arrays::resetTexCoordArray()
+
+
+
+ogl::Arrays::release
+--------------------
+Releases all inner buffers.
+
+.. ocv:function:: void ogl::Arrays::release()
+
+
+
+ogl::Arrays::setAutoRelease
+---------------------------
+Sets auto release mode all inner buffers.
+
+.. ocv:function:: void ogl::Arrays::setAutoRelease(bool flag)
+
+    :param flag: Auto release mode.
+
+
+
+ogl::Arrays::bind
+-----------------
+Binds all vertex arrays.
+
+.. ocv:function:: void ogl::Arrays::bind() const
+
+
+
+ogl::Arrays::size
+-----------------
+Returns the vertex count.
+
+.. ocv:function:: int ogl::Arrays::size() const
+
+
+
+ogl::render
+-----------
+Render OpenGL texture or primitives.
+
+.. ocv:function:: void ogl::render(const Texture2D& tex, Rect_<double> wndRect = Rect_<double>(0.0, 0.0, 1.0, 1.0), Rect_<double> texRect = Rect_<double>(0.0, 0.0, 1.0, 1.0))
+
+.. ocv:function:: void ogl::render(const Arrays& arr, int mode = POINTS, Scalar color = Scalar::all(255))
+
+.. ocv:function:: void ogl::render(const Arrays& arr, InputArray indices, int mode = POINTS, Scalar color = Scalar::all(255))
+
+    :param tex: Texture to draw.
+
+    :param wndRect: Region of window, where to draw a texture (normalized coordinates).
+
+    :param texRect: Region of texture to draw (normalized coordinates).
+
+    :param arr: Array of privitives vertices.
+
+    :param indices: Array of vertices indices (host or device memory).
+
+    :param mode: Render mode. Available options:
+
+        * **POINTS**
+        * **LINES**
+        * **LINE_LOOP**
+        * **LINE_STRIP**
+        * **TRIANGLES**
+        * **TRIANGLE_STRIP**
+        * **TRIANGLE_FAN**
+        * **QUADS**
+        * **QUAD_STRIP**
+        * **POLYGON**
+
+    :param color: Color for all vertices. Will be used if ``arr`` doesn't contain color array.
+
+
+
+gpu::setGlDevice
+----------------
+Sets a CUDA device and initializes it for the current thread with OpenGL interoperability.
+
+.. ocv:function:: void gpu::setGlDevice( int device = 0 )
+
+    :param device: System index of a GPU device starting with 0.
+
+This function should be explicitly called after OpenGL context creation and before any CUDA calls.
index d338444..a312818 100644 (file)
@@ -532,7 +532,7 @@ Performs the per-element comparison of two arrays or an array and scalar value.
 
     :param value: scalar value.
 
-    :param dst: output array that has the same size as the input arrays and type= ``CV_8UC1`` .
+    :param dst: output array that has the same size and type as the input arrays.
 
     :param cmpop: a flag, that specifies correspondence between the arrays:
 
@@ -997,6 +997,12 @@ All of the above improvements have been implemented in :ocv:func:`matchTemplate`
 
 .. seealso:: :ocv:func:`dct` , :ocv:func:`getOptimalDFTSize` , :ocv:func:`mulSpectrums`, :ocv:func:`filter2D` , :ocv:func:`matchTemplate` , :ocv:func:`flip` , :ocv:func:`cartToPolar` , :ocv:func:`magnitude` , :ocv:func:`phase`
 
+.. note::
+
+   * An example using the discrete fourier transform can be found at opencv_source_code/samples/cpp/dft.cpp
+
+   * (Python) An example using the dft functionality to perform Wiener deconvolution can be found at opencv_source/samples/python2/deconvolution.py
+   * (Python) An example rearranging the quadrants of a Fourier image can be found at opencv_source/samples/python2/dft.py
 
 
 divide
@@ -1062,6 +1068,8 @@ Returns the determinant of a square floating-point matrix.
 
     :param mtx: input matrix that must have ``CV_32FC1`` or ``CV_64FC1`` type and square size.
 
+    :param mat: input matrix that must have ``CV_32FC1`` or ``CV_64FC1`` type and square size.
+
 The function ``determinant`` calculates and returns the determinant of the specified matrix. For small matrices ( ``mtx.cols=mtx.rows<=3`` ),
 the direct method is used. For larger matrices, the function uses LU factorization with partial pivoting.
 
@@ -2260,7 +2268,9 @@ The sample below is the function that takes two matrices. The first function sto
     :ocv:func:`dft`,
     :ocv:func:`dct`
 
+.. note::
 
+   * An example using PCA for dimensionality reduction while maintaining an amount of variance can be found at opencv_source_code/samples/cpp/pca.cpp
 
 PCA::PCA
 --------
index 54198b0..41cf7e1 100644 (file)
@@ -173,6 +173,8 @@ Checks a condition at runtime and throws exception if it fails
 
 .. ocv:function:: CV_Assert(expr)
 
+    :param expr: Expression for check.
+
 The macros ``CV_Assert`` (and ``CV_DbgAssert``) evaluate the specified expression. If it is 0, the macros raise an error (see :ocv:func:`error` ). The macro ``CV_Assert`` checks the condition in both Debug and Release configurations while ``CV_DbgAssert`` is only retained in the Debug configuration.
 
 
@@ -188,8 +190,14 @@ Signals an error and raises an exception.
 
     :param status: Error code. Normally, it is a negative value. The list of pre-defined error codes can be found in  ``cxerror.h`` .
 
+    :param func_name: The function name where error occurs.
+
     :param err_msg: Text of the error message.
 
+    :param file_name: The file name where error occurs.
+
+    :param line: The line number where error occurs.
+
     :param args: ``printf`` -like formatted error message in parentheses.
 
 The function and the helper macros ``CV_Error`` and ``CV_Error_``: ::
@@ -249,6 +257,7 @@ Allocates an aligned memory buffer.
 .. ocv:cfunction:: void* cvAlloc( size_t size )
 
     :param size: Allocated buffer size.
+    :param bufSize: Allocated buffer size.
 
 The function allocates the buffer of the specified size and returns it. When the buffer size is 16 bytes or more, the returned buffer is aligned to 16 bytes.
 
index c7d55d0..01a1188 100644 (file)
@@ -11,7 +11,7 @@ You can store and then restore various OpenCV data structures to/from XML (http:
 
 Use the following procedure to write something to XML or YAML:
  #. Create new :ocv:class:`FileStorage` and open it for writing. It can be done with a single call to :ocv:func:`FileStorage::FileStorage` constructor that takes a filename, or you can use the default constructor and then call :ocv:func:`FileStorage::open`. Format of the file (XML or YAML) is determined from the filename extension (".xml" and ".yml"/".yaml", respectively)
- #. Write all the data you want using the streaming operator ``>>``, just like in the case of STL streams.
+ #. Write all the data you want using the streaming operator ``<<``, just like in the case of STL streams.
  #. Close the file using :ocv:func:`FileStorage::release`. ``FileStorage`` destructor also closes the file.
 
 Here is an example: ::
@@ -91,6 +91,10 @@ Several things can be noted by looking at the sample code and the output:
  *
    In YAML (but not XML), mappings and sequences can be written in a compact Python-like inline form. In the sample above matrix elements, as well as each feature, including its lbp value, is stored in such inline form. To store a mapping/sequence in a compact form, put ":" after the opening character, e.g. use **"{:"** instead of **"{"** and **"[:"** instead of **"["**. When the data is written to XML, those extra ":" are ignored.
 
+.. note::
+
+   * A complete example using the FileStorage interface can be found at opencv_source_code/samples/cpp/filestorage.cpp
+
 
 Reading data from a file storage.
 ---------------------------------
@@ -181,6 +185,17 @@ Opens a file.
 
 .. ocv:function:: bool FileStorage::open(const string& filename, int flags, const string& encoding=string())
 
+    :param filename: Name of the file to open or the text string to read the data from.
+                     Extension of the file (``.xml`` or ``.yml``/``.yaml``) determines its format (XML or YAML respectively).
+                     Also you can append ``.gz`` to work with compressed files, for example ``myHugeMatrix.xml.gz``.
+                     If both ``FileStorage::WRITE`` and ``FileStorage::MEMORY`` flags are specified, ``source``
+                     is used just to specify the output file format (e.g. ``mydata.xml``, ``.yml`` etc.).
+
+    :param flags: Mode of operation. See FileStorage constructor for more details.
+
+    :param encoding: Encoding of the file. Note that UTF-16 XML encoding is not supported currently and you should use 8-bit encoding instead of it.
+
+
 See description of parameters in :ocv:func:`FileStorage::FileStorage`. The method calls :ocv:func:`FileStorage::release` before opening the file.
 
 
index 2b77919..bc1a68f 100644 (file)
@@ -1322,7 +1322,8 @@ public:
         EXPR              = 6 << KIND_SHIFT,
         OPENGL_BUFFER     = 7 << KIND_SHIFT,
         OPENGL_TEXTURE    = 8 << KIND_SHIFT,
-        GPU_MAT           = 9 << KIND_SHIFT
+        GPU_MAT           = 9 << KIND_SHIFT,
+        OCL_MAT           =10 << KIND_SHIFT
     };
     _InputArray();
 
@@ -3409,8 +3410,6 @@ public:
     //! converts dense 2d matrix to the sparse form
     /*!
      \param m the input matrix
-     \param try1d if true and m is a single-column matrix (Nx1),
-            then the sparse matrix will be 1-dimensional.
     */
     explicit SparseMat(const Mat& m);
     //! converts old-style sparse matrix to the new-style. All the data is copied
index 5335fa0..2f26e7c 100644 (file)
@@ -50,6 +50,9 @@
 
 #include <vector>
 
+#include "opencv2/core/core.hpp"
+#include "opencv2/core/types_c.h"
+
 #if defined WIN32 || defined _WIN32
 #  ifndef WIN32
 #    define WIN32
@@ -133,7 +136,13 @@ CV_INLINE IppiSize ippiSize(int width, int height)
 #  endif
 #endif
 
-#ifdef __ARM_NEON__
+
+#if (defined WIN32 || defined _WIN32) && defined(_M_ARM)
+# include <Intrin.h>
+# include "arm_neon.h"
+# define CV_NEON 1
+# define CPU_HAS_NEON_FEATURE (true)
+#elif defined(__ARM_NEON__)
 #  include <arm_neon.h>
 #  define CV_NEON 1
 #  define CPU_HAS_NEON_FEATURE (true)
@@ -251,6 +260,10 @@ namespace cv
         body(range);
     }
 #endif
+
+    // Returns a static string if there is a parallel framework,
+    // NULL otherwise.
+    CV_EXPORTS const char* currentParallelFramework();
 } //namespace cv
 
 #define CV_INIT_ALGORITHM(classname, algname, memberinit) \
@@ -333,25 +346,6 @@ namespace cv
 *                                  Common declarations                                   *
 \****************************************************************************************/
 
-/* get alloca declaration */
-#ifdef __GNUC__
-#  undef alloca
-#  define alloca __builtin_alloca
-#  define CV_HAVE_ALLOCA 1
-#elif defined WIN32 || defined _WIN32 || \
-      defined WINCE || defined _MSC_VER || defined __BORLANDC__
-#  include <malloc.h>
-#  define CV_HAVE_ALLOCA 1
-#elif defined HAVE_ALLOCA_H
-#  include <alloca.h>
-#  define CV_HAVE_ALLOCA 1
-#elif defined HAVE_ALLOCA
-#  include <stdlib.h>
-#  define CV_HAVE_ALLOCA 1
-#else
-#  undef CV_HAVE_ALLOCA
-#endif
-
 #ifdef __GNUC__
 #  define CV_DECL_ALIGNED(x) __attribute__ ((aligned (x)))
 #elif defined _MSC_VER
@@ -360,11 +354,6 @@ namespace cv
 #  define CV_DECL_ALIGNED(x)
 #endif
 
-#if CV_HAVE_ALLOCA
-/* ! DO NOT make it an inline function */
-#  define cvStackAlloc(size) cvAlignPtr( alloca((size) + CV_MALLOC_ALIGN), CV_MALLOC_ALIGN )
-#endif
-
 #ifndef CV_IMPL
 #  define CV_IMPL CV_EXTERN_C
 #endif
index 8db2fe7..27e53cd 100644 (file)
 #ifndef CV_INLINE
 #  if defined __cplusplus
 #    define CV_INLINE inline
-#  elif (defined WIN32 || defined _WIN32 || defined WINCE) && !defined __GNUC__
+#  elif defined _MSC_VER
 #    define CV_INLINE __inline
 #  else
 #    define CV_INLINE static
@@ -317,7 +317,7 @@ CV_INLINE  int  cvRound( double value )
     return t;
 #elif defined _MSC_VER && defined _M_ARM && defined HAVE_TEGRA_OPTIMIZATION
     TEGRA_ROUND(value);
-#elif defined HAVE_LRINT || defined CV_ICC || defined __GNUC__
+#elif defined CV_ICC || defined __GNUC__
 #  ifdef HAVE_TEGRA_OPTIMIZATION
     TEGRA_ROUND(value);
 #  else
index 5676a17..ba71a82 100644 (file)
@@ -49,8 +49,8 @@
 
 #define CV_VERSION_EPOCH    2
 #define CV_VERSION_MAJOR    4
-#define CV_VERSION_MINOR    5
-#define CV_VERSION_REVISION 0
+#define CV_VERSION_MINOR    6
+#define CV_VERSION_REVISION 1
 
 #define CVAUX_STR_EXP(__A)  #__A
 #define CVAUX_STR(__A)      CVAUX_STR_EXP(__A)
diff --git a/modules/core/perf/perf_precomp.cpp b/modules/core/perf/perf_precomp.cpp
deleted file mode 100644 (file)
index 8552ac3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "perf_precomp.hpp"
index b7fc43d..9698076 100644 (file)
@@ -33,7 +33,7 @@ PERF_TEST_P(Size_MatType, mean, TYPICAL_MATS)
 
     TEST_CYCLE() s = mean(src);
 
-    SANITY_CHECK(s, 1e-6);
+    SANITY_CHECK(s, 1e-5);
 }
 
 PERF_TEST_P(Size_MatType, mean_mask, TYPICAL_MATS)
@@ -49,7 +49,7 @@ PERF_TEST_P(Size_MatType, mean_mask, TYPICAL_MATS)
 
     TEST_CYCLE() s = mean(src, mask);
 
-    SANITY_CHECK(s, 1e-6);
+    SANITY_CHECK(s, 5e-5);
 }
 
 PERF_TEST_P(Size_MatType, meanStdDev, TYPICAL_MATS)
index 1944ed1..37b1e0d 100644 (file)
@@ -94,9 +94,20 @@ void fastFree(void* ptr)
 #define STAT(stmt)
 
 #ifdef WIN32
+#if (_WIN32_WINNT >= 0x0602)
+#include <synchapi.h>
+#endif
+
 struct CriticalSection
 {
-    CriticalSection() { InitializeCriticalSection(&cs); }
+    CriticalSection()
+    {
+#if (_WIN32_WINNT >= 0x0600)
+        InitializeCriticalSectionEx(&cs, 1000, 0);
+#else
+        InitializeCriticalSection(&cs);
+#endif
+    }
     ~CriticalSection() { DeleteCriticalSection(&cs); }
     void lock() { EnterCriticalSection(&cs); }
     void unlock() { LeaveCriticalSection(&cs); }
index 9e33408..144fa96 100644 (file)
@@ -886,11 +886,13 @@ void ellipse2Poly( Point center, Size axes, int angle,
         Point pt;
         pt.x = cvRound( cx + x * alpha - y * beta );
         pt.y = cvRound( cy + x * beta + y * alpha );
-        if( pt != prevPt )
+        if( pt != prevPt ){
             pts.push_back(pt);
+            prevPt = pt;
+        }
     }
 
-    if( pts.size() < 2 )
+    if( pts.size() == 1 )
         pts.push_back(pts[0]);
 }
 
index b3c2b83..c76705f 100644 (file)
@@ -1458,6 +1458,10 @@ static void CCSIDFT_64f( const double* src, double* dst, int n, int nf, int* fac
 
 }
 
+#ifdef HAVE_IPP
+typedef IppStatus (CV_STDCALL* IppDFTGetSizeFunc)(int, int, IppHintAlgorithm, int*, int*, int*);
+typedef IppStatus (CV_STDCALL* IppDFTInitFunc)(int, int, IppHintAlgorithm, void*, uchar*);
+#endif
 
 void cv::dft( InputArray _src0, OutputArray _dst, int flags, int nonzero_rows )
 {
@@ -1483,7 +1487,7 @@ void cv::dft( InputArray _src0, OutputArray _dst, int flags, int nonzero_rows )
     int factors[34];
     bool inplace_transform = false;
 #ifdef HAVE_IPP
-    void *spec_r = 0, *spec_c = 0;
+    AutoBuffer<uchar> ippbuf;
     int ipp_norm_flag = !(flags & DFT_SCALE) ? 8 : inv ? 2 : 1;
 #endif
 
@@ -1543,52 +1547,51 @@ void cv::dft( InputArray _src0, OutputArray _dst, int flags, int nonzero_rows )
 
         spec = 0;
 #ifdef HAVE_IPP
-        if( len*count >= 64 ) // use IPP DFT if available
+        if(
+#if IPP_VERSION_MAJOR >= 7
+           depth == CV_32F && // IPP 7.x and 8.0 have bug somewhere in double-precision DFT
+#endif
+           len*count >= 64 ) // use IPP DFT if available
         {
-            int ipp_sz = 0;
+            int specsize=0, initsize=0, worksize=0;
+            IppDFTGetSizeFunc getSizeFunc = 0;
+            IppDFTInitFunc initFunc = 0;
 
             if( real_transform && stage == 0 )
             {
                 if( depth == CV_32F )
                 {
-                    if( spec_r )
-                        IPPI_CALL( ippsDFTFree_R_32f( (IppsDFTSpec_R_32f*)spec_r ));
-                    IPPI_CALL( ippsDFTInitAlloc_R_32f(
-                        (IppsDFTSpec_R_32f**)&spec_r, len, ipp_norm_flag, ippAlgHintNone ));
-                    IPPI_CALL( ippsDFTGetBufSize_R_32f( (IppsDFTSpec_R_32f*)spec_r, &ipp_sz ));
+                    getSizeFunc = ippsDFTGetSize_R_32f;
+                    initFunc = (IppDFTInitFunc)ippsDFTInit_R_32f;
                 }
                 else
                 {
-                    if( spec_r )
-                        IPPI_CALL( ippsDFTFree_R_64f( (IppsDFTSpec_R_64f*)spec_r ));
-                    IPPI_CALL( ippsDFTInitAlloc_R_64f(
-                        (IppsDFTSpec_R_64f**)&spec_r, len, ipp_norm_flag, ippAlgHintNone ));
-                    IPPI_CALL( ippsDFTGetBufSize_R_64f( (IppsDFTSpec_R_64f*)spec_r, &ipp_sz ));
+                    getSizeFunc = ippsDFTGetSize_R_64f;
+                    initFunc = (IppDFTInitFunc)ippsDFTInit_R_64f;
                 }
-                spec = spec_r;
             }
             else
             {
                 if( depth == CV_32F )
                 {
-                    if( spec_c )
-                        IPPI_CALL( ippsDFTFree_C_32fc( (IppsDFTSpec_C_32fc*)spec_c ));
-                    IPPI_CALL( ippsDFTInitAlloc_C_32fc(
-                        (IppsDFTSpec_C_32fc**)&spec_c, len, ipp_norm_flag, ippAlgHintNone ));
-                    IPPI_CALL( ippsDFTGetBufSize_C_32fc( (IppsDFTSpec_C_32fc*)spec_c, &ipp_sz ));
+                    getSizeFunc = ippsDFTGetSize_C_32fc;
+                    initFunc = (IppDFTInitFunc)ippsDFTInit_C_32fc;
                 }
                 else
                 {
-                    if( spec_c )
-                        IPPI_CALL( ippsDFTFree_C_64fc( (IppsDFTSpec_C_64fc*)spec_c ));
-                    IPPI_CALL( ippsDFTInitAlloc_C_64fc(
-                        (IppsDFTSpec_C_64fc**)&spec_c, len, ipp_norm_flag, ippAlgHintNone ));
-                    IPPI_CALL( ippsDFTGetBufSize_C_64fc( (IppsDFTSpec_C_64fc*)spec_c, &ipp_sz ));
+                    getSizeFunc = ippsDFTGetSize_C_64fc;
+                    initFunc = (IppDFTInitFunc)ippsDFTInit_C_64fc;
                 }
-                spec = spec_c;
             }
-
-            sz += ipp_sz;
+            if( getSizeFunc(len, ipp_norm_flag, ippAlgHintNone, &specsize, &initsize, &worksize) >= 0 )
+            {
+                ippbuf.allocate(specsize + initsize + 64);
+                spec = alignPtr(&ippbuf[0], 32);
+                uchar* initbuf = alignPtr((uchar*)spec + specsize, 32);
+                if( initFunc(len, ipp_norm_flag, ippAlgHintNone, spec, initbuf) < 0 )
+                    spec = 0;
+                sz += worksize;
+            }
         }
         else
 #endif
@@ -1862,24 +1865,6 @@ void cv::dft( InputArray _src0, OutputArray _dst, int flags, int nonzero_rows )
             src = dst;
         }
     }
-
-#ifdef HAVE_IPP
-    if( spec_c )
-    {
-        if( depth == CV_32F )
-            ippsDFTFree_C_32fc( (IppsDFTSpec_C_32fc*)spec_c );
-        else
-            ippsDFTFree_C_64fc( (IppsDFTSpec_C_64fc*)spec_c );
-    }
-
-    if( spec_r )
-    {
-        if( depth == CV_32F )
-            ippsDFTFree_R_32f( (IppsDFTSpec_R_32f*)spec_r );
-        else
-            ippsDFTFree_R_64f( (IppsDFTSpec_R_64f*)spec_r );
-    }
-#endif
 }
 
 
index 368f304..e39cba0 100644 (file)
@@ -56,16 +56,39 @@ namespace
 
     struct DIR
     {
+#ifdef HAVE_WINRT
+        WIN32_FIND_DATAW data;
+#else
         WIN32_FIND_DATA data;
+#endif
         HANDLE handle;
         dirent ent;
+#ifdef HAVE_WINRT
+        DIR() {};
+        ~DIR()
+        {
+            if (ent.d_name)
+                delete[] ent.d_name;
+        }
+#endif
     };
 
     DIR* opendir(const char* path)
     {
         DIR* dir = new DIR;
         dir->ent.d_name = 0;
-        dir->handle = ::FindFirstFileA((cv::String(path) + "\\*").c_str(), &dir->data);
+#ifdef HAVE_WINRT
+        cv::String full_path = cv::String(path) + "\\*";
+        size_t size = mbstowcs(NULL, full_path.c_str(), full_path.size());
+        cv::Ptr<wchar_t> wfull_path = new wchar_t[size+1];
+        wfull_path[size] = 0;
+        mbstowcs(wfull_path, full_path.c_str(), full_path.size());
+        dir->handle = ::FindFirstFileExW(wfull_path, FindExInfoStandard,
+                        &dir->data, FindExSearchNameMatch, NULL, 0);
+#else
+        dir->handle = ::FindFirstFileExA((cv::String(path) + "\\*").c_str(),
+            FindExInfoStandard, &dir->data, FindExSearchNameMatch, NULL, 0);
+#endif
         if(dir->handle == INVALID_HANDLE_VALUE)
         {
             /*closedir will do all cleanup*/
@@ -76,12 +99,25 @@ namespace
 
     dirent* readdir(DIR* dir)
     {
+#ifdef HAVE_WINRT
         if (dir->ent.d_name != 0)
         {
-            if (::FindNextFile(dir->handle, &dir->data) != TRUE)
+            if (::FindNextFileW(dir->handle, &dir->data) != TRUE)
+                return 0;
+        }
+        size_t asize = wcstombs(NULL, dir->data.cFileName, 0);
+        char* aname = new char[asize+1];
+        aname[asize] = 0;
+        wcstombs(aname, dir->data.cFileName, asize);
+        dir->ent.d_name = aname;
+#else
+        if (dir->ent.d_name != 0)
+        {
+            if (::FindNextFileA(dir->handle, &dir->data) != TRUE)
                 return 0;
         }
         dir->ent.d_name = dir->data.cFileName;
+#endif
         return &dir->ent;
     }
 
@@ -107,7 +143,19 @@ static bool isDir(const cv::String& path, DIR* dir)
     if (dir)
         attributes = dir->data.dwFileAttributes;
     else
-        attributes = ::GetFileAttributes(path.c_str());
+    {
+        WIN32_FILE_ATTRIBUTE_DATA all_attrs;
+#ifdef HAVE_WINRT
+        size_t size = mbstowcs(NULL, path.c_str(), path.size());
+        cv::Ptr<wchar_t> wpath = new wchar_t[size+1];
+        wpath[size] = 0;
+        mbstowcs(wpath, path.c_str(), path.size());
+        ::GetFileAttributesExW(wpath, GetFileExInfoStandard, &all_attrs);
+#else
+        ::GetFileAttributesExA(path.c_str(), GetFileExInfoStandard, &all_attrs);
+#endif
+        attributes = all_attrs.dwFileAttributes;
+    }
 
     return (attributes != INVALID_FILE_ATTRIBUTES) && ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
 #else
index 7acb0e0..5a3600b 100644 (file)
@@ -980,6 +980,11 @@ Mat _InputArray::getMat(int i) const
         return !v.empty() ? Mat(size(i), t, (void*)&v[0]) : Mat();
     }
 
+    if( k == OCL_MAT )
+    {
+        CV_Error(CV_StsNotImplemented, "This method is not implemented for oclMat yet");
+    }
+
     CV_Assert( k == STD_VECTOR_MAT );
     //if( k == STD_VECTOR_MAT )
     {
@@ -1062,6 +1067,11 @@ void _InputArray::getMatVector(vector<Mat>& mv) const
         return;
     }
 
+    if( k == OCL_MAT )
+    {
+        CV_Error(CV_StsNotImplemented, "This method is not implemented for oclMat yet");
+    }
+
     CV_Assert( k == STD_VECTOR_MAT );
     //if( k == STD_VECTOR_MAT )
     {
@@ -1189,6 +1199,11 @@ Size _InputArray::size(int i) const
         return tex->size();
     }
 
+    if( k == OCL_MAT )
+    {
+        CV_Error(CV_StsNotImplemented, "This method is not implemented for oclMat yet");
+    }
+
     CV_Assert( k == GPU_MAT );
     //if( k == GPU_MAT )
     {
@@ -1303,6 +1318,11 @@ bool _InputArray::empty() const
     if( k == OPENGL_TEXTURE )
         return ((const ogl::Texture2D*)obj)->empty();
 
+    if( k == OCL_MAT )
+    {
+        CV_Error(CV_StsNotImplemented, "This method is not implemented for oclMat yet");
+    }
+
     CV_Assert( k == GPU_MAT );
     //if( k == GPU_MAT )
         return ((const gpu::GpuMat*)obj)->empty();
@@ -1523,6 +1543,11 @@ void _OutputArray::create(int dims, const int* sizes, int mtype, int i, bool all
         return;
     }
 
+    if( k == OCL_MAT )
+    {
+        CV_Error(CV_StsNotImplemented, "This method is not implemented for oclMat yet");
+    }
+
     if( k == NONE )
     {
         CV_Error(CV_StsNullPtr, "create() called for the missing output array" );
@@ -1634,6 +1659,11 @@ void _OutputArray::release() const
         return;
     }
 
+    if( k == OCL_MAT )
+    {
+        CV_Error(CV_StsNotImplemented, "This method is not implemented for oclMat yet");
+    }
+
     CV_Assert( k == STD_VECTOR_MAT );
     //if( k == STD_VECTOR_MAT )
     {
index 0b2a845..1ae8c96 100644 (file)
     #endif
 #endif
 
-#if defined HAVE_TBB || defined HAVE_CSTRIPES || defined HAVE_OPENMP || defined HAVE_GCD || defined HAVE_CONCURRENCY
-   #define HAVE_PARALLEL_FRAMEWORK
+#if defined HAVE_TBB && TBB_VERSION_MAJOR*100 + TBB_VERSION_MINOR >= 202
+#  define CV_PARALLEL_FRAMEWORK "tbb"
+#elif defined HAVE_CSTRIPES
+#  define CV_PARALLEL_FRAMEWORK "cstripes"
+#elif defined HAVE_OPENMP
+#  define CV_PARALLEL_FRAMEWORK "openmp"
+#elif defined HAVE_GCD
+#  define CV_PARALLEL_FRAMEWORK "gcd"
+#elif defined HAVE_CONCURRENCY
+#  define CV_PARALLEL_FRAMEWORK "ms-concurrency"
 #endif
 
 namespace cv
@@ -121,7 +129,7 @@ namespace cv
 
 namespace
 {
-#ifdef HAVE_PARALLEL_FRAMEWORK
+#ifdef CV_PARALLEL_FRAMEWORK
     class ParallelLoopBodyWrapper
     {
     public:
@@ -218,7 +226,7 @@ public:
 static SchedPtr pplScheduler;
 #endif
 
-#endif // HAVE_PARALLEL_FRAMEWORK
+#endif // CV_PARALLEL_FRAMEWORK
 
 } //namespace
 
@@ -226,7 +234,7 @@ static SchedPtr pplScheduler;
 
 void cv::parallel_for_(const cv::Range& range, const cv::ParallelLoopBody& body, double nstripes)
 {
-#ifdef HAVE_PARALLEL_FRAMEWORK
+#ifdef CV_PARALLEL_FRAMEWORK
 
     if(numThreads != 0)
     {
@@ -281,7 +289,7 @@ void cv::parallel_for_(const cv::Range& range, const cv::ParallelLoopBody& body,
     }
     else
 
-#endif // HAVE_PARALLEL_FRAMEWORK
+#endif // CV_PARALLEL_FRAMEWORK
     {
         (void)nstripes;
         body(range);
@@ -290,7 +298,7 @@ void cv::parallel_for_(const cv::Range& range, const cv::ParallelLoopBody& body,
 
 int cv::getNumThreads(void)
 {
-#ifdef HAVE_PARALLEL_FRAMEWORK
+#ifdef CV_PARALLEL_FRAMEWORK
 
     if(numThreads == 0)
         return 1;
@@ -333,7 +341,7 @@ int cv::getNumThreads(void)
 void cv::setNumThreads( int threads )
 {
     (void)threads;
-#ifdef HAVE_PARALLEL_FRAMEWORK
+#ifdef CV_PARALLEL_FRAMEWORK
     numThreads = threads;
 #endif
 
@@ -445,7 +453,11 @@ int cv::getNumberOfCPUs(void)
 {
 #if defined WIN32 || defined _WIN32
     SYSTEM_INFO sysinfo;
+#if defined(_M_ARM) || defined(_M_X64) || defined(HAVE_WINRT)
+    GetNativeSystemInfo( &sysinfo );
+#else
     GetSystemInfo( &sysinfo );
+#endif
 
     return (int)sysinfo.dwNumberOfProcessors;
 #elif defined ANDROID
@@ -480,6 +492,14 @@ int cv::getNumberOfCPUs(void)
 #endif
 }
 
+const char* cv::currentParallelFramework() {
+#ifdef CV_PARALLEL_FRAMEWORK
+    return CV_PARALLEL_FRAMEWORK;
+#else
+    return NULL;
+#endif
+}
+
 CV_IMPL void cvSetNumThreads(int nt)
 {
     cv::setNumThreads(nt);
index a16b63e..bf6a64c 100644 (file)
@@ -59,7 +59,6 @@
 #endif
 
 #if USE_ZLIB
-#  undef HAVE_UNISTD_H //to avoid redefinition
 #  ifndef _LFS64_LARGEFILE
 #    define _LFS64_LARGEFILE 0
 #  endif
diff --git a/modules/core/src/precomp.cpp b/modules/core/src/precomp.cpp
deleted file mode 100644 (file)
index e540cc5..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*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 "precomp.hpp"
-
-/* End of file. */
index 84f7f5e..c53224e 100644 (file)
@@ -43,9 +43,7 @@
 #ifndef __OPENCV_PRECOMP_H__
 #define __OPENCV_PRECOMP_H__
 
-#ifdef HAVE_CVCONFIG_H
 #include "cvconfig.h"
-#endif
 
 #include "opencv2/core/core.hpp"
 #include "opencv2/core/core_c.h"
index 2cdbe39..54bb753 100644 (file)
@@ -726,33 +726,54 @@ void RNG::fill( InputOutputArray _mat, int disttype,
 }
 
 #ifdef WIN32
+
+
+#ifdef HAVE_WINRT
+// using C++11 thread attribute for local thread data
+__declspec( thread ) RNG* rng = NULL;
+
+ void deleteThreadRNGData()
+ {
+    if (rng)
+        delete rng;
+}
+
+RNG& theRNG()
+{
+    if (!rng)
+    {
+        rng =  new RNG;
+    }
+    return *rng;
+}
+#else
 #ifdef WINCE
 #      define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF)
 #endif
 static DWORD tlsRNGKey = TLS_OUT_OF_INDEXES;
 
-void deleteThreadRNGData()
-{
-    if( tlsRNGKey != TLS_OUT_OF_INDEXES )
-        delete (RNG*)TlsGetValue( tlsRNGKey );
+ void deleteThreadRNGData()
+ {
+     if( tlsRNGKey != TLS_OUT_OF_INDEXES )
+         delete (RNG*)TlsGetValue( tlsRNGKey );
 }
 
 RNG& theRNG()
 {
     if( tlsRNGKey == TLS_OUT_OF_INDEXES )
     {
-        tlsRNGKey = TlsAlloc();
-        CV_Assert(tlsRNGKey != TLS_OUT_OF_INDEXES);
+       tlsRNGKey = TlsAlloc();
+       CV_Assert(tlsRNGKey != TLS_OUT_OF_INDEXES);
     }
     RNG* rng = (RNG*)TlsGetValue( tlsRNGKey );
     if( !rng )
     {
-        rng = new RNG;
-        TlsSetValue( tlsRNGKey, rng );
+       rng = new RNG;
+       TlsSetValue( tlsRNGKey, rng );
     }
     return *rng;
 }
-
+#endif //HAVE_WINRT
 #else
 
 static pthread_key_t tlsRNGKey = 0;
index e069e52..d8f28e2 100644 (file)
@@ -439,6 +439,45 @@ cv::Scalar cv::sum( InputArray _src )
 {
     Mat src = _src.getMat();
     int k, cn = src.channels(), depth = src.depth();
+       
+#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
+       size_t total_size = src.total();
+       int rows = src.size[0], cols = (int)(total_size/rows);
+       if( src.dims == 2 || (src.isContinuous() && cols > 0 && (size_t)rows*cols == total_size) )
+       {
+               IppiSize sz = { cols, rows };
+               int type = src.type();
+               typedef IppStatus (CV_STDCALL* ippiSumFunc)(const void*, int, IppiSize, double *, int);
+               ippiSumFunc ippFunc = 
+                       type == CV_8UC1 ? (ippiSumFunc)ippiSum_8u_C1R :
+                       type == CV_8UC3 ? (ippiSumFunc)ippiSum_8u_C3R :
+                       type == CV_8UC4 ? (ippiSumFunc)ippiSum_8u_C4R :
+                       type == CV_16UC1 ? (ippiSumFunc)ippiSum_16u_C1R :
+                       type == CV_16UC3 ? (ippiSumFunc)ippiSum_16u_C3R :
+                       type == CV_16UC4 ? (ippiSumFunc)ippiSum_16u_C4R :
+                       type == CV_16SC1 ? (ippiSumFunc)ippiSum_16s_C1R :
+                       type == CV_16SC3 ? (ippiSumFunc)ippiSum_16s_C3R :
+                       type == CV_16SC4 ? (ippiSumFunc)ippiSum_16s_C4R :
+                       type == CV_32FC1 ? (ippiSumFunc)ippiSum_32f_C1R :
+                       type == CV_32FC3 ? (ippiSumFunc)ippiSum_32f_C3R :
+                       type == CV_32FC4 ? (ippiSumFunc)ippiSum_32f_C4R :
+                       0;
+               if( ippFunc )
+               {
+                       Ipp64f res[4];
+                       if( ippFunc(src.data, src.step[0], sz, res, ippAlgHintAccurate) >= 0 )
+                       {
+                               Scalar sc;
+                               for( int i = 0; i < cn; i++ )
+                               {
+                                       sc[i] = res[i];
+                               }
+                               return sc;
+                       }
+               }
+       }
+#endif 
+       
     SumFunc func = sumTab[depth];
 
     CV_Assert( cn <= 4 && func != 0 );
@@ -512,6 +551,81 @@ cv::Scalar cv::mean( InputArray _src, InputArray _mask )
     CV_Assert( mask.empty() || mask.type() == CV_8U );
 
     int k, cn = src.channels(), depth = src.depth();
+       
+#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
+       size_t total_size = src.total();
+       int rows = src.size[0], cols = (int)(total_size/rows);
+       if( src.dims == 2 || (src.isContinuous() && mask.isContinuous() && cols > 0 && (size_t)rows*cols == total_size) )
+       {
+               IppiSize sz = { cols, rows };
+               int type = src.type();
+               if( !mask.empty() )
+               {
+                       typedef IppStatus (CV_STDCALL* ippiMaskMeanFuncC1)(const void *, int, void *, int, IppiSize, Ipp64f *);
+                       ippiMaskMeanFuncC1 ippFuncC1 = 
+                       type == CV_8UC1 ? (ippiMaskMeanFuncC1)ippiMean_8u_C1MR :
+                       type == CV_16UC1 ? (ippiMaskMeanFuncC1)ippiMean_16u_C1MR :
+                       type == CV_32FC1 ? (ippiMaskMeanFuncC1)ippiMean_32f_C1MR :
+                       0;
+                       if( ippFuncC1 )
+                       {
+                               Ipp64f res;
+                               if( ippFuncC1(src.data, src.step[0], mask.data, mask.step[0], sz, &res) >= 0 )
+                               {
+                                       return Scalar(res);
+                               }
+                       }
+                       typedef IppStatus (CV_STDCALL* ippiMaskMeanFuncC3)(const void *, int, void *, int, IppiSize, int, Ipp64f *);
+                       ippiMaskMeanFuncC3 ippFuncC3 = 
+                       type == CV_8UC3 ? (ippiMaskMeanFuncC3)ippiMean_8u_C3CMR :
+                       type == CV_16UC3 ? (ippiMaskMeanFuncC3)ippiMean_16u_C3CMR :
+                       type == CV_32FC3 ? (ippiMaskMeanFuncC3)ippiMean_32f_C3CMR :
+                       0;
+                       if( ippFuncC3 )
+                       {
+                               Ipp64f res1, res2, res3;
+                               if( ippFuncC3(src.data, src.step[0], mask.data, mask.step[0], sz, 1, &res1) >= 0 &&
+                                       ippFuncC3(src.data, src.step[0], mask.data, mask.step[0], sz, 2, &res2) >= 0 &&
+                                       ippFuncC3(src.data, src.step[0], mask.data, mask.step[0], sz, 3, &res3) >= 0 )
+                               {
+                                       return Scalar(res1, res2, res3);
+                               }
+                       }
+               }
+               else
+               {
+                       typedef IppStatus (CV_STDCALL* ippiMeanFunc)(const void*, int, IppiSize, double *, int);
+                       ippiMeanFunc ippFunc = 
+                               type == CV_8UC1 ? (ippiMeanFunc)ippiMean_8u_C1R :
+                               type == CV_8UC3 ? (ippiMeanFunc)ippiMean_8u_C3R :
+                               type == CV_8UC4 ? (ippiMeanFunc)ippiMean_8u_C4R :
+                               type == CV_16UC1 ? (ippiMeanFunc)ippiMean_16u_C1R :
+                               type == CV_16UC3 ? (ippiMeanFunc)ippiMean_16u_C3R :
+                               type == CV_16UC4 ? (ippiMeanFunc)ippiMean_16u_C4R :
+                               type == CV_16SC1 ? (ippiMeanFunc)ippiMean_16s_C1R :
+                               type == CV_16SC3 ? (ippiMeanFunc)ippiMean_16s_C3R :
+                               type == CV_16SC4 ? (ippiMeanFunc)ippiMean_16s_C4R :
+                               type == CV_32FC1 ? (ippiMeanFunc)ippiMean_32f_C1R :
+                               type == CV_32FC3 ? (ippiMeanFunc)ippiMean_32f_C3R :
+                               type == CV_32FC4 ? (ippiMeanFunc)ippiMean_32f_C4R :
+                               0;
+                       if( ippFunc )
+                       {
+                               Ipp64f res[4];
+                               if( ippFunc(src.data, src.step[0], sz, res, ippAlgHintAccurate) >= 0 )
+                               {
+                                       Scalar sc;
+                                       for( int i = 0; i < cn; i++ )
+                                       {
+                                               sc[i] = res[i];
+                                       }
+                                       return sc;
+                               }
+                       }
+               }
+       }
+#endif
+       
     SumFunc func = sumTab[depth];
 
     CV_Assert( cn <= 4 && func != 0 );
index a891e94..7e01ca5 100644 (file)
@@ -47,6 +47,9 @@
   #define _WIN32_WINNT 0x0400  // http://msdn.microsoft.com/en-us/library/ms686857(VS.85).aspx
 #endif
 #include <windows.h>
+#if (_WIN32_WINNT >= 0x0602)
+  #include <synchapi.h>
+#endif
 #undef small
 #undef min
 #undef max
     }
   #endif
 #endif
+
+#ifdef HAVE_WINRT
+#include <wrl/client.h>
+
+std::wstring GetTempPathWinRT()
+{
+    return std::wstring(Windows::Storage::ApplicationData::Current->TemporaryFolder->Path->Data());
+}
+
+std::wstring GetTempFileNameWinRT(std::wstring prefix)
+{
+    wchar_t guidStr[40];
+    GUID g;
+    CoCreateGuid(&g);
+    wchar_t* mask = L"%08x_%04x_%04x_%02x%02x_%02x%02x%02x%02x%02x%02x";
+    swprintf(&guidStr[0], sizeof(guidStr)/sizeof(wchar_t), mask,
+             g.Data1, g.Data2, g.Data3, UINT(g.Data4[0]), UINT(g.Data4[1]),
+             UINT(g.Data4[2]), UINT(g.Data4[3]), UINT(g.Data4[4]),
+             UINT(g.Data4[5]), UINT(g.Data4[6]), UINT(g.Data4[7]));
+
+    return prefix + std::wstring(guidStr);
+}
+
+#endif
 #else
 #include <pthread.h>
 #include <sys/time.h>
@@ -359,10 +386,38 @@ string format( const char* fmt, ... )
 
 string tempfile( const char* suffix )
 {
+#ifdef HAVE_WINRT
+    std::wstring temp_dir = L"";
+    const wchar_t* opencv_temp_dir = _wgetenv(L"OPENCV_TEMP_PATH");
+    if (opencv_temp_dir)
+        temp_dir = std::wstring(opencv_temp_dir);
+#else
     const char *temp_dir = getenv("OPENCV_TEMP_PATH");
+#endif
     string fname;
 
 #if defined WIN32 || defined _WIN32
+#ifdef HAVE_WINRT
+    RoInitialize(RO_INIT_MULTITHREADED);
+    std::wstring temp_dir2;
+    if (temp_dir.empty())
+        temp_dir = GetTempPathWinRT();
+
+    std::wstring temp_file;
+    temp_file = GetTempFileNameWinRT(L"ocv");
+    if (temp_file.empty())
+        return std::string();
+
+    temp_file = temp_dir + std::wstring(L"\\") + temp_file;
+    DeleteFileW(temp_file.c_str());
+
+    size_t asize = wcstombs(NULL, temp_file.c_str(), 0);
+    Ptr<char> aname = new char[asize+1];
+    aname[asize] = 0;
+    wcstombs(aname, temp_file.c_str(), asize);
+    fname = std::string(aname);
+    RoUninitialize();
+#else
     char temp_dir2[MAX_PATH + 1] = { 0 };
     char temp_file[MAX_PATH + 1] = { 0 };
 
@@ -377,6 +432,7 @@ string tempfile( const char* suffix )
     DeleteFileA(temp_file);
 
     fname = temp_file;
+#endif
 # else
 #  ifdef ANDROID
     //char defaultTemplate[] = "/mnt/sdcard/__opencv_temp.XXXXXX";
@@ -469,40 +525,6 @@ redirectError( CvErrorCallback errCallback, void* userdata, void** prevUserdata)
 
 }
 
-/*CV_IMPL int
-cvGuiBoxReport( int code, const char *func_name, const char *err_msg,
-                const char *file, int line, void* )
-{
-#if (!defined WIN32 && !defined _WIN32) || defined WINCE
-    return cvStdErrReport( code, func_name, err_msg, file, line, 0 );
-#else
-    if( code != CV_StsBackTrace && code != CV_StsAutoTrace )
-    {
-        size_t msg_len = strlen(err_msg ? err_msg : "") + 1024;
-        char* message = (char*)alloca(msg_len);
-        char title[100];
-
-        wsprintf( message, "%s (%s)\nin function %s, %s(%d)\n\n"
-                  "Press \"Abort\" to terminate application.\n"
-                  "Press \"Retry\" to debug (if the app is running under debugger).\n"
-                  "Press \"Ignore\" to continue (this is not safe).\n",
-                  cvErrorStr(code), err_msg ? err_msg : "no description",
-                  func_name, file, line );
-
-        wsprintf( title, "OpenCV GUI Error Handler" );
-
-        int answer = MessageBox( NULL, message, title, MB_ICONERROR|MB_ABORTRETRYIGNORE|MB_SYSTEMMODAL );
-
-        if( answer == IDRETRY )
-        {
-            CV_DBG_BREAK();
-        }
-        return answer != IDIGNORE;
-    }
-    return 0;
-#endif
-}*/
-
 CV_IMPL int cvCheckHardwareSupport(int feature)
 {
     CV_DbgAssert( 0 <= feature && feature <= CV_HARDWARE_MAX_FEATURE );
@@ -779,7 +801,11 @@ cvGetModuleInfo( const char* name, const char **version, const char **plugin_lis
         *plugin_list = plugin_list_buf;
 }
 
-#if defined BUILD_SHARED_LIBS && defined CVAPI_EXPORTS && defined WIN32 && !defined WINCE
+#if defined CVAPI_EXPORTS && defined WIN32 && !defined WINCE
+#ifdef HAVE_WINRT
+    #pragma warning(disable:4447) // Disable warning 'main' signature found without threading model
+#endif
+
 BOOL WINAPI DllMain( HINSTANCE, DWORD  fdwReason, LPVOID );
 
 BOOL WINAPI DllMain( HINSTANCE, DWORD  fdwReason, LPVOID )
@@ -800,7 +826,15 @@ namespace cv
 
 struct Mutex::Impl
 {
-    Impl() { InitializeCriticalSection(&cs); refcount = 1; }
+    Impl()
+    {
+#if (_WIN32_WINNT >= 0x0600)
+        ::InitializeCriticalSectionEx(&cs, 1000, 0);
+#else
+        ::InitializeCriticalSection(&cs);
+#endif
+        refcount = 1;
+    }
     ~Impl() { DeleteCriticalSection(&cs); }
 
     void lock() { EnterCriticalSection(&cs); }
@@ -904,4 +938,4 @@ bool Mutex::trylock() { return impl->trylock(); }
 
 }
 
-/* End of file. */
\ No newline at end of file
+/* End of file. */
index a3e61f2..0bb185d 100644 (file)
@@ -1123,7 +1123,7 @@ struct MeanOp : public BaseElemWiseOp
     }
     double getMaxErr(int)
     {
-        return 1e-6;
+        return 1e-5;
     }
 };
 
index 6b24993..3294fab 100644 (file)
@@ -1,3 +1,7 @@
+#ifdef HAVE_WINRT
+    #pragma warning(disable:4447) // Disable warning 'main' signature found without threading model
+#endif
+
 #include "test_precomp.hpp"
 
 CV_TEST_MAIN("cv")
diff --git a/modules/core/test/test_precomp.cpp b/modules/core/test/test_precomp.cpp
deleted file mode 100644 (file)
index 5956e13..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "test_precomp.hpp"
index 63e56f6..3639bd6 100644 (file)
@@ -9,7 +9,10 @@ represented as vectors in a multidimensional space. All objects that implement t
 descriptor extractors inherit the
 :ocv:class:`DescriptorExtractor` interface.
 
+.. note::
 
+   * An example explaining keypoint extraction can be found at opencv_source_code/samples/cpp/descriptor_extractor_matcher.cpp
+   * An example on descriptor evaluation can be found at opencv_source_code/samples/cpp/detector_descriptor_evaluation.cpp
 
 DescriptorExtractor
 -------------------
@@ -78,9 +81,10 @@ The current implementation supports the following types of a descriptor extracto
 
  * ``"SIFT"`` -- :ocv:class:`SIFT`
  * ``"SURF"`` -- :ocv:class:`SURF`
- * ``"ORB"`` -- :ocv:class:`ORB`
- * ``"BRISK"`` -- :ocv:class:`BRISK`
  * ``"BRIEF"`` -- :ocv:class:`BriefDescriptorExtractor`
+ * ``"BRISK"`` -- :ocv:class:`BRISK`
+ * ``"ORB"`` -- :ocv:class:`ORB`
+ * ``"FREAK"`` -- :ocv:class:`FREAK`
 
 A combined format is also supported: descriptor extractor adapter name ( ``"Opponent"`` --
 :ocv:class:`OpponentColorDescriptorExtractor` ) + descriptor extractor name (see above),
@@ -137,4 +141,6 @@ Strecha C., Fua P. *BRIEF: Binary Robust Independent Elementary Features* ,
         ...
     };
 
+.. note::
 
+   * A complete BRIEF extractor sample can be found at opencv_source_code/samples/cpp/brief_match_test.cpp
index d7e5eb4..264d3a1 100644 (file)
@@ -9,6 +9,12 @@ that are represented as vectors in a multidimensional space. All objects that im
 descriptor matchers inherit the
 :ocv:class:`DescriptorMatcher` interface.
 
+.. note::
+
+   * An example explaining keypoint matching can be found at opencv_source_code/samples/cpp/descriptor_extractor_matcher.cpp
+   * An example on descriptor matching evaluation can be found at opencv_source_code/samples/cpp/detector_descriptor_matcher_evaluation.cpp
+   * An example on one to many image matching can be found at opencv_source_code/samples/cpp/matching_to_many_images.cpp
+
 DMatch
 ------
 .. ocv:struct:: DMatch
index 81c72d3..51efca5 100644 (file)
@@ -8,6 +8,11 @@ between different algorithms solving the same problem. All objects that implemen
 inherit the
 :ocv:class:`FeatureDetector` interface.
 
+.. note::
+
+   * An example explaining keypoint detection can be found at opencv_source_code/samples/cpp/descriptor_extractor_matcher.cpp
+
+
 KeyPoint
 --------
 .. ocv:class:: KeyPoint
@@ -220,7 +225,7 @@ StarFeatureDetector
 -------------------
 .. ocv:class:: StarFeatureDetector : public FeatureDetector
 
-The class implements the keypoint detector introduced by K. Konolige, synonym of ``StarDetector``.  ::
+The class implements the keypoint detector introduced by [Agrawal08]_, synonym of ``StarDetector``.  ::
 
     class StarFeatureDetector : public FeatureDetector
     {
@@ -234,6 +239,9 @@ The class implements the keypoint detector introduced by K. Konolige, synonym of
         ...
     };
 
+.. [Agrawal08] Agrawal, M., Konolige, K., & Blas, M. R. (2008). Censure: Center surround extremas for realtime feature detection and matching. In Computer Vision–ECCV 2008 (pp. 102-115). Springer Berlin Heidelberg.
+
+
 DenseFeatureDetector
 --------------------
 .. ocv:class:: DenseFeatureDetector : public FeatureDetector
index a306c66..fcdc8b9 100644 (file)
@@ -11,7 +11,11 @@ Every descriptor with the
 :ocv:class:`VectorDescriptorMatcher` ).
 There are descriptors such as the One-way descriptor and Ferns that have the ``GenericDescriptorMatcher`` interface implemented but do not support ``DescriptorExtractor``.
 
+.. note::
 
+   * An example explaining keypoint description can be found at opencv_source_code/samples/cpp/descriptor_extractor_matcher.cpp
+   * An example on descriptor matching evaluation can be found at opencv_source_code/samples/cpp/detector_descriptor_matcher_evaluation.cpp
+   * An example on one to many image matching can be found at opencv_source_code/samples/cpp/matching_to_many_images.cpp
 
 GenericDescriptorMatcher
 ------------------------
index 80a1de0..a027202 100644 (file)
@@ -3,6 +3,10 @@ Feature Detection and Description
 
 .. highlight:: cpp
 
+.. note::
+
+   * An example explaining keypoint detection and description can be found at opencv_source_code/samples/cpp/descriptor_extractor_matcher.cpp
+
 FAST
 ----
 Detects corners using the FAST algorithm
@@ -51,6 +55,10 @@ Maximally stable extremal region extractor. ::
 The class encapsulates all the parameters of the MSER extraction algorithm (see
 http://en.wikipedia.org/wiki/Maximally_stable_extremal_regions). Also see http://code.opencv.org/projects/opencv/wiki/MSER for useful comments and parameters description.
 
+.. note::
+
+   * (Python) A complete example showing the use of the MSER detector can be found at opencv_source_code/samples/python2/mser.py
+
 
 ORB
 ---
@@ -158,6 +166,10 @@ Class implementing the FREAK (*Fast Retina Keypoint*) keypoint descriptor, descr
 
 .. [AOV12] A. Alahi, R. Ortiz, and P. Vandergheynst. FREAK: Fast Retina Keypoint. In IEEE Conference on Computer Vision and Pattern Recognition, 2012. CVPR 2012 Open Source Award Winner.
 
+.. note::
+
+   * An example on how to use the FREAK descriptor can be found at opencv_source_code/samples/cpp/freak_demo.cpp
+
 FREAK::FREAK
 ------------
 The FREAK constructor
index d7b34af..cf10460 100644 (file)
@@ -5,6 +5,12 @@ Object Categorization
 
 This section describes approaches based on local 2D features and used to categorize objects.
 
+.. note::
+
+   * A complete Bag-Of-Words sample can be found at opencv_source_code/samples/cpp/bagofwords_classification.cpp
+
+   * (Python) An example using the features2D framework to perform object categorization can be found at opencv_source_code/samples/python2/find_obj.py
+
 BOWTrainer
 ----------
 .. ocv:class:: BOWTrainer
index 8d644a3..d4649ba 100644 (file)
@@ -263,6 +263,8 @@ public:
                                      OutputArray descriptors,
                                      bool useProvidedKeypoints=false ) const = 0;
 
+    CV_WRAP void compute( const Mat& image, CV_OUT CV_IN_OUT std::vector<KeyPoint>& keypoints, CV_OUT Mat& descriptors ) const;
+
     // Create feature detector and descriptor extractor by name.
     CV_WRAP static Ptr<Feature2D> create( const string& name );
 };
@@ -589,11 +591,11 @@ protected:
 };
 
 
-class CV_EXPORTS GFTTDetector : public FeatureDetector
+class CV_EXPORTS_W GFTTDetector : public FeatureDetector
 {
 public:
-    GFTTDetector( int maxCorners=1000, double qualityLevel=0.01, double minDistance=1,
-                  int blockSize=3, bool useHarrisDetector=false, double k=0.04 );
+    CV_WRAP GFTTDetector( int maxCorners=1000, double qualityLevel=0.01, double minDistance=1,
+                          int blockSize=3, bool useHarrisDetector=false, double k=0.04 );
     AlgorithmInfo* info() const;
 
 protected:
diff --git a/modules/features2d/perf/perf_precomp.cpp b/modules/features2d/perf/perf_precomp.cpp
deleted file mode 100644 (file)
index 8552ac3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "perf_precomp.hpp"
index 9770064..898c634 100644 (file)
@@ -149,7 +149,7 @@ void BOWImgDescriptorExtractor::compute( const Mat& image, vector<KeyPoint>& key
     int clusterCount = descriptorSize(); // = vocabulary.rows
 
     // Compute descriptors for the image.
-    Mat descriptors = _descriptors ? *_descriptors : Mat();
+    Mat descriptors;
     dextractor->compute( image, keypoints, descriptors );
 
     // Match keypoint descriptors to cluster center (to vocabulary)
@@ -178,6 +178,11 @@ void BOWImgDescriptorExtractor::compute( const Mat& image, vector<KeyPoint>& key
 
     // Normalize image descriptor.
     imgDescriptor /= descriptors.rows;
+       
+    // Add the descriptors of image keypoints
+    if (_descriptors) {
+        *_descriptors = descriptors.clone(); 
+    }
 }
 
 int BOWImgDescriptorExtractor::descriptorSize() const
index d1fa0c9..622f772 100644 (file)
@@ -525,7 +525,11 @@ BRISK::operator()( InputArray _image, InputArray _mask, vector<KeyPoint>& keypoi
   bool doOrientation=true;
   if (useProvidedKeypoints)
     doOrientation = false;
-  computeDescriptorsAndOrOrientation(_image, _mask, keypoints, _descriptors, true, doOrientation,
+
+  // If the user specified cv::noArray(), this will yield false. Otherwise it will return true.
+  bool doDescriptors = _descriptors.needed();
+
+  computeDescriptorsAndOrOrientation(_image, _mask, keypoints, _descriptors, doDescriptors, doOrientation,
                                        useProvidedKeypoints);
 }
 
index 06efe97..c9e87c2 100644 (file)
@@ -106,6 +106,12 @@ Ptr<DescriptorExtractor> DescriptorExtractor::create(const string& descriptorExt
     return Algorithm::create<DescriptorExtractor>("Feature2D." + descriptorExtractorType);
 }
 
+
+CV_WRAP void Feature2D::compute( const Mat& image, CV_OUT CV_IN_OUT std::vector<KeyPoint>& keypoints, CV_OUT Mat& descriptors ) const
+{
+   DescriptorExtractor::compute(image, keypoints, descriptors);
+}
+
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 /****************************************************************************************\
diff --git a/modules/features2d/src/precomp.cpp b/modules/features2d/src/precomp.cpp
deleted file mode 100644 (file)
index 3e0ec42..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*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 "precomp.hpp"
-
-/* End of file. */
index cbc1eb6..72f6186 100644 (file)
@@ -43,9 +43,7 @@
 #ifndef __OPENCV_PRECOMP_H__
 #define __OPENCV_PRECOMP_H__
 
-#ifdef HAVE_CVCONFIG_H
 #include "cvconfig.h"
-#endif
 
 #include "opencv2/features2d/features2d.hpp"
 #include "opencv2/imgproc/imgproc.hpp"
diff --git a/modules/features2d/test/test_precomp.cpp b/modules/features2d/test/test_precomp.cpp
deleted file mode 100644 (file)
index 5956e13..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "test_precomp.hpp"
index 7380d0c..80ae2dc 100644 (file)
@@ -43,8 +43,12 @@ typedef unsigned __int64 uint64_t;
 
 #include "defines.h"
 
+#if (defined WIN32 || defined _WIN32) && defined(_M_ARM)
+# include <Intrin.h>
+#endif
+
 #ifdef __ARM_NEON__
-#include "arm_neon.h"
+# include "arm_neon.h"
 #endif
 
 namespace cvflann
diff --git a/modules/flann/src/precomp.cpp b/modules/flann/src/precomp.cpp
deleted file mode 100644 (file)
index c149df1..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "precomp.hpp"
index fb5ee3f..76d8399 100644 (file)
@@ -5,9 +5,7 @@
 #include <cstdarg>
 #include <sstream>
 
-#ifdef HAVE_CVCONFIG_H
 # include "cvconfig.h"
-#endif
 #include "opencv2/core/core.hpp"
 #include "opencv2/core/internal.hpp"
 
diff --git a/modules/flann/test/test_precomp.cpp b/modules/flann/test/test_precomp.cpp
deleted file mode 100644 (file)
index 5956e13..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "test_precomp.hpp"
index 0062944..44b5072 100644 (file)
@@ -43,6 +43,14 @@ if(HAVE_CUDA)
   ocv_cuda_compile(cuda_objs ${lib_cuda} ${ncv_cuda})
 
   set(cuda_link_libs ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
+  
+  if(HAVE_CUFFT)
+      set(cuda_link_libs ${cuda_link_libs} ${CUDA_cufft_LIBRARY})
+  endif()
+
+  if(HAVE_CUBLAS)
+      set(cuda_link_libs ${cuda_link_libs} ${CUDA_cublas_LIBRARY})
+  endif()
 
   if(WITH_NVCUVID)
     set(cuda_link_libs ${cuda_link_libs} ${CUDA_CUDA_LIBRARY} ${CUDA_nvcuvid_LIBRARY})
@@ -71,14 +79,6 @@ ocv_set_module_sources(
 ocv_create_module(${cuda_link_libs})
 
 if(HAVE_CUDA)
-  if(HAVE_CUFFT)
-    CUDA_ADD_CUFFT_TO_TARGET(${the_module})
-  endif()
-
-  if(HAVE_CUBLAS)
-    CUDA_ADD_CUBLAS_TO_TARGET(${the_module})
-  endif()
-
   install(FILES src/nvidia/NPP_staging/NPP_staging.hpp  src/nvidia/core/NCV.hpp
     DESTINATION ${OPENCV_INCLUDE_INSTALL_PATH}/opencv2/${name}
     COMPONENT main)
index 587c253..d99def2 100644 (file)
@@ -44,8 +44,12 @@ The class also performs pre- and post-filtering steps: Sobel pre-filtering (if `
 
 This means that the input left image is low textured.
 
+.. note::
 
-
+   * A basic stereo matching example can be found at opencv_source_code/samples/gpu/stereo_match.cpp
+   * A stereo matching example using several GPU's can be found at opencv_source_code/samples/gpu/stereo_multi.cpp
+   * A stereo matching example using several GPU's and driver API can be found at opencv_source_code/samples/gpu/driver_api_stereo_multi.cpp
+   
 gpu::StereoBM_GPU::StereoBM_GPU
 -----------------------------------
 Enables :ocv:class:`gpu::StereoBM_GPU` constructors.
index 348a425..824fbfa 100644 (file)
@@ -5,7 +5,9 @@ Image Filtering
 
 Functions and classes described in this section are used to perform various linear or non-linear filtering operations on 2D images.
 
+.. note::
 
+   * An example containing all basic morphology operators like erode and dilate can be found at opencv_source_code/samples/gpu/morphology.cpp
 
 gpu::BaseRowFilter_GPU
 ----------------------
index 0b32540..abf4fda 100644 (file)
@@ -966,7 +966,9 @@ Composites two images using alpha opacity values contained in each image.
 
     :param stream: Stream for the asynchronous version.
 
+.. note::
 
+   * An example demonstrating the use of alphaComp can be found at opencv_source_code/samples/gpu/alpha_comp.cpp
 
 gpu::Canny
 -------------------
@@ -1028,7 +1030,9 @@ Finds lines in a binary image using the classical Hough transform.
 
 .. seealso:: :ocv:func:`HoughLines`
 
+.. note::
 
+   * An example using the Hough lines detector can be found at opencv_source_code/samples/gpu/houghlines.cpp
 
 gpu::HoughLinesDownload
 -----------------------
index 1336602..c8e2dbf 100644 (file)
@@ -62,7 +62,12 @@ The class implements Histogram of Oriented Gradients ([Dalal2005]_) object detec
 
 Interfaces of all methods are kept similar to the ``CPU HOG`` descriptor and detector analogues as much as possible.
 
+.. note::
 
+   * An example applying the HOG descriptor for people detection can be found at opencv_source_code/samples/cpp/peopledetect.cpp
+   * A GPU example applying the HOG descriptor for people detection can be found at opencv_source_code/samples/gpu/hog.cpp
+
+   * (Python) An example applying the HOG descriptor for people detection can be found at opencv_source_code/samples/python2/peopledetect.py
 
 gpu::HOGDescriptor::HOGDescriptor
 -------------------------------------
@@ -230,7 +235,10 @@ Cascade classifier class used for object detection. Supports HAAR and LBP cascad
             Size getClassifierSize() const;
     };
 
+.. note::
 
+   * A cascade classifier example can be found at opencv_source_code/samples/gpu/cascadeclassifier.cpp
+   * A Nvidea API specific cascade classifier example can be found at opencv_source_code/samples/gpu/cascadeclassifier_nvidia_api.cpp
 
 gpu::CascadeClassifier_GPU::CascadeClassifier_GPU
 -----------------------------------------------------
index 284bb17..7b8dde6 100644 (file)
@@ -3,8 +3,11 @@ Video Analysis
 
 .. highlight:: cpp
 
+.. note::
 
-
+   * A general optical flow example can be found at opencv_source_code/samples/gpu/optical_flow.cpp
+   * A general optical flow example using the Nvidia API can be found at opencv_source_code/samples/gpu/opticalflow_nvidia_api.cpp
+   
 gpu::BroxOpticalFlow
 --------------------
 .. ocv:class:: gpu::BroxOpticalFlow
@@ -44,7 +47,9 @@ Class computing the optical flow for two images using Brox et al Optical Flow al
         GpuMat buf;
     };
 
+.. note::
 
+   * An example illustrating the Brox et al optical flow algorithm can be found at opencv_source_code/samples/gpu/brox_optical_flow.cpp
 
 gpu::GoodFeaturesToTrackDetector_GPU
 ------------------------------------
@@ -213,7 +218,9 @@ The class can calculate an optical flow for a sparse feature set or dense optica
 
 .. seealso:: :ocv:func:`calcOpticalFlowPyrLK`
 
+.. note::
 
+   * An example of the Lucas Kanade optical flow algorithm can be found at opencv_source_code/samples/gpu/pyrlk_optical_flow.cpp
 
 gpu::PyrLKOpticalFlow::sparse
 -----------------------------
@@ -418,7 +425,9 @@ The class discriminates between foreground and background pixels by building and
 
 .. seealso:: :ocv:class:`BackgroundSubtractorMOG`
 
+.. note::
 
+   * An example on gaussian mixture based background/foreground segmantation can be found at opencv_source_code/samples/gpu/bgfg_segm.cpp
 
 gpu::MOG_GPU::MOG_GPU
 ---------------------
@@ -697,7 +706,9 @@ The class uses H264 video codec.
 
 .. note:: Currently only Windows platform is supported.
 
+.. note::
 
+   * An example on how to use the videoWriter class can be found at opencv_source_code/samples/gpu/video_writer.cpp
 
 gpu::VideoWriter_GPU::VideoWriter_GPU
 -------------------------------------
@@ -910,7 +921,9 @@ Class for reading video from files.
 
 .. note:: Currently only Windows and Linux platforms are supported.
 
+.. note::
 
+   * An example on how to use the videoReader class can be found at opencv_source_code/samples/gpu/video_reader.cpp
 
 gpu::VideoReader_GPU::Codec
 ---------------------------
index b040f19..5959780 100644 (file)
 #ifndef __OPENCV_GPU_LIMITS_GPU_HPP__
 #define __OPENCV_GPU_LIMITS_GPU_HPP__
 
-#include <limits>
+#include <limits.h>
+#include <float.h>
 #include "common.hpp"
 
 namespace cv { namespace gpu { namespace device
 {
-    template<class T> struct numeric_limits
-    {
-        typedef T type;
-        __device__ __forceinline__ static type min()  { return type(); };
-        __device__ __forceinline__ static type max() { return type(); };
-        __device__ __forceinline__ static type epsilon() { return type(); }
-        __device__ __forceinline__ static type round_error() { return type(); }
-        __device__ __forceinline__ static type denorm_min()  { return type(); }
-        __device__ __forceinline__ static type infinity() { return type(); }
-        __device__ __forceinline__ static type quiet_NaN() { return type(); }
-        __device__ __forceinline__ static type signaling_NaN() { return T(); }
-        static const bool is_signed;
-    };
 
-    template<> struct numeric_limits<bool>
-    {
-        typedef bool type;
-        __device__ __forceinline__ static type min() { return false; };
-        __device__ __forceinline__ static type max() { return true;  };
-        __device__ __forceinline__ static type epsilon();
-        __device__ __forceinline__ static type round_error();
-        __device__ __forceinline__ static type denorm_min();
-        __device__ __forceinline__ static type infinity();
-        __device__ __forceinline__ static type quiet_NaN();
-        __device__ __forceinline__ static type signaling_NaN();
-        static const bool is_signed = false;
-    };
+template <class T> struct numeric_limits;
 
-    template<> struct numeric_limits<char>
-    {
-        typedef char type;
-        __device__ __forceinline__ static type min() { return CHAR_MIN; };
-        __device__ __forceinline__ static type max() { return CHAR_MAX; };
-        __device__ __forceinline__ static type epsilon();
-        __device__ __forceinline__ static type round_error();
-        __device__ __forceinline__ static type denorm_min();
-        __device__ __forceinline__ static type infinity();
-        __device__ __forceinline__ static type quiet_NaN();
-        __device__ __forceinline__ static type signaling_NaN();
-        static const bool is_signed = (char)-1 == -1;
-    };
-
-    template<> struct numeric_limits<signed char>
-    {
-        typedef char type;
-        __device__ __forceinline__ static type min() { return SCHAR_MIN; };
-        __device__ __forceinline__ static type max() { return SCHAR_MAX; };
-        __device__ __forceinline__ static type epsilon();
-        __device__ __forceinline__ static type round_error();
-        __device__ __forceinline__ static type denorm_min();
-        __device__ __forceinline__ static type infinity();
-        __device__ __forceinline__ static type quiet_NaN();
-        __device__ __forceinline__ static type signaling_NaN();
-        static const bool is_signed = (signed char)-1 == -1;
-    };
-
-    template<> struct numeric_limits<unsigned char>
-    {
-        typedef unsigned char type;
-        __device__ __forceinline__ static type min() { return 0; };
-        __device__ __forceinline__ static type max() { return UCHAR_MAX; };
-        __device__ __forceinline__ static type epsilon();
-        __device__ __forceinline__ static type round_error();
-        __device__ __forceinline__ static type denorm_min();
-        __device__ __forceinline__ static type infinity();
-        __device__ __forceinline__ static type quiet_NaN();
-        __device__ __forceinline__ static type signaling_NaN();
-        static const bool is_signed = false;
-    };
+template <> struct numeric_limits<bool>
+{
+    __device__ __forceinline__ static bool min() { return false; }
+    __device__ __forceinline__ static bool max() { return true;  }
+    static const bool is_signed = false;
+};
 
-    template<> struct numeric_limits<short>
-    {
-        typedef short type;
-        __device__ __forceinline__ static type min() { return SHRT_MIN; };
-        __device__ __forceinline__ static type max() { return SHRT_MAX; };
-        __device__ __forceinline__ static type epsilon();
-        __device__ __forceinline__ static type round_error();
-        __device__ __forceinline__ static type denorm_min();
-        __device__ __forceinline__ static type infinity();
-        __device__ __forceinline__ static type quiet_NaN();
-        __device__ __forceinline__ static type signaling_NaN();
-        static const bool is_signed = true;
-    };
+template <> struct numeric_limits<signed char>
+{
+    __device__ __forceinline__ static signed char min() { return SCHAR_MIN; }
+    __device__ __forceinline__ static signed char max() { return SCHAR_MAX; }
+    static const bool is_signed = true;
+};
 
-    template<> struct numeric_limits<unsigned short>
-    {
-        typedef unsigned short type;
-        __device__ __forceinline__ static type min() { return 0; };
-        __device__ __forceinline__ static type max() { return USHRT_MAX; };
-        __device__ __forceinline__ static type epsilon();
-        __device__ __forceinline__ static type round_error();
-        __device__ __forceinline__ static type denorm_min();
-        __device__ __forceinline__ static type infinity();
-        __device__ __forceinline__ static type quiet_NaN();
-        __device__ __forceinline__ static type signaling_NaN();
-        static const bool is_signed = false;
-    };
+template <> struct numeric_limits<unsigned char>
+{
+    __device__ __forceinline__ static unsigned char min() { return 0; }
+    __device__ __forceinline__ static unsigned char max() { return UCHAR_MAX; }
+    static const bool is_signed = false;
+};
 
-    template<> struct numeric_limits<int>
-    {
-        typedef int type;
-        __device__ __forceinline__ static type min() { return INT_MIN; };
-        __device__ __forceinline__ static type max() { return INT_MAX; };
-        __device__ __forceinline__ static type epsilon();
-        __device__ __forceinline__ static type round_error();
-        __device__ __forceinline__ static type denorm_min();
-        __device__ __forceinline__ static type infinity();
-        __device__ __forceinline__ static type quiet_NaN();
-        __device__ __forceinline__ static type signaling_NaN();
-        static const bool is_signed = true;
-    };
+template <> struct numeric_limits<short>
+{
+    __device__ __forceinline__ static short min() { return SHRT_MIN; }
+    __device__ __forceinline__ static short max() { return SHRT_MAX; }
+    static const bool is_signed = true;
+};
 
+template <> struct numeric_limits<unsigned short>
+{
+    __device__ __forceinline__ static unsigned short min() { return 0; }
+    __device__ __forceinline__ static unsigned short max() { return USHRT_MAX; }
+    static const bool is_signed = false;
+};
 
-    template<> struct numeric_limits<unsigned int>
-    {
-        typedef unsigned int type;
-        __device__ __forceinline__ static type min() { return 0; };
-        __device__ __forceinline__ static type max() { return UINT_MAX; };
-        __device__ __forceinline__ static type epsilon();
-        __device__ __forceinline__ static type round_error();
-        __device__ __forceinline__ static type denorm_min();
-        __device__ __forceinline__ static type infinity();
-        __device__ __forceinline__ static type quiet_NaN();
-        __device__ __forceinline__ static type signaling_NaN();
-        static const bool is_signed = false;
-    };
+template <> struct numeric_limits<int>
+{
+    __device__ __forceinline__ static int min() { return INT_MIN; }
+    __device__ __forceinline__ static int max() { return INT_MAX; }
+    static const bool is_signed = true;
+};
 
-    template<> struct numeric_limits<long>
-    {
-        typedef long type;
-        __device__ __forceinline__ static type min() { return LONG_MIN; };
-        __device__ __forceinline__ static type max() { return LONG_MAX; };
-        __device__ __forceinline__ static type epsilon();
-        __device__ __forceinline__ static type round_error();
-        __device__ __forceinline__ static type denorm_min();
-        __device__ __forceinline__ static type infinity();
-        __device__ __forceinline__ static type quiet_NaN();
-        __device__ __forceinline__ static type signaling_NaN();
-        static const bool is_signed = true;
-    };
+template <> struct numeric_limits<unsigned int>
+{
+    __device__ __forceinline__ static unsigned int min() { return 0; }
+    __device__ __forceinline__ static unsigned int max() { return UINT_MAX; }
+    static const bool is_signed = false;
+};
 
-    template<> struct numeric_limits<unsigned long>
-    {
-        typedef unsigned long type;
-        __device__ __forceinline__ static type min() { return 0; };
-        __device__ __forceinline__ static type max() { return ULONG_MAX; };
-        __device__ __forceinline__ static type epsilon();
-        __device__ __forceinline__ static type round_error();
-        __device__ __forceinline__ static type denorm_min();
-        __device__ __forceinline__ static type infinity();
-        __device__ __forceinline__ static type quiet_NaN();
-        __device__ __forceinline__ static type signaling_NaN();
-        static const bool is_signed = false;
-    };
+template <> struct numeric_limits<float>
+{
+    __device__ __forceinline__ static float min() { return FLT_MIN; }
+    __device__ __forceinline__ static float max() { return FLT_MAX; }
+    __device__ __forceinline__ static float epsilon() { return FLT_EPSILON; }
+    static const bool is_signed = true;
+};
 
-    template<> struct numeric_limits<float>
-    {
-        typedef float type;
-        __device__ __forceinline__ static type min() { return 1.175494351e-38f/*FLT_MIN*/; };
-        __device__ __forceinline__ static type max() { return 3.402823466e+38f/*FLT_MAX*/; };
-        __device__ __forceinline__ static type epsilon() { return 1.192092896e-07f/*FLT_EPSILON*/; };
-        __device__ __forceinline__ static type round_error();
-        __device__ __forceinline__ static type denorm_min();
-        __device__ __forceinline__ static type infinity();
-        __device__ __forceinline__ static type quiet_NaN();
-        __device__ __forceinline__ static type signaling_NaN();
-        static const bool is_signed = true;
-    };
+template <> struct numeric_limits<double>
+{
+    __device__ __forceinline__ static double min() { return DBL_MIN; }
+    __device__ __forceinline__ static double max() { return DBL_MAX; }
+    __device__ __forceinline__ static double epsilon() { return DBL_EPSILON; }
+    static const bool is_signed = true;
+};
 
-    template<> struct numeric_limits<double>
-    {
-        typedef double type;
-        __device__ __forceinline__ static type min() { return 2.2250738585072014e-308/*DBL_MIN*/; };
-        __device__ __forceinline__ static type max() { return 1.7976931348623158e+308/*DBL_MAX*/; };
-        __device__ __forceinline__ static type epsilon();
-        __device__ __forceinline__ static type round_error();
-        __device__ __forceinline__ static type denorm_min();
-        __device__ __forceinline__ static type infinity();
-        __device__ __forceinline__ static type quiet_NaN();
-        __device__ __forceinline__ static type signaling_NaN();
-        static const bool is_signed = true;
-    };
 }}} // namespace cv { namespace gpu { namespace device {
 
 #endif // __OPENCV_GPU_LIMITS_GPU_HPP__
index ee46012..c7fb2a1 100644 (file)
@@ -562,7 +562,17 @@ PERF_TEST_P(Sz, ImgProc_CalcHist,
     }
     else
     {
-        FAIL_NO_CPU();
+        cv::Mat dst;
+
+        const int hbins = 256;
+        const float hranges[] = {0.0f, 256.0f};
+        const int histSize[] = {hbins};
+        const float* ranges[] = {hranges};
+        const int channels[] = {0};
+
+        TEST_CYCLE() cv::calcHist(&src, 1, channels, cv::Mat(), dst, 1, histSize, ranges);
+
+        CPU_SANITY_CHECK(dst);
     }
 }
 
index a7ac1cc..53a19ca 100644 (file)
 
 using namespace perf;
 
-CV_PERF_TEST_MAIN(gpu, printCudaInfo())
+static const char * impls[] = {
+#ifdef HAVE_CUDA
+    "cuda",
+#endif
+    "plain"
+};
+
+CV_PERF_TEST_MAIN_WITH_IMPLS(gpu, impls, printCudaInfo())
diff --git a/modules/gpu/perf/perf_precomp.cpp b/modules/gpu/perf/perf_precomp.cpp
deleted file mode 100644 (file)
index 81f16e8..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*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 "perf_precomp.hpp"
index f6a65ad..8c68385 100644 (file)
@@ -42,9 +42,7 @@
 
 #include <cstdio>
 
-#ifdef HAVE_CVCONFIG_H
 #include "cvconfig.h"
-#endif
 
 #include "opencv2/ts/ts.hpp"
 #include "opencv2/ts/gpu_perf.hpp"
 #include "opencv2/video/video.hpp"
 #include "opencv2/legacy/legacy.hpp"
 
-int main(int argc, char* argv[])
-{
-    perf::printCudaInfo();
-
-    perf::Regression::Init("gpu_perf4au");
-    perf::TestBase::Init(argc, argv);
-    testing::InitGoogleTest(&argc, argv);
+static const char * impls[] = {
+    "cuda",
+    "plain"
+};
 
-    return RUN_ALL_TESTS();
-}
+CV_PERF_TEST_MAIN_WITH_IMPLS(gpu_perf4au, impls, perf::printCudaInfo())
 
 //////////////////////////////////////////////////////////
 // HoughLinesP
index 8b8a1e8..d0ec257 100644 (file)
@@ -111,6 +111,86 @@ namespace hist
 
 namespace hist
 {
+    __device__ __forceinline__ void histEvenInc(int* shist, uint data, int binSize, int lowerLevel, int upperLevel)
+    {
+        if (data >= lowerLevel && data <= upperLevel)
+        {
+            const uint ind = (data - lowerLevel) / binSize;
+            Emulation::smem::atomicAdd(shist + ind, 1);
+        }
+    }
+
+    __global__ void histEven8u(const uchar* src, const size_t step, const int rows, const int cols,
+                               int* hist, const int binCount, const int binSize, const int lowerLevel, const int upperLevel)
+    {
+        extern __shared__ int shist[];
+
+        const int y = blockIdx.x * blockDim.y + threadIdx.y;
+        const int tid = threadIdx.y * blockDim.x + threadIdx.x;
+
+        if (tid < binCount)
+            shist[tid] = 0;
+
+        __syncthreads();
+
+        if (y < rows)
+        {
+            const uchar* rowPtr = src + y * step;
+            const uint* rowPtr4 = (uint*) rowPtr;
+
+            const int cols_4 = cols / 4;
+            for (int x = threadIdx.x; x < cols_4; x += blockDim.x)
+            {
+                const uint data = rowPtr4[x];
+
+                histEvenInc(shist, (data >>  0) & 0xFFU, binSize, lowerLevel, upperLevel);
+                histEvenInc(shist, (data >>  8) & 0xFFU, binSize, lowerLevel, upperLevel);
+                histEvenInc(shist, (data >> 16) & 0xFFU, binSize, lowerLevel, upperLevel);
+                histEvenInc(shist, (data >> 24) & 0xFFU, binSize, lowerLevel, upperLevel);
+            }
+
+            if (cols % 4 != 0 && threadIdx.x == 0)
+            {
+                for (int x = cols_4 * 4; x < cols; ++x)
+                {
+                    const uchar data = rowPtr[x];
+                    histEvenInc(shist, data, binSize, lowerLevel, upperLevel);
+                }
+            }
+        }
+
+        __syncthreads();
+
+        if (tid < binCount)
+        {
+            const int histVal = shist[tid];
+
+            if (histVal > 0)
+                ::atomicAdd(hist + tid, histVal);
+        }
+    }
+
+    void histEven8u(PtrStepSzb src, int* hist, int binCount, int lowerLevel, int upperLevel, cudaStream_t stream)
+    {
+        const dim3 block(32, 8);
+        const dim3 grid(divUp(src.rows, block.y));
+
+        const int binSize = divUp(upperLevel - lowerLevel, binCount);
+
+        const size_t smem_size = binCount * sizeof(int);
+
+        histEven8u<<<grid, block, smem_size, stream>>>(src.data, src.step, src.rows, src.cols, hist, binCount, binSize, lowerLevel, upperLevel);
+        cudaSafeCall( cudaGetLastError() );
+
+        if (stream == 0)
+            cudaSafeCall( cudaDeviceSynchronize() );
+    }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+namespace hist
+{
     __constant__ int c_lut[256];
 
     struct EqualizeHist : unary_function<uchar, uchar>
index b23e0a6..067dfaf 100644 (file)
@@ -619,6 +619,7 @@ namespace cv { namespace gpu { namespace device
         //////////////////////////////////////////////////////////////////////////
         // mulSpectrums
 
+#ifdef HAVE_CUFFT
         __global__ void mulSpectrumsKernel(const PtrStep<cufftComplex> a, const PtrStep<cufftComplex> b, PtrStepSz<cufftComplex> c)
         {
             const int x = blockIdx.x * blockDim.x + threadIdx.x;
@@ -642,11 +643,13 @@ namespace cv { namespace gpu { namespace device
             if (stream == 0)
                 cudaSafeCall( cudaDeviceSynchronize() );
         }
+#endif
 
 
         //////////////////////////////////////////////////////////////////////////
         // mulSpectrums_CONJ
 
+#ifdef HAVE_CUFFT
         __global__ void mulSpectrumsKernel_CONJ(const PtrStep<cufftComplex> a, const PtrStep<cufftComplex> b, PtrStepSz<cufftComplex> c)
         {
             const int x = blockIdx.x * blockDim.x + threadIdx.x;
@@ -670,11 +673,13 @@ namespace cv { namespace gpu { namespace device
             if (stream == 0)
                 cudaSafeCall( cudaDeviceSynchronize() );
         }
+#endif
 
 
         //////////////////////////////////////////////////////////////////////////
         // mulAndScaleSpectrums
 
+#ifdef HAVE_CUFFT
         __global__ void mulAndScaleSpectrumsKernel(const PtrStep<cufftComplex> a, const PtrStep<cufftComplex> b, float scale, PtrStepSz<cufftComplex> c)
         {
             const int x = blockIdx.x * blockDim.x + threadIdx.x;
@@ -699,11 +704,13 @@ namespace cv { namespace gpu { namespace device
             if (stream)
                 cudaSafeCall( cudaDeviceSynchronize() );
         }
+#endif
 
 
         //////////////////////////////////////////////////////////////////////////
         // mulAndScaleSpectrums_CONJ
 
+#ifdef HAVE_CUFFT
         __global__ void mulAndScaleSpectrumsKernel_CONJ(const PtrStep<cufftComplex> a, const PtrStep<cufftComplex> b, float scale, PtrStepSz<cufftComplex> c)
         {
             const int x = blockIdx.x * blockDim.x + threadIdx.x;
@@ -728,6 +735,7 @@ namespace cv { namespace gpu { namespace device
             if (stream == 0)
                 cudaSafeCall( cudaDeviceSynchronize() );
         }
+#endif
 
         //////////////////////////////////////////////////////////////////////////
         // buildWarpMaps
index 7fae710..53d691f 100644 (file)
 #ifndef __OPENCV_CUDA_SAFE_CALL_HPP__
 #define __OPENCV_CUDA_SAFE_CALL_HPP__
 
+#include "cvconfig.h"
+
 #include <cuda_runtime_api.h>
-#include <cufft.h>
-#include <cublas.h>
-#include "NCV.hpp"
 
-#if defined(__GNUC__)
-    #define nppSafeCall(expr)  ___nppSafeCall(expr, __FILE__, __LINE__, __func__)
-    #define ncvSafeCall(expr)  ___ncvSafeCall(expr, __FILE__, __LINE__, __func__)
-    #define cufftSafeCall(expr)  ___cufftSafeCall(expr, __FILE__, __LINE__, __func__)
-    #define cublasSafeCall(expr)  ___cublasSafeCall(expr, __FILE__, __LINE__, __func__)
-#else /* defined(__CUDACC__) || defined(__MSVC__) */
-    #define nppSafeCall(expr)  ___nppSafeCall(expr, __FILE__, __LINE__)
-    #define ncvSafeCall(expr)  ___ncvSafeCall(expr, __FILE__, __LINE__)
-    #define cufftSafeCall(expr)  ___cufftSafeCall(expr, __FILE__, __LINE__)
-    #define cublasSafeCall(expr)  ___cublasSafeCall(expr, __FILE__, __LINE__)
+#ifdef HAVE_CUFFT
+#   include <cufft.h>
 #endif
 
-namespace cv { namespace gpu
-{
-    void nppError(int err, const char *file, const int line, const char *func = "");
-    void ncvError(int err, const char *file, const int line, const char *func = "");
+#ifdef HAVE_CUBLAS
+#   include <cublas.h>
+#endif
+
+#include "NCV.hpp"
+
+namespace cv { namespace gpu {
+
+void nppError(int err, const char *file, const int line, const char *func = "");
+
+void ncvError(int err, const char *file, const int line, const char *func = "");
+
+#ifdef HAVE_CUFFT
     void cufftError(int err, const char *file, const int line, const char *func = "");
+#endif
+
+#ifdef HAVE_CUBLAS
     void cublasError(int err, const char *file, const int line, const char *func = "");
+#endif
+
 }}
 
+// nppSafeCall
+
 static inline void ___nppSafeCall(int err, const char *file, const int line, const char *func = "")
 {
     if (err < 0)
         cv::gpu::nppError(err, file, line, func);
 }
 
+#if defined(__GNUC__)
+    #define nppSafeCall(expr)  ___nppSafeCall(expr, __FILE__, __LINE__, __func__)
+#else
+    #define nppSafeCall(expr)  ___nppSafeCall(expr, __FILE__, __LINE__)
+#endif
+
+// ncvSafeCall
+
 static inline void ___ncvSafeCall(int err, const char *file, const int line, const char *func = "")
 {
     if (NCV_SUCCESS != err)
         cv::gpu::ncvError(err, file, line, func);
 }
 
-static inline void ___cufftSafeCall(cufftResult_t err, const char *file, const int line, const char *func = "")
-{
-    if (CUFFT_SUCCESS != err)
-        cv::gpu::cufftError(err, file, line, func);
-}
+#if defined(__GNUC__)
+    #define ncvSafeCall(expr)  ___ncvSafeCall(expr, __FILE__, __LINE__, __func__)
+#else
+    #define ncvSafeCall(expr)  ___ncvSafeCall(expr, __FILE__, __LINE__)
+#endif
 
-static inline void ___cublasSafeCall(cublasStatus_t err, const char *file, const int line, const char *func = "")
-{
-    if (CUBLAS_STATUS_SUCCESS != err)
-        cv::gpu::cublasError(err, file, line, func);
-}
+// cufftSafeCall
+
+#ifdef HAVE_CUFFT
+    static inline void ___cufftSafeCall(cufftResult_t err, const char *file, const int line, const char *func = "")
+    {
+        if (CUFFT_SUCCESS != err)
+            cv::gpu::cufftError(err, file, line, func);
+    }
+
+    #if defined(__GNUC__)
+        #define cufftSafeCall(expr)  ___cufftSafeCall(expr, __FILE__, __LINE__, __func__)
+    #else
+        #define cufftSafeCall(expr)  ___cufftSafeCall(expr, __FILE__, __LINE__)
+    #endif
+#endif
+
+// cublasSafeCall
+
+#ifdef HAVE_CUBLAS
+    static inline void ___cublasSafeCall(cublasStatus_t err, const char *file, const int line, const char *func = "")
+    {
+        if (CUBLAS_STATUS_SUCCESS != err)
+            cv::gpu::cublasError(err, file, line, func);
+    }
+
+    #if defined(__GNUC__)
+        #define cublasSafeCall(expr)  ___cublasSafeCall(expr, __FILE__, __LINE__, __func__)
+    #else
+        #define cublasSafeCall(expr)  ___cublasSafeCall(expr, __FILE__, __LINE__)
+    #endif
+#endif
 
 #endif /* __OPENCV_CUDA_SAFE_CALL_HPP__ */
index 7f5d5f3..ff0cadb 100644 (file)
@@ -224,6 +224,7 @@ namespace
     //////////////////////////////////////////////////////////////////////////
     // CUFFT errors
 
+#ifdef HAVE_CUFFT
     const ErrorEntry cufft_errors[] =
     {
         error_entry( CUFFT_INVALID_PLAN ),
@@ -238,10 +239,12 @@ namespace
     };
 
     const int cufft_error_num = sizeof(cufft_errors) / sizeof(cufft_errors[0]);
+#endif
 
     //////////////////////////////////////////////////////////////////////////
     // CUBLAS errors
 
+#ifdef HAVE_CUBLAS
     const ErrorEntry cublas_errors[] =
     {
         error_entry( CUBLAS_STATUS_SUCCESS ),
@@ -255,6 +258,7 @@ namespace
     };
 
     const int cublas_error_num = sizeof(cublas_errors) / sizeof(cublas_errors[0]);
+#endif
 }
 
 namespace cv
@@ -273,17 +277,21 @@ namespace cv
             cv::gpu::error(msg.c_str(), file, line, func);
         }
 
+#ifdef HAVE_CUFFT
         void cufftError(int code, const char *file, const int line, const char *func)
         {
             string msg = getErrorString(code, cufft_errors, cufft_error_num);
             cv::gpu::error(msg.c_str(), file, line, func);
         }
+#endif
 
+#ifdef HAVE_CUBLAS
         void cublasError(int code, const char *file, const int line, const char *func)
         {
             string msg = getErrorString(code, cublas_errors, cublas_error_num);
             cv::gpu::error(msg.c_str(), file, line, func);
         }
+#endif
     }
 }
 
index 97c7c76..1904b6a 100644 (file)
@@ -889,6 +889,21 @@ void cv::gpu::histEven(const GpuMat& src, GpuMat& hist, int histSize, int lowerL
     histEven(src, hist, buf, histSize, lowerLevel, upperLevel, stream);
 }
 
+namespace hist
+{
+    void histEven8u(PtrStepSzb src, int* hist, int binCount, int lowerLevel, int upperLevel, cudaStream_t stream);
+}
+
+namespace
+{
+    void histEven8u(const GpuMat& src, GpuMat& hist, int histSize, int lowerLevel, int upperLevel, cudaStream_t stream)
+    {
+        hist.create(1, histSize, CV_32S);
+        cudaSafeCall( cudaMemsetAsync(hist.data, 0, histSize * sizeof(int), stream) );
+        hist::histEven8u(src, hist.ptr<int>(), histSize, lowerLevel, upperLevel, stream);
+    }
+}
+
 void cv::gpu::histEven(const GpuMat& src, GpuMat& hist, GpuMat& buf, int histSize, int lowerLevel, int upperLevel, Stream& stream)
 {
     CV_Assert(src.type() == CV_8UC1 || src.type() == CV_16UC1 || src.type() == CV_16SC1 );
@@ -902,6 +917,12 @@ void cv::gpu::histEven(const GpuMat& src, GpuMat& hist, GpuMat& buf, int histSiz
         NppHistogramEvenC1<CV_16S, nppiHistogramEven_16s_C1R, nppiHistogramEvenGetBufferSize_16s_C1R>::hist
     };
 
+    if (src.depth() == CV_8U && deviceSupports(FEATURE_SET_COMPUTE_30))
+    {
+        histEven8u(src, hist, histSize, lowerLevel, upperLevel, StreamAccessor::getStream(stream));
+        return;
+    }
+
     hist_callers[src.depth()](src, hist, buf, histSize, lowerLevel, upperLevel, StreamAccessor::getStream(stream));
 }
 
@@ -1136,6 +1157,8 @@ void cv::gpu::cornerMinEigenVal(const GpuMat& src, GpuMat& dst, GpuMat& Dx, GpuM
 //////////////////////////////////////////////////////////////////////////////
 // mulSpectrums
 
+#ifdef HAVE_CUFFT
+
 namespace cv { namespace gpu { namespace device
 {
     namespace imgproc
@@ -1146,9 +1169,20 @@ namespace cv { namespace gpu { namespace device
     }
 }}}
 
+#endif
+
 void cv::gpu::mulSpectrums(const GpuMat& a, const GpuMat& b, GpuMat& c, int flags, bool conjB, Stream& stream)
 {
-    (void)flags;
+#ifndef HAVE_CUFFT
+    (void) a;
+    (void) b;
+    (void) c;
+    (void) flags;
+    (void) conjB;
+    (void) stream;
+    throw_nogpu();
+#else
+    (void) flags;
     using namespace ::cv::gpu::device::imgproc;
 
     typedef void (*Caller)(const PtrStep<cufftComplex>, const PtrStep<cufftComplex>, PtrStepSz<cufftComplex>, cudaStream_t stream);
@@ -1162,11 +1196,14 @@ void cv::gpu::mulSpectrums(const GpuMat& a, const GpuMat& b, GpuMat& c, int flag
 
     Caller caller = callers[(int)conjB];
     caller(a, b, c, StreamAccessor::getStream(stream));
+#endif
 }
 
 //////////////////////////////////////////////////////////////////////////////
 // mulAndScaleSpectrums
 
+#ifdef HAVE_CUFFT
+
 namespace cv { namespace gpu { namespace device
 {
     namespace imgproc
@@ -1177,8 +1214,20 @@ namespace cv { namespace gpu { namespace device
     }
 }}}
 
+#endif
+
 void cv::gpu::mulAndScaleSpectrums(const GpuMat& a, const GpuMat& b, GpuMat& c, int flags, float scale, bool conjB, Stream& stream)
 {
+#ifndef HAVE_CUFFT
+    (void) a;
+    (void) b;
+    (void) c;
+    (void) flags;
+    (void) scale;
+    (void) conjB;
+    (void) stream;
+    throw_nogpu();
+#else
     (void)flags;
     using namespace ::cv::gpu::device::imgproc;
 
@@ -1192,6 +1241,7 @@ void cv::gpu::mulAndScaleSpectrums(const GpuMat& a, const GpuMat& b, GpuMat& c,
 
     Caller caller = callers[(int)conjB];
     caller(a, b, scale, c, StreamAccessor::getStream(stream));
+#endif
 }
 
 //////////////////////////////////////////////////////////////////////////////
index 0394dba..80e1da7 100644 (file)
@@ -130,7 +130,7 @@ typedef                int Ncv32s;
 typedef       unsigned int Ncv32u;
 typedef              short Ncv16s;
 typedef     unsigned short Ncv16u;
-typedef               char Ncv8s;
+typedef        signed char Ncv8s;
 typedef      unsigned char Ncv8u;
 typedef              float Ncv32f;
 typedef             double Ncv64f;
index ec2f16e..c1e06b4 100644 (file)
@@ -51,7 +51,7 @@ template<typename TBase> inline __host__ __device__ TBase _pixMaxVal();
 template<> static inline __host__ __device__ Ncv8u  _pixMaxVal<Ncv8u>()  {return UCHAR_MAX;}
 template<> static inline __host__ __device__ Ncv16u _pixMaxVal<Ncv16u>() {return USHRT_MAX;}
 template<> static inline __host__ __device__ Ncv32u _pixMaxVal<Ncv32u>() {return  UINT_MAX;}
-template<> static inline __host__ __device__ Ncv8s  _pixMaxVal<Ncv8s>()  {return  CHAR_MAX;}
+template<> static inline __host__ __device__ Ncv8s  _pixMaxVal<Ncv8s>()  {return  SCHAR_MAX;}
 template<> static inline __host__ __device__ Ncv16s _pixMaxVal<Ncv16s>() {return  SHRT_MAX;}
 template<> static inline __host__ __device__ Ncv32s _pixMaxVal<Ncv32s>() {return   INT_MAX;}
 template<> static inline __host__ __device__ Ncv32f _pixMaxVal<Ncv32f>() {return   FLT_MAX;}
@@ -61,7 +61,7 @@ template<typename TBase> inline __host__ __device__ TBase _pixMinVal();
 template<> static inline __host__ __device__ Ncv8u  _pixMinVal<Ncv8u>()  {return 0;}
 template<> static inline __host__ __device__ Ncv16u _pixMinVal<Ncv16u>() {return 0;}
 template<> static inline __host__ __device__ Ncv32u _pixMinVal<Ncv32u>() {return 0;}
-template<> static inline __host__ __device__ Ncv8s  _pixMinVal<Ncv8s>()  {return CHAR_MIN;}
+template<> static inline __host__ __device__ Ncv8s  _pixMinVal<Ncv8s>()  {return SCHAR_MIN;}
 template<> static inline __host__ __device__ Ncv16s _pixMinVal<Ncv16s>() {return SHRT_MIN;}
 template<> static inline __host__ __device__ Ncv32s _pixMinVal<Ncv32s>() {return INT_MIN;}
 template<> static inline __host__ __device__ Ncv32f _pixMinVal<Ncv32f>() {return FLT_MIN;}
index 06d5386..d3a4467 100644 (file)
@@ -47,9 +47,7 @@
     #pragma warning( disable: 4251 4710 4711 4514 4996 )
 #endif
 
-#ifdef HAVE_CVCONFIG_H
     #include "cvconfig.h"
-#endif
 
 #include <cstring>
 #include <iostream>
index e424763..811d129 100644 (file)
@@ -86,13 +86,16 @@ INSTANTIATE_TEST_CASE_P(GPU_ImgProc, Integral, testing::Combine(
 ///////////////////////////////////////////////////////////////////////////////////////////////////////
 // HistEven
 
-struct HistEven : testing::TestWithParam<cv::gpu::DeviceInfo>
+PARAM_TEST_CASE(HistEven, cv::gpu::DeviceInfo, cv::Size)
 {
     cv::gpu::DeviceInfo devInfo;
 
+    cv::Size size;
+
     virtual void SetUp()
     {
-        devInfo = GetParam();
+        devInfo = GET_PARAM(0);
+        size = GET_PARAM(1);
 
         cv::gpu::setDevice(devInfo.deviceID());
     }
@@ -100,57 +103,34 @@ struct HistEven : testing::TestWithParam<cv::gpu::DeviceInfo>
 
 GPU_TEST_P(HistEven, Accuracy)
 {
-    cv::Mat img = readImage("stereobm/aloe-L.png");
-    ASSERT_FALSE(img.empty());
-
-    cv::Mat hsv;
-    cv::cvtColor(img, hsv, CV_BGR2HSV);
+    cv::Mat src = randomMat(size, CV_8UC1);
 
     int hbins = 30;
-    float hranges[] = {0.0f, 180.0f};
-
-    std::vector<cv::gpu::GpuMat> srcs;
-    cv::gpu::split(loadMat(hsv), srcs);
+    float hranges[] = {50.0f, 200.0f};
 
     cv::gpu::GpuMat hist;
-    cv::gpu::histEven(srcs[0], hist, hbins, (int)hranges[0], (int)hranges[1]);
+    cv::gpu::histEven(loadMat(src), hist, hbins, (int) hranges[0], (int) hranges[1]);
+
+    cv::Mat hist_gold;
 
-    cv::MatND histnd;
     int histSize[] = {hbins};
     const float* ranges[] = {hranges};
     int channels[] = {0};
-    cv::calcHist(&hsv, 1, channels, cv::Mat(), histnd, 1, histSize, ranges);
+    cv::calcHist(&src, 1, channels, cv::Mat(), hist_gold, 1, histSize, ranges);
 
-    cv::Mat hist_gold = histnd;
     hist_gold = hist_gold.t();
     hist_gold.convertTo(hist_gold, CV_32S);
 
     EXPECT_MAT_NEAR(hist_gold, hist, 0.0);
 }
 
-INSTANTIATE_TEST_CASE_P(GPU_ImgProc, HistEven, ALL_DEVICES);
+INSTANTIATE_TEST_CASE_P(GPU_ImgProc, HistEven, testing::Combine(
+    ALL_DEVICES,
+    DIFFERENT_SIZES));
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////////
 // CalcHist
 
-namespace
-{
-    void calcHistGold(const cv::Mat& src, cv::Mat& hist)
-    {
-        hist.create(1, 256, CV_32SC1);
-        hist.setTo(cv::Scalar::all(0));
-
-        int* hist_row = hist.ptr<int>();
-        for (int y = 0; y < src.rows; ++y)
-        {
-            const uchar* src_row = src.ptr(y);
-
-            for (int x = 0; x < src.cols; ++x)
-                ++hist_row[src_row[x]];
-        }
-    }
-}
-
 PARAM_TEST_CASE(CalcHist, cv::gpu::DeviceInfo, cv::Size)
 {
     cv::gpu::DeviceInfo devInfo;
@@ -174,7 +154,16 @@ GPU_TEST_P(CalcHist, Accuracy)
     cv::gpu::calcHist(loadMat(src), hist);
 
     cv::Mat hist_gold;
-    calcHistGold(src, hist_gold);
+
+    const int hbins = 256;
+    const float hranges[] = {0.0f, 256.0f};
+    const int histSize[] = {hbins};
+    const float* ranges[] = {hranges};
+    const int channels[] = {0};
+
+    cv::calcHist(&src, 1, channels, cv::Mat(), hist_gold, 1, histSize, ranges);
+    hist_gold = hist_gold.reshape(1, 1);
+    hist_gold.convertTo(hist_gold, CV_32S);
 
     EXPECT_MAT_NEAR(hist_gold, hist, 0.0);
 }
diff --git a/modules/gpu/test/test_precomp.cpp b/modules/gpu/test/test_precomp.cpp
deleted file mode 100644 (file)
index 0fb6521..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*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"
index 05ab99a..3d7667b 100644 (file)
@@ -9,38 +9,33 @@ ocv_add_module(highgui opencv_imgproc OPTIONAL opencv_androidcamera)
 
 ocv_clear_vars(GRFMT_LIBS)
 
-if(WITH_PNG OR WITH_TIFF OR WITH_OPENEXR)
+if(HAVE_PNG OR HAVE_TIFF OR HAVE_OPENEXR)
   ocv_include_directories(${ZLIB_INCLUDE_DIR})
   list(APPEND GRFMT_LIBS ${ZLIB_LIBRARIES})
 endif()
 
-if(WITH_JPEG)
-  add_definitions(-DHAVE_JPEG)
+if(HAVE_JPEG)
   ocv_include_directories(${JPEG_INCLUDE_DIR})
   list(APPEND GRFMT_LIBS ${JPEG_LIBRARIES})
 endif()
 
-if(WITH_PNG)
-  add_definitions(-DHAVE_PNG)
+if(HAVE_PNG)
   add_definitions(${PNG_DEFINITIONS})
   ocv_include_directories(${PNG_INCLUDE_DIR})
   list(APPEND GRFMT_LIBS ${PNG_LIBRARIES})
 endif()
 
-if(WITH_TIFF)
-  add_definitions(-DHAVE_TIFF)
+if(HAVE_TIFF)
   ocv_include_directories(${TIFF_INCLUDE_DIR})
   list(APPEND GRFMT_LIBS ${TIFF_LIBRARIES})
 endif()
 
-if(WITH_JASPER)
-  add_definitions(-DHAVE_JASPER)
+if(HAVE_JASPER)
   ocv_include_directories(${JASPER_INCLUDE_DIR})
   list(APPEND GRFMT_LIBS ${JASPER_LIBRARIES})
 endif()
 
-if(WITH_OPENEXR)
-  add_definitions(-DHAVE_OPENEXR)
+if(HAVE_OPENEXR)
   include_directories(SYSTEM ${OPENEXR_INCLUDE_PATHS})
   list(APPEND GRFMT_LIBS ${OPENEXR_LIBRARIES})
 endif()
@@ -63,7 +58,6 @@ set(highgui_srcs
     src/cap_images.cpp
     src/cap_ffmpeg.cpp
     src/loadsave.cpp
-    src/precomp.cpp
     src/utils.cpp
     src/window.cpp
     )
@@ -108,16 +102,12 @@ elseif(HAVE_WIN32UI)
   list(APPEND highgui_srcs src/window_w32.cpp)
 elseif(HAVE_GTK)
   list(APPEND highgui_srcs src/window_gtk.cpp)
-elseif(APPLE)
-  if(WITH_CARBON)
-    add_definitions(-DHAVE_CARBON=1)
-    list(APPEND highgui_srcs src/window_carbon.cpp)
-    list(APPEND HIGHGUI_LIBRARIES "-framework Carbon" "-framework QuickTime")
-  elseif(NOT IOS)
-    add_definitions(-DHAVE_COCOA=1)
-    list(APPEND highgui_srcs src/window_cocoa.mm)
-    list(APPEND HIGHGUI_LIBRARIES "-framework Cocoa")
-  endif()
+elseif(HAVE_CARBON)
+  list(APPEND highgui_srcs src/window_carbon.cpp)
+  list(APPEND HIGHGUI_LIBRARIES "-framework Carbon" "-framework QuickTime")
+elseif(HAVE_COCOA)
+  list(APPEND highgui_srcs src/window_cocoa.mm)
+  list(APPEND HIGHGUI_LIBRARIES "-framework Cocoa")
 endif()
 
 if(WIN32 AND NOT ARM)
@@ -197,6 +187,7 @@ endif(HAVE_FFMPEG)
 
 if(HAVE_PVAPI)
   add_definitions(-DHAVE_PVAPI)
+  add_definitions(${PVAPI_DEFINITIONS})
   ocv_include_directories(${PVAPI_INCLUDE_PATH})
   set(highgui_srcs src/cap_pvapi.cpp ${highgui_srcs})
   list(APPEND HIGHGUI_LIBRARIES ${PVAPI_LIBRARY})
@@ -210,31 +201,26 @@ if(HAVE_GIGE_API)
   list(APPEND highgui_srcs src/cap_giganetix.cpp)
 endif(HAVE_GIGE_API)
 
-if(WITH_IMAGEIO)
-  add_definitions(-DHAVE_IMAGEIO=1)
-  if(IOS)
-    list(APPEND HIGHGUI_LIBRARIES "-framework ImageIO")
-  endif()
-endif(WITH_IMAGEIO)
+if(HAVE_IMAGEIO AND IOS)
+  list(APPEND HIGHGUI_LIBRARIES "-framework ImageIO")
+endif()
 
-if(WITH_AVFOUNDATION)
-  add_definitions(-DHAVE_AVFOUNDATION=1)
+if(HAVE_AVFOUNDATION)
   list(APPEND highgui_srcs src/cap_avfoundation.mm)
   list(APPEND HIGHGUI_LIBRARIES "-framework AVFoundation" "-framework QuartzCore")
+endif()
+
+if(HAVE_QUICKTIME)
+  list(APPEND highgui_srcs src/cap_qt.cpp)
+  list(APPEND HIGHGUI_LIBRARIES "-framework Carbon" "-framework QuickTime" "-framework CoreFoundation" "-framework QuartzCore")
 elseif(APPLE)
-  add_definitions(-DHAVE_QUICKTIME=1)
-  if(WITH_QUICKTIME)
-    list(APPEND highgui_srcs src/cap_qt.cpp)
-    list(APPEND HIGHGUI_LIBRARIES "-framework Carbon" "-framework QuickTime" "-framework CoreFoundation" "-framework QuartzCore")
-  else()
-    list(APPEND highgui_srcs src/cap_qtkit.mm)
-    list(APPEND HIGHGUI_LIBRARIES "-framework QTKit" "-framework QuartzCore" "-framework AppKit")
-  endif()
+  list(APPEND highgui_srcs src/cap_qtkit.mm)
+  list(APPEND HIGHGUI_LIBRARIES "-framework QTKit" "-framework QuartzCore" "-framework AppKit")
 endif()
 
 if(IOS)
   add_definitions(-DHAVE_IOS=1)
-  list(APPEND highgui_srcs src/cap_ios_abstract_camera.mm src/cap_ios_photo_camera.mm src/cap_ios_video_camera.mm)
+  list(APPEND highgui_srcs src/ios_conversions.mm src/cap_ios_abstract_camera.mm src/cap_ios_photo_camera.mm src/cap_ios_video_camera.mm)
   list(APPEND HIGHGUI_LIBRARIES "-framework Accelerate" "-framework AVFoundation" "-framework CoreGraphics" "-framework CoreImage" "-framework CoreMedia" "-framework CoreVideo" "-framework QuartzCore" "-framework AssetsLibrary")
 endif()
 
index d473bb4..811f3da 100644 (file)
@@ -224,6 +224,15 @@ The class provides C++ API for capturing video from cameras or for reading video
 
 .. note:: In C API the black-box structure ``CvCapture`` is used instead of ``VideoCapture``.
 
+.. note::
+
+   * A basic sample on using the VideoCapture interface can be found at opencv_source_code/samples/cpp/starter_video.cpp
+   * Another basic video processing sample can be found at opencv_source_code/samples/cpp/video_dmtx.cpp
+
+   * (Python) A basic sample on using the VideoCapture interface can be found at opencv_source_code/samples/python2/video.py
+   * (Python) Another basic video processing sample can be found at opencv_source_code/samples/python2/video_dmtx.py
+   * (Python) A multi threaded video processing sample can be found at opencv_source_code/samples/python2/video_threaded.py
+
 
 VideoCapture::VideoCapture
 ------------------------------
index def8451..f287b77 100644 (file)
@@ -33,6 +33,10 @@ The function ``createTrackbar`` creates a trackbar (a slider or range control) w
 
 Clicking the label of each trackbar enables editing the trackbar values manually.
 
+.. note::
+
+   * An example of using the trackbar functionality can be found at opencv_source_code/samples/cpp/connected_components.cpp
+
 getTrackbarPos
 ------------------
 Returns the trackbar position.
@@ -79,6 +83,7 @@ The function ``imshow`` displays an image in the specified window. If the window
 
     * If the image is 32-bit floating-point, the pixel values are multiplied by 255. That is, the value range [0,1] is mapped to [0,255].
 
+If window was created with OpenGL support, ``imshow`` also support :ocv:class:`ogl::Buffer` ,  :ocv:class:`ogl::Texture2D` and  :ocv:class:`gpu::GpuMat` as input.
 
 namedWindow
 ---------------
@@ -94,7 +99,13 @@ Creates a window.
 
     :param name: Name of the window in the window caption that may be used as a window identifier.
 
-    :param flags: Flags of the window. Currently the only supported flag is  ``CV_WINDOW_AUTOSIZE`` . If this is set, the window size is automatically adjusted to fit the displayed image (see  :ocv:func:`imshow` ), and you cannot change the window size manually.
+    :param flags: Flags of the window. The supported flags are:
+
+        * **WINDOW_NORMAL** If this is set, the user can resize the window (no constraint).
+
+        * **WINDOW_AUTOSIZE** If this is set, the window size is automatically adjusted to fit the displayed image (see  :ocv:func:`imshow` ), and you cannot change the window size manually.
+
+        * **WINDOW_OPENGL** If this is set, the window will be created with OpenGL support.
 
 The function ``namedWindow`` creates a window that can be used as a placeholder for images and trackbars. Created windows are referred to by their names.
 
@@ -256,3 +267,31 @@ The function ``waitKey`` waits for a key event infinitely (when
 .. note::
 
     The function only works if there is at least one HighGUI window created and the window is active. If there are several HighGUI windows, any of them can be active.
+
+setOpenGlDrawCallback
+---------------------
+Set OpenGL render handler for the specified window.
+
+.. ocv:function:: void setOpenGlDrawCallback(const string& winname, OpenGlDrawCallback onOpenGlDraw, void* userdata = 0)
+
+    :param winname: Window name
+
+    :param onOpenGlDraw: Draw callback.
+
+    :param userdata: The optional parameter passed to the callback.
+
+setOpenGlContext
+----------------
+Sets the specified window as current OpenGL context.
+
+.. ocv:function:: void setOpenGlContext(const string& winname)
+
+    :param winname: Window name
+
+updateWindow
+------------
+Force window to redraw its context and call draw callback ( :ocv:func:`setOpenGlDrawCallback` ).
+
+.. ocv:function:: void updateWindow(const string& winname)
+
+    :param winname: Window name
index 5bd5fe3..db3928f 100644 (file)
@@ -1,6 +1,4 @@
-/*
- *  cap_ios.h
- *  For iOS video I/O
+/*  For iOS video I/O
  *  by Eduard Feicho on 29/07/12
  *  Copyright 2012. All rights reserved.
  *
 - (void)createVideoPreviewLayer;
 - (void)updateOrientation;
 
+- (void)lockFocus;
+- (void)unlockFocus;
+- (void)lockExposure;
+- (void)unlockExposure;
+- (void)lockBalance;
+- (void)unlockBalance;
 
 @end
 
     BOOL grayscaleMode;
 
     BOOL recordVideo;
+    BOOL rotateVideo;
     AVAssetWriterInput* recordAssetWriterInput;
     AVAssetWriterInputPixelBufferAdaptor* recordPixelBufferAdaptor;
     AVAssetWriter* recordAssetWriter;
 @property (nonatomic, assign) BOOL grayscaleMode;
 
 @property (nonatomic, assign) BOOL recordVideo;
+@property (nonatomic, assign) BOOL rotateVideo;
 @property (nonatomic, retain) AVAssetWriterInput* recordAssetWriterInput;
 @property (nonatomic, retain) AVAssetWriterInputPixelBufferAdaptor* recordPixelBufferAdaptor;
 @property (nonatomic, retain) AVAssetWriter* recordAssetWriter;
index 12be986..9204ee8 100644 (file)
@@ -558,9 +558,11 @@ CVAPI(int)    cvGetCaptureDomain( CvCapture* capture);
 /* "black box" video file writer structure */
 typedef struct CvVideoWriter CvVideoWriter;
 
+#define CV_FOURCC_MACRO(c1, c2, c3, c4) (((c1) & 255) + (((c2) & 255) << 8) + (((c3) & 255) << 16) + (((c4) & 255) << 24))
+
 CV_INLINE int CV_FOURCC(char c1, char c2, char c3, char c4)
 {
-    return (c1 & 255) + ((c2 & 255) << 8) + ((c3 & 255) << 16) + ((c4 & 255) << 24);
+    return CV_FOURCC_MACRO(c1, c2, c3, c4);
 }
 
 #define CV_FOURCC_PROMPT -1  /* Open Codec Selection Dialog (Windows only) */
similarity index 90%
rename from modules/nonfree/src/precomp.cpp
rename to modules/highgui/include/opencv2/highgui/ios.h
index 730edbb..a78fbf7 100644 (file)
@@ -1,3 +1,4 @@
+
 /*M///////////////////////////////////////////////////////////////////////////////////////
 //
 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
@@ -40,6 +41,9 @@
 //
 //M*/
 
-#include "precomp.hpp"
+#include "opencv2/core/core.hpp"
+#import "opencv2/highgui/cap_ios.h"
 
-/* End of file. */
+UIImage* MatToUIImage(const cv::Mat& image);
+void UIImageToMat(const UIImage* image,
+                         cv::Mat& m, bool alphaExist = false);
\ No newline at end of file
index 0c1e8e0..414c853 100644 (file)
@@ -11,11 +11,21 @@ using std::tr1::get;
 
 typedef perf::TestBaseWithParam<String> VideoCapture_Reading;
 
+#if defined(HAVE_MSMF)
+// MPEG2 is not supported by Media Foundation yet
+// http://social.msdn.microsoft.com/Forums/en-US/mediafoundationdevelopment/thread/39a36231-8c01-40af-9af5-3c105d684429
+PERF_TEST_P(VideoCapture_Reading, ReadFile, testing::Values( "highgui/video/big_buck_bunny.avi",
+                                               "highgui/video/big_buck_bunny.mov",
+                                               "highgui/video/big_buck_bunny.mp4",
+                                               "highgui/video/big_buck_bunny.wmv" ) )
+
+#else
 PERF_TEST_P(VideoCapture_Reading, ReadFile, testing::Values( "highgui/video/big_buck_bunny.avi",
                                                "highgui/video/big_buck_bunny.mov",
                                                "highgui/video/big_buck_bunny.mp4",
                                                "highgui/video/big_buck_bunny.mpg",
                                                "highgui/video/big_buck_bunny.wmv" ) )
+#endif
 {
   string filename = getDataPath(GetParam());
 
index 6428bb4..2adfe89 100644 (file)
@@ -22,10 +22,16 @@ PERF_TEST_P(VideoWriter_Writing, WriteFrame,
 {
   string filename = getDataPath(get<0>(GetParam()));
   bool isColor = get<1>(GetParam());
-
-  VideoWriter writer(cv::tempfile(".avi"), CV_FOURCC('X', 'V', 'I', 'D'), 25, cv::Size(640, 480), isColor);
-
-  TEST_CYCLE() { Mat image = imread(filename, 1); writer << image; }
+  Mat image = imread(filename, 1);
+#if defined(HAVE_MSMF) && !defined(HAVE_VFW) && !defined(HAVE_FFMPEG) // VFW has greater priority
+  VideoWriter writer(cv::tempfile(".wmv"), CV_FOURCC('W', 'M', 'V', '3'),
+                            25, cv::Size(image.cols, image.rows), isColor);
+#else
+  VideoWriter writer(cv::tempfile(".avi"), CV_FOURCC('X', 'V', 'I', 'D'),
+                            25, cv::Size(image.cols, image.rows), isColor);
+#endif
+
+  TEST_CYCLE() { image = imread(filename, 1); writer << image; }
 
   bool dummy = writer.isOpened();
   SANITY_CHECK(dummy);
diff --git a/modules/highgui/perf/perf_precomp.cpp b/modules/highgui/perf/perf_precomp.cpp
deleted file mode 100644 (file)
index 8552ac3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "perf_precomp.hpp"
index 529187d..d6b28b6 100644 (file)
@@ -21,6 +21,7 @@
     defined(HAVE_QUICKTIME)    || \
     defined(HAVE_AVFOUNDATION) || \
     defined(HAVE_FFMPEG)       || \
+    defined(HAVE_MSMF)         || \
     defined(HAVE_VFW)
     /*defined(HAVE_OPENNI) too specialized */ \
 
@@ -34,6 +35,7 @@
     defined(HAVE_QUICKTIME)    || \
     defined(HAVE_AVFOUNDATION) || \
     defined(HAVE_FFMPEG)       || \
+    defined(HAVE_MSMF)         || \
     defined(HAVE_VFW)
 #  define BUILD_WITH_VIDEO_OUTPUT_SUPPORT 1
 #else
index 2c3b3a9..b5cdc5e 100644 (file)
@@ -117,6 +117,9 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
 #ifdef HAVE_DSHOW
         CV_CAP_DSHOW,
 #endif
+#ifdef HAVE_MSMF
+        CV_CAP_MSMF,
+#endif
 #if 1
         CV_CAP_IEEE1394,   // identical to CV_CAP_DC1394
 #endif
@@ -196,21 +199,20 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
 
         switch (domains[i])
         {
-#ifdef HAVE_MSMF
-        case CV_CAP_MSMF:
-             capture = cvCreateCameraCapture_MSMF (index);
+#ifdef HAVE_DSHOW
+        case CV_CAP_DSHOW:
+             capture = cvCreateCameraCapture_DShow (index);
              if (capture)
                  return capture;
             break;
 #endif
-#ifdef HAVE_DSHOW
-        case CV_CAP_DSHOW:
-             capture = cvCreateCameraCapture_DShow (index);
+#ifdef HAVE_MSMF
+        case CV_CAP_MSMF:
+             capture = cvCreateCameraCapture_MSMF (index);
              if (capture)
                  return capture;
             break;
 #endif
-
 #ifdef HAVE_TYZX
         case CV_CAP_STEREO:
             capture = cvCreateCameraCapture_TYZX (index);
@@ -218,14 +220,12 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
                 return capture;
             break;
 #endif
-
         case CV_CAP_VFW:
 #ifdef HAVE_VFW
             capture = cvCreateCameraCapture_VFW (index);
             if (capture)
                 return capture;
 #endif
-
 #if defined HAVE_LIBV4L || defined HAVE_CAMV4L || defined HAVE_CAMV4L2 || defined HAVE_VIDEOIO
             capture = cvCreateCameraCapture_V4L (index);
             if (capture)
@@ -358,6 +358,16 @@ CV_IMPL CvCapture * cvCreateFileCapture (const char * filename)
     if (! result)
         result = cvCreateFileCapture_FFMPEG_proxy (filename);
 
+#ifdef HAVE_VFW
+    if (! result)
+        result = cvCreateFileCapture_VFW (filename);
+#endif
+
+#ifdef HAVE_MSMF
+    if (! result)
+        result = cvCreateFileCapture_MSMF (filename);
+#endif
+
 #ifdef HAVE_XINE
     if (! result)
         result = cvCreateFileCapture_XINE (filename);
@@ -406,6 +416,16 @@ CV_IMPL CvVideoWriter* cvCreateVideoWriter( const char* filename, int fourcc,
     if(!result)
         result = cvCreateVideoWriter_FFMPEG_proxy (filename, fourcc, fps, frameSize, is_color);
 
+#ifdef HAVE_VFW
+    if(!result)
+        result = cvCreateVideoWriter_VFW(filename, fourcc, fps, frameSize, is_color);
+#endif
+
+#ifdef HAVE_MSMF
+    if (!result)
+        result = cvCreateVideoWriter_MSMF(filename, fourcc, fps, frameSize, is_color);
+#endif
+
 /*  #ifdef HAVE_XINE
     if(!result)
         result = cvCreateVideoWriter_XINE(filename, fourcc, fps, frameSize, is_color);
@@ -469,14 +489,14 @@ VideoCapture::~VideoCapture()
 
 bool VideoCapture::open(const string& filename)
 {
-    if (!isOpened())
+    if (isOpened()) release();
     cap = cvCreateFileCapture(filename.c_str());
     return isOpened();
 }
 
 bool VideoCapture::open(int device)
 {
-    if (!isOpened())
+    if (isOpened()) release();
     cap = cvCreateCameraCapture(device);
     return isOpened();
 }
index ea7e4b2..0d5f898 100644 (file)
@@ -304,6 +304,11 @@ bool CvCaptureCAM_DC1394_v2_CPP::startCapture()
         return false;
     if (isoSpeed > 0)
     {
+        // if capable set operation mode to 1394b for iso speeds above 400
+        if (isoSpeed > 400 && dcCam->bmode_capable == DC1394_TRUE)
+        {
+            dc1394_video_set_operation_mode(dcCam, DC1394_OPERATION_MODE_1394B);
+        }
         code = dc1394_video_set_iso_speed(dcCam,
                                           isoSpeed <= 100 ? DC1394_ISO_SPEED_100 :
                                           isoSpeed <= 200 ? DC1394_ISO_SPEED_200 :
index b7cfbd9..606e520 100644 (file)
@@ -3164,18 +3164,18 @@ void CvCaptureCAM_DShow::close()
 // Initialize camera input
 bool CvCaptureCAM_DShow::open( int _index )
 {
-    int try_index = _index;
     int devices = 0;
 
     close();
     devices = VI.listDevices(true);
     if (devices == 0)
         return false;
-    try_index = try_index < 0 ? 0 : (try_index > devices-1 ? devices-1 : try_index);
-    VI.setupDevice(try_index);
-    if( !VI.isDeviceSetup(try_index) )
+    if (_index < 0 || _index > devices-1)
         return false;
-    index = try_index;
+    VI.setupDevice(_index);
+    if( !VI.isDeviceSetup(_index) )
+        return false;
+    index = _index;
     return true;
 }
 
index 669ebda..bf73c08 100644 (file)
@@ -209,11 +209,7 @@ CvCapture* cvCreateFileCapture_FFMPEG_proxy(const char * filename)
     if( result->open( filename ))
         return result;
     delete result;
-#ifdef HAVE_VFW
-    return cvCreateFileCapture_VFW(filename);
-#else
     return 0;
-#endif
 }
 
 class CvVideoWriter_FFMPEG_proxy : 
@@ -263,9 +259,5 @@ CvVideoWriter* cvCreateVideoWriter_FFMPEG_proxy( const char* filename, int fourc
     if( result->open( filename, fourcc, fps, frameSize, isColor != 0 ))
         return result;
     delete result;
-#ifdef HAVE_VFW
-     return cvCreateVideoWriter_VFW(filename, fourcc, fps, frameSize, isColor);
- #else
     return 0;
-#endif
 }
index d494948..84222ad 100644 (file)
@@ -1362,8 +1362,6 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int
 /// close video output stream and free associated memory
 void CvVideoWriter_FFMPEG::close()
 {
-    unsigned i;
-
     // nothing to do if already released
     if ( !picture )
         return;
@@ -1419,13 +1417,6 @@ void CvVideoWriter_FFMPEG::close()
 
     av_free(outbuf);
 
-    /* free the streams */
-    for(i = 0; i < oc->nb_streams; i++)
-    {
-        av_freep(&oc->streams[i]->codec);
-        av_freep(&oc->streams[i]);
-    }
-
     if (!(fmt->flags & AVFMT_NOFILE))
     {
         /* close the output file */
@@ -1443,7 +1434,7 @@ void CvVideoWriter_FFMPEG::close()
     }
 
     /* free the stream */
-    av_free(oc);
+    avformat_free_context(oc);
 
     if( temp_image.data )
     {
index b6a7d94..38e1c12 100644 (file)
@@ -2,6 +2,7 @@
  *  cap_ios_abstract_camera.mm
  *  For iOS video I/O
  *  by Eduard Feicho on 29/07/12
+ *  by Alexander Shishkov on 17/07/13
  *  Copyright 2012. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
     }
 }
 
+- (void)lockFocus;
+{
+    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
+    if ([device isFocusModeSupported:AVCaptureFocusModeLocked]) {
+        NSError *error = nil;
+        if ([device lockForConfiguration:&error]) {
+            device.focusMode = AVCaptureFocusModeLocked;
+            [device unlockForConfiguration];
+        } else {
+            NSLog(@"unable to lock device for locked focus configuration %@", [error localizedDescription]);
+        }
+    }
+}
+
+- (void) unlockFocus;
+{
+    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
+    if ([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) {
+        NSError *error = nil;
+        if ([device lockForConfiguration:&error]) {
+            device.focusMode = AVCaptureFocusModeContinuousAutoFocus;
+            [device unlockForConfiguration];
+        } else {
+            NSLog(@"unable to lock device for autofocus configuration %@", [error localizedDescription]);
+        }
+    }
+}
+
+- (void)lockExposure;
+{
+    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
+    if ([device isExposureModeSupported:AVCaptureExposureModeLocked]) {
+        NSError *error = nil;
+        if ([device lockForConfiguration:&error]) {
+            device.exposureMode = AVCaptureExposureModeLocked;
+            [device unlockForConfiguration];
+        } else {
+            NSLog(@"unable to lock device for locked exposure configuration %@", [error localizedDescription]);
+        }
+    }
+}
+
+- (void) unlockExposure;
+{
+    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
+    if ([device isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) {
+        NSError *error = nil;
+        if ([device lockForConfiguration:&error]) {
+            device.exposureMode = AVCaptureExposureModeContinuousAutoExposure;
+            [device unlockForConfiguration];
+        } else {
+            NSLog(@"unable to lock device for autoexposure configuration %@", [error localizedDescription]);
+        }
+    }
+}
+
+- (void)lockBalance;
+{
+    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
+    if ([device isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeLocked]) {
+        NSError *error = nil;
+        if ([device lockForConfiguration:&error]) {
+            device.whiteBalanceMode = AVCaptureWhiteBalanceModeLocked;
+            [device unlockForConfiguration];
+        } else {
+            NSLog(@"unable to lock device for locked white balance configuration %@", [error localizedDescription]);
+        }
+    }
+}
+
+- (void) unlockBalance;
+{
+    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
+    if ([device isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance]) {
+        NSError *error = nil;
+        if ([device lockForConfiguration:&error]) {
+            device.whiteBalanceMode = AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance;
+            [device unlockForConfiguration];
+        } else {
+            NSLog(@"unable to lock device for auto white balance configuration %@", [error localizedDescription]);
+        }
+    }
+}
+
 @end
+
index 1f9ea14..ac85f79 100644 (file)
@@ -2,6 +2,7 @@
  *  cap_ios_video_camera.mm
  *  For iOS video I/O
  *  by Eduard Feicho on 29/07/12
+ *  by Alexander Shishkov on 17/07/13
  *  Copyright 2012. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -30,7 +31,6 @@
 
 #import "opencv2/highgui/cap_ios.h"
 #include "precomp.hpp"
-
 #import <AssetsLibrary/AssetsLibrary.h>
 
 
@@ -70,6 +70,7 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};
 @synthesize videoDataOutput;
 
 @synthesize recordVideo;
+@synthesize rotateVideo;
 //@synthesize videoFileOutput;
 @synthesize recordAssetWriterInput;
 @synthesize recordPixelBufferAdaptor;
@@ -85,6 +86,7 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};
     if (self) {
         self.useAVCaptureVideoPreviewLayer = NO;
         self.recordVideo = NO;
+        self.rotateVideo = NO;
     }
     return self;
 }
@@ -269,13 +271,8 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};
 
 }
 
-
-
-
 #pragma mark - Private Interface
 
-
-
 - (void)createVideoDataOutput;
 {
     // Make a video data output
@@ -389,6 +386,38 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};
     [self.parentView.layer addSublayer:self.customPreviewLayer];
 }
 
+- (CVPixelBufferRef) pixelBufferFromCGImage: (CGImageRef) image
+{
+    
+    CGSize frameSize = CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image));
+    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
+                             [NSNumber numberWithBool:NO], kCVPixelBufferCGImageCompatibilityKey,
+                             [NSNumber numberWithBool:NO], kCVPixelBufferCGBitmapContextCompatibilityKey,
+                             nil];
+    CVPixelBufferRef pxbuffer = NULL;
+    CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, frameSize.width,
+                                          frameSize.height,  kCVPixelFormatType_32ARGB, (CFDictionaryRef) CFBridgingRetain(options),
+                                          &pxbuffer);
+    NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);
+    
+    CVPixelBufferLockBaseAddress(pxbuffer, 0);
+    void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
+    
+    
+    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
+    CGContextRef context = CGBitmapContextCreate(pxdata, frameSize.width,
+                                                 frameSize.height, 8, 4*frameSize.width, rgbColorSpace,
+                                                 kCGImageAlphaPremultipliedFirst);
+    
+    CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image),
+                                           CGImageGetHeight(image)), image);
+    CGColorSpaceRelease(rgbColorSpace);
+    CGContextRelease(context);
+    
+    CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
+    
+    return pxbuffer;
+}
 
 #pragma mark - Protocol AVCaptureVideoDataOutputSampleBufferDelegate
 
@@ -522,7 +551,8 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};
             }
 
             if (self.recordAssetWriterInput.readyForMoreMediaData) {
-                if (! [self.recordPixelBufferAdaptor appendPixelBuffer:imageBuffer
+                CVImageBufferRef pixelBuffer = [self pixelBufferFromCGImage:dstImage];
+                if (! [self.recordPixelBufferAdaptor appendPixelBuffer:pixelBuffer
                                                   withPresentationTime:lastSampleTime] ) {
                     NSLog(@"Video Writing Error");
                 }
@@ -543,9 +573,12 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};
 
 - (void)updateOrientation;
 {
-    NSLog(@"rotate..");
-    self.customPreviewLayer.bounds = CGRectMake(0, 0, self.parentView.frame.size.width, self.parentView.frame.size.height);
-    [self layoutPreviewLayer];
+    if (self.rotateVideo == YES)
+    {
+        NSLog(@"rotate..");
+        self.customPreviewLayer.bounds = CGRectMake(0, 0, self.parentView.frame.size.width, self.parentView.frame.size.height);
+        [self layoutPreviewLayer];
+    }
 }
 
 
@@ -583,3 +616,4 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};
 }
 
 @end
+
index b081621..6027cae 100644 (file)
@@ -14,7 +14,9 @@ It has been tested with the motempl sample program
 First Patch:  August 24, 2004 Travis Wood   TravisOCV@tkwood.com
 For Release:  OpenCV-Linux Beta4  opencv-0.9.6
 Tested On:    LMLBT44 with 8 video inputs
-Problems?     Post problems/fixes to OpenCV group on groups.yahoo.com
+Problems?     Post your questions at answers.opencv.org, 
+              Report bugs at code.opencv.org,
+              Submit your fixes at https://github.com/Itseez/opencv/
 Patched Comments:
 
 TW: The cv cam utils that came with the initial release of OpenCV for LINUX Beta4
index 52b7804..76b9a21 100644 (file)
@@ -53,7 +53,8 @@
 #include <Mfapi.h>
 #include <mfplay.h>
 #include <mfobjects.h>
-#include "Strsafe.h"
+#include <strsafe.h>
+#include <Mfreadwrite.h>
 #include <new>
 #include <map>
 #include <vector>
 #include <stdio.h>
 #include <stdarg.h>
 #include <string.h>
+
 #pragma warning(disable:4503)
 #pragma comment(lib, "mfplat")
 #pragma comment(lib, "mf")
 #pragma comment(lib, "mfuuid")
 #pragma comment(lib, "Strmiids")
+#pragma comment(lib, "Mfreadwrite")
 #pragma comment(lib, "MinCore_Downlevel")
+
+// for ComPtr usage
+#include <wrl/client.h>
+using namespace Microsoft::WRL;
+
 struct IMFMediaType;
 struct IMFActivate;
 struct IMFMediaSource;
 struct IMFAttributes;
+
 namespace
 {
+
 template <class T> void SafeRelease(T **ppT)
 {
     if (*ppT)
@@ -81,7 +91,8 @@ template <class T> void SafeRelease(T **ppT)
         *ppT = NULL;
     }
 }
- /// Class for printing info into consol
+
+/// Class for printing info into consol
 class DebugPrintOut
 {
 public:
@@ -93,6 +104,7 @@ public:
 private:
     DebugPrintOut(void);
 };
+
 // Structure for collecting info about types of video, which are supported by current video device
 struct MediaType
 {
@@ -101,14 +113,14 @@ struct MediaType
     unsigned int width;
     unsigned int MF_MT_YUV_MATRIX;
     unsigned int MF_MT_VIDEO_LIGHTING;
-    unsigned int MF_MT_DEFAULT_STRIDE;
+    int MF_MT_DEFAULT_STRIDE; // stride is negative if image is bottom-up
     unsigned int MF_MT_VIDEO_CHROMA_SITING;
     GUID MF_MT_AM_FORMAT_TYPE;
     wchar_t *pMF_MT_AM_FORMAT_TYPEName;
     unsigned int MF_MT_FIXED_SIZE_SAMPLES;
     unsigned int MF_MT_VIDEO_NOMINAL_RANGE;
-    unsigned int MF_MT_FRAME_RATE;
-    unsigned int MF_MT_FRAME_RATE_low;
+    unsigned int MF_MT_FRAME_RATE_NUMERATOR;
+    unsigned int MF_MT_FRAME_RATE_DENOMINATOR;
     unsigned int MF_MT_PIXEL_ASPECT_RATIO;
     unsigned int MF_MT_PIXEL_ASPECT_RATIO_low;
     unsigned int MF_MT_ALL_SAMPLES_INDEPENDENT;
@@ -127,6 +139,7 @@ struct MediaType
     ~MediaType();
     void Clear();
 };
+
 /// Class for parsing info from IMFMediaType into the local MediaType
 class FormatReader
 {
@@ -136,9 +149,10 @@ public:
 private:
     FormatReader(void);
 };
+
 DWORD WINAPI MainThreadFunction( LPVOID lpParam );
 typedef void(*emergensyStopEventCallback)(int, void *);
-typedef unsigned char BYTE;
+
 class RawImage
 {
 public:
@@ -156,6 +170,7 @@ private:
     unsigned char *ri_pixels;
     RawImage(unsigned int size);
 };
+
 // Class for grabbing image from video stream
 class ImageGrabber : public IMFSampleGrabberSinkCallback
 {
@@ -163,13 +178,21 @@ public:
     ~ImageGrabber(void);
     HRESULT initImageGrabber(IMFMediaSource *pSource, GUID VideoFormat);
     HRESULT startGrabbing(void);
+    void pauseGrabbing();
+    void resumeGrabbing();
     void stopGrabbing();
     RawImage *getRawImage();
     // Function of creation of the instance of the class
-    static HRESULT CreateInstance(ImageGrabber **ppIG,unsigned int deviceID);
+    static HRESULT CreateInstance(ImageGrabber **ppIG, unsigned int deviceID, bool synchronous = false);
+
+    const HANDLE ig_hFrameReady;
+    const HANDLE ig_hFrameGrabbed;
+    const HANDLE ig_hFinish;
+
 private:
     bool ig_RIE;
     bool ig_Close;
+    bool ig_Synchronous;
     long m_cRef;
     unsigned int ig_DeviceID;
     IMFMediaSource *ig_pSource;
@@ -178,19 +201,11 @@ private:
     RawImage *ig_RIFirst;
     RawImage *ig_RISecond;
     RawImage *ig_RIOut;
-    ImageGrabber(unsigned int deviceID);
+    ImageGrabber(unsigned int deviceID, bool synchronous);
     HRESULT CreateTopology(IMFMediaSource *pSource, IMFActivate *pSinkActivate, IMFTopology **ppTopo);
-    HRESULT AddSourceNode(
-    IMFTopology *pTopology,
-    IMFMediaSource *pSource,
-    IMFPresentationDescriptor *pPD,
-    IMFStreamDescriptor *pSD,
-    IMFTopologyNode **ppNode);
-    HRESULT AddOutputNode(
-    IMFTopology *pTopology,
-    IMFActivate *pActivate,
-    DWORD dwId,
-    IMFTopologyNode **ppNode);
+    HRESULT AddSourceNode(IMFTopology *pTopology, IMFMediaSource *pSource,
+        IMFPresentationDescriptor *pPD, IMFStreamDescriptor *pSD, IMFTopologyNode **ppNode);
+    HRESULT AddOutputNode(IMFTopology *pTopology, IMFActivate *pActivate, DWORD dwId, IMFTopologyNode **ppNode);
     // IUnknown methods
     STDMETHODIMP QueryInterface(REFIID iid, void** ppv);
     STDMETHODIMP_(ULONG) AddRef();
@@ -208,13 +223,14 @@ private:
         DWORD dwSampleSize);
     STDMETHODIMP OnShutdown();
 };
+
 /// Class for controlling of thread of the grabbing raw data from video device
 class ImageGrabberThread
 {
     friend DWORD WINAPI MainThreadFunction( LPVOID lpParam );
 public:
     ~ImageGrabberThread(void);
-    static HRESULT CreateInstance(ImageGrabberThread **ppIGT, IMFMediaSource *pSource, unsigned int deviceID);
+    static HRESULT CreateInstance(ImageGrabberThread **ppIGT, IMFMediaSource *pSource, unsigned int deviceID, bool synchronious = false);
     void start();
     void stop();
     void setEmergencyStopEvent(void *userData, void(*func)(int, void *));
@@ -222,7 +238,7 @@ public:
 protected:
     virtual void run();
 private:
-    ImageGrabberThread(IMFMediaSource *pSource, unsigned int deviceID);
+    ImageGrabberThread(IMFMediaSource *pSource, unsigned int deviceID, bool synchronious);
     HANDLE igt_Handle;
     DWORD   igt_ThreadIdArray;
     ImageGrabber *igt_pImageGrabber;
@@ -231,6 +247,7 @@ private:
     bool igt_stop;
     unsigned int igt_DeviceID;
 };
+
 // Structure for collecting info about one parametr of current video device
 struct Parametr
 {
@@ -242,6 +259,7 @@ struct Parametr
     long Flag;
     Parametr();
 };
+
 // Structure for collecting info about 17 parametrs of current video device
 struct CamParametrs
 {
@@ -263,11 +281,13 @@ struct CamParametrs
         Parametr Iris;
         Parametr Focus;
 };
+
 typedef std::wstring String;
 typedef std::vector<int> vectorNum;
 typedef std::map<String, vectorNum> SUBTYPEMap;
 typedef std::map<UINT64, SUBTYPEMap> FrameRateMap;
 typedef void(*emergensyStopEventCallback)(int, void *);
+
 /// Class for controlling of video device
 class videoDevice
 {
@@ -311,7 +331,7 @@ private:
     IMFMediaSource *vd_pSource;
     emergensyStopEventCallback vd_func;
     void *vd_userData;
-    long enumerateCaptureFormats(IMFMediaSource *pSource);
+    HRESULT enumerateCaptureFormats(IMFMediaSource *pSource);
     long setDeviceFormat(IMFMediaSource *pSource, unsigned long dwFormatIndex);
     void buildLibraryofTypes();
     int findType(unsigned int size, unsigned int frameRate = 0);
@@ -319,6 +339,7 @@ private:
     long initDevice();
     long checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice);
 };
+
 /// Class for managing of list of video devices
 class videoDevices
 {
@@ -334,6 +355,7 @@ private:
     std::vector<videoDevice *> vds_Devices;
     videoDevices(void);
 };
+
 // Class for creating of Media Foundation context
 class Media_Foundation
 {
@@ -344,6 +366,7 @@ public:
 private:
     Media_Foundation(void);
 };
+
 /// The only visiable class for controlling of video devices in format singelton
 class videoInput
 {
@@ -393,23 +416,27 @@ public:
     bool isFrameNew(int deviceID);
     // Writing of Raw Data pixels from video device with deviceID with correction of RedAndBlue flipping flipRedAndBlue and vertical flipping flipImage
     bool getPixels(int deviceID, unsigned char * pixels, bool flipRedAndBlue = false, bool flipImage = false);
+    static void processPixels(unsigned char * src, unsigned char * dst, unsigned int width, unsigned int height, unsigned int bpp, bool bRGB, bool bFlip);
 private:
     bool accessToDevices;
     videoInput(void);
-    void processPixels(unsigned char * src, unsigned char * dst, unsigned int width, unsigned int height, unsigned int bpp, bool bRGB, bool bFlip);
     void updateListOfDevices();
 };
+
 DebugPrintOut::DebugPrintOut(void):verbose(true)
 {
 }
+
 DebugPrintOut::~DebugPrintOut(void)
 {
 }
+
 DebugPrintOut& DebugPrintOut::getInstance()
 {
     static DebugPrintOut instance;
     return instance;
 }
+
 void DebugPrintOut::printOut(const wchar_t *format, ...)
 {
     if(verbose)
@@ -430,14 +457,17 @@ void DebugPrintOut::printOut(const wchar_t *format, ...)
         va_end (args);
     }
 }
+
 void DebugPrintOut::setVerbose(bool state)
 {
     verbose = state;
 }
+
 LPCWSTR GetGUIDNameConstNew(const GUID& guid);
 HRESULT GetGUIDNameNew(const GUID& guid, WCHAR **ppwsz);
 HRESULT LogAttributeValueByIndexNew(IMFAttributes *pAttr, DWORD index);
 HRESULT SpecialCaseAttributeValueNew(GUID guid, const PROPVARIANT& var, MediaType &out);
+
 unsigned int *GetParametr(GUID guid, MediaType &out)
 {
     if(guid == MF_MT_YUV_MATRIX)
@@ -445,7 +475,7 @@ unsigned int *GetParametr(GUID guid, MediaType &out)
     if(guid == MF_MT_VIDEO_LIGHTING)
         return &(out.MF_MT_VIDEO_LIGHTING);
     if(guid == MF_MT_DEFAULT_STRIDE)
-        return &(out.MF_MT_DEFAULT_STRIDE);
+        return (unsigned int*)&(out.MF_MT_DEFAULT_STRIDE);
     if(guid == MF_MT_VIDEO_CHROMA_SITING)
         return &(out.MF_MT_VIDEO_CHROMA_SITING);
     if(guid == MF_MT_VIDEO_NOMINAL_RANGE)
@@ -462,6 +492,7 @@ unsigned int *GetParametr(GUID guid, MediaType &out)
         return &(out.MF_MT_INTERLACE_MODE);
     return NULL;
 }
+
 HRESULT LogAttributeValueByIndexNew(IMFAttributes *pAttr, DWORD index, MediaType &out)
 {
     WCHAR *pGuidName = NULL;
@@ -548,6 +579,7 @@ done:
     PropVariantClear(&var);
     return hr;
 }
+
 HRESULT GetGUIDNameNew(const GUID& guid, WCHAR **ppwsz)
 {
     HRESULT hr = S_OK;
@@ -589,14 +621,17 @@ done:
     }
     return hr;
 }
+
 void LogUINT32AsUINT64New(const PROPVARIANT& var, UINT32 &uHigh, UINT32 &uLow)
 {
     Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &uHigh, &uLow);
 }
+
 float OffsetToFloatNew(const MFOffset& offset)
 {
     return offset.value + (static_cast<float>(offset.fract) / 65536.0f);
 }
+
 HRESULT LogVideoAreaNew(const PROPVARIANT& var)
 {
     if (var.caub.cElems < sizeof(MFVideoArea))
@@ -605,8 +640,13 @@ HRESULT LogVideoAreaNew(const PROPVARIANT& var)
     }
     return S_OK;
 }
+
 HRESULT SpecialCaseAttributeValueNew(GUID guid, const PROPVARIANT& var, MediaType &out)
 {
+    if (guid == MF_MT_DEFAULT_STRIDE)
+    {
+        out.MF_MT_DEFAULT_STRIDE = var.intVal;
+    } else
     if (guid == MF_MT_FRAME_SIZE)
     {
         UINT32 uHigh = 0, uLow = 0;
@@ -620,8 +660,8 @@ HRESULT SpecialCaseAttributeValueNew(GUID guid, const PROPVARIANT& var, MediaTyp
     {
         UINT32 uHigh = 0, uLow = 0;
         LogUINT32AsUINT64New(var, uHigh, uLow);
-        out.MF_MT_FRAME_RATE = uHigh;
-        out.MF_MT_FRAME_RATE_low = uLow;
+        out.MF_MT_FRAME_RATE_NUMERATOR = uHigh;
+        out.MF_MT_FRAME_RATE_DENOMINATOR = uLow;
     }
     else
     if (guid == MF_MT_FRAME_RATE_RANGE_MAX)
@@ -653,9 +693,11 @@ HRESULT SpecialCaseAttributeValueNew(GUID guid, const PROPVARIANT& var, MediaTyp
     }
     return S_OK;
 }
+
 #ifndef IF_EQUAL_RETURN
 #define IF_EQUAL_RETURN(param, val) if(val == param) return L#val
 #endif
+
 LPCWSTR GetGUIDNameConstNew(const GUID& guid)
 {
     IF_EQUAL_RETURN(guid, MF_MT_MAJOR_TYPE);
@@ -800,9 +842,11 @@ LPCWSTR GetGUIDNameConstNew(const GUID& guid)
     IF_EQUAL_RETURN(guid, MFAudioFormat_ADTS); //             WAVE_FORMAT_MPEG_ADTS_AAC
     return NULL;
 }
+
 FormatReader::FormatReader(void)
 {
 }
+
 MediaType FormatReader::Read(IMFMediaType *pType)
 {
     UINT32 count = 0;
@@ -833,32 +877,57 @@ MediaType FormatReader::Read(IMFMediaType *pType)
     }
     return out;
 }
+
 FormatReader::~FormatReader(void)
 {
 }
+
 #define CHECK_HR(x) if (FAILED(x)) { goto done; }
-ImageGrabber::ImageGrabber(unsigned int deviceID): m_cRef(1), ig_DeviceID(deviceID), ig_pSource(NULL), ig_pSession(NULL), ig_pTopology(NULL), ig_RIE(true), ig_Close(false)
-{
-}
+
+ImageGrabber::ImageGrabber(unsigned int deviceID, bool synchronous):
+    m_cRef(1),
+    ig_DeviceID(deviceID),
+    ig_pSource(NULL),
+    ig_pSession(NULL),
+    ig_pTopology(NULL),
+    ig_RIE(true),
+    ig_Close(false),
+    ig_Synchronous(synchronous),
+    ig_hFrameReady(synchronous ? CreateEvent(NULL, FALSE, FALSE, NULL): 0),
+    ig_hFrameGrabbed(synchronous ? CreateEvent(NULL, FALSE, TRUE, NULL): 0),
+    ig_hFinish(CreateEvent(NULL, TRUE, FALSE, NULL))
+{}
+
 ImageGrabber::~ImageGrabber(void)
 {
     if (ig_pSession)
     {
         ig_pSession->Shutdown();
     }
-    //SafeRelease(&ig_pSession);
-    //SafeRelease(&ig_pTopology);
+
+    CloseHandle(ig_hFinish);
+
+    if (ig_Synchronous)
+    {
+        CloseHandle(ig_hFrameReady);
+        CloseHandle(ig_hFrameGrabbed);
+    }
+
+    SafeRelease(&ig_pSession);
+    SafeRelease(&ig_pTopology);
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-    DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Destroing instance of the ImageGrabber class \n", ig_DeviceID);
+
+    DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Destroing instance of the ImageGrabber class\n", ig_DeviceID);
 }
+
 HRESULT ImageGrabber::initImageGrabber(IMFMediaSource *pSource, GUID VideoFormat)
 {
-    IMFActivate *pSinkActivate = NULL;
-    IMFMediaType *pType = NULL;
-    IMFPresentationDescriptor *pPD = NULL;
-    IMFStreamDescriptor *pSD = NULL;
-    IMFMediaTypeHandler *pHandler = NULL;
-    IMFMediaType *pCurrentType = NULL;
+    ComPtr<IMFActivate> pSinkActivate = NULL;
+    ComPtr<IMFMediaType> pType = NULL;
+    ComPtr<IMFPresentationDescriptor> pPD = NULL;
+    ComPtr<IMFStreamDescriptor> pSD = NULL;
+    ComPtr<IMFMediaTypeHandler> pHandler = NULL;
+    ComPtr<IMFMediaType> pCurrentType = NULL;
     HRESULT hr = S_OK;
     MediaType MT;
      // Clean up.
@@ -871,30 +940,32 @@ HRESULT ImageGrabber::initImageGrabber(IMFMediaSource *pSource, GUID VideoFormat
     ig_pSource = pSource;
     hr = pSource->CreatePresentationDescriptor(&pPD);
     if (FAILED(hr))
+    {
         goto err;
+    }
     BOOL fSelected;
     hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, &pSD);
-    if (FAILED(hr))
+    if (FAILED(hr)) {
         goto err;
+    }
     hr = pSD->GetMediaTypeHandler(&pHandler);
-    if (FAILED(hr))
+    if (FAILED(hr)) {
         goto err;
+    }
     DWORD cTypes = 0;
     hr = pHandler->GetMediaTypeCount(&cTypes);
-    if (FAILED(hr))
+    if (FAILED(hr)) {
         goto err;
+    }
     if(cTypes > 0)
     {
         hr = pHandler->GetCurrentMediaType(&pCurrentType);
-        if (FAILED(hr))
+        if (FAILED(hr)) {
             goto err;
-        MT = FormatReader::Read(pCurrentType);
+        }
+        MT = FormatReader::Read(pCurrentType.Get());
     }
 err:
-    SafeRelease(&pPD);
-    SafeRelease(&pSD);
-    SafeRelease(&pHandler);
-    SafeRelease(&pCurrentType);
     unsigned int sizeRawImage = 0;
     if(VideoFormat == MFVideoFormat_RGB24)
     {
@@ -910,17 +981,17 @@ err:
     // Configure the media type that the Sample Grabber will receive.
     // Setting the major and subtype is usually enough for the topology loader
     // to resolve the topology.
-    CHECK_HR(hr = MFCreateMediaType(&pType));
+    CHECK_HR(hr = MFCreateMediaType(pType.GetAddressOf()));
     CHECK_HR(hr = pType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video));
     CHECK_HR(hr = pType->SetGUID(MF_MT_SUBTYPE, VideoFormat));
     // Create the sample grabber sink.
-    CHECK_HR(hr = MFCreateSampleGrabberSinkActivate(pType, this, &pSinkActivate));
+    CHECK_HR(hr = MFCreateSampleGrabberSinkActivate(pType.Get(), this, pSinkActivate.GetAddressOf()));
     // To run as fast as possible, set this attribute (requires Windows 7):
     CHECK_HR(hr = pSinkActivate->SetUINT32(MF_SAMPLEGRABBERSINK_IGNORE_CLOCK, TRUE));
     // Create the Media Session.
     CHECK_HR(hr = MFCreateMediaSession(NULL, &ig_pSession));
     // Create the topology.
-    CHECK_HR(hr = CreateTopology(pSource, pSinkActivate, &ig_pTopology));
+    CHECK_HR(hr = CreateTopology(pSource, pSinkActivate.Get(), &ig_pTopology));
 done:
     // Clean up.
     if (FAILED(hr))
@@ -932,10 +1003,10 @@ done:
         SafeRelease(&ig_pSession);
         SafeRelease(&ig_pTopology);
     }
-    SafeRelease(&pSinkActivate);
-    SafeRelease(&pType);
+
     return hr;
 }
+
 void ImageGrabber::stopGrabbing()
 {
     if(ig_pSession)
@@ -943,16 +1014,17 @@ void ImageGrabber::stopGrabbing()
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Stopping of of grabbing of images\n", ig_DeviceID);
 }
+
 HRESULT ImageGrabber::startGrabbing(void)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-    IMFMediaEvent *pEvent = NULL;
+    ComPtr<IMFMediaEvent> pEvent = NULL;
     PROPVARIANT var;
     PropVariantInit(&var);
     HRESULT hr = S_OK;
-    CHECK_HR(hr = ig_pSession->SetTopology(0, ig_pTopology));
-    CHECK_HR(hr = ig_pSession->Start(&GUID_NULL, &var));
+    hr = ig_pSession->SetTopology(0, ig_pTopology);
     DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Start Grabbing of the images\n", ig_DeviceID);
+    hr = ig_pSession->Start(&GUID_NULL, &var);
     for(;;)
     {
         HRESULT hrStatus = S_OK;
@@ -992,27 +1064,41 @@ HRESULT ImageGrabber::startGrabbing(void)
             DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MEVideoCaptureDeviceRemoved \n", ig_DeviceID);
             break;
         }
-        SafeRelease(&pEvent);
+        if ((met == MEError) || (met == MENonFatalError))
+        {
+            pEvent->GetStatus(&hrStatus);
+            DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MEError | MENonFatalError: %u\n", ig_DeviceID, hrStatus);
+            break;
+        }
     }
     DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Finish startGrabbing \n", ig_DeviceID);
+
 done:
-    SafeRelease(&pEvent);
-    SafeRelease(&ig_pSession);
-    SafeRelease(&ig_pTopology);
+    SetEvent(ig_hFinish);
+
     return hr;
 }
+
+void ImageGrabber::pauseGrabbing()
+{
+}
+
+void ImageGrabber::resumeGrabbing()
+{
+}
+
 HRESULT ImageGrabber::CreateTopology(IMFMediaSource *pSource, IMFActivate *pSinkActivate, IMFTopology **ppTopo)
 {
-    IMFTopology *pTopology = NULL;
-    IMFPresentationDescriptor *pPD = NULL;
-    IMFStreamDescriptor *pSD = NULL;
-    IMFMediaTypeHandler *pHandler = NULL;
-    IMFTopologyNode *pNode1 = NULL;
-    IMFTopologyNode *pNode2 = NULL;
+    IMFTopologypTopology = NULL;
+    ComPtr<IMFPresentationDescriptor> pPD = NULL;
+    ComPtr<IMFStreamDescriptor> pSD = NULL;
+    ComPtr<IMFMediaTypeHandler> pHandler = NULL;
+    ComPtr<IMFTopologyNode> pNode1 = NULL;
+    ComPtr<IMFTopologyNode> pNode2 = NULL;
     HRESULT hr = S_OK;
     DWORD cStreams = 0;
     CHECK_HR(hr = MFCreateTopology(&pTopology));
-    CHECK_HR(hr = pSource->CreatePresentationDescriptor(&pPD));
+    CHECK_HR(hr = pSource->CreatePresentationDescriptor(pPD.GetAddressOf()));
     CHECK_HR(hr = pPD->GetStreamDescriptorCount(&cStreams));
     for (DWORD i = 0; i < cStreams; i++)
     {
@@ -1024,29 +1110,23 @@ HRESULT ImageGrabber::CreateTopology(IMFMediaSource *pSource, IMFActivate *pSink
         CHECK_HR(hr = pHandler->GetMajorType(&majorType));
         if (majorType == MFMediaType_Video && fSelected)
         {
-            CHECK_HR(hr = AddSourceNode(pTopology, pSource, pPD, pSD, &pNode1));
-            CHECK_HR(hr = AddOutputNode(pTopology, pSinkActivate, 0, &pNode2));
-            CHECK_HR(hr = pNode1->ConnectOutput(0, pNode2, 0));
+            CHECK_HR(hr = AddSourceNode(pTopology, pSource, pPD.Get(), pSD.Get(), pNode1.GetAddressOf()));
+            CHECK_HR(hr = AddOutputNode(pTopology, pSinkActivate, 0, pNode2.GetAddressOf()));
+            CHECK_HR(hr = pNode1->ConnectOutput(0, pNode2.Get(), 0));
             break;
         }
         else
         {
             CHECK_HR(hr = pPD->DeselectStream(i));
         }
-        SafeRelease(&pSD);
-        SafeRelease(&pHandler);
     }
     *ppTopo = pTopology;
     (*ppTopo)->AddRef();
+
 done:
-    SafeRelease(&pTopology);
-    SafeRelease(&pNode1);
-    SafeRelease(&pNode2);
-    SafeRelease(&pPD);
-    SafeRelease(&pSD);
-    SafeRelease(&pHandler);
     return hr;
 }
+
 HRESULT ImageGrabber::AddSourceNode(
     IMFTopology *pTopology,           // Topology.
     IMFMediaSource *pSource,          // Media source.
@@ -1054,43 +1134,45 @@ HRESULT ImageGrabber::AddSourceNode(
     IMFStreamDescriptor *pSD,         // Stream descriptor.
     IMFTopologyNode **ppNode)         // Receives the node pointer.
 {
-    IMFTopologyNode *pNode = NULL;
+    ComPtr<IMFTopologyNode> pNode = NULL;
     HRESULT hr = S_OK;
-    CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &pNode));
+    CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, pNode.GetAddressOf()));
     CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_SOURCE, pSource));
     CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, pPD));
     CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, pSD));
-    CHECK_HR(hr = pTopology->AddNode(pNode));
+    CHECK_HR(hr = pTopology->AddNode(pNode.Get()));
     // Return the pointer to the caller.
-    *ppNode = pNode;
+    *ppNode = pNode.Get();
     (*ppNode)->AddRef();
+
 done:
-    SafeRelease(&pNode);
     return hr;
 }
+
 HRESULT ImageGrabber::AddOutputNode(
     IMFTopology *pTopology,     // Topology.
     IMFActivate *pActivate,     // Media sink activation object.
     DWORD dwId,                 // Identifier of the stream sink.
     IMFTopologyNode **ppNode)   // Receives the node pointer.
 {
-    IMFTopologyNode *pNode = NULL;
+    ComPtr<IMFTopologyNode> pNode = NULL;
     HRESULT hr = S_OK;
-    CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &pNode));
+    CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, pNode.GetAddressOf()));
     CHECK_HR(hr = pNode->SetObject(pActivate));
     CHECK_HR(hr = pNode->SetUINT32(MF_TOPONODE_STREAMID, dwId));
     CHECK_HR(hr = pNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE));
-    CHECK_HR(hr = pTopology->AddNode(pNode));
+    CHECK_HR(hr = pTopology->AddNode(pNode.Get()));
     // Return the pointer to the caller.
-    *ppNode = pNode;
+    *ppNode = pNode.Get();
     (*ppNode)->AddRef();
+
 done:
-    SafeRelease(&pNode);
     return hr;
 }
-HRESULT ImageGrabber::CreateInstance(ImageGrabber **ppIG, unsigned int deviceID)
+
+HRESULT ImageGrabber::CreateInstance(ImageGrabber **ppIG, unsigned int deviceID, bool synchronious)
 {
-    *ppIG = new (std::nothrow) ImageGrabber(deviceID);
+    *ppIG = new (std::nothrow) ImageGrabber(deviceID, synchronious);
     if (ppIG == NULL)
     {
         return E_OUTOFMEMORY;
@@ -1099,6 +1181,7 @@ HRESULT ImageGrabber::CreateInstance(ImageGrabber **ppIG, unsigned int deviceID)
     DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Creating instance of ImageGrabber\n", deviceID);
     return S_OK;
 }
+
 STDMETHODIMP ImageGrabber::QueryInterface(REFIID riid, void** ppv)
 {
     HRESULT hr = E_NOINTERFACE;
@@ -1119,10 +1202,12 @@ STDMETHODIMP ImageGrabber::QueryInterface(REFIID riid, void** ppv)
     }
     return hr;
 }
+
 STDMETHODIMP_(ULONG) ImageGrabber::AddRef()
 {
     return InterlockedIncrement(&m_cRef);
 }
+
 STDMETHODIMP_(ULONG) ImageGrabber::Release()
 {
     ULONG cRef = InterlockedDecrement(&m_cRef);
@@ -1132,38 +1217,45 @@ STDMETHODIMP_(ULONG) ImageGrabber::Release()
     }
     return cRef;
 }
+
 STDMETHODIMP ImageGrabber::OnClockStart(MFTIME hnsSystemTime, LONGLONG llClockStartOffset)
 {
     (void)hnsSystemTime;
     (void)llClockStartOffset;
     return S_OK;
 }
+
 STDMETHODIMP ImageGrabber::OnClockStop(MFTIME hnsSystemTime)
 {
     (void)hnsSystemTime;
     return S_OK;
 }
+
 STDMETHODIMP ImageGrabber::OnClockPause(MFTIME hnsSystemTime)
 {
     (void)hnsSystemTime;
     return S_OK;
 }
+
 STDMETHODIMP ImageGrabber::OnClockRestart(MFTIME hnsSystemTime)
 {
     (void)hnsSystemTime;
     return S_OK;
 }
+
 STDMETHODIMP ImageGrabber::OnClockSetRate(MFTIME hnsSystemTime, float flRate)
 {
     (void)flRate;
     (void)hnsSystemTime;
     return S_OK;
 }
+
 STDMETHODIMP ImageGrabber::OnSetPresentationClock(IMFPresentationClock* pClock)
 {
     (void)pClock;
     return S_OK;
 }
+
 STDMETHODIMP ImageGrabber::OnProcessSample(REFGUID guidMajorMediaType, DWORD dwSampleFlags,
     LONGLONG llSampleTime, LONGLONG llSampleDuration, const BYTE * pSampleBuffer,
     DWORD dwSampleSize)
@@ -1173,6 +1265,16 @@ STDMETHODIMP ImageGrabber::OnProcessSample(REFGUID guidMajorMediaType, DWORD dwS
     (void)dwSampleFlags;
     (void)llSampleDuration;
     (void)dwSampleSize;
+
+    HANDLE tmp[] = {ig_hFinish, ig_hFrameGrabbed, NULL};
+
+    DWORD status = WaitForMultipleObjects(2, tmp, FALSE, INFINITE);
+    if (status == WAIT_OBJECT_0)
+    {
+        printf("OnProcessFrame called after ig_hFinish event\n");
+        return S_OK;
+    }
+
     if(ig_RIE)
     {
         ig_RIFirst->fastCopy(pSampleBuffer);
@@ -1183,27 +1285,41 @@ STDMETHODIMP ImageGrabber::OnProcessSample(REFGUID guidMajorMediaType, DWORD dwS
         ig_RISecond->fastCopy(pSampleBuffer);
         ig_RIOut = ig_RISecond;
     }
-    ig_RIE = !ig_RIE;
+
+    if (ig_Synchronous)
+    {
+        SetEvent(ig_hFrameReady);
+    }
+    else
+    {
+        ig_RIE = !ig_RIE;
+    }
+
     return S_OK;
 }
+
 STDMETHODIMP ImageGrabber::OnShutdown()
 {
+    SetEvent(ig_hFinish);
     return S_OK;
 }
+
 RawImage *ImageGrabber::getRawImage()
 {
     return ig_RIOut;
 }
+
 DWORD WINAPI MainThreadFunction( LPVOID lpParam )
 {
     ImageGrabberThread *pIGT = (ImageGrabberThread *)lpParam;
     pIGT->run();
     return 0;
 }
-HRESULT ImageGrabberThread::CreateInstance(ImageGrabberThread **ppIGT, IMFMediaSource *pSource, unsigned int deviceID)
+
+HRESULT ImageGrabberThread::CreateInstance(ImageGrabberThread **ppIGT, IMFMediaSource *pSource, unsigned int deviceID, bool synchronious)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-    *ppIGT = new (std::nothrow) ImageGrabberThread(pSource, deviceID);
+    *ppIGT = new (std::nothrow) ImageGrabberThread(pSource, deviceID, synchronious);
     if (ppIGT == NULL)
     {
         DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Memory cannot be allocated\n", deviceID);
@@ -1213,10 +1329,14 @@ HRESULT ImageGrabberThread::CreateInstance(ImageGrabberThread **ppIGT, IMFMediaS
         DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Creating of the instance of ImageGrabberThread\n", deviceID);
     return S_OK;
 }
-ImageGrabberThread::ImageGrabberThread(IMFMediaSource *pSource, unsigned int deviceID): igt_Handle(NULL), igt_stop(false)
+
+ImageGrabberThread::ImageGrabberThread(IMFMediaSource *pSource, unsigned int deviceID, bool synchronious):
+    igt_func(NULL),
+    igt_Handle(NULL),
+    igt_stop(false)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
-    HRESULT hr = ImageGrabber::CreateInstance(&igt_pImageGrabber, deviceID);
+    HRESULT hr = ImageGrabber::CreateInstance(&igt_pImageGrabber, deviceID, synchronious);
     igt_DeviceID = deviceID;
     if(SUCCEEDED(hr))
     {
@@ -1235,6 +1355,7 @@ ImageGrabberThread::ImageGrabberThread(IMFMediaSource *pSource, unsigned int dev
         DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i There is a problem with creation of the instance of the ImageGrabber class\n", deviceID);
     }
 }
+
 void ImageGrabberThread::setEmergencyStopEvent(void *userData, void(*func)(int, void *))
 {
     if(func)
@@ -1243,12 +1364,16 @@ void ImageGrabberThread::setEmergencyStopEvent(void *userData, void(*func)(int,
         igt_userData = userData;
     }
 }
+
 ImageGrabberThread::~ImageGrabberThread(void)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Destroing ImageGrabberThread\n", igt_DeviceID);
+    if (igt_Handle)
+        WaitForSingleObject(igt_Handle, INFINITE);
     delete igt_pImageGrabber;
 }
+
 void ImageGrabberThread::stop()
 {
     igt_stop = true;
@@ -1257,16 +1382,18 @@ void ImageGrabberThread::stop()
         igt_pImageGrabber->stopGrabbing();
     }
 }
+
 void ImageGrabberThread::start()
 {
     igt_Handle = CreateThread(
-            NULL,                   // default security attributes
-            0,                      // use default stack size
-            MainThreadFunction,       // thread function name
-            this,          // argument to thread function
-            0,                      // use default creation flags
+            NULL,                  // default security attributes
+            0,                     // use default stack size
+            MainThreadFunction,    // thread function name
+            this,                  // argument to thread function
+            0,                     // use default creation flags
             &igt_ThreadIdArray);   // returns the thread identifier
 }
+
 void ImageGrabberThread::run()
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
@@ -1294,10 +1421,12 @@ void ImageGrabberThread::run()
     else
         DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Finish thread\n", igt_DeviceID);
 }
+
 ImageGrabber *ImageGrabberThread::getImageGrabber()
 {
     return igt_pImageGrabber;
 }
+
 Media_Foundation::Media_Foundation(void)
 {
     HRESULT hr = MFStartup(MF_VERSION);
@@ -1307,6 +1436,7 @@ Media_Foundation::Media_Foundation(void)
         DPO->printOut(L"MEDIA FOUNDATION: It cannot be created!!!\n");
     }
 }
+
 Media_Foundation::~Media_Foundation(void)
 {
     HRESULT hr = MFShutdown();
@@ -1316,12 +1446,13 @@ Media_Foundation::~Media_Foundation(void)
         DPO->printOut(L"MEDIA FOUNDATION: Resources cannot be released\n");
     }
 }
+
 bool Media_Foundation::buildListOfDevices()
 {
     HRESULT hr = S_OK;
-    IMFAttributes *pAttributes = NULL;
+    ComPtr<IMFAttributes> pAttributes = NULL;
     CoInitialize(NULL);
-    hr = MFCreateAttributes(&pAttributes, 1);
+    hr = MFCreateAttributes(pAttributes.GetAddressOf(), 1);
     if (SUCCEEDED(hr))
     {
         hr = pAttributes->SetGUID(
@@ -1332,40 +1463,46 @@ bool Media_Foundation::buildListOfDevices()
     if (SUCCEEDED(hr))
     {
         videoDevices *vDs = &videoDevices::getInstance();
-        hr = vDs->initDevices(pAttributes);
+        hr = vDs->initDevices(pAttributes.Get());
     }
     else
     {
        DebugPrintOut *DPO = &DebugPrintOut::getInstance();
        DPO->printOut(L"MEDIA FOUNDATION: The access to the video cameras denied\n");
     }
-    SafeRelease(&pAttributes);
+
     return (SUCCEEDED(hr));
 }
+
 Media_Foundation& Media_Foundation::getInstance()
 {
     static Media_Foundation instance;
     return instance;
 }
+
 RawImage::RawImage(unsigned int size): ri_new(false), ri_pixels(NULL)
 {
     ri_size = size;
     ri_pixels = new unsigned char[size];
     memset((void *)ri_pixels,0,ri_size);
 }
+
 bool RawImage::isNew()
 {
     return ri_new;
 }
+
 unsigned int RawImage::getSize()
 {
     return ri_size;
 }
+
 RawImage::~RawImage(void)
 {
     delete []ri_pixels;
     ri_pixels = NULL;
 }
+
 long RawImage::CreateInstance(RawImage **ppRImage,unsigned int size)
 {
     *ppRImage = new (std::nothrow) RawImage(size);
@@ -1375,25 +1512,30 @@ long RawImage::CreateInstance(RawImage **ppRImage,unsigned int size)
     }
     return S_OK;
 }
+
 void RawImage::setCopy(const BYTE * pSampleBuffer)
 {
     memcpy(ri_pixels, pSampleBuffer, ri_size);
     ri_new = true;
 }
+
 void RawImage::fastCopy(const BYTE * pSampleBuffer)
 {
     memcpy(ri_pixels, pSampleBuffer, ri_size);
     ri_new = true;
 }
+
 unsigned char * RawImage::getpPixels()
 {
     ri_new = false;
     return ri_pixels;
 }
+
 videoDevice::videoDevice(void): vd_IsSetuped(false), vd_LockOut(OpenLock), vd_pFriendlyName(NULL),
     vd_Width(0), vd_Height(0), vd_pSource(NULL), vd_func(NULL), vd_userData(NULL)
 {
 }
+
 void videoDevice::setParametrs(CamParametrs parametrs)
 {
     if(vd_IsSetuped)
@@ -1428,6 +1570,7 @@ void videoDevice::setParametrs(CamParametrs parametrs)
         }
     }
 }
+
 CamParametrs videoDevice::getParametrs()
 {
     CamParametrs out;
@@ -1472,6 +1615,7 @@ CamParametrs videoDevice::getParametrs()
     }
     return out;
 }
+
 long videoDevice::resetDevice(IMFActivate *pActivate)
 {
     HRESULT hr = -1;
@@ -1503,6 +1647,7 @@ long videoDevice::resetDevice(IMFActivate *pActivate)
     }
     return hr;
 }
+
 long videoDevice::readInfoOfDevice(IMFActivate *pActivate, unsigned int Num)
 {
     HRESULT hr = -1;
@@ -1510,6 +1655,7 @@ long videoDevice::readInfoOfDevice(IMFActivate *pActivate, unsigned int Num)
     hr = resetDevice(pActivate);
     return hr;
 }
+
 long videoDevice::checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice)
 {
     HRESULT hr = S_OK;
@@ -1568,14 +1714,15 @@ long videoDevice::checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice)
     }
     return hr;
 }
+
 long videoDevice::initDevice()
 {
     HRESULT hr = -1;
-    IMFAttributes *pAttributes = NULL;
-    IMFActivate * vd_pActivate= NULL;
+    ComPtr<IMFAttributes> pAttributes = NULL;
+    IMFActivate *vd_pActivate = NULL;
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     CoInitialize(NULL);
-    hr = MFCreateAttributes(&pAttributes, 1);
+    hr = MFCreateAttributes(pAttributes.GetAddressOf(), 1);
     if (SUCCEEDED(hr))
     {
         hr = pAttributes->SetGUID(
@@ -1585,7 +1732,7 @@ long videoDevice::initDevice()
     }
     if (SUCCEEDED(hr))
     {
-        hr = checkDevice(pAttributes, &vd_pActivate);
+        hr = checkDevice(pAttributes.Get(), &vd_pActivate);
         if (SUCCEEDED(hr) && vd_pActivate)
         {
             SafeRelease(&vd_pSource);
@@ -1607,9 +1754,10 @@ long videoDevice::initDevice()
     {
         DPO->printOut(L"VIDEODEVICE %i: The attribute of video cameras cannot be getting \n", vd_CurrentNumber);
     }
-    SafeRelease(&pAttributes);
+
     return hr;
 }
+
 MediaType videoDevice::getFormat(unsigned int id)
 {
     if(id < vd_CurrentFormats.size())
@@ -1713,6 +1861,7 @@ int videoDevice::findType(unsigned int size, unsigned int frameRate)
         return 0;
     return VN[0];
 }
+
 void videoDevice::buildLibraryofTypes()
 {
     unsigned int size;
@@ -1722,7 +1871,7 @@ void videoDevice::buildLibraryofTypes()
     for(; i != vd_CurrentFormats.end(); i++)
     {
         size = (*i).MF_MT_FRAME_SIZE;
-        framerate = (*i).MF_MT_FRAME_RATE;
+        framerate = (*i).MF_MT_FRAME_RATE_NUMERATOR;
         FrameRateMap FRM = vd_CaptureFormats[size];
         SUBTYPEMap STM = FRM[framerate];
         String subType((*i).pMF_MT_SUBTYPEName);
@@ -1734,45 +1883,45 @@ void videoDevice::buildLibraryofTypes()
         count++;
     }
 }
+
 long videoDevice::setDeviceFormat(IMFMediaSource *pSource, unsigned long  dwFormatIndex)
 {
-    IMFPresentationDescriptor *pPD = NULL;
-    IMFStreamDescriptor *pSD = NULL;
-    IMFMediaTypeHandler *pHandler = NULL;
-    IMFMediaType *pType = NULL;
-    HRESULT hr = pSource->CreatePresentationDescriptor(&pPD);
+    ComPtr<IMFPresentationDescriptor> pPD = NULL;
+    ComPtr<IMFStreamDescriptor> pSD = NULL;
+    ComPtr<IMFMediaTypeHandler> pHandler = NULL;
+    ComPtr<IMFMediaType> pType = NULL;
+    HRESULT hr = pSource->CreatePresentationDescriptor(pPD.GetAddressOf());
     if (FAILED(hr))
     {
         goto done;
     }
     BOOL fSelected;
-    hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, &pSD);
+    hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, pSD.GetAddressOf());
     if (FAILED(hr))
     {
         goto done;
     }
-    hr = pSD->GetMediaTypeHandler(&pHandler);
+    hr = pSD->GetMediaTypeHandler(pHandler.GetAddressOf());
     if (FAILED(hr))
     {
         goto done;
     }
-    hr = pHandler->GetMediaTypeByIndex((DWORD)dwFormatIndex, &pType);
+    hr = pHandler->GetMediaTypeByIndex((DWORD)dwFormatIndex, pType.GetAddressOf());
     if (FAILED(hr))
     {
         goto done;
     }
-    hr = pHandler->SetCurrentMediaType(pType);
+    hr = pHandler->SetCurrentMediaType(pType.Get());
+
 done:
-    SafeRelease(&pPD);
-    SafeRelease(&pSD);
-    SafeRelease(&pHandler);
-    SafeRelease(&pType);
     return hr;
 }
+
 bool videoDevice::isDeviceSetup()
 {
     return vd_IsSetuped;
 }
+
 RawImage * videoDevice::getRawImageOut()
 {
     if(!vd_IsSetuped) return NULL;
@@ -1785,6 +1934,7 @@ RawImage * videoDevice::getRawImageOut()
     }
     return NULL;
 }
+
 bool videoDevice::isFrameNew()
 {
     if(!vd_IsSetuped) return false;
@@ -1809,16 +1959,19 @@ bool videoDevice::isFrameNew()
     }
     return false;
 }
+
 bool videoDevice::isDeviceMediaSource()
 {
     if(vd_LockOut == MediaSourceLock) return true;
     return false;
 }
+
 bool videoDevice::isDeviceRawDataSource()
 {
     if(vd_LockOut == RawDataLock) return true;
     return false;
 }
+
 bool videoDevice::setupDevice(unsigned int id)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
@@ -1849,15 +2002,18 @@ bool videoDevice::setupDevice(unsigned int id)
         return false;
     }
 }
+
 bool videoDevice::setupDevice(unsigned int w, unsigned int h, unsigned int idealFramerate)
 {
     unsigned int id = findType(w * h, idealFramerate);
     return setupDevice(id);
 }
+
 wchar_t *videoDevice::getName()
 {
     return vd_pFriendlyName;
 }
+
 videoDevice::~videoDevice(void)
 {
     closeDevice();
@@ -1865,24 +2021,25 @@ videoDevice::~videoDevice(void)
     if(vd_pFriendlyName)
         CoTaskMemFree(vd_pFriendlyName);
 }
-long videoDevice::enumerateCaptureFormats(IMFMediaSource *pSource)
+
+HRESULT videoDevice::enumerateCaptureFormats(IMFMediaSource *pSource)
 {
-    IMFPresentationDescriptor *pPD = NULL;
-    IMFStreamDescriptor *pSD = NULL;
-    IMFMediaTypeHandler *pHandler = NULL;
-    IMFMediaType *pType = NULL;
-    HRESULT hr = pSource->CreatePresentationDescriptor(&pPD);
+    ComPtr<IMFPresentationDescriptor> pPD = NULL;
+    ComPtr<IMFStreamDescriptor> pSD = NULL;
+    ComPtr<IMFMediaTypeHandler> pHandler = NULL;
+    ComPtr<IMFMediaType> pType = NULL;
+    HRESULT hr = pSource->CreatePresentationDescriptor(pPD.GetAddressOf());
     if (FAILED(hr))
     {
         goto done;
     }
     BOOL fSelected;
-    hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, &pSD);
+    hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, pSD.GetAddressOf());
     if (FAILED(hr))
     {
         goto done;
     }
-    hr = pSD->GetMediaTypeHandler(&pHandler);
+    hr = pSD->GetMediaTypeHandler(pHandler.GetAddressOf());
     if (FAILED(hr))
     {
         goto done;
@@ -1895,24 +2052,22 @@ long videoDevice::enumerateCaptureFormats(IMFMediaSource *pSource)
     }
     for (DWORD i = 0; i < cTypes; i++)
     {
-        hr = pHandler->GetMediaTypeByIndex(i, &pType);
+        hr = pHandler->GetMediaTypeByIndex(i, pType.GetAddressOf());
         if (FAILED(hr))
         {
             goto done;
         }
-        MediaType MT = FormatReader::Read(pType);
+        MediaType MT = FormatReader::Read(pType.Get());
         vd_CurrentFormats.push_back(MT);
-        SafeRelease(&pType);
     }
+
 done:
-    SafeRelease(&pPD);
-    SafeRelease(&pSD);
-    SafeRelease(&pHandler);
-    SafeRelease(&pType);
     return hr;
 }
+
 videoDevices::videoDevices(void): count(0)
 {}
+
 void videoDevices::clearDevices()
 {
     std::vector<videoDevice *>::iterator i = vds_Devices.begin();
@@ -1920,10 +2075,12 @@ void videoDevices::clearDevices()
         delete (*i);
     vds_Devices.clear();
 }
+
 videoDevices::~videoDevices(void)
 {
     clearDevices();
 }
+
 videoDevice * videoDevices::getDevice(unsigned int i)
 {
     if(i >= vds_Devices.size())
@@ -1936,6 +2093,7 @@ videoDevice * videoDevices::getDevice(unsigned int i)
     }
     return vds_Devices[i];
 }
+
 long videoDevices::initDevices(IMFAttributes *pAttributes)
 {
     HRESULT hr = S_OK;
@@ -1965,15 +2123,18 @@ long videoDevices::initDevices(IMFAttributes *pAttributes)
     }
     return hr;
 }
-size_t videoDevices::getCount()
+
+unsigned int videoDevices::getCount()
 {
     return vds_Devices.size();
 }
+
 videoDevices& videoDevices::getInstance()
 {
     static videoDevices instance;
     return instance;
 }
+
 Parametr::Parametr()
 {
     CurrentValue = 0;
@@ -1983,6 +2144,7 @@ Parametr::Parametr()
     Default = 0;
     Flag = 0;
 }
+
 MediaType::MediaType()
 {
     pMF_MT_AM_FORMAT_TYPEName = NULL;
@@ -1990,10 +2152,12 @@ MediaType::MediaType()
     pMF_MT_SUBTYPEName = NULL;
     Clear();
 }
+
 MediaType::~MediaType()
 {
     Clear();
 }
+
 void MediaType::Clear()
 {
     MF_MT_FRAME_SIZE = 0;
@@ -2005,8 +2169,8 @@ void MediaType::Clear()
     MF_MT_VIDEO_CHROMA_SITING = 0;
     MF_MT_FIXED_SIZE_SAMPLES = 0;
     MF_MT_VIDEO_NOMINAL_RANGE = 0;
-    MF_MT_FRAME_RATE = 0;
-    MF_MT_FRAME_RATE_low = 0;
+    MF_MT_FRAME_RATE_NUMERATOR = 0;
+    MF_MT_FRAME_RATE_DENOMINATOR = 0;
     MF_MT_PIXEL_ASPECT_RATIO = 0;
     MF_MT_PIXEL_ASPECT_RATIO_low = 0;
     MF_MT_ALL_SAMPLES_INDEPENDENT = 0;
@@ -2021,6 +2185,7 @@ void MediaType::Clear()
     memset(&MF_MT_AM_FORMAT_TYPE, 0, sizeof(GUID));
     memset(&MF_MT_SUBTYPE, 0, sizeof(GUID));
 }
+
 videoInput::videoInput(void): accessToDevices(false)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
@@ -2029,6 +2194,7 @@ videoInput::videoInput(void): accessToDevices(false)
     if(!accessToDevices)
         DPO->printOut(L"INITIALIZATION: Ther is not any suitable video device\n");
 }
+
 void videoInput::updateListOfDevices()
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
@@ -2037,11 +2203,13 @@ void videoInput::updateListOfDevices()
     if(!accessToDevices)
         DPO->printOut(L"UPDATING: Ther is not any suitable video device\n");
 }
+
 videoInput::~videoInput(void)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     DPO->printOut(L"\n***** CLOSE VIDEOINPUT LIBRARY - 2013 *****\n\n");
 }
+
 IMFMediaSource *videoInput::getMediaSource(int deviceID)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
@@ -2063,6 +2231,7 @@ IMFMediaSource *videoInput::getMediaSource(int deviceID)
     }
     return NULL;
 }
+
 bool videoInput::setupDevice(int deviceID, unsigned int id)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
@@ -2089,6 +2258,7 @@ bool videoInput::setupDevice(int deviceID, unsigned int id)
     }
     return false;
 }
+
 bool videoInput::setupDevice(int deviceID, unsigned int w, unsigned int h, unsigned int idealFramerate)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
@@ -2115,6 +2285,7 @@ bool videoInput::setupDevice(int deviceID, unsigned int w, unsigned int h, unsig
     }
     return false;
 }
+
 MediaType videoInput::getFormat(int deviceID, unsigned int id)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
@@ -2136,6 +2307,7 @@ MediaType videoInput::getFormat(int deviceID, unsigned int id)
     }
     return MediaType();
 }
+
 bool videoInput::isDeviceSetup(int deviceID)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
@@ -2157,6 +2329,7 @@ bool videoInput::isDeviceSetup(int deviceID)
     }
     return false;
 }
+
 bool videoInput::isDeviceMediaSource(int deviceID)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
@@ -2178,6 +2351,7 @@ bool videoInput::isDeviceMediaSource(int deviceID)
     }
     return false;
 }
+
 bool videoInput::isDeviceRawDataSource(int deviceID)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
@@ -2202,6 +2376,7 @@ bool videoInput::isDeviceRawDataSource(int deviceID)
     }
     return false;
 }
+
 bool videoInput::isFrameNew(int deviceID)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
@@ -2230,6 +2405,7 @@ bool videoInput::isFrameNew(int deviceID)
     }
     return false;
 }
+
 unsigned int videoInput::getCountFormats(int deviceID)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
@@ -2251,12 +2427,14 @@ unsigned int videoInput::getCountFormats(int deviceID)
     }
     return 0;
 }
+
 void videoInput::closeAllDevices()
 {
     videoDevices *VDS = &videoDevices::getInstance();
     for(unsigned int i = 0; i < VDS->getCount(); i++)
         closeDevice(i);
 }
+
 void videoInput::setParametrs(int deviceID, CamParametrs parametrs)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
@@ -2277,6 +2455,7 @@ void videoInput::setParametrs(int deviceID, CamParametrs parametrs)
         DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
     }
 }
+
 CamParametrs videoInput::getParametrs(int deviceID)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
@@ -2299,6 +2478,7 @@ CamParametrs videoInput::getParametrs(int deviceID)
     }
     return out;
 }
+
 void videoInput::closeDevice(int deviceID)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
@@ -2319,6 +2499,7 @@ void videoInput::closeDevice(int deviceID)
         DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
     }
 }
+
 unsigned int videoInput::getWidth(int deviceID)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
@@ -2340,6 +2521,7 @@ unsigned int videoInput::getWidth(int deviceID)
     }
     return 0;
 }
+
 unsigned int videoInput::getHeight(int deviceID)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
@@ -2361,6 +2543,7 @@ unsigned int videoInput::getHeight(int deviceID)
     }
     return 0;
 }
+
 wchar_t *videoInput::getNameVideoDevice(int deviceID)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
@@ -2382,6 +2565,7 @@ wchar_t *videoInput::getNameVideoDevice(int deviceID)
     }
     return L"Empty";
 }
+
 unsigned int videoInput::listDevices(bool silent)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
@@ -2405,20 +2589,24 @@ unsigned int videoInput::listDevices(bool silent)
     }
     return out;
 }
+
 videoInput& videoInput::getInstance()
 {
     static videoInput instance;
     return instance;
 }
+
 bool videoInput::isDevicesAcceable()
 {
     return accessToDevices;
 }
+
 void videoInput::setVerbose(bool state)
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
     DPO->setVerbose(state);
 }
+
 void videoInput::setEmergencyStopEvent(int deviceID, void *userData, void(*func)(int, void *))
 {
     DebugPrintOut *DPO = &DebugPrintOut::getInstance();
@@ -2442,6 +2630,7 @@ void videoInput::setEmergencyStopEvent(int deviceID, void *userData, void(*func)
         DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
     }
 }
+
 bool videoInput::getPixels(int deviceID, unsigned char * dstBuffer, bool flipRedAndBlue, bool flipImage)
 {
     bool success = false;
@@ -2491,6 +2680,7 @@ bool videoInput::getPixels(int deviceID, unsigned char * dstBuffer, bool flipRed
     }
     return success;
 }
+
 void videoInput::processPixels(unsigned char * src, unsigned char * dst, unsigned int width,
                                 unsigned int height, unsigned int bpp, bool bRGB, bool bFlip)
 {
@@ -2553,6 +2743,7 @@ void videoInput::processPixels(unsigned char * src, unsigned char * dst, unsigne
     }
 }
 }
+
 /******* Capturing video from camera via Microsoft Media Foundation **********/
 class CvCaptureCAM_MSMF : public CvCapture
 {
@@ -2568,33 +2759,35 @@ public:
     virtual int getCaptureDomain() { return CV_CAP_MSMF; } // Return the type of the capture object: CV_CAP_VFW, etc...
 protected:
     void init();
-    int index, width, height,fourcc;
-    int widthSet, heightSet;
+    int index, width, height, fourcc;
     IplImage* frame;
     videoInput VI;
 };
+
 struct SuppressVideoInputMessages
 {
     SuppressVideoInputMessages() { videoInput::setVerbose(true); }
 };
+
 static SuppressVideoInputMessages do_it;
+
 CvCaptureCAM_MSMF::CvCaptureCAM_MSMF():
     index(-1),
     width(-1),
     height(-1),
     fourcc(-1),
-    widthSet(-1),
-    heightSet(-1),
-    frame(0),
+    frame(NULL),
     VI(videoInput::getInstance())
 {
     CoInitialize(0);
 }
+
 CvCaptureCAM_MSMF::~CvCaptureCAM_MSMF()
 {
     close();
     CoUninitialize();
 }
+
 void CvCaptureCAM_MSMF::close()
 {
     if( index >= 0 )
@@ -2603,8 +2796,9 @@ void CvCaptureCAM_MSMF::close()
         index = -1;
         cvReleaseImage(&frame);
     }
-    widthSet = heightSet = width = height = -1;
+    width = height = -1;
 }
+
 // Initialize camera input
 bool CvCaptureCAM_MSMF::open( int _index )
 {
@@ -2621,10 +2815,14 @@ bool CvCaptureCAM_MSMF::open( int _index )
     index = try_index;
     return true;
 }
+
 bool CvCaptureCAM_MSMF::grabFrame()
 {
-    return true;
+    while (VI.isDeviceSetup(index) && !VI.isFrameNew(index))
+        Sleep(1);
+    return VI.isDeviceSetup(index);
 }
+
 IplImage* CvCaptureCAM_MSMF::retrieveFrame(int)
 {
     if( !frame || (int)VI.getWidth(index) != frame->width || (int)VI.getHeight(index) != frame->height )
@@ -2637,6 +2835,7 @@ IplImage* CvCaptureCAM_MSMF::retrieveFrame(int)
     VI.getPixels( index, (uchar*)frame->imageData, false, true );
     return frame;
 }
+
 double CvCaptureCAM_MSMF::getProperty( int property_id )
 {
     // image format proprrties
@@ -2646,50 +2845,7 @@ double CvCaptureCAM_MSMF::getProperty( int property_id )
         return VI.getWidth(index);
     case CV_CAP_PROP_FRAME_HEIGHT:
         return VI.getHeight(index);
-    case CV_CAP_PROP_FOURCC:
-        // FIXME: implement method in VideoInput back end
-        //return VI.getFourcc(index);
-        ;
-    case CV_CAP_PROP_FPS:
-        // FIXME: implement method in VideoInput back end
-        //return VI.getFPS(index);
-        ;
-    }
-    // video filter properties
-    switch( property_id )
-    {
-    case CV_CAP_PROP_BRIGHTNESS:
-    case CV_CAP_PROP_CONTRAST:
-    case CV_CAP_PROP_HUE:
-    case CV_CAP_PROP_SATURATION:
-    case CV_CAP_PROP_SHARPNESS:
-    case CV_CAP_PROP_GAMMA:
-    case CV_CAP_PROP_MONOCROME:
-    case CV_CAP_PROP_WHITE_BALANCE_BLUE_U:
-    case CV_CAP_PROP_BACKLIGHT:
-    case CV_CAP_PROP_GAIN:
-        // FIXME: implement method in VideoInput back end
-        // if ( VI.getVideoSettingFilter(index, VI.getVideoPropertyFromCV(property_id), min_value,
-        //                               max_value, stepping_delta, current_value, flags,defaultValue) )
-        //     return (double)current_value;
-        return 0.;
-    }
-    // camera properties
-    switch( property_id )
-    {
-    case CV_CAP_PROP_PAN:
-    case CV_CAP_PROP_TILT:
-    case CV_CAP_PROP_ROLL:
-    case CV_CAP_PROP_ZOOM:
-    case CV_CAP_PROP_EXPOSURE:
-    case CV_CAP_PROP_IRIS:
-    case CV_CAP_PROP_FOCUS:
-    // FIXME: implement method in VideoInput back end
-    //     if (VI.getVideoSettingCamera(index,VI.getCameraPropertyFromCV(property_id),min_value,
-    //          max_value,stepping_delta,current_value,flags,defaultValue) ) return (double)current_value;
-        return 0.;
     }
-    // unknown parameter or value not available
     return -1;
 }
 bool CvCaptureCAM_MSMF::setProperty( int property_id, double value )
@@ -2706,91 +2862,272 @@ bool CvCaptureCAM_MSMF::setProperty( int property_id, double value )
         height = cvRound(value);
         handled = true;
         break;
-    case CV_CAP_PROP_FOURCC:
-        fourcc = (int)(unsigned long)(value);
-        if ( fourcc == -1 ) {
-            // following cvCreateVideo usage will pop up caprturepindialog here if fourcc=-1
-            // TODO - how to create a capture pin dialog
-        }
-        handled = true;
-        break;
-    case CV_CAP_PROP_FPS:
-        // FIXME: implement method in VideoInput back end
-        // int fps = cvRound(value);
-        // if (fps != VI.getFPS(index))
-        // {
-        //     VI.stopDevice(index);
-        //     VI.setIdealFramerate(index,fps);
-        //     if (widthSet > 0 && heightSet > 0)
-        //         VI.setupDevice(index, widthSet, heightSet);
-        //     else
-        //         VI.setupDevice(index);
-        // }
-        // return VI.isDeviceSetup(index);
-        ;
     }
+
     if ( handled ) {
-        // a stream setting
         if( width > 0 && height > 0 )
         {
-            if( width != (int)VI.getWidth(index) || height != (int)VI.getHeight(index) )//|| fourcc != VI.getFourcc(index) )
-            {
-                // FIXME: implement method in VideoInput back end
-                // int fps = static_cast<int>(VI.getFPS(index));
-                // VI.stopDevice(index);
-                // VI.setIdealFramerate(index, fps);
-                // VI.setupDeviceFourcc(index, width, height, fourcc);
-            }
-            bool success = VI.isDeviceSetup(index);
-            if (success)
+            if( width != (int)VI.getWidth(index) || height != (int)VI.getHeight(index)  && VI.isDeviceSetup(index))//|| fourcc != VI.getFourcc(index) )
             {
-                widthSet = width;
-                heightSet = height;
-                width = height = fourcc = -1;
+                VI.closeDevice(index);
+                VI.setupDevice(index, width, height);
             }
-            return success;
+            return VI.isDeviceSetup(index);
         }
         return true;
     }
-    // show video/camera filter dialog
+
+    return false;
+}
+
+class CvCaptureFile_MSMF : public CvCapture
+{
+public:
+    CvCaptureFile_MSMF();
+    virtual ~CvCaptureFile_MSMF();
+
+    virtual bool open( const char* filename );
+    virtual void close();
+
+    virtual double getProperty(int);
+    virtual bool setProperty(int, double);
+    virtual bool grabFrame();
+    virtual IplImage* retrieveFrame(int);
+    virtual int getCaptureDomain() { return CV_CAP_MSMF; }
+protected:
+    ImageGrabberThread* grabberThread;
+    IMFMediaSource* videoFileSource;
+    std::vector<MediaType> captureFormats;
+    int captureFormatIndex;
+    IplImage* frame;
+    bool isOpened;
+
+    HRESULT enumerateCaptureFormats(IMFMediaSource *pSource);
+    HRESULT getSourceDuration(IMFMediaSource *pSource, MFTIME *pDuration);
+};
+
+CvCaptureFile_MSMF::CvCaptureFile_MSMF():
+    grabberThread(NULL),
+    videoFileSource(NULL),
+    captureFormatIndex(0),
+    frame(NULL),
+    isOpened(false)
+{
+    MFStartup(MF_VERSION);
+}
+
+CvCaptureFile_MSMF::~CvCaptureFile_MSMF()
+{
+    close();
+    MFShutdown();
+}
+
+bool CvCaptureFile_MSMF::open(const char* filename)
+{
+    if (!filename)
+        return false;
+
+    wchar_t* unicodeFileName = new wchar_t[strlen(filename)+1];
+    MultiByteToWideChar(CP_ACP, 0, filename, -1, unicodeFileName, strlen(filename)+1);
+
+    HRESULT hr = S_OK;
+
+    MF_OBJECT_TYPE ObjectType = MF_OBJECT_INVALID;
+
+    ComPtr<IMFSourceResolver> pSourceResolver = NULL;
+    IUnknown* pUnkSource = NULL;
+
+    hr = MFCreateSourceResolver(pSourceResolver.GetAddressOf());
+
+    if (SUCCEEDED(hr))
+    {
+        hr = pSourceResolver->CreateObjectFromURL(
+            unicodeFileName,
+            MF_RESOLUTION_MEDIASOURCE,
+            NULL, // Optional property store.
+            &ObjectType,
+            &pUnkSource
+            );
+    }
+
+    // Get the IMFMediaSource from the IUnknown pointer.
+    if (SUCCEEDED(hr))
+    {
+        hr = pUnkSource->QueryInterface(IID_PPV_ARGS(&videoFileSource));
+    }
+
+    SafeRelease(&pUnkSource);
+
+    if (SUCCEEDED(hr))
+    {
+        hr = enumerateCaptureFormats(videoFileSource);
+    }
+
+    if (SUCCEEDED(hr))
+    {
+        hr = ImageGrabberThread::CreateInstance(&grabberThread, videoFileSource, (unsigned int)-2, true);
+    }
+
+    if (SUCCEEDED(hr))
+    {
+        grabberThread->start();
+    }
+
+    isOpened = SUCCEEDED(hr);
+
+    return isOpened;
+}
+
+void CvCaptureFile_MSMF::close()
+{
+    if (grabberThread)
+    {
+        isOpened = false;
+        SetEvent(grabberThread->getImageGrabber()->ig_hFinish);
+        grabberThread->stop();
+        delete grabberThread;
+    }
+
+    if (videoFileSource)
+    {
+        videoFileSource->Shutdown();
+    }
+}
+
+bool CvCaptureFile_MSMF::setProperty(int property_id, double value)
+{
+    // image capture properties
     // FIXME: implement method in VideoInput back end
-    // if ( property_id == CV_CAP_PROP_SETTINGS ) {
-    //     VI.showSettingsWindow(index);
-    //     return true;
-    // }
-    //video Filter properties
+    (void) property_id;
+    (void) value;
+    return false;
+}
+
+double CvCaptureFile_MSMF::getProperty(int property_id)
+{
+    // image format proprrties
     switch( property_id )
     {
-    case CV_CAP_PROP_BRIGHTNESS:
-    case CV_CAP_PROP_CONTRAST:
-    case CV_CAP_PROP_HUE:
-    case CV_CAP_PROP_SATURATION:
-    case CV_CAP_PROP_SHARPNESS:
-    case CV_CAP_PROP_GAMMA:
-    case CV_CAP_PROP_MONOCROME:
-    case CV_CAP_PROP_WHITE_BALANCE_BLUE_U:
-    case CV_CAP_PROP_BACKLIGHT:
-    case CV_CAP_PROP_GAIN:
-        // FIXME: implement method in VideoInput back end
-        //return VI.setVideoSettingFilter(index,VI.getVideoPropertyFromCV(property_id),(long)value);
-        ;
-    }
-    //camera properties
-    switch( property_id )
+    case CV_CAP_PROP_FRAME_WIDTH:
+        return captureFormats[captureFormatIndex].width;
+    case CV_CAP_PROP_FRAME_HEIGHT:
+        return captureFormats[captureFormatIndex].height;
+    case CV_CAP_PROP_FRAME_COUNT:
+        {
+            MFTIME duration;
+            getSourceDuration(this->videoFileSource, &duration);
+            double fps = ((double)captureFormats[captureFormatIndex].MF_MT_FRAME_RATE_NUMERATOR) /
+            ((double)captureFormats[captureFormatIndex].MF_MT_FRAME_RATE_DENOMINATOR);
+            return (double)floor(((double)duration/1e7)*fps+0.5);
+        }
+    case CV_CAP_PROP_FOURCC:
+        return captureFormats[captureFormatIndex].MF_MT_SUBTYPE.Data1;
+    case CV_CAP_PROP_FPS:
+        return ((double)captureFormats[captureFormatIndex].MF_MT_FRAME_RATE_NUMERATOR) /
+            ((double)captureFormats[captureFormatIndex].MF_MT_FRAME_RATE_DENOMINATOR);
+    }
+    return -1;
+}
+
+bool CvCaptureFile_MSMF::grabFrame()
+{
+    DWORD waitResult = (DWORD)-1;
+    if (isOpened)
     {
-    case CV_CAP_PROP_PAN:
-    case CV_CAP_PROP_TILT:
-    case CV_CAP_PROP_ROLL:
-    case CV_CAP_PROP_ZOOM:
-    case CV_CAP_PROP_EXPOSURE:
-    case CV_CAP_PROP_IRIS:
-    case CV_CAP_PROP_FOCUS:
-        // FIXME: implement method in VideoInput back end
-        //return VI.setVideoSettingCamera(index,VI.getCameraPropertyFromCV(property_id),(long)value);
-        ;
+        SetEvent(grabberThread->getImageGrabber()->ig_hFrameGrabbed);
+        HANDLE tmp[] = {grabberThread->getImageGrabber()->ig_hFrameReady, grabberThread->getImageGrabber()->ig_hFinish, 0};
+        waitResult = WaitForMultipleObjects(2, tmp, FALSE, INFINITE);
     }
-    return false;
+
+    return isOpened && grabberThread->getImageGrabber()->getRawImage()->isNew() && (waitResult == WAIT_OBJECT_0);
+}
+
+IplImage* CvCaptureFile_MSMF::retrieveFrame(int)
+{
+    unsigned int width = captureFormats[captureFormatIndex].width;
+    unsigned int height = captureFormats[captureFormatIndex].height;
+    unsigned int bytes = 3;
+    if( !frame || (int)width != frame->width || (int)height != frame->height )
+    {
+        if (frame)
+            cvReleaseImage( &frame );
+        frame = cvCreateImage( cvSize(width,height), 8, 3 );
+    }
+
+    RawImage *RIOut = grabberThread->getImageGrabber()->getRawImage();
+    unsigned int size = bytes * width * height;
+
+    bool verticalFlip = captureFormats[captureFormatIndex].MF_MT_DEFAULT_STRIDE < 0;
+
+    if(RIOut && size == RIOut->getSize())
+    {
+         videoInput::processPixels(RIOut->getpPixels(), (unsigned char*)frame->imageData, width, 
+             height, bytes, false, verticalFlip);
+    }
+
+    return frame;
 }
+
+HRESULT CvCaptureFile_MSMF::enumerateCaptureFormats(IMFMediaSource *pSource)
+{
+    ComPtr<IMFPresentationDescriptor> pPD = NULL;
+    ComPtr<IMFStreamDescriptor> pSD = NULL;
+    ComPtr<IMFMediaTypeHandler> pHandler = NULL;
+    ComPtr<IMFMediaType> pType = NULL;
+    HRESULT hr = pSource->CreatePresentationDescriptor(pPD.GetAddressOf());
+    if (FAILED(hr))
+    {
+        goto done;
+    }
+
+    BOOL fSelected;
+    hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, pSD.GetAddressOf());
+    if (FAILED(hr))
+    {
+        goto done;
+    }
+    hr = pSD->GetMediaTypeHandler(pHandler.GetAddressOf());
+    if (FAILED(hr))
+    {
+        goto done;
+    }
+    DWORD cTypes = 0;
+    hr = pHandler->GetMediaTypeCount(&cTypes);
+    if (FAILED(hr))
+    {
+        goto done;
+    }
+    for (DWORD i = 0; i < cTypes; i++)
+    {
+        hr = pHandler->GetMediaTypeByIndex(i, pType.GetAddressOf());
+        if (FAILED(hr))
+        {
+            goto done;
+        }
+        MediaType MT = FormatReader::Read(pType.Get());
+        captureFormats.push_back(MT);
+    }
+
+done:
+    return hr;
+}
+
+HRESULT CvCaptureFile_MSMF::getSourceDuration(IMFMediaSource *pSource, MFTIME *pDuration)
+{
+    *pDuration = 0;
+
+    IMFPresentationDescriptor *pPD = NULL;
+
+    HRESULT hr = pSource->CreatePresentationDescriptor(&pPD);
+    if (SUCCEEDED(hr))
+    {
+        hr = pPD->GetUINT64(MF_PD_DURATION, (UINT64*)pDuration);
+        pPD->Release();
+    }
+    return hr;
+}
+
 CvCapture* cvCreateCameraCapture_MSMF( int index )
 {
     CvCaptureCAM_MSMF* capture = new CvCaptureCAM_MSMF;
@@ -2807,4 +3144,392 @@ CvCapture* cvCreateCameraCapture_MSMF( int index )
     delete capture;
     return 0;
 }
+
+CvCapture* cvCreateFileCapture_MSMF (const char* filename)
+{
+    CvCaptureFile_MSMF* capture = new CvCaptureFile_MSMF;
+    try
+    {
+        if( capture->open(filename) )
+            return capture;
+        else
+        {
+            delete capture;
+            return NULL;
+        }
+    }
+    catch(...)
+    {
+        delete capture;
+        throw;
+    }
+}
+
+//
+//
+// Media Foundation-based Video Writer
+//
+//
+
+class CvVideoWriter_MSMF : public CvVideoWriter
+{
+public:
+    CvVideoWriter_MSMF();
+    virtual ~CvVideoWriter_MSMF();
+    virtual bool open(const char* filename, int fourcc,
+                       double fps, CvSize frameSize, bool isColor);
+    virtual void close();
+    virtual bool writeFrame(const IplImage* img);
+
+private:
+    UINT32 videoWidth;
+    UINT32 videoHeight;
+    double fps;
+    UINT32 bitRate;
+    UINT32 frameSize;
+    GUID   encodingFormat;
+    GUID   inputFormat;
+
+    DWORD  streamIndex;
+    ComPtr<IMFSinkWriter> sinkWriter;
+
+    bool   initiated;
+
+    LONGLONG rtStart;
+    UINT64 rtDuration;
+
+    HRESULT InitializeSinkWriter(const char* filename);
+    static const GUID FourCC2GUID(int fourcc);
+    HRESULT WriteFrame(DWORD *videoFrameBuffer, const LONGLONG& rtStart, const LONGLONG& rtDuration);
+};
+
+CvVideoWriter_MSMF::CvVideoWriter_MSMF():
+    initiated(false)
+{
+}
+
+CvVideoWriter_MSMF::~CvVideoWriter_MSMF()
+{
+    close();
+}
+
+const GUID CvVideoWriter_MSMF::FourCC2GUID(int fourcc)
+{
+    switch(fourcc)
+    {
+        case CV_FOURCC_MACRO('d', 'v', '2', '5'):
+            return MFVideoFormat_DV25; break;
+        case CV_FOURCC_MACRO('d', 'v', '5', '0'):
+            return MFVideoFormat_DV50; break;
+        case CV_FOURCC_MACRO('d', 'v', 'c', ' '):
+            return MFVideoFormat_DVC; break;
+        case CV_FOURCC_MACRO('d', 'v', 'h', '1'):
+            return MFVideoFormat_DVH1; break;
+        case CV_FOURCC_MACRO('d', 'v', 'h', 'd'):
+            return MFVideoFormat_DVHD; break;
+        case CV_FOURCC_MACRO('d', 'v', 's', 'd'):
+            return MFVideoFormat_DVSD; break;
+        case CV_FOURCC_MACRO('d', 'v', 's', 'l'):
+                return MFVideoFormat_DVSL; break;
+        case CV_FOURCC_MACRO('H', '2', '6', '3'):
+                return MFVideoFormat_H263; break;
+        case CV_FOURCC_MACRO('H', '2', '6', '4'):
+                return MFVideoFormat_H264; break;
+        case CV_FOURCC_MACRO('M', '4', 'S', '2'):
+                return MFVideoFormat_M4S2; break;
+        case CV_FOURCC_MACRO('M', 'J', 'P', 'G'):
+                return MFVideoFormat_MJPG; break;
+        case CV_FOURCC_MACRO('M', 'P', '4', '3'):
+                return MFVideoFormat_MP43; break;
+        case CV_FOURCC_MACRO('M', 'P', '4', 'S'):
+                return MFVideoFormat_MP4S; break;
+        case CV_FOURCC_MACRO('M', 'P', '4', 'V'):
+                return MFVideoFormat_MP4V; break;
+        case CV_FOURCC_MACRO('M', 'P', 'G', '1'):
+                return MFVideoFormat_MPG1; break;
+        case CV_FOURCC_MACRO('M', 'S', 'S', '1'):
+                return MFVideoFormat_MSS1; break;
+        case CV_FOURCC_MACRO('M', 'S', 'S', '2'):
+                return MFVideoFormat_MSS2; break;
+        case CV_FOURCC_MACRO('W', 'M', 'V', '1'):
+                return MFVideoFormat_WMV1; break;
+        case CV_FOURCC_MACRO('W', 'M', 'V', '2'):
+                return MFVideoFormat_WMV2; break;
+        case CV_FOURCC_MACRO('W', 'M', 'V', '3'):
+                return MFVideoFormat_WMV3; break;
+        case CV_FOURCC_MACRO('W', 'V', 'C', '1'):
+                return MFVideoFormat_WVC1; break;
+        default:
+            return MFVideoFormat_H264;
+    }
+}
+
+bool CvVideoWriter_MSMF::open( const char* filename, int fourcc,
+                       double _fps, CvSize frameSize, bool /*isColor*/ )
+{
+    videoWidth = frameSize.width;
+    videoHeight = frameSize.height;
+    fps = _fps;
+    bitRate = (UINT32)fps*videoWidth*videoHeight; // 1-bit per pixel
+    encodingFormat = FourCC2GUID(fourcc);
+    inputFormat = MFVideoFormat_RGB32;
+
+    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+    if (SUCCEEDED(hr))
+    {
+        hr = MFStartup(MF_VERSION);
+        if (SUCCEEDED(hr))
+        {
+            hr = InitializeSinkWriter(filename);
+            if (SUCCEEDED(hr))
+            {
+                initiated = true;
+                rtStart = 0;
+                MFFrameRateToAverageTimePerFrame((UINT32)fps, 1, &rtDuration);
+            }
+        }
+    }
+
+    return SUCCEEDED(hr);
+}
+
+void CvVideoWriter_MSMF::close()
+{
+    if (!initiated)
+    {
+        return;
+    }
+
+    initiated = false;
+    sinkWriter->Finalize();
+    MFShutdown();
+}
+
+bool CvVideoWriter_MSMF::writeFrame(const IplImage* img)
+{
+    if (!img)
+        return false;
+
+    int length = img->width * img->height * 4;
+    DWORD* target = new DWORD[length];
+
+    for (int rowIdx = 0; rowIdx < img->height; rowIdx++)
+    {
+        char* rowStart = img->imageData + rowIdx*img->widthStep;
+        for (int colIdx = 0; colIdx < img->width; colIdx++)
+        {
+            BYTE b = rowStart[colIdx * img->nChannels + 0];
+            BYTE g = rowStart[colIdx * img->nChannels + 1];
+            BYTE r = rowStart[colIdx * img->nChannels + 2];
+
+            target[rowIdx*img->width+colIdx] = (r << 16) + (g << 8) + b;
+        }
+    }
+
+    // Send frame to the sink writer.
+    HRESULT hr = WriteFrame(target, rtStart, rtDuration);
+    if (FAILED(hr))
+    {
+        delete[] target;
+        return false;
+    }
+    rtStart += rtDuration;
+
+    delete[] target;
+
+    return true;
+}
+
+HRESULT CvVideoWriter_MSMF::InitializeSinkWriter(const char* filename)
+{
+    ComPtr<IMFAttributes> spAttr;
+    ComPtr<IMFMediaType>  mediaTypeOut;
+    ComPtr<IMFMediaType>  mediaTypeIn;
+    ComPtr<IMFByteStream> spByteStream;
+
+    MFCreateAttributes(&spAttr, 10);
+    spAttr->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, true);
+
+    wchar_t* unicodeFileName = new wchar_t[strlen(filename)+1];
+    MultiByteToWideChar(CP_ACP, 0, filename, -1, unicodeFileName, strlen(filename)+1);
+
+    HRESULT hr = MFCreateSinkWriterFromURL(unicodeFileName, NULL, spAttr.Get(), &sinkWriter);
+
+    delete[] unicodeFileName;
+
+    // Set the output media type.
+    if (SUCCEEDED(hr))
+    {
+        hr = MFCreateMediaType(&mediaTypeOut);
+    }
+    if (SUCCEEDED(hr))
+    {
+        hr = mediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
+    }
+    if (SUCCEEDED(hr))
+    {
+        hr = mediaTypeOut->SetGUID(MF_MT_SUBTYPE, encodingFormat);
+    }
+    if (SUCCEEDED(hr))
+    {
+        hr = mediaTypeOut->SetUINT32(MF_MT_AVG_BITRATE, bitRate);
+    }
+    if (SUCCEEDED(hr))
+    {
+        hr = mediaTypeOut->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
+    }
+    if (SUCCEEDED(hr))
+    {
+        hr = MFSetAttributeSize(mediaTypeOut.Get(), MF_MT_FRAME_SIZE, videoWidth, videoHeight);
+    }
+    if (SUCCEEDED(hr))
+    {
+        hr = MFSetAttributeRatio(mediaTypeOut.Get(), MF_MT_FRAME_RATE, (UINT32)fps, 1);
+    }
+    if (SUCCEEDED(hr))
+    {
+        hr = MFSetAttributeRatio(mediaTypeOut.Get(), MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
+    }
+
+    if (SUCCEEDED(hr))
+    {
+        hr = sinkWriter->AddStream(mediaTypeOut.Get(), &streamIndex);
+    }
+
+    // Set the input media type.
+    if (SUCCEEDED(hr))
+    {
+        hr = MFCreateMediaType(&mediaTypeIn);
+    }
+    if (SUCCEEDED(hr))
+    {
+        hr = mediaTypeIn->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
+    }
+    if (SUCCEEDED(hr))
+    {
+        hr = mediaTypeIn->SetGUID(MF_MT_SUBTYPE, inputFormat);
+    }
+    if (SUCCEEDED(hr))
+    {
+        hr = mediaTypeIn->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
+    }
+    if (SUCCEEDED(hr))
+    {
+        hr = MFSetAttributeSize(mediaTypeIn.Get(), MF_MT_FRAME_SIZE, videoWidth, videoHeight);
+    }
+    if (SUCCEEDED(hr))
+    {
+        hr = MFSetAttributeRatio(mediaTypeIn.Get(), MF_MT_FRAME_RATE, (UINT32)fps, 1);
+    }
+    if (SUCCEEDED(hr))
+    {
+        hr = MFSetAttributeRatio(mediaTypeIn.Get(), MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
+    }
+
+    if (SUCCEEDED(hr))
+    {
+        hr = sinkWriter->SetInputMediaType(streamIndex, mediaTypeIn.Get(), NULL);
+    }
+
+    // Tell the sink writer to start accepting data.
+    if (SUCCEEDED(hr))
+    {
+        hr = sinkWriter->BeginWriting();
+    }
+
+    return hr;
+}
+
+HRESULT CvVideoWriter_MSMF::WriteFrame(DWORD *videoFrameBuffer, const LONGLONG& Start, const LONGLONG& Duration)
+{
+    ComPtr<IMFSample> sample;
+    ComPtr<IMFMediaBuffer> buffer;
+
+    const LONG cbWidth = 4 * videoWidth;
+    const DWORD cbBuffer = cbWidth * videoHeight;
+
+    BYTE *pData = NULL;
+
+    // Create a new memory buffer.
+    HRESULT hr = MFCreateMemoryBuffer(cbBuffer, &buffer);
+
+    // Lock the buffer and copy the video frame to the buffer.
+    if (SUCCEEDED(hr))
+    {
+        hr = buffer->Lock(&pData, NULL, NULL);
+    }
+
+    if (SUCCEEDED(hr))
+    {
+#if defined(_M_ARM)
+        hr = MFCopyImage(
+            pData,                      // Destination buffer.
+            -cbWidth,                   // Destination stride.
+            (BYTE*)videoFrameBuffer,    // First row in source image.
+            cbWidth,                    // Source stride.
+            cbWidth,                    // Image width in bytes.
+            videoHeight                 // Image height in pixels.
+            );
+#else
+        hr = MFCopyImage(
+            pData,                      // Destination buffer.
+            cbWidth,                    // Destination stride.
+            (BYTE*)videoFrameBuffer,    // First row in source image.
+            cbWidth,                    // Source stride.
+            cbWidth,                    // Image width in bytes.
+            videoHeight                 // Image height in pixels.
+            );
+#endif
+    }
+
+    if (buffer)
+    {
+        buffer->Unlock();
+    }
+
+    // Set the data length of the buffer.
+    if (SUCCEEDED(hr))
+    {
+        hr = buffer->SetCurrentLength(cbBuffer);
+    }
+
+    // Create a media sample and add the buffer to the sample.
+    if (SUCCEEDED(hr))
+    {
+        hr = MFCreateSample(&sample);
+    }
+    if (SUCCEEDED(hr))
+    {
+        hr = sample->AddBuffer(buffer.Get());
+    }
+
+    // Set the time stamp and the duration.
+    if (SUCCEEDED(hr))
+    {
+        hr = sample->SetSampleTime(Start);
+    }
+    if (SUCCEEDED(hr))
+    {
+        hr = sample->SetSampleDuration(Duration);
+    }
+
+    // Send the sample to the Sink Writer.
+    if (SUCCEEDED(hr))
+    {
+        hr = sinkWriter->WriteSample(streamIndex, sample.Get());
+    }
+
+    return hr;
+}
+
+CvVideoWriter* cvCreateVideoWriter_MSMF( const char* filename, int fourcc,
+                                        double fps, CvSize frameSize, int isColor )
+{
+    CvVideoWriter_MSMF* writer = new CvVideoWriter_MSMF;
+    if( writer->open( filename, fourcc, fps, frameSize, isColor != 0 ))
+        return writer;
+    delete writer;
+    return NULL;
+}
+
 #endif
\ No newline at end of file
index a788c90..23497a5 100644 (file)
@@ -14,7 +14,9 @@ It has been tested with the motempl sample program
 First Patch:  August 24, 2004 Travis Wood   TravisOCV@tkwood.com
 For Release:  OpenCV-Linux Beta4  opencv-0.9.6
 Tested On:    LMLBT44 with 8 video inputs
-Problems?     Post problems/fixes to OpenCV group on groups.yahoo.com
+Problems?     Post your questions at answers.opencv.org, 
+              Report bugs at code.opencv.org,
+              Submit your fixes at https://github.com/Itseez/opencv/
 Patched Comments:
 
 TW: The cv cam utils that came with the initial release of OpenCV for LINUX Beta4
index d419a48..d845953 100644 (file)
@@ -613,8 +613,10 @@ bool CvVideoWriter_VFW::open( const char* filename, int _fourcc, double _fps, Cv
             close();
             return false;
         }
+        return true;
     }
-    return true;
+    else
+        return false;
 }
 
 
index 5acf2c0..98279e0 100644 (file)
@@ -52,6 +52,8 @@ void CvCaptureCAM_XIMEA::init()
 {
     xiGetNumberDevices( &numDevices);
     hmv = NULL;
+    frame = NULL;
+    timeout = 0;
     memset(&image, 0, sizeof(XI_IMG));
 }
 
@@ -60,6 +62,8 @@ void CvCaptureCAM_XIMEA::init()
 // Initialize camera input
 bool CvCaptureCAM_XIMEA::open( int wIndex )
 {
+#define HandleXiResult(res) if (res!=XI_OK)  goto error;
+
     int mvret = XI_OK;
 
     if(numDevices == 0)
@@ -73,26 +77,42 @@ bool CvCaptureCAM_XIMEA::open( int wIndex )
 
     // always use auto exposure/gain
     mvret = xiSetParamInt( hmv, XI_PRM_AEAG, 1);
-    if(mvret != XI_OK) goto error;
-
-    // always use auto white ballance
-    mvret = xiSetParamInt( hmv, XI_PRM_AUTO_WB, 1);
-    if(mvret != XI_OK) goto error;
-    
-    // default image format RGB24
-    mvret = xiSetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, XI_RGB24);
-    if(mvret != XI_OK) goto error;
+    HandleXiResult(mvret);
 
     int width = 0;
     mvret = xiGetParamInt( hmv, XI_PRM_WIDTH, &width);
-    if(mvret != XI_OK) goto error;
+    HandleXiResult(mvret);
 
     int height = 0;
     mvret = xiGetParamInt( hmv, XI_PRM_HEIGHT, &height);
-    if(mvret != XI_OK) goto error;
+    HandleXiResult(mvret);
+
+    int isColor = 0;
+    mvret = xiGetParamInt(hmv, XI_PRM_IMAGE_IS_COLOR, &isColor);
+    HandleXiResult(mvret);
+
+    if(isColor)        // for color cameras
+    {
+        // default image format RGB24
+        mvret = xiSetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, XI_RGB24);
+        HandleXiResult(mvret);
+
+        // always use auto white ballance for color cameras
+        mvret = xiSetParamInt( hmv, XI_PRM_AUTO_WB, 1);
+        HandleXiResult(mvret);
+
+        // allocate frame buffer for RGB24 image
+        frame = cvCreateImage(cvSize( width, height), IPL_DEPTH_8U, 3);
+    }
+    else // for mono cameras
+    {
+        // default image format MONO8
+        mvret = xiSetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, XI_MONO8);
+        HandleXiResult(mvret);
 
-    // allocate frame buffer for RGB24 image
-    frame = cvCreateImage(cvSize( width, height), IPL_DEPTH_8U, 3);
+        // allocate frame buffer for MONO8 image
+        frame = cvCreateImage(cvSize( width, height), IPL_DEPTH_8U, 1);
+    }
 
     //default capture timeout 10s
     timeout = 10000;
@@ -118,9 +138,12 @@ void CvCaptureCAM_XIMEA::close()
 {
     if(frame)
         cvReleaseImage(&frame);
-
-    xiStopAcquisition(hmv);
-    xiCloseDevice(hmv);
+    
+    if(hmv)
+    {
+        xiStopAcquisition(hmv);
+        xiCloseDevice(hmv);
+    }
     hmv = NULL;
 }
 
index d9080e5..28818e3 100644 (file)
 #endif
 #endif
 
-#undef PACKAGE
-#undef PACKAGE_BUGREPORT
-#undef PACKAGE_NAME
-#undef PACKAGE_STRING
-#undef PACKAGE_TARNAME
-#undef PACKAGE_VERSION
 #undef VERSION
 
 #include <jasper/jasper.h>
index 9bb5d32..fb0fe6c 100644 (file)
@@ -51,7 +51,6 @@
     and png2bmp sample from libpng distribution (Copyright (C) 1999-2001 MIYASAKA Masaru)
 \****************************************************************************************/
 
-#undef HAVE_UNISTD_H //to avoid redefinition
 #ifndef _LFS64_LARGEFILE
 #  define _LFS64_LARGEFILE 0
 #endif
diff --git a/modules/highgui/src/ios_conversions.mm b/modules/highgui/src/ios_conversions.mm
new file mode 100644 (file)
index 0000000..7295743
--- /dev/null
@@ -0,0 +1,117 @@
+/*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*/
+
+#import "opencv2/highgui/cap_ios.h"
+#include "precomp.hpp"
+
+UIImage* MatToUIImage(const cv::Mat& image) {
+    
+    NSData *data = [NSData dataWithBytes:image.data
+                                  length:image.elemSize()*image.total()];
+    
+    CGColorSpaceRef colorSpace;
+    
+    if (image.elemSize() == 1) {
+        colorSpace = CGColorSpaceCreateDeviceGray();
+    } else {
+        colorSpace = CGColorSpaceCreateDeviceRGB();
+    }
+    
+    CGDataProviderRef provider =
+            CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
+    
+    // Creating CGImage from cv::Mat
+    CGImageRef imageRef = CGImageCreate(image.cols,
+                                        image.rows,
+                                        8,
+                                        8 * image.elemSize(),
+                                        image.step.p[0],
+                                        colorSpace,
+                                        kCGImageAlphaNone|
+                                        kCGBitmapByteOrderDefault,
+                                        provider,
+                                        NULL,
+                                        false,
+                                        kCGRenderingIntentDefault
+                                        );
+    
+    
+    // Getting UIImage from CGImage
+    UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
+    CGImageRelease(imageRef);
+    CGDataProviderRelease(provider);
+    CGColorSpaceRelease(colorSpace);
+    
+    return finalImage;
+}
+
+void UIImageToMat(const UIImage* image,
+                         cv::Mat& m, bool alphaExist) {
+    CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
+    CGFloat cols = image.size.width, rows = image.size.height;
+    CGContextRef contextRef;
+    CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast;
+    if (CGColorSpaceGetModel(colorSpace) == 0)
+    {
+        m.create(rows, cols, CV_8UC1); // 8 bits per component, 1 channel
+        bitmapInfo = kCGImageAlphaNone;
+        if (!alphaExist)
+            bitmapInfo = kCGImageAlphaNone;
+        contextRef = CGBitmapContextCreate(m.data, m.cols, m.rows, 8,
+                                           m.step[0], colorSpace,
+                                           bitmapInfo);
+    }
+    else
+    {
+        m.create(rows, cols, CV_8UC4); // 8 bits per component, 4 channels
+        if (!alphaExist)
+            bitmapInfo = kCGImageAlphaNoneSkipLast |
+                                kCGBitmapByteOrderDefault;
+        contextRef = CGBitmapContextCreate(m.data, m.cols, m.rows, 8,
+                                           m.step[0], colorSpace,
+                                           bitmapInfo);
+    }
+    CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows),
+                       image.CGImage);
+    CGContextRelease(contextRef);
+    CGColorSpaceRelease(colorSpace);
+}
\ No newline at end of file
diff --git a/modules/highgui/src/precomp.cpp b/modules/highgui/src/precomp.cpp
deleted file mode 100644 (file)
index d6f6e18..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*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 "precomp.hpp"
-
index aa327d6..dcd4afd 100644 (file)
@@ -119,6 +119,9 @@ CvVideoWriter* cvCreateVideoWriter_VFW( const char* filename, int fourcc,
                                         double fps, CvSize frameSize, int is_color );
 CvCapture* cvCreateCameraCapture_DShow( int index );
 CvCapture* cvCreateCameraCapture_MSMF( int index );
+CvCapture* cvCreateFileCapture_MSMF (const char* filename);
+CvVideoWriter* cvCreateVideoWriter_MSMF( const char* filename, int fourcc,
+                                        double fps, CvSize frameSize, int is_color );
 CvCapture* cvCreateCameraCapture_OpenNI( int index );
 CvCapture* cvCreateFileCapture_OpenNI( const char* filename );
 CvCapture* cvCreateCameraCapture_Android( int index );
index 50f2b9e..64d57ab 100644 (file)
@@ -38,6 +38,7 @@
 
 //--------------------Google Code 2010 -- Yannick Verdie--------------------//
 
+#include "precomp.hpp"
 
 #if defined(HAVE_QT)
 
@@ -2473,35 +2474,33 @@ void DefaultViewPort::saveView()
     if (!fileName.isEmpty()) //save the picture
     {
         QString extension = fileName.right(3);
-
-        //   (no need anymore) create the image resized to receive the 'screenshot'
-        //    image2Draw_qt_resized = QImage(viewport()->width(), viewport()->height(),QImage::Format_RGB888);
-
-        QPainter saveimage(&image2Draw_qt_resized);
-        this->render(&saveimage);
+        
+        // Create a new pixmap to render the viewport into
+        QPixmap viewportPixmap(viewport()->size());
+        viewport()->render(&viewportPixmap);
 
         // Save it..
         if (QString::compare(extension, "png", Qt::CaseInsensitive) == 0)
         {
-            image2Draw_qt_resized.save(fileName, "PNG");
+            viewportPixmap.save(fileName, "PNG");
             return;
         }
 
         if (QString::compare(extension, "jpg", Qt::CaseInsensitive) == 0)
         {
-            image2Draw_qt_resized.save(fileName, "JPG");
+            viewportPixmap.save(fileName, "JPG");
             return;
         }
 
         if (QString::compare(extension, "bmp", Qt::CaseInsensitive) == 0)
         {
-            image2Draw_qt_resized.save(fileName, "BMP");
+            viewportPixmap.save(fileName, "BMP");
             return;
         }
 
         if (QString::compare(extension, "jpeg", Qt::CaseInsensitive) == 0)
         {
-            image2Draw_qt_resized.save(fileName, "JPEG");
+            viewportPixmap.save(fileName, "JPEG");
             return;
         }
 
@@ -2651,17 +2650,16 @@ void DefaultViewPort::paintEvent(QPaintEvent* evnt)
     //Now disable matrixWorld for overlay display
     myPainter.setWorldMatrixEnabled(false);
 
+    //overlay pixel values if zoomed in far enough
+    if (param_matrixWorld.m11()*ratioX >= threshold_zoom_img_region &&
+        param_matrixWorld.m11()*ratioY >= threshold_zoom_img_region)
+    {
+        drawImgRegion(&myPainter);
+    }
+
     //in mode zoom/panning
     if (param_matrixWorld.m11() > 1)
     {
-        if (param_matrixWorld.m11() >= threshold_zoom_img_region)
-        {
-            if (centralWidget->param_flags == CV_WINDOW_NORMAL)
-                startDisplayInfo("WARNING: The values displayed are the resized image's values. If you want the original image's values, use CV_WINDOW_AUTOSIZE", 1000);
-
-            drawImgRegion(&myPainter);
-        }
-
         drawViewOverview(&myPainter);
     }
 
@@ -2887,22 +2885,24 @@ void DefaultViewPort::drawStatusBar()
 //accept only CV_8UC1 and CV_8UC8 image for now
 void DefaultViewPort::drawImgRegion(QPainter *painter)
 {
-
     if (nbChannelOriginImage!=CV_8UC1 && nbChannelOriginImage!=CV_8UC3)
         return;
 
-    qreal offsetX = param_matrixWorld.dx()/param_matrixWorld.m11();
+    double pixel_width = param_matrixWorld.m11()*ratioX;
+    double pixel_height = param_matrixWorld.m11()*ratioY;
+
+    qreal offsetX = param_matrixWorld.dx()/pixel_width;
     offsetX = offsetX - floor(offsetX);
-    qreal offsetY = param_matrixWorld.dy()/param_matrixWorld.m11();
+    qreal offsetY = param_matrixWorld.dy()/pixel_height;
     offsetY = offsetY - floor(offsetY);
 
     QSize view = size();
     QVarLengthArray<QLineF, 30> linesX;
-    for (qreal _x = offsetX*param_matrixWorld.m11(); _x < view.width(); _x += param_matrixWorld.m11() )
+    for (qreal _x = offsetX*pixel_width; _x < view.width(); _x += pixel_width )
         linesX.append(QLineF(_x, 0, _x, view.height()));
 
     QVarLengthArray<QLineF, 30> linesY;
-    for (qreal _y = offsetY*param_matrixWorld.m11(); _y < view.height(); _y += param_matrixWorld.m11() )
+    for (qreal _y = offsetY*pixel_height; _y < view.height(); _y += pixel_height )
         linesY.append(QLineF(0, _y, view.width(), _y));
 
 
@@ -2910,27 +2910,25 @@ void DefaultViewPort::drawImgRegion(QPainter *painter)
     int original_font_size = f.pointSize();
     //change font size
     //f.setPointSize(4+(param_matrixWorld.m11()-threshold_zoom_img_region)/5);
-    f.setPixelSize(10+(param_matrixWorld.m11()-threshold_zoom_img_region)/5);
+    f.setPixelSize(10+(pixel_height-threshold_zoom_img_region)/5);
     painter->setFont(f);
-    QString val;
-    QRgb rgbValue;
 
-    QPointF point1;//sorry, I do not know how to name it
-    QPointF point2;//idem
 
-    for (int j=-1;j<height()/param_matrixWorld.m11();j++)//-1 because display the pixels top rows left colums
-        for (int i=-1;i<width()/param_matrixWorld.m11();i++)//-1
+    for (int j=-1;j<height()/pixel_height;j++)//-1 because display the pixels top rows left columns
+        for (int i=-1;i<width()/pixel_width;i++)//-1
         {
-            point1.setX((i+offsetX)*param_matrixWorld.m11());
-            point1.setY((j+offsetY)*param_matrixWorld.m11());
-
-            matrixWorld_inv.map(point1.x(),point1.y(),&point2.rx(),&point2.ry());
-
-            point2.rx()= (long) (point2.x() + 0.5);
-            point2.ry()= (long) (point2.y() + 0.5);
-
-            if (point2.x() >= 0 && point2.y() >= 0)
-                rgbValue = image2Draw_qt_resized.pixel(QPoint(point2.x(),point2.y()));
+            // Calculate top left of the pixel's position in the viewport (screen space)
+            QPointF pos_in_view((i+offsetX)*pixel_width, (j+offsetY)*pixel_height);
+
+            // Calculate top left of the pixel's position in the image (image space)
+            QPointF pos_in_image = matrixWorld_inv.map(pos_in_view);// Top left of pixel in view
+            pos_in_image.rx() = pos_in_image.x()/ratioX;
+            pos_in_image.ry() = pos_in_image.y()/ratioY;
+            QPoint point_in_image(pos_in_image.x() + 0.5f,pos_in_image.y() + 0.5f);// Add 0.5 for rounding
+
+            QRgb rgbValue;
+            if (image2Draw_qt.valid(point_in_image))
+                rgbValue = image2Draw_qt.pixel(point_in_image);
             else
                 rgbValue = qRgb(0,0,0);
 
@@ -2943,29 +2941,29 @@ void DefaultViewPort::drawImgRegion(QPainter *painter)
                 painter->drawText(QRect(point1.x(),point1.y(),param_matrixWorld.m11(),param_matrixWorld.m11()/2),
                     Qt::AlignCenter, val);
                 */
+                QString val;
 
                 val = tr("%1").arg(qRed(rgbValue));
                 painter->setPen(QPen(Qt::red, 1));
-                painter->drawText(QRect(point1.x(),point1.y(),param_matrixWorld.m11(),param_matrixWorld.m11()/3),
+                painter->drawText(QRect(pos_in_view.x(),pos_in_view.y(),pixel_width,pixel_height/3),
                     Qt::AlignCenter, val);
 
                 val = tr("%1").arg(qGreen(rgbValue));
                 painter->setPen(QPen(Qt::green, 1));
-                painter->drawText(QRect(point1.x(),point1.y()+param_matrixWorld.m11()/3,param_matrixWorld.m11(),param_matrixWorld.m11()/3),
+                painter->drawText(QRect(pos_in_view.x(),pos_in_view.y()+pixel_height/3,pixel_width,pixel_height/3),
                     Qt::AlignCenter, val);
 
                 val = tr("%1").arg(qBlue(rgbValue));
                 painter->setPen(QPen(Qt::blue, 1));
-                painter->drawText(QRect(point1.x(),point1.y()+2*param_matrixWorld.m11()/3,param_matrixWorld.m11(),param_matrixWorld.m11()/3),
+                painter->drawText(QRect(pos_in_view.x(),pos_in_view.y()+2*pixel_height/3,pixel_width,pixel_height/3),
                     Qt::AlignCenter, val);
 
             }
 
             if (nbChannelOriginImage==CV_8UC1)
             {
-
-                val = tr("%1").arg(qRed(rgbValue));
-                painter->drawText(QRect(point1.x(),point1.y(),param_matrixWorld.m11(),param_matrixWorld.m11()),
+                QString val = tr("%1").arg(qRed(rgbValue));
+                painter->drawText(QRect(pos_in_view.x(),pos_in_view.y(),pixel_width,pixel_height),
                     Qt::AlignCenter, val);
             }
         }
index 089997f..a96a8c6 100644 (file)
@@ -522,7 +522,6 @@ private:
 
     CvMat* image2Draw_mat;
     QImage image2Draw_qt;
-    QImage image2Draw_qt_resized;
     int nbChannelOriginImage;
 
     //for mouse callback
diff --git a/modules/highgui/test/test_precomp.cpp b/modules/highgui/test/test_precomp.cpp
deleted file mode 100644 (file)
index 5956e13..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "test_precomp.hpp"
index 0d0bd80..5e03081 100644 (file)
@@ -9,9 +9,7 @@
 #ifndef __OPENCV_TEST_PRECOMP_HPP__
 #define __OPENCV_TEST_PRECOMP_HPP__
 
-#ifdef HAVE_CVCONFIG_H
 # include "cvconfig.h"
-#endif
 
 #include "opencv2/ts/ts.hpp"
 #include "opencv2/imgproc/imgproc.hpp"
@@ -47,7 +45,8 @@
     defined(HAVE_QUICKTIME)    || \
     defined(HAVE_AVFOUNDATION) || \
     /*defined(HAVE_OPENNI)     || too specialized */ \
-    defined(HAVE_FFMPEG)
+    defined(HAVE_FFMPEG)       || \
+    defined(HAVE_MSMF)
 #  define BUILD_WITH_VIDEO_INPUT_SUPPORT 1
 #else
 #  define BUILD_WITH_VIDEO_INPUT_SUPPORT 0
@@ -57,7 +56,8 @@
     defined(HAVE_GSTREAMER)    || \
     defined(HAVE_QUICKTIME)    || \
     defined(HAVE_AVFOUNDATION) || \
-    defined(HAVE_FFMPEG)
+    defined(HAVE_FFMPEG)       || \
+    defined(HAVE_MSMF)
 #  define BUILD_WITH_VIDEO_OUTPUT_SUPPORT 1
 #else
 #  define BUILD_WITH_VIDEO_OUTPUT_SUPPORT 0
index b0c2e53..5d4de7e 100644 (file)
@@ -54,6 +54,35 @@ string fourccToString(int fourcc)
     return format("%c%c%c%c", fourcc & 255, (fourcc >> 8) & 255, (fourcc >> 16) & 255, (fourcc >> 24) & 255);
 }
 
+#ifdef HAVE_MSMF
+const VideoFormat g_specific_fmt_list[] =
+{
+        /*VideoFormat("wmv", CV_FOURCC_MACRO('d', 'v', '2', '5')),
+        VideoFormat("wmv", CV_FOURCC_MACRO('d', 'v', '5', '0')),
+        VideoFormat("wmv", CV_FOURCC_MACRO('d', 'v', 'c', ' ')),
+        VideoFormat("wmv", CV_FOURCC_MACRO('d', 'v', 'h', '1')),
+        VideoFormat("wmv", CV_FOURCC_MACRO('d', 'v', 'h', 'd')),
+        VideoFormat("wmv", CV_FOURCC_MACRO('d', 'v', 's', 'd')),
+        VideoFormat("wmv", CV_FOURCC_MACRO('d', 'v', 's', 'l')),
+        VideoFormat("wmv", CV_FOURCC_MACRO('H', '2', '6', '3')),
+        VideoFormat("wmv", CV_FOURCC_MACRO('M', '4', 'S', '2')),
+        VideoFormat("avi", CV_FOURCC_MACRO('M', 'J', 'P', 'G')),
+        VideoFormat("mp4", CV_FOURCC_MACRO('M', 'P', '4', 'S')),
+        VideoFormat("mp4", CV_FOURCC_MACRO('M', 'P', '4', 'V')),
+        VideoFormat("wmv", CV_FOURCC_MACRO('M', 'P', '4', '3')),
+        VideoFormat("wmv", CV_FOURCC_MACRO('M', 'P', 'G', '1')),
+        VideoFormat("wmv", CV_FOURCC_MACRO('M', 'S', 'S', '1')),
+        VideoFormat("wmv", CV_FOURCC_MACRO('M', 'S', 'S', '2')),*/
+#if !defined(_M_ARM)
+        VideoFormat("wmv", CV_FOURCC_MACRO('W', 'M', 'V', '1')),
+        VideoFormat("wmv", CV_FOURCC_MACRO('W', 'M', 'V', '2')),
+#endif
+        VideoFormat("wmv", CV_FOURCC_MACRO('W', 'M', 'V', '3')),
+        VideoFormat("avi", CV_FOURCC_MACRO('H', '2', '6', '4')),
+        //VideoFormat("wmv", CV_FOURCC_MACRO('W', 'V', 'C', '1')),
+        VideoFormat()
+};
+#else
 const VideoFormat g_specific_fmt_list[] =
 {
     VideoFormat("avi", CV_FOURCC('X', 'V', 'I', 'D')),
@@ -63,17 +92,17 @@ const VideoFormat g_specific_fmt_list[] =
     VideoFormat("mkv", CV_FOURCC('X', 'V', 'I', 'D')),
     VideoFormat("mkv", CV_FOURCC('M', 'P', 'E', 'G')),
     VideoFormat("mkv", CV_FOURCC('M', 'J', 'P', 'G')),
-
     VideoFormat("mov", CV_FOURCC('m', 'p', '4', 'v')),
     VideoFormat()
 };
+#endif
 
 }
 
 class CV_HighGuiTest : public cvtest::BaseTest
 {
 protected:
-    void ImageTest(const string& dir);
+    void ImageTest (const string& dir);
     void VideoTest (const string& dir, const cvtest::VideoFormat& fmt);
     void SpecificImageTest (const string& dir);
     void SpecificVideoTest (const string& dir, const cvtest::VideoFormat& fmt);
@@ -242,19 +271,19 @@ void CV_HighGuiTest::VideoTest(const string& dir, const cvtest::VideoFormat& fmt
 
     for(;;)
     {
-        IplImage * img = cvQueryFrame( cap );
+        IplImage* img = cvQueryFrame( cap );
 
         if (!img)
             break;
 
         frames.push_back(Mat(img).clone());
 
-        if (writer == 0)
+        if (writer == NULL)
         {
             writer = cvCreateVideoWriter(tmp_name.c_str(), fmt.fourcc, 24, cvGetSize(img));
-            if (writer == 0)
+            if (writer == NULL)
             {
-                ts->printf(ts->LOG, "can't create writer (with fourcc : %d)\n",
+                ts->printf(ts->LOG, "can't create writer (with fourcc : %s)\n",
                            cvtest::fourccToString(fmt.fourcc).c_str());
                 cvReleaseCapture( &cap );
                 ts->set_failed_test_info(ts->FAIL_MISMATCH);
@@ -290,15 +319,22 @@ void CV_HighGuiTest::VideoTest(const string& dir, const cvtest::VideoFormat& fmt
         double psnr = PSNR(img1, img);
         if (psnr < thresDbell)
         {
-            printf("Too low psnr = %gdb\n", psnr);
-            // imwrite("img.png", img);
-            // imwrite("img1.png", img1);
+            ts->printf(ts->LOG, "Too low frame %d psnr = %gdb\n", i, psnr);
             ts->set_failed_test_info(ts->FAIL_MISMATCH);
+
+            //imwrite("original.png", img);
+            //imwrite("after_test.png", img1);
+            //Mat diff;
+            //absdiff(img, img1, diff);
+            //imwrite("diff.png", diff);
+
             break;
         }
     }
 
+    printf("Before saved release for %s\n", tmp_name.c_str());
     cvReleaseCapture( &saved );
+    printf("After release\n");
 
     ts->printf(ts->LOG, "end test function : ImagesVideo \n");
 }
index df1a193..8218ef2 100644 (file)
@@ -32,7 +32,11 @@ Finds edges in an image using the [Canny86]_ algorithm.
 The function finds edges in the input image ``image`` and marks them in the output map ``edges`` using the Canny algorithm. The smallest value between ``threshold1`` and ``threshold2`` is used for edge linking. The largest value is used to find initial segments of strong edges. See
 http://en.wikipedia.org/wiki/Canny_edge_detector
 
+.. note::
 
+   * An example on using the canny edge detector can be found at opencv_source_code/samples/cpp/edge.cpp
+
+   * (Python) An example on using the canny edge detector can be found at opencv_source_code/samples/cpp/edge.py
 
 cornerEigenValsAndVecs
 ----------------------
@@ -85,7 +89,9 @@ The output of the function can be used for robust edge or corner detection.
     :ocv:func:`cornerHarris`,
     :ocv:func:`preCornerDetect`
 
+.. note::
 
+   * (Python) An example on how to use eigenvectors and eigenvalues to estimate image texture flow direction can be found at opencv_source_code/samples/python2/texture_flow.py
 
 cornerHarris
 ------------
@@ -356,6 +362,9 @@ Example: ::
     :ocv:func:`fitEllipse`,
     :ocv:func:`minEnclosingCircle`
 
+.. note::
+
+   * An example using the Hough circle detector can be found at opencv_source_code/samples/cpp/houghcircles.cpp
 
 HoughLines
 ----------
@@ -412,6 +421,10 @@ Finds lines in a binary image using the standard Hough transform.
 The function implements the standard or standard multi-scale Hough transform algorithm for line detection.  See http://homepages.inf.ed.ac.uk/rbf/HIPR2/hough.htm for a good explanation of Hough transform.
 See also the example in :ocv:func:`HoughLinesP` description.
 
+.. note::
+
+   * An example using the Hough line detector can be found at opencv_source_code/samples/cpp/houghlines.cpp
+
 HoughLinesP
 -----------
 Finds line segments in a binary image using the probabilistic Hough transform.
index 0b1f9a3..73df71e 100755 (executable)
@@ -22,6 +22,10 @@ OpenCV enables you to specify the extrapolation method. For details, see the fun
     * BORDER_CONSTANT:      iiiiii|abcdefgh|iiiiiii  with some specified 'i'
     */
 
+.. note::
+
+   * (Python) A complete example illustrating different morphological operations like erode/dilate, open/close, blackhat/tophat ... can be found at opencv_source_code/samples/python2/morphology.py
+
 BaseColumnFilter
 ----------------
 .. ocv:class:: BaseColumnFilter
@@ -868,6 +872,9 @@ The function supports the in-place mode. Dilation can be applied several ( ``ite
     :ocv:func:`morphologyEx`,
     :ocv:func:`createMorphologyFilter`
 
+.. note::
+
+   * An example using the morphological dilate operation can be found at opencv_source_code/samples/cpp/morphology2.cpp
 
 erode
 -----
@@ -908,7 +915,9 @@ The function supports the in-place mode. Erosion can be applied several ( ``iter
     :ocv:func:`morphologyEx`,
     :ocv:func:`createMorphologyFilter`
 
+.. note::
 
+   * An example using the morphological erode operation can be found at opencv_source_code/samples/cpp/morphology2.cpp
 
 filter2D
 --------
@@ -1245,6 +1254,9 @@ Any of the operations can be done in-place. In case of multi-channel images, eac
     :ocv:func:`erode`,
     :ocv:func:`createMorphologyFilter`
 
+.. note::
+
+   * An example using the morphologyEx function for the morphological opening and closing operations can be found at opencv_source_code/samples/cpp/morphology2.cpp
 
 Laplacian
 ---------
@@ -1290,7 +1302,9 @@ This is done when ``ksize > 1`` . When ``ksize == 1`` , the Laplacian is compute
     :ocv:func:`Sobel`,
     :ocv:func:`Scharr`
 
+.. note::
 
+   * An example using the Laplace transformation for edge detection can be found at opencv_source_code/samples/cpp/laplace.cpp
 
 pyrDown
 -------
@@ -1351,6 +1365,10 @@ Upsamples an image and then blurs it.
 The function performs the upsampling step of the Gaussian pyramid construction, though it can actually be used to construct the Laplacian pyramid. First, it upsamples the source image by injecting even zero rows and columns and then convolves the result with the same kernel as in
 :ocv:func:`pyrDown`  multiplied by 4.
 
+.. note::
+
+   * (Python) An example of Laplacian Pyramid construction and merging can be found at opencv_source_code/samples/python2/lappyr.py
+
 
 pyrMeanShiftFiltering
 ---------------------
@@ -1400,6 +1418,9 @@ After the iterations over, the color components of the initial pixel (that is, t
 
 When ``maxLevel > 0``, the gaussian pyramid of ``maxLevel+1`` levels is built, and the above procedure is run on the smallest layer first. After that, the results are propagated to the larger layer and the iterations are run again only on those pixels where the layer colors differ by more than ``sr`` from the lower-resolution layer of the pyramid. That makes boundaries of color regions sharper. Note that the results will be actually different from the ones obtained by running the meanshift procedure on the whole original image (i.e. when ``maxLevel==0``).
 
+.. note::
+
+   * An example using mean-shift image segmentation can be found at opencv_source_code/samples/cpp/meanshift_segmentation.cpp
 
 sepFilter2D
 -----------
@@ -1425,7 +1446,7 @@ Applies a separable linear filter to an image.
 
     :param kernelY: Coefficients for filtering each column.
 
-    :param anchor: Anchor position within the kernel. The default value  :math:`(-1, 1)`  means that the anchor is at the kernel center.
+    :param anchor: Anchor position within the kernel. The default value  :math:`(-1,-1)`  means that the anchor is at the kernel center.
 
     :param delta: Value added to the filtered results before storing them.
 
index c48da01..c3abdb7 100644 (file)
@@ -307,6 +307,9 @@ where
 
 The function emulates the human "foveal" vision and can be used for fast scale and rotation-invariant template matching, for object tracking and so forth. The function can not operate in-place.
 
+.. note::
+
+   * An example using the geometric logpolar operation in 4 applications can be found at opencv_source_code/samples/cpp/logpolar_bsm.cpp
 
 remap
 -----
index f576d5d..bf6c98f 100644 (file)
@@ -99,7 +99,12 @@ input arrays at the same location. The sample below shows how to compute a 2D Hu
         waitKey();
     }
 
+.. note::
 
+   * An example for creating histograms of an image can be found at opencv_source_code/samples/cpp/demhist.cpp
+
+   * (Python) An example for creating color histograms can be found at opencv_source/samples/python2/color_histogram.py
+   * (Python) An example illustrating RGB and grayscale histogram plotting can be found at opencv_source/samples/python2/hist.py
 
 
 calcBackProject
index 9fd8df5..ae728c2 100644 (file)
@@ -481,6 +481,12 @@ In this mode, the complexity is still linear.
 That is, the function provides a very fast way to compute the Voronoi diagram for a binary image.
 Currently, the second variant can use only the approximate distance transform algorithm, i.e. ``maskSize=CV_DIST_MASK_PRECISE`` is not supported yet.
 
+.. note::
+
+   * An example on using the distance transform can be found at opencv_source_code/samples/cpp/distrans.cpp
+
+   * (Python) An example on using the distance transform can be found at opencv_source/samples/python2/distrans.py
+
 floodFill
 ---------
 Fills a connected component with the given color.
@@ -580,11 +586,15 @@ where
 *
     Color/brightness of the seed point in case of a fixed range.
 
-Use these functions to either mark a connected component with the specified color in-place, or build a mask and then extract the contour, or copy the region to another image, and so on. Various modes of the function are demonstrated in the ``floodfill.cpp`` sample.
+Use these functions to either mark a connected component with the specified color in-place, or build a mask and then extract the contour, or copy the region to another image, and so on.
 
 .. seealso:: :ocv:func:`findContours`
 
+.. note::
 
+   * An example using the FloodFill technique can be found at opencv_source_code/samples/cpp/ffilldemo.cpp
+
+   * (Python) An example using the FloodFill technique can be found at opencv_source_code/samples/python2/floodfill.cpp
 
 integral
 --------
@@ -748,6 +758,12 @@ Visual demonstration and usage example of the function can be found in the OpenC
 
 .. seealso:: :ocv:func:`findContours`
 
+.. note::
+
+   * An example using the watershed algorithm can be found at opencv_source_code/samples/cpp/watershed.cpp
+
+   * (Python) An example using the watershed algorithm can be found at opencv_source_code/samples/python2/watershed.py
+
 grabCut
 -------
 Runs the GrabCut algorithm.
@@ -794,3 +810,9 @@ See the sample ``grabcut.cpp`` to learn how to use the function.
 .. [Meyer92] Meyer, F. *Color Image Segmentation*, ICIP92, 1992
 
 .. [Telea04] Alexandru Telea, *An Image Inpainting Technique Based on the Fast Marching Method*. Journal of Graphics, GPU, and Game Tools 9 1, pp 23-34 (2004)
+
+.. note::
+
+   * An example using the GrabCut algorithm can be found at opencv_source_code/samples/cpp/grabcut.cpp
+
+   * (Python) An example using the GrabCut algorithm can be found at opencv_source_code/samples/python2/grabcut.py
\ No newline at end of file
index c6231a0..ab4db33 100644 (file)
@@ -74,3 +74,6 @@ image patch:
 After the function finishes the comparison, the best matches can be found as global minimums (when ``CV_TM_SQDIFF`` was used) or maximums (when ``CV_TM_CCORR`` or ``CV_TM_CCOEFF`` was used) using the
 :ocv:func:`minMaxLoc` function. In case of a color image, template summation in the numerator and each sum in the denominator is done over all of the channels and separate mean values are used for each channel. That is, the function can take a color template and a color image. The result will still be a single-channel image, which is easier to analyze.
 
+.. note::
+
+   * (Python) An example on how to match mouse selected regions in an image can be found at opencv_source_code/samples/python2/mouse_and_match.py
\ No newline at end of file
index 37b2351..f25cc5a 100644 (file)
@@ -166,6 +166,14 @@ The function retrieves contours from the binary image using the algorithm
 
 .. note:: If you use the new Python interface then the ``CV_`` prefix has to be omitted in contour retrieval mode and contour approximation method parameters (for example, use ``cv2.RETR_LIST`` and ``cv2.CHAIN_APPROX_NONE`` parameters). If you use the old Python interface then these parameters have the ``CV_`` prefix (for example, use ``cv.CV_RETR_LIST`` and ``cv.CV_CHAIN_APPROX_NONE``).
 
+.. note::
+
+   * An example using the findContour functionality can be found at opencv_source_code/samples/cpp/contours2.cpp
+   * An example using findContours to clean up a background segmentation result at opencv_source_code/samples/cpp/segment_objects.cpp
+
+   * (Python) An example using the findContour functionality can be found at opencv_source/samples/python2/contours.py
+   * (Python) An example of detecting squares in an image can be found at opencv_source/samples/python2/squares.py
+
 drawContours
 ----------------
 Draws contours outlines or filled contours.
@@ -246,7 +254,12 @@ The function draws contour outlines in the image if
         waitKey(0);
     }
 
+.. note::
+
+   * An example using the drawContour functionality can be found at opencv_source_code/samples/cpp/contours2.cpp
+   * An example using drawContours to clean up a background segmentation result at opencv_source_code/samples/cpp/segment_objects.cpp
 
+   * (Python) An example using the drawContour functionality can be found at opencv_source/samples/python2/contours.py
 
 approxPolyDP
 ----------------
@@ -417,6 +430,10 @@ The functions find the convex hull of a 2D point set using the Sklansky's algori
 that has
 *O(N logN)* complexity in the current implementation. See the OpenCV sample ``convexhull.cpp`` that demonstrates the usage of different function variants.
 
+.. note::
+
+   * An example using the convexHull functionality can be found at opencv_source_code/samples/cpp/convexhull.cpp
+
 
 convexityDefects
 ----------------
@@ -473,6 +490,10 @@ Fits an ellipse around a set of 2D points.
 
 The function calculates the ellipse that fits (in a least-squares sense) a set of 2D points best of all. It returns the rotated rectangle in which the ellipse is inscribed. The algorithm [Fitzgibbon95]_ is used.
 
+.. note::
+
+   * An example using the fitEllipse technique can be found at opencv_source_code/samples/cpp/fitellipse.cpp
+
 fitLine
 -----------
 Fits a line to a 2D or 3D point set.
@@ -545,7 +566,9 @@ http://en.wikipedia.org/wiki/M-estimator
 :math:`w_i` are adjusted to be inversely proportional to
 :math:`\rho(r_i)` .
 
+.. Sample code:
 
+   * (Python) An example of robust line fitting can be found at opencv_source_code/samples/python2/fitline.py
 
 isContourConvex
 -------------------
index 89c7c69..966a442 100644 (file)
@@ -258,7 +258,7 @@ PERF_TEST_P(Size_CvtMode, cvtColor8u,
     declare.time(100);
     declare.in(src, WARMUP_RNG).out(dst);
 
-    int runs = sz.width <= 320 ? 70 : 1;
+    int runs = sz.width <= 320 ? 100 : 5;
     TEST_CYCLE_MULTIRUN(runs) cvtColor(src, dst, mode, ch.dcn);
 
     SANITY_CHECK(dst, 1);
index 92db3be..1789470 100644 (file)
@@ -28,14 +28,14 @@ PERF_TEST_P(Size_Source, calcHist1d,
     int dims = 1;
     int numberOfImages = 1;
 
-    const float r[] = {rangeLow, rangeHight};
-    const float* ranges[] = {r};
+    const float range[] = {rangeLow, rangeHight};
+    const float* ranges[] = {range};
 
     randu(source, rangeLow, rangeHight);
 
     declare.in(source);
 
-    TEST_CYCLE()
+    TEST_CYCLE_MULTIRUN(3)
     {
         calcHist(&source, numberOfImages, channels, Mat(), hist, dims, histSize, ranges);
     }
diff --git a/modules/imgproc/perf/perf_precomp.cpp b/modules/imgproc/perf/perf_precomp.cpp
deleted file mode 100644 (file)
index 8552ac3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "perf_precomp.hpp"
index 7aef05e..7634644 100644 (file)
@@ -25,7 +25,7 @@ PERF_TEST_P(MatInfo_Size_Size, resizeUpLinear,
     cvtest::fillGradient(src);
     declare.in(src).out(dst);
 
-    TEST_CYCLE() resize(src, dst, to);
+    TEST_CYCLE_MULTIRUN(10) resize(src, dst, to);
 
 #ifdef ANDROID
     SANITY_CHECK(dst, 5);
@@ -52,7 +52,7 @@ PERF_TEST_P(MatInfo_Size_Size, resizeDownLinear,
     cvtest::fillGradient(src);
     declare.in(src).out(dst);
 
-    TEST_CYCLE() resize(src, dst, to);
+    TEST_CYCLE_MULTIRUN(10) resize(src, dst, to);
 
 #ifdef ANDROID
     SANITY_CHECK(dst, 5);
@@ -85,7 +85,8 @@ PERF_TEST_P(MatInfo_Size_Scale, ResizeAreaFast,
 
     declare.in(src, WARMUP_RNG).out(dst);
 
-    TEST_CYCLE() resize(src, dst, dst.size(), 0, 0, INTER_AREA);
+    int runs = 15;
+    TEST_CYCLE_MULTIRUN(runs) resize(src, dst, dst.size(), 0, 0, INTER_AREA);
 
     //difference equal to 1 is allowed because of different possible rounding modes: round-to-nearest vs bankers' rounding
     SANITY_CHECK(dst, 1);
index 01fff2e..9ccafd6 100644 (file)
@@ -51,7 +51,8 @@ PERF_TEST_P(Size_Only, threshold_otsu, testing::Values(TYPICAL_MAT_SIZES))
 
     declare.in(src, WARMUP_RNG).out(dst);
 
-    TEST_CYCLE() threshold(src, dst, 0, maxval, THRESH_BINARY|THRESH_OTSU);
+    int runs = 15;
+    TEST_CYCLE_MULTIRUN(runs) threshold(src, dst, 0, maxval, THRESH_BINARY|THRESH_OTSU);
 
     SANITY_CHECK(dst);
 }
index 41ca2db..fed7b73 100644 (file)
@@ -3457,7 +3457,7 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
         case CV_BGR2YUV: case CV_RGB2YUV:
             {
             CV_Assert( scn == 3 || scn == 4 );
-            bidx = code == CV_BGR2YCrCb || code == CV_RGB2YUV ? 0 : 2;
+            bidx = code == CV_BGR2YCrCb || code == CV_BGR2YUV ? 0 : 2;
             static const float yuv_f[] = { 0.114f, 0.587f, 0.299f, 0.492f, 0.877f };
             static const int yuv_i[] = { B2Y, G2Y, R2Y, 8061, 14369 };
             const float* coeffs_f = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_f;
@@ -3486,7 +3486,7 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
             {
             if( dcn <= 0 ) dcn = 3;
             CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) );
-            bidx = code == CV_YCrCb2BGR || code == CV_YUV2RGB ? 0 : 2;
+            bidx = code == CV_YCrCb2BGR || code == CV_YUV2BGR ? 0 : 2;
             static const float yuv_f[] = { 2.032f, -0.395f, -0.581f, 1.140f };
             static const int yuv_i[] = { 33292, -6472, -9519, 18678 };
             const float* coeffs_f = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_f;
index d3e6f90..a09b940 100644 (file)
@@ -779,6 +779,16 @@ cvDistTransform( const void* srcarr, void* dstarr,
 
         if( !labels )
         {
+        #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
+            if( maskSize == CV_DIST_MASK_5 )
+            {
+                IppiSize roi = { src->cols, src->rows };
+                if( ippiDistanceTransform_5x5_8u32f_C1R(
+                        src->data.ptr, src->step,
+                        dst->data.fl, dst->step, roi, _mask) >= 0 )
+                    return;
+            }
+        #endif
             CvDistTransFunc func = maskSize == CV_DIST_MASK_3 ?
                 icvDistanceTransform_3x3_C1R :
                 icvDistanceTransform_5x5_C1R;
index bfcdee5..18ff343 100644 (file)
@@ -270,6 +270,8 @@ public:
     }
 
 private:
+    calcHist1D_Invoker operator=(const calcHist1D_Invoker&);
+
     T* p_[one];
     uchar* mask_;
     int step_[one];
@@ -342,6 +344,8 @@ public:
     }
 
 private:
+    calcHist2D_Invoker operator=(const calcHist2D_Invoker&);
+
     T* p_[two];
     uchar* mask_;
     int step_[two];
@@ -432,6 +436,8 @@ public:
     }
 
 private:
+    calcHist3D_Invoker operator=(const calcHist3D_Invoker&);
+
     T* p_[three];
     uchar* mask_;
     int step_[three];
@@ -771,8 +777,7 @@ calcHist_( vector<uchar*>& _ptrs, const vector<int>& _deltas,
 #ifdef HAVE_TBB
             calcHist1D_Invoker<T> body(_ptrs, _deltas, hist, _uniranges, size[0], dims, imsize);
             parallel_for(BlockedRange(0, imsize.height), body);
-            return;
-#endif
+#else
             double a = uniranges[0], b = uniranges[1];
             int sz = size[0], d0 = deltas[0], step0 = deltas[1];
             const T* p0 = (const T*)ptrs[0];
@@ -795,14 +800,15 @@ calcHist_( vector<uchar*>& _ptrs, const vector<int>& _deltas,
                                 ((int*)H)[idx]++;
                         }
             }
+#endif //HAVE_TBB
+            return;
         }
         else if( dims == 2 )
         {
 #ifdef HAVE_TBB
             calcHist2D_Invoker<T> body(_ptrs, _deltas, hist, _uniranges, size, dims, imsize, hstep);
             parallel_for(BlockedRange(0, imsize.height), body);
-            return;
-#endif
+#else
             double a0 = uniranges[0], b0 = uniranges[1], a1 = uniranges[2], b1 = uniranges[3];
             int sz0 = size[0], sz1 = size[1];
             int d0 = deltas[0], step0 = deltas[1],
@@ -831,6 +837,8 @@ calcHist_( vector<uchar*>& _ptrs, const vector<int>& _deltas,
                                 ((int*)(H + hstep0*idx0))[idx1]++;
                         }
             }
+#endif //HAVE_TBB
+            return;
         }
         else if( dims == 3 )
         {
index 53d2347..fb901b7 100644 (file)
@@ -1136,11 +1136,151 @@ private:
     Scalar borderValue;
 };
 
+#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
+static bool IPPMorphReplicate(int op, const Mat &src, Mat &dst, const Mat &kernel, const Point &anchor)
+{
+       int type = src.type();
+       const Mat* _src = &src;
+       Mat temp;
+       if( src.data == dst.data )
+       {
+               src.copyTo(temp);
+               _src = &temp;
+       }
+       //DEPRECATED. Allocates and initializes morphology state structure for erosion or dilation operation.
+       typedef IppStatus (CV_STDCALL* ippiMorphologyInitAllocFunc)(int, const void*, IppiSize, IppiPoint, IppiMorphState **);
+       ippiMorphologyInitAllocFunc ippInitAllocFunc = 
+               type == CV_8UC1 ? (ippiMorphologyInitAllocFunc)ippiMorphologyInitAlloc_8u_C1R : 
+               type == CV_8UC3 ? (ippiMorphologyInitAllocFunc)ippiMorphologyInitAlloc_8u_C3R : 
+               type == CV_8UC4 ? (ippiMorphologyInitAllocFunc)ippiMorphologyInitAlloc_8u_C4R : 
+               type == CV_32FC1 ? (ippiMorphologyInitAllocFunc)ippiMorphologyInitAlloc_32f_C1R : 
+               type == CV_32FC3 ? (ippiMorphologyInitAllocFunc)ippiMorphologyInitAlloc_32f_C3R :
+               type == CV_32FC4 ? (ippiMorphologyInitAllocFunc)ippiMorphologyInitAlloc_32f_C4R :
+               0;
+       typedef IppStatus (CV_STDCALL* ippiMorphologyBorderReplicateFunc)(const void*, int, void *, int, IppiSize, IppiBorderType, IppiMorphState *);
+       ippiMorphologyBorderReplicateFunc ippFunc = 0;
+       switch( op )
+       {
+       case MORPH_DILATE:
+               {
+                       ippFunc = 
+                               type == CV_8UC1 ? (ippiMorphologyBorderReplicateFunc)ippiDilateBorderReplicate_8u_C1R : 
+                               type == CV_8UC3 ? (ippiMorphologyBorderReplicateFunc)ippiDilateBorderReplicate_8u_C3R : 
+                               type == CV_8UC4 ? (ippiMorphologyBorderReplicateFunc)ippiDilateBorderReplicate_8u_C4R : 
+                               type == CV_32FC1 ? (ippiMorphologyBorderReplicateFunc)ippiDilateBorderReplicate_32f_C1R :  
+                               type == CV_32FC3 ? (ippiMorphologyBorderReplicateFunc)ippiDilateBorderReplicate_32f_C3R :  
+                               type == CV_32FC4 ? (ippiMorphologyBorderReplicateFunc)ippiDilateBorderReplicate_32f_C4R :  
+                               0;
+                       break;
+               }
+       case MORPH_ERODE:
+               {
+                       ippFunc = 
+                               type == CV_8UC1 ? (ippiMorphologyBorderReplicateFunc)ippiErodeBorderReplicate_8u_C1R : 
+                               type == CV_8UC3 ? (ippiMorphologyBorderReplicateFunc)ippiErodeBorderReplicate_8u_C3R : 
+                               type == CV_8UC4 ? (ippiMorphologyBorderReplicateFunc)ippiErodeBorderReplicate_8u_C4R : 
+                               type == CV_32FC1 ? (ippiMorphologyBorderReplicateFunc)ippiErodeBorderReplicate_32f_C1R :  
+                               type == CV_32FC3 ? (ippiMorphologyBorderReplicateFunc)ippiErodeBorderReplicate_32f_C3R :  
+                               type == CV_32FC4 ? (ippiMorphologyBorderReplicateFunc)ippiErodeBorderReplicate_32f_C4R :  
+                               0;
+                       break;
+               }
+       }
+       if( ippFunc && ippInitAllocFunc)
+       {
+               IppiMorphState* pState;
+               IppiSize roiSize = {src.cols, src.rows};
+               IppiSize kernelSize = {kernel.cols, kernel.rows};
+               IppiPoint point = {anchor.x, anchor.y};
+               if( ippInitAllocFunc( roiSize.width, kernel.data, kernelSize, point, &pState ) < 0 )
+                       return false;
+               bool is_ok = ippFunc( _src->data, _src->step[0],  dst.data, dst.step[0], roiSize, ippBorderRepl, pState ) >= 0;
+               ippiMorphologyFree(pState);
+               return is_ok;
+       }
+       return false;
+}
+
+static bool IPPMorphOp(int op, InputArray _src, OutputArray _dst,
+       InputArray _kernel,
+       const Point &anchor, int iterations,
+       int borderType, const Scalar &borderValue)
+{
+       Mat src = _src.getMat(), kernel = _kernel.getMat();
+       if( !( src.depth() == CV_8U || src.depth() == CV_32F ) || ( iterations > 1 ) || 
+               !( borderType == cv::BORDER_REPLICATE || (borderType == cv::BORDER_CONSTANT && borderValue == morphologyDefaultBorderValue()) ) 
+               || !( op == MORPH_DILATE || op == MORPH_ERODE) )
+               return false;
+       if( borderType == cv::BORDER_CONSTANT )
+       {
+               int x, y;
+               for( y = 0; y < kernel.rows; y++ )
+               {
+                       if( kernel.at<uchar>(y, anchor.x) != 0 )
+                               continue;
+                       for( x = 0; x < kernel.cols; x++ )
+                       {
+                               if( kernel.at<uchar>(y,x) != 0 )
+                                       return false;
+                       }
+               }
+               for( x = 0; y < kernel.cols; x++ )
+               {
+                       if( kernel.at<uchar>(anchor.y, x) != 0 )
+                               continue;
+                       for( y = 0; y < kernel.rows; y++ )
+                       {
+                               if( kernel.at<uchar>(y,x) != 0 )
+                                       return false;
+                       }
+               }
+
+       }
+       Size ksize = kernel.data ? kernel.size() : Size(3,3);
+       Point normanchor = normalizeAnchor(anchor, ksize);
+
+       CV_Assert( normanchor.inside(Rect(0, 0, ksize.width, ksize.height)) );
+
+       _dst.create( src.size(), src.type() );
+       Mat dst = _dst.getMat();
+
+       if( iterations == 0 || kernel.rows*kernel.cols == 1 )
+       {
+               src.copyTo(dst);
+               return true;
+       }
+
+       if( !kernel.data )
+       {
+               kernel = getStructuringElement(MORPH_RECT, Size(1+iterations*2,1+iterations*2));
+               normanchor = Point(iterations, iterations);
+               iterations = 1;
+       }
+       else if( iterations > 1 && countNonZero(kernel) == kernel.rows*kernel.cols )
+       {
+               normanchor = Point(normanchor.x*iterations, normanchor.y*iterations);
+               kernel = getStructuringElement(MORPH_RECT,
+                       Size(ksize.width + (iterations-1)*(ksize.width-1),
+                       ksize.height + (iterations-1)*(ksize.height-1)),
+                       normanchor);
+               iterations = 1;
+       }
+
+       return IPPMorphReplicate( op, src, dst, kernel, normanchor );
+}
+#endif
+
 static void morphOp( int op, InputArray _src, OutputArray _dst,
                      InputArray _kernel,
                      Point anchor, int iterations,
                      int borderType, const Scalar& borderValue )
 {
+
+#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
+       if( IPPMorphOp(op, _src, _dst, _kernel, anchor, iterations, borderType, borderValue) )
+               return;
+#endif
+
     Mat src = _src.getMat(), kernel = _kernel.getMat();
     Size ksize = kernel.data ? kernel.size() : Size(3,3);
     anchor = normalizeAnchor(anchor, ksize);
diff --git a/modules/imgproc/src/precomp.cpp b/modules/imgproc/src/precomp.cpp
deleted file mode 100644 (file)
index 3e0ec42..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*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 "precomp.hpp"
-
-/* End of file. */
index 842a15c..20101b7 100644 (file)
@@ -43,9 +43,7 @@
 #ifndef __OPENCV_PRECOMP_H__
 #define __OPENCV_PRECOMP_H__
 
-#ifdef HAVE_CVCONFIG_H
 #include "cvconfig.h"
-#endif
 
 #include "opencv2/imgproc/imgproc.hpp"
 #include "opencv2/imgproc/imgproc_c.h"
index e6d2d12..eb2f617 100644 (file)
@@ -519,6 +519,12 @@ typedef CvStatus (CV_STDCALL *CvGetRectSubPixFunc)( const void* src, int src_ste
                                                     int dst_step, CvSize win_size,
                                                     CvPoint2D32f center );
 
+typedef CvStatus (CV_STDCALL *CvIPPGetRectSubPixFunc)( const void* src, int src_step,
+                                                       CvSize src_size, void* dst,
+                                                       int dst_step, CvSize win_size,
+                                                       CvPoint2D32f center,
+                                                       CvPoint* minpt, CvPoint* maxpt );
+
 CV_IMPL void
 cvGetRectSubPix( const void* srcarr, void* dstarr, CvPoint2D32f center )
 {
@@ -556,6 +562,18 @@ cvGetRectSubPix( const void* srcarr, void* dstarr, CvPoint2D32f center )
 
     //if( dst_size.width > src_size.width || dst_size.height > src_size.height )
     //    CV_ERROR( CV_StsBadSize, "destination ROI must be smaller than source ROI" );
+#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
+    CvPoint minpt, maxpt;
+    int srctype = CV_MAT_TYPE(src->type), dsttype = CV_MAT_TYPE(dst->type);
+    CvIPPGetRectSubPixFunc ippfunc =
+        srctype == CV_8UC1 && dsttype == CV_8UC1 ? (CvIPPGetRectSubPixFunc)ippiCopySubpixIntersect_8u_C1R :
+        srctype == CV_8UC1 && dsttype == CV_32FC1 ? (CvIPPGetRectSubPixFunc)ippiCopySubpixIntersect_8u32f_C1R :
+        srctype == CV_32FC1 && dsttype == CV_32FC1 ? (CvIPPGetRectSubPixFunc)ippiCopySubpixIntersect_32f_C1R : 0;
+
+    if( ippfunc && ippfunc(src->data.ptr, src->step, src_size, dst->data.ptr,
+                           dst->step, dst_size, center, &minpt, &maxpt) >= 0 )
+        return;
+#endif
 
     if( CV_ARE_DEPTHS_EQ( src, dst ))
     {
index b1bc1ba..c6c49a1 100644 (file)
@@ -804,7 +804,7 @@ cvFitEllipse2( const CvArr* array )
     CvPoint2D32f c = {0,0};
     double gfp[5], rp[5], t;
     CvMat A, b, x;
-    const double min_eps = 1e-6;
+    const double min_eps = 1e-8;
     int i, is_float;
     CvSeqReader reader;
 
index c84abe5..00be086 100644 (file)
@@ -856,6 +856,22 @@ void cv::GaussianBlur( InputArray _src, OutputArray _dst, Size ksize,
         return;
 #endif
 
+#if defined HAVE_IPP && (IPP_VERSION_MAJOR >= 7)
+    if(src.type() == CV_32FC1 && sigma1 == sigma2 && ksize.width == ksize.height && sigma1 != 0.0 )
+    {
+        IppiSize roi = {src.cols, src.rows};
+        int bufSize = 0;
+        ippiFilterGaussGetBufferSize_32f_C1R(roi, ksize.width, &bufSize);
+        AutoBuffer<uchar> buf(bufSize+128);
+        if( ippiFilterGaussBorder_32f_C1R((const Ipp32f *)src.data, (int)src.step,
+                                          (Ipp32f *)dst.data, (int)dst.step,
+                                          roi, ksize.width, (Ipp32f)sigma1,
+                                          (IppiBorderType)borderType, 0.0,
+                                          alignPtr(&buf[0],32)) >= 0 )
+            return;
+    }
+#endif
+
     Ptr<FilterEngine> f = createGaussianFilter( src.type(), ksize, sigma1, sigma2, borderType );
     f->apply( src, dst );
 }
@@ -1888,6 +1904,29 @@ bilateralFilter_8u( const Mat& src, Mat& dst, int d,
     radius = MAX(radius, 1);
     d = radius*2 + 1;
 
+#if 0 && defined HAVE_IPP && (IPP_VERSION_MAJOR >= 7)
+    if(cn == 1)
+    {
+        IppiSize kernel = {d, d};
+        IppiSize roi={src.cols, src.rows};
+        int bufsize=0;
+        ippiFilterBilateralGetBufSize_8u_C1R( ippiFilterBilateralGauss, roi, kernel, &bufsize);
+        AutoBuffer<uchar> buf(bufsize+128);
+        IppiFilterBilateralSpec *pSpec = (IppiFilterBilateralSpec *)alignPtr(&buf[0], 32);
+        ippiFilterBilateralInit_8u_C1R( ippiFilterBilateralGauss, kernel, sigma_color*sigma_color, sigma_space*sigma_space, 1, pSpec );
+        Mat tsrc;
+        const Mat* psrc = &src;
+        if( src.data == dst.data )
+        {
+            src.copyTo(tsrc);
+            psrc = &tsrc;
+        }
+        if( ippiFilterBilateral_8u_C1R(psrc->data, (int)psrc->step[0],
+                                       dst.data, (int)dst.step[0],
+                                       roi, kernel, pSpec) >= 0 )
+            return;
+    }
+#endif
     Mat temp;
     copyMakeBorder( src, temp, radius, radius, radius, radius, borderType );
 
index b441970..4ee9417 100644 (file)
@@ -41,6 +41,9 @@
 //M*/
 
 #include "precomp.hpp"
+#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
+static IppStatus sts = ippInit();
+#endif
 
 namespace cv
 {
@@ -234,6 +237,53 @@ void cv::integral( InputArray _src, OutputArray _sum, OutputArray _sqsum, Output
     if( sdepth <= 0 )
         sdepth = depth == CV_8U ? CV_32S : CV_64F;
     sdepth = CV_MAT_DEPTH(sdepth);
+
+#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
+       if( ( depth == CV_8U ) && ( !_tilted.needed() ) )
+       {
+               if( sdepth == CV_32F )
+               {
+                       if( cn == 1 )
+                       {
+                               IppiSize srcRoiSize = ippiSize( src.cols, src.rows );
+                               _sum.create( isize, CV_MAKETYPE( sdepth, cn ) );
+                               sum = _sum.getMat();
+                               if( _sqsum.needed() )
+                               {
+                                       _sqsum.create( isize, CV_MAKETYPE( CV_64F, cn ) );
+                                       sqsum = _sqsum.getMat();
+                                       ippiSqrIntegral_8u32f64f_C1R( (const Ipp8u*)src.data, src.step, (Ipp32f*)sum.data, sum.step, (Ipp64f*)sqsum.data, sqsum.step, srcRoiSize, 0, 0 );
+                               }
+                               else
+                               {
+                                       ippiIntegral_8u32f_C1R( (const Ipp8u*)src.data, src.step, (Ipp32f*)sum.data, sum.step, srcRoiSize, 0 );
+                               }
+                               return;
+                       }
+               }
+               if( sdepth == CV_32S )
+               {
+                       if( cn == 1 )
+                       {
+                               IppiSize srcRoiSize = ippiSize( src.cols, src.rows );
+                               _sum.create( isize, CV_MAKETYPE( sdepth, cn ) );
+                               sum = _sum.getMat();
+                               if( _sqsum.needed() )
+                               {
+                                       _sqsum.create( isize, CV_MAKETYPE( CV_64F, cn ) );
+                                       sqsum = _sqsum.getMat();
+                                       ippiSqrIntegral_8u32s64f_C1R( (const Ipp8u*)src.data, src.step, (Ipp32s*)sum.data, sum.step, (Ipp64f*)sqsum.data, sqsum.step, srcRoiSize, 0, 0 );
+                               }
+                               else
+                               {
+                                       ippiIntegral_8u32s_C1R( (const Ipp8u*)src.data, src.step, (Ipp32s*)sum.data, sum.step, srcRoiSize, 0 );
+                               }
+                               return;
+                       }
+               }
+       }
+#endif
+
     _sum.create( isize, CV_MAKETYPE(sdepth, cn) );
     sum = _sum.getMat();
 
index ec7a92a..18d7da9 100644 (file)
@@ -248,6 +248,8 @@ void cv::matchTemplate( InputArray _img, InputArray _templ, OutputArray _result,
     CV_Assert( (img.depth() == CV_8U || img.depth() == CV_32F) &&
                img.type() == templ.type() );
 
+    CV_Assert( img.rows >= templ.rows && img.cols >= templ.cols);
+
     Size corrSize(img.cols - templ.cols + 1, img.rows - templ.rows + 1);
     _result.create(corrSize, CV_32F);
     Mat result = _result.getMat();
diff --git a/modules/imgproc/test/test_precomp.cpp b/modules/imgproc/test/test_precomp.cpp
deleted file mode 100644 (file)
index 5956e13..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "test_precomp.hpp"
index 2dc4aea..9425e26 100644 (file)
@@ -17,8 +17,6 @@ import android.util.Log;
 
 /**
  * This only class is Android specific.
- *
- * @see <a href="http://opencv.itseez.com">OpenCV</a>
  */
 
 public class OpenCVTestRunner extends InstrumentationTestRunner {
index 8bcaf58..db806b6 100644 (file)
@@ -585,4 +585,18 @@ public class Calib3dTest extends OpenCVTestCase {
     public void testValidateDisparityMatMatIntIntInt() {
         fail("Not yet implemented");
     }
+
+    public void testComputeCorrespondEpilines()
+    {
+        Mat fundamental = new Mat(3, 3, CvType.CV_64F);
+        fundamental.put(0, 0, 0, -0.577, 0.288, 0.577, 0, 0.288, -0.288, -0.288, 0);
+        MatOfPoint2f left = new MatOfPoint2f();
+        left.alloc(1);
+        left.put(0, 0, 2, 3); //add(new Point(x, y));
+        Mat lines = new Mat();
+        Mat truth = new Mat(1, 1, CvType.CV_32FC3);
+        truth.put(0, 0, -0.70735186, 0.70686162, -0.70588124);
+        Calib3d.computeCorrespondEpilines(left, 1, fundamental, lines);
+        assertMatEqual(truth, lines, EPS);
+    }
 }
index a6023c7..45e4353 100644 (file)
@@ -491,20 +491,6 @@ public class CoreTest extends OpenCVTestCase {
 
         Point truth[] = {
                 new Point(5, 6),
-                new Point(5, 6),
-                new Point(5, 6),
-                new Point(5, 6),
-                new Point(5, 6),
-                new Point(5, 6),
-                new Point(5, 6),
-                new Point(5, 6),
-                new Point(4, 6),
-                new Point(4, 6),
-                new Point(4, 6),
-                new Point(4, 6),
-                new Point(4, 6),
-                new Point(4, 6),
-                new Point(4, 6),
                 new Point(4, 6)
         };
         assertArrayPointsEquals(truth, pts.toArray(), EPS);
index 726dcaf..b651b4d 100644 (file)
@@ -1,12 +1,37 @@
 #define LOG_TAG "org.opencv.core.Mat"
 
+#include <stdexcept>
+
 #include "common.h"
 #include "opencv2/core/core.hpp"
 
 using namespace cv;
 
-extern "C" {
+/// throw java exception
+static void throwJavaException(JNIEnv *env, const std::exception *e, const char *method) {
+  std::string what = "unknown exception";
+  jclass je = 0;
+  
+  if(e) {
+    std::string exception_type = "std::exception";
+    
+    if(dynamic_cast<const cv::Exception*>(e)) {
+      exception_type = "cv::Exception";
+      je = env->FindClass("org/opencv/core/CvException");
+    }
+
+    what = exception_type + ": " + e->what();
+  }
+  
+  if(!je) je = env->FindClass("java/lang/Exception");
+  env->ThrowNew(je, what.c_str());
+  
+  LOGE("%s caught %s", method, what.c_str());
+  (void)method;        // avoid "unused" warning
+}
 
+extern "C" {
+  
 
 //
 //   MatXXX::MatXXX()
@@ -35,24 +60,17 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1Mat__III
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1Mat__III
   (JNIEnv* env, jclass, jint rows, jint cols, jint type)
 {
+    static const char method_name[] = "Mat::n_1Mat__III()";
     try {
-        LOGD("Mat::n_1Mat__III()");
-
-        Mat* _retval_ = new Mat( rows, cols, type );
-
-        return (jlong) _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1Mat__III() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        LOGD("%s", method_name);
+        return (jlong) new Mat( rows, cols, type );
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1Mat__III() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1Mat__III()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -67,24 +85,18 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1Mat__DDI
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1Mat__DDI
   (JNIEnv* env, jclass, jdouble size_width, jdouble size_height, jint type)
 {
+    static const char method_name[] = "Mat::n_1Mat__DDI()";
     try {
-        LOGD("Mat::n_1Mat__DDI()");
+        LOGD("%s", method_name);
         Size size((int)size_width, (int)size_height);
-        Mat* _retval_ = new Mat( size, type );
-
-        return (jlong) _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1Mat__DDI() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return (jlong) new Mat( size, type );
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1Mat__DDI() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1Mat__DDI()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -100,24 +112,18 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1Mat__IIIDDDD
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1Mat__IIIDDDD
   (JNIEnv* env, jclass, jint rows, jint cols, jint type, jdouble s_val0, jdouble s_val1, jdouble s_val2, jdouble s_val3)
 {
+    static const char method_name[] = "Mat::n_1Mat__IIIDDDD()";
     try {
-        LOGD("Mat::n_1Mat__IIIDDDD()");
+        LOGD("%s", method_name);
         Scalar s(s_val0, s_val1, s_val2, s_val3);
-        Mat* _retval_ = new Mat( rows, cols, type, s );
-
-        return (jlong) _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1Mat__IIIDDDD() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return (jlong) new Mat( rows, cols, type, s );
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1Mat__IIIDDDD() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1Mat__IIIDDDD()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -132,25 +138,19 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1Mat__DDIDDDD
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1Mat__DDIDDDD
   (JNIEnv* env, jclass, jdouble size_width, jdouble size_height, jint type, jdouble s_val0, jdouble s_val1, jdouble s_val2, jdouble s_val3)
 {
+    static const char method_name[] = "Mat::n_1Mat__DDIDDDD()";
     try {
-        LOGD("Mat::n_1Mat__DDIDDDD()");
+        LOGD("%s", method_name);
         Size size((int)size_width, (int)size_height);
         Scalar s(s_val0, s_val1, s_val2, s_val3);
-        Mat* _retval_ = new Mat( size, type, s );
-
-        return (jlong) _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1Mat__DDIDDDD() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return (jlong) new Mat( size, type, s );
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1Mat__DDIDDDD() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1Mat__DDIDDDD()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -165,25 +165,19 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1Mat__JIIII
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1Mat__JIIII
   (JNIEnv* env, jclass, jlong m_nativeObj, jint rowRange_start, jint rowRange_end, jint colRange_start, jint colRange_end)
 {
+    static const char method_name[] = "Mat::n_1Mat__JIIII()";
     try {
-        LOGD("Mat::n_1Mat__JIIII()");
+        LOGD("%s", method_name);
         Range rowRange(rowRange_start, rowRange_end);
         Range colRange(colRange_start, colRange_end);
-        Mat* _retval_ = new Mat( (*(Mat*)m_nativeObj), rowRange, colRange );
-
-        return (jlong) _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1Mat__JIIII() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return (jlong) new Mat( (*(Mat*)m_nativeObj), rowRange, colRange );
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1Mat__JIIII() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1Mat__JIIII()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -194,24 +188,18 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1Mat__JII
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1Mat__JII
   (JNIEnv* env, jclass, jlong m_nativeObj, jint rowRange_start, jint rowRange_end)
 {
+    static const char method_name[] = "Mat::n_1Mat__JII()";
     try {
-        LOGD("Mat::n_1Mat__JII()");
+        LOGD("%s", method_name);
         Range rowRange(rowRange_start, rowRange_end);
-        Mat* _retval_ = new Mat( (*(Mat*)m_nativeObj), rowRange );
-
-        return (jlong) _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1Mat__JII() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return (jlong) new Mat( (*(Mat*)m_nativeObj), rowRange );
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1Mat__JII() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1Mat__JII()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -225,24 +213,19 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1adjustROI
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1adjustROI
   (JNIEnv* env, jclass, jlong self, jint dtop, jint dbottom, jint dleft, jint dright)
 {
+    static const char method_name[] = "Mat::n_1adjustROI()";
     try {
-        LOGD("Mat::n_1adjustROI()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat _retval_ = me->adjustROI( dtop, dbottom, dleft, dright );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1adjustROI() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1adjustROI() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1adjustROI()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -257,23 +240,15 @@ JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1assignTo__JJI
 JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1assignTo__JJI
   (JNIEnv* env, jclass, jlong self, jlong m_nativeObj, jint type)
 {
+    static const char method_name[] = "Mat::n_1assignTo__JJI()";
     try {
-        LOGD("Mat::n_1assignTo__JJI()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         me->assignTo( (*(Mat*)m_nativeObj), type );
-
-        return;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1assignTo__JJI() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1assignTo__JJI() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1assignTo__JJI()}");
-        return;
+        throwJavaException(env, 0, method_name);
     }
 }
 
@@ -284,23 +259,15 @@ JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1assignTo__JJ
 JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1assignTo__JJ
   (JNIEnv* env, jclass, jlong self, jlong m_nativeObj)
 {
+    static const char method_name[] = "Mat::n_1assignTo__JJ()";
     try {
-        LOGD("Mat::n_1assignTo__JJ()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         me->assignTo( (*(Mat*)m_nativeObj) );
-
-        return;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1assignTo__JJ() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1assignTo__JJ() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1assignTo__JJ()}");
-        return;
+        throwJavaException(env, 0, method_name);
     }
 }
 
@@ -316,24 +283,18 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_n_1channels
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_n_1channels
   (JNIEnv* env, jclass, jlong self)
 {
+    static const char method_name[] = "Mat::n_1channels()";
     try {
-        LOGD("Mat::n_1channels()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
-        int _retval_ = me->channels(  );
-
-        return _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1channels() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return me->channels(  );
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1channels() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1channels()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -348,24 +309,18 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_n_1checkVector__JIIZ
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_n_1checkVector__JIIZ
   (JNIEnv* env, jclass, jlong self, jint elemChannels, jint depth, jboolean requireContinuous)
 {
+    static const char method_name[] = "Mat::n_1checkVector__JIIZ()";
     try {
-        LOGD("Mat::n_1checkVector__JIIZ()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
-        int _retval_ = me->checkVector( elemChannels, depth, requireContinuous );
-
-        return _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1checkVector__JIIZ() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return me->checkVector( elemChannels, depth, requireContinuous );
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1checkVector__JIIZ() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1checkVector__JIIZ()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -376,24 +331,18 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_n_1checkVector__JII
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_n_1checkVector__JII
   (JNIEnv* env, jclass, jlong self, jint elemChannels, jint depth)
 {
+    static const char method_name[] = "Mat::n_1checkVector__JII()";
     try {
-        LOGD("Mat::n_1checkVector__JII()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
-        int _retval_ = me->checkVector( elemChannels, depth );
-
-        return _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1checkVector__JII() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return me->checkVector( elemChannels, depth );
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1checkVector__JII() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1checkVector__JII()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -404,24 +353,18 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_n_1checkVector__JI
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_n_1checkVector__JI
   (JNIEnv* env, jclass, jlong self, jint elemChannels)
 {
+    static const char method_name[] = "Mat::n_1checkVector__JI()";
     try {
-        LOGD("Mat::n_1checkVector__JI()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
-        int _retval_ = me->checkVector( elemChannels );
-
-        return _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1checkVector__JI() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return me->checkVector( elemChannels );
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1checkVector__JI() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1checkVector__JI()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -437,24 +380,19 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1clone
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1clone
   (JNIEnv* env, jclass, jlong self)
 {
+    static const char method_name[] = "Mat::n_1clone()";
     try {
-        LOGD("Mat::n_1clone()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat _retval_ = me->clone(  );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1clone() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1clone() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1clone()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -469,24 +407,19 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1col
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1col
   (JNIEnv* env, jclass, jlong self, jint x)
 {
+    static const char method_name[] = "Mat::n_1col()";
     try {
-        LOGD("Mat::n_1col()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat _retval_ = me->col( x );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1col() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1col() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1col()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -501,24 +434,45 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1colRange
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1colRange
   (JNIEnv* env, jclass, jlong self, jint startcol, jint endcol)
 {
+    static const char method_name[] = "Mat::n_1colRange()";
     try {
-        LOGD("Mat::n_1colRange()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat _retval_ = me->colRange( startcol, endcol );
-
         return (jlong) new Mat(_retval_);
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
+    } catch (...) {
+        throwJavaException(env, 0, method_name);
+    }
+    
+    return 0;
+}
+
+
+
+//
+//  int Mat::dims()
+//
+  
+JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_n_1dims
+  (JNIEnv* env, jclass, jlong self);
+
+JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_n_1dims
+  (JNIEnv* env, jclass, jlong self)
+{
+    static const char method_name[] = "Mat::n_1dims()";
+    try {
+        LOGD("%s", method_name);
+        Mat* me = (Mat*) self; //TODO: check for NULL
+        return me->dims;
     } catch(cv::Exception e) {
-        LOGD("Mat::n_1colRange() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1colRange() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1colRange()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -533,24 +487,18 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_n_1cols
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_n_1cols
   (JNIEnv* env, jclass, jlong self)
 {
+    static const char method_name[] = "Mat::n_1cols()";
     try {
-        LOGD("Mat::n_1cols()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
-        int _retval_ = me->cols;
-
-        return _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1cols() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return me->cols;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1cols() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1cols()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -565,24 +513,16 @@ JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1convertTo__JJIDD
 JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1convertTo__JJIDD
   (JNIEnv* env, jclass, jlong self, jlong m_nativeObj, jint rtype, jdouble alpha, jdouble beta)
 {
+    static const char method_name[] = "Mat::n_1convertTo__JJIDD()";
     try {
-        LOGD("Mat::n_1convertTo__JJIDD()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat& m = *((Mat*)m_nativeObj);
         me->convertTo( m, rtype, alpha, beta );
-
-        return;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1convertTo__JJIDD() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1convertTo__JJIDD() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1convertTo__JJIDD()}");
-        return;
+        throwJavaException(env, 0, method_name);
     }
 }
 
@@ -593,24 +533,16 @@ JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1convertTo__JJID
 JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1convertTo__JJID
   (JNIEnv* env, jclass, jlong self, jlong m_nativeObj, jint rtype, jdouble alpha)
 {
+    static const char method_name[] = "Mat::n_1convertTo__JJID()";
     try {
-        LOGD("Mat::n_1convertTo__JJID()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat& m = *((Mat*)m_nativeObj);
         me->convertTo( m, rtype, alpha );
-
-        return;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1convertTo__JJID() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1convertTo__JJID() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1convertTo__JJID()}");
-        return;
+        throwJavaException(env, 0, method_name);
     }
 }
 
@@ -621,24 +553,16 @@ JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1convertTo__JJI
 JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1convertTo__JJI
   (JNIEnv* env, jclass, jlong self, jlong m_nativeObj, jint rtype)
 {
+    static const char method_name[] = "Mat::n_1convertTo__JJI()";
     try {
-        LOGD("Mat::n_1convertTo__JJI()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat& m = *((Mat*)m_nativeObj);
         me->convertTo( m, rtype );
-
-        return;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1convertTo__JJI() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1convertTo__JJI() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1convertTo__JJI()}");
-        return;
+        throwJavaException(env, 0, method_name);
     }
 }
 
@@ -654,24 +578,16 @@ JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1copyTo__JJ
 JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1copyTo__JJ
   (JNIEnv* env, jclass, jlong self, jlong m_nativeObj)
 {
+    static const char method_name[] = "Mat::n_1copyTo__JJ()";
     try {
-        LOGD("Mat::n_1copyTo__JJ()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat& m = *((Mat*)m_nativeObj);
         me->copyTo( m );
-
-        return;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1copyTo__JJ() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1copyTo__JJ() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1copyTo__JJ()}");
-        return;
+        throwJavaException(env, 0, method_name);
     }
 }
 
@@ -687,25 +603,17 @@ JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1copyTo__JJJ
 JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1copyTo__JJJ
   (JNIEnv* env, jclass, jlong self, jlong m_nativeObj, jlong mask_nativeObj)
 {
+    static const char method_name[] = "Mat::n_1copyTo__JJJ()";
     try {
-        LOGD("Mat::n_1copyTo__JJJ()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat& m = *((Mat*)m_nativeObj);
         Mat& mask = *((Mat*)mask_nativeObj);
         me->copyTo( m, mask );
-
-        return;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1copyTo__JJJ() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1copyTo__JJJ() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1copyTo__JJJ()}");
-        return;
+        throwJavaException(env, 0, method_name);
     }
 }
 
@@ -721,23 +629,15 @@ JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1create__JIII
 JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1create__JIII
   (JNIEnv* env, jclass, jlong self, jint rows, jint cols, jint type)
 {
+    static const char method_name[] = "Mat::n_1create__JIII()";
     try {
-        LOGD("Mat::n_1create__JIII()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         me->create( rows, cols, type );
-
-        return;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1create__JIII() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1create__JIII() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1create__JIII()}");
-        return;
+        throwJavaException(env, 0, method_name);
     }
 }
 
@@ -753,24 +653,16 @@ JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1create__JDDI
 JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1create__JDDI
   (JNIEnv* env, jclass, jlong self, jdouble size_width, jdouble size_height, jint type)
 {
+    static const char method_name[] = "Mat::n_1create__JDDI()";
     try {
-        LOGD("Mat::n_1create__JDDI()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Size size((int)size_width, (int)size_height);
         me->create( size, type );
-
-        return;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1create__JDDI() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1create__JDDI() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1create__JDDI()}");
-        return;
+        throwJavaException(env, 0, method_name);
     }
 }
 
@@ -786,25 +678,20 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1cross
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1cross
   (JNIEnv* env, jclass, jlong self, jlong m_nativeObj)
 {
+    static const char method_name[] = "Mat::n_1cross()";
     try {
-        LOGD("Mat::n_1cross()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat& m = *((Mat*)m_nativeObj);
         Mat _retval_ = me->cross( m );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1cross() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1cross() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1cross()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -836,24 +723,18 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_n_1depth
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_n_1depth
   (JNIEnv* env, jclass, jlong self)
 {
+    static const char method_name[] = "Mat::n_1depth()";
     try {
-        LOGD("Mat::n_1depth()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
-        int _retval_ = me->depth(  );
-
-        return _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1depth() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return me->depth(  );
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1depth() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1depth()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -868,24 +749,19 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1diag__JI
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1diag__JI
   (JNIEnv* env, jclass, jlong self, jint d)
 {
+    static const char method_name[] = "Mat::n_1diag__JI()";
     try {
-        LOGD("Mat::n_1diag__JI()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat _retval_ = me->diag( d );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1diag__JI() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1diag__JI() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1diag__JI()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -901,24 +777,18 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1diag__J
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1diag__J
   (JNIEnv* env, jclass, jlong d_nativeObj)
 {
+    static const char method_name[] = "Mat::n_1diag__J()";
     try {
-        LOGD("Mat::n_1diag__J()");
-
+        LOGD("%s", method_name);
         Mat _retval_ = Mat::diag( (*(Mat*)d_nativeObj) );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1diag__J() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1diag__J() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1diag__J()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -933,25 +803,19 @@ JNIEXPORT jdouble JNICALL Java_org_opencv_core_Mat_n_1dot
 JNIEXPORT jdouble JNICALL Java_org_opencv_core_Mat_n_1dot
   (JNIEnv* env, jclass, jlong self, jlong m_nativeObj)
 {
+    static const char method_name[] = "Mat::n_1dot()";
     try {
-        LOGD("Mat::n_1dot()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat& m = *((Mat*)m_nativeObj);
-        double _retval_ = me->dot( m );
-
-        return _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1dot() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return me->dot( m );
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1dot() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1dot()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -966,24 +830,18 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1elemSize
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1elemSize
   (JNIEnv* env, jclass, jlong self)
 {
+    static const char method_name[] = "Mat::n_1elemSize()";
     try {
-        LOGD("Mat::n_1elemSize()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
-        size_t _retval_ = me->elemSize(  );
-
-        return _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1elemSize() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return me->elemSize(  );
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1elemSize() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1elemSize()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -998,24 +856,18 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1elemSize1
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1elemSize1
   (JNIEnv* env, jclass, jlong self)
 {
+    static const char method_name[] = "Mat::n_1elemSize1()";
     try {
-        LOGD("Mat::n_1elemSize1()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
-        size_t _retval_ = me->elemSize1(  );
-
-        return _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1elemSize1() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return me->elemSize1(  );
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1elemSize1() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1elemSize1()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -1030,24 +882,18 @@ JNIEXPORT jboolean JNICALL Java_org_opencv_core_Mat_n_1empty
 JNIEXPORT jboolean JNICALL Java_org_opencv_core_Mat_n_1empty
   (JNIEnv* env, jclass, jlong self)
 {
+    static const char method_name[] = "Mat::n_1empty()";
     try {
-        LOGD("Mat::n_1empty()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
-        bool _retval_ = me->empty(  );
-
-        return _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1empty() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return me->empty(  );
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1empty() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1empty()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -1062,24 +908,18 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1eye__III
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1eye__III
   (JNIEnv* env, jclass, jint rows, jint cols, jint type)
 {
+    static const char method_name[] = "Mat::n_1eye__III()";
     try {
-        LOGD("Mat::n_1eye__III()");
-
+        LOGD("%s", method_name);
         Mat _retval_ = Mat::eye( rows, cols, type );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1eye__III() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1eye__III() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1eye__III()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -1094,24 +934,19 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1eye__DDI
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1eye__DDI
   (JNIEnv* env, jclass, jdouble size_width, jdouble size_height, jint type)
 {
+    static const char method_name[] = "Mat::n_1eye__DDI()";
     try {
-        LOGD("Mat::n_1eye__DDI()");
+        LOGD("%s", method_name);
         Size size((int)size_width, (int)size_height);
         Mat _retval_ = Mat::eye( size, type );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1eye__DDI() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1eye__DDI() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1eye__DDI()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -1126,24 +961,19 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1inv__JI
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1inv__JI
   (JNIEnv* env, jclass, jlong self, jint method)
 {
+    static const char method_name[] = "Mat::n_1inv__JI()";
     try {
-        LOGD("Mat::n_1inv__JI()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat _retval_ = me->inv( method );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1inv__JI() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1inv__JI() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1inv__JI()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -1153,24 +983,19 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1inv__J
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1inv__J
   (JNIEnv* env, jclass, jlong self)
 {
+    static const char method_name[] = "Mat::n_1inv__J()";
     try {
-        LOGD("Mat::n_1inv__J()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat _retval_ = me->inv(  );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1inv__J() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1inv__J() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1inv__J()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -1185,24 +1010,18 @@ JNIEXPORT jboolean JNICALL Java_org_opencv_core_Mat_n_1isContinuous
 JNIEXPORT jboolean JNICALL Java_org_opencv_core_Mat_n_1isContinuous
   (JNIEnv* env, jclass, jlong self)
 {
+    static const char method_name[] = "Mat::n_1isContinuous()";
     try {
-        LOGD("Mat::n_1isContinuous()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
-        bool _retval_ = me->isContinuous(  );
-
-        return _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1isContinuous() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return me->isContinuous(  );
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1isContinuous() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1isContinuous()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -1217,24 +1036,18 @@ JNIEXPORT jboolean JNICALL Java_org_opencv_core_Mat_n_1isSubmatrix
 JNIEXPORT jboolean JNICALL Java_org_opencv_core_Mat_n_1isSubmatrix
   (JNIEnv* env, jclass, jlong self)
 {
+    static const char method_name[] = "Mat::n_1isSubmatrix()";
     try {
-        LOGD("Mat::n_1isSubmatrix()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
-        bool _retval_ = me->isSubmatrix(  );
-
-        return _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1isSubmatrix() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return me->isSubmatrix(  );
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1isSubmatrix() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1isSubmatrix()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -1249,25 +1062,18 @@ JNIEXPORT void JNICALL Java_org_opencv_core_Mat_locateROI_10
 JNIEXPORT void JNICALL Java_org_opencv_core_Mat_locateROI_10
   (JNIEnv* env, jclass, jlong self, jdoubleArray wholeSize_out, jdoubleArray ofs_out)
 {
+    static const char method_name[] = "core::locateROI_10()";
     try {
-        LOGD("core::locateROI_10()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Size wholeSize;
         Point ofs;
         me->locateROI( wholeSize, ofs );
         jdouble tmp_wholeSize[2] = {wholeSize.width, wholeSize.height}; env->SetDoubleArrayRegion(wholeSize_out, 0, 2, tmp_wholeSize);  jdouble tmp_ofs[2] = {ofs.x, ofs.y}; env->SetDoubleArrayRegion(ofs_out, 0, 2, tmp_ofs);
-        return;
-    } catch(cv::Exception e) {
-        LOGD("Mat::locateROI_10() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::locateROI_10() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::locateROI_10()}");
-        return;
+        throwJavaException(env, 0, method_name);
     }
 }
 
@@ -1283,25 +1089,20 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1mul__JJD
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1mul__JJD
   (JNIEnv* env, jclass, jlong self, jlong m_nativeObj, jdouble scale)
 {
+    static const char method_name[] = "Mat::n_1mul__JJD()";
     try {
-        LOGD("Mat::n_1mul__JJD()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat& m = *((Mat*)m_nativeObj);
         Mat _retval_ = me->mul( m, scale );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1mul__JJD() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1mul__JJD() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1mul__JJD()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -1312,25 +1113,20 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1mul__JJ
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1mul__JJ
   (JNIEnv* env, jclass, jlong self, jlong m_nativeObj)
 {
+    static const char method_name[] = "Mat::n_1mul__JJ()";
     try {
-        LOGD("Mat::n_1mul__JJ()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat& m = *((Mat*)m_nativeObj);
         Mat _retval_ = me->mul( m );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1mul__JJ() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1mul__JJ() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1mul__JJ()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 
@@ -1345,24 +1141,18 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1ones__III
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1ones__III
   (JNIEnv* env, jclass, jint rows, jint cols, jint type)
 {
+    static const char method_name[] = "Mat::n_1ones__III()";
     try {
-        LOGD("Mat::n_1ones__III()");
-
+        LOGD("%s", method_name);
         Mat _retval_ = Mat::ones( rows, cols, type );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1ones__III() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1ones__III() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1ones__III()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 
@@ -1377,24 +1167,19 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1ones__DDI
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1ones__DDI
   (JNIEnv* env, jclass, jdouble size_width, jdouble size_height, jint type)
 {
+    static const char method_name[] = "Mat::n_1ones__DDI()";
     try {
-        LOGD("Mat::n_1ones__DDI()");
+        LOGD("%s", method_name);
         Size size((int)size_width, (int)size_height);
         Mat _retval_ = Mat::ones( size, type );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1ones__DDI() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1ones__DDI() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1ones__DDI()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 
@@ -1409,23 +1194,15 @@ JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1push_1back
 JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1push_1back
   (JNIEnv* env, jclass, jlong self, jlong m_nativeObj)
 {
+    static const char method_name[] = "Mat::n_1push_1back()";
     try {
-        LOGD("Mat::n_1push_1back()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         me->push_back( (*(Mat*)m_nativeObj) );
-
-        return;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1push_1back() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1push_1back() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1push_1back()}");
-        return;
+        throwJavaException(env, 0, method_name);
     }
 }
 
@@ -1441,23 +1218,15 @@ JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1release
 JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1release
   (JNIEnv* env, jclass, jlong self)
 {
+    static const char method_name[] = "Mat::n_1release()";
     try {
-        LOGD("Mat::n_1release()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         me->release(  );
-
-        return;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1release() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1release() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1release()}");
-        return;
+        throwJavaException(env, 0, method_name);
     }
 }
 
@@ -1473,24 +1242,19 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1reshape__JII
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1reshape__JII
   (JNIEnv* env, jclass, jlong self, jint cn, jint rows)
 {
+    static const char method_name[] = "Mat::n_1reshape__JII()";
     try {
-        LOGD("Mat::n_1reshape__JII()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat _retval_ = me->reshape( cn, rows );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1reshape__JII() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1reshape__JII() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1reshape__JII()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -1501,24 +1265,19 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1reshape__JI
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1reshape__JI
   (JNIEnv* env, jclass, jlong self, jint cn)
 {
+    static const char method_name[] = "Mat::n_1reshape__JI()";
     try {
-        LOGD("Mat::n_1reshape__JI()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat _retval_ = me->reshape( cn );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1reshape__JI() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1reshape__JI() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1reshape__JI()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -1533,24 +1292,19 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1row
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1row
   (JNIEnv* env, jclass, jlong self, jint y)
 {
+    static const char method_name[] = "Mat::n_1row()";
     try {
-        LOGD("Mat::n_1row()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat _retval_ = me->row( y );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1row() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1row() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1row()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+    
+    return 0;
 }
 
 
@@ -1565,24 +1319,19 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1rowRange
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1rowRange
   (JNIEnv* env, jclass, jlong self, jint startrow, jint endrow)
 {
+    static const char method_name[] = "Mat::n_1rowRange()";
     try {
-        LOGD("Mat::n_1rowRange()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat _retval_ = me->rowRange( startrow, endrow );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1rowRange() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1rowRange() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1rowRange()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 
@@ -1597,24 +1346,18 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_n_1rows
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_n_1rows
   (JNIEnv* env, jclass, jlong self)
 {
+    static const char method_name[] = "Mat::n_1rows()";
     try {
-        LOGD("Mat::n_1rows()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
-        int _retval_ = me->rows;
-
-        return _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1rows() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return me->rows;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1rows() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1rows()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 
@@ -1629,25 +1372,20 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1setTo__JDDDD
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1setTo__JDDDD
   (JNIEnv* env, jclass, jlong self, jdouble s_val0, jdouble s_val1, jdouble s_val2, jdouble s_val3)
 {
+    static const char method_name[] = "Mat::n_1setTo__JDDDD()";
     try {
-        LOGD("Mat::n_1setTo__JDDDD()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Scalar s(s_val0, s_val1, s_val2, s_val3);
         Mat _retval_ = me->operator =( s );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1setTo__JDDDD() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1setTo__JDDDD() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1setTo__JDDDD()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 
@@ -1662,26 +1400,21 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1setTo__JDDDDJ
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1setTo__JDDDDJ
   (JNIEnv* env, jclass, jlong self, jdouble s_val0, jdouble s_val1, jdouble s_val2, jdouble s_val3, jlong mask_nativeObj)
 {
+    static const char method_name[] = "Mat::n_1setTo__JDDDDJ()";
     try {
-        LOGD("Mat::n_1setTo__JDDDDJ()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Scalar s(s_val0, s_val1, s_val2, s_val3);
         Mat& mask = *((Mat*)mask_nativeObj);
         Mat _retval_ = me->setTo( s, mask );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1setTo__JDDDDJ() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1setTo__JDDDDJ() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1setTo__JDDDDJ()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 
@@ -1696,26 +1429,21 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1setTo__JJJ
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1setTo__JJJ
   (JNIEnv* env, jclass, jlong self, jlong value_nativeObj, jlong mask_nativeObj)
 {
+    static const char method_name[] = "Mat::n_1setTo__JJJ()";
     try {
-        LOGD("Mat::n_1setTo__JJJ()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat& value = *((Mat*)value_nativeObj);
         Mat& mask = *((Mat*)mask_nativeObj);
         Mat _retval_ = me->setTo( value, mask );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1setTo__JJJ() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1setTo__JJJ() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1setTo__JJJ()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 
@@ -1726,25 +1454,20 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1setTo__JJ
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1setTo__JJ
   (JNIEnv* env, jclass, jlong self, jlong value_nativeObj)
 {
+    static const char method_name[] = "Mat::n_1setTo__JJ()";
     try {
-        LOGD("Mat::n_1setTo__JJ()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat& value = *((Mat*)value_nativeObj);
         Mat _retval_ = me->setTo( value );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1setTo__JJ() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1setTo__JJ() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1setTo__JJ()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 
@@ -1759,24 +1482,22 @@ JNIEXPORT jdoubleArray JNICALL Java_org_opencv_core_Mat_n_1size
 JNIEXPORT jdoubleArray JNICALL Java_org_opencv_core_Mat_n_1size
   (JNIEnv* env, jclass, jlong self)
 {
+    static const char method_name[] = "Mat::n_1size()";
     try {
-        LOGD("Mat::n_1size()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Size _retval_ = me->size(  );
-        jdoubleArray _da_retval_ = env->NewDoubleArray(2);  jdouble _tmp_retval_[2] = {_retval_.width, _retval_.height}; env->SetDoubleArrayRegion(_da_retval_, 0, 2, _tmp_retval_);
+        jdoubleArray _da_retval_ = env->NewDoubleArray(2);  
+        jdouble _tmp_retval_[2] = {_retval_.width, _retval_.height};
+        env->SetDoubleArrayRegion(_da_retval_, 0, 2, _tmp_retval_);
         return _da_retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1size() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1size() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1size()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 
@@ -1791,24 +1512,18 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1step1__JI
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1step1__JI
   (JNIEnv* env, jclass, jlong self, jint i)
 {
+    static const char method_name[] = "Mat::n_1step1__JI()";
     try {
-        LOGD("Mat::n_1step1__JI()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
-        size_t _retval_ = me->step1( i );
-
-        return _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1step1__JI() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return me->step1( i );
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1step1__JI() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1step1__JI()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 
@@ -1819,24 +1534,18 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1step1__J
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1step1__J
   (JNIEnv* env, jclass, jlong self)
 {
+    static const char method_name[] = "Mat::n_1step1__J()";
     try {
-        LOGD("Mat::n_1step1__J()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
-        size_t _retval_ = me->step1(  );
-
-        return _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1step1__J() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return me->step1(  );
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1step1__J() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1step1__J()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 //
@@ -1849,26 +1558,21 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1submat_1rr
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1submat_1rr
   (JNIEnv* env, jclass, jlong self, jint rowRange_start, jint rowRange_end, jint colRange_start, jint colRange_end)
 {
+    static const char method_name[] = "Mat::n_1submat_1rr()";
     try {
-        LOGD("Mat::n_1submat_1rr()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Range rowRange(rowRange_start, rowRange_end);
         Range colRange(colRange_start, colRange_end);
         Mat _retval_ = me->operator()( rowRange, colRange );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1submat_1rr() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1submat_1rr() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1submat_1rr()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 
@@ -1883,25 +1587,20 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1submat
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1submat
   (JNIEnv* env, jclass, jlong self, jint roi_x, jint roi_y, jint roi_width, jint roi_height)
 {
+    static const char method_name[] = "Mat::n_1submat()";
     try {
-        LOGD("Mat::n_1submat()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Rect roi(roi_x, roi_y, roi_width, roi_height);
         Mat _retval_ = me->operator()( roi );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1submat() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1submat() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1submat()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 
@@ -1916,24 +1615,19 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1t
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1t
   (JNIEnv* env, jclass, jlong self)
 {
+    static const char method_name[] = "Mat::n_1t()";
     try {
-        LOGD("Mat::n_1t()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
         Mat _retval_ = me->t(  );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1t() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1t() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1t()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 
@@ -1948,24 +1642,18 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1total
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1total
   (JNIEnv* env, jclass, jlong self)
 {
+    static const char method_name[] = "Mat::n_1total()";
     try {
-        LOGD("Mat::n_1total()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
-        size_t _retval_ = me->total(  );
-
-        return _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1total() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return me->total(  );
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1total() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1total()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 
@@ -1980,24 +1668,18 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_n_1type
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_n_1type
   (JNIEnv* env, jclass, jlong self)
 {
+    static const char method_name[] = "Mat::n_1type()";
     try {
-        LOGD("Mat::n_1type()");
+        LOGD("%s", method_name);
         Mat* me = (Mat*) self; //TODO: check for NULL
-        int _retval_ = me->type(  );
-
-        return _retval_;
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1type() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+        return me->type(  );
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1type() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1type()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 
@@ -2012,24 +1694,18 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1zeros__III
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1zeros__III
   (JNIEnv* env, jclass, jint rows, jint cols, jint type)
 {
+    static const char method_name[] = "Mat::n_1zeros__III()";
     try {
-        LOGD("Mat::n_1zeros__III()");
-
+        LOGD("%s", method_name);
         Mat _retval_ = Mat::zeros( rows, cols, type );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1zeros__III() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1zeros__III() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1zeros__III()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 
@@ -2044,24 +1720,19 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1zeros__DDI
 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1zeros__DDI
   (JNIEnv* env, jclass, jdouble size_width, jdouble size_height, jint type)
 {
+    static const char method_name[] = "Mat::n_1zeros__DDI()";
     try {
-        LOGD("Mat::n_1zeros__DDI()");
+        LOGD("%s", method_name);
         Size size((int)size_width, (int)size_height);
         Mat _retval_ = Mat::zeros( size, type );
-
         return (jlong) new Mat(_retval_);
-    } catch(cv::Exception e) {
-        LOGD("Mat::n_1zeros__DDI() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::n_1zeros__DDI() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::n_1zeros__DDI()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 
@@ -2089,8 +1760,9 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutD
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutD
     (JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jdoubleArray vals)
 {
+    static const char method_name[] = "Mat::nPutD()";
     try {
-        LOGD("Mat::nPutD()");
+        LOGD("%s", method_name);
         cv::Mat* me = (cv::Mat*) self;
         if(!me || !me->data) return 0;  // no native object behind
         if(me->rows<=row || me->cols<=col) return 0; // indexes out of range
@@ -2130,18 +1802,13 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutD
 
         env->ReleasePrimitiveArrayCritical(vals, values, 0);
         return res;
-    } catch(cv::Exception e) {
-        LOGD("Mat::nPutD() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::nPutD() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::nPutD()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 
@@ -2186,8 +1853,9 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutB
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutB
     (JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jbyteArray vals)
 {
+    static const char method_name[] = "Mat::nPutB()";
     try {
-        LOGD("Mat::nPutB()");
+        LOGD("%s", method_name);
         cv::Mat* me = (cv::Mat*) self;
         if(! self) return 0; // no native object behind
         if(me->depth() != CV_8U && me->depth() != CV_8S) return 0; // incompatible type
@@ -2197,18 +1865,13 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutB
         int res = mat_put<char>(me, row, col, count, values);
         env->ReleasePrimitiveArrayCritical(vals, values, 0);
         return res;
-    } catch(cv::Exception e) {
-        LOGD("Mat::nPutB() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::nPutB() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::nPutB()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutS
@@ -2217,8 +1880,9 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutS
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutS
     (JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jshortArray vals)
 {
+    static const char method_name[] = "Mat::nPutS()";
     try {
-        LOGD("Mat::nPutS()");
+        LOGD("%s", method_name);
         cv::Mat* me = (cv::Mat*) self;
         if(! self) return 0; // no native object behind
         if(me->depth() != CV_16U && me->depth() != CV_16S) return 0; // incompatible type
@@ -2228,18 +1892,13 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutS
         int res = mat_put<short>(me, row, col, count, values);
         env->ReleasePrimitiveArrayCritical(vals, values, 0);
         return res;
-    } catch(cv::Exception e) {
-        LOGD("Mat::nPutS() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::nPutS() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::nPutS()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutI
@@ -2248,8 +1907,9 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutI
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutI
     (JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jintArray vals)
 {
+    static const char method_name[] = "Mat::nPutI()";
     try {
-        LOGD("Mat::nPutI()");
+        LOGD("%s", method_name);
         cv::Mat* me = (cv::Mat*) self;
         if(! self) return 0; // no native object behind
         if(me->depth() != CV_32S) return 0; // incompatible type
@@ -2259,18 +1919,13 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutI
         int res = mat_put<int>(me, row, col, count, values);
         env->ReleasePrimitiveArrayCritical(vals, values, 0);
         return res;
-    } catch(cv::Exception e) {
-        LOGD("Mat::nPutI() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::nPutI() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::nPutI()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutF
@@ -2279,8 +1934,9 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutF
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutF
     (JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jfloatArray vals)
 {
+    static const char method_name[] = "Mat::nPutF()";
     try {
-        LOGD("Mat::nPutF()");
+        LOGD("%s", method_name);
         cv::Mat* me = (cv::Mat*) self;
         if(! self) return 0; // no native object behind
         if(me->depth() != CV_32F) return 0; // incompatible type
@@ -2290,18 +1946,13 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutF
         int res = mat_put<float>(me, row, col, count, values);
         env->ReleasePrimitiveArrayCritical(vals, values, 0);
         return res;
-    } catch(cv::Exception e) {
-        LOGD("Mat::nPutF() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::nPutF() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::nPutF()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 
@@ -2345,8 +1996,9 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nGetB
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nGetB
     (JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jbyteArray vals)
 {
+    static const char method_name[] = "Mat::nGetB()";
     try {
-        LOGD("Mat::nGetB()");
+        LOGD("%s", method_name);
         cv::Mat* me = (cv::Mat*) self;
         if(! self) return 0; // no native object behind
         if(me->depth() != CV_8U && me->depth() != CV_8S) return 0; // incompatible type
@@ -2356,18 +2008,13 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nGetB
         int res = mat_get<char>(me, row, col, count, values);
         env->ReleasePrimitiveArrayCritical(vals, values, 0);
         return res;
-    } catch(cv::Exception e) {
-        LOGD("Mat::nGetB() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::nGetB() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::nGetB()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nGetS
@@ -2376,8 +2023,9 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nGetS
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nGetS
     (JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jshortArray vals)
 {
+    static const char method_name[] = "Mat::nGetS()";
     try {
-        LOGD("Mat::nGetS()");
+        LOGD("%s", method_name);
         cv::Mat* me = (cv::Mat*) self;
         if(! self) return 0; // no native object behind
         if(me->depth() != CV_16U && me->depth() != CV_16S) return 0; // incompatible type
@@ -2387,18 +2035,13 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nGetS
         int res = mat_get<short>(me, row, col, count, values);
         env->ReleasePrimitiveArrayCritical(vals, values, 0);
         return res;
-    } catch(cv::Exception e) {
-        LOGD("Mat::nGetS() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::nGetS() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::nGetS()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nGetI
@@ -2407,8 +2050,9 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nGetI
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nGetI
     (JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jintArray vals)
 {
+    static const char method_name[] = "Mat::nGetI()";
     try {
-        LOGD("Mat::nGetI()");
+        LOGD("%s", method_name);
         cv::Mat* me = (cv::Mat*) self;
         if(! self) return 0; // no native object behind
         if(me->depth() != CV_32S) return 0; // incompatible type
@@ -2418,18 +2062,13 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nGetI
         int res = mat_get<int>(me, row, col, count, values);
         env->ReleasePrimitiveArrayCritical(vals, values, 0);
         return res;
-    } catch(cv::Exception e) {
-        LOGD("Mat::nGetI() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::nGetI() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::nGetI()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nGetF
@@ -2438,8 +2077,9 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nGetF
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nGetF
     (JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jfloatArray vals)
 {
+    static const char method_name[] = "Mat::nGetF()";
     try {
-        LOGD("Mat::nGetF()");
+        LOGD("%s", method_name);
         cv::Mat* me = (cv::Mat*) self;
         if(! self) return 0; // no native object behind
         if(me->depth() != CV_32F) return 0; // incompatible type
@@ -2449,18 +2089,13 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nGetF
         int res = mat_get<float>(me, row, col, count, values);
         env->ReleasePrimitiveArrayCritical(vals, values, 0);
         return res;
-    } catch(cv::Exception e) {
-        LOGD("Mat::nGetF() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::nGetF() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::nGetF()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nGetD
@@ -2469,8 +2104,9 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nGetD
 JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nGetD
     (JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jdoubleArray vals)
 {
+    static const char method_name[] = "Mat::nGetD()";
     try {
-        LOGD("Mat::nGetD()");
+        LOGD("%s", method_name);
         cv::Mat* me = (cv::Mat*) self;
         if(! self) return 0; // no native object behind
         if(me->depth() != CV_64F) return 0; // incompatible type
@@ -2480,18 +2116,13 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nGetD
         int res = mat_get<double>(me, row, col, count, values);
         env->ReleasePrimitiveArrayCritical(vals, values, 0);
         return res;
-    } catch(cv::Exception e) {
-        LOGD("Mat::nGetD() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::nGetD() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::nGetD()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 JNIEXPORT jdoubleArray JNICALL Java_org_opencv_core_Mat_nGet
@@ -2500,8 +2131,9 @@ JNIEXPORT jdoubleArray JNICALL Java_org_opencv_core_Mat_nGet
 JNIEXPORT jdoubleArray JNICALL Java_org_opencv_core_Mat_nGet
     (JNIEnv* env, jclass, jlong self, jint row, jint col)
 {
+    static const char method_name[] = "Mat::nGet()";
     try {
-        LOGD("Mat::nGet()");
+        LOGD("%s", method_name);
         cv::Mat* me = (cv::Mat*) self;
         if(! self) return 0; // no native object behind
         if(me->rows<=row || me->cols<=col) return 0; // indexes out of range
@@ -2522,18 +2154,13 @@ JNIEXPORT jdoubleArray JNICALL Java_org_opencv_core_Mat_nGet
             env->SetDoubleArrayRegion(res, 0, me->channels(), buff);
         }
         return res;
-    } catch(cv::Exception e) {
-        LOGD("Mat::nGet() catched cv::Exception: %s", e.what());
-        jclass je = env->FindClass("org/opencv/core/CvException");
-        if(!je) je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, e.what());
-        return 0;
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
     } catch (...) {
-        LOGD("Mat::nGet() catched unknown exception (...)");
-        jclass je = env->FindClass("java/lang/Exception");
-        env->ThrowNew(je, "Unknown exception in JNI code {Mat::nGet()}");
-        return 0;
+        throwJavaException(env, 0, method_name);
     }
+
+    return 0;
 }
 
 JNIEXPORT jstring JNICALL Java_org_opencv_core_Mat_nDump
@@ -2542,25 +2169,21 @@ JNIEXPORT jstring JNICALL Java_org_opencv_core_Mat_nDump
 JNIEXPORT jstring JNICALL Java_org_opencv_core_Mat_nDump
   (JNIEnv *env, jclass, jlong self)
 {
-    cv::Mat* me = (cv::Mat*) self; //TODO: check for NULL
-    std::stringstream s;
-    try {
-            LOGD("Mat::nDump()");
-
-            s << *me;
-            return env->NewStringUTF(s.str().c_str());
-        } catch(cv::Exception e) {
-            LOGE("Mat::nDump() catched cv::Exception: %s", e.what());
-            jclass je = env->FindClass("org/opencv/core/CvException");
-            if(!je) je = env->FindClass("java/lang/Exception");
-            env->ThrowNew(je, e.what());
-            return env->NewStringUTF("ERROR");
-        } catch (...) {
-            LOGE("Mat::nDump() catched unknown exception (...)");
-            jclass je = env->FindClass("java/lang/Exception");
-            env->ThrowNew(je, "Unknown exception in JNI code {Mat::nDump()}");
-            return env->NewStringUTF("ERROR");
-        }
+    static const char method_name[] = "Mat::nDump()";
+    try {
+        LOGD("%s", method_name);
+        cv::Mat* me = (cv::Mat*) self; //TODO: check for NULL
+        std::stringstream s;
+        s << *me;
+        std::string str = s.str();
+        return env->NewStringUTF(str.c_str());
+    } catch(const std::exception &e) {
+        throwJavaException(env, &e, method_name);
+    } catch (...) {
+        throwJavaException(env, 0, method_name);
+    }
+
+    return 0;
 }
 
 
index 0dcdad2..f864e53 100644 (file)
@@ -6,7 +6,6 @@ import android.content.Context;
 import android.graphics.ImageFormat;
 import android.graphics.SurfaceTexture;
 import android.hardware.Camera;
-import android.hardware.Camera.CameraInfo;
 import android.hardware.Camera.PreviewCallback;
 import android.os.Build;
 import android.util.AttributeSet;
@@ -39,7 +38,7 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
     private boolean mStopThread;
 
     protected Camera mCamera;
-    protected JavaCameraFrame mCameraFrame;
+    protected JavaCameraFrame[] mCameraFrame;
     private SurfaceTexture mSurfaceTexture;
 
     public static class JavaCameraSizeAccessor implements ListItemAccessor {
@@ -181,7 +180,9 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
 
                     AllocateCache();
 
-                    mCameraFrame = new JavaCameraFrame(mFrameChain[mChainIdx], mFrameWidth, mFrameHeight);
+                    mCameraFrame = new JavaCameraFrame[2];
+                    mCameraFrame[0] = new JavaCameraFrame(mFrameChain[0], mFrameWidth, mFrameHeight);
+                    mCameraFrame[1] = new JavaCameraFrame(mFrameChain[1], mFrameWidth, mFrameHeight);
 
                     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                         mSurfaceTexture = new SurfaceTexture(MAGIC_TEXTURE_ID);
@@ -217,8 +218,10 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
                 mFrameChain[0].release();
                 mFrameChain[1].release();
             }
-            if (mCameraFrame != null)
-                mCameraFrame.release();
+            if (mCameraFrame != null) {
+                mCameraFrame[0].release();
+                mCameraFrame[1].release();
+            }
         }
     }
 
@@ -319,7 +322,7 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
 
                 if (!mStopThread) {
                     if (!mFrameChain[mChainIdx].empty())
-                        deliverAndDrawFrame(mCameraFrame);
+                        deliverAndDrawFrame(mCameraFrame[mChainIdx]);
                     mChainIdx = 1 - mChainIdx;
                 }
             } while (!mStopThread);
index fb05b82..a76471e 100644 (file)
@@ -27,6 +27,11 @@ public class OpenCVLoader
      */
     public static final String OPENCV_VERSION_2_4_5 = "2.4.5";
 
+    /**
+     * OpenCV Library version 2.4.6.
+     */
+    public static final String OPENCV_VERSION_2_4_6 = "2.4.6";
+
 
     /**
      * Loads and initializes OpenCV library from current application package. Roughly, it's an analog of system.loadLibrary("opencv_java").
index 8dd72fb..6db2554 100644 (file)
@@ -246,6 +246,19 @@ public class Mat {
     }
 
     //
+    // C++: int Mat::dims()
+    //
+
+    // javadoc: Mat::dims()
+    public int dims()
+    {
+
+        int retVal = n_dims(nativeObj);
+
+        return retVal;
+    }
+
+    //
     // C++: int Mat::cols()
     //
 
@@ -1130,6 +1143,9 @@ public class Mat {
     // C++: Mat Mat::colRange(int startcol, int endcol)
     private static native long n_colRange(long nativeObj, int startcol, int endcol);
 
+    // C++: int Mat::dims()
+    private static native int n_dims(long nativeObj);
+
     // C++: int Mat::cols()
     private static native int n_cols(long nativeObj);
 
index b3fe569..7756eb9 100644 (file)
@@ -15,7 +15,7 @@ public class MatOfByte extends Mat {
     protected MatOfByte(long addr) {
         super(addr);
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
@@ -26,7 +26,7 @@ public class MatOfByte extends Mat {
     public MatOfByte(Mat m) {
         super(m, Range.all());
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
index 4a16101..b703c5c 100644 (file)
@@ -17,7 +17,7 @@ public class MatOfDMatch extends Mat {
     protected MatOfDMatch(long addr) {
         super(addr);
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat: " + toString());
+            throw new IllegalArgumentException("Incompatible Mat: " + toString());
         //FIXME: do we need release() here?
     }
 
@@ -28,7 +28,7 @@ public class MatOfDMatch extends Mat {
     public MatOfDMatch(Mat m) {
         super(m, Range.all());
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat: " + toString());
+            throw new IllegalArgumentException("Incompatible Mat: " + toString());
         //FIXME: do we need release() here?
     }
 
index 4eb7cbc..1a8e23c 100644 (file)
@@ -15,7 +15,7 @@ public class MatOfDouble extends Mat {
     protected MatOfDouble(long addr) {
         super(addr);
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
@@ -26,7 +26,7 @@ public class MatOfDouble extends Mat {
     public MatOfDouble(Mat m) {
         super(m, Range.all());
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
index 96bbeab..dfd6b84 100644 (file)
@@ -15,7 +15,7 @@ public class MatOfFloat extends Mat {
     protected MatOfFloat(long addr) {
         super(addr);
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
@@ -26,7 +26,7 @@ public class MatOfFloat extends Mat {
     public MatOfFloat(Mat m) {
         super(m, Range.all());
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
index aaa97b7..96f9e5c 100644 (file)
@@ -15,7 +15,7 @@ public class MatOfFloat4 extends Mat {
     protected MatOfFloat4(long addr) {
         super(addr);
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
@@ -26,7 +26,7 @@ public class MatOfFloat4 extends Mat {
     public MatOfFloat4(Mat m) {
         super(m, Range.all());
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
index 68e6249..140bb57 100644 (file)
@@ -15,7 +15,7 @@ public class MatOfFloat6 extends Mat {
     protected MatOfFloat6(long addr) {
         super(addr);
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
@@ -26,7 +26,7 @@ public class MatOfFloat6 extends Mat {
     public MatOfFloat6(Mat m) {
         super(m, Range.all());
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
index 33e5124..7d07687 100644 (file)
@@ -16,7 +16,7 @@ public class MatOfInt extends Mat {
     protected MatOfInt(long addr) {
         super(addr);
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
@@ -27,7 +27,7 @@ public class MatOfInt extends Mat {
     public MatOfInt(Mat m) {
         super(m, Range.all());
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
index c924233..4ca4d9e 100644 (file)
@@ -16,7 +16,7 @@ public class MatOfInt4 extends Mat {
     protected MatOfInt4(long addr) {
         super(addr);
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
@@ -27,7 +27,7 @@ public class MatOfInt4 extends Mat {
     public MatOfInt4(Mat m) {
         super(m, Range.all());
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
index b402fe1..d0a1879 100644 (file)
@@ -17,7 +17,7 @@ public class MatOfKeyPoint extends Mat {
     protected MatOfKeyPoint(long addr) {
         super(addr);
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
@@ -28,7 +28,7 @@ public class MatOfKeyPoint extends Mat {
     public MatOfKeyPoint(Mat m) {
         super(m, Range.all());
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
index 6d23ed1..f4d573b 100644 (file)
@@ -15,7 +15,7 @@ public class MatOfPoint extends Mat {
     protected MatOfPoint(long addr) {
         super(addr);
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
@@ -26,7 +26,7 @@ public class MatOfPoint extends Mat {
     public MatOfPoint(Mat m) {
         super(m, Range.all());
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
index 0c69607..4b8c926 100644 (file)
@@ -15,7 +15,7 @@ public class MatOfPoint2f extends Mat {
     protected MatOfPoint2f(long addr) {
         super(addr);
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
@@ -26,7 +26,7 @@ public class MatOfPoint2f extends Mat {
     public MatOfPoint2f(Mat m) {
         super(m, Range.all());
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
index 0c8374f..3b50561 100644 (file)
@@ -15,7 +15,7 @@ public class MatOfPoint3 extends Mat {
     protected MatOfPoint3(long addr) {
         super(addr);
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
@@ -26,7 +26,7 @@ public class MatOfPoint3 extends Mat {
     public MatOfPoint3(Mat m) {
         super(m, Range.all());
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
index b0d50d4..fc5fee4 100644 (file)
@@ -15,7 +15,7 @@ public class MatOfPoint3f extends Mat {
     protected MatOfPoint3f(long addr) {
         super(addr);
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
@@ -26,7 +26,7 @@ public class MatOfPoint3f extends Mat {
     public MatOfPoint3f(Mat m) {
         super(m, Range.all());
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
index 3844d9d..ec0fb01 100644 (file)
@@ -16,7 +16,7 @@ public class MatOfRect extends Mat {
     protected MatOfRect(long addr) {
         super(addr);
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
@@ -27,7 +27,7 @@ public class MatOfRect extends Mat {
     public MatOfRect(Mat m) {
         super(m, Range.all());
         if( !empty() && checkVector(_channels, _depth) < 0 )
-            throw new IllegalArgumentException("Incomatible Mat");
+            throw new IllegalArgumentException("Incompatible Mat");
         //FIXME: do we need release() here?
     }
 
index b8569bb..6f3b035 100644 (file)
@@ -56,7 +56,7 @@ public class VideoCapture {
  *   * CV_CAP_PROP_FRAME_WIDTH width of the frames in the video stream.
  *   * CV_CAP_PROP_FRAME_HEIGHT height of the frames in the video stream.
  *
- * @see <a href="http://opencv.itseez.com/modules/highgui/doc/reading_and_writing_images_and_video.html#videocapture-get">org.opencv.highgui.VideoCapture.get</a>
+ * @see <a href="http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html#videocapture-get">org.opencv.highgui.VideoCapture.get</a>
  */
     public double get(int propId)
     {
@@ -178,7 +178,7 @@ public class VideoCapture {
  *   * CV_CAP_PROP_FRAME_HEIGHT height of the frames in the video stream.
  * @param value value of the property.
  *
- * @see <a href="http://opencv.itseez.com/modules/highgui/doc/reading_and_writing_images_and_video.html#videocapture-set">org.opencv.highgui.VideoCapture.set</a>
+ * @see <a href="http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html#videocapture-set">org.opencv.highgui.VideoCapture.set</a>
  */
     public boolean set(int propId, double value)
     {
index d97d152..e3791cb 100644 (file)
@@ -5,6 +5,12 @@ This section describes obsolete ``C`` interface of EM algorithm. Details of the
 
 .. highlight:: cpp
 
+.. note::
+
+   * An example on using the Expectation Maximalization algorithm can be found at opencv_source_code/samples/cpp/em.cpp
+
+   * (Python) An example using Expectation Maximalization for Gaussian Mixing can be found at opencv_source_code/samples/python2/gaussian_mix.py
+
 
 CvEMParams
 ----------
index 222d7a0..3dc1ae5 100644 (file)
@@ -75,7 +75,9 @@ Class containing a base structure for ``RTreeClassifier``. ::
             void estimateQuantPercForPosteriors(float perc[2]);
     };
 
+.. note::
 
+   * : PYTHON : An example using Randomized Tree training for letter recognition can be found at opencv_source_code/samples/python2/letter_recog.py
 
 RandomizedTree::train
 -------------------------
@@ -99,7 +101,9 @@ Trains a randomized tree using an input set of keypoints.
 
     :param num_quant_bits: Number of bits used for quantization.
 
+.. note::
 
+   * : An example on training a Random Tree Classifier for letter recognition can be found at opencv_source_code\samples\cpp\letter_recog.cpp
 
 RandomizedTree::read
 ------------------------
diff --git a/modules/legacy/src/precomp.cpp b/modules/legacy/src/precomp.cpp
deleted file mode 100644 (file)
index a9477b8..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*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 "precomp.hpp"
index 48b9e4a..383b694 100644 (file)
@@ -41,9 +41,7 @@
 #ifndef __OPENCV_PRECOMP_H__
 #define __OPENCV_PRECOMP_H__
 
-#ifdef HAVE_CVCONFIG_H
 #include "cvconfig.h"
-#endif
 
 #include "opencv2/legacy/legacy.hpp"
 
diff --git a/modules/legacy/test/test_precomp.cpp b/modules/legacy/test/test_precomp.cpp
deleted file mode 100644 (file)
index 5956e13..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "test_precomp.hpp"
index 739f52d..6692417 100644 (file)
@@ -9,7 +9,13 @@ CvKNearest
 ----------
 .. ocv:class:: CvKNearest : public CvStatModel
 
-The class implements K-Nearest Neighbors model as described in the beginning of this section. 
+The class implements K-Nearest Neighbors model as described in the beginning of this section.
+
+.. note::
+
+   * (Python) An example of digit recognition using KNearest can be found at opencv_source/samples/python2/digits.py
+   * (Python) An example of grid search digit recognition using KNearest can be found at opencv_source/samples/python2/digits_adjust.py
+   * (Python) An example of video digit recognition using KNearest can be found at opencv_source/samples/python2/digits_video.py
 
 CvKNearest::CvKNearest
 ----------------------
index b0d23ae..8c24e5f 100644 (file)
@@ -150,6 +150,12 @@ CvSVM
 
 Support Vector Machines.
 
+.. note::
+
+   * (Python) An example of digit recognition using SVM can be found at opencv_source/samples/python2/digits.py
+   * (Python) An example of grid search digit recognition using SVM can be found at opencv_source/samples/python2/digits_adjust.py
+   * (Python) An example of video digit recognition using SVM can be found at opencv_source/samples/python2/digits_video.py
+
 CvSVM::CvSVM
 ------------
 Default and training constructors.
diff --git a/modules/ml/src/precomp.cpp b/modules/ml/src/precomp.cpp
deleted file mode 100644 (file)
index e540cc5..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*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 "precomp.hpp"
-
-/* End of file. */
index 63002a8..b4ae21a 100644 (file)
@@ -41,9 +41,7 @@
 #ifndef __OPENCV_PRECOMP_H__
 #define __OPENCV_PRECOMP_H__
 
-#ifdef HAVE_CVCONFIG_H
 #include "cvconfig.h"
-#endif
 
 #include "opencv2/ml/ml.hpp"
 #include "opencv2/core/core_c.h"
diff --git a/modules/ml/test/test_precomp.cpp b/modules/ml/test/test_precomp.cpp
deleted file mode 100644 (file)
index 5956e13..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "test_precomp.hpp"
index c7ccb74..5c2b2a0 100644 (file)
@@ -75,6 +75,10 @@ SURF
 
 .. [Bay06] Bay, H. and Tuytelaars, T. and Van Gool, L. "SURF: Speeded Up Robust Features", 9th European Conference on Computer Vision, 2006
 
+.. note::
+
+   * An example using the SURF feature detector can be found at opencv_source_code/samples/cpp/generic_descriptor_match.cpp
+   * Another example using the SURF feature detector, extractor and matcher can be found at opencv_source_code/samples/cpp/matcher_simple.cpp
 
 SURF::SURF
 ----------
@@ -230,6 +234,9 @@ The class ``SURF_GPU`` uses some buffers and provides access to it. All buffers
 
 .. seealso:: :ocv:class:`SURF`
 
+.. note::
+
+   * An example for using the SURF keypoint matcher on GPU can be found at opencv_source_code/samples/gpu/surf_keypoint_matcher.cpp
 
 ocl::SURF_OCL
 -------------
@@ -327,4 +334,8 @@ The ``descriptors`` matrix is :math:`\texttt{nFeatures} \times \texttt{descripto
 
 The class ``SURF_OCL`` uses some buffers and provides access to it. All buffers can be safely released between function calls.
 
-.. seealso:: :ocv:class:`SURF`
\ No newline at end of file
+.. seealso:: :ocv:class:`SURF`
+
+.. note::
+
+   * OCL : An example of the SURF detector can be found at opencv_source_code/samples/ocl/surf_matcher.cpp
\ No newline at end of file
index de12421..d5f4a1a 100644 (file)
@@ -1,4 +1,11 @@
 #include "perf_precomp.hpp"
 #include "opencv2/ts/gpu_perf.hpp"
 
-CV_PERF_TEST_MAIN(nonfree, perf::printCudaInfo())
+static const char * impls[] = {
+#ifdef HAVE_CUDA
+    "cuda",
+#endif
+    "plain"
+};
+
+CV_PERF_TEST_MAIN_WITH_IMPLS(nonfree, impls, perf::printCudaInfo())
diff --git a/modules/nonfree/perf/perf_precomp.cpp b/modules/nonfree/perf/perf_precomp.cpp
deleted file mode 100644 (file)
index 8552ac3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "perf_precomp.hpp"
index 6c46114..2abe603 100644 (file)
@@ -43,9 +43,7 @@
 #ifndef __OPENCV_PRECOMP_H__
 #define __OPENCV_PRECOMP_H__
 
-#ifdef HAVE_CVCONFIG_H
 #include "cvconfig.h"
-#endif
 
 #include "opencv2/opencv_modules.hpp"
 
index 001d628..4cce77b 100644 (file)
@@ -1146,3 +1146,76 @@ protected:
 TEST(Features2d_SIFTHomographyTest, regression) { CV_DetectPlanarTest test("SIFT", 80); test.safe_run(); }
 TEST(Features2d_SURFHomographyTest, regression) { CV_DetectPlanarTest test("SURF", 80); test.safe_run(); }
 
+class FeatureDetectorUsingMaskTest : public cvtest::BaseTest
+{
+public:
+    FeatureDetectorUsingMaskTest(const Ptr<FeatureDetector>& featureDetector) :
+        featureDetector_(featureDetector)
+    {
+        CV_Assert(!featureDetector_.empty());
+    }
+
+protected:
+
+    void run(int)
+    {
+        const int nStepX = 2;
+        const int nStepY = 2;
+
+        const string imageFilename = string(ts->get_data_path()) + "/features2d/tsukuba.png";
+
+        Mat image = imread(imageFilename);
+        if(image.empty())
+        {
+            ts->printf(cvtest::TS::LOG, "Image %s can not be read.\n", imageFilename.c_str());
+            ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
+            return;
+        }
+
+        Mat mask(image.size(), CV_8U);
+
+        const int stepX = image.size().width / nStepX;
+        const int stepY = image.size().height / nStepY;
+
+        vector<KeyPoint> keyPoints;
+        vector<Point2f> points;
+        for(int i=0; i<nStepX; ++i)
+            for(int j=0; j<nStepY; ++j)
+            {
+
+                mask.setTo(0);
+                Rect whiteArea(i * stepX, j * stepY, stepX, stepY);
+                mask(whiteArea).setTo(255);
+
+                featureDetector_->detect(image, keyPoints, mask);
+                KeyPoint::convert(keyPoints, points);
+
+                for(size_t k=0; k<points.size(); ++k)
+                {
+                    if ( !whiteArea.contains(points[k]) )
+                    {
+                        ts->printf(cvtest::TS::LOG, "The feature point is outside of the mask.");
+                        ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
+                        return;
+                    }
+                }
+            }
+
+        ts->set_failed_test_info( cvtest::TS::OK );
+    }
+
+    Ptr<FeatureDetector> featureDetector_;
+};
+
+TEST(Features2d_SIFT_using_mask, regression)
+{
+    FeatureDetectorUsingMaskTest test(Algorithm::create<FeatureDetector>("Feature2D.SIFT"));
+    test.safe_run();
+}
+
+TEST(DISABLED_Features2d_SURF_using_mask, regression)
+{
+    FeatureDetectorUsingMaskTest test(Algorithm::create<FeatureDetector>("Feature2D.SURF"));
+    test.safe_run();
+}
+
diff --git a/modules/nonfree/test/test_precomp.cpp b/modules/nonfree/test/test_precomp.cpp
deleted file mode 100644 (file)
index 5956e13..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "test_precomp.hpp"
index eb07a6c..231a193 100644 (file)
@@ -215,6 +215,10 @@ Detects objects of different sizes in the input image. The detected objects are
 
 The function is parallelized with the TBB library.
 
+.. note::
+
+   * (Python) A face detection example using cascade classifiers can be found at opencv_source_code/samples/python2/facedetect.py
+
 
 CascadeClassifier::setImage
 -------------------------------
index 8d7efb0..d5d6f0b 100644 (file)
@@ -192,12 +192,12 @@ typedef struct CvLSVMFilterObject{
 
 // data type: STRUCT CvLatentSvmDetector
 // structure contains internal representation of trained Latent SVM detector
-// num_filters                 - total number of filters (root plus part) in model
-// num_components              - number of components in model
-// num_part_filters            - array containing number of part filters for each component
-// filters                             - root and part filters for all model components
-// b                                   - biases for all model components
-// score_threshold             - confidence level threshold
+// num_filters          - total number of filters (root plus part) in model
+// num_components       - number of components in model
+// num_part_filters     - array containing number of part filters for each component
+// filters              - root and part filters for all model components
+// b                    - biases for all model components
+// score_threshold      - confidence level threshold
 typedef struct CvLatentSvmDetector
 {
     int num_filters;
@@ -211,8 +211,8 @@ CvLatentSvmDetector;
 
 // data type: STRUCT CvObjectDetection
 // structure contains the bounding box and confidence level for detected object
-// rect                                        - bounding box for a detected object
-// score                               - confidence level
+// rect                 - bounding box for a detected object
+// score                - confidence level
 typedef struct CvObjectDetection
 {
     CvRect rect;
@@ -228,7 +228,7 @@ typedef struct CvObjectDetection
 // API
 // CvLatentSvmDetector* cvLoadLatentSvmDetector(const char* filename);
 // INPUT
-// filename                            - path to the file containing the parameters of
+// filename             - path to the file containing the parameters of
                         - trained Latent SVM detector
 // OUTPUT
 // trained Latent SVM detector in internal representation
@@ -241,7 +241,7 @@ CVAPI(CvLatentSvmDetector*) cvLoadLatentSvmDetector(const char* filename);
 // API
 // void cvReleaseLatentSvmDetector(CvLatentSvmDetector** detector);
 // INPUT
-// detector                            - CvLatentSvmDetector structure to be released
+// detector             - CvLatentSvmDetector structure to be released
 // OUTPUT
 */
 CVAPI(void) cvReleaseLatentSvmDetector(CvLatentSvmDetector** detector);
@@ -252,16 +252,16 @@ CVAPI(void) cvReleaseLatentSvmDetector(CvLatentSvmDetector** detector);
 //
 // API
 // CvSeq* cvLatentSvmDetectObjects(const IplImage* image,
-//                                                                     CvLatentSvmDetector* detector,
-//                                                                     CvMemStorage* storage,
-//                                                                     float overlap_threshold = 0.5f,
+//                                  CvLatentSvmDetector* detector,
+//                                  CvMemStorage* storage,
+//                                  float overlap_threshold = 0.5f,
 //                                  int numThreads = -1);
 // INPUT
-// image                               - image to detect objects in
-// detector                            - Latent SVM detector in internal representation
-// storage                             - memory storage to store the resultant sequence
-//                                                     of the object candidate rectangles
-// overlap_threshold   - threshold for the non-maximum suppression algorithm
+// image                - image to detect objects in
+// detector             - Latent SVM detector in internal representation
+// storage              - memory storage to store the resultant sequence
+//                          of the object candidate rectangles
+// overlap_threshold    - threshold for the non-maximum suppression algorithm
                            = 0.5f [here will be the reference to original paper]
 // OUTPUT
 // sequence of detected objects (bounding boxes and confidence levels stored in CvObjectDetection structures)
@@ -327,6 +327,23 @@ private:
     vector<string> classNames;
 };
 
+// class for grouping object candidates, detected by Cascade Classifier, HOG etc.
+// instance of the class is to be passed to cv::partition (see cxoperations.hpp)
+class CV_EXPORTS SimilarRects
+{
+public:
+    SimilarRects(double _eps) : eps(_eps) {}
+    inline bool operator()(const Rect& r1, const Rect& r2) const
+    {
+        double delta = eps*(std::min(r1.width, r2.width) + std::min(r1.height, r2.height))*0.5;
+        return std::abs(r1.x - r2.x) <= delta &&
+            std::abs(r1.y - r2.y) <= delta &&
+            std::abs(r1.x + r1.width - r2.x - r2.width) <= delta &&
+            std::abs(r1.y + r1.height - r2.y - r2.height) <= delta;
+    }
+    double eps;
+};
+
 CV_EXPORTS void groupRectangles(CV_OUT CV_IN_OUT vector<Rect>& rectList, int groupThreshold, double eps=0.2);
 CV_EXPORTS_W void groupRectangles(CV_OUT CV_IN_OUT vector<Rect>& rectList, CV_OUT vector<int>& weights, int groupThreshold, double eps=0.2);
 CV_EXPORTS void groupRectangles( vector<Rect>& rectList, int groupThreshold, double eps, vector<int>* weights, vector<double>* levelWeights );
@@ -611,6 +628,7 @@ public:
 
    // read/parse Dalal's alt model file
    void readALTModel(std::string modelfile);
+   void groupRectangles(vector<cv::Rect>& rectList, vector<double>& weights, int groupThreshold, double eps) const;
 };
 
 
diff --git a/modules/objdetect/perf/perf_precomp.cpp b/modules/objdetect/perf/perf_precomp.cpp
deleted file mode 100644 (file)
index 8552ac3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "perf_precomp.hpp"
index 9e78dce..6c41655 100644 (file)
@@ -114,24 +114,6 @@ struct Logger
 namespace cv
 {
 
-// class for grouping object candidates, detected by Cascade Classifier, HOG etc.
-// instance of the class is to be passed to cv::partition (see cxoperations.hpp)
-class CV_EXPORTS SimilarRects
-{
-public:
-    SimilarRects(double _eps) : eps(_eps) {}
-    inline bool operator()(const Rect& r1, const Rect& r2) const
-    {
-        double delta = eps*(std::min(r1.width, r2.width) + std::min(r1.height, r2.height))*0.5;
-        return std::abs(r1.x - r2.x) <= delta &&
-        std::abs(r1.y - r2.y) <= delta &&
-        std::abs(r1.x + r1.width - r2.x - r2.width) <= delta &&
-        std::abs(r1.y + r1.height - r2.y - r2.height) <= delta;
-    }
-    double eps;
-};
-
-
 void groupRectangles(vector<Rect>& rectList, int groupThreshold, double eps, vector<int>* weights, vector<double>* levelWeights)
 {
     if( groupThreshold <= 0 || rectList.empty() )
index 1eab434..7287d57 100644 (file)
@@ -1060,7 +1060,7 @@ void HOGDescriptor::detectMultiScale(
     }
     else
     {
-        groupRectangles(foundLocations, (int)finalThreshold, 0.2);
+        groupRectangles(foundLocations, foundWeights, (int)finalThreshold, 0.2);
     }
 }
 
@@ -2634,4 +2634,82 @@ void HOGDescriptor::readALTModel(std::string modelfile)
    fclose(modelfl);
 }
 
+void HOGDescriptor::groupRectangles(vector<cv::Rect>& rectList, vector<double>& weights, int groupThreshold, double eps) const
+{
+    if( groupThreshold <= 0 || rectList.empty() )
+    {
+        return;
+    }
+
+    CV_Assert(rectList.size() == weights.size());
+
+    vector<int> labels;
+    int nclasses = partition(rectList, labels, SimilarRects(eps));
+
+    vector<cv::Rect_<double> > rrects(nclasses);
+    vector<int> numInClass(nclasses, 0);
+    vector<double> foundWeights(nclasses, DBL_MIN);
+    vector<double> totalFactorsPerClass(nclasses, 1);
+    int i, j, nlabels = (int)labels.size();
+
+    for( i = 0; i < nlabels; i++ )
+    {
+        int cls = labels[i];
+        rrects[cls].x += rectList[i].x;
+        rrects[cls].y += rectList[i].y;
+        rrects[cls].width += rectList[i].width;
+        rrects[cls].height += rectList[i].height;
+        foundWeights[cls] = max(foundWeights[cls], weights[i]);
+        numInClass[cls]++;
+    }
+
+    for( i = 0; i < nclasses; i++ )
+    {
+        // find the average of all ROI in the cluster
+        cv::Rect_<double> r = rrects[i];
+        double s = 1.0/numInClass[i];
+        rrects[i] = cv::Rect_<double>(cv::saturate_cast<double>(r.x*s),
+            cv::saturate_cast<double>(r.y*s),
+            cv::saturate_cast<double>(r.width*s),
+            cv::saturate_cast<double>(r.height*s));
+    }
+
+    rectList.clear();
+    weights.clear();
+
+    for( i = 0; i < nclasses; i++ )
+    {
+        cv::Rect r1 = rrects[i];
+        int n1 = numInClass[i];
+        double w1 = foundWeights[i];
+        if( n1 <= groupThreshold )
+            continue;
+        // filter out small rectangles inside large rectangles
+        for( j = 0; j < nclasses; j++ )
+        {
+            int n2 = numInClass[j];
+
+            if( j == i || n2 <= groupThreshold )
+                continue;
+
+            cv::Rect r2 = rrects[j];
+
+            int dx = cv::saturate_cast<int>( r2.width * eps );
+            int dy = cv::saturate_cast<int>( r2.height * eps );
+
+            if( r1.x >= r2.x - dx &&
+                r1.y >= r2.y - dy &&
+                r1.x + r1.width <= r2.x + r2.width + dx &&
+                r1.y + r1.height <= r2.y + r2.height + dy &&
+                (n2 > std::max(3, n1) || n1 < 3) )
+                break;
+        }
+
+        if( j == nclasses )
+        {
+            rectList.push_back(r1);
+            weights.push_back(w1);
+        }
+    }
+}
 }
diff --git a/modules/objdetect/src/precomp.cpp b/modules/objdetect/src/precomp.cpp
deleted file mode 100644 (file)
index 3e0ec42..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*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 "precomp.hpp"
-
-/* End of file. */
index 560ed45..37f3673 100644 (file)
@@ -43,9 +43,7 @@
 #ifndef __OPENCV_PRECOMP_H__
 #define __OPENCV_PRECOMP_H__
 
-#ifdef HAVE_CVCONFIG_H
 #include "cvconfig.h"
-#endif
 
 #include "opencv2/objdetect/objdetect.hpp"
 #include "opencv2/imgproc/imgproc.hpp"
index b595d7a..1efa55f 100644 (file)
@@ -44,9 +44,7 @@
 
 #include <string>
 
-#ifdef HAVE_CVCONFIG_H
 #include "cvconfig.h"
-#endif
 
 #ifdef HAVE_TBB
 #include "tbb/task_scheduler_init.h"
diff --git a/modules/objdetect/test/test_precomp.cpp b/modules/objdetect/test/test_precomp.cpp
deleted file mode 100644 (file)
index 5956e13..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "test_precomp.hpp"
index d4fd6e6..f654124 100644 (file)
@@ -363,7 +363,9 @@ The class implements Histogram of Oriented Gradients ([Dalal2005]_) object detec
 
 Interfaces of all methods are kept similar to the ``CPU HOG`` descriptor and detector analogues as much as possible.
 
+.. note::
 
+   (Ocl) An example using the HOG descriptor can be found at opencv_source_code/samples/ocl/hog.cpp
 
 ocl::HOGDescriptor::HOGDescriptor
 -------------------------------------
index 94712e0..de3669c 100644 (file)
@@ -257,7 +257,10 @@ The class can calculate an optical flow for a sparse feature set or dense optica
 
 .. seealso:: :ocv:func:`calcOpticalFlowPyrLK`
 
+.. note::
 
+   (Ocl) An example the Lucas Kanade optical flow pyramid method can be found at opencv_source_code/samples/ocl/pyrlk_optical_flow.cpp
+   (Ocl) An example for square detection can be found at opencv_source_code/samples/ocl/squares.cpp
 
 ocl::PyrLKOpticalFlow::sparse
 -----------------------------
index 17eb62d..36f3e46 100644 (file)
@@ -20,6 +20,10 @@ Cascade classifier class used for object detection. Supports HAAR cascade classi
                                       CvSize maxSize = cvSize(0, 0));
     };
 
+.. note::
+
+   (Ocl) A face detection example using cascade classifiers can be found at opencv_source_code/samples/ocl/facedetect.cpp
+
 ocl::OclCascadeClassifier::oclHaarDetectObjects
 ------------------------------------------------------
 Returns the detected objects by a list of rectangles
index 145659b..1500ea5 100644 (file)
@@ -481,4 +481,40 @@ Performs generalized matrix multiplication.
             * **GEMM_1_T** transpose  ``src1``
             * **GEMM_2_T** transpose  ``src2``
 
-.. seealso:: :ocv:func:`gemm`
\ No newline at end of file
+.. seealso:: :ocv:func:`gemm`
+
+ocl::sortByKey
+------------------
+Returns void
+
+.. ocv:function:: void ocl::sortByKey(oclMat& keys, oclMat& values, int method, bool isGreaterThan = false)
+
+    :param keys:   The keys to be used as sorting indices.
+
+    :param values: The array of values.
+
+    :param isGreaterThan: Determine sorting order.
+
+    :param method: supported sorting methods:
+            * **SORT_BITONIC**   bitonic sort, only support power-of-2 buffer size
+            * **SORT_SELECTION** selection sort, currently cannot sort duplicate keys
+            * **SORT_MERGE**     merge sort
+            * **SORT_RADIX**     radix sort, only support signed int/float keys(``CV_32S``/``CV_32F``)
+            
+Returns the sorted result of all the elements in values based on equivalent keys.
+
+The element unit in the values to be sorted is determined from the data type, 
+i.e., a ``CV_32FC2`` input ``{a1a2, b1b2}`` will be considered as two elements, regardless its matrix dimension.
+
+Both keys and values will be sorted inplace. 
+
+Keys needs to be a **single** channel `oclMat`.
+
+Example::
+    input -
+    keys   = {2,    3,   1}   (CV_8UC1)
+    values = {10,5, 4,3, 6,2} (CV_8UC2)
+    sortByKey(keys, values, SORT_SELECTION, false);
+    output -
+    keys   = {1,    2,   3}   (CV_8UC1)
+    values = {6,2, 10,5, 4,3} (CV_8UC2)
index fcd847c..55f2fc9 100644 (file)
@@ -211,8 +211,8 @@ namespace cv
         {
             flags &= roi.width < m.cols ? ~Mat::CONTINUOUS_FLAG : -1;
             offset += roi.y * step + roi.x * elemSize();
-            CV_Assert( 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols &&
-                       0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows );
+            CV_Assert( 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.wholecols &&
+                       0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.wholerows );
             if( refcount )
                 CV_XADD(refcount, 1);
             if( rows <= 0 || cols <= 0 )
index d6dd4b9..3c83129 100644 (file)
@@ -248,6 +248,11 @@ namespace cv
             operator Mat() const;
             void download(cv::Mat &m) const;
 
+            //! convert to _InputArray
+            operator _InputArray();
+
+            //! convert to _OutputArray
+            operator _OutputArray();
 
             //! returns a new oclMatrix header for the specified row
             oclMat row(int y) const;
@@ -387,6 +392,9 @@ namespace cv
             int wholecols;
         };
 
+        // convert InputArray/OutputArray to oclMat references
+        CV_EXPORTS oclMat& getOclMatRef(InputArray src);
+        CV_EXPORTS oclMat& getOclMatRef(OutputArray src);
 
         ///////////////////// mat split and merge /////////////////////////////////
         //! Compose a multi-channel array from several single-channel arrays
@@ -508,20 +516,7 @@ namespace cv
         CV_EXPORTS void equalizeHist(const oclMat &mat_src, oclMat &mat_dst);
         
         //! only 8UC1 is supported now
-        class CV_EXPORTS CLAHE
-        {
-        public:
-            virtual void apply(const oclMat &src, oclMat &dst) = 0;
-
-            virtual void setClipLimit(double clipLimit) = 0;
-            virtual double getClipLimit() const = 0;
-
-            virtual void setTilesGridSize(Size tileGridSize) = 0;
-            virtual Size getTilesGridSize() const = 0;
-
-            virtual void collectGarbage() = 0;
-        };
-        CV_EXPORTS Ptr<cv::ocl::CLAHE> createCLAHE(double clipLimit = 40.0, Size tileGridSize = Size(8, 8));
+        CV_EXPORTS Ptr<cv::CLAHE> createCLAHE(double clipLimit = 40.0, Size tileGridSize = Size(8, 8));
         
         //! bilateralFilter
         // supports 8UC1 8UC4
@@ -839,6 +834,18 @@ namespace cv
         CV_EXPORTS void cornerMinEigenVal_dxdy(const oclMat &src, oclMat &dst, oclMat &Dx, oclMat &Dy,
             int blockSize, int ksize, int bordertype = cv::BORDER_DEFAULT);
 
+        /////////////////////////////////// ML ///////////////////////////////////////////
+
+        //! Compute closest centers for each lines in source and lable it after center's index
+        // supports CV_32FC1/CV_32FC2/CV_32FC4 data type
+        CV_EXPORTS void distanceToCenters(oclMat &dists, oclMat &labels, const oclMat &src, const oclMat &centers);
+
+        //!Does k-means procedure on GPU 
+        // supports CV_32FC1/CV_32FC2/CV_32FC4 data type
+        CV_EXPORTS double kmeans(const oclMat &src, int K, oclMat &bestLabels,
+                                     TermCriteria criteria, int attemps, int flags, oclMat &centers);
+
+
         ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
         ///////////////////////////////////////////CascadeClassifier//////////////////////////////////////////////////////////////////
         ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1400,6 +1407,45 @@ namespace cv
             oclMat vPyr_[2];
             bool isDeviceArch11_;
         };
+
+        class CV_EXPORTS FarnebackOpticalFlow
+        {
+        public:
+            FarnebackOpticalFlow();
+
+            int numLevels;
+            double pyrScale;
+            bool fastPyramids;
+            int winSize;
+            int numIters;
+            int polyN;
+            double polySigma;
+            int flags;
+
+            void operator ()(const oclMat &frame0, const oclMat &frame1, oclMat &flowx, oclMat &flowy);
+
+            void releaseMemory();
+
+        private:
+            void prepareGaussian(
+                int n, double sigma, float *g, float *xg, float *xxg,
+                double &ig11, double &ig03, double &ig33, double &ig55);
+
+            void setPolynomialExpansionConsts(int n, double sigma);
+
+            void updateFlow_boxFilter(
+                const oclMat& R0, const oclMat& R1, oclMat& flowx, oclMat &flowy,
+                oclMat& M, oclMat &bufM, int blockSize, bool updateMatrices);
+
+            void updateFlow_gaussianBlur(
+                const oclMat& R0, const oclMat& R1, oclMat& flowx, oclMat& flowy,
+                oclMat& M, oclMat &bufM, int blockSize, bool updateMatrices);
+
+            oclMat frames_[2];
+            oclMat pyrLevel_[2], M_, bufM_, R_[2], blurredFrame_[2];
+            std::vector<oclMat> pyramid0_, pyramid1_;
+        };
+
         //////////////// build warping maps ////////////////////
         //! builds plane warping maps
         CV_EXPORTS void buildWarpPlaneMaps(Size src_size, Rect dst_roi, const Mat &K, const Mat &R, const Mat &T, float scale, oclMat &map_x, oclMat &map_y);
@@ -1627,6 +1673,31 @@ namespace cv
             oclMat diff_buf;
             oclMat norm_buf;
         };
+        // current supported sorting methods
+        enum
+        {
+            SORT_BITONIC,   // only support power-of-2 buffer size
+            SORT_SELECTION, // cannot sort duplicate keys
+            SORT_MERGE,
+            SORT_RADIX      // only support signed int/float keys(CV_32S/CV_32F)
+        };
+        //! Returns the sorted result of all the elements in input based on equivalent keys.
+        //
+        //  The element unit in the values to be sorted is determined from the data type, 
+        //  i.e., a CV_32FC2 input {a1a2, b1b2} will be considered as two elements, regardless its
+        //  matrix dimension.
+        //  both keys and values will be sorted inplace
+        //  Key needs to be single channel oclMat.
+        //
+        //  Example:
+        //  input -
+        //    keys   = {2,    3,   1}   (CV_8UC1)
+        //    values = {10,5, 4,3, 6,2} (CV_8UC2)
+        //  sortByKey(keys, values, SORT_SELECTION, false);
+        //  output -
+        //    keys   = {1,    2,   3}   (CV_8UC1)
+        //    values = {6,2, 10,5, 4,3} (CV_8UC2)
+        void CV_EXPORTS sortByKey(oclMat& keys, oclMat& values, int method, bool isGreaterThan = false);
     }
 }
 #if defined _MSC_VER && _MSC_VER >= 1200
index 2da1775..0875903 100644 (file)
 //
 //M*/
 
-#include "precomp.hpp"
+#include "perf_precomp.hpp"
 
 int main(int argc, const char *argv[])
 {
-    vector<ocl::Info> oclinfo;
-    int num_devices = getDevice(oclinfo);
-
-    if (num_devices < 1)
-    {
-        cerr << "no device found\n";
-        return -1;
-    }
-
-    int devidx = 0;
-
-    for (size_t i = 0; i < oclinfo.size(); i++)
-    {
-        for (size_t j = 0; j < oclinfo[i].DeviceName.size(); j++)
-        {
-            printf("device %d: %s\n", devidx++, oclinfo[i].DeviceName[j].c_str());
-        }
-    }
-
-    redirectError(cvErrorCallback);
-
     const char *keys =
         "{ h | help    | false | print help message }"
         "{ f | filter  |       | filter for test }"
         "{ w | workdir |       | set working directory }"
         "{ l | list    | false | show all tests }"
         "{ d | device  | 0     | device id }"
+        "{ c | cpu_ocl | false | use cpu as ocl device}"
         "{ i | iters   | 10    | iteration count }"
         "{ m | warmup  | 1     | gpu warm up iteration count}"
-        "{ t | xtop    | 1.1     | xfactor top boundary}"
-        "{ b | xbottom | 0.9     | xfactor bottom boundary}"
+        "{ t | xtop    | 1.1   | xfactor top boundary}"
+        "{ b | xbottom | 0.9   | xfactor bottom boundary}"
         "{ v | verify  | false | only run gpu once to verify if problems occur}";
 
+    redirectError(cvErrorCallback);
     CommandLineParser cmd(argc, argv, keys);
-
     if (cmd.get<bool>("help"))
     {
         cout << "Avaible options:" << endl;
@@ -86,14 +66,40 @@ int main(int argc, const char *argv[])
         return 0;
     }
 
-    int device = cmd.get<int>("device");
+    // get ocl devices
+    bool use_cpu = cmd.get<bool>("c");
+    vector<ocl::Info> oclinfo;
+    int num_devices = 0;
+    if(use_cpu)
+        num_devices = getDevice(oclinfo, ocl::CVCL_DEVICE_TYPE_CPU);
+    else
+        num_devices = getDevice(oclinfo);
+    if (num_devices < 1)
+    {
+        cerr << "no device found\n";
+        return -1;
+    }
 
+    // show device info
+    int devidx = 0;
+    for (size_t i = 0; i < oclinfo.size(); i++)
+    {
+        for (size_t j = 0; j < oclinfo[i].DeviceName.size(); j++)
+        {
+            cout << "device " << devidx++ << ": " << oclinfo[i].DeviceName[j] << endl;
+        }
+    }
+
+    int device = cmd.get<int>("device");
     if (device < 0 || device >= num_devices)
     {
         cerr << "Invalid device ID" << endl;
         return -1;
     }
 
+    // set this to overwrite binary cache every time the test starts
+    ocl::setBinaryDiskCache(ocl::CACHE_UPDATE);
+    
     if (cmd.get<bool>("verify"))
     {
         TestSystem::instance().setNumIters(1);
@@ -102,7 +108,6 @@ int main(int argc, const char *argv[])
     }
 
     devidx = 0;
-
     for (size_t i = 0; i < oclinfo.size(); i++)
     {
         for (size_t j = 0; j < oclinfo[i].DeviceName.size(); j++, devidx++)
@@ -111,7 +116,7 @@ int main(int argc, const char *argv[])
             {
                 ocl::setDevice(oclinfo[i], (int)j);
                 TestSystem::instance().setRecordName(oclinfo[i].DeviceName[j]);
-                printf("\nuse %d: %s\n", devidx, oclinfo[i].DeviceName[j].c_str());
+                cout << "use " << devidx << ": " <<oclinfo[i].DeviceName[j] << endl;
                 goto END_DEV;
             }
         }
index 3ef0634..29ff0d8 100644 (file)
@@ -44,7 +44,7 @@
 //
 //M*/
 
-#include "precomp.hpp"
+#include "perf_precomp.hpp"
 ///////////// Lut ////////////////////////
 PERFTEST(lut)
 {
index 8ebb648..2213977 100644 (file)
@@ -44,7 +44,7 @@
 //
 //M*/
 
-#include "precomp.hpp"
+#include "perf_precomp.hpp"
 ///////////// blend ////////////////////////
 template <typename T>
 void blendLinearGold(const cv::Mat &img1, const cv::Mat &img2, const cv::Mat &weights1, const cv::Mat &weights2, cv::Mat &result_gold)
index 406b46a..c481766 100644 (file)
@@ -43,7 +43,7 @@
 // the use of this software, even if advised of the possibility of such damage.
 //
 //M*/
-#include "precomp.hpp"
+#include "perf_precomp.hpp"
 
 //////////////////// BruteForceMatch /////////////////
 PERFTEST(BruteForceMatcher)
similarity index 64%
rename from modules/ocl/test/test_pyrup.cpp
rename to modules/ocl/perf/perf_calib3d.cpp
index afd3e8b..e0622aa 100644 (file)
@@ -15,8 +15,8 @@
 // Third party copyrights are property of their respective owners.
 //
 // @Authors
-//    Zhang Chunpeng chunpeng@multicorewareinc.com
-//    Yao Wang yao@multicorewareinc.com
+//    Fangfang Bai, fangfang@multicorewareinc.com
+//    Jin Ma,       jin@multicorewareinc.com
 //
 // Redistribution and use in source and binary forms, with or without modification,
 // are permitted provided that the following conditions are met:
@@ -31,7 +31,7 @@
 //   * 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
+// 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,
 //
 //M*/
 
-#include "precomp.hpp"
-#include "opencv2/core/core.hpp"
+#include "perf_precomp.hpp"
+///////////// StereoMatchBM ////////////////////////
+PERFTEST(StereoMatchBM)
+{
+       Mat left_image = imread(abspath("aloeL.jpg"), cv::IMREAD_GRAYSCALE);
+       Mat right_image = imread(abspath("aloeR.jpg"), cv::IMREAD_GRAYSCALE);
+       Mat disp,dst;
+       ocl::oclMat d_left, d_right,d_disp;
+       int n_disp= 128;
+       int winSize =19;
 
-#ifdef HAVE_OPENCL
+       SUBTEST << left_image.cols << 'x' << left_image.rows << "; aloeL.jpg ;"<< right_image.cols << 'x' << right_image.rows << "; aloeR.jpg ";
 
-using namespace cv;
-using namespace cvtest;
-using namespace testing;
-using namespace std;
+       StereoBM bm(0, n_disp, winSize);
+       bm(left_image, right_image, dst);
 
-PARAM_TEST_CASE(PyrUp, MatType, int)
-{
-    int type;
-    int channels;
+       CPU_ON;
+       bm(left_image, right_image, dst);
+       CPU_OFF;
 
-    virtual void SetUp()
-    {
-        type = GET_PARAM(0);
-        channels = GET_PARAM(1);
-    }
-};
+       d_left.upload(left_image);
+       d_right.upload(right_image);
 
-TEST_P(PyrUp, Accuracy)
-{
-    for(int j = 0; j < LOOP_TIMES; j++)
-    {
-        Size size(MWIDTH, MHEIGHT);
-        Mat src = randomMat(size, CV_MAKETYPE(type, channels));
-        Mat dst_gold;
-        pyrUp(src, dst_gold);
-        ocl::oclMat dst;
-        ocl::oclMat srcMat(src);
-        ocl::pyrUp(srcMat, dst);
-
-        EXPECT_MAT_NEAR(dst_gold, Mat(dst), (type == CV_32F ? 1e-4f : 1.0));
-    }
+       ocl::StereoBM_OCL d_bm(0, n_disp, winSize);
+
+       WARMUP_ON;
+       d_bm(d_left, d_right, d_disp);
+       WARMUP_OFF;
+
+    cv::Mat ocl_mat;
+    d_disp.download(ocl_mat);
+    ocl_mat.convertTo(ocl_mat, dst.type());
 
+       GPU_ON;
+       d_bm(d_left, d_right, d_disp);
+       GPU_OFF;
+
+       GPU_FULL_ON;
+       d_left.upload(left_image);
+       d_right.upload(right_image);
+       d_bm(d_left, d_right, d_disp);
+       d_disp.download(disp);
+       GPU_FULL_OFF;
+    
+    TestSystem::instance().setAccurate(-1, 0.);
 }
 
 
-INSTANTIATE_TEST_CASE_P(OCL_ImgProc, PyrUp, testing::Combine(
-                            Values(CV_8U, CV_32F), Values(1, 3, 4)));
 
 
-#endif // HAVE_OPENCL
\ No newline at end of file
+
+
+
+
+       
\ No newline at end of file
index cb23d7a..7ea0ce6 100644 (file)
@@ -43,7 +43,7 @@
 // the use of this software, even if advised of the possibility of such damage.
 //
 //M*/
-#include "precomp.hpp"
+#include "perf_precomp.hpp"
 
 ///////////// Canny ////////////////////////
 PERFTEST(Canny)
index daf1cfd..4bd5fa5 100644 (file)
@@ -43,7 +43,7 @@
 // the use of this software, even if advised of the possibility of such damage.
 //
 //M*/
-#include "precomp.hpp"
+#include "perf_precomp.hpp"
 
 ///////////// cvtColor////////////////////////
 PERFTEST(cvtColor)
index 6e0be3f..7073eb6 100644 (file)
@@ -43,7 +43,7 @@
 // the use of this software, even if advised of the possibility of such damage.
 //
 //M*/
-#include "precomp.hpp"
+#include "perf_precomp.hpp"
 
 ///////////// dft ////////////////////////
 PERFTEST(dft)
index a05301b..be288b4 100644 (file)
@@ -43,7 +43,7 @@
 // the use of this software, even if advised of the possibility of such damage.
 //
 //M*/
-#include "precomp.hpp"
+#include "perf_precomp.hpp"
 
 ///////////// Blur////////////////////////
 PERFTEST(Blur)
@@ -284,6 +284,7 @@ PERFTEST(GaussianBlur)
     Mat src, dst, ocl_dst;
     int all_type[] = {CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4};
     std::string type_name[] = {"CV_8UC1", "CV_8UC4", "CV_32FC1", "CV_32FC4"};
+    const int ksize = 7;       
 
     for (int size = Min_Size; size <= Max_Size; size *= Multiple)
     {
@@ -291,29 +292,28 @@ PERFTEST(GaussianBlur)
         {
             SUBTEST << size << 'x' << size << "; " << type_name[j] ;
 
-            gen(src, size, size, all_type[j], 5, 16);
+            gen(src, size, size, all_type[j], 0, 256);
 
-            GaussianBlur(src, dst, Size(9, 9), 0);
+            GaussianBlur(src, dst, Size(ksize, ksize), 0);
 
             CPU_ON;
-            GaussianBlur(src, dst, Size(9, 9), 0);
+            GaussianBlur(src, dst, Size(ksize, ksize), 0);
             CPU_OFF;
 
             ocl::oclMat d_src(src);
-            ocl::oclMat d_dst(src.size(), src.type());
-            ocl::oclMat d_buf;
+            ocl::oclMat d_dst;
 
             WARMUP_ON;
-            ocl::GaussianBlur(d_src, d_dst, Size(9, 9), 0);
+            ocl::GaussianBlur(d_src, d_dst, Size(ksize, ksize), 0);
             WARMUP_OFF;
 
             GPU_ON;
-            ocl::GaussianBlur(d_src, d_dst, Size(9, 9), 0);
+            ocl::GaussianBlur(d_src, d_dst, Size(ksize, ksize), 0);
             GPU_OFF;
 
             GPU_FULL_ON;
             d_src.upload(src);
-            ocl::GaussianBlur(d_src, d_dst, Size(9, 9), 0);
+            ocl::GaussianBlur(d_src, d_dst, Size(ksize, ksize), 0);
             d_dst.download(ocl_dst);
             GPU_FULL_OFF;
 
index f197c5f..abaeda3 100644 (file)
@@ -43,7 +43,7 @@
 // the use of this software, even if advised of the possibility of such damage.
 //
 //M*/
-#include "precomp.hpp"
+#include "perf_precomp.hpp"
 
 ///////////// gemm ////////////////////////
 PERFTEST(gemm)
similarity index 53%
rename from modules/ocl/src/precomp.cpp
rename to modules/ocl/perf/perf_gftt.cpp
index 766138c..9e809e4 100644 (file)
 //                           License Agreement
 //                For Open Source Computer Vision Library
 //
-// Copyright (C) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved.
+// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
 // Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
 // Third party copyrights are property of their respective owners.
 //
 // @Authors
+//    Peng Xiao, pengxiao@outlook.com
 //
 // Redistribution and use in source and binary forms, with or without modification,
 // are permitted provided that the following conditions are met:
@@ -29,7 +30,7 @@
 //   * 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
+// 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,
 //
 //M*/
 
-#include "precomp.hpp"
-//CriticalSection cs;
-/* End of file. */
+
+#include "perf_precomp.hpp"
+
+///////////// GoodFeaturesToTrack ////////////////////////
+PERFTEST(GoodFeaturesToTrack)
+{
+    using namespace cv;
+
+    int maxCorners = 2000;
+    double qualityLevel = 0.01;
+
+    std::string images[] = { "rubberwhale1.png", "aloeL.jpg" };
+    
+    std::vector<cv::Point2f> pts_gold, pts_ocl;
+
+    for(size_t imgIdx = 0; imgIdx < (sizeof(images)/sizeof(std::string)); ++imgIdx)
+    {
+        Mat frame = imread(abspath(images[imgIdx]), IMREAD_GRAYSCALE);
+        CV_Assert(!frame.empty());
+        
+        for(float minDistance = 0; minDistance < 4; minDistance += 3.0)
+        {
+            SUBTEST << "image = " << images[imgIdx] << "; ";
+            SUBTEST << "minDistance = " << minDistance << "; ";
+
+            cv::goodFeaturesToTrack(frame, pts_gold, maxCorners, qualityLevel, minDistance);
+
+            CPU_ON;
+            cv::goodFeaturesToTrack(frame, pts_gold, maxCorners, qualityLevel, minDistance);
+            CPU_OFF;
+
+            cv::ocl::GoodFeaturesToTrackDetector_OCL detector(maxCorners, qualityLevel, minDistance);
+
+            ocl::oclMat frame_ocl(frame), pts_oclmat;
+
+            WARMUP_ON;
+            detector(frame_ocl, pts_oclmat);
+            WARMUP_OFF;
+
+            detector.downloadPoints(pts_oclmat, pts_ocl);
+
+            double diff = abs(static_cast<float>(pts_gold.size() - pts_ocl.size()));
+            TestSystem::instance().setAccurate(diff == 0.0, diff);
+
+            GPU_ON;
+            detector(frame_ocl, pts_oclmat);
+            GPU_OFF;
+
+            GPU_FULL_ON;
+            frame_ocl.upload(frame);
+            detector(frame_ocl, pts_oclmat);
+            detector.downloadPoints(pts_oclmat, pts_ocl);
+            GPU_FULL_OFF;
+        }
+    }
+}
index 72f01dc..26bed5e 100644 (file)
@@ -43,7 +43,7 @@
 // the use of this software, even if advised of the possibility of such damage.
 //
 //M*/
-#include "precomp.hpp"
+#include "perf_precomp.hpp"
 
 ///////////// Haar ////////////////////////
 namespace cv
index 0509381..0f05581 100644 (file)
 // the use of this software, even if advised of the possibility of such damage.
 //
 //M*/
-#include "precomp.hpp"
+#include "perf_precomp.hpp"
 
 ///////////// HOG////////////////////////
-bool match_rect(cv::Rect r1, cv::Rect r2, int threshold)
-{
-    return ((abs(r1.x - r2.x) < threshold) && (abs(r1.y - r2.y) < threshold) &&
-        (abs(r1.width - r2.width) < threshold) && (abs(r1.height - r2.height) < threshold));
-}
 
 PERFTEST(HOG)
 {
@@ -61,13 +56,12 @@ PERFTEST(HOG)
         throw runtime_error("can't open road.png");
     }
 
-
     cv::HOGDescriptor hog;
     hog.setSVMDetector(hog.getDefaultPeopleDetector());
     std::vector<cv::Rect> found_locations;
     std::vector<cv::Rect> d_found_locations;
 
-    SUBTEST << 768 << 'x' << 576 << "; road.png";
+    SUBTEST << src.cols << 'x' << src.rows << "; road.png";
 
     hog.detectMultiScale(src, found_locations);
 
@@ -84,70 +78,10 @@ PERFTEST(HOG)
     ocl_hog.detectMultiScale(d_src, d_found_locations);
     WARMUP_OFF;
     
-    // Ground-truth rectangular people window
-    cv::Rect win1_64x128(231, 190, 72, 144);
-    cv::Rect win2_64x128(621, 156, 97, 194);
-    cv::Rect win1_48x96(238, 198, 63, 126);
-    cv::Rect win2_48x96(619, 161, 92, 185);
-    cv::Rect win3_48x96(488, 136, 56, 112);
-
-    // Compare whether ground-truth windows are detected and compare the number of windows detected.
-    std::vector<int> d_comp(4);
-    std::vector<int> comp(4);
-    for(int i = 0; i < (int)d_comp.size(); i++)
-    {
-        d_comp[i] = 0;
-        comp[i] = 0;
-    }
-
-    int threshold = 10;
-    int val = 32;
-    d_comp[0] = (int)d_found_locations.size();
-    comp[0] = (int)found_locations.size();
-
-    cv::Size winSize = hog.winSize;
-
-    if (winSize == cv::Size(48, 96))
-    {
-        for(int i = 0; i < (int)d_found_locations.size(); i++)
-        {
-            if (match_rect(d_found_locations[i], win1_48x96, threshold))
-                d_comp[1] = val;
-            if (match_rect(d_found_locations[i], win2_48x96, threshold))
-                d_comp[2] = val;
-            if (match_rect(d_found_locations[i], win3_48x96, threshold))
-                d_comp[3] = val;
-        }
-        for(int i = 0; i < (int)found_locations.size(); i++)
-        {
-            if (match_rect(found_locations[i], win1_48x96, threshold))
-                comp[1] = val;
-            if (match_rect(found_locations[i], win2_48x96, threshold))
-                comp[2] = val;
-            if (match_rect(found_locations[i], win3_48x96, threshold))
-                comp[3] = val;
-        }
-    }
-    else if (winSize == cv::Size(64, 128))
-    {
-        for(int i = 0; i < (int)d_found_locations.size(); i++)
-        {
-            if (match_rect(d_found_locations[i], win1_64x128, threshold))
-                d_comp[1] = val;
-            if (match_rect(d_found_locations[i], win2_64x128, threshold))
-                d_comp[2] = val;
-        }
-        for(int i = 0; i < (int)found_locations.size(); i++)
-        {
-            if (match_rect(found_locations[i], win1_64x128, threshold))
-                comp[1] = val;
-            if (match_rect(found_locations[i], win2_64x128, threshold))
-                comp[2] = val;
-        }
-    }
-
-    cv::Mat gpu_rst(d_comp), cpu_rst(comp);
-    TestSystem::instance().ExpectedMatNear(gpu_rst, cpu_rst, 3);
+    if(d_found_locations.size() == found_locations.size())
+        TestSystem::instance().setAccurate(1, 0);
+    else
+        TestSystem::instance().setAccurate(0, abs((int)found_locations.size() - (int)d_found_locations.size()));
 
     GPU_ON;
     ocl_hog.detectMultiScale(d_src, found_locations);
index e87e821..582853d 100644 (file)
@@ -43,7 +43,7 @@
 // the use of this software, even if advised of the possibility of such damage.
 //
 //M*/
-#include "precomp.hpp"
+#include "perf_precomp.hpp"
 
 ///////////// equalizeHist ////////////////////////
 PERFTEST(equalizeHist)
@@ -743,12 +743,12 @@ PERFTEST(meanShiftFiltering)
         WARMUP_OFF;
 
         GPU_ON;
-        ocl::meanShiftFiltering(d_src, d_dst, sp, sr);
+        ocl::meanShiftFiltering(d_src, d_dst, sp, sr, crit);
         GPU_OFF;
 
         GPU_FULL_ON;
         d_src.upload(src);
-        ocl::meanShiftFiltering(d_src, d_dst, sp, sr);
+        ocl::meanShiftFiltering(d_src, d_dst, sp, sr, crit);
         d_dst.download(ocl_dst);
         GPU_FULL_OFF;
 
@@ -932,8 +932,8 @@ PERFTEST(CLAHE)
 
     double clipLimit = 40.0;
 
-    cv::Ptr<cv::CLAHE>      clahe   = cv::createCLAHE(clipLimit);
-    cv::Ptr<cv::ocl::CLAHE> d_clahe = cv::ocl::createCLAHE(clipLimit);
+    cv::Ptr<cv::CLAHE> clahe   = cv::createCLAHE(clipLimit);
+    cv::Ptr<cv::CLAHE> d_clahe = cv::ocl::createCLAHE(clipLimit);
 
     for (int size = Min_Size; size <= Max_Size; size *= Multiple)
     {
@@ -969,3 +969,45 @@ PERFTEST(CLAHE)
         }
     }
 }
+
+///////////// columnSum////////////////////////
+PERFTEST(columnSum)
+{
+    Mat src, dst, ocl_dst;
+    ocl::oclMat d_src, d_dst;
+
+    for (int size = Min_Size; size <= Max_Size; size *= Multiple)
+    {
+        SUBTEST << size << 'x' << size << "; CV_32FC1";
+
+        gen(src, size, size, CV_32FC1, 0, 256);
+
+        CPU_ON;
+        dst.create(src.size(), src.type());
+        for (int j = 0; j < src.cols; j++)
+            dst.at<float>(0, j) = src.at<float>(0, j);
+
+        for (int i = 1; i < src.rows; ++i)
+            for (int j = 0; j < src.cols; ++j)
+                dst.at<float>(i, j) = dst.at<float>(i - 1 , j) + src.at<float>(i , j);
+        CPU_OFF;
+
+        d_src.upload(src);
+
+        WARMUP_ON;
+        ocl::columnSum(d_src, d_dst);
+        WARMUP_OFF;
+
+        GPU_ON;
+        ocl::columnSum(d_src, d_dst);
+        GPU_OFF;
+
+        GPU_FULL_ON;
+        d_src.upload(src);
+        ocl::columnSum(d_src, d_dst);
+        d_dst.download(ocl_dst);
+        GPU_FULL_OFF;
+
+        TestSystem::instance().ExpectedMatNear(dst, ocl_dst, 5e-1);
+    }
+}
index 5da15aa..8aafc98 100644 (file)
@@ -43,7 +43,7 @@
 // the use of this software, even if advised of the possibility of such damage.
 //
 //M*/
-#include "precomp.hpp"
+#include "perf_precomp.hpp"
 
 /////////// matchTemplate ////////////////////////
 //void InitMatchTemplate()
index b724cdb..bb407c9 100644 (file)
@@ -43,7 +43,7 @@
 // the use of this software, even if advised of the possibility of such damage.
 //
 //M*/
-#include "precomp.hpp"
+#include "perf_precomp.hpp"
 
 ///////////// ConvertTo////////////////////////
 PERFTEST(ConvertTo)
similarity index 67%
rename from modules/ocl/perf/perf_columnsum.cpp
rename to modules/ocl/perf/perf_moments.cpp
index ff7ebcd..a1515b8 100644 (file)
 // the use of this software, even if advised of the possibility of such damage.
 //
 //M*/
-#include "precomp.hpp"
-
-///////////// columnSum////////////////////////
-PERFTEST(columnSum)
+#include "perf_precomp.hpp"
+///////////// Moments ////////////////////////
+PERFTEST(Moments)
 {
-    Mat src, dst, ocl_dst;
-    ocl::oclMat d_src, d_dst;
+    Mat src;
+    bool binaryImage = 0;
+
+    int all_type[] = {CV_8UC1, CV_16SC1, CV_32FC1, CV_64FC1};
+    std::string type_name[] = {"CV_8UC1", "CV_16SC1", "CV_32FC1", "CV_64FC1"};
 
     for (int size = Min_Size; size <= Max_Size; size *= Multiple)
     {
-        SUBTEST << size << 'x' << size << "; CV_32FC1";
+        for (size_t j = 0; j < sizeof(all_type) / sizeof(int); j++)
+        {
+            SUBTEST << size << 'x' << size << "; " << type_name[j];
+
+            gen(src, size, size, all_type[j], 0, 256);
+
+            cv::Moments CvMom = moments(src, binaryImage);
 
-        gen(src, size, size, CV_32FC1, 0, 256);
+            CPU_ON;
+            moments(src, binaryImage);
+            CPU_OFF;
 
-        CPU_ON;
-        dst.create(src.size(), src.type());
-        for (int j = 0; j < src.cols; j++)
-            dst.at<float>(0, j) = src.at<float>(0, j);
+            cv::Moments oclMom;
+            WARMUP_ON;
+            oclMom = ocl::ocl_moments(src, binaryImage);
+            WARMUP_OFF;
 
-        for (int i = 1; i < src.rows; ++i)
-            for (int j = 0; j < src.cols; ++j)
-                dst.at<float>(i, j) = dst.at<float>(i - 1 , j) + src.at<float>(i , j);
-        CPU_OFF;
+            Mat gpu_dst, cpu_dst;
+            HuMoments(CvMom, cpu_dst);
+            HuMoments(oclMom, gpu_dst);
 
-        d_src.upload(src);
+            GPU_ON;
+            ocl::ocl_moments(src, binaryImage);
+            GPU_OFF;
 
-        WARMUP_ON;
-        ocl::columnSum(d_src, d_dst);
-        WARMUP_OFF;
+            GPU_FULL_ON;
+            ocl::ocl_moments(src, binaryImage);
+            GPU_FULL_OFF;
 
-        GPU_ON;
-        ocl::columnSum(d_src, d_dst);
-        GPU_OFF;
+            TestSystem::instance().ExpectedMatNear(gpu_dst, cpu_dst, .5);
 
-        GPU_FULL_ON;
-        d_src.upload(src);
-        ocl::columnSum(d_src, d_dst);
-        d_dst.download(ocl_dst);
-        GPU_FULL_OFF;
+        }
 
-        TestSystem::instance().ExpectedMatNear(dst, ocl_dst, 5e-1);
     }
-}
\ No newline at end of file
+}
index 1d986c8..fec8d73 100644 (file)
@@ -43,7 +43,7 @@
 // the use of this software, even if advised of the possibility of such damage.
 //
 //M*/
-#include "precomp.hpp"
+#include "perf_precomp.hpp"
 
 ///////////// norm////////////////////////
 PERFTEST(norm)
index 97283b2..a6724c8 100644 (file)
 // the use of this software, even if advised of the possibility of such damage.
 //
 //M*/
-#include "precomp.hpp"
+#include "perf_precomp.hpp"
 
 ///////////// PyrLKOpticalFlow ////////////////////////
 PERFTEST(PyrLKOpticalFlow)
 {
-    std::string images1[] = {"rubberwhale1.png", "basketball1.png"};
-    std::string images2[] = {"rubberwhale2.png", "basketball2.png"};
+    std::string images1[] = {"rubberwhale1.png", "aloeL.jpg"};
+    std::string images2[] = {"rubberwhale2.png", "aloeR.jpg"};
 
     for (size_t i = 0; i < sizeof(images1) / sizeof(std::string); i++)
     {
@@ -136,11 +136,13 @@ PERFTEST(PyrLKOpticalFlow)
             size_t mismatch = 0;
             for (int i = 0; i < (int)nextPts.size(); ++i)
             {
-                if(status[i] != ocl_status.at<unsigned char>(0, i)){
+                if(status[i] != ocl_status.at<unsigned char>(0, i))
+                {
                     mismatch++;
                     continue;
                 }
-                if(status[i]){
+                if(status[i])
+                {
                     Point2f gpu_rst = ocl_nextPts.at<Point2f>(0, i);
                     Point2f cpu_rst = nextPts[i];
                     if(fabs(gpu_rst.x - cpu_rst.x) >= 1. || fabs(gpu_rst.y - cpu_rst.y) >= 1.)
@@ -193,24 +195,24 @@ PERFTEST(tvl1flow)
     WARMUP_ON;
     d_alg(d0, d1, d_flowx, d_flowy);
     WARMUP_OFF;
-/*
-    double diff1 = 0.0, diff2 = 0.0;
-    if(ExceptedMatSimilar(gold[0], cv::Mat(d_flowx), 3e-3, diff1) == 1
-        &&ExceptedMatSimilar(gold[1], cv::Mat(d_flowy), 3e-3, diff2) == 1)
-        TestSystem::instance().setAccurate(1);
-    else
-        TestSystem::instance().setAccurate(0);
+    /*
+        double diff1 = 0.0, diff2 = 0.0;
+        if(ExceptedMatSimilar(gold[0], cv::Mat(d_flowx), 3e-3, diff1) == 1
+            &&ExceptedMatSimilar(gold[1], cv::Mat(d_flowy), 3e-3, diff2) == 1)
+            TestSystem::instance().setAccurate(1);
+        else
+            TestSystem::instance().setAccurate(0);
 
-    TestSystem::instance().setDiff(diff1);
-    TestSystem::instance().setDiff(diff2);
-*/
+        TestSystem::instance().setDiff(diff1);
+        TestSystem::instance().setDiff(diff2);
+    */
 
 
     GPU_ON;
     d_alg(d0, d1, d_flowx, d_flowy);
     d_alg.collectGarbage();
     GPU_OFF;
-    
+
 
     cv::Mat flowx, flowy;
 
@@ -225,4 +227,130 @@ PERFTEST(tvl1flow)
 
     TestSystem::instance().ExceptedMatSimilar(gold[0], flowx, 3e-3);
     TestSystem::instance().ExceptedMatSimilar(gold[1], flowy, 3e-3);
-}
\ No newline at end of file
+}
+
+///////////// FarnebackOpticalFlow ////////////////////////
+PERFTEST(FarnebackOpticalFlow)
+{
+    cv::Mat frame0 = imread("rubberwhale1.png", cv::IMREAD_GRAYSCALE);
+    ASSERT_FALSE(frame0.empty());
+
+    cv::Mat frame1 = imread("rubberwhale2.png", cv::IMREAD_GRAYSCALE);
+    ASSERT_FALSE(frame1.empty());
+
+    cv::ocl::oclMat d_frame0(frame0), d_frame1(frame1);
+
+    int polyNs[2] = { 5, 7 };
+    double polySigmas[2] = { 1.1, 1.5 };
+    int farneFlags[2] = { 0, cv::OPTFLOW_FARNEBACK_GAUSSIAN };
+    bool UseInitFlows[2] = { false, true };
+    double pyrScale = 0.5;
+
+    string farneFlagStrs[2] = { "BoxFilter", "GaussianBlur" };
+    string useInitFlowStrs[2] = { "", "UseInitFlow" };
+
+    for ( int i = 0; i < 2; ++i)
+    {
+        int polyN = polyNs[i];
+        double polySigma = polySigmas[i];
+
+        for ( int j = 0; j < 2; ++j)
+        {
+            int flags = farneFlags[j];
+
+            for ( int k = 0; k < 2; ++k)
+            {
+                bool useInitFlow = UseInitFlows[k];
+                SUBTEST << "polyN(" << polyN << "); " << farneFlagStrs[j] << "; " << useInitFlowStrs[k];
+
+                cv::ocl::FarnebackOpticalFlow farn;
+                farn.pyrScale = pyrScale;
+                farn.polyN = polyN;
+                farn.polySigma = polySigma;
+                farn.flags = flags;
+
+                cv::ocl::oclMat d_flowx, d_flowy;
+                cv::Mat flow, flowBuf, flowxBuf, flowyBuf;
+
+                WARMUP_ON;
+                farn(d_frame0, d_frame1, d_flowx, d_flowy);
+
+                if (useInitFlow)
+                {
+                    cv::Mat flowxy[] = {cv::Mat(d_flowx), cv::Mat(d_flowy)};
+                    cv::merge(flowxy, 2, flow);
+                    flow.copyTo(flowBuf);
+                    flowxy[0].copyTo(flowxBuf);
+                    flowxy[1].copyTo(flowyBuf);
+
+                    farn.flags |= cv::OPTFLOW_USE_INITIAL_FLOW;
+                    farn(d_frame0, d_frame1, d_flowx, d_flowy);
+                }
+                WARMUP_OFF;
+
+                cv::calcOpticalFlowFarneback(
+                    frame0, frame1, flow, farn.pyrScale, farn.numLevels, farn.winSize,
+                    farn.numIters, farn.polyN, farn.polySigma, farn.flags);
+
+                std::vector<cv::Mat> flowxy;
+                cv::split(flow, flowxy);
+
+                Mat md_flowx = cv::Mat(d_flowx);
+                Mat md_flowy = cv::Mat(d_flowy);
+                TestSystem::instance().ExceptedMatSimilar(flowxy[0], md_flowx, 0.1);
+                TestSystem::instance().ExceptedMatSimilar(flowxy[1], md_flowy, 0.1);
+
+                if (useInitFlow)
+                {
+                    cv::Mat flowx, flowy;
+                    farn.flags = (flags | cv::OPTFLOW_USE_INITIAL_FLOW);
+
+                    CPU_ON;
+                    cv::calcOpticalFlowFarneback(
+                        frame0, frame1, flowBuf, farn.pyrScale, farn.numLevels, farn.winSize,
+                        farn.numIters, farn.polyN, farn.polySigma, farn.flags);
+                    CPU_OFF;
+
+                    GPU_ON;
+                    farn(d_frame0, d_frame1, d_flowx, d_flowy);
+                    GPU_OFF;
+
+                    GPU_FULL_ON;
+                    d_frame0.upload(frame0);
+                    d_frame1.upload(frame1);
+                    d_flowx.upload(flowxBuf);
+                    d_flowy.upload(flowyBuf);
+                    farn(d_frame0, d_frame1, d_flowx, d_flowy);
+                    d_flowx.download(flowx);
+                    d_flowy.download(flowy);
+                    GPU_FULL_OFF;
+                }
+                else
+                {
+                    cv::Mat flow, flowx, flowy;
+                    cv::ocl::oclMat d_flowx, d_flowy;
+
+                    farn.flags = flags;
+
+                    CPU_ON;
+                    cv::calcOpticalFlowFarneback(
+                        frame0, frame1, flow, farn.pyrScale, farn.numLevels, farn.winSize,
+                        farn.numIters, farn.polyN, farn.polySigma, farn.flags);
+                    CPU_OFF;
+
+                    GPU_ON;
+                    farn(d_frame0, d_frame1, d_flowx, d_flowy);
+                    GPU_OFF;
+
+                    GPU_FULL_ON;
+                    d_frame0.upload(frame0);
+                    d_frame1.upload(frame1);
+                    farn(d_frame0, d_frame1, d_flowx, d_flowy);
+                    d_flowx.download(flowx);
+                    d_flowy.download(flowy);
+                    GPU_FULL_OFF;
+                }
+            }
+        }
+    }
+}
similarity index 97%
rename from modules/ocl/perf/precomp.cpp
rename to modules/ocl/perf/perf_precomp.cpp
index 71a13a1..2a49eb2 100644 (file)
 //
 //M*/
 
-#include "precomp.hpp"
+#include "perf_precomp.hpp"
 #if GTEST_OS_WINDOWS
+#ifndef NOMINMAX
 #define NOMINMAX
+#endif
 # include <windows.h>
 #endif
 
@@ -278,7 +280,7 @@ enum GTestColor {
 };
 #if GTEST_OS_WINDOWS&&!GTEST_OS_WINDOWS_MOBILE
 // Returns the character attribute for the given color.
-WORD GetColorAttribute(GTestColor color) {
+static WORD GetColorAttribute(GTestColor color) {
     switch (color) {
     case COLOR_RED:    return FOREGROUND_RED;
     case COLOR_GREEN:  return FOREGROUND_GREEN;
@@ -331,20 +333,6 @@ void TestSystem::printMetrics(int is_accurate, double cpu_time, double gpu_time,
     cout << setiosflags(ios_base::left);
     stringstream stream;
 
-#if 0
-    if(is_accurate == 1)
-            stream << "Pass";
-    else if(is_accurate_ == 0)
-            stream << "Fail";
-    else if(is_accurate == -1)
-        stream << " ";
-    else
-    {
-        std::cout<<"is_accurate errer: "<<is_accurate<<"\n";
-        exit(-1);
-    }
-#endif
-
     std::stringstream &cur_subtest_description = getCurSubtestDescription();
    
 #if GTEST_OS_WINDOWS&&!GTEST_OS_WINDOWS_MOBILE
similarity index 98%
rename from modules/ocl/perf/precomp.hpp
rename to modules/ocl/perf/perf_precomp.hpp
index 97e3d7e..2df1b2c 100644 (file)
@@ -40,6 +40,9 @@
 //
 //M*/
 
+#ifndef __OPENCV_PERF_PRECOMP_HPP__
+#define __OPENCV_PERF_PRECOMP_HPP__
+
 #include <iomanip>
 #include <stdexcept>
 #include <string>
@@ -99,7 +102,7 @@ int EeceptDoubleEQ(T1 expected, T1 actual)
     testing::internal::Double lhs(expected);
     testing::internal::Double rhs(actual);
 
-    if (lhs.AlmostEquals(rhs)) 
+    if (lhs.AlmostEquals(rhs))
     {
         return 1;
     }
@@ -352,7 +355,7 @@ public:
         if(accurate_diff_ <= eps)
             is_accurate_ = 1;
         else
-            is_accurate_ = 0;    
+            is_accurate_ = 0;
     }
 
     std::stringstream &getCurSubtestDescription()
@@ -369,7 +372,7 @@ private:
         speedup_full_faster_count_(0), speedup_full_slower_count_(0), speedup_full_equal_count_(0), is_list_mode_(false),
         num_iters_(10), cpu_num_iters_(2),
         gpu_warmup_iters_(1), cur_iter_idx_(0), cur_warmup_idx_(0),
-        record_(0), recordname_("performance"), itname_changed_(true), 
+        record_(0), recordname_("performance"), itname_changed_(true),
         is_accurate_(-1), accurate_diff_(0.)
     {
         cpu_times_.reserve(num_iters_);
@@ -506,3 +509,5 @@ struct name##_test: Runnable { \
 #define WARMUP_OFF \
        ocl::finish();\
        } TestSystem::instance().warmupComplete()
+
+#endif
index 3b96251..b98f531 100644 (file)
@@ -43,7 +43,7 @@
 // the use of this software, even if advised of the possibility of such damage.
 //
 //M*/
-#include "precomp.hpp"
+#include "perf_precomp.hpp"
 
 ///////////// pyrDown //////////////////////
 PERFTEST(pyrDown)
index 0fafd14..cbe817f 100644 (file)
@@ -43,7 +43,7 @@
 // the use of this software, even if advised of the possibility of such damage.
 //
 //M*/
-#include "precomp.hpp"
+#include "perf_precomp.hpp"
 
 ///////////// Merge////////////////////////
 PERFTEST(Merge)
index e14bd27..493dbc3 100644 (file)
@@ -213,7 +213,7 @@ void cvtColor_caller(const oclMat &src, oclMat &dst, int code, int dcn)
     case CV_RGB2YUV:
     {
         CV_Assert(scn == 3 || scn == 4);
-        bidx = code == CV_BGR2YUV ? 0 : 2;
+        bidx = code == CV_RGB2YUV ? 0 : 2;
         dst.create(sz, CV_MAKETYPE(depth, 3));
         RGB2YUV_caller(src, dst, bidx);
         break;
@@ -222,7 +222,7 @@ void cvtColor_caller(const oclMat &src, oclMat &dst, int code, int dcn)
     case CV_YUV2RGB:
     {
         CV_Assert(scn == 3 || scn == 4);
-        bidx = code == CV_YUV2BGR ? 0 : 2;
+        bidx = code == CV_YUV2RGB ? 0 : 2;
         dst.create(sz, CV_MAKETYPE(depth, 3));
         YUV2RGB_caller(src, dst, bidx);
         break;
similarity index 97%
rename from modules/ocl/src/gfft.cpp
rename to modules/ocl/src/gftt.cpp
index 7fd5e3a..0684417 100644 (file)
@@ -55,7 +55,7 @@ namespace cv
     namespace ocl
     {
         ///////////////////////////OpenCL kernel strings///////////////////////////
-        extern const char *imgproc_gfft;
+        extern const char *imgproc_gftt;
     }
 }
 
@@ -133,7 +133,7 @@ struct Sorter<BITONIC>
             for(int passOfStage = 0; passOfStage < stage + 1; ++passOfStage)
             {
                 args[4] = std::make_pair(sizeof(cl_int), (void *)&passOfStage);
-                openCLExecuteKernel(cxt, &imgproc_gfft, kernelname, globalThreads, localThreads, args, -1, -1);
+                openCLExecuteKernel(cxt, &imgproc_gftt, kernelname, globalThreads, localThreads, args, -1, -1);
             }
         }
     }
@@ -160,12 +160,12 @@ struct Sorter<SELECTION>
         args.push_back( std::make_pair( sizeof(cl_int), (void*)&count) );
         args.push_back( std::make_pair( lds_size,       (void*)NULL) );
 
-        openCLExecuteKernel(cxt, &imgproc_gfft, kernelname, globalThreads, localThreads, args, -1, -1);
+        openCLExecuteKernel(cxt, &imgproc_gftt, kernelname, globalThreads, localThreads, args, -1, -1);
 
         //final
         kernelname = "sortCorners_selectionSortFinal";
         args.pop_back();
-        openCLExecuteKernel(cxt, &imgproc_gfft, kernelname, globalThreads, localThreads, args, -1, -1);
+        openCLExecuteKernel(cxt, &imgproc_gftt, kernelname, globalThreads, localThreads, args, -1, -1);
     }
 };
 
@@ -201,7 +201,7 @@ int findCorners_caller(
     size_t localThreads[3]  = {16, 16, 1};
 
     const char * opt = mask.empty() ? "" : "-D WITH_MASK";
-    openCLExecuteKernel(cxt, &imgproc_gfft, kernelname, globalThreads, localThreads, args, -1, -1, opt);
+    openCLExecuteKernel(cxt, &imgproc_gftt, kernelname, globalThreads, localThreads, args, -1, -1, opt);
     return std::min(Mat(g_counter).at<int>(0), max_count);
 }
 }//unnamed namespace
index 565270c..6283ac8 100644 (file)
@@ -142,7 +142,7 @@ typedef struct
     int imgoff;
     float factor;
 } detect_piramid_info;
-#ifdef WIN32
+#ifdef _MSC_VER
 #define _ALIGNED_ON(_ALIGNMENT) __declspec(align(_ALIGNMENT))
 
 typedef _ALIGNED_ON(128) struct  GpuHidHaarTreeNode
index a351458..c7ac409 100644 (file)
@@ -15,7 +15,7 @@
 // Third party copyrights are property of their respective owners.
 //
 // @Authors
-//             Wenju He, wenju@multicorewareinc.com
+//     Wenju He, wenju@multicorewareinc.com
 //
 // Redistribution and use in source and binary forms, with or without modification,
 // are permitted provided that the following conditions are met:
@@ -48,13 +48,15 @@ using namespace cv;
 using namespace cv::ocl;
 using namespace std;
 
-
 #define CELL_WIDTH 8
 #define CELL_HEIGHT 8
 #define CELLS_PER_BLOCK_X 2
 #define CELLS_PER_BLOCK_Y 2
 #define NTHREADS 256
 
+static oclMat gauss_w_lut;
+static bool hog_device_cpu;
+
 namespace cv
 {
     namespace ocl
@@ -78,38 +80,43 @@ namespace cv
                 int cnblocks_win_x;
                 int cnblocks_win_y;
                 int cblock_hist_size;
-                int cblock_hist_size_2up;
                 int cdescr_size;
                 int cdescr_width;
+                int cdescr_height;
 
                 void set_up_constants(int nbins, int block_stride_x, int block_stride_y,
                                       int nblocks_win_x, int nblocks_win_y);
 
                 void compute_hists(int nbins, int block_stride_x, int blovck_stride_y,
                                    int height, int width, const cv::ocl::oclMat &grad,
-                                   const cv::ocl::oclMat &qangle, float sigma, cv::ocl::oclMat &block_hists);
+                                   const cv::ocl::oclMat &qangle, 
+                                   const cv::ocl::oclMat &gauss_w_lut, cv::ocl::oclMat &block_hists);
 
                 void normalize_hists(int nbins, int block_stride_x, int block_stride_y,
-                                     int height, int width, cv::ocl::oclMat &block_hists, float threshold);
+                                     int height, int width, cv::ocl::oclMat &block_hists, 
+                                     float threshold);
 
                 void classify_hists(int win_height, int win_width, int block_stride_y,
-                                    int block_stride_x, int win_stride_y, int win_stride_x, int height,
-                                    int width, const cv::ocl::oclMat &block_hists, const cv::ocl::oclMat &coefs, float free_coef,
+                                    int block_stride_x, int win_stride_y, int win_stride_x, 
+                                    int height, int width, const cv::ocl::oclMat &block_hists, 
+                                    const cv::ocl::oclMat &coefs, float free_coef,
                                     float threshold, cv::ocl::oclMat &labels);
 
-                void extract_descrs_by_rows(int win_height, int win_width, int block_stride_y, int block_stride_x,
-                                            int win_stride_y, int win_stride_x, int height, int width, const cv::ocl::oclMat &block_hists,
+                void extract_descrs_by_rows(int win_height, int win_width, int block_stride_y, 
+                                            int block_stride_x, int win_stride_y, int win_stride_x, 
+                                            int height, int width, const cv::ocl::oclMat &block_hists,
                                             cv::ocl::oclMat &descriptors);
-                void extract_descrs_by_cols(int win_height, int win_width, int block_stride_y, int block_stride_x,
-                                            int win_stride_y, int win_stride_x, int height, int width, const cv::ocl::oclMat &block_hists,
+                void extract_descrs_by_cols(int win_height, int win_width, int block_stride_y, 
+                                            int block_stride_x, int win_stride_y, int win_stride_x, 
+                                            int height, int width, const cv::ocl::oclMat &block_hists,
                                             cv::ocl::oclMat &descriptors);
 
                 void compute_gradients_8UC1(int height, int width, const cv::ocl::oclMat &img,
-                                            float angle_scale, cv::ocl::oclMat &grad, cv::ocl::oclMat &qangle, bool correct_gamma);
+                                            float angle_scale, cv::ocl::oclMat &grad, 
+                                            cv::ocl::oclMat &qangle, bool correct_gamma);
                 void compute_gradients_8UC4(int height, int width, const cv::ocl::oclMat &img,
-                                            float angle_scale, cv::ocl::oclMat &grad, cv::ocl::oclMat &qangle, bool correct_gamma);
-
-                void resize( const oclMat &src, oclMat &dst, const Size sz);
+                                            float angle_scale, cv::ocl::oclMat &grad, 
+                                            cv::ocl::oclMat &qangle, bool correct_gamma);
             }
         }
     }
@@ -117,8 +124,14 @@ namespace cv
 
 using namespace ::cv::ocl::device;
 
-cv::ocl::HOGDescriptor::HOGDescriptor(Size win_size_, Size block_size_, Size block_stride_, Size cell_size_,
-                                      int nbins_, double win_sigma_, double threshold_L2hys_, bool gamma_correction_, int nlevels_)
+static inline int divUp(int total, int grain)
+{
+    return (total + grain - 1) / grain;
+}
+
+cv::ocl::HOGDescriptor::HOGDescriptor(Size win_size_, Size block_size_, Size block_stride_, 
+                                      Size cell_size_, int nbins_, double win_sigma_, 
+                                      double threshold_L2hys_, bool gamma_correction_, int nlevels_)
     : win_size(win_size_),
       block_size(block_size_),
       block_stride(block_stride_),
@@ -132,19 +145,27 @@ cv::ocl::HOGDescriptor::HOGDescriptor(Size win_size_, Size block_size_, Size blo
     CV_Assert((win_size.width  - block_size.width ) % block_stride.width  == 0 &&
               (win_size.height - block_size.height) % block_stride.height == 0);
 
-    CV_Assert(block_size.width % cell_size.width == 0 && block_size.height % cell_size.height == 0);
+    CV_Assert(block_size.width % cell_size.width == 0 && 
+        block_size.height % cell_size.height == 0);
 
     CV_Assert(block_stride == cell_size);
 
     CV_Assert(cell_size == Size(8, 8));
 
-    Size cells_per_block = Size(block_size.width / cell_size.width, block_size.height / cell_size.height);
+    Size cells_per_block(block_size.width / cell_size.width, 
+        block_size.height / cell_size.height);
     CV_Assert(cells_per_block == Size(2, 2));
 
     cv::Size blocks_per_win = numPartsWithin(win_size, block_size, block_stride);
-    hog::set_up_constants(nbins, block_stride.width, block_stride.height, blocks_per_win.width, blocks_per_win.height);
+    hog::set_up_constants(nbins, block_stride.width, block_stride.height, 
+        blocks_per_win.width, blocks_per_win.height);
 
     effect_size = Size(0, 0);
+
+    if (queryDeviceInfo<IS_CPU_DEVICE, bool>())
+        hog_device_cpu = true;
+    else
+        hog_device_cpu = false;
 }
 
 size_t cv::ocl::HOGDescriptor::getDescriptorSize() const
@@ -154,7 +175,8 @@ size_t cv::ocl::HOGDescriptor::getDescriptorSize() const
 
 size_t cv::ocl::HOGDescriptor::getBlockHistogramSize() const
 {
-    Size cells_per_block = Size(block_size.width / cell_size.width, block_size.height / cell_size.height);
+    Size cells_per_block = Size(block_size.width / cell_size.width, 
+        block_size.height / cell_size.height);
     return (size_t)(nbins * cells_per_block.area());
 }
 
@@ -167,7 +189,8 @@ bool cv::ocl::HOGDescriptor::checkDetectorSize() const
 {
     size_t detector_size = detector.rows * detector.cols;
     size_t descriptor_size = getDescriptorSize();
-    return detector_size == 0 || detector_size == descriptor_size || detector_size == descriptor_size + 1;
+    return detector_size == 0 || detector_size == descriptor_size || 
+        detector_size == descriptor_size + 1;
 }
 
 void cv::ocl::HOGDescriptor::setSVMDetector(const vector<float> &_detector)
@@ -207,10 +230,24 @@ void cv::ocl::HOGDescriptor::init_buffer(const oclMat &img, Size win_stride)
 
     const size_t block_hist_size = getBlockHistogramSize();
     const Size blocks_per_img = numPartsWithin(img.size(), block_size, block_stride);
-    block_hists.create(1, static_cast<int>(block_hist_size * blocks_per_img.area()), CV_32F);
+    block_hists.create(1, 
+        static_cast<int>(block_hist_size * blocks_per_img.area()) + 256, CV_32F);
 
     Size wins_per_img = numPartsWithin(img.size(), win_size, win_stride);
     labels.create(1, wins_per_img.area(), CV_8U);
+
+    float sigma = getWinSigma();
+    float scale = 1.f / (2.f * sigma * sigma);
+    Mat gaussian_lut(1, 512, CV_32FC1);
+    int idx = 0;
+    for(int i=-8; i<8; i++)
+        for(int j=-8; j<8; j++)
+            gaussian_lut.at<float>(idx++) = std::exp(-(j * j + i * i) * scale);
+    for(int i=-8; i<8; i++)
+        for(int j=-8; j<8; j++)
+            gaussian_lut.at<float>(idx++) = (8.f - fabs(j + 0.5f)) * (8.f - fabs(i + 0.5f)) / 64.f;
+
+    gauss_w_lut.upload(gaussian_lut);
 }
 
 void cv::ocl::HOGDescriptor::computeGradient(const oclMat &img, oclMat &grad, oclMat &qangle)
@@ -221,29 +258,34 @@ void cv::ocl::HOGDescriptor::computeGradient(const oclMat &img, oclMat &grad, oc
     switch (img.type())
     {
     case CV_8UC1:
-        hog::compute_gradients_8UC1(effect_size.height, effect_size.width, img, angleScale, grad, qangle, gamma_correction);
+        hog::compute_gradients_8UC1(effect_size.height, effect_size.width, img, 
+            angleScale, grad, qangle, gamma_correction);
         break;
     case CV_8UC4:
-        hog::compute_gradients_8UC4(effect_size.height, effect_size.width, img, angleScale, grad, qangle, gamma_correction);
+        hog::compute_gradients_8UC4(effect_size.height, effect_size.width, img, 
+            angleScale, grad, qangle, gamma_correction);
         break;
     }
 }
 
+
 void cv::ocl::HOGDescriptor::computeBlockHistograms(const oclMat &img)
 {
-    computeGradient(img, grad, qangle);
+    computeGradient(img, this->grad, this->qangle);
 
-    hog::compute_hists(nbins, block_stride.width, block_stride.height, effect_size.height, effect_size.width,
-                       grad, qangle, (float)getWinSigma(), block_hists);
+    hog::compute_hists(nbins, block_stride.width, block_stride.height, effect_size.height, 
+        effect_size.width, grad, qangle, gauss_w_lut, block_hists);
 
-    hog::normalize_hists(nbins, block_stride.width, block_stride.height, effect_size.height, effect_size.width,
-                         block_hists, (float)threshold_L2hys);
+    hog::normalize_hists(nbins, block_stride.width, block_stride.height, effect_size.height, 
+        effect_size.width, block_hists, (float)threshold_L2hys);
 }
 
 
-void cv::ocl::HOGDescriptor::getDescriptors(const oclMat &img, Size win_stride, oclMat &descriptors, int descr_format)
+void cv::ocl::HOGDescriptor::getDescriptors(const oclMat &img, Size win_stride, 
+                                            oclMat &descriptors, int descr_format)
 {
-    CV_Assert(win_stride.width % block_stride.width == 0 && win_stride.height % block_stride.height == 0);
+    CV_Assert(win_stride.width % block_stride.width == 0 && 
+        win_stride.height % block_stride.height == 0);
 
     init_buffer(img, win_stride);
 
@@ -253,17 +295,20 @@ void cv::ocl::HOGDescriptor::getDescriptors(const oclMat &img, Size win_stride,
     Size blocks_per_win = numPartsWithin(win_size, block_size, block_stride);
     Size wins_per_img   = numPartsWithin(effect_size, win_size, win_stride);
 
-    descriptors.create(wins_per_img.area(), static_cast<int>(blocks_per_win.area() * block_hist_size), CV_32F);
+    descriptors.create(wins_per_img.area(), 
+        static_cast<int>(blocks_per_win.area() * block_hist_size), CV_32F);
 
     switch (descr_format)
     {
     case DESCR_FORMAT_ROW_BY_ROW:
-        hog::extract_descrs_by_rows(win_size.height, win_size.width, block_stride.height, block_stride.width,
-                                    win_stride.height, win_stride.width, effect_size.height, effect_size.width, block_hists, descriptors);
+        hog::extract_descrs_by_rows(win_size.height, win_size.width, 
+            block_stride.height, block_stride.width, win_stride.height, win_stride.width, 
+            effect_size.height, effect_size.width, block_hists, descriptors);
         break;
     case DESCR_FORMAT_COL_BY_COL:
-        hog::extract_descrs_by_cols(win_size.height, win_size.width, block_stride.height, block_stride.width,
-                                    win_stride.height, win_stride.width, effect_size.height, effect_size.width, block_hists, descriptors);
+        hog::extract_descrs_by_cols(win_size.height, win_size.width, 
+            block_stride.height, block_stride.width, win_stride.height, win_stride.width, 
+            effect_size.height, effect_size.width, block_hists, descriptors);
         break;
     default:
         CV_Error(CV_StsBadArg, "Unknown descriptor format");
@@ -271,7 +316,8 @@ void cv::ocl::HOGDescriptor::getDescriptors(const oclMat &img, Size win_stride,
 }
 
 
-void cv::ocl::HOGDescriptor::detect(const oclMat &img, vector<Point> &hits, double hit_threshold, Size win_stride, Size padding)
+void cv::ocl::HOGDescriptor::detect(const oclMat &img, vector<Point> &hits, 
+                                    double hit_threshold, Size win_stride, Size padding)
 {
     CV_Assert(img.type() == CV_8UC1 || img.type() == CV_8UC4);
     CV_Assert(padding == Size(0, 0));
@@ -283,14 +329,16 @@ void cv::ocl::HOGDescriptor::detect(const oclMat &img, vector<Point> &hits, doub
     if (win_stride == Size())
         win_stride = block_stride;
     else
-        CV_Assert(win_stride.width % block_stride.width == 0 && win_stride.height % block_stride.height == 0);
+        CV_Assert(win_stride.width % block_stride.width == 0 && 
+            win_stride.height % block_stride.height == 0);
     init_buffer(img, win_stride);
 
     computeBlockHistograms(img);
 
-    hog::classify_hists(win_size.height, win_size.width, block_stride.height, block_stride.width,
-                        win_stride.height, win_stride.width, effect_size.height, effect_size.width, block_hists,
-                        detector, (float)free_coef, (float)hit_threshold, labels);
+    hog::classify_hists(win_size.height, win_size.width, block_stride.height, 
+        block_stride.width, win_stride.height, win_stride.width, 
+        effect_size.height, effect_size.width, block_hists, detector, 
+        (float)free_coef, (float)hit_threshold, labels);
 
     labels.download(labels_host);
     unsigned char *vec = labels_host.ptr();
@@ -306,8 +354,9 @@ void cv::ocl::HOGDescriptor::detect(const oclMat &img, vector<Point> &hits, doub
 
 
 
-void cv::ocl::HOGDescriptor::detectMultiScale(const oclMat &img, vector<Rect> &found_locations, double hit_threshold,
-        Size win_stride, Size padding, double scale0, int group_threshold)
+void cv::ocl::HOGDescriptor::detectMultiScale(const oclMat &img, vector<Rect> &found_locations, 
+                                              double hit_threshold, Size win_stride, Size padding, 
+                                              double scale0, int group_threshold)
 {
     CV_Assert(img.type() == CV_8UC1 || img.type() == CV_8UC4);
     CV_Assert(scale0 > 1);
@@ -333,7 +382,8 @@ void cv::ocl::HOGDescriptor::detectMultiScale(const oclMat &img, vector<Rect> &f
     if (win_stride == Size())
         win_stride = block_stride;
     else
-        CV_Assert(win_stride.width % block_stride.width == 0 && win_stride.height % block_stride.height == 0);
+        CV_Assert(win_stride.width % block_stride.width == 0 && 
+            win_stride.height % block_stride.height == 0);
     init_buffer(img, win_stride);
     image_scale.create(img.size(), img.type());
 
@@ -347,16 +397,18 @@ void cv::ocl::HOGDescriptor::detectMultiScale(const oclMat &img, vector<Rect> &f
         }
         else
         {
-            hog::resize( img, image_scale, effect_size);
+            resize(img, image_scale, effect_size);
             detect(image_scale, locations, hit_threshold, win_stride, padding);
         }
-        Size scaled_win_size(cvRound(win_size.width * scale), cvRound(win_size.height * scale));
+        Size scaled_win_size(cvRound(win_size.width * scale), 
+            cvRound(win_size.height * scale));
         for (size_t j = 0; j < locations.size(); j++)
-            all_candidates.push_back(Rect(Point2d((CvPoint)locations[j]) * scale, scaled_win_size));
+            all_candidates.push_back(Rect(Point2d((CvPoint)locations[j]) * scale, 
+              scaled_win_size));
     }
 
     found_locations.assign(all_candidates.begin(), all_candidates.end());
-    groupRectangles(found_locations, group_threshold, 0.2/*magic number copied from CPU version*/);
+    groupRectangles(found_locations, group_threshold, 0.2);
 }
 
 int cv::ocl::HOGDescriptor::numPartsWithin(int size, int part_size, int stride)
@@ -364,9 +416,11 @@ int cv::ocl::HOGDescriptor::numPartsWithin(int size, int part_size, int stride)
     return (size - part_size + stride) / stride;
 }
 
-cv::Size cv::ocl::HOGDescriptor::numPartsWithin(cv::Size size, cv::Size part_size, cv::Size stride)
+cv::Size cv::ocl::HOGDescriptor::numPartsWithin(cv::Size size, cv::Size part_size, 
+                                                cv::Size stride)
 {
-    return Size(numPartsWithin(size.width, part_size.width, stride.width), numPartsWithin(size.height, part_size.height, stride.height));
+    return Size(numPartsWithin(size.width, part_size.width, stride.width), 
+        numPartsWithin(size.height, part_size.height, stride.height));
 }
 
 std::vector<float> cv::ocl::HOGDescriptor::getDefaultPeopleDetector()
@@ -1547,8 +1601,9 @@ static int power_2up(unsigned int n)
     return -1; // Input is too big
 }
 
-void cv::ocl::device::hog::set_up_constants(int nbins, int block_stride_x, int block_stride_y,
-        int nblocks_win_x, int nblocks_win_y)
+void cv::ocl::device::hog::set_up_constants(int nbins, 
+                                            int block_stride_x, int block_stride_y, 
+                                            int nblocks_win_x, int nblocks_win_y)
 {
     cnbins = nbins;
     cblock_stride_x = block_stride_x;
@@ -1559,59 +1614,39 @@ void cv::ocl::device::hog::set_up_constants(int nbins, int block_stride_x, int b
     int block_hist_size = nbins * CELLS_PER_BLOCK_X * CELLS_PER_BLOCK_Y;
     cblock_hist_size = block_hist_size;
 
-    int block_hist_size_2up = power_2up(block_hist_size);
-    cblock_hist_size_2up = block_hist_size_2up;
-
     int descr_width = nblocks_win_x * block_hist_size;
     cdescr_width = descr_width;
+    cdescr_height = nblocks_win_y;
 
     int descr_size = descr_width * nblocks_win_y;
     cdescr_size = descr_size;
 }
 
-static inline int divUp(int total, int grain)
-{
-    return (total + grain - 1) / grain;
-}
-
-static void openCLExecuteKernel_hog(Context *clCxt , const char **source, string kernelName, 
-                                    size_t globalThreads[3], size_t localThreads[3], 
-                                    vector< pair<size_t, const void *> > &args)
-{
-    cl_kernel kernel = openCLGetKernelFromSource(clCxt, source, kernelName);
-    size_t wave_size = queryDeviceInfo<WAVEFRONT_SIZE, size_t>(kernel);
-    openCLSafeCall(clReleaseKernel(kernel));
-    if (wave_size <= 16)
-    {
-        char build_options[64];
-        sprintf(build_options, (wave_size == 16) ? "-D WAVE_SIZE_16" : "-D WAVE_SIZE_1");
-        openCLExecuteKernel(clCxt, source, kernelName, globalThreads, localThreads, args, -1, -1, build_options);
-    }
-    else
-        openCLExecuteKernel(clCxt, source, kernelName, globalThreads, localThreads, args, -1, -1);
-}
-
-void cv::ocl::device::hog::compute_hists(int nbins, int block_stride_x, int block_stride_y,
-        int height, int width, const cv::ocl::oclMat &grad,
-        const cv::ocl::oclMat &qangle, float sigma, cv::ocl::oclMat &block_hists)
+void cv::ocl::device::hog::compute_hists(int nbins, 
+                                         int block_stride_x, int block_stride_y,
+                                         int height, int width, 
+                                         const cv::ocl::oclMat &grad, 
+                                         const cv::ocl::oclMat &qangle, 
+                                         const cv::ocl::oclMat &gauss_w_lut, 
+                                         cv::ocl::oclMat &block_hists)
 {
     Context *clCxt = Context::getContext();
-    string kernelName = "compute_hists_kernel";
     vector< pair<size_t, const void *> > args;
+    string kernelName = "compute_hists_lut_kernel";
 
-    int img_block_width = (width - CELLS_PER_BLOCK_X * CELL_WIDTH + block_stride_x) / block_stride_x;
-    int img_block_height = (height - CELLS_PER_BLOCK_Y * CELL_HEIGHT + block_stride_y) / block_stride_y;
-
+    int img_block_width = (width - CELLS_PER_BLOCK_X * CELL_WIDTH + block_stride_x) 
+        / block_stride_x;
+    int img_block_height = (height - CELLS_PER_BLOCK_Y * CELL_HEIGHT + block_stride_y) 
+        / block_stride_y;
     int blocks_total = img_block_width * img_block_height;
-    int blocks_in_group = 4;
-    size_t localThreads[3] = { blocks_in_group * 24, 2, 1 };
-    size_t globalThreads[3] = { divUp(blocks_total, blocks_in_group) * localThreads[0], 2, 1 };
 
     int grad_quadstep = grad.step >> 2;
     int qangle_step = qangle.step;
 
-    // Precompute gaussian spatial window parameter
-    float scale = 1.f / (2.f * sigma * sigma);
+    int blocks_in_group = 4;
+    size_t localThreads[3] = { blocks_in_group * 24, 2, 1 };
+    size_t globalThreads[3] = { 
+        divUp(img_block_width * img_block_height, blocks_in_group) * localThreads[0], 2, 1 };
 
     int hists_size = (nbins * CELLS_PER_BLOCK_X * CELLS_PER_BLOCK_Y * 12) * sizeof(float);
     int final_hists_size = (nbins * CELLS_PER_BLOCK_X * CELLS_PER_BLOCK_Y) * sizeof(float);
@@ -1628,62 +1663,134 @@ void cv::ocl::device::hog::compute_hists(int nbins, int block_stride_x, int bloc
     args.push_back( make_pair( sizeof(cl_int), (void *)&qangle_step));
     args.push_back( make_pair( sizeof(cl_mem), (void *)&grad.data));
     args.push_back( make_pair( sizeof(cl_mem), (void *)&qangle.data));
-    args.push_back( make_pair( sizeof(cl_float), (void *)&scale));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&gauss_w_lut.data));
     args.push_back( make_pair( sizeof(cl_mem), (void *)&block_hists.data));
     args.push_back( make_pair( smem, (void *)NULL));
 
-    openCLExecuteKernel_hog(clCxt, &objdetect_hog, kernelName, globalThreads, localThreads, args);
+    if(hog_device_cpu)
+    {
+        openCLExecuteKernel(clCxt, &objdetect_hog, kernelName, globalThreads, 
+            localThreads, args, -1, -1, "-D CPU");
+    }else
+    {
+        cl_kernel kernel = openCLGetKernelFromSource(clCxt, &objdetect_hog, kernelName);
+        int wave_size = queryDeviceInfo<WAVEFRONT_SIZE, int>(kernel);
+        char opt[32] = {0};
+        sprintf(opt, "-D WAVE_SIZE=%d", wave_size);
+        openCLExecuteKernel(clCxt, &objdetect_hog, kernelName, globalThreads, 
+            localThreads, args, -1, -1, opt);
+    }
 }
 
-void cv::ocl::device::hog::normalize_hists(int nbins, int block_stride_x, int block_stride_y,
-        int height, int width, cv::ocl::oclMat &block_hists, float threshold)
+void cv::ocl::device::hog::normalize_hists(int nbins, 
+                                           int block_stride_x, int block_stride_y,
+                                           int height, int width, 
+                                           cv::ocl::oclMat &block_hists, 
+                                           float threshold)
 {
     Context *clCxt = Context::getContext();
-    string kernelName = "normalize_hists_kernel";
     vector< pair<size_t, const void *> > args;
+    string kernelName;
 
     int block_hist_size = nbins * CELLS_PER_BLOCK_X * CELLS_PER_BLOCK_Y;
-    int nthreads = power_2up(block_hist_size);
-
-    int img_block_width = (width - CELLS_PER_BLOCK_X * CELL_WIDTH + block_stride_x) / block_stride_x;
-    int img_block_height = (height - CELLS_PER_BLOCK_Y * CELL_HEIGHT + block_stride_y) / block_stride_y;
-    size_t globalThreads[3] = { img_block_width * nthreads, img_block_height, 1 };
-    size_t localThreads[3] = { nthreads, 1, 1  };
-
-    if ((nthreads < 32) || (nthreads > 512) )
-        cv::ocl::error("normalize_hists: histogram's size is too small or too big", __FILE__, __LINE__, "normalize_hists");
+    int img_block_width = (width - CELLS_PER_BLOCK_X * CELL_WIDTH + block_stride_x) 
+        / block_stride_x;
+    int img_block_height = (height - CELLS_PER_BLOCK_Y * CELL_HEIGHT + block_stride_y) 
+        / block_stride_y;
+    int nthreads;
+    size_t globalThreads[3] = { 1, 1, 1  };
+    size_t localThreads[3] = { 1, 1, 1  };
+    
+    if ( nbins == 9 )
+    {
+        /* optimized for the case of 9 bins */
+        kernelName = "normalize_hists_36_kernel";
+        int blocks_in_group = NTHREADS / block_hist_size;
+        nthreads = blocks_in_group * block_hist_size;
+        int num_groups = divUp( img_block_width * img_block_height, blocks_in_group);
+        globalThreads[0] = nthreads * num_groups;
+        localThreads[0] = nthreads;
+    }
+    else
+    {
+        kernelName = "normalize_hists_kernel";
+        nthreads = power_2up(block_hist_size);
+        globalThreads[0] = img_block_width * nthreads;
+        globalThreads[1] = img_block_height;
+        localThreads[0] = nthreads;
+
+        if ((nthreads < 32) || (nthreads > 512) )
+            cv::ocl::error("normalize_hists: histogram's size is too small or too big", 
+                __FILE__, __LINE__, "normalize_hists");
+
+        args.push_back( make_pair( sizeof(cl_int), (void *)&nthreads));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&block_hist_size));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&img_block_width));
+    }
 
-    args.push_back( make_pair( sizeof(cl_int), (void *)&nthreads));
-    args.push_back( make_pair( sizeof(cl_int), (void *)&block_hist_size));
-    args.push_back( make_pair( sizeof(cl_int), (void *)&img_block_width));
     args.push_back( make_pair( sizeof(cl_mem), (void *)&block_hists.data));
     args.push_back( make_pair( sizeof(cl_float), (void *)&threshold));
     args.push_back( make_pair( nthreads * sizeof(float), (void *)NULL));
 
-    openCLExecuteKernel_hog(clCxt, &objdetect_hog, kernelName, globalThreads, localThreads, args);
+    if(hog_device_cpu)
+        openCLExecuteKernel(clCxt, &objdetect_hog, kernelName, globalThreads, 
+                             localThreads, args, -1, -1, "-D CPU");
+    else
+    {
+        cl_kernel kernel = openCLGetKernelFromSource(clCxt, &objdetect_hog, kernelName);
+        int wave_size = queryDeviceInfo<WAVEFRONT_SIZE, int>(kernel);
+        char opt[32] = {0};
+        sprintf(opt, "-D WAVE_SIZE=%d", wave_size);
+        openCLExecuteKernel(clCxt, &objdetect_hog, kernelName, globalThreads, 
+                             localThreads, args, -1, -1, opt);
+    }
 }
 
-void cv::ocl::device::hog::classify_hists(int win_height, int win_width, int block_stride_y,
-        int block_stride_x, int win_stride_y, int win_stride_x, int height,
-        int width, const cv::ocl::oclMat &block_hists, const cv::ocl::oclMat &coefs, float free_coef,
-        float threshold, cv::ocl::oclMat &labels)
+void cv::ocl::device::hog::classify_hists(int win_height, int win_width, 
+                                          int block_stride_y, int block_stride_x, 
+                                          int win_stride_y, int win_stride_x, 
+                                          int height, int width, 
+                                          const cv::ocl::oclMat &block_hists, 
+                                          const cv::ocl::oclMat &coefs, 
+                                          float free_coef, float threshold, 
+                                          cv::ocl::oclMat &labels)
 {
     Context *clCxt = Context::getContext();
-    string kernelName = "classify_hists_kernel";
     vector< pair<size_t, const void *> > args;
 
+    int nthreads;
+    string kernelName;
+    switch (cdescr_width)
+    {
+    case 180:
+        nthreads = 180;
+        kernelName = "classify_hists_180_kernel";
+        args.push_back( make_pair( sizeof(cl_int), (void *)&cdescr_width));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&cdescr_height));
+        break;
+    case 252:
+        nthreads = 256;
+        kernelName = "classify_hists_252_kernel";
+        args.push_back( make_pair( sizeof(cl_int), (void *)&cdescr_width));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&cdescr_height));
+        break;
+    default:
+        nthreads = 256;
+        kernelName = "classify_hists_kernel";
+        args.push_back( make_pair( sizeof(cl_int), (void *)&cdescr_size));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&cdescr_width));
+    }
+
     int win_block_stride_x = win_stride_x / block_stride_x;
     int win_block_stride_y = win_stride_y / block_stride_y;
     int img_win_width = (width - win_width + win_stride_x) / win_stride_x;
     int img_win_height = (height - win_height + win_stride_y) / win_stride_y;
-    int img_block_width = (width - CELLS_PER_BLOCK_X * CELL_WIDTH + block_stride_x) / block_stride_x;
-
-    size_t globalThreads[3] = { img_win_width * NTHREADS, img_win_height, 1 };
-    size_t localThreads[3] = { NTHREADS, 1, 1 };
+    int img_block_width = (width - CELLS_PER_BLOCK_X * CELL_WIDTH + block_stride_x) / 
+        block_stride_x;
 
+    size_t globalThreads[3] = { img_win_width * nthreads, img_win_height, 1 };
+    size_t localThreads[3] = { nthreads, 1, 1 };
     args.push_back( make_pair( sizeof(cl_int), (void *)&cblock_hist_size));
-    args.push_back( make_pair( sizeof(cl_int), (void *)&cdescr_size));
-    args.push_back( make_pair( sizeof(cl_int), (void *)&cdescr_width));
     args.push_back( make_pair( sizeof(cl_int), (void *)&img_win_width));
     args.push_back( make_pair( sizeof(cl_int), (void *)&img_block_width));
     args.push_back( make_pair( sizeof(cl_int), (void *)&win_block_stride_x));
@@ -1694,12 +1801,26 @@ void cv::ocl::device::hog::classify_hists(int win_height, int win_width, int blo
     args.push_back( make_pair( sizeof(cl_float), (void *)&threshold));
     args.push_back( make_pair( sizeof(cl_mem), (void *)&labels.data));
 
-    openCLExecuteKernel_hog(clCxt, &objdetect_hog, kernelName, globalThreads, localThreads, args);
+    if(hog_device_cpu)
+        openCLExecuteKernel(clCxt, &objdetect_hog, kernelName, globalThreads, 
+                             localThreads, args, -1, -1, "-D CPU");
+    else
+    {
+        cl_kernel kernel = openCLGetKernelFromSource(clCxt, &objdetect_hog, kernelName);
+        int wave_size = queryDeviceInfo<WAVEFRONT_SIZE, int>(kernel);
+        char opt[32] = {0};
+        sprintf(opt, "-D WAVE_SIZE=%d", wave_size);
+        openCLExecuteKernel(clCxt, &objdetect_hog, kernelName, globalThreads, 
+                             localThreads, args, -1, -1, opt);
+    }
 }
 
-void cv::ocl::device::hog::extract_descrs_by_rows(int win_height, int win_width, int block_stride_y, int block_stride_x,
-        int win_stride_y, int win_stride_x, int height, int width,
-        const cv::ocl::oclMat &block_hists, cv::ocl::oclMat &descriptors)
+void cv::ocl::device::hog::extract_descrs_by_rows(int win_height, int win_width, 
+                                                  int block_stride_y, int block_stride_x,
+                                                  int win_stride_y, int win_stride_x, 
+                                                  int height, int width,
+                                                  const cv::ocl::oclMat &block_hists, 
+                                                  cv::ocl::oclMat &descriptors)
 {
     Context *clCxt = Context::getContext();
     string kernelName = "extract_descrs_by_rows_kernel";
@@ -1709,7 +1830,8 @@ void cv::ocl::device::hog::extract_descrs_by_rows(int win_height, int win_width,
     int win_block_stride_y = win_stride_y / block_stride_y;
     int img_win_width = (width - win_width + win_stride_x) / win_stride_x;
     int img_win_height = (height - win_height + win_stride_y) / win_stride_y;
-    int img_block_width = (width - CELLS_PER_BLOCK_X * CELL_WIDTH + block_stride_x) / block_stride_x;
+    int img_block_width = (width - CELLS_PER_BLOCK_X * CELL_WIDTH + block_stride_x) / 
+        block_stride_x;
     int descriptors_quadstep = descriptors.step >> 2;
 
     size_t globalThreads[3] = { img_win_width * NTHREADS, img_win_height, 1 };
@@ -1725,12 +1847,16 @@ void cv::ocl::device::hog::extract_descrs_by_rows(int win_height, int win_width,
     args.push_back( make_pair( sizeof(cl_mem), (void *)&block_hists.data));
     args.push_back( make_pair( sizeof(cl_mem), (void *)&descriptors.data));
 
-    openCLExecuteKernel(clCxt, &objdetect_hog, kernelName, globalThreads, localThreads, args, -1, -1);
+    openCLExecuteKernel(clCxt, &objdetect_hog, kernelName, globalThreads, 
+        localThreads, args, -1, -1);
 }
 
-void cv::ocl::device::hog::extract_descrs_by_cols(int win_height, int win_width, int block_stride_y, int block_stride_x,
-        int win_stride_y, int win_stride_x, int height, int width,
-        const cv::ocl::oclMat &block_hists, cv::ocl::oclMat &descriptors)
+void cv::ocl::device::hog::extract_descrs_by_cols(int win_height, int win_width, 
+                                                  int block_stride_y, int block_stride_x,
+                                                  int win_stride_y, int win_stride_x, 
+                                                  int height, int width,
+                                                  const cv::ocl::oclMat &block_hists, 
+                                                  cv::ocl::oclMat &descriptors)
 {
     Context *clCxt = Context::getContext();
     string kernelName = "extract_descrs_by_cols_kernel";
@@ -1740,7 +1866,8 @@ void cv::ocl::device::hog::extract_descrs_by_cols(int win_height, int win_width,
     int win_block_stride_y = win_stride_y / block_stride_y;
     int img_win_width = (width - win_width + win_stride_x) / win_stride_x;
     int img_win_height = (height - win_height + win_stride_y) / win_stride_y;
-    int img_block_width = (width - CELLS_PER_BLOCK_X * CELL_WIDTH + block_stride_x) / block_stride_x;
+    int img_block_width = (width - CELLS_PER_BLOCK_X * CELL_WIDTH + block_stride_x) / 
+        block_stride_x;
     int descriptors_quadstep = descriptors.step >> 2;
 
     size_t globalThreads[3] = { img_win_width * NTHREADS, img_win_height, 1 };
@@ -1757,11 +1884,16 @@ void cv::ocl::device::hog::extract_descrs_by_cols(int win_height, int win_width,
     args.push_back( make_pair( sizeof(cl_mem), (void *)&block_hists.data));
     args.push_back( make_pair( sizeof(cl_mem), (void *)&descriptors.data));
 
-    openCLExecuteKernel(clCxt, &objdetect_hog, kernelName, globalThreads, localThreads, args, -1, -1);
+    openCLExecuteKernel(clCxt, &objdetect_hog, kernelName, globalThreads, 
+        localThreads, args, -1, -1);
 }
 
-void cv::ocl::device::hog::compute_gradients_8UC1(int height, int width, const cv::ocl::oclMat &img,
-        float angle_scale, cv::ocl::oclMat &grad, cv::ocl::oclMat &qangle, bool correct_gamma)
+void cv::ocl::device::hog::compute_gradients_8UC1(int height, int width, 
+                                                  const cv::ocl::oclMat &img,
+                                                  float angle_scale, 
+                                                  cv::ocl::oclMat &grad, 
+                                                  cv::ocl::oclMat &qangle, 
+                                                  bool correct_gamma)
 {
     Context *clCxt = Context::getContext();
     string kernelName = "compute_gradients_8UC1_kernel";
@@ -1786,11 +1918,16 @@ void cv::ocl::device::hog::compute_gradients_8UC1(int height, int width, const c
     args.push_back( make_pair( sizeof(cl_char), (void *)&correctGamma));
     args.push_back( make_pair( sizeof(cl_int), (void *)&cnbins));
 
-    openCLExecuteKernel(clCxt, &objdetect_hog, kernelName, globalThreads, localThreads, args, -1, -1);
+    openCLExecuteKernel(clCxt, &objdetect_hog, kernelName, globalThreads, 
+        localThreads, args, -1, -1);
 }
 
-void cv::ocl::device::hog::compute_gradients_8UC4(int height, int width, const cv::ocl::oclMat &img,
-        float angle_scale, cv::ocl::oclMat &grad, cv::ocl::oclMat &qangle, bool correct_gamma)
+void cv::ocl::device::hog::compute_gradients_8UC4(int height, int width, 
+                                                  const cv::ocl::oclMat &img,
+                                                  float angle_scale, 
+                                                  cv::ocl::oclMat &grad, 
+                                                  cv::ocl::oclMat &qangle, 
+                                                  bool correct_gamma)
 {
     Context *clCxt = Context::getContext();
     string kernelName = "compute_gradients_8UC4_kernel";
@@ -1816,39 +1953,6 @@ void cv::ocl::device::hog::compute_gradients_8UC4(int height, int width, const c
     args.push_back( make_pair( sizeof(cl_char), (void *)&correctGamma));
     args.push_back( make_pair( sizeof(cl_int), (void *)&cnbins));
 
-    openCLExecuteKernel(clCxt, &objdetect_hog, kernelName, globalThreads, localThreads, args, -1, -1);
-}
-
-void cv::ocl::device::hog::resize( const oclMat &src, oclMat &dst, const Size sz)
-{
-    CV_Assert( (src.channels() == dst.channels()) );
-    Context *clCxt = Context::getContext();
-
-    string kernelName = (src.type() == CV_8UC1) ? "resize_8UC1_kernel" : "resize_8UC4_kernel";
-    size_t blkSizeX = 16, blkSizeY = 16;
-    size_t glbSizeX = sz.width % blkSizeX == 0 ? sz.width : (sz.width / blkSizeX + 1) * blkSizeX;
-    size_t glbSizeY = sz.height % blkSizeY == 0 ? sz.height : (sz.height / blkSizeY + 1) * blkSizeY;
-    size_t globalThreads[3] = {glbSizeX, glbSizeY, 1};
-    size_t localThreads[3] = {blkSizeX, blkSizeY, 1};
-
-    float ifx = (float)src.cols / sz.width;
-    float ify = (float)src.rows / sz.height;
-    int src_step = static_cast<int>(src.step);
-    int dst_step = static_cast<int>(dst.step);
-
-    vector< pair<size_t, const void *> > args;
-    args.push_back( make_pair(sizeof(cl_mem), (void *)&dst.data));
-    args.push_back( make_pair(sizeof(cl_mem), (void *)&src.data));
-    args.push_back( make_pair(sizeof(cl_int), (void *)&dst.offset));
-    args.push_back( make_pair(sizeof(cl_int), (void *)&src.offset));
-    args.push_back( make_pair(sizeof(cl_int), (void *)&dst_step));
-    args.push_back( make_pair(sizeof(cl_int), (void *)&src_step));
-    args.push_back( make_pair(sizeof(cl_int), (void *)&src.cols));
-    args.push_back( make_pair(sizeof(cl_int), (void *)&src.rows));
-    args.push_back( make_pair(sizeof(cl_int), (void *)&sz.width));
-    args.push_back( make_pair(sizeof(cl_int), (void *)&sz.height));
-    args.push_back( make_pair(sizeof(cl_float), (void *)&ifx));
-    args.push_back( make_pair(sizeof(cl_float), (void *)&ify));
-
-    openCLExecuteKernel(clCxt, &objdetect_hog, kernelName, globalThreads, localThreads, args, -1, -1);
-}
+    openCLExecuteKernel(clCxt, &objdetect_hog, kernelName, globalThreads, 
+        localThreads, args, -1, -1);
+}
\ No newline at end of file
index 3dbd68d..15c1539 100644 (file)
@@ -1591,14 +1591,14 @@ namespace cv
 
         namespace
         {
-            class CLAHE_Impl : public cv::ocl::CLAHE
+            class CLAHE_Impl : public cv::CLAHE
             {
             public:
                 CLAHE_Impl(double clipLimit = 40.0, int tilesX = 8, int tilesY = 8);
 
                 cv::AlgorithmInfo* info() const;
 
-                void apply(const oclMat &src, oclMat &dst);
+                void apply(cv::InputArray src, cv::OutputArray dst);
 
                 void setClipLimit(double clipLimit);
                 double getClipLimit() const;
@@ -1616,14 +1616,19 @@ namespace cv
                 oclMat srcExt_;
                 oclMat lut_;
             };
-
             CLAHE_Impl::CLAHE_Impl(double clipLimit, int tilesX, int tilesY) :
             clipLimit_(clipLimit), tilesX_(tilesX), tilesY_(tilesY)
             {
             }
 
-            void CLAHE_Impl::apply(const oclMat &src, oclMat &dst)
+            CV_INIT_ALGORITHM(CLAHE_Impl, "CLAHE_OCL",
+                obj.info()->addParam(obj, "clipLimit", obj.clipLimit_);
+                obj.info()->addParam(obj, "tilesX", obj.tilesX_);
+                obj.info()->addParam(obj, "tilesY", obj.tilesY_))
+            void CLAHE_Impl::apply(cv::InputArray src_raw, cv::OutputArray dst_raw)
             {
+                oclMat& src = getOclMatRef(src_raw);
+                oclMat& dst = getOclMatRef(dst_raw);
                 CV_Assert( src.type() == CV_8UC1 );
 
                 dst.create( src.size(), src.type() );
@@ -1691,7 +1696,7 @@ namespace cv
             }
         }
 
-        cv::Ptr<cv::ocl::CLAHE> createCLAHE(double clipLimit, cv::Size tileGridSize)
+        cv::Ptr<cv::CLAHE> createCLAHE(double clipLimit, cv::Size tileGridSize)
         {
             return new CLAHE_Impl(clipLimit, tileGridSize.width, tileGridSize.height);
         }
index d4841fc..5d81517 100644 (file)
@@ -123,9 +123,6 @@ namespace cv
             codeCache.clear();
             cacheSize = 0;
         }
-
-        // not to be exported to dynamic lib
-        void setBinaryDiskCacheImpl(int mode, String path, Info::Impl * impl);
         struct Info::Impl
         {
             cl_platform_id oclplatform;
@@ -143,9 +140,6 @@ namespace cv
             char extra_options[512];
             int  double_support;
             int unified_memory; //1 means integrated GPU, otherwise this value is 0
-            bool enable_disk_cache; 
-            bool update_disk_cache;
-            string binpath;
             int refcounter;
 
             Impl();
@@ -173,6 +167,16 @@ namespace cv
             void releaseResources();
         };
 
+        // global variables to hold binary cache properties
+        static int enable_disk_cache = 
+#ifdef _DEBUG
+            false;
+#else
+            true;
+#endif
+        static int update_disk_cache = false;
+        static String binpath = "";
+
         Info::Impl::Impl()
             :oclplatform(0),
             oclcontext(0),
@@ -183,13 +187,9 @@ namespace cv
             maxComputeUnits(0),
             double_support(0),
             unified_memory(0),
-            enable_disk_cache(false),
-            update_disk_cache(false),
-            binpath("./"),
             refcounter(1)
         {
             memset(extra_options, 0, 512);
-            setBinaryDiskCacheImpl(CACHE_RELEASE, String("./"), this);
         }
 
         void Info::Impl::releaseResources()
@@ -198,7 +198,8 @@ namespace cv
 
             if(clCmdQueue)
             {
-                openCLSafeCall(clReleaseCommandQueue(clCmdQueue));
+                //temporarily disable command queue release as it causes program hang at exit
+                //openCLSafeCall(clReleaseCommandQueue(clCmdQueue));
                 clCmdQueue = 0;
             }
 
@@ -318,7 +319,7 @@ namespace cv
             char clVersion[256];
             for (unsigned i = 0; i < numPlatforms; ++i)
             {
-                cl_uint numsdev;
+                cl_uint numsdev = 0;
                 cl_int status = clGetDeviceIDs(platforms[i], devicetype, 0, NULL, &numsdev);
                 if(status != CL_DEVICE_NOT_FOUND)
                     openCLVerifyCall(status);
@@ -504,29 +505,30 @@ namespace cv
             return openCLGetKernelFromSource(clCxt, source, kernelName, NULL);
         }
 
-        void setBinaryDiskCacheImpl(int mode, String path, Info::Impl * impl)
+        void setBinaryDiskCache(int mode, String path)
         {
-            impl->update_disk_cache = (mode & CACHE_UPDATE) == CACHE_UPDATE;
-            impl->enable_disk_cache = 
+            if(mode == CACHE_NONE)
+            {
+                update_disk_cache = 0;
+                enable_disk_cache = 0;
+                return;
+            }
+            update_disk_cache |= (mode & CACHE_UPDATE) == CACHE_UPDATE;
+            enable_disk_cache |= 
 #ifdef _DEBUG 
                 (mode & CACHE_DEBUG)   == CACHE_DEBUG;
 #else
                 (mode & CACHE_RELEASE) == CACHE_RELEASE;
 #endif
-            if(impl->enable_disk_cache && !path.empty())
+            if(enable_disk_cache && !path.empty())
             {
-                impl->binpath = path;
+                binpath = path;
             }
         }
-        void setBinaryDiskCache(int mode, cv::String path)
-        {
-            setBinaryDiskCacheImpl(mode, path, Context::getContext()->impl);
-        }
 
         void setBinpath(const char *path)
         {
-            Context *clcxt = Context::getContext();
-            clcxt->impl->binpath = path;
+            binpath = path;
         }
 
         int savetofile(const Context*,  cl_program &program, const char *fileName)
@@ -594,15 +596,15 @@ namespace cv
                     strcat(all_build_options, build_options);
                 if(all_build_options != NULL)
                 {
-                    filename = clCxt->impl->binpath  + kernelName + "_" + clCxt->impl->devName[clCxt->impl->devnum] + all_build_options + ".clb";
+                    filename = binpath + kernelName + "_" + clCxt->impl->devName[clCxt->impl->devnum] + all_build_options + ".clb";
                 }
                 else
                 {
-                    filename = clCxt->impl->binpath  + kernelName + "_" + clCxt->impl->devName[clCxt->impl->devnum] + ".clb";
+                    filename = binpath + kernelName + "_" + clCxt->impl->devName[clCxt->impl->devnum] + ".clb";
                 }
 
-                FILE *fp = clCxt->impl->enable_disk_cache ? fopen(filename.c_str(), "rb") : NULL;
-                if(fp == NULL || clCxt->impl->update_disk_cache)
+                FILE *fp = enable_disk_cache ? fopen(filename.c_str(), "rb") : NULL;
+                if(fp == NULL || update_disk_cache)
                 {
                     if(fp != NULL)
                         fclose(fp);
@@ -611,7 +613,7 @@ namespace cv
                                   clCxt->impl->oclcontext, 1, source, NULL, &status);
                     openCLVerifyCall(status);
                     status = clBuildProgram(program, 1, &(clCxt->impl->devices[clCxt->impl->devnum]), all_build_options, NULL, NULL);
-                    if(status == CL_SUCCESS && clCxt->impl->enable_disk_cache)
+                    if(status == CL_SUCCESS && enable_disk_cache)
                         savetofile(clCxt, program, filename.c_str());
                 }
                 else
@@ -1075,26 +1077,3 @@ namespace cv
     }//namespace ocl
 
 }//namespace cv
-
-#if defined BUILD_SHARED_LIBS && defined CVAPI_EXPORTS && defined WIN32 && !defined WINCE
-#include <windows.h>
-BOOL WINAPI DllMain( HINSTANCE, DWORD  fdwReason, LPVOID );
-
-BOOL WINAPI DllMain( HINSTANCE, DWORD  fdwReason, LPVOID )
-{
-    if( fdwReason == DLL_PROCESS_DETACH )
-    {
-        // application hangs if call clReleaseCommandQueue here, so release context only
-        // without context release application hangs as well
-        context_tear_down = 1;
-        Context* cv_ctx = Context::getContext();
-        if(cv_ctx)
-        {
-            cl_context ctx = cv_ctx->impl->oclcontext;
-            if(ctx)
-                openCLSafeCall(clReleaseContext(ctx));
-        }
-    }
-    return TRUE;
-}
-#endif
diff --git a/modules/ocl/src/kmeans.cpp b/modules/ocl/src/kmeans.cpp
new file mode 100644 (file)
index 0000000..22f8660
--- /dev/null
@@ -0,0 +1,438 @@
+/*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) 2010-2012, Multicoreware, Inc., all rights reserved.
+// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//     Xiaopeng Fu, fuxiaopeng2222@163.com
+//
+// 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 oclMaterials 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 <iomanip>
+#include "precomp.hpp"
+
+using namespace cv;
+using namespace ocl;
+
+namespace cv
+{
+namespace ocl
+{
+////////////////////////////////////OpenCL kernel strings//////////////////////////
+extern const char *kmeans_kernel;
+}
+}
+
+static void generateRandomCenter(const vector<Vec2f>& box, float* center, RNG& rng)
+{
+    size_t j, dims = box.size();
+    float margin = 1.f/dims;
+    for( j = 0; j < dims; j++ )
+        center[j] = ((float)rng*(1.f+margin*2.f)-margin)*(box[j][1] - box[j][0]) + box[j][0];
+}
+
+// This class is copied from matrix.cpp in core module.
+class KMeansPPDistanceComputer : public ParallelLoopBody
+{
+public:
+    KMeansPPDistanceComputer( float *_tdist2,
+                              const float *_data,
+                              const float *_dist,
+                              int _dims,
+                              size_t _step,
+                              size_t _stepci )
+        : tdist2(_tdist2),
+          data(_data),
+          dist(_dist),
+          dims(_dims),
+          step(_step),
+          stepci(_stepci) { }
+
+    void operator()( const cv::Range& range ) const
+    {
+        const int begin = range.start;
+        const int end = range.end;
+
+        for ( int i = begin; i<end; i++ )
+        {
+            tdist2[i] = std::min(normL2Sqr_(data + step*i, data + stepci, dims), dist[i]);
+        }
+    }
+
+private:
+    KMeansPPDistanceComputer& operator=(const KMeansPPDistanceComputer&); // to quiet MSVC
+
+    float *tdist2;
+    const float *data;
+    const float *dist;
+    const int dims;
+    const size_t step;
+    const size_t stepci;
+};
+/*
+k-means center initialization using the following algorithm:
+Arthur & Vassilvitskii (2007) k-means++: The Advantages of Careful Seeding
+*/
+static void generateCentersPP(const Mat& _data, Mat& _out_centers,
+                              int K, RNG& rng, int trials)
+{
+    int i, j, k, dims = _data.cols, N = _data.rows;
+    const float* data = (float*)_data.data;
+    size_t step = _data.step/sizeof(data[0]);
+    vector<int> _centers(K);
+    int* centers = &_centers[0];
+    vector<float> _dist(N*3);
+    float* dist = &_dist[0], *tdist = dist + N, *tdist2 = tdist + N;
+    double sum0 = 0;
+
+    centers[0] = (unsigned)rng % N;
+
+    for( i = 0; i < N; i++ )
+    {
+        dist[i] = normL2Sqr_(data + step*i, data + step*centers[0], dims);
+        sum0 += dist[i];
+    }
+
+    for( k = 1; k < K; k++ )
+    {
+        double bestSum = DBL_MAX;
+        int bestCenter = -1;
+
+        for( j = 0; j < trials; j++ )
+        {
+            double p = (double)rng*sum0, s = 0;
+            for( i = 0; i < N-1; i++ )
+                if( (p -= dist[i]) <= 0 )
+                    break;
+            int ci = i;
+
+            parallel_for_(Range(0, N),
+                          KMeansPPDistanceComputer(tdist2, data, dist, dims, step, step*ci));
+            for( i = 0; i < N; i++ )
+            {
+                s += tdist2[i];
+            }
+
+            if( s < bestSum )
+            {
+                bestSum = s;
+                bestCenter = ci;
+                std::swap(tdist, tdist2);
+            }
+        }
+        centers[k] = bestCenter;
+        sum0 = bestSum;
+        std::swap(dist, tdist);
+    }
+
+    for( k = 0; k < K; k++ )
+    {
+        const float* src = data + step*centers[k];
+        float* dst = _out_centers.ptr<float>(k);
+        for( j = 0; j < dims; j++ )
+            dst[j] = src[j];
+    }
+}
+
+void cv::ocl::distanceToCenters(oclMat &dists, oclMat &labels, const oclMat &src, const oclMat &centers)
+{
+    //if(src.clCxt -> impl -> double_support == 0 && src.type() == CV_64F)
+    //{
+    //    CV_Error(CV_GpuNotSupported, "Selected device don't support double\r\n");
+    //    return;
+    //}
+
+    Context  *clCxt = src.clCxt;
+    int labels_step = (int)(labels.step/labels.elemSize());
+    string kernelname = "distanceToCenters";
+    int threadNum = src.rows > 256 ? 256 : src.rows;
+    size_t localThreads[3]  = {1, threadNum, 1};
+    size_t globalThreads[3] = {1, src.rows, 1};
+
+    vector<pair<size_t, const void *> > args;
+    args.push_back(make_pair(sizeof(cl_int), (void *)&labels_step));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&centers.rows));
+    args.push_back(make_pair(sizeof(cl_mem), (void *)&src.data));
+    args.push_back(make_pair(sizeof(cl_mem), (void *)&labels.data));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&centers.cols));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src.rows));
+    args.push_back(make_pair(sizeof(cl_mem), (void *)&centers.data));
+    args.push_back(make_pair(sizeof(cl_mem), (void*)&dists.data));
+
+    openCLExecuteKernel(clCxt, &kmeans_kernel, kernelname, globalThreads, localThreads, args, -1, -1, NULL);
+}
+///////////////////////////////////k - means /////////////////////////////////////////////////////////
+double cv::ocl::kmeans(const oclMat &_src, int K, oclMat &_bestLabels,
+                       TermCriteria criteria, int attempts, int flags, oclMat &_centers)
+{
+    const int SPP_TRIALS = 3;
+    bool isrow = _src.rows == 1 && _src.oclchannels() > 1;
+    int N = !isrow ? _src.rows : _src.cols;
+    int dims = (!isrow ? _src.cols : 1) * _src.oclchannels();
+    int type = _src.depth();
+
+    attempts = std::max(attempts, 1);
+    CV_Assert(type == CV_32F && K > 0 );
+    CV_Assert( N >= K );
+
+    Mat _labels;
+    if( flags & CV_KMEANS_USE_INITIAL_LABELS )
+    {
+        CV_Assert( (_bestLabels.cols == 1 || _bestLabels.rows == 1) &&
+                   _bestLabels.cols * _bestLabels.rows == N &&
+                   _bestLabels.type() == CV_32S );
+        _bestLabels.download(_labels);
+    }
+    else
+    {
+        if( !((_bestLabels.cols == 1 || _bestLabels.rows == 1) &&
+                _bestLabels.cols * _bestLabels.rows == N &&
+                _bestLabels.type() == CV_32S &&
+                _bestLabels.isContinuous()))
+            _bestLabels.create(N, 1, CV_32S);
+        _labels.create(_bestLabels.size(), _bestLabels.type());
+    }
+    int* labels = _labels.ptr<int>();
+
+    Mat data;
+    _src.download(data);
+    Mat centers(K, dims, type), old_centers(K, dims, type), temp(1, dims, type);
+    vector<int> counters(K);
+    vector<Vec2f> _box(dims);
+    Vec2f* box = &_box[0];
+    double best_compactness = DBL_MAX, compactness = 0;
+    RNG& rng = theRNG();
+    int a, iter, i, j, k;
+
+    if( criteria.type & TermCriteria::EPS )
+        criteria.epsilon = std::max(criteria.epsilon, 0.);
+    else
+        criteria.epsilon = FLT_EPSILON;
+    criteria.epsilon *= criteria.epsilon;
+
+    if( criteria.type & TermCriteria::COUNT )
+        criteria.maxCount = std::min(std::max(criteria.maxCount, 2), 100);
+    else
+        criteria.maxCount = 100;
+
+    if( K == 1 )
+    {
+        attempts = 1;
+        criteria.maxCount = 2;
+    }
+
+    const float* sample = data.ptr<float>();
+    for( j = 0; j < dims; j++ )
+        box[j] = Vec2f(sample[j], sample[j]);
+
+    for( i = 1; i < N; i++ )
+    {
+        sample = data.ptr<float>(i);
+        for( j = 0; j < dims; j++ )
+        {
+            float v = sample[j];
+            box[j][0] = std::min(box[j][0], v);
+            box[j][1] = std::max(box[j][1], v);
+        }
+    }
+
+    for( a = 0; a < attempts; a++ )
+    {
+        double max_center_shift = DBL_MAX;
+        for( iter = 0;; )
+        {
+            swap(centers, old_centers);
+
+            if( iter == 0 && (a > 0 || !(flags & KMEANS_USE_INITIAL_LABELS)) )
+            {
+                if( flags & KMEANS_PP_CENTERS )
+                    generateCentersPP(data, centers, K, rng, SPP_TRIALS);
+                else
+                {
+                    for( k = 0; k < K; k++ )
+                        generateRandomCenter(_box, centers.ptr<float>(k), rng);
+                }
+            }
+            else
+            {
+                if( iter == 0 && a == 0 && (flags & KMEANS_USE_INITIAL_LABELS) )
+                {
+                    for( i = 0; i < N; i++ )
+                        CV_Assert( (unsigned)labels[i] < (unsigned)K );
+                }
+
+                // compute centers
+                centers = Scalar(0);
+                for( k = 0; k < K; k++ )
+                    counters[k] = 0;
+
+                for( i = 0; i < N; i++ )
+                {
+                    sample = data.ptr<float>(i);
+                    k = labels[i];
+                    float* center = centers.ptr<float>(k);
+                    j=0;
+#if CV_ENABLE_UNROLLED
+                    for(; j <= dims - 4; j += 4 )
+                    {
+                        float t0 = center[j] + sample[j];
+                        float t1 = center[j+1] + sample[j+1];
+
+                        center[j] = t0;
+                        center[j+1] = t1;
+
+                        t0 = center[j+2] + sample[j+2];
+                        t1 = center[j+3] + sample[j+3];
+
+                        center[j+2] = t0;
+                        center[j+3] = t1;
+                    }
+#endif
+                    for( ; j < dims; j++ )
+                        center[j] += sample[j];
+                    counters[k]++;
+                }
+
+                if( iter > 0 )
+                    max_center_shift = 0;
+
+                for( k = 0; k < K; k++ )
+                {
+                    if( counters[k] != 0 )
+                        continue;
+
+                    // if some cluster appeared to be empty then:
+                    //   1. find the biggest cluster
+                    //   2. find the farthest from the center point in the biggest cluster
+                    //   3. exclude the farthest point from the biggest cluster and form a new 1-point cluster.
+                    int max_k = 0;
+                    for( int k1 = 1; k1 < K; k1++ )
+                    {
+                        if( counters[max_k] < counters[k1] )
+                            max_k = k1;
+                    }
+
+                    double max_dist = 0;
+                    int farthest_i = -1;
+                    float* new_center =  centers.ptr<float>(k);
+                    float* old_center =  centers.ptr<float>(max_k);
+                    float* _old_center = temp.ptr<float>(); // normalized
+                    float scale = 1.f/counters[max_k];
+                    for( j = 0; j < dims; j++ )
+                        _old_center[j] = old_center[j]*scale;
+
+                    for( i = 0; i < N; i++ )
+                    {
+                        if( labels[i] != max_k )
+                            continue;
+                        sample = data.ptr<float>(i);
+                        double dist = normL2Sqr_(sample, _old_center, dims);
+
+                        if( max_dist <= dist )
+                        {
+                            max_dist = dist;
+                            farthest_i = i;
+                        }
+                    }
+
+                    counters[max_k]--;
+                    counters[k]++;
+                    labels[farthest_i] = k;
+                    sample = data.ptr<float>(farthest_i);
+
+                    for( j = 0; j < dims; j++ )
+                    {
+                        old_center[j] -= sample[j];
+                        new_center[j] += sample[j];
+                    }
+                }
+
+                for( k = 0; k < K; k++ )
+                {
+                    float* center = centers.ptr<float>(k);
+                    CV_Assert( counters[k] != 0 );
+
+                    float scale = 1.f/counters[k];
+                    for( j = 0; j < dims; j++ )
+                        center[j] *= scale;
+
+                    if( iter > 0 )
+                    {
+                        double dist = 0;
+                        const float* old_center = old_centers.ptr<float>(k);
+                        for( j = 0; j < dims; j++ )
+                        {
+                            double t = center[j] - old_center[j];
+                            dist += t*t;
+                        }
+                        max_center_shift = std::max(max_center_shift, dist);
+                    }
+                }
+            }
+
+            if( ++iter == MAX(criteria.maxCount, 2) || max_center_shift <= criteria.epsilon )
+                break;
+
+            // assign labels
+            oclMat _dists(1, N, CV_64F);
+
+            _bestLabels.upload(_labels);
+            _centers.upload(centers);
+            distanceToCenters(_dists, _bestLabels, _src, _centers);
+
+            Mat dists;
+            _dists.download(dists);
+            _bestLabels.download(_labels);
+
+            double* dist = dists.ptr<double>(0);
+            compactness = 0;
+            for( i = 0; i < N; i++ )
+            {
+                compactness += dist[i];
+            }
+        }
+
+        if( compactness < best_compactness )
+        {
+            best_compactness = compactness;
+        }
+    }
+
+    return best_compactness;
+}
+
index 268a1fe..1ff963a 100644 (file)
@@ -74,6 +74,7 @@ namespace cv
     }
 }
 
+
 ////////////////////////////////////////////////////////////////////////
 // convert_C3C4
 static void convert_C3C4(const cl_mem &src, oclMat &dst)
@@ -227,6 +228,34 @@ void cv::ocl::oclMat::upload(const Mat &m)
     //download_channels = m.channels();
 }
 
+cv::ocl::oclMat::operator cv::_InputArray()
+{
+    _InputArray newInputArray;
+    newInputArray.flags = cv::_InputArray::OCL_MAT;
+    newInputArray.obj   = reinterpret_cast<void *>(this);
+    return newInputArray;
+}
+
+cv::ocl::oclMat::operator cv::_OutputArray()
+{
+    _OutputArray newOutputArray;
+    newOutputArray.flags = cv::_InputArray::OCL_MAT;
+    newOutputArray.obj   = reinterpret_cast<void *>(this);
+    return newOutputArray;
+}
+
+cv::ocl::oclMat& cv::ocl::getOclMatRef(InputArray src)
+{
+    CV_Assert(src.flags & cv::_InputArray::OCL_MAT);
+    return *reinterpret_cast<oclMat*>(src.obj);
+}
+
+cv::ocl::oclMat& cv::ocl::getOclMatRef(OutputArray src)
+{
+    CV_Assert(src.flags & cv::_InputArray::OCL_MAT);
+    return *reinterpret_cast<oclMat*>(src.obj);
+}
+
 void cv::ocl::oclMat::download(cv::Mat &m) const
 {
     CV_DbgAssert(!this->empty());
@@ -394,7 +423,7 @@ void cv::ocl::oclMat::convertTo( oclMat &dst, int rtype, double alpha, double be
     if( rtype < 0 )
         rtype = type();
     else
-        rtype = CV_MAKETYPE(CV_MAT_DEPTH(rtype), oclchannels());
+        rtype = CV_MAKETYPE(CV_MAT_DEPTH(rtype), channels());
 
     //int scn = channels();
     int sdepth = depth(), ddepth = CV_MAT_DEPTH(rtype);
index 75314fb..4292a1f 100644 (file)
@@ -149,7 +149,7 @@ namespace cv
             cl_image_format format;
             int err;
             int depth    = mat.depth();
-            int channels = mat.channels();
+            int channels = mat.oclchannels();
 
             switch(depth)
             {
index d6baba2..cb16fb1 100644 (file)
@@ -16,7 +16,7 @@
 // Third party copyrights are property of their respective owners.
 //
 // @Authors
-//    Sen Liu, sen@multicorewareinc.com
+//    Sen Liu, swjtuls1987@126.com
 //
 // Redistribution and use in source and binary forms, with or without modification,
 // are permitted provided that the following conditions are met:
@@ -277,8 +277,8 @@ static void ocl_cvMoments( const void* array, CvMoments* mom, int binary )
         blocky = size.height/TILE_SIZE;
     else
         blocky = size.height/TILE_SIZE + 1;
-    cv::ocl::oclMat dst_m(blocky * 10, blockx, CV_64FC1);
-    cl_mem sum = openCLCreateBuffer(src.clCxt,CL_MEM_READ_WRITE,10*sizeof(double));
+    oclMat dst_m(blocky * 10, blockx, CV_64FC1);
+    oclMat sum(1, 10, CV_64FC1);
     int tile_width  = std::min(size.width,TILE_SIZE);
     int tile_height = std::min(size.height,TILE_SIZE);
     size_t localThreads[3]  = { tile_height, 1, 1};
@@ -288,19 +288,16 @@ static void ocl_cvMoments( const void* array, CvMoments* mom, int binary )
     args.push_back( make_pair( sizeof(cl_int) , (void *)&src.rows ));
     args.push_back( make_pair( sizeof(cl_int) , (void *)&src.cols ));
     args.push_back( make_pair( sizeof(cl_int) , (void *)&src.step ));
-    args.push_back( make_pair( sizeof(cl_int) , (void *)&tileSize.width ));
-    args.push_back( make_pair( sizeof(cl_int) , (void *)&tileSize.height ));
     args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst_m.data ));
     args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_m.cols ));
     args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_m.step ));
     args.push_back( make_pair( sizeof(cl_int) , (void *)&blocky ));
-    args.push_back( make_pair( sizeof(cl_int) , (void *)&type ));
     args.push_back( make_pair( sizeof(cl_int) , (void *)&depth ));
     args.push_back( make_pair( sizeof(cl_int) , (void *)&cn ));
     args.push_back( make_pair( sizeof(cl_int) , (void *)&coi ));
     args.push_back( make_pair( sizeof(cl_int) , (void *)&binary ));
     args.push_back( make_pair( sizeof(cl_int) , (void *)&TILE_SIZE ));
-    openCLExecuteKernel(dst_m.clCxt, &moments, "CvMoments", globalThreads, localThreads, args, -1, depth);
+    openCLExecuteKernel(Context::getContext(), &moments, "CvMoments", globalThreads, localThreads, args, -1, depth);
 
     size_t localThreadss[3]  = { 128, 1, 1};
     size_t globalThreadss[3] = { 128, 1, 1};
@@ -309,25 +306,23 @@ static void ocl_cvMoments( const void* array, CvMoments* mom, int binary )
     args_sum.push_back( make_pair( sizeof(cl_int) , (void *)&tile_height ));
     args_sum.push_back( make_pair( sizeof(cl_int) , (void *)&tile_width ));
     args_sum.push_back( make_pair( sizeof(cl_int) , (void *)&TILE_SIZE ));
-    args_sum.push_back( make_pair( sizeof(cl_mem) , (void *)&sum ));
+    args_sum.push_back( make_pair( sizeof(cl_mem) , (void *)&sum.data ));
     args_sum.push_back( make_pair( sizeof(cl_mem) , (void *)&dst_m.data ));
     args_sum.push_back( make_pair( sizeof(cl_int) , (void *)&dst_m.step ));
-    openCLExecuteKernel(dst_m.clCxt, &moments, "dst_sum", globalThreadss, localThreadss, args_sum, -1, -1);
-    double* dstsum = new double[10];
-    memset(dstsum,0,10*sizeof(double));
-    openCLReadBuffer(dst_m.clCxt,sum,(void *)dstsum,10*sizeof(double));
-    mom->m00 = dstsum[0];
-    mom->m10 = dstsum[1];
-    mom->m01 = dstsum[2];
-    mom->m20 = dstsum[3];
-    mom->m11 = dstsum[4];
-    mom->m02 = dstsum[5];
-    mom->m30 = dstsum[6];
-    mom->m21 = dstsum[7];
-    mom->m12 = dstsum[8];
-    mom->m03 = dstsum[9];
-    delete [] dstsum;
-    openCLSafeCall(clReleaseMemObject(sum));
+    openCLExecuteKernel(Context::getContext(), &moments, "dst_sum", globalThreadss, localThreadss, args_sum, -1, -1);
+
+    Mat dstsum(sum);
+    mom->m00 = dstsum.at<double>(0, 0);
+    mom->m10 = dstsum.at<double>(0, 1);
+    mom->m01 = dstsum.at<double>(0, 2);
+    mom->m20 = dstsum.at<double>(0, 3);
+    mom->m11 = dstsum.at<double>(0, 4);
+    mom->m02 = dstsum.at<double>(0, 5);
+    mom->m30 = dstsum.at<double>(0, 6);
+    mom->m21 = dstsum.at<double>(0, 7);
+    mom->m12 = dstsum.at<double>(0, 8);
+    mom->m03 = dstsum.at<double>(0, 9);
+
     icvCompleteMomentState( mom );
 }
 
diff --git a/modules/ocl/src/opencl/kernel_radix_sort_by_key.cl b/modules/ocl/src/opencl/kernel_radix_sort_by_key.cl
new file mode 100644 (file)
index 0000000..fdb440a
--- /dev/null
@@ -0,0 +1,176 @@
+/*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) 2010-2012, Multicoreware, Inc., all rights reserved.
+// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Peng Xiao, pengxiao@outlook.com
+//
+// 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 oclMaterials 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*/
+
+#pragma OPENCL EXTENSION cl_khr_byte_addressable_store : enable 
+
+#ifndef N   // number of radices
+#define N 4
+#endif
+
+#ifndef K_T
+#define K_T float
+#endif
+
+#ifndef V_T
+#define V_T float
+#endif
+
+#ifndef IS_GT
+#define IS_GT 0
+#endif
+
+
+// from Thrust::b40c, link:
+// https://github.com/thrust/thrust/blob/master/thrust/system/cuda/detail/detail/b40c/radixsort_key_conversion.h
+__inline uint convertKey(uint converted_key)
+{
+#ifdef K_FLT
+    unsigned int mask = (converted_key & 0x80000000) ? 0xffffffff : 0x80000000;
+    converted_key ^= mask;
+#elif defined(K_INT)
+    const uint SIGN_MASK = 1u << ((sizeof(int) * 8) - 1);
+    converted_key ^= SIGN_MASK;        
+#else
+
+#endif
+    return converted_key;
+}
+
+//FIXME(pengx17): 
+// exclusive scan, need to be optimized as this is too naive...
+kernel
+    void naiveScanAddition(
+    __global int * input,
+    __global int * output,
+    int size
+    )
+{
+    if(get_global_id(0) == 0)
+    {
+        output[0] = 0;
+        for(int i = 1; i < size; i ++)
+        {
+            output[i] = output[i - 1] + input[i - 1];
+        }
+    }
+}
+
+// following is ported from
+// https://github.com/HSA-Libraries/Bolt/blob/master/include/bolt/cl/sort_uint_kernels.cl
+kernel
+    void histogramRadixN (
+    __global K_T* unsortedKeys,
+    __global int * buckets,
+    uint shiftCount
+    )
+{
+    const int RADIX_T     = N;
+    const int RADICES_T   = (1 << RADIX_T);
+    const int NUM_OF_ELEMENTS_PER_WORK_ITEM_T = RADICES_T; 
+    const int MASK_T      = (1 << RADIX_T) - 1;
+    int localBuckets[16] = {0,0,0,0,0,0,0,0,
+                            0,0,0,0,0,0,0,0};
+    int globalId    = get_global_id(0);
+    int numOfGroups = get_num_groups(0);
+
+    /* Calculate thread-histograms */
+    for(int i = 0; i < NUM_OF_ELEMENTS_PER_WORK_ITEM_T; ++i)
+    {
+        uint value = convertKey(as_uint(unsortedKeys[mad24(globalId, NUM_OF_ELEMENTS_PER_WORK_ITEM_T, i)]));
+        value = (value >> shiftCount) & MASK_T;
+#if IS_GT
+        localBuckets[RADICES_T - value - 1]++;
+#else
+        localBuckets[value]++;
+#endif
+    }
+
+    for(int i = 0; i < NUM_OF_ELEMENTS_PER_WORK_ITEM_T; ++i)
+    {
+        buckets[mad24(i, RADICES_T * numOfGroups, globalId) ] = localBuckets[i];
+    }
+}
+
+kernel
+    void permuteRadixN (
+    __global K_T*  unsortedKeys,
+    __global V_T*  unsortedVals,
+    __global int* scanedBuckets,
+    uint shiftCount,
+    __global K_T*  sortedKeys,
+    __global V_T*  sortedVals
+    )
+{
+    const int RADIX_T     = N;
+    const int RADICES_T   = (1 << RADIX_T);
+    const int MASK_T = (1<<RADIX_T)  -1;
+
+    int globalId  = get_global_id(0);
+    int numOfGroups = get_num_groups(0);
+    const int NUM_OF_ELEMENTS_PER_WORK_GROUP_T = numOfGroups << N;
+    int  localIndex[16];
+
+    /*Load the index to local memory*/
+    for(int i = 0; i < RADICES_T; ++i)
+    {
+#if IS_GT
+        localIndex[i] = scanedBuckets[mad24(RADICES_T - i - 1, NUM_OF_ELEMENTS_PER_WORK_GROUP_T, globalId)];
+#else
+        localIndex[i] = scanedBuckets[mad24(i, NUM_OF_ELEMENTS_PER_WORK_GROUP_T, globalId)];
+#endif
+    }
+    /* Permute elements to appropriate location */
+    for(int i = 0; i < RADICES_T; ++i)
+    {
+        int old_idx = mad24(globalId, RADICES_T, i);
+        K_T  ovalue = unsortedKeys[old_idx];
+        uint value = convertKey(as_uint(ovalue));
+        uint maskedValue = (value >> shiftCount) & MASK_T;
+        uint index = localIndex[maskedValue];
+        sortedKeys[index] = ovalue;
+        sortedVals[index] = unsortedVals[old_idx];
+        localIndex[maskedValue] = index + 1;
+    }
+}
diff --git a/modules/ocl/src/opencl/kernel_sort_by_key.cl b/modules/ocl/src/opencl/kernel_sort_by_key.cl
new file mode 100644 (file)
index 0000000..18e9d41
--- /dev/null
@@ -0,0 +1,245 @@
+/*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) 2010-2012, Multicoreware, Inc., all rights reserved.
+// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Peng Xiao, pengxiao@outlook.com
+//
+// 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 oclMaterials 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 K_T
+#define K_T float
+#endif
+
+#ifndef V_T
+#define V_T float
+#endif
+
+#ifndef IS_GT
+#define IS_GT false
+#endif
+
+#if IS_GT
+#define my_comp(x,y) ((x) > (y))
+#else
+#define my_comp(x,y) ((x) < (y))
+#endif
+
+/////////////////////// Bitonic sort ////////////////////////////
+// ported from 
+// https://github.com/HSA-Libraries/Bolt/blob/master/include/bolt/cl/sort_by_key_kernels.cl
+__kernel
+    void bitonicSort
+    (
+        __global K_T * keys,
+        __global V_T * vals,
+        int count,
+        int stage,
+        int passOfStage
+    )
+{
+    const int threadId = get_global_id(0);
+    if(threadId >= count / 2)
+    {
+        return;
+    }
+    const int pairDistance = 1 << (stage - passOfStage);
+    const int blockWidth   = 2 * pairDistance;
+
+    int leftId = min( (threadId % pairDistance) 
+                   + (threadId / pairDistance) * blockWidth, count );
+
+    int rightId = min( leftId + pairDistance, count );
+
+    int temp;
+
+    const V_T lval = vals[leftId];
+    const V_T rval = vals[rightId]; 
+
+    const K_T lkey = keys[leftId];
+    const K_T rkey = keys[rightId];
+
+    int sameDirectionBlockWidth = 1 << stage;
+
+    if((threadId/sameDirectionBlockWidth) % 2 == 1)
+    {
+        temp = rightId;
+        rightId = leftId;
+        leftId = temp;
+    }
+
+    const bool compareResult = my_comp(lkey, rkey);
+
+    if(compareResult)
+    {
+        keys[rightId] = rkey;
+        keys[leftId]  = lkey;
+        vals[rightId] = rval;
+        vals[leftId]  = lval;
+    }
+    else
+    {
+        keys[rightId] = lkey;
+        keys[leftId]  = rkey;
+        vals[rightId] = lval;
+        vals[leftId]  = rval;
+    }
+}
+
+/////////////////////// Selection sort ////////////////////////////
+//kernel is ported from Bolt library:
+//https://github.com/HSA-Libraries/Bolt/blob/master/include/bolt/cl/sort_kernels.cl
+__kernel
+    void selectionSortLocal
+    (
+        __global K_T * keys,
+        __global V_T * vals,
+        const int count,
+        __local  K_T * scratch
+    )
+{
+    int          i  = get_local_id(0); // index in workgroup
+    int numOfGroups = get_num_groups(0); // index in workgroup
+    int groupID     = get_group_id(0);
+    int         wg  = get_local_size(0); // workgroup size = block size
+    int n; // number of elements to be processed for this work group
+
+    int offset   = groupID * wg;
+    int same     = 0;
+    
+    vals      += offset;
+    keys      += offset;
+    n = (groupID == (numOfGroups-1))? (count - wg*(numOfGroups-1)) : wg;
+
+    int clamped_i= min(i, n - 1);
+
+    K_T key1 = keys[clamped_i], key2;
+    V_T val1 = vals[clamped_i];
+    scratch[i] = key1;
+    barrier(CLK_LOCAL_MEM_FENCE);
+
+    if(i >= n)
+    {
+        return;
+    }
+
+    int pos = 0;
+    for (int j=0;j<n;++j)
+    {
+        key2  = scratch[j];
+        if(my_comp(key2, key1)) 
+            pos++;//calculate the rank of this element in this work group
+        else 
+        {
+            if(my_comp(key1, key2))
+                continue;
+            else 
+            {
+                // key1 and key2 are same
+                same++;
+            }
+        }
+    }
+    for (int j=0; j< same; j++)
+    {
+        vals[pos + j] = val1;
+        keys[pos + j] = key1;
+    }
+}
+__kernel
+    void selectionSortFinal
+    (
+        __global K_T * keys,
+        __global V_T * vals,
+        const int count
+    )
+{
+    const int          i  = get_local_id(0); // index in workgroup
+    const int numOfGroups = get_num_groups(0); // index in workgroup
+    const int groupID     = get_group_id(0);
+    const int         wg  = get_local_size(0); // workgroup size = block size
+    int pos = 0, same = 0;
+    const int offset = get_group_id(0) * wg;
+    const int remainder = count - wg*(numOfGroups-1);
+
+    if((offset + i ) >= count)
+        return;
+    V_T val1 = vals[offset + i];
+
+    K_T key1 = keys[offset + i];
+    K_T key2;
+
+    for(int j=0; j<numOfGroups-1; j++ )
+    {
+        for(int k=0; k<wg; k++)
+        {
+            key2 = keys[j*wg + k]; 
+            if(my_comp(key1, key2))
+                break;
+            else
+            {
+                //Increment only if the value is not the same. 
+                if(my_comp(key2, key1))
+                    pos++;
+                else 
+                    same++;
+            }
+        }
+    }
+
+    for(int k=0; k<remainder; k++)
+    {
+        key2 = keys[(numOfGroups-1)*wg + k]; 
+        if(my_comp(key1, key2))
+            break;
+        else
+        {
+            //Don't increment if the value is the same. 
+            if(my_comp(key2, key1))
+                pos++;
+            else 
+                same++;
+        }
+    }  
+    for (int j=0; j< same; j++)
+    {
+        vals[pos + j] = val1;
+        keys[pos + j] = key1;
+    }
+}
diff --git a/modules/ocl/src/opencl/kernel_stablesort_by_key.cl b/modules/ocl/src/opencl/kernel_stablesort_by_key.cl
new file mode 100644 (file)
index 0000000..9596d8c
--- /dev/null
@@ -0,0 +1,296 @@
+/*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) 2010-2012, Multicoreware, Inc., all rights reserved.
+// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Peng Xiao, pengxiao@outlook.com
+//
+// 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 oclMaterials 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 K_T
+#define K_T float
+#endif
+
+#ifndef V_T
+#define V_T float
+#endif
+
+#ifndef IS_GT
+#define IS_GT false
+#endif
+
+#if IS_GT
+#define my_comp(x,y) ((x) > (y))
+#else
+#define my_comp(x,y) ((x) < (y))
+#endif
+
+///////////// parallel merge sort ///////////////
+// ported from https://github.com/HSA-Libraries/Bolt/blob/master/include/bolt/cl/stablesort_by_key_kernels.cl
+uint lowerBoundLinear( global K_T* data, uint left, uint right, K_T searchVal)
+{
+    //  The values firstIndex and lastIndex get modified within the loop, narrowing down the potential sequence
+    uint firstIndex = left;
+    uint lastIndex = right;
+
+    //  This loops through [firstIndex, lastIndex)
+    //  Since firstIndex and lastIndex will be different for every thread depending on the nested branch,
+    //  this while loop will be divergent within a wavefront
+    while( firstIndex < lastIndex )
+    {
+        K_T dataVal = data[ firstIndex ];
+
+        //  This branch will create divergent wavefronts
+        if( my_comp( dataVal, searchVal ) )
+        {
+            firstIndex = firstIndex+1;
+        }
+        else
+        {
+            break;
+        }
+    }
+
+    return firstIndex;
+}
+
+//  This implements a binary search routine to look for an 'insertion point' in a sequence, denoted
+//  by a base pointer and left and right index for a particular candidate value.  The comparison operator is
+//  passed as a functor parameter my_comp
+//  This function returns an index that is the first index whos value would be equal to the searched value
+uint lowerBoundBinary( global K_T* data, uint left, uint right, K_T searchVal)
+{
+    //  The values firstIndex and lastIndex get modified within the loop, narrowing down the potential sequence
+    uint firstIndex = left;
+    uint lastIndex = right;
+
+    //  This loops through [firstIndex, lastIndex)
+    //  Since firstIndex and lastIndex will be different for every thread depending on the nested branch,
+    //  this while loop will be divergent within a wavefront
+    while( firstIndex < lastIndex )
+    {
+        //  midIndex is the average of first and last, rounded down
+        uint midIndex = ( firstIndex + lastIndex ) / 2;
+        K_T midValue = data[ midIndex ];
+
+        //  This branch will create divergent wavefronts
+        if( my_comp( midValue, searchVal ) )
+        {
+            firstIndex = midIndex+1;
+            // printf( "lowerBound: lastIndex[ %i ]=%i\n", get_local_id( 0 ), lastIndex );
+        }
+        else
+        {
+            lastIndex = midIndex;
+            // printf( "lowerBound: firstIndex[ %i ]=%i\n", get_local_id( 0 ), firstIndex );
+        }
+    }
+
+    return firstIndex;
+}
+
+//  This implements a binary search routine to look for an 'insertion point' in a sequence, denoted
+//  by a base pointer and left and right index for a particular candidate value.  The comparison operator is
+//  passed as a functor parameter my_comp
+//  This function returns an index that is the first index whos value would be greater than the searched value
+//  If the search value is not found in the sequence, upperbound returns the same result as lowerbound
+uint upperBoundBinary( global K_T* data, uint left, uint right, K_T searchVal)
+{
+    uint upperBound = lowerBoundBinary( data, left, right, searchVal );
+
+    // printf( "upperBoundBinary: upperBound[ %i, %i ]= %i\n", left, right, upperBound );
+    //  If upperBound == right, then  searchVal was not found in the sequence.  Just return.
+    if( upperBound != right )
+    {
+        //  While the values are equal i.e. !(x < y) && !(y < x) increment the index
+        K_T upperValue = data[ upperBound ];
+        while( !my_comp( upperValue, searchVal ) && !my_comp( searchVal, upperValue) && (upperBound != right) )
+        {
+            upperBound++;
+            upperValue = data[ upperBound ];
+        }
+    }
+
+    return upperBound;
+}
+
+//  This kernel implements merging of blocks of sorted data.  The input to this kernel most likely is
+//  the output of blockInsertionSortTemplate.  It is expected that the source array contains multiple
+//  blocks, each block is independently sorted.  The goal is to write into the output buffer half as
+//  many blocks, of double the size.  The even and odd blocks are stably merged together to form
+//  a new sorted block of twice the size.  The algorithm is out-of-place.
+kernel void merge(
+    global K_T*   iKey_ptr,
+    global V_T*   iValue_ptr,
+    global K_T*   oKey_ptr,
+    global V_T*   oValue_ptr,
+    const uint    srcVecSize,
+    const uint    srcLogicalBlockSize,
+    local K_T*    key_lds,
+    local V_T*    val_lds
+)
+{
+    size_t globalID     = get_global_id( 0 );
+    size_t groupID      = get_group_id( 0 );
+    size_t localID      = get_local_id( 0 );
+    size_t wgSize       = get_local_size( 0 );
+
+    //  Abort threads that are passed the end of the input vector
+    if( globalID >= srcVecSize )
+        return; // on SI this doesn't mess-up barriers
+
+    //  For an element in sequence A, find the lowerbound index for it in sequence B
+    uint srcBlockNum   = globalID / srcLogicalBlockSize;
+    uint srcBlockIndex = globalID % srcLogicalBlockSize;
+
+    // printf( "mergeTemplate: srcBlockNum[%i]=%i\n", srcBlockNum, srcBlockIndex );
+
+    //  Pairs of even-odd blocks will be merged together
+    //  An even block should search for an insertion point in the next odd block,
+    //  and the odd block should look for an insertion point in the corresponding previous even block
+    uint dstLogicalBlockSize = srcLogicalBlockSize<<1;
+    uint leftBlockIndex = globalID & ~((dstLogicalBlockSize) - 1 );
+    leftBlockIndex += (srcBlockNum & 0x1) ? 0 : srcLogicalBlockSize;
+    leftBlockIndex = min( leftBlockIndex, srcVecSize );
+    uint rightBlockIndex = min( leftBlockIndex + srcLogicalBlockSize, srcVecSize );
+
+    // if( localID == 0 )
+    // {
+    // printf( "mergeTemplate: wavefront[ %i ] logicalBlock[ %i ] logicalIndex[ %i ] leftBlockIndex[ %i ] <=> rightBlockIndex[ %i ]\n", groupID, srcBlockNum, srcBlockIndex, leftBlockIndex, rightBlockIndex );
+    // }
+
+    //  For a particular element in the input array, find the lowerbound index for it in the search sequence given by leftBlockIndex & rightBlockIndex
+    // uint insertionIndex = lowerBoundLinear( iKey_ptr, leftBlockIndex, rightBlockIndex, iKey_ptr[ globalID ], my_comp ) - leftBlockIndex;
+    uint insertionIndex = 0;
+    if( (srcBlockNum & 0x1) == 0 )
+    {
+        insertionIndex = lowerBoundBinary( iKey_ptr, leftBlockIndex, rightBlockIndex, iKey_ptr[ globalID ] ) - leftBlockIndex;
+    }
+    else
+    {
+        insertionIndex = upperBoundBinary( iKey_ptr, leftBlockIndex, rightBlockIndex, iKey_ptr[ globalID ] ) - leftBlockIndex;
+    }
+
+    //  The index of an element in the result sequence is the summation of it's indixes in the two input
+    //  sequences
+    uint dstBlockIndex = srcBlockIndex + insertionIndex;
+    uint dstBlockNum = srcBlockNum/2;
+
+    // if( (dstBlockNum*dstLogicalBlockSize)+dstBlockIndex == 395 )
+    // {
+    // printf( "mergeTemplate: (dstBlockNum[ %i ] * dstLogicalBlockSize[ %i ]) + dstBlockIndex[ %i ] = srcBlockIndex[ %i ] + insertionIndex[ %i ]\n", dstBlockNum, dstLogicalBlockSize, dstBlockIndex, srcBlockIndex, insertionIndex );
+    // printf( "mergeTemplate: dstBlockIndex[ %i ] = iKey_ptr[ %i ] ( %i )\n", (dstBlockNum*dstLogicalBlockSize)+dstBlockIndex, globalID, iKey_ptr[ globalID ] );
+    // }
+    oKey_ptr[ (dstBlockNum*dstLogicalBlockSize)+dstBlockIndex ] = iKey_ptr[ globalID ];
+    oValue_ptr[ (dstBlockNum*dstLogicalBlockSize)+dstBlockIndex ] = iValue_ptr[ globalID ];
+    // printf( "mergeTemplate: leftResultIndex[ %i ]=%i + %i\n", leftResultIndex, srcBlockIndex, leftInsertionIndex );
+}
+
+kernel void blockInsertionSort(
+    global K_T*   key_ptr,
+    global V_T*   value_ptr,
+    const uint    vecSize,
+    local K_T*    key_lds,
+    local V_T*    val_lds
+)
+{
+    size_t gloId    = get_global_id( 0 );
+    size_t groId    = get_group_id( 0 );
+    size_t locId    = get_local_id( 0 );
+    size_t wgSize   = get_local_size( 0 );
+
+    bool in_range = gloId < vecSize;
+    K_T key;
+    V_T val;
+    //  Abort threads that are passed the end of the input vector
+    if (in_range)
+    {
+        //  Make a copy of the entire input array into fast local memory
+        key = key_ptr[ gloId ];
+        val = value_ptr[ gloId ];
+        key_lds[ locId ] = key;
+        val_lds[ locId ] = val;
+    }
+    barrier( CLK_LOCAL_MEM_FENCE );
+    //  Sorts a workgroup using a naive insertion sort
+    //  The sort uses one thread within a workgroup to sort the entire workgroup
+    if( locId == 0 && in_range )
+    {
+        //  The last workgroup may have an irregular size, so we calculate a per-block endIndex
+        //  endIndex is essentially emulating a mod operator with subtraction and multiply
+        size_t endIndex = vecSize - ( groId * wgSize );
+        endIndex = min( endIndex, wgSize );
+
+        // printf( "Debug: endIndex[%i]=%i\n", groId, endIndex );
+
+        //  Indices are signed because the while loop will generate a -1 index inside of the max function
+        for( int currIndex = 1; currIndex < endIndex; ++currIndex )
+        {
+            key = key_lds[ currIndex ];
+            val = val_lds[ currIndex ];
+            int scanIndex = currIndex;
+            K_T ldsKey = key_lds[scanIndex - 1];
+            while( scanIndex > 0 && my_comp( key, ldsKey ) )
+            {
+                V_T ldsVal = val_lds[scanIndex - 1];
+
+                //  If the keys are being swapped, make sure the values are swapped identicaly
+                key_lds[ scanIndex ] = ldsKey;
+                val_lds[ scanIndex ] = ldsVal;
+
+                scanIndex = scanIndex - 1;
+                ldsKey = key_lds[ max( 0, scanIndex - 1 ) ];  // scanIndex-1 may be -1
+            }
+            key_lds[ scanIndex ] = key;
+            val_lds[ scanIndex ] = val;
+        }
+    }
+    barrier( CLK_LOCAL_MEM_FENCE );
+
+    if(in_range)
+    {
+        key = key_lds[ locId ];
+        key_ptr[ gloId ] = key;
+
+        val = val_lds[ locId ];
+        value_ptr[ gloId ] = val;
+    }
+}
+
+///////////// Radix sort from b40c library /////////////
similarity index 67%
rename from modules/ocl/test/test_columnsum.cpp
rename to modules/ocl/src/opencl/kmeans_kernel.cl
index 231f065..c6af0ad 100644 (file)
@@ -15,8 +15,7 @@
 // Third party copyrights are property of their respective owners.
 //
 // @Authors
-//        Chunpeng Zhang chunpeng@multicorewareinc.com
-//
+//    Xiaopeng Fu, fuxiaopeng2222@163.com
 //
 // Redistribution and use in source and binary forms, with or without modification,
 // are permitted provided that the following conditions are met:
 //
 //   * 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 oclMaterials provided with the distribution.
+//     and/or other GpuMaterials 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
+// 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,
 //
 //M*/
 
-#include "precomp.hpp"
-#include <iomanip>
-
-#ifdef HAVE_OPENCL
-
-PARAM_TEST_CASE(ColumnSum, cv::Size)
+__kernel void distanceToCenters(
+    int label_step, int K,
+    __global float *src,
+    __global int *labels, int dims, int rows,
+    __global float *centers,
+    __global float *dists)
 {
-    cv::Size size;
-    cv::Mat src;
+    int gid = get_global_id(1);
 
-    virtual void SetUp()
-    {
-        size = GET_PARAM(0);
-    }
-};
+    float dist, euDist, min;
+    int minCentroid;
 
-TEST_P(ColumnSum, Accuracy)
-{
-    cv::Mat src = randomMat(size, CV_32FC1);
-    cv::ocl::oclMat d_dst;
-    cv::ocl::oclMat d_src(src);
-
-    cv::ocl::columnSum(d_src, d_dst);
+    if(gid >= rows)
+        return;
 
-    cv::Mat dst(d_dst);
-
-    for (int j = 0; j < src.cols; ++j)
+    for(int i = 0 ; i < K; i++)
     {
-        float gold = src.at<float>(0, j);
-        float res = dst.at<float>(0, j);
-        ASSERT_NEAR(res, gold, 1e-5);
-    }
+        euDist = 0;
+        for(int j = 0; j < dims; j++)
+        {
+            dist = (src[j + gid * dims]
+                    - centers[j + i * dims]);
+            euDist += dist * dist;
+        }
 
-    for (int i = 1; i < src.rows; ++i)
-    {
-        for (int j = 0; j < src.cols; ++j)
+        if(i == 0)
+        {
+            min = euDist;
+            minCentroid = 0;
+        }
+        else if(euDist < min)
         {
-            float gold = src.at<float>(i, j) += src.at<float>(i - 1, j);
-            float res = dst.at<float>(i, j);
-            ASSERT_NEAR(res, gold, 1e-5);
+            min = euDist;
+            minCentroid = i;
         }
     }
+    dists[gid] = min;
+    labels[label_step * gid] = minCentroid;
 }
-
-INSTANTIATE_TEST_CASE_P(OCL_ImgProc, ColumnSum, DIFFERENT_SIZES);
-
-
-#endif
index 2378f4f..7131301 100644 (file)
@@ -173,10 +173,10 @@ __kernel void dst_sum(int src_rows, int src_cols, int tile_height, int tile_widt
             sum[i] = dst_sum[i][0];
 }
 
-__kernel void CvMoments_D0(__global uchar16* src_data, int src_rows, int src_cols, int src_step, int tileSize_width, int tileSize_height,
+__kernel void CvMoments_D0(__global uchar16* src_data, int src_rows, int src_cols, int src_step,
                            __global F* dst_m,
                            int dst_cols, int dst_step, int blocky,
-                           int type, int depth, int cn, int coi, int binary, int TILE_SIZE)
+                           int depth, int cn, int coi, int binary, int TILE_SIZE)
 {
     uchar tmp_coi[16]; // get the coi data
     uchar16 tmp[16];
@@ -192,35 +192,43 @@ __kernel void CvMoments_D0(__global uchar16* src_data, int src_rows, int src_col
     int x = wgidx*TILE_SIZE;  // vector length of uchar
     int kcn = (cn==2)?2:4;
     int rstep = min(src_step, TILE_SIZE);
-    tileSize_height = min(TILE_SIZE, src_rows - y);
-    tileSize_width = min(TILE_SIZE, src_cols - x);
-
-    if( tileSize_width < TILE_SIZE )
-        for(int i = tileSize_width; i < rstep; i++ )
-            *((__global uchar*)src_data+(y+lidy)*src_step+x+i) = 0;
-    if( coi > 0 )      //channel of interest
-        for(int i = 0; i < tileSize_width; i += VLEN_C)
-        {
-            for(int j=0; j<VLEN_C; j++)
-                tmp_coi[j] = *((__global uchar*)src_data+(y+lidy)*src_step+(x+i+j)*kcn+coi-1);
-            tmp[i/VLEN_C] = (uchar16)(tmp_coi[0],tmp_coi[1],tmp_coi[2],tmp_coi[3],tmp_coi[4],tmp_coi[5],tmp_coi[6],tmp_coi[7],
-                                      tmp_coi[8],tmp_coi[9],tmp_coi[10],tmp_coi[11],tmp_coi[12],tmp_coi[13],tmp_coi[14],tmp_coi[15]);
-        }
-    else
-        for(int i=0; i < tileSize_width; i+=VLEN_C)
-            tmp[i/VLEN_C] = *(src_data+(y+lidy)*src_step/VLEN_C+(x+i)/VLEN_C);
+    int tileSize_height = min(TILE_SIZE, src_rows - y);
+    int tileSize_width = min(TILE_SIZE, src_cols - x);
+
+    if ( y+lidy < src_rows )
+    {
+        if( tileSize_width < TILE_SIZE )
+            for(int i = tileSize_width; i < rstep && (x+i) < src_cols; i++ )
+                *((__global uchar*)src_data+(y+lidy)*src_step+x+i) = 0;
+
+        if( coi > 0 )  //channel of interest
+            for(int i = 0; i < tileSize_width; i += VLEN_C)
+            {
+                for(int j=0; j<VLEN_C; j++)
+                    tmp_coi[j] = *((__global uchar*)src_data+(y+lidy)*src_step+(x+i+j)*kcn+coi-1);
+                tmp[i/VLEN_C] = (uchar16)(tmp_coi[0],tmp_coi[1],tmp_coi[2],tmp_coi[3],tmp_coi[4],tmp_coi[5],tmp_coi[6],tmp_coi[7],
+                                          tmp_coi[8],tmp_coi[9],tmp_coi[10],tmp_coi[11],tmp_coi[12],tmp_coi[13],tmp_coi[14],tmp_coi[15]);
+            }
+        else
+            for(int i=0; i < tileSize_width; i+=VLEN_C)
+                tmp[i/VLEN_C] = *(src_data+(y+lidy)*src_step/VLEN_C+(x+i)/VLEN_C);
+    }
+
     uchar16 zero = (uchar16)(0);
     uchar16 full = (uchar16)(255);
     if( binary )
         for(int i=0; i < tileSize_width; i+=VLEN_C)
             tmp[i/VLEN_C] = (tmp[i/VLEN_C]!=zero)?full:zero;
+
     F mom[10];
     __local int m[10][128];
-    if(lidy == 0)
+    if(lidy < 128)
+    {
         for(int i=0; i<10; i++)
-            for(int j=0; j<128; j++)
-                m[i][j]=0;
+            m[i][lidy]=0;
+    }
     barrier(CLK_LOCAL_MEM_FENCE);
+
     int lm[10] = {0};
     int16 x0 = (int16)(0);
     int16 x1 = (int16)(0);
@@ -281,6 +289,7 @@ __kernel void CvMoments_D0(__global uchar16* src_data, int src_rows, int src_col
                 m[i][lidy-j/2] = lm[i];
         barrier(CLK_LOCAL_MEM_FENCE);
     }
+
     if(lidy == 0&&lidx == 0)
     {
         for( int mt = 0; mt < 10; mt++ )
@@ -328,10 +337,10 @@ __kernel void CvMoments_D0(__global uchar16* src_data, int src_rows, int src_col
     }
 }
 
-__kernel void CvMoments_D2(__global ushort8* src_data, int src_rows, int src_cols, int src_step, int tileSize_width, int tileSize_height,
+__kernel void CvMoments_D2(__global ushort8* src_data, int src_rows, int src_cols, int src_step,
                            __global F* dst_m,
                            int dst_cols, int dst_step, int blocky,
-                           int type, int depth, int cn, int coi, int binary, const int TILE_SIZE)
+                           int depth, int cn, int coi, int binary, const int TILE_SIZE)
 {
     ushort tmp_coi[8]; // get the coi data
     ushort8 tmp[32];
@@ -346,21 +355,26 @@ __kernel void CvMoments_D2(__global ushort8* src_data, int src_rows, int src_col
     int x = wgidx*TILE_SIZE;  // real X index of pixel
     int kcn = (cn==2)?2:4;
     int rstep = min(src_step/2, TILE_SIZE);
-    tileSize_height = min(TILE_SIZE, src_rows - y);
-    tileSize_width = min(TILE_SIZE, src_cols -x);
-    if(src_cols > TILE_SIZE && tileSize_width < TILE_SIZE)
-        for(int i=tileSize_width; i < rstep; i++ )
-            *((__global ushort*)src_data+(y+lidy)*src_step/2+x+i) = 0;
-    if( coi > 0 )
-        for(int i=0; i < tileSize_width; i+=VLEN_US)
-        {
-            for(int j=0; j<VLEN_US; j++)
-                tmp_coi[j] = *((__global ushort*)src_data+(y+lidy)*(int)src_step/2+(x+i+j)*kcn+coi-1);
-            tmp[i/VLEN_US] = (ushort8)(tmp_coi[0],tmp_coi[1],tmp_coi[2],tmp_coi[3],tmp_coi[4],tmp_coi[5],tmp_coi[6],tmp_coi[7]);
-        }
-    else
-        for(int i=0; i < tileSize_width; i+=VLEN_US)
-            tmp[i/VLEN_US] = *(src_data+(y+lidy)*src_step/(2*VLEN_US)+(x+i)/VLEN_US);
+    int tileSize_height = min(TILE_SIZE, src_rows - y);
+    int tileSize_width = min(TILE_SIZE, src_cols -x);
+
+    if ( y+lidy < src_rows )
+    {
+        if(src_cols > TILE_SIZE && tileSize_width < TILE_SIZE)
+            for(int i=tileSize_width; i < rstep && (x+i) < src_cols; i++ )
+                *((__global ushort*)src_data+(y+lidy)*src_step/2+x+i) = 0;
+        if( coi > 0 )
+            for(int i=0; i < tileSize_width; i+=VLEN_US)
+            {
+                for(int j=0; j<VLEN_US; j++)
+                    tmp_coi[j] = *((__global ushort*)src_data+(y+lidy)*(int)src_step/2+(x+i+j)*kcn+coi-1);
+                tmp[i/VLEN_US] = (ushort8)(tmp_coi[0],tmp_coi[1],tmp_coi[2],tmp_coi[3],tmp_coi[4],tmp_coi[5],tmp_coi[6],tmp_coi[7]);
+            }
+        else
+            for(int i=0; i < tileSize_width; i+=VLEN_US)
+                tmp[i/VLEN_US] = *(src_data+(y+lidy)*src_step/(2*VLEN_US)+(x+i)/VLEN_US);
+    }
+
     ushort8 zero = (ushort8)(0);
     ushort8 full = (ushort8)(255);
     if( binary )
@@ -368,11 +382,11 @@ __kernel void CvMoments_D2(__global ushort8* src_data, int src_rows, int src_col
             tmp[i/VLEN_US] = (tmp[i/VLEN_US]!=zero)?full:zero;
     F mom[10];
     __local long m[10][128];
-    if(lidy == 0)
+    if(lidy < 128)
         for(int i=0; i<10; i++)
-            for(int j=0; j<128; j++)
-                m[i][j]=0;
+            m[i][lidy]=0;
     barrier(CLK_LOCAL_MEM_FENCE);
+
     long lm[10] = {0};
     int8 x0 = (int8)(0);
     int8 x1 = (int8)(0);
@@ -422,17 +436,22 @@ __kernel void CvMoments_D2(__global ushort8* src_data, int src_rows, int src_col
         lm[0] = x0.s0;             // m00
     }
     barrier(CLK_LOCAL_MEM_FENCE);
+
     for( int j = TILE_SIZE/2; j >= 1; j = j/2 )
     {
         if(lidy < j)
             for( int i = 0; i < 10; i++ )
                 lm[i] = lm[i] + m[i][lidy];
-        barrier(CLK_LOCAL_MEM_FENCE);
+    }
+    barrier(CLK_LOCAL_MEM_FENCE);
+    for( int j = TILE_SIZE/2; j >= 1; j = j/2 )
+    {
         if(lidy >= j/2&&lidy < j)
             for( int i = 0; i < 10; i++ )
                 m[i][lidy-j/2] = lm[i];
-        barrier(CLK_LOCAL_MEM_FENCE);
     }
+    barrier(CLK_LOCAL_MEM_FENCE);
+
     if(lidy == 0&&lidx == 0)
     {
         for(int mt = 0; mt < 10; mt++ )
@@ -482,10 +501,10 @@ __kernel void CvMoments_D2(__global ushort8* src_data, int src_rows, int src_col
     }
 }
 
-__kernel void CvMoments_D3(__global short8* src_data, int src_rows, int src_cols, int src_step, int tileSize_width, int tileSize_height,
+__kernel void CvMoments_D3(__global short8* src_data, int src_rows, int src_cols, int src_step,
                            __global F* dst_m,
                            int dst_cols, int dst_step, int blocky,
-                           int type, int depth, int cn, int coi, int binary, const int TILE_SIZE)
+                           int depth, int cn, int coi, int binary, const int TILE_SIZE)
 {
     short tmp_coi[8]; // get the coi data
     short8 tmp[32];
@@ -500,21 +519,26 @@ __kernel void CvMoments_D3(__global short8* src_data, int src_rows, int src_cols
     int x = wgidx*TILE_SIZE;  // real X index of pixel
     int kcn = (cn==2)?2:4;
     int rstep = min(src_step/2, TILE_SIZE);
-    tileSize_height = min(TILE_SIZE, src_rows - y);
-    tileSize_width = min(TILE_SIZE, src_cols -x);
-    if(tileSize_width < TILE_SIZE)
-        for(int i = tileSize_width; i < rstep; i++ )
-            *((__global short*)src_data+(y+lidy)*src_step/2+x+i) = 0;
-    if( coi > 0 )
-        for(int i=0; i < tileSize_width; i+=VLEN_S)
-        {
-            for(int j=0; j<VLEN_S; j++)
-                tmp_coi[j] = *((__global short*)src_data+(y+lidy)*src_step/2+(x+i+j)*kcn+coi-1);
-            tmp[i/VLEN_S] = (short8)(tmp_coi[0],tmp_coi[1],tmp_coi[2],tmp_coi[3],tmp_coi[4],tmp_coi[5],tmp_coi[6],tmp_coi[7]);
-        }
-    else
-        for(int i=0; i < tileSize_width; i+=VLEN_S)
-            tmp[i/VLEN_S] = *(src_data+(y+lidy)*src_step/(2*VLEN_S)+(x+i)/VLEN_S);
+    int tileSize_height = min(TILE_SIZE, src_rows - y);
+    int tileSize_width = min(TILE_SIZE, src_cols -x);
+
+    if ( y+lidy < src_rows )
+    {
+        if(tileSize_width < TILE_SIZE)
+            for(int i = tileSize_width; i < rstep && (x+i) < src_cols; i++ )
+                *((__global short*)src_data+(y+lidy)*src_step/2+x+i) = 0;
+        if( coi > 0 )
+            for(int i=0; i < tileSize_width; i+=VLEN_S)
+            {
+                for(int j=0; j<VLEN_S; j++)
+                    tmp_coi[j] = *((__global short*)src_data+(y+lidy)*src_step/2+(x+i+j)*kcn+coi-1);
+                tmp[i/VLEN_S] = (short8)(tmp_coi[0],tmp_coi[1],tmp_coi[2],tmp_coi[3],tmp_coi[4],tmp_coi[5],tmp_coi[6],tmp_coi[7]);
+            }
+        else
+            for(int i=0; i < tileSize_width; i+=VLEN_S)
+                tmp[i/VLEN_S] = *(src_data+(y+lidy)*src_step/(2*VLEN_S)+(x+i)/VLEN_S);
+    }
+
     short8 zero = (short8)(0);
     short8 full = (short8)(255);
     if( binary )
@@ -523,10 +547,9 @@ __kernel void CvMoments_D3(__global short8* src_data, int src_rows, int src_cols
 
     F mom[10];
     __local long m[10][128];
-    if(lidy == 0)
+    if(lidy < 128)
         for(int i=0; i<10; i++)
-            for(int j=0; j<128; j++)
-                m[i][j]=0;
+            m[i][lidy]=0;
     barrier(CLK_LOCAL_MEM_FENCE);
     long lm[10] = {0};
     int8 x0 = (int8)(0);
@@ -637,10 +660,10 @@ __kernel void CvMoments_D3(__global short8* src_data, int src_rows, int src_cols
     }
 }
 
-__kernel void CvMoments_D5( __global float* src_data, int src_rows, int src_cols, int src_step, int tileSize_width, int tileSize_height,
+__kernel void CvMoments_D5( __global float* src_data, int src_rows, int src_cols, int src_step,
                             __global F* dst_m,
                             int dst_cols, int dst_step, int blocky,
-                            int type, int depth, int cn, int coi, int binary, const int TILE_SIZE)
+                            int depth, int cn, int coi, int binary, const int TILE_SIZE)
 {
     float tmp_coi[4]; // get the coi data
     float4 tmp[64] ;
@@ -654,33 +677,30 @@ __kernel void CvMoments_D5( __global float* src_data, int src_rows, int src_cols
     int y = wgidy*TILE_SIZE;  // real Y index of pixel
     int x = wgidx*TILE_SIZE;  // real X index of pixel
     int kcn = (cn==2)?2:4;
-    src_step /= sizeof(*src_data);
-    int rstep = min(src_step, TILE_SIZE);
-    tileSize_height = min(TILE_SIZE, src_rows - y);
-    tileSize_width = min(TILE_SIZE, src_cols -x);
+    int rstep = min(src_step/4, TILE_SIZE);
+    int tileSize_height = min(TILE_SIZE, src_rows - y);
+    int tileSize_width = min(TILE_SIZE, src_cols -x);
     int maxIdx = mul24(src_rows, src_cols);
     int yOff = (y+lidy)*src_step;
     int index;
-    if(tileSize_width < TILE_SIZE && yOff < src_rows)
-        for(int i = tileSize_width; i < rstep && (yOff+x+i) < maxIdx; i++ )
-            *(src_data+yOff+x+i) = 0;
-    if( coi > 0 )
-        for(int i=0; i < tileSize_width; i+=VLEN_F)
-        {
-#pragma unroll
-            for(int j=0; j<4; j++)
+
+    if ( y+lidy < src_rows )
+    {
+        if(tileSize_width < TILE_SIZE)
+            for(int i = tileSize_width; i < rstep && (x+i) < src_cols; i++ )
+                *((__global float*)src_data+(y+lidy)*src_step/4+x+i) = 0;
+        if( coi > 0 )
+            for(int i=0; i < tileSize_width; i+=VLEN_F)
             {
-                index = yOff+(x+i+j)*kcn+coi-1;
-                if (index < maxIdx)
-                    tmp_coi[j] = *(src_data+index);
-                else
-                    tmp_coi[j] = 0;
+                for(int j=0; j<4; j++)
+                    tmp_coi[j] = *(src_data+(y+lidy)*src_step/4+(x+i+j)*kcn+coi-1);
+                tmp[i/VLEN_F] = (float4)(tmp_coi[0],tmp_coi[1],tmp_coi[2],tmp_coi[3]);
             }
-            tmp[i/VLEN_F] = (float4)(tmp_coi[0],tmp_coi[1],tmp_coi[2],tmp_coi[3]);
-        }
-    else
-        for(int i=0; i < tileSize_width && (yOff+x+i) < maxIdx; i+=VLEN_F)
-            tmp[i/VLEN_F] = (*(__global float4 *)(src_data+yOff+x+i));
+        else
+            for(int i=0; i < tileSize_width; i+=VLEN_F)
+                tmp[i/VLEN_F] = (float4)(*(src_data+(y+lidy)*src_step/4+x+i),*(src_data+(y+lidy)*src_step/4+x+i+1),*(src_data+(y+lidy)*src_step/4+x+i+2),*(src_data+(y+lidy)*src_step/4+x+i+3));
+    }
+
     float4 zero = (float4)(0);
     float4 full = (float4)(255);
     if( binary )
@@ -688,10 +708,9 @@ __kernel void CvMoments_D5( __global float* src_data, int src_rows, int src_cols
             tmp[i/VLEN_F] = (tmp[i/VLEN_F]!=zero)?full:zero;
     F mom[10];
     __local F m[10][128];
-    if(lidy == 0)
+    if(lidy < 128)
         for(int i = 0; i < 10; i ++)
-            for(int j = 0; j < 128; j ++)
-                m[i][j] = 0;
+            m[i][lidy] = 0;
     barrier(CLK_LOCAL_MEM_FENCE);
     F lm[10] = {0};
     F4 x0 = (F4)(0);
@@ -770,66 +789,42 @@ __kernel void CvMoments_D5( __global float* src_data, int src_rows, int src_cols
         // accumulate moments computed in each tile
         dst_step /= sizeof(F);
 
-        int dst_x_off = mad24(wgidy, dst_cols, wgidx);
-        int dst_off = 0;
-        int max_dst_index = 10 * blocky * get_global_size(1);
-
         // + m00 ( = m00' )
-        dst_off = mad24(DST_ROW_00 * blocky, dst_step, dst_x_off);
-        if (dst_off < max_dst_index)
-            *(dst_m + dst_off) = mom[0];
+        *(dst_m + mad24(DST_ROW_00 * blocky, dst_step, mad24(wgidy, dst_cols, wgidx))) = mom[0];
 
         // + m10 ( = m10' + x*m00' )
-        dst_off = mad24(DST_ROW_10 * blocky, dst_step, dst_x_off);
-        if (dst_off < max_dst_index)
-            *(dst_m + dst_off) = mom[1] + xm;
+        *(dst_m + mad24(DST_ROW_10 * blocky, dst_step, mad24(wgidy, dst_cols, wgidx))) = mom[1] + xm;
 
         // + m01 ( = m01' + y*m00' )
-        dst_off = mad24(DST_ROW_01 * blocky, dst_step, dst_x_off);
-        if (dst_off < max_dst_index)
-            *(dst_m + dst_off) = mom[2] + ym;
+        *(dst_m + mad24(DST_ROW_01 * blocky, dst_step, mad24(wgidy, dst_cols, wgidx))) = mom[2] + ym;
 
         // + m20 ( = m20' + 2*x*m10' + x*x*m00' )
-        dst_off = mad24(DST_ROW_20 * blocky, dst_step, dst_x_off);
-        if (dst_off < max_dst_index)
-            *(dst_m + dst_off) = mom[3] + x * (mom[1] * 2 + xm);
+        *(dst_m + mad24(DST_ROW_20 * blocky, dst_step, mad24(wgidy, dst_cols, wgidx))) = mom[3] + x * (mom[1] * 2 + xm);
 
         // + m11 ( = m11' + x*m01' + y*m10' + x*y*m00' )
-        dst_off = mad24(DST_ROW_11 * blocky, dst_step, dst_x_off);
-        if (dst_off < max_dst_index)
-            *(dst_m + dst_off) = mom[4] + x * (mom[2] + ym) + y * mom[1];
+        *(dst_m + mad24(DST_ROW_11 * blocky, dst_step, mad24(wgidy, dst_cols, wgidx))) = mom[4] + x * (mom[2] + ym) + y * mom[1];
 
         // + m02 ( = m02' + 2*y*m01' + y*y*m00' )
-        dst_off = mad24(DST_ROW_02 * blocky, dst_step, dst_x_off);
-        if (dst_off < max_dst_index)
-            *(dst_m + dst_off) = mom[5] + y * (mom[2] * 2 + ym);
+        *(dst_m + mad24(DST_ROW_02 * blocky, dst_step, mad24(wgidy, dst_cols, wgidx))) = mom[5] + y * (mom[2] * 2 + ym);
 
         // + m30 ( = m30' + 3*x*m20' + 3*x*x*m10' + x*x*x*m00' )
-        dst_off = mad24(DST_ROW_30 * blocky, dst_step, dst_x_off);
-        if (dst_off < max_dst_index)
-            *(dst_m + dst_off) = mom[6] + x * (3. * mom[3] + x * (3. * mom[1] + xm));
+        *(dst_m + mad24(DST_ROW_30 * blocky, dst_step, mad24(wgidy, dst_cols, wgidx))) = mom[6] + x * (3. * mom[3] + x * (3. * mom[1] + xm));
 
         // + m21 ( = m21' + x*(2*m11' + 2*y*m10' + x*m01' + x*y*m00') + y*m20')
-        dst_off = mad24(DST_ROW_21 * blocky, dst_step, dst_x_off);
-        if (dst_off < max_dst_index)
-            *(dst_m + dst_off) = mom[7] + x * (2 * (mom[4] + y * mom[1]) + x * (mom[2] + ym)) + y * mom[3];
+        *(dst_m + mad24(DST_ROW_21 * blocky, dst_step, mad24(wgidy, dst_cols, wgidx))) = mom[7] + x * (2 * (mom[4] + y * mom[1]) + x * (mom[2] + ym)) + y * mom[3];
 
         // + m12 ( = m12' + y*(2*m11' + 2*x*m01' + y*m10' + x*y*m00') + x*m02')
-        dst_off = mad24(DST_ROW_12 * blocky, dst_step, dst_x_off);
-        if (dst_off < max_dst_index)
-            *(dst_m + dst_off) = mom[8] + y * (2 * (mom[4] + x * mom[2]) + y * (mom[1] + xm)) + x * mom[5];
+        *(dst_m + mad24(DST_ROW_12 * blocky, dst_step, mad24(wgidy, dst_cols, wgidx))) = mom[8] + y * (2 * (mom[4] + x * mom[2]) + y * (mom[1] + xm)) + x * mom[5];
 
         // + m03 ( = m03' + 3*y*m02' + 3*y*y*m01' + y*y*y*m00' )
-        dst_off = mad24(DST_ROW_03 * blocky, dst_step, dst_x_off);
-        if (dst_off < max_dst_index)
-            *(dst_m + dst_off) = mom[9] + y * (3. * mom[5] + y * (3. * mom[2] + ym));
+        *(dst_m + mad24(DST_ROW_03 * blocky, dst_step, mad24(wgidy, dst_cols, wgidx))) = mom[9] + y * (3. * mom[5] + y * (3. * mom[2] + ym));
     }
 }
 
-__kernel void CvMoments_D6(__global F* src_data,  int src_rows, int src_cols, int src_step, int tileSize_width, int tileSize_height,
+__kernel void CvMoments_D6(__global F* src_data,  int src_rows, int src_cols, int src_step,
                            __global F* dst_m,
                            int dst_cols, int dst_step, int blocky,
-                           int type, int depth, int cn, int coi, int binary, const int TILE_SIZE)
+                           int depth, int cn, int coi, int binary, const int TILE_SIZE)
 {
     F tmp_coi[4]; // get the coi data
     F4 tmp[64];
@@ -844,22 +839,26 @@ __kernel void CvMoments_D6(__global F* src_data,  int src_rows, int src_cols, in
     int x = wgidx*TILE_SIZE;  // real X index of pixel
     int kcn = (cn==2)?2:4;
     int rstep = min(src_step/8, TILE_SIZE);
-    tileSize_height = min(TILE_SIZE,  src_rows - y);
-    tileSize_width = min(TILE_SIZE, src_cols - x);
+    int tileSize_height = min(TILE_SIZE,  src_rows - y);
+    int tileSize_width = min(TILE_SIZE, src_cols - x);
+
+    if ( y+lidy < src_rows )
+    {
+        if(tileSize_width < TILE_SIZE)
+            for(int i = tileSize_width; i < rstep && (x+i) < src_cols; i++ )
+                *((__global F*)src_data+(y+lidy)*src_step/8+x+i) = 0;
+        if( coi > 0 )
+            for(int i=0; i < tileSize_width; i+=VLEN_D)
+            {
+                for(int j=0; j<4 && ((x+i+j)*kcn+coi-1)<src_cols; j++)
+                    tmp_coi[j] = *(src_data+(y+lidy)*src_step/8+(x+i+j)*kcn+coi-1);
+                tmp[i/VLEN_D] = (F4)(tmp_coi[0],tmp_coi[1],tmp_coi[2],tmp_coi[3]);
+            }
+        else
+            for(int i=0; i < tileSize_width && (x+i+3) < src_cols; i+=VLEN_D)
+                tmp[i/VLEN_D] = (F4)(*(src_data+(y+lidy)*src_step/8+x+i),*(src_data+(y+lidy)*src_step/8+x+i+1),*(src_data+(y+lidy)*src_step/8+x+i+2),*(src_data+(y+lidy)*src_step/8+x+i+3));
+    }
 
-    if(tileSize_width < TILE_SIZE)
-        for(int i = tileSize_width; i < rstep; i++ )
-            *((__global F*)src_data+(y+lidy)*src_step/8+x+i) = 0;
-    if( coi > 0 )
-        for(int i=0; i < tileSize_width; i+=VLEN_D)
-        {
-            for(int j=0; j<4; j++)
-                tmp_coi[j] = *(src_data+(y+lidy)*src_step/8+(x+i+j)*kcn+coi-1);
-            tmp[i/VLEN_D] = (F4)(tmp_coi[0],tmp_coi[1],tmp_coi[2],tmp_coi[3]);
-        }
-    else
-        for(int i=0; i < tileSize_width; i+=VLEN_D)
-            tmp[i/VLEN_D] = (F4)(*(src_data+(y+lidy)*src_step/8+x+i),*(src_data+(y+lidy)*src_step/8+x+i+1),*(src_data+(y+lidy)*src_step/8+x+i+2),*(src_data+(y+lidy)*src_step/8+x+i+3));
     F4 zero = (F4)(0);
     F4 full = (F4)(255);
     if( binary )
@@ -867,10 +866,9 @@ __kernel void CvMoments_D6(__global F* src_data,  int src_rows, int src_cols, in
             tmp[i/VLEN_D] = (tmp[i/VLEN_D]!=zero)?full:zero;
     F mom[10];
     __local F m[10][128];
-    if(lidy == 0)
+    if(lidy < 128)
         for(int i=0; i<10; i++)
-            for(int j=0; j<128; j++)
-                m[i][j]=0;
+            m[i][lidy]=0;
     barrier(CLK_LOCAL_MEM_FENCE);
     F lm[10] = {0};
     F4 x0 = (F4)(0);
@@ -907,7 +905,6 @@ __kernel void CvMoments_D6(__global F* src_data,  int src_rows, int src_cols, in
         m[1][lidy-bheight] = x1.s0;             // m10
         m[0][lidy-bheight] = x0.s0;             // m00
     }
-
     else if(lidy < bheight)
     {
         lm[9] = ((F)py) * sy;  // m03
@@ -922,6 +919,7 @@ __kernel void CvMoments_D6(__global F* src_data,  int src_rows, int src_cols, in
         lm[0] = x0.s0;             // m00
     }
     barrier(CLK_LOCAL_MEM_FENCE);
+
     for( int j = TILE_SIZE/2; j >= 1; j = j/2 )
     {
         if(lidy < j)
index 8852fac..0363227 100644 (file)
@@ -43,7 +43,6 @@
 //
 //M*/
 
-
 #define CELL_WIDTH 8
 #define CELL_HEIGHT 8
 #define CELLS_PER_BLOCK_X 2
 //----------------------------------------------------------------------------
 // Histogram computation
 // 12 threads for a cell, 12x4 threads per block
-__kernel void compute_hists_kernel(
+// Use pre-computed gaussian and interp_weight lookup tables
+__kernel void compute_hists_lut_kernel(
     const int cblock_stride_x, const int cblock_stride_y,
     const int cnbins, const int cblock_hist_size, const int img_block_width, 
     const int blocks_in_group, const int blocks_total,
     const int grad_quadstep, const int qangle_step,
     __global const float* grad, __global const uchar* qangle,
-    const float scale, __global float* block_hists, __local float* smem)
+    __global const float* gauss_w_lut,
+    __global float* block_hists, __local float* smem)
 {
     const int lx = get_local_id(0);
     const int lp = lx / 24; /* local group id */
@@ -107,10 +108,10 @@ __kernel void compute_hists_kernel(
 
         int dist_center_y = dist_y - 4 * (1 - 2 * cell_y);
 
-        float gaussian = exp(-(dist_center_y * dist_center_y + dist_center_x * 
-            dist_center_x) * scale);
-        float interp_weight = (8.f - fabs(dist_y + 0.5f)) * 
-            (8.f - fabs(dist_x + 0.5f)) / 64.f;
+        int idx = (dist_center_y + 8) * 16 + (dist_center_x + 8);
+        float gaussian = gauss_w_lut[idx];
+        idx = (dist_y + 8) * 16 + (dist_x + 8);
+        float interp_weight = gauss_w_lut[256+idx];
 
         hist[bin.x * 48] += gaussian * interp_weight * vote.x;
         hist[bin.y * 48] += gaussian * interp_weight * vote.y;
@@ -125,14 +126,14 @@ __kernel void compute_hists_kernel(
         barrier(CLK_LOCAL_MEM_FENCE);
         if (cell_thread_x < 3)
             hist_[0] += hist_[3];
-#ifdef WAVE_SIZE_1
+#ifdef CPU
         barrier(CLK_LOCAL_MEM_FENCE);
 #endif
         if (cell_thread_x == 0)
             final_hist[(cell_x * 2 + cell_y) * cnbins + bin_id] = 
                 hist_[0] + hist_[1] + hist_[2];
     }
-#ifdef WAVE_SIZE_1
+#ifdef CPU
     barrier(CLK_LOCAL_MEM_FENCE);
 #endif
 
@@ -147,82 +148,111 @@ __kernel void compute_hists_kernel(
 
 //-------------------------------------------------------------
 //  Normalization of histograms via L2Hys_norm
+//  optimized for the case of 9 bins
+__kernel void normalize_hists_36_kernel(__global float* block_hists, 
+                                        const float threshold, __local float *squares)
+{
+    const int tid = get_local_id(0);
+    const int gid = get_global_id(0);
+    const int bid = tid / 36;      /* block-hist id, (0 - 6) */
+    const int boffset = bid * 36;  /* block-hist offset in the work-group */
+    const int hid = tid - boffset; /* histogram bin id, (0 - 35) */
+
+    float elem = block_hists[gid];
+    squares[tid] = elem * elem;
+    barrier(CLK_LOCAL_MEM_FENCE);
+
+    __local float* smem = squares + boffset;
+    float sum = smem[hid];
+    if (hid < 18)
+        smem[hid] = sum = sum + smem[hid + 18];
+    barrier(CLK_LOCAL_MEM_FENCE);
+    if (hid < 9)
+        smem[hid] = sum = sum + smem[hid + 9];
+    barrier(CLK_LOCAL_MEM_FENCE);
+    if (hid < 4)
+        smem[hid] = sum + smem[hid + 4];
+    barrier(CLK_LOCAL_MEM_FENCE);
+    sum = smem[0] + smem[1] + smem[2] + smem[3] + smem[8];
+
+    elem = elem / (sqrt(sum) + 3.6f);
+    elem = min(elem, threshold);
+
+    barrier(CLK_LOCAL_MEM_FENCE);
+    squares[tid] = elem * elem;
+    barrier(CLK_LOCAL_MEM_FENCE);
+
+    sum = smem[hid];
+    if (hid < 18)
+      smem[hid] = sum = sum + smem[hid + 18];
+    barrier(CLK_LOCAL_MEM_FENCE);
+    if (hid < 9)
+        smem[hid] = sum = sum + smem[hid + 9];
+    barrier(CLK_LOCAL_MEM_FENCE);
+    if (hid < 4)
+        smem[hid] = sum + smem[hid + 4];
+    barrier(CLK_LOCAL_MEM_FENCE);
+    sum = smem[0] + smem[1] + smem[2] + smem[3] + smem[8];
+
+    block_hists[gid] = elem / (sqrt(sum) + 1e-3f);
+}
+
+//-------------------------------------------------------------
+//  Normalization of histograms via L2Hys_norm
 //
 float reduce_smem(volatile __local float* smem, int size)
 {
     unsigned int tid = get_local_id(0);
     float sum = smem[tid];
 
-    if (size >= 512)
-    {
-        if (tid < 256) smem[tid] = sum = sum + smem[tid + 256];
-        barrier(CLK_LOCAL_MEM_FENCE);
-    }
-    if (size >= 256)
-    {
-        if (tid < 128) smem[tid] = sum = sum + smem[tid + 128];
-        barrier(CLK_LOCAL_MEM_FENCE);
-    }
-    if (size >= 128)
-    {
-        if (tid < 64) smem[tid] = sum = sum + smem[tid + 64];
-        barrier(CLK_LOCAL_MEM_FENCE);
-    }
-
+    if (size >= 512) { if (tid < 256) smem[tid] = sum = sum + smem[tid + 256]; 
+        barrier(CLK_LOCAL_MEM_FENCE); }
+    if (size >= 256) { if (tid < 128) smem[tid] = sum = sum + smem[tid + 128]; 
+        barrier(CLK_LOCAL_MEM_FENCE); }
+    if (size >= 128) { if (tid < 64) smem[tid] = sum = sum + smem[tid + 64]; 
+        barrier(CLK_LOCAL_MEM_FENCE); }
+#ifdef CPU
+    if (size >= 64) { if (tid < 32) smem[tid] = sum = sum + smem[tid + 32]; 
+        barrier(CLK_LOCAL_MEM_FENCE); }
+    if (size >= 32) { if (tid < 16) smem[tid] = sum = sum + smem[tid + 16]; 
+        barrier(CLK_LOCAL_MEM_FENCE); }        
+    if (size >= 16) { if (tid < 8) smem[tid] = sum = sum + smem[tid + 8]; 
+        barrier(CLK_LOCAL_MEM_FENCE); }
+    if (size >= 8) { if (tid < 4) smem[tid] = sum = sum + smem[tid + 4]; 
+        barrier(CLK_LOCAL_MEM_FENCE); }
+    if (size >= 4) { if (tid < 2) smem[tid] = sum = sum + smem[tid + 2]; 
+        barrier(CLK_LOCAL_MEM_FENCE); }                
+    if (size >= 2) { if (tid < 1) smem[tid] = sum = sum + smem[tid + 1]; 
+        barrier(CLK_LOCAL_MEM_FENCE); }
+#else
     if (tid < 32)
     {
         if (size >= 64) smem[tid] = sum = sum + smem[tid + 32];
-#if defined(WAVE_SIZE_16) || defined(WAVE_SIZE_1)
-    }
-    barrier(CLK_LOCAL_MEM_FENCE);
-    if (tid < 16)
-    {
+#if WAVE_SIZE < 32
+    } barrier(CLK_LOCAL_MEM_FENCE);
+    if (tid < 16) {
 #endif
         if (size >= 32) smem[tid] = sum = sum + smem[tid + 16];
-#ifdef WAVE_SIZE_1
-    }
-    barrier(CLK_LOCAL_MEM_FENCE);
-    if (tid < 8)
-    {
-#endif
         if (size >= 16) smem[tid] = sum = sum + smem[tid + 8];
-#ifdef WAVE_SIZE_1
-    }
-    barrier(CLK_LOCAL_MEM_FENCE);
-    if (tid < 4)
-    {
-#endif
         if (size >= 8) smem[tid] = sum = sum + smem[tid + 4];
-#ifdef WAVE_SIZE_1
-    }
-    barrier(CLK_LOCAL_MEM_FENCE);
-    if (tid < 2)
-    {
-#endif
         if (size >= 4) smem[tid] = sum = sum + smem[tid + 2];
-#ifdef WAVE_SIZE_1
-    }
-    barrier(CLK_LOCAL_MEM_FENCE);
-    if (tid < 1)
-    {
-#endif
         if (size >= 2) smem[tid] = sum = sum + smem[tid + 1];
     }
-
-    barrier(CLK_LOCAL_MEM_FENCE);
-    sum = smem[0];
+#endif
 
     return sum;
 }
 
-__kernel void normalize_hists_kernel(const int nthreads, const int block_hist_size, const int img_block_width,
-                                     __global float* block_hists, const float threshold, __local float *squares)
+__kernel void normalize_hists_kernel(
+    const int nthreads, const int block_hist_size, const int img_block_width,
+    __global float* block_hists, const float threshold, __local float *squares)
 {
     const int tid = get_local_id(0);
     const int gidX = get_group_id(0);
     const int gidY = get_group_id(1);
 
-    __global float* hist = block_hists + (gidY * img_block_width + gidX) * block_hist_size + tid;
+    __global float* hist = block_hists + (gidY * img_block_width + gidX) * 
+        block_hist_size + tid;
 
     float elem = 0.f;
     if (tid < block_hist_size)
@@ -249,100 +279,237 @@ __kernel void normalize_hists_kernel(const int nthreads, const int block_hist_si
 
 //---------------------------------------------------------------------
 //  Linear SVM based classification
-//
-__kernel void classify_hists_kernel(const int cblock_hist_size, const int cdescr_size, const int cdescr_width,
-                                    const int img_win_width, const int img_block_width,
-                                    const int win_block_stride_x, const int win_block_stride_y,
-                                    __global const float * block_hists, __global const float* coefs,
-                                    float free_coef, float threshold, __global uchar* labels)
+//  48x96 window, 9 bins and default parameters
+//  180 threads, each thread corresponds to a bin in a row
+__kernel void classify_hists_180_kernel(
+    const int cdescr_width, const int cdescr_height, const int cblock_hist_size,
+    const int img_win_width, const int img_block_width,
+    const int win_block_stride_x, const int win_block_stride_y,
+    __global const float * block_hists, __global const float* coefs,
+    float free_coef, float threshold, __global uchar* labels)
 {
     const int tid = get_local_id(0);
     const int gidX = get_group_id(0);
     const int gidY = get_group_id(1);
 
-    __global const float* hist = block_hists + (gidY * win_block_stride_y * img_block_width + gidX * win_block_stride_x) * cblock_hist_size;
+    __global const float* hist = block_hists + (gidY * win_block_stride_y * 
+        img_block_width + gidX * win_block_stride_x) * cblock_hist_size;
 
     float product = 0.f;
-    for (int i = tid; i < cdescr_size; i += NTHREADS)
+
+    for (int i = 0; i < cdescr_height; i++)
     {
-        int offset_y = i / cdescr_width;
-        int offset_x = i - offset_y * cdescr_width;
-        product += coefs[i] * hist[offset_y * img_block_width * cblock_hist_size + offset_x];
+        product += coefs[i * cdescr_width + tid] * 
+            hist[i * img_block_width * cblock_hist_size + tid];
     }
 
-    __local float products[NTHREADS];
+    __local float products[180];
 
     products[tid] = product;
 
     barrier(CLK_LOCAL_MEM_FENCE);
 
-    if (tid < 128) products[tid] = product = product + products[tid + 128];
+    if (tid < 90) products[tid] = product = product + products[tid + 90];
     barrier(CLK_LOCAL_MEM_FENCE);
 
-    if (tid < 64) products[tid] = product = product + products[tid + 64];
+    if (tid < 45) products[tid] = product = product + products[tid + 45];
     barrier(CLK_LOCAL_MEM_FENCE);
 
     volatile __local float* smem = products;
-    if (tid < 32)
+#ifdef CPU
+    if (tid < 13) smem[tid] = product = product + smem[tid + 32];
+       barrier(CLK_LOCAL_MEM_FENCE);
+    if (tid < 16) smem[tid] = product = product + smem[tid + 16];
+       barrier(CLK_LOCAL_MEM_FENCE);
+       if(tid<8) smem[tid] = product = product + smem[tid + 8];
+       barrier(CLK_LOCAL_MEM_FENCE);
+       if(tid<4) smem[tid] = product = product + smem[tid + 4];
+       barrier(CLK_LOCAL_MEM_FENCE);
+       if(tid<2) smem[tid] = product = product + smem[tid + 2];
+       barrier(CLK_LOCAL_MEM_FENCE);
+#else
+    if (tid < 13)
     {
         smem[tid] = product = product + smem[tid + 32];
-#if defined(WAVE_SIZE_16) || defined(WAVE_SIZE_1)
     }
+#if WAVE_SIZE < 32
     barrier(CLK_LOCAL_MEM_FENCE);
+#endif
     if (tid < 16)
     {
-#endif
         smem[tid] = product = product + smem[tid + 16];
-#ifdef WAVE_SIZE_1
+        smem[tid] = product = product + smem[tid + 8];
+        smem[tid] = product = product + smem[tid + 4];
+        smem[tid] = product = product + smem[tid + 2];
     }
-    barrier(CLK_LOCAL_MEM_FENCE);
-    if (tid < 8)
-    {
 #endif
-        smem[tid] = product = product + smem[tid + 8];
-#ifdef WAVE_SIZE_1
+
+    if (tid == 0){
+               product = product + smem[tid + 1];
+        labels[gidY * img_win_width + gidX] = (product + free_coef >= threshold);
+       }
+}
+
+//---------------------------------------------------------------------
+//  Linear SVM based classification
+//  64x128 window, 9 bins and default parameters
+//  256 threads, 252 of them are used
+__kernel void classify_hists_252_kernel(
+    const int cdescr_width, const int cdescr_height, const int cblock_hist_size,
+    const int img_win_width, const int img_block_width,
+    const int win_block_stride_x, const int win_block_stride_y,
+    __global const float * block_hists, __global const float* coefs,
+    float free_coef, float threshold, __global uchar* labels)
+{
+    const int tid = get_local_id(0);
+    const int gidX = get_group_id(0);
+    const int gidY = get_group_id(1);
+
+    __global const float* hist = block_hists + (gidY * win_block_stride_y * 
+        img_block_width + gidX * win_block_stride_x) * cblock_hist_size;
+
+    float product = 0.f;
+    if (tid < cdescr_width)
+    {
+        for (int i = 0; i < cdescr_height; i++)
+            product += coefs[i * cdescr_width + tid] * 
+                hist[i * img_block_width * cblock_hist_size + tid];
     }
+
+    __local float products[NTHREADS];
+
+    products[tid] = product;
+
     barrier(CLK_LOCAL_MEM_FENCE);
-    if (tid < 4)
-    {
+
+    if (tid < 128) products[tid] = product = product + products[tid + 128];
+    barrier(CLK_LOCAL_MEM_FENCE);
+
+    if (tid < 64) products[tid] = product = product + products[tid + 64];
+    barrier(CLK_LOCAL_MEM_FENCE);
+
+       volatile __local float* smem = products;
+#ifdef CPU
+       if(tid<32) smem[tid] = product = product + smem[tid + 32];
+       barrier(CLK_LOCAL_MEM_FENCE);
+       if(tid<16) smem[tid] = product = product + smem[tid + 16];
+       barrier(CLK_LOCAL_MEM_FENCE);
+       if(tid<8) smem[tid] = product = product + smem[tid + 8];
+       barrier(CLK_LOCAL_MEM_FENCE);
+       if(tid<4) smem[tid] = product = product + smem[tid + 4];
+       barrier(CLK_LOCAL_MEM_FENCE);
+       if(tid<2) smem[tid] = product = product + smem[tid + 2];
+       barrier(CLK_LOCAL_MEM_FENCE);
+#else
+    if (tid < 32)
+    {      
+        smem[tid] = product = product + smem[tid + 32];
+#if WAVE_SIZE < 32
+    } barrier(CLK_LOCAL_MEM_FENCE);
+    if (tid < 16) {
 #endif
+        smem[tid] = product = product + smem[tid + 16];
+        smem[tid] = product = product + smem[tid + 8];
         smem[tid] = product = product + smem[tid + 4];
-#ifdef WAVE_SIZE_1
+        smem[tid] = product = product + smem[tid + 2];
     }
-    barrier(CLK_LOCAL_MEM_FENCE);
-    if (tid < 2)
-    {
 #endif
-        smem[tid] = product = product + smem[tid + 2];
-#ifdef WAVE_SIZE_1
+    if (tid == 0){
+               product = product + smem[tid + 1];
+        labels[gidY * img_win_width + gidX] = (product + free_coef >= threshold);
+       }
+}
+
+//---------------------------------------------------------------------
+//  Linear SVM based classification
+//  256 threads
+__kernel void classify_hists_kernel(
+    const int cdescr_size, const int cdescr_width, const int cblock_hist_size,
+    const int img_win_width, const int img_block_width,
+    const int win_block_stride_x, const int win_block_stride_y,
+    __global const float * block_hists, __global const float* coefs,
+    float free_coef, float threshold, __global uchar* labels)
+{
+    const int tid = get_local_id(0);
+    const int gidX = get_group_id(0);
+    const int gidY = get_group_id(1);
+
+    __global const float* hist = block_hists + (gidY * win_block_stride_y * 
+        img_block_width + gidX * win_block_stride_x) * cblock_hist_size;
+
+    float product = 0.f;
+    for (int i = tid; i < cdescr_size; i += NTHREADS)
+    {
+        int offset_y = i / cdescr_width;
+        int offset_x = i - offset_y * cdescr_width;
+        product += coefs[i] * 
+            hist[offset_y * img_block_width * cblock_hist_size + offset_x];
     }
+
+    __local float products[NTHREADS];
+
+    products[tid] = product;
+
     barrier(CLK_LOCAL_MEM_FENCE);
-    if (tid < 1)
-    {
+
+    if (tid < 128) products[tid] = product = product + products[tid + 128];
+    barrier(CLK_LOCAL_MEM_FENCE);
+
+    if (tid < 64) products[tid] = product = product + products[tid + 64];
+    barrier(CLK_LOCAL_MEM_FENCE);
+
+       volatile __local float* smem = products;
+#ifdef CPU
+       if(tid<32) smem[tid] = product = product + smem[tid + 32];
+       barrier(CLK_LOCAL_MEM_FENCE);
+       if(tid<16) smem[tid] = product = product + smem[tid + 16];
+       barrier(CLK_LOCAL_MEM_FENCE);
+       if(tid<8) smem[tid] = product = product + smem[tid + 8];
+       barrier(CLK_LOCAL_MEM_FENCE);
+       if(tid<4) smem[tid] = product = product + smem[tid + 4];
+       barrier(CLK_LOCAL_MEM_FENCE);
+       if(tid<2) smem[tid] = product = product + smem[tid + 2];
+       barrier(CLK_LOCAL_MEM_FENCE);
+#else
+    if (tid < 32)
+    {       
+        smem[tid] = product = product + smem[tid + 32];
+#if WAVE_SIZE < 32
+    } barrier(CLK_LOCAL_MEM_FENCE);
+    if (tid < 16) {
 #endif
-        smem[tid] = product = product + smem[tid + 1];
+        smem[tid] = product = product + smem[tid + 16];
+        smem[tid] = product = product + smem[tid + 8];
+        smem[tid] = product = product + smem[tid + 4];
+        smem[tid] = product = product + smem[tid + 2];
     }
-
-    if (tid == 0)
+#endif
+    if (tid == 0){
+               smem[tid] = product = product + smem[tid + 1];
         labels[gidY * img_win_width + gidX] = (product + free_coef >= threshold);
+       }
 }
 
 //----------------------------------------------------------------------------
 // Extract descriptors
 
-__kernel void extract_descrs_by_rows_kernel(const int cblock_hist_size, const int descriptors_quadstep, const int cdescr_size, const int cdescr_width,
-        const int img_block_width, const int win_block_stride_x, const int win_block_stride_y,
-        __global const float* block_hists, __global float* descriptors)
+__kernel void extract_descrs_by_rows_kernel(
+    const int cblock_hist_size, const int descriptors_quadstep, 
+    const int cdescr_size, const int cdescr_width, const int img_block_width, 
+    const int win_block_stride_x, const int win_block_stride_y,
+    __global const float* block_hists, __global float* descriptors)
 {
     int tid = get_local_id(0);
     int gidX = get_group_id(0);
     int gidY = get_group_id(1);
 
     // Get left top corner of the window in src
-    __global const float* hist = block_hists + (gidY * win_block_stride_y * img_block_width + gidX * win_block_stride_x) * cblock_hist_size;
+    __global const float* hist = block_hists + (gidY * win_block_stride_y * 
+        img_block_width + gidX * win_block_stride_x) * cblock_hist_size;
 
     // Get left top corner of the window in dst
-    __global float* descriptor = descriptors + (gidY * get_num_groups(0) + gidX) * descriptors_quadstep;
+    __global float* descriptor = descriptors + 
+        (gidY * get_num_groups(0) + gidX) * descriptors_quadstep;
 
     // Copy elements from src to dst
     for (int i = tid; i < cdescr_size; i += NTHREADS)
@@ -353,19 +520,23 @@ __kernel void extract_descrs_by_rows_kernel(const int cblock_hist_size, const in
     }
 }
 
-__kernel void extract_descrs_by_cols_kernel(const int cblock_hist_size, const int descriptors_quadstep, const int cdescr_size,
-        const int cnblocks_win_x, const int cnblocks_win_y, const int img_block_width, const int win_block_stride_x,
-        const int win_block_stride_y, __global const float* block_hists, __global float* descriptors)
+__kernel void extract_descrs_by_cols_kernel(
+    const int cblock_hist_size, const int descriptors_quadstep, const int cdescr_size,
+    const int cnblocks_win_x, const int cnblocks_win_y, const int img_block_width, 
+    const int win_block_stride_x, const int win_block_stride_y, 
+    __global const float* block_hists, __global float* descriptors)
 {
     int tid = get_local_id(0);
     int gidX = get_group_id(0);
     int gidY = get_group_id(1);
 
     // Get left top corner of the window in src
-    __global const float* hist = block_hists + (gidY * win_block_stride_y * img_block_width + gidX * win_block_stride_x) * cblock_hist_size;
+    __global const float* hist = block_hists +  (gidY * win_block_stride_y * 
+        img_block_width + gidX * win_block_stride_x) * cblock_hist_size;
 
     // Get left top corner of the window in dst
-    __global float* descriptor = descriptors + (gidY * get_num_groups(0) + gidX) * descriptors_quadstep;
+    __global float* descriptor = descriptors + 
+        (gidY * get_num_groups(0) + gidX) * descriptors_quadstep;
 
     // Copy elements from src to dst
     for (int i = tid; i < cdescr_size; i += NTHREADS)
@@ -376,16 +547,19 @@ __kernel void extract_descrs_by_cols_kernel(const int cblock_hist_size, const in
         int y = block_idx / cnblocks_win_x;
         int x = block_idx - y * cnblocks_win_x;
 
-        descriptor[(x * cnblocks_win_y + y) * cblock_hist_size + idx_in_block] = hist[(y * img_block_width  + x) * cblock_hist_size + idx_in_block];
+        descriptor[(x * cnblocks_win_y + y) * cblock_hist_size + idx_in_block] = 
+            hist[(y * img_block_width  + x) * cblock_hist_size + idx_in_block];
     }
 }
 
 //----------------------------------------------------------------------------
 // Gradients computation
 
-__kernel void compute_gradients_8UC4_kernel(const int height, const int width, const int img_step, const int grad_quadstep, const int qangle_step,
-        const __global uchar4 * img, __global float * grad, __global uchar * qangle,
-        const float angle_scale, const char correct_gamma, const int cnbins)
+__kernel void compute_gradients_8UC4_kernel(
+    const int height, const int width, 
+    const int img_step, const int grad_quadstep, const int qangle_step,
+    const __global uchar4 * img, __global float * grad, __global uchar * qangle,
+    const float angle_scale, const char correct_gamma, const int cnbins)
 {
     const int x = get_global_id(0);
     const int tid = get_local_id(0);
@@ -426,8 +600,10 @@ __kernel void compute_gradients_8UC4_kernel(const int height, const int width, c
     barrier(CLK_LOCAL_MEM_FENCE);
     if (x < width)
     {
-        float3 a = (float3) (sh_row[tid], sh_row[tid + (NTHREADS + 2)], sh_row[tid + 2 * (NTHREADS + 2)]);
-        float3 b = (float3) (sh_row[tid + 2], sh_row[tid + 2 + (NTHREADS + 2)], sh_row[tid + 2 + 2 * (NTHREADS + 2)]);
+        float3 a = (float3) (sh_row[tid], sh_row[tid + (NTHREADS + 2)], 
+            sh_row[tid + 2 * (NTHREADS + 2)]);
+        float3 b = (float3) (sh_row[tid + 2], sh_row[tid + 2 + (NTHREADS + 2)], 
+            sh_row[tid + 2 + 2 * (NTHREADS + 2)]);
 
         float3 dx;
         if (correct_gamma == 1)
@@ -482,9 +658,11 @@ __kernel void compute_gradients_8UC4_kernel(const int height, const int width, c
     }
 }
 
-__kernel void compute_gradients_8UC1_kernel(const int height, const int width, const int img_step, const int grad_quadstep, const int qangle_step,
-        __global const uchar * img, __global float * grad, __global uchar * qangle,
-        const float angle_scale, const char correct_gamma, const int cnbins)
+__kernel void compute_gradients_8UC1_kernel(
+    const int height, const int width, 
+    const int img_step, const int grad_quadstep, const int qangle_step,
+    __global const uchar * img, __global float * grad, __global uchar * qangle,
+    const float angle_scale, const char correct_gamma, const int cnbins)
 {
     const int x = get_global_id(0);
     const int tid = get_local_id(0);
@@ -539,43 +717,4 @@ __kernel void compute_gradients_8UC1_kernel(const int height, const int width, c
         grad[ (gidY * grad_quadstep + x) << 1 ]       = mag * (1.f - ang);
         grad[ ((gidY * grad_quadstep + x) << 1) + 1 ]   = mag * ang;
     }
-}
-
-//----------------------------------------------------------------------------
-// Resize
-
-__kernel void resize_8UC4_kernel(__global uchar4 * dst, __global const uchar4 * src,
-                                 int dst_offset, int src_offset, int dst_step, int src_step,
-                                 int src_cols, int src_rows, int dst_cols, int dst_rows, float ifx, float ify )
-{
-    int dx = get_global_id(0);
-    int dy = get_global_id(1);
-
-    int sx = (int)floor(dx*ifx+0.5f);
-    int sy = (int)floor(dy*ify+0.5f);
-    sx = min(sx, src_cols-1);
-    sy = min(sy, src_rows-1);
-    int dpos = (dst_offset>>2) + dy * (dst_step>>2) + dx;
-    int spos = (src_offset>>2) + sy * (src_step>>2) + sx;
-
-    if(dx<dst_cols && dy<dst_rows)
-        dst[dpos] = src[spos];
-}
-
-__kernel void resize_8UC1_kernel(__global uchar * dst, __global const uchar * src,
-                                 int dst_offset, int src_offset, int dst_step, int src_step,
-                                 int src_cols, int src_rows, int dst_cols, int dst_rows, float ifx, float ify )
-{
-    int dx = get_global_id(0);
-    int dy = get_global_id(1);
-
-    int sx = (int)floor(dx*ifx+0.5f);
-    int sy = (int)floor(dy*ify+0.5f);
-    sx = min(sx, src_cols-1);
-    sy = min(sy, src_rows-1);
-    int dpos = dst_offset + dy * dst_step + dx;
-    int spos = src_offset + sy * src_step + sx;
-
-    if(dx<dst_cols && dy<dst_rows)
-        dst[dpos] = src[spos];
 }
\ No newline at end of file
diff --git a/modules/ocl/src/opencl/optical_flow_farneback.cl b/modules/ocl/src/opencl/optical_flow_farneback.cl
new file mode 100644 (file)
index 0000000..7cc564e
--- /dev/null
@@ -0,0 +1,450 @@
+/*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) 2010-2012, Multicoreware, Inc., all rights reserved.
+// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Sen Liu, swjtuls1987@126.com
+//
+// 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 oclMaterials 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*/
+
+
+#define tx  get_local_id(0)
+#define ty  get_local_id(1)
+#define bx  get_group_id(0)
+#define bdx get_local_size(0)
+
+#define BORDER_SIZE 5
+#define MAX_KSIZE_HALF 100
+
+#ifndef polyN
+#define polyN 5
+#endif
+
+__kernel void polynomialExpansion(__global float * dst,
+                                  __global __const float * src,
+                                  __global __const float * c_g,
+                                  __global __const float * c_xg,
+                                  __global __const float * c_xxg,
+                                  __local float * smem,
+                                  const float4 ig,
+                                  const int height, const int width,
+                                  int dstStep, int srcStep)
+{
+    const int y = get_global_id(1);
+    const int x = bx * (bdx - 2*polyN) + tx - polyN;
+
+    dstStep /= sizeof(*dst);
+    srcStep /= sizeof(*src);
+
+    int xWarped;
+    __local float *row = smem + tx;
+
+    if (y < height && y >= 0)
+    {
+        xWarped = min(max(x, 0), width - 1);
+
+        row[0] = src[mad24(y, srcStep, xWarped)] * c_g[0];
+        row[bdx] = 0.f;
+        row[2*bdx] = 0.f;
+
+#pragma unroll
+        for (int k = 1; k <= polyN; ++k)
+        {
+            float t0 = src[mad24(max(y - k, 0), srcStep, xWarped)];
+            float t1 = src[mad24(min(y + k, height - 1), srcStep, xWarped)];
+
+            row[0] += c_g[k] * (t0 + t1);
+            row[bdx] += c_xg[k] * (t1 - t0);
+            row[2*bdx] += c_xxg[k] * (t0 + t1);
+        }
+    }
+
+    barrier(CLK_LOCAL_MEM_FENCE);
+
+    if (y < height && y >= 0 && tx >= polyN && tx + polyN < bdx && x < width)
+    {
+        float b1 = c_g[0] * row[0];
+        float b3 = c_g[0] * row[bdx];
+        float b5 = c_g[0] * row[2*bdx];
+        float b2 = 0, b4 = 0, b6 = 0;
+
+#pragma unroll
+        for (int k = 1; k <= polyN; ++k)
+        {
+            b1 += (row[k] + row[-k]) * c_g[k];
+            b4 += (row[k] + row[-k]) * c_xxg[k];
+            b2 += (row[k] - row[-k]) * c_xg[k];
+            b3 += (row[k + bdx] + row[-k + bdx]) * c_g[k];
+            b6 += (row[k + bdx] - row[-k + bdx]) * c_xg[k];
+            b5 += (row[k + 2*bdx] + row[-k + 2*bdx]) * c_g[k];
+        }
+
+        dst[mad24(y, dstStep, xWarped)] = b3*ig.s0;
+        dst[mad24(height + y, dstStep, xWarped)] = b2*ig.s0;
+        dst[mad24(2*height + y, dstStep, xWarped)] = b1*ig.s1 + b5*ig.s2;
+        dst[mad24(3*height + y, dstStep, xWarped)] = b1*ig.s1 + b4*ig.s2;
+        dst[mad24(4*height + y, dstStep, xWarped)] = b6*ig.s3;
+    }
+}
+
+inline int idx_row_low(const int y, const int last_row)
+{
+    return abs(y) % (last_row + 1);
+}
+
+inline int idx_row_high(const int y, const int last_row)
+{
+    return abs(last_row - abs(last_row - y)) % (last_row + 1);
+}
+
+inline int idx_row(const int y, const int last_row)
+{
+    return idx_row_low(idx_row_high(y, last_row), last_row);
+}
+
+inline int idx_col_low(const int x, const int last_col)
+{
+    return abs(x) % (last_col + 1);
+}
+
+inline int idx_col_high(const int x, const int last_col)
+{
+    return abs(last_col - abs(last_col - x)) % (last_col + 1);
+}
+
+inline int idx_col(const int x, const int last_col)
+{
+    return idx_col_low(idx_col_high(x, last_col), last_col);
+}
+
+__kernel void gaussianBlur(__global float * dst,
+                           __global const float * src,
+                           __global const float * c_gKer,
+                           __local float * smem,
+                           const int height,  const int width,
+                           int dstStep, int srcStep,
+                           const int ksizeHalf)
+{
+    const int y = get_global_id(1);
+    const int x = get_global_id(0);
+
+    dstStep /= sizeof(*dst);
+    srcStep /= sizeof(*src);
+
+    __local float *row = smem + ty * (bdx + 2*ksizeHalf);
+
+    if (y < height)
+    {
+        // Vertical pass
+        for (int i = tx; i < bdx + 2*ksizeHalf; i += bdx)
+        {
+            int xExt = (int)(bx * bdx) + i - ksizeHalf;
+            xExt = idx_col(xExt, width - 1);
+            row[i] = src[mad24(y, srcStep, xExt)] * c_gKer[0];
+            for (int j = 1; j <= ksizeHalf; ++j)
+                row[i] += (src[mad24(idx_row_low(y - j, height - 1), srcStep, xExt)]
+                           + src[mad24(idx_row_high(y + j, height - 1), srcStep, xExt)]) * c_gKer[j];
+        }
+    }
+
+    barrier(CLK_LOCAL_MEM_FENCE);
+
+    if (y < height && y >= 0 && x < width && x >= 0)
+    {
+        // Horizontal pass
+        row += tx + ksizeHalf;
+        float res = row[0] * c_gKer[0];
+        for (int i = 1; i <= ksizeHalf; ++i)
+            res += (row[-i] + row[i]) * c_gKer[i];
+
+        dst[mad24(y, dstStep, x)] = res;
+    }
+}
+
+__constant float c_border[BORDER_SIZE + 1] = { 0.14f, 0.14f, 0.4472f, 0.4472f, 0.4472f, 1.f };
+
+__kernel void updateMatrices(__global float * M,
+                             __global const float * flowx, __global const float * flowy,
+                             __global const float * R0, __global const float * R1,
+                             const int height, const int width,
+                             int mStep, int xStep,  int yStep, int R0Step, int R1Step)
+{
+    const int y = get_global_id(1);
+    const int x = get_global_id(0);
+
+    mStep /= sizeof(*M);
+    xStep /= sizeof(*flowx);
+    yStep /= sizeof(*flowy);
+    R0Step /= sizeof(*R0);
+    R1Step /= sizeof(*R1);
+
+    if (y < height && y >= 0 && x < width && x >= 0)
+    {
+        float dx = flowx[mad24(y, xStep, x)];
+        float dy = flowy[mad24(y, yStep, x)];
+        float fx = x + dx;
+        float fy = y + dy;
+
+        int x1 = convert_int(floor(fx));
+        int y1 = convert_int(floor(fy));
+        fx -= x1;
+        fy -= y1;
+
+        float r2, r3, r4, r5, r6;
+
+        if (x1 >= 0 && y1 >= 0 && x1 < width - 1 && y1 < height - 1)
+        {
+            float a00 = (1.f - fx) * (1.f - fy);
+            float a01 = fx * (1.f - fy);
+            float a10 = (1.f - fx) * fy;
+            float a11 = fx * fy;
+
+            r2 = a00 * R1[mad24(y1, R1Step, x1)] +
+                 a01 * R1[mad24(y1, R1Step, x1 + 1)] +
+                 a10 * R1[mad24(y1 + 1, R1Step, x1)] +
+                 a11 * R1[mad24(y1 + 1, R1Step, x1 + 1)];
+
+            r3 = a00 * R1[mad24(height + y1, R1Step, x1)] +
+                 a01 * R1[mad24(height + y1, R1Step, x1 + 1)] +
+                 a10 * R1[mad24(height + y1 + 1, R1Step, x1)] +
+                 a11 * R1[mad24(height + y1 + 1, R1Step, x1 + 1)];
+
+            r4 = a00 * R1[mad24(2*height + y1, R1Step, x1)] +
+                 a01 * R1[mad24(2*height + y1, R1Step, x1 + 1)] +
+                 a10 * R1[mad24(2*height + y1 + 1, R1Step, x1)] +
+                 a11 * R1[mad24(2*height + y1 + 1, R1Step, x1 + 1)];
+
+            r5 = a00 * R1[mad24(3*height + y1, R1Step, x1)] +
+                 a01 * R1[mad24(3*height + y1, R1Step, x1 + 1)] +
+                 a10 * R1[mad24(3*height + y1 + 1, R1Step, x1)] +
+                 a11 * R1[mad24(3*height + y1 + 1, R1Step, x1 + 1)];
+
+            r6 = a00 * R1[mad24(4*height + y1, R1Step, x1)] +
+                 a01 * R1[mad24(4*height + y1, R1Step, x1 + 1)] +
+                 a10 * R1[mad24(4*height + y1 + 1, R1Step, x1)] +
+                 a11 * R1[mad24(4*height + y1 + 1, R1Step, x1 + 1)];
+
+            r4 = (R0[mad24(2*height + y, R0Step, x)] + r4) * 0.5f;
+            r5 = (R0[mad24(3*height + y, R0Step, x)] + r5) * 0.5f;
+            r6 = (R0[mad24(4*height + y, R0Step, x)] + r6) * 0.25f;
+        }
+        else
+        {
+            r2 = r3 = 0.f;
+            r4 = R0[mad24(2*height + y, R0Step, x)];
+            r5 = R0[mad24(3*height + y, R0Step, x)];
+            r6 = R0[mad24(4*height + y, R0Step, x)] * 0.5f;
+        }
+
+        r2 = (R0[mad24(y, R0Step, x)] - r2) * 0.5f;
+        r3 = (R0[mad24(height + y, R0Step, x)] - r3) * 0.5f;
+
+        r2 += r4*dy + r6*dx;
+        r3 += r6*dy + r5*dx;
+
+        float scale =
+            c_border[min(x, BORDER_SIZE)] *
+            c_border[min(y, BORDER_SIZE)] *
+            c_border[min(width - x - 1, BORDER_SIZE)] *
+            c_border[min(height - y - 1, BORDER_SIZE)];
+
+        r2 *= scale;
+        r3 *= scale;
+        r4 *= scale;
+        r5 *= scale;
+        r6 *= scale;
+
+        M[mad24(y, mStep, x)] = r4*r4 + r6*r6;
+        M[mad24(height + y, mStep, x)] = (r4 + r5)*r6;
+        M[mad24(2*height + y, mStep, x)] = r5*r5 + r6*r6;
+        M[mad24(3*height + y, mStep, x)] = r4*r2 + r6*r3;
+        M[mad24(4*height + y, mStep, x)] = r6*r2 + r5*r3;
+    }
+}
+
+__kernel void boxFilter5(__global float * dst,
+                         __global const float * src,
+                         __local float * smem,
+                         const int height,  const int width,
+                         int dstStep, int srcStep,
+                         const int ksizeHalf)
+{
+    const int y = get_global_id(1);
+    const int x = get_global_id(0);
+
+    const float boxAreaInv = 1.f / ((1 + 2*ksizeHalf) * (1 + 2*ksizeHalf));
+    const int smw = bdx + 2*ksizeHalf; // shared memory "width"
+    __local float *row = smem + 5 * ty * smw;
+
+    dstStep /= sizeof(*dst);
+    srcStep /= sizeof(*src);
+
+    if (y < height)
+    {
+        // Vertical pass
+        for (int i = tx; i < bdx + 2*ksizeHalf; i += bdx)
+        {
+            int xExt = (int)(bx * bdx) + i - ksizeHalf;
+            xExt = min(max(xExt, 0), width - 1);
+
+#pragma unroll
+            for (int k = 0; k < 5; ++k)
+                row[k*smw + i] = src[mad24(k*height + y, srcStep, xExt)];
+
+            for (int j = 1; j <= ksizeHalf; ++j)
+#pragma unroll
+                for (int k = 0; k < 5; ++k)
+                    row[k*smw + i] +=
+                        src[mad24(k*height + max(y - j, 0), srcStep, xExt)] +
+                        src[mad24(k*height + min(y + j, height - 1), srcStep, xExt)];
+        }
+    }
+
+    barrier(CLK_LOCAL_MEM_FENCE);
+
+    if (y < height && y >= 0 && x < width && x >= 0)
+    {
+        // Horizontal pass
+
+        row += tx + ksizeHalf;
+        float res[5];
+
+#pragma unroll
+        for (int k = 0; k < 5; ++k)
+            res[k] = row[k*smw];
+
+        for (int i = 1; i <= ksizeHalf; ++i)
+#pragma unroll
+            for (int k = 0; k < 5; ++k)
+                res[k] += row[k*smw - i] + row[k*smw + i];
+
+#pragma unroll
+        for (int k = 0; k < 5; ++k)
+            dst[mad24(k*height + y, dstStep, x)] = res[k] * boxAreaInv;
+    }
+}
+
+__kernel void updateFlow(__global float4 * flowx, __global float4 * flowy,
+                         __global const float4 * M,
+                         const int height, const int width,
+                         int xStep, int yStep, int mStep)
+{
+    const int y = get_global_id(1);
+    const int x = get_global_id(0);
+
+    xStep /= sizeof(*flowx);
+    yStep /= sizeof(*flowy);
+    mStep /= sizeof(*M);
+
+    if (y < height && y >= 0 && x < width && x >= 0)
+    {
+        float4 g11 = M[mad24(y, mStep, x)];
+        float4 g12 = M[mad24(height + y, mStep, x)];
+        float4 g22 = M[mad24(2*height + y, mStep, x)];
+        float4 h1 =  M[mad24(3*height + y, mStep, x)];
+        float4 h2 =  M[mad24(4*height + y, mStep, x)];
+
+        float4 detInv = (float4)(1.f) / (g11*g22 - g12*g12 + (float4)(1e-3f));
+
+        flowx[mad24(y, xStep, x)] = (g11*h2 - g12*h1) * detInv;
+        flowy[mad24(y, yStep, x)] = (g22*h1 - g12*h2) * detInv;
+    }
+}
+
+__kernel void gaussianBlur5(__global float * dst,
+                            __global const float * src,
+                            __global const float * c_gKer,
+                            __local float * smem,
+                            const int height,  const int width,
+                            int dstStep, int srcStep,
+                            const int ksizeHalf)
+{
+    const int y = get_global_id(1);
+    const int x = get_global_id(0);
+
+    const int smw = bdx + 2*ksizeHalf; // shared memory "width"
+    __local volatile float *row = smem + 5 * ty * smw;
+
+    dstStep /= sizeof(*dst);
+    srcStep /= sizeof(*src);
+
+    if (y < height)
+    {
+        // Vertical pass
+        for (int i = tx; i < bdx + 2*ksizeHalf; i += bdx)
+        {
+            int xExt = (int)(bx * bdx) + i - ksizeHalf;
+            xExt = idx_col(xExt, width - 1);
+
+#pragma unroll
+            for (int k = 0; k < 5; ++k)
+                row[k*smw + i] = src[mad24(k*height + y, srcStep, xExt)] * c_gKer[0];
+
+            for (int j = 1; j <= ksizeHalf; ++j)
+#pragma unroll
+                for (int k = 0; k < 5; ++k)
+                    row[k*smw + i] +=
+                        (src[mad24(k*height + idx_row_low(y - j, height - 1), srcStep, xExt)] +
+                         src[mad24(k*height + idx_row_high(y + j, height - 1), srcStep, xExt)]) * c_gKer[j];
+        }
+    }
+
+    barrier(CLK_LOCAL_MEM_FENCE);
+
+    if (y < height && y >= 0 && x < width && x >= 0)
+    {
+        // Horizontal pass
+
+        row += tx + ksizeHalf;
+        float res[5];
+
+#pragma unroll
+        for (int k = 0; k < 5; ++k)
+            res[k] = row[k*smw] * c_gKer[0];
+
+        for (int i = 1; i <= ksizeHalf; ++i)
+#pragma unroll
+            for (int k = 0; k < 5; ++k)
+                res[k] += (row[k*smw - i] + row[k*smw + i]) * c_gKer[i];
+
+#pragma unroll
+        for (int k = 0; k < 5; ++k)
+            dst[mad24(k*height + y, dstStep, x)] = res[k];
+    }
+}
index 40a1993..02cf3af 100644 (file)
@@ -17,6 +17,7 @@
 // @Authors
 //    Dachuan Zhao, dachuan@multicorewareinc.com
 //    Yao Wang, bitwangyaoyao@gmail.com
+//    Xiaopeng Fu, fuxiaopeng2222@163.com
 //
 // Redistribution and use in source and binary forms, with or without modification,
 // are permitted provided that the following conditions are met:
@@ -47,6 +48,7 @@
 //#pragma OPENCL EXTENSION cl_amd_printf : enable
 
 #define        BUFFER  64
+#define        BUFFER2 BUFFER>>1
 #ifndef WAVE_SIZE
 #define WAVE_SIZE 1
 #endif
@@ -58,53 +60,16 @@ void reduce3(float val1, float val2, float val3,  __local float* smem1,  __local
     smem3[tid] = val3;
     barrier(CLK_LOCAL_MEM_FENCE);
 
-    if (tid < 32)
-    {
-        smem1[tid] += smem1[tid + 32];
-        smem2[tid] += smem2[tid + 32];
-        smem3[tid] += smem3[tid + 32];
-    }
-    barrier(CLK_LOCAL_MEM_FENCE);
-
-    if (tid < 16)
-    {
-        smem1[tid] += smem1[tid + 16];
-        smem2[tid] += smem2[tid + 16];
-        smem3[tid] += smem3[tid + 16];
-    }
-    barrier(CLK_LOCAL_MEM_FENCE);
-
-    if (tid < 8)
-    {
-        smem1[tid] += smem1[tid + 8];
-        smem2[tid] += smem2[tid + 8];
-        smem3[tid] += smem3[tid + 8];
-    }
-    barrier(CLK_LOCAL_MEM_FENCE);
-
-    if (tid < 4)
-    {
-        smem1[tid] += smem1[tid + 4];
-        smem2[tid] += smem2[tid + 4];
-        smem3[tid] += smem3[tid + 4];
-    }
-    barrier(CLK_LOCAL_MEM_FENCE);
-
-    if (tid < 2)
-    {
-        smem1[tid] += smem1[tid + 2];
-        smem2[tid] += smem2[tid + 2];
-        smem3[tid] += smem3[tid + 2];
-    }
-    barrier(CLK_LOCAL_MEM_FENCE);
-
-    if (tid < 1)
+    for(int i = BUFFER2; i > 0; i >>= 1)
     {
-        smem1[BUFFER] = smem1[tid] + smem1[tid + 1];
-        smem2[BUFFER] = smem2[tid] + smem2[tid + 1];
-        smem3[BUFFER] = smem3[tid] + smem3[tid + 1];
+        if(tid < i)
+        {
+            smem1[tid] += smem1[tid + i];
+            smem2[tid] += smem2[tid + i];
+            smem3[tid] += smem3[tid + i];
+        }
+        barrier(CLK_LOCAL_MEM_FENCE);
     }
-    barrier(CLK_LOCAL_MEM_FENCE);
 }
 
 void reduce2(float val1, float val2, volatile __local float* smem1, volatile __local float* smem2, int tid)
@@ -113,47 +78,15 @@ void reduce2(float val1, float val2, volatile __local float* smem1, volatile __l
     smem2[tid] = val2;
     barrier(CLK_LOCAL_MEM_FENCE);
 
-    if (tid < 32)
-    {
-        smem1[tid] += smem1[tid + 32];
-        smem2[tid] += smem2[tid + 32];
-    }
-    barrier(CLK_LOCAL_MEM_FENCE);
-
-    if (tid < 16)
+    for(int i = BUFFER2; i > 0; i >>= 1)
     {
-        smem1[tid] += smem1[tid + 16];
-        smem2[tid] += smem2[tid + 16];
-    }
-    barrier(CLK_LOCAL_MEM_FENCE);
-
-    if (tid < 8)
-    {
-        smem1[tid] += smem1[tid + 8];
-        smem2[tid] += smem2[tid + 8];
-    }
-    barrier(CLK_LOCAL_MEM_FENCE);
-
-    if (tid < 4)
-    {
-        smem1[tid] += smem1[tid + 4];
-        smem2[tid] += smem2[tid + 4];
-    }
-    barrier(CLK_LOCAL_MEM_FENCE);
-
-    if (tid < 2)
-    {
-        smem1[tid] += smem1[tid + 2];
-        smem2[tid] += smem2[tid + 2];
-    }
-    barrier(CLK_LOCAL_MEM_FENCE);
-
-    if (tid < 1)
-    {
-        smem1[BUFFER] = smem1[tid] + smem1[tid + 1];
-        smem2[BUFFER] = smem2[tid] + smem2[tid + 1];
+        if(tid < i)
+        {
+            smem1[tid] += smem1[tid + i];
+            smem2[tid] += smem2[tid + i];
+        }
+        barrier(CLK_LOCAL_MEM_FENCE);
     }
-    barrier(CLK_LOCAL_MEM_FENCE);
 }
 
 void reduce1(float val1, volatile __local float* smem1, int tid)
@@ -161,45 +94,18 @@ void reduce1(float val1, volatile __local float* smem1, int tid)
     smem1[tid] = val1;
     barrier(CLK_LOCAL_MEM_FENCE);
 
-    if (tid < 32)
+    for(int i = BUFFER2; i > 0; i >>= 1)
     {
-        smem1[tid] += smem1[tid + 32];
-    }
-    barrier(CLK_LOCAL_MEM_FENCE);
-
-    if (tid < 16)
-    {
-        smem1[tid] += smem1[tid + 16];
-    }
-    barrier(CLK_LOCAL_MEM_FENCE);
-
-    if (tid < 8)
-    {
-        smem1[tid] += smem1[tid + 8];
-    }
-    barrier(CLK_LOCAL_MEM_FENCE);
-
-    if (tid < 4)
-    {
-        smem1[tid] += smem1[tid + 4];
-    }
-    barrier(CLK_LOCAL_MEM_FENCE);
-
-    if (tid < 2)
-    {
-        smem1[tid] += smem1[tid + 2];
-    }
-    barrier(CLK_LOCAL_MEM_FENCE);
-
-    if (tid < 1)
-    {
-        smem1[BUFFER] = smem1[tid] + smem1[tid + 1];
+        if(tid < i)
+        {
+            smem1[tid] += smem1[tid + i];
+        }
+        barrier(CLK_LOCAL_MEM_FENCE);
     }
-    barrier(CLK_LOCAL_MEM_FENCE);
 }
 #else
-void reduce3(float val1, float val2, float val3, 
-__local volatile float* smem1, __local volatile float* smem2, __local volatile float* smem3, int tid)
+void reduce3(float val1, float val2, float val3,
+             __local volatile float* smem1, __local volatile float* smem2, __local volatile float* smem3, int tid)
 {
     smem1[tid] = val1;
     smem2[tid] = val2;
@@ -212,15 +118,19 @@ __local volatile float* smem1, __local volatile float* smem2, __local volatile f
         smem2[tid] += smem2[tid + 32];
         smem3[tid] += smem3[tid + 32];
 #if WAVE_SIZE < 32
-       } barrier(CLK_LOCAL_MEM_FENCE);
-       if (tid < 16) {
+    }
+    barrier(CLK_LOCAL_MEM_FENCE);
+    if (tid < 16)
+    {
 #endif
         smem1[tid] += smem1[tid + 16];
         smem2[tid] += smem2[tid + 16];
         smem3[tid] += smem3[tid + 16];
 #if WAVE_SIZE <16
-       } barrier(CLK_LOCAL_MEM_FENCE);
-       if (tid < 8) {
+    }
+    barrier(CLK_LOCAL_MEM_FENCE);
+    if (tid < 8)
+    {
 #endif
         smem1[tid] += smem1[tid + 8];
         smem2[tid] += smem2[tid + 8];
@@ -238,6 +148,7 @@ __local volatile float* smem1, __local volatile float* smem2, __local volatile f
         smem2[tid] += smem2[tid + 1];
         smem3[tid] += smem3[tid + 1];
     }
+    barrier(CLK_LOCAL_MEM_FENCE);
 }
 
 void reduce2(float val1, float val2, __local volatile float* smem1, __local volatile float* smem2, int tid)
@@ -251,14 +162,18 @@ void reduce2(float val1, float val2, __local volatile float* smem1, __local vola
         smem1[tid] += smem1[tid + 32];
         smem2[tid] += smem2[tid + 32];
 #if WAVE_SIZE < 32
-       } barrier(CLK_LOCAL_MEM_FENCE);
-       if (tid < 16) {
+    }
+    barrier(CLK_LOCAL_MEM_FENCE);
+    if (tid < 16)
+    {
 #endif
         smem1[tid] += smem1[tid + 16];
         smem2[tid] += smem2[tid + 16];
 #if WAVE_SIZE <16
-       } barrier(CLK_LOCAL_MEM_FENCE);
-       if (tid < 8) {
+    }
+    barrier(CLK_LOCAL_MEM_FENCE);
+    if (tid < 8)
+    {
 #endif
         smem1[tid] += smem1[tid + 8];
         smem2[tid] += smem2[tid + 8];
@@ -272,6 +187,7 @@ void reduce2(float val1, float val2, __local volatile float* smem1, __local vola
         smem1[tid] += smem1[tid + 1];
         smem2[tid] += smem2[tid + 1];
     }
+    barrier(CLK_LOCAL_MEM_FENCE);
 }
 
 void reduce1(float val1, __local volatile float* smem1, int tid)
@@ -283,19 +199,24 @@ void reduce1(float val1, __local volatile float* smem1, int tid)
     {
         smem1[tid] += smem1[tid + 32];
 #if WAVE_SIZE < 32
-       } barrier(CLK_LOCAL_MEM_FENCE);
-       if (tid < 16) {
+    }
+    barrier(CLK_LOCAL_MEM_FENCE);
+    if (tid < 16)
+    {
 #endif
         smem1[tid] += smem1[tid + 16];
 #if WAVE_SIZE <16
-       } barrier(CLK_LOCAL_MEM_FENCE);
-       if (tid < 8) {
+    }
+    barrier(CLK_LOCAL_MEM_FENCE);
+    if (tid < 8)
+    {
 #endif
         smem1[tid] += smem1[tid + 8];
         smem1[tid] += smem1[tid + 4];
         smem1[tid] += smem1[tid + 2];
         smem1[tid] += smem1[tid + 1];
     }
+    barrier(CLK_LOCAL_MEM_FENCE);
 }
 #endif
 
@@ -306,106 +227,100 @@ void reduce1(float val1, __local volatile float* smem1, int tid)
 __constant sampler_t sampler    = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_LINEAR;
 
 void SetPatch(image2d_t I, float x, float y,
-                                float* Pch, float* Dx, float* Dy,
-                                float* A11, float* A12, float* A22)
+              float* Pch, float* Dx, float* Dy,
+              float* A11, float* A12, float* A22)
 {
-            *Pch = read_imagef(I, sampler, (float2)(x, y)).x;
+    *Pch = read_imagef(I, sampler, (float2)(x, y)).x;
 
-            float dIdx = 3.0f * read_imagef(I, sampler, (float2)(x + 1, y - 1)).x + 10.0f * read_imagef(I, sampler, (float2)(x + 1, y)).x + 3.0f * read_imagef(I, sampler, (float2)(x + 1, y + 1)).x -
-                             (3.0f * read_imagef(I, sampler, (float2)(x - 1, y - 1)).x + 10.0f * read_imagef(I, sampler, (float2)(x - 1, y)).x + 3.0f * read_imagef(I, sampler, (float2)(x - 1, y + 1)).x);
+    float dIdx = 3.0f * read_imagef(I, sampler, (float2)(x + 1, y - 1)).x + 10.0f * read_imagef(I, sampler, (float2)(x + 1, y)).x + 3.0f * read_imagef(I, sampler, (float2)(x + 1, y + 1)).x -
+                 (3.0f * read_imagef(I, sampler, (float2)(x - 1, y - 1)).x + 10.0f * read_imagef(I, sampler, (float2)(x - 1, y)).x + 3.0f * read_imagef(I, sampler, (float2)(x - 1, y + 1)).x);
 
-            float dIdy = 3.0f * read_imagef(I, sampler, (float2)(x - 1, y + 1)).x + 10.0f * read_imagef(I, sampler, (float2)(x, y + 1)).x + 3.0f * read_imagef(I, sampler, (float2)(x + 1, y + 1)).x -
-                            (3.0f * read_imagef(I, sampler, (float2)(x - 1, y - 1)).x + 10.0f * read_imagef(I, sampler, (float2)(x, y - 1)).x + 3.0f * read_imagef(I, sampler, (float2)(x + 1, y - 1)).x);
+    float dIdy = 3.0f * read_imagef(I, sampler, (float2)(x - 1, y + 1)).x + 10.0f * read_imagef(I, sampler, (float2)(x, y + 1)).x + 3.0f * read_imagef(I, sampler, (float2)(x + 1, y + 1)).x -
+                 (3.0f * read_imagef(I, sampler, (float2)(x - 1, y - 1)).x + 10.0f * read_imagef(I, sampler, (float2)(x, y - 1)).x + 3.0f * read_imagef(I, sampler, (float2)(x + 1, y - 1)).x);
 
 
-            *Dx = dIdx;
-            *Dy = dIdy;
+    *Dx = dIdx;
+    *Dy = dIdy;
 
-            *A11 += dIdx * dIdx;
-            *A12 += dIdx * dIdy;
-            *A22 += dIdy * dIdy;
+    *A11 += dIdx * dIdx;
+    *A12 += dIdx * dIdy;
+    *A22 += dIdy * dIdy;
 }
 
 void GetPatch(image2d_t J, float x, float y,
-                                float* Pch, float* Dx, float* Dy,
-                                float* b1, float* b2)
+              float* Pch, float* Dx, float* Dy,
+              float* b1, float* b2)
 {
-                float J_val = read_imagef(J, sampler, (float2)(x, y)).x;
-                float diff = (J_val - *Pch) * 32.0f;
-                *b1 += diff**Dx;
-                *b2 += diff**Dy;
+    float J_val = read_imagef(J, sampler, (float2)(x, y)).x;
+    float diff = (J_val - *Pch) * 32.0f;
+    *b1 += diff**Dx;
+    *b2 += diff**Dy;
 }
 
 void GetError(image2d_t J, const float x, const float y, const float* Pch, float* errval)
 {
-        float diff = read_imagef(J, sampler, (float2)(x,y)).x-*Pch;
-        *errval += fabs(diff);
+    float diff = read_imagef(J, sampler, (float2)(x,y)).x-*Pch;
+    *errval += fabs(diff);
 }
 
 void SetPatch4(image2d_t I, const float x, const float y,
-                                float4* Pch, float4* Dx, float4* Dy,
-                                float* A11, float* A12, float* A22)
+               float4* Pch, float4* Dx, float4* Dy,
+               float* A11, float* A12, float* A22)
 {
-            *Pch = read_imagef(I, sampler, (float2)(x, y));
+    *Pch = read_imagef(I, sampler, (float2)(x, y));
 
-            float4 dIdx = 3.0f * read_imagef(I, sampler, (float2)(x + 1, y - 1)) + 10.0f * read_imagef(I, sampler, (float2)(x + 1, y)) + 3.0f * read_imagef(I, sampler, (float2)(x + 1, y + 1)) -
-                             (3.0f * read_imagef(I, sampler, (float2)(x - 1, y - 1)) + 10.0f * read_imagef(I, sampler, (float2)(x - 1, y)) + 3.0f * read_imagef(I, sampler, (float2)(x - 1, y + 1)));
+    float4 dIdx = 3.0f * read_imagef(I, sampler, (float2)(x + 1, y - 1)) + 10.0f * read_imagef(I, sampler, (float2)(x + 1, y)) + 3.0f * read_imagef(I, sampler, (float2)(x + 1, y + 1)) -
+                  (3.0f * read_imagef(I, sampler, (float2)(x - 1, y - 1)) + 10.0f * read_imagef(I, sampler, (float2)(x - 1, y)) + 3.0f * read_imagef(I, sampler, (float2)(x - 1, y + 1)));
 
-            float4 dIdy = 3.0f * read_imagef(I, sampler, (float2)(x - 1, y + 1)) + 10.0f * read_imagef(I, sampler, (float2)(x, y + 1)) + 3.0f * read_imagef(I, sampler, (float2)(x + 1, y + 1)) -
-                            (3.0f * read_imagef(I, sampler, (float2)(x - 1, y - 1)) + 10.0f * read_imagef(I, sampler, (float2)(x, y - 1)) + 3.0f * read_imagef(I, sampler, (float2)(x + 1, y - 1)));
+    float4 dIdy = 3.0f * read_imagef(I, sampler, (float2)(x - 1, y + 1)) + 10.0f * read_imagef(I, sampler, (float2)(x, y + 1)) + 3.0f * read_imagef(I, sampler, (float2)(x + 1, y + 1)) -
+                  (3.0f * read_imagef(I, sampler, (float2)(x - 1, y - 1)) + 10.0f * read_imagef(I, sampler, (float2)(x, y - 1)) + 3.0f * read_imagef(I, sampler, (float2)(x + 1, y - 1)));
 
 
-            *Dx = dIdx;
-            *Dy = dIdy;
-                        float4 sqIdx = dIdx * dIdx;
-                        *A11 += sqIdx.x + sqIdx.y + sqIdx.z;
-                        sqIdx = dIdx * dIdy;
-                        *A12 += sqIdx.x + sqIdx.y + sqIdx.z;
-                        sqIdx = dIdy * dIdy;
-                        *A22 += sqIdx.x + sqIdx.y + sqIdx.z;
+    *Dx = dIdx;
+    *Dy = dIdy;
+    float4 sqIdx = dIdx * dIdx;
+    *A11 += sqIdx.x + sqIdx.y + sqIdx.z;
+    sqIdx = dIdx * dIdy;
+    *A12 += sqIdx.x + sqIdx.y + sqIdx.z;
+    sqIdx = dIdy * dIdy;
+    *A22 += sqIdx.x + sqIdx.y + sqIdx.z;
 }
 
 void GetPatch4(image2d_t J, const float x, const float y,
-                                const float4* Pch, const float4* Dx, const float4* Dy,
-                                float* b1, float* b2)
+               const float4* Pch, const float4* Dx, const float4* Dy,
+               float* b1, float* b2)
 {
-                float4 J_val = read_imagef(J, sampler, (float2)(x, y));
-                float4 diff = (J_val - *Pch) * 32.0f;
-                                float4 xdiff = diff* *Dx;
-                                *b1 += xdiff.x + xdiff.y + xdiff.z;
-                                xdiff = diff* *Dy;
-                                *b2 += xdiff.x + xdiff.y + xdiff.z;
+    float4 J_val = read_imagef(J, sampler, (float2)(x, y));
+    float4 diff = (J_val - *Pch) * 32.0f;
+    float4 xdiff = diff* *Dx;
+    *b1 += xdiff.x + xdiff.y + xdiff.z;
+    xdiff = diff* *Dy;
+    *b2 += xdiff.x + xdiff.y + xdiff.z;
 }
 
 void GetError4(image2d_t J, const float x, const float y, const float4* Pch, float* errval)
 {
-        float4 diff = read_imagef(J, sampler, (float2)(x,y))-*Pch;
-        *errval += fabs(diff.x) + fabs(diff.y) + fabs(diff.z);
+    float4 diff = read_imagef(J, sampler, (float2)(x,y))-*Pch;
+    *errval += fabs(diff.x) + fabs(diff.y) + fabs(diff.z);
 }
 
 #define        GRIDSIZE        3
 __kernel void lkSparse_C1_D5(image2d_t I, image2d_t J,
-    __global const float2* prevPts, int prevPtsStep, __global float2* nextPts, int nextPtsStep, __global uchar* status, __global float* err,
-        const int level, const int rows, const int cols, int PATCH_X, int PATCH_Y, int cn, int c_winSize_x, int c_winSize_y, int c_iters, char calcErr)
+                             __global const float2* prevPts, int prevPtsStep, __global float2* nextPts, int nextPtsStep, __global uchar* status, __global float* err,
+                             const int level, const int rows, const int cols, int PATCH_X, int PATCH_Y, int cn, int c_winSize_x, int c_winSize_y, int c_iters, char calcErr)
 {
-#ifdef CPU
-    __local float smem1[BUFFER+1];
-    __local float smem2[BUFFER+1];
-    __local float smem3[BUFFER+1];
-#else
     __local float smem1[BUFFER];
     __local float smem2[BUFFER];
     __local float smem3[BUFFER];
-#endif
 
-        unsigned int xid=get_local_id(0);
-        unsigned int yid=get_local_id(1);
-        unsigned int gid=get_group_id(0);
-        unsigned int xsize=get_local_size(0);
-        unsigned int ysize=get_local_size(1);
-        int xBase, yBase, i, j, k;
+    unsigned int xid=get_local_id(0);
+    unsigned int yid=get_local_id(1);
+    unsigned int gid=get_group_id(0);
+    unsigned int xsize=get_local_size(0);
+    unsigned int ysize=get_local_size(1);
+    int xBase, yBase, i, j, k;
 
-        float2 c_halfWin = (float2)((c_winSize_x - 1)>>1, (c_winSize_y - 1)>>1);
+    float2 c_halfWin = (float2)((c_winSize_x - 1)>>1, (c_winSize_y - 1)>>1);
 
     const int tid = mad24(yid, xsize, xid);
 
@@ -432,77 +347,71 @@ __kernel void lkSparse_C1_D5(image2d_t I, image2d_t J,
     float dIdx_patch[GRIDSIZE][GRIDSIZE];
     float dIdy_patch[GRIDSIZE][GRIDSIZE];
 
-        yBase=yid;
-        {
-                xBase=xid;
-                SetPatch(I, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                        &I_patch[0][0], &dIdx_patch[0][0], &dIdy_patch[0][0],
-                                        &A11, &A12, &A22);
-
-
-                xBase+=xsize;
-                SetPatch(I, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                        &I_patch[0][1], &dIdx_patch[0][1], &dIdy_patch[0][1],
-                                        &A11, &A12, &A22);
-
-                xBase+=xsize;
-                if(xBase<c_winSize_x)
-                SetPatch(I, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                        &I_patch[0][2], &dIdx_patch[0][2], &dIdy_patch[0][2],
-                                        &A11, &A12, &A22);
-        }
-        yBase+=ysize;
-        {
-                xBase=xid;
-                SetPatch(I, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                        &I_patch[1][0], &dIdx_patch[1][0], &dIdy_patch[1][0],
-                                        &A11, &A12, &A22);
-
-
-                xBase+=xsize;
-                SetPatch(I, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                        &I_patch[1][1], &dIdx_patch[1][1], &dIdy_patch[1][1],
-                                        &A11, &A12, &A22);
-
-                xBase+=xsize;
-                if(xBase<c_winSize_x)
-                SetPatch(I, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                        &I_patch[1][2], &dIdx_patch[1][2], &dIdy_patch[1][2],
-                                        &A11, &A12, &A22);
-        }
-        yBase+=ysize;
-        if(yBase<c_winSize_y)
-        {
-                xBase=xid;
-                SetPatch(I, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                        &I_patch[2][0], &dIdx_patch[2][0], &dIdy_patch[2][0],
-                                        &A11, &A12, &A22);
-
-
-                xBase+=xsize;
-                SetPatch(I, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                        &I_patch[2][1], &dIdx_patch[2][1], &dIdy_patch[2][1],
-                                        &A11, &A12, &A22);
-
-                xBase+=xsize;
-                if(xBase<c_winSize_x)
-                SetPatch(I, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                        &I_patch[2][2], &dIdx_patch[2][2], &dIdy_patch[2][2],
-                                        &A11, &A12, &A22);
-        }
+    yBase=yid;
+    {
+        xBase=xid;
+        SetPatch(I, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                 &I_patch[0][0], &dIdx_patch[0][0], &dIdy_patch[0][0],
+                 &A11, &A12, &A22);
+
+
+        xBase+=xsize;
+        SetPatch(I, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                 &I_patch[0][1], &dIdx_patch[0][1], &dIdy_patch[0][1],
+                 &A11, &A12, &A22);
+
+        xBase+=xsize;
+        if(xBase<c_winSize_x)
+            SetPatch(I, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                     &I_patch[0][2], &dIdx_patch[0][2], &dIdy_patch[0][2],
+                     &A11, &A12, &A22);
+    }
+    yBase+=ysize;
+    {
+        xBase=xid;
+        SetPatch(I, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                 &I_patch[1][0], &dIdx_patch[1][0], &dIdy_patch[1][0],
+                 &A11, &A12, &A22);
+
+
+        xBase+=xsize;
+        SetPatch(I, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                 &I_patch[1][1], &dIdx_patch[1][1], &dIdy_patch[1][1],
+                 &A11, &A12, &A22);
+
+        xBase+=xsize;
+        if(xBase<c_winSize_x)
+            SetPatch(I, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                     &I_patch[1][2], &dIdx_patch[1][2], &dIdy_patch[1][2],
+                     &A11, &A12, &A22);
+    }
+    yBase+=ysize;
+    if(yBase<c_winSize_y)
+    {
+        xBase=xid;
+        SetPatch(I, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                 &I_patch[2][0], &dIdx_patch[2][0], &dIdy_patch[2][0],
+                 &A11, &A12, &A22);
+
+
+        xBase+=xsize;
+        SetPatch(I, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                 &I_patch[2][1], &dIdx_patch[2][1], &dIdy_patch[2][1],
+                 &A11, &A12, &A22);
+
+        xBase+=xsize;
+        if(xBase<c_winSize_x)
+            SetPatch(I, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                     &I_patch[2][2], &dIdx_patch[2][2], &dIdy_patch[2][2],
+                     &A11, &A12, &A22);
+    }
 
     reduce3(A11, A12, A22, smem1, smem2, smem3, tid);
-    barrier(CLK_LOCAL_MEM_FENCE);
 
-#ifdef CPU
-    A11 = smem1[BUFFER];
-    A12 = smem2[BUFFER];
-    A22 = smem3[BUFFER];
-#else
     A11 = smem1[0];
     A12 = smem2[0];
     A22 = smem3[0];
-#endif
+    barrier(CLK_LOCAL_MEM_FENCE);
 
     float D = A11 * A22 - A12 * A12;
 
@@ -532,81 +441,76 @@ __kernel void lkSparse_C1_D5(image2d_t I, image2d_t J,
         float b1 = 0;
         float b2 = 0;
 
-                yBase=yid;
-                {
-                        xBase=xid;
-                        GetPatch(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                                &I_patch[0][0], &dIdx_patch[0][0], &dIdy_patch[0][0],
-                                                &b1, &b2);
-
-
-                        xBase+=xsize;
-                        GetPatch(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                                &I_patch[0][1], &dIdx_patch[0][1], &dIdy_patch[0][1],
-                                                &b1, &b2);
-
-                        xBase+=xsize;
-                        if(xBase<c_winSize_x)
-                        GetPatch(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                                &I_patch[0][2], &dIdx_patch[0][2], &dIdy_patch[0][2],
-                                                &b1, &b2);
-                }
-                yBase+=ysize;
-                {
-                        xBase=xid;
-                        GetPatch(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                                &I_patch[1][0], &dIdx_patch[1][0], &dIdy_patch[1][0],
-                                                &b1, &b2);
-
-
-                        xBase+=xsize;
-                        GetPatch(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                                &I_patch[1][1], &dIdx_patch[1][1], &dIdy_patch[1][1],
-                                                &b1, &b2);
-
-                        xBase+=xsize;
-                        if(xBase<c_winSize_x)
-                        GetPatch(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                                &I_patch[1][2], &dIdx_patch[1][2], &dIdy_patch[1][2],
-                                                &b1, &b2);
-                }
-                yBase+=ysize;
-                if(yBase<c_winSize_y)
-                {
-                        xBase=xid;
-                        GetPatch(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                                &I_patch[2][0], &dIdx_patch[2][0], &dIdy_patch[2][0],
-                                                &b1, &b2);
-
-
-                        xBase+=xsize;
-                        GetPatch(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                                &I_patch[2][1], &dIdx_patch[2][1], &dIdy_patch[2][1],
-                                                &b1, &b2);
-
-                        xBase+=xsize;
-                        if(xBase<c_winSize_x)
-                        GetPatch(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                                &I_patch[2][2], &dIdx_patch[2][2], &dIdy_patch[2][2],
-                                                &b1, &b2);
-                }
+        yBase=yid;
+        {
+            xBase=xid;
+            GetPatch(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                     &I_patch[0][0], &dIdx_patch[0][0], &dIdy_patch[0][0],
+                     &b1, &b2);
+
+
+            xBase+=xsize;
+            GetPatch(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                     &I_patch[0][1], &dIdx_patch[0][1], &dIdy_patch[0][1],
+                     &b1, &b2);
+
+            xBase+=xsize;
+            if(xBase<c_winSize_x)
+                GetPatch(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                         &I_patch[0][2], &dIdx_patch[0][2], &dIdy_patch[0][2],
+                         &b1, &b2);
+        }
+        yBase+=ysize;
+        {
+            xBase=xid;
+            GetPatch(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                     &I_patch[1][0], &dIdx_patch[1][0], &dIdy_patch[1][0],
+                     &b1, &b2);
+
+
+            xBase+=xsize;
+            GetPatch(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                     &I_patch[1][1], &dIdx_patch[1][1], &dIdy_patch[1][1],
+                     &b1, &b2);
+
+            xBase+=xsize;
+            if(xBase<c_winSize_x)
+                GetPatch(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                         &I_patch[1][2], &dIdx_patch[1][2], &dIdy_patch[1][2],
+                         &b1, &b2);
+        }
+        yBase+=ysize;
+        if(yBase<c_winSize_y)
+        {
+            xBase=xid;
+            GetPatch(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                     &I_patch[2][0], &dIdx_patch[2][0], &dIdy_patch[2][0],
+                     &b1, &b2);
+
+
+            xBase+=xsize;
+            GetPatch(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                     &I_patch[2][1], &dIdx_patch[2][1], &dIdy_patch[2][1],
+                     &b1, &b2);
+
+            xBase+=xsize;
+            if(xBase<c_winSize_x)
+                GetPatch(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                         &I_patch[2][2], &dIdx_patch[2][2], &dIdy_patch[2][2],
+                         &b1, &b2);
+        }
 
         reduce2(b1, b2, smem1, smem2, tid);
-        barrier(CLK_LOCAL_MEM_FENCE);
 
-#ifdef CPU
-        b1 = smem1[BUFFER];
-        b2 = smem2[BUFFER];
-#else
         b1 = smem1[0];
         b2 = smem2[0];
-#endif
+        barrier(CLK_LOCAL_MEM_FENCE);
 
         float2 delta;
         delta.x = A12 * b2 - A22 * b1;
         delta.y = A12 * b1 - A11 * b2;
 
-                prevPt += delta;
+        prevPt += delta;
 
         if (fabs(delta.x) < THRESHOLD && fabs(delta.y) < THRESHOLD)
             break;
@@ -615,97 +519,87 @@ __kernel void lkSparse_C1_D5(image2d_t I, image2d_t J,
     D = 0.0f;
     if (calcErr)
     {
-                yBase=yid;
-                {
-                        xBase=xid;
-                        GetError(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                                &I_patch[0][0], &D);
-
-
-                        xBase+=xsize;
-                        GetError(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                                &I_patch[0][1], &D);
-
-                        xBase+=xsize;
-                        if(xBase<c_winSize_x)
-                        GetError(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                                &I_patch[0][2], &D);
-                }
-                yBase+=ysize;
-                {
-                        xBase=xid;
-                        GetError(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                                &I_patch[1][0], &D);
-
-
-                        xBase+=xsize;
-                        GetError(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                                &I_patch[1][1], &D);
-
-                        xBase+=xsize;
-                        if(xBase<c_winSize_x)
-                        GetError(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                                &I_patch[1][2], &D);
-                }
-                yBase+=ysize;
-                if(yBase<c_winSize_y)
-                {
-                        xBase=xid;
-                        GetError(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                                &I_patch[2][0], &D);
-
-
-                        xBase+=xsize;
-                        GetError(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                                &I_patch[2][1], &D);
-
-                        xBase+=xsize;
-                        if(xBase<c_winSize_x)
-                        GetError(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
-                                                &I_patch[2][2], &D);
-                }
+        yBase=yid;
+        {
+            xBase=xid;
+            GetError(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                     &I_patch[0][0], &D);
+
+
+            xBase+=xsize;
+            GetError(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                     &I_patch[0][1], &D);
+
+            xBase+=xsize;
+            if(xBase<c_winSize_x)
+                GetError(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                         &I_patch[0][2], &D);
+        }
+        yBase+=ysize;
+        {
+            xBase=xid;
+            GetError(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                     &I_patch[1][0], &D);
+
+
+            xBase+=xsize;
+            GetError(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                     &I_patch[1][1], &D);
+
+            xBase+=xsize;
+            if(xBase<c_winSize_x)
+                GetError(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                         &I_patch[1][2], &D);
+        }
+        yBase+=ysize;
+        if(yBase<c_winSize_y)
+        {
+            xBase=xid;
+            GetError(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                     &I_patch[2][0], &D);
+
+
+            xBase+=xsize;
+            GetError(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                     &I_patch[2][1], &D);
+
+            xBase+=xsize;
+            if(xBase<c_winSize_x)
+                GetError(J, prevPt.x + xBase + 0.5f, prevPt.y + yBase + 0.5f,
+                         &I_patch[2][2], &D);
+        }
 
         reduce1(D, smem1, tid);
     }
 
     if (tid == 0)
     {
-                prevPt += c_halfWin;
+        prevPt += c_halfWin;
 
         nextPts[gid] = prevPt;
 
         if (calcErr)
-#ifdef CPU
-            err[gid] = smem1[BUFFER] / (float)(c_winSize_x * c_winSize_y);
-#else
             err[gid] = smem1[0] / (float)(c_winSize_x * c_winSize_y);
-#endif
     }
 }
 
 
 __kernel void lkSparse_C4_D5(image2d_t I, image2d_t J,
-    __global const float2* prevPts, int prevPtsStep, __global float2* nextPts, int nextPtsStep, __global uchar* status, __global float* err,
-        const int level, const int rows, const int cols, int PATCH_X, int PATCH_Y, int cn, int c_winSize_x, int c_winSize_y, int c_iters, char calcErr)
+                             __global const float2* prevPts, int prevPtsStep, __global float2* nextPts, int nextPtsStep, __global uchar* status, __global float* err,
+                             const int level, const int rows, const int cols, int PATCH_X, int PATCH_Y, int cn, int c_winSize_x, int c_winSize_y, int c_iters, char calcErr)
 {
-#ifdef CPU
-     __local float smem1[BUFFER+1];
-     __local float smem2[BUFFER+1];
-     __local float smem3[BUFFER+1];
-#else
-     __local float smem1[BUFFER];
-     __local float smem2[BUFFER];
-     __local float smem3[BUFFER];
-#endif
+    __local float smem1[BUFFER];
+    __local float smem2[BUFFER];
+    __local float smem3[BUFFER];
 
-        unsigned int xid=get_local_id(0);
-        unsigned int yid=get_local_id(1);
-        unsigned int gid=get_group_id(0);
-        unsigned int xsize=get_local_size(0);
-        unsigned int ysize=get_local_size(1);
-        int xBase, yBase, i, j, k;
+    unsigned int xid=get_local_id(0);
+    unsigned int yid=get_local_id(1);
+    unsigned int gid=get_group_id(0);
+    unsigned int xsize=get_local_size(0);
+    unsigned int ysize=get_local_size(1);
+    int xBase, yBase, i, j, k;
 
-        float2 c_halfWin = (float2)((c_winSize_x - 1)>>1, (c_winSize_y - 1)>>1);
+    float2 c_halfWin = (float2)((c_winSize_x - 1)>>1, (c_winSize_y - 1)>>1);
 
     const int tid = mad24(yid, xsize, xid);
 
@@ -721,7 +615,7 @@ __kernel void lkSparse_C4_D5(image2d_t I, image2d_t J,
         return;
     }
 
-        nextPt -= c_halfWin;
+    nextPt -= c_halfWin;
 
     // extract the patch from the first image, compute covariation matrix of derivatives
 
@@ -732,80 +626,74 @@ __kernel void lkSparse_C4_D5(image2d_t I, image2d_t J,
     float4 I_patch[8];
     float4 dIdx_patch[8];
     float4 dIdy_patch[8];
-        float4 I_add,Dx_add,Dy_add;
+    float4 I_add,Dx_add,Dy_add;
 
-        yBase=yid;
-        {
-                xBase=xid;
-                SetPatch4(I, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                        &I_patch[0], &dIdx_patch[0], &dIdy_patch[0],
-                                        &A11, &A12, &A22);
+    yBase=yid;
+    {
+        xBase=xid;
+        SetPatch4(I, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                  &I_patch[0], &dIdx_patch[0], &dIdy_patch[0],
+                  &A11, &A12, &A22);
 
 
-                xBase+=xsize;
-                SetPatch4(I, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                        &I_patch[1], &dIdx_patch[1], &dIdy_patch[1],
-                                        &A11, &A12, &A22);
+        xBase+=xsize;
+        SetPatch4(I, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                  &I_patch[1], &dIdx_patch[1], &dIdy_patch[1],
+                  &A11, &A12, &A22);
 
-                xBase+=xsize;
-                if(xBase<c_winSize_x)
-                SetPatch4(I, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                        &I_patch[2], &dIdx_patch[2], &dIdy_patch[2],
-                                        &A11, &A12, &A22);
+        xBase+=xsize;
+        if(xBase<c_winSize_x)
+            SetPatch4(I, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                      &I_patch[2], &dIdx_patch[2], &dIdy_patch[2],
+                      &A11, &A12, &A22);
 
-        }
-        yBase+=ysize;
-        {
-                xBase=xid;
-                SetPatch4(I, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                        &I_patch[3], &dIdx_patch[3], &dIdy_patch[3],
-                                        &A11, &A12, &A22);
-
-
-                xBase+=xsize;
-                SetPatch4(I, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                        &I_patch[4], &dIdx_patch[4], &dIdy_patch[4],
-                                        &A11, &A12, &A22);
-
-                xBase+=xsize;
-                if(xBase<c_winSize_x)
-                SetPatch4(I, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                        &I_patch[5], &dIdx_patch[5], &dIdy_patch[5],
-                                        &A11, &A12, &A22);
-        }
-        yBase+=ysize;
-        if(yBase<c_winSize_y)
-        {
-                xBase=xid;
-                SetPatch4(I, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                        &I_patch[6], &dIdx_patch[6], &dIdy_patch[6],
-                                        &A11, &A12, &A22);
-
-
-                xBase+=xsize;
-                SetPatch4(I, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                        &I_patch[7], &dIdx_patch[7], &dIdy_patch[7],
-                                        &A11, &A12, &A22);
-
-                xBase+=xsize;
-                if(xBase<c_winSize_x)
-                SetPatch4(I, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                        &I_add, &Dx_add, &Dy_add,
-                                        &A11, &A12, &A22);
-        }
+    }
+    yBase+=ysize;
+    {
+        xBase=xid;
+        SetPatch4(I, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                  &I_patch[3], &dIdx_patch[3], &dIdy_patch[3],
+                  &A11, &A12, &A22);
+
+
+        xBase+=xsize;
+        SetPatch4(I, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                  &I_patch[4], &dIdx_patch[4], &dIdy_patch[4],
+                  &A11, &A12, &A22);
+
+        xBase+=xsize;
+        if(xBase<c_winSize_x)
+            SetPatch4(I, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                      &I_patch[5], &dIdx_patch[5], &dIdy_patch[5],
+                      &A11, &A12, &A22);
+    }
+    yBase+=ysize;
+    if(yBase<c_winSize_y)
+    {
+        xBase=xid;
+        SetPatch4(I, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                  &I_patch[6], &dIdx_patch[6], &dIdy_patch[6],
+                  &A11, &A12, &A22);
+
+
+        xBase+=xsize;
+        SetPatch4(I, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                  &I_patch[7], &dIdx_patch[7], &dIdy_patch[7],
+                  &A11, &A12, &A22);
+
+        xBase+=xsize;
+        if(xBase<c_winSize_x)
+            SetPatch4(I, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                      &I_add, &Dx_add, &Dy_add,
+                      &A11, &A12, &A22);
+    }
 
     reduce3(A11, A12, A22, smem1, smem2, smem3, tid);
-    barrier(CLK_LOCAL_MEM_FENCE);
 
-#ifdef CPU
-    A11 = smem1[BUFFER];
-    A12 = smem2[BUFFER];
-    A22 = smem3[BUFFER];
-#else
     A11 = smem1[0];
     A12 = smem2[0];
     A22 = smem3[0];
-#endif
+    barrier(CLK_LOCAL_MEM_FENCE);
 
     float D = A11 * A22 - A12 * A12;
 
@@ -821,7 +709,7 @@ __kernel void lkSparse_C4_D5(image2d_t I, image2d_t J,
     A12 /= D;
     A22 /= D;
 
-        nextPt = nextPts[gid] * 2.0f - c_halfWin;
+    nextPt = nextPts[gid] * 2.0f - c_halfWin;
 
     for (k = 0; k < c_iters; ++k)
     {
@@ -835,81 +723,76 @@ __kernel void lkSparse_C4_D5(image2d_t I, image2d_t J,
         float b1 = 0;
         float b2 = 0;
 
-                yBase=yid;
-                {
-                        xBase=xid;
-                        GetPatch4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                                &I_patch[0], &dIdx_patch[0], &dIdy_patch[0],
-                                                &b1, &b2);
-
-
-                        xBase+=xsize;
-                        GetPatch4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                                &I_patch[1], &dIdx_patch[1], &dIdy_patch[1],
-                                                &b1, &b2);
-
-                        xBase+=xsize;
-                        if(xBase<c_winSize_x)
-                        GetPatch4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                                &I_patch[2], &dIdx_patch[2], &dIdy_patch[2],
-                                                &b1, &b2);
-                }
-                yBase+=ysize;
-                {
-                        xBase=xid;
-                        GetPatch4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                                &I_patch[3], &dIdx_patch[3], &dIdy_patch[3],
-                                                &b1, &b2);
-
-
-                        xBase+=xsize;
-                        GetPatch4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                                &I_patch[4], &dIdx_patch[4], &dIdy_patch[4],
-                                                &b1, &b2);
-
-                        xBase+=xsize;
-                        if(xBase<c_winSize_x)
-                        GetPatch4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                                &I_patch[5], &dIdx_patch[5], &dIdy_patch[5],
-                                                &b1, &b2);
-                }
-                yBase+=ysize;
-                if(yBase<c_winSize_y)
-                {
-                        xBase=xid;
-                        GetPatch4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                                &I_patch[6], &dIdx_patch[6], &dIdy_patch[6],
-                                                &b1, &b2);
-
-
-                        xBase+=xsize;
-                        GetPatch4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                                &I_patch[7], &dIdx_patch[7], &dIdy_patch[7],
-                                                &b1, &b2);
-
-                        xBase+=xsize;
-                        if(xBase<c_winSize_x)
-                        GetPatch4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                                &I_add, &Dx_add, &Dy_add,
-                                                &b1, &b2);
-                }
+        yBase=yid;
+        {
+            xBase=xid;
+            GetPatch4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                      &I_patch[0], &dIdx_patch[0], &dIdy_patch[0],
+                      &b1, &b2);
+
+
+            xBase+=xsize;
+            GetPatch4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                      &I_patch[1], &dIdx_patch[1], &dIdy_patch[1],
+                      &b1, &b2);
+
+            xBase+=xsize;
+            if(xBase<c_winSize_x)
+                GetPatch4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                          &I_patch[2], &dIdx_patch[2], &dIdy_patch[2],
+                          &b1, &b2);
+        }
+        yBase+=ysize;
+        {
+            xBase=xid;
+            GetPatch4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                      &I_patch[3], &dIdx_patch[3], &dIdy_patch[3],
+                      &b1, &b2);
+
+
+            xBase+=xsize;
+            GetPatch4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                      &I_patch[4], &dIdx_patch[4], &dIdy_patch[4],
+                      &b1, &b2);
+
+            xBase+=xsize;
+            if(xBase<c_winSize_x)
+                GetPatch4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                          &I_patch[5], &dIdx_patch[5], &dIdy_patch[5],
+                          &b1, &b2);
+        }
+        yBase+=ysize;
+        if(yBase<c_winSize_y)
+        {
+            xBase=xid;
+            GetPatch4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                      &I_patch[6], &dIdx_patch[6], &dIdy_patch[6],
+                      &b1, &b2);
+
+
+            xBase+=xsize;
+            GetPatch4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                      &I_patch[7], &dIdx_patch[7], &dIdy_patch[7],
+                      &b1, &b2);
+
+            xBase+=xsize;
+            if(xBase<c_winSize_x)
+                GetPatch4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                          &I_add, &Dx_add, &Dy_add,
+                          &b1, &b2);
+        }
 
         reduce2(b1, b2, smem1, smem2, tid);
-        barrier(CLK_LOCAL_MEM_FENCE);
 
-#ifdef CPU
-        b1 = smem1[BUFFER];
-        b2 = smem2[BUFFER];
-#else
         b1 = smem1[0];
         b2 = smem2[0];
-#endif
+        barrier(CLK_LOCAL_MEM_FENCE);
 
         float2 delta;
         delta.x = A12 * b2 - A22 * b1;
         delta.y = A12 * b1 - A11 * b2;
 
-                nextPt +=delta;
+        nextPt +=delta;
 
         if (fabs(delta.x) < THRESHOLD && fabs(delta.y) < THRESHOLD)
             break;
@@ -918,78 +801,74 @@ __kernel void lkSparse_C4_D5(image2d_t I, image2d_t J,
     D = 0.0f;
     if (calcErr)
     {
-                yBase=yid;
-                {
-                        xBase=xid;
-                        GetError4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                                &I_patch[0], &D);
-
-
-                        xBase+=xsize;
-                        GetError4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                                &I_patch[1], &D);
-
-                        xBase+=xsize;
-                        if(xBase<c_winSize_x)
-                        GetError4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                                &I_patch[2], &D);
-                }
-                yBase+=ysize;
-                {
-                        xBase=xid;
-                        GetError4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                                &I_patch[3], &D);
-
-
-                        xBase+=xsize;
-                        GetError4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                                &I_patch[4], &D);
-
-                        xBase+=xsize;
-                        if(xBase<c_winSize_x)
-                        GetError4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                                &I_patch[5], &D);
-                }
-                yBase+=ysize;
-                if(yBase<c_winSize_y)
-                {
-                        xBase=xid;
-                        GetError4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                                &I_patch[6], &D);
-
-
-                        xBase+=xsize;
-                        GetError4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                                &I_patch[7], &D);
-
-                        xBase+=xsize;
-                        if(xBase<c_winSize_x)
-                        GetError4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
-                                                &I_add, &D);
-                }
+        yBase=yid;
+        {
+            xBase=xid;
+            GetError4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                      &I_patch[0], &D);
+
+
+            xBase+=xsize;
+            GetError4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                      &I_patch[1], &D);
+
+            xBase+=xsize;
+            if(xBase<c_winSize_x)
+                GetError4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                          &I_patch[2], &D);
+        }
+        yBase+=ysize;
+        {
+            xBase=xid;
+            GetError4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                      &I_patch[3], &D);
+
+
+            xBase+=xsize;
+            GetError4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                      &I_patch[4], &D);
+
+            xBase+=xsize;
+            if(xBase<c_winSize_x)
+                GetError4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                          &I_patch[5], &D);
+        }
+        yBase+=ysize;
+        if(yBase<c_winSize_y)
+        {
+            xBase=xid;
+            GetError4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                      &I_patch[6], &D);
+
+
+            xBase+=xsize;
+            GetError4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                      &I_patch[7], &D);
+
+            xBase+=xsize;
+            if(xBase<c_winSize_x)
+                GetError4(J, nextPt.x + xBase + 0.5f, nextPt.y + yBase + 0.5f,
+                          &I_add, &D);
+        }
 
         reduce1(D, smem1, tid);
     }
 
     if (tid == 0)
     {
-                nextPt += c_halfWin;
+        nextPt += c_halfWin;
         nextPts[gid] = nextPt;
 
         if (calcErr)
-#ifdef CPU
-            err[gid] = smem1[BUFFER] / (float)(3 * c_winSize_x * c_winSize_y);
-#else
             err[gid] = smem1[0] / (float)(3 * c_winSize_x * c_winSize_y);
-#endif
     }
 }
 
 __kernel void lkDense_C1_D0(image2d_t I, image2d_t J, __global float* u, int uStep, __global float* v, int vStep, __global const float* prevU, int prevUStep, __global const float* prevV, int prevVStep,
-    const int rows, const int cols, /*__global float* err, int errStep, int cn,*/ int c_winSize_x, int c_winSize_y, int c_iters, char calcErr)
+                            const int rows, const int cols, /*__global float* err, int errStep, int cn,*/ int c_winSize_x, int c_winSize_y, int c_iters, char calcErr)
 {
-        int c_halfWin_x = (c_winSize_x - 1) / 2;
-        int c_halfWin_y = (c_winSize_y - 1) / 2;
+    int c_halfWin_x = (c_winSize_x - 1) / 2;
+    int c_halfWin_y = (c_winSize_y - 1) / 2;
 
     const int patchWidth  = get_local_size(0) + 2 * c_halfWin_x;
     const int patchHeight = get_local_size(1) + 2 * c_halfWin_y;
@@ -1003,7 +882,7 @@ __kernel void lkDense_C1_D0(image2d_t I, image2d_t J, __global float* u, int uSt
     const int xBase = get_group_id(0) * get_local_size(0);
     const int yBase = get_group_id(1) * get_local_size(1);
 
-        sampler_t sampleri    = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;
+    sampler_t sampleri    = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;
 
     for (int i = get_local_id(1); i < patchHeight; i += get_local_size(1))
     {
@@ -1017,10 +896,10 @@ __kernel void lkDense_C1_D0(image2d_t I, image2d_t J, __global float* u, int uSt
             // Sharr Deriv
 
             dIdx_patch[i * patchWidth + j] = 3 * read_imagei(I, sampleri, (float2)(x+1, y-1)).x + 10 * read_imagei(I, sampleri, (float2)(x+1, y)).x + 3 * read_imagei(I, sampleri, (float2)(x+1, y+1)).x -
-                                            (3 * read_imagei(I, sampleri, (float2)(x-1, y-1)).x + 10 * read_imagei(I, sampleri, (float2)(x-1, y)).x + 3 * read_imagei(I, sampleri, (float2)(x-1, y+1)).x);
+                                             (3 * read_imagei(I, sampleri, (float2)(x-1, y-1)).x + 10 * read_imagei(I, sampleri, (float2)(x-1, y)).x + 3 * read_imagei(I, sampleri, (float2)(x-1, y+1)).x);
 
             dIdy_patch[i * patchWidth + j] = 3 * read_imagei(I, sampleri, (float2)(x-1, y+1)).x + 10 * read_imagei(I, sampleri, (float2)(x, y+1)).x + 3 * read_imagei(I, sampleri, (float2)(x+1, y+1)).x -
-                                            (3 * read_imagei(I, sampleri, (float2)(x-1, y-1)).x + 10 * read_imagei(I, sampleri, (float2)(x, y-1)).x + 3 * read_imagei(I, sampleri, (float2)(x+1, y-1)).x);
+                                             (3 * read_imagei(I, sampleri, (float2)(x-1, y-1)).x + 10 * read_imagei(I, sampleri, (float2)(x, y-1)).x + 3 * read_imagei(I, sampleri, (float2)(x+1, y-1)).x);
         }
     }
     barrier(CLK_LOCAL_MEM_FENCE);
index bd86a7f..f1b9588 100644 (file)
@@ -162,8 +162,8 @@ __kernel void stereoKernel(__global unsigned char *left, __global unsigned char
     int y_tex;
     int x_tex = X - radius;
 
-    if (x_tex >= cwidth)
-        return;
+    //if (x_tex >= cwidth)
+    //    return;
 
     for(int d = STEREO_MIND; d < maxdisp; d += STEREO_DISP_STEP)
     {
@@ -258,27 +258,13 @@ float sobel(__global unsigned char *input, int x, int y, int rows, int cols)
 
 float CalcSums(__local float *cols, __local float *cols_cache, int winsz)
 {
-    float cache = 0;
-    float cache2 = 0;
-    int winsz2 = winsz/2;
-
-    int x = get_local_id(0);
-    int group_size_x = get_local_size(0);
+    unsigned int cache = cols[0];
 
-    for(int i = 1; i <= winsz2; i++)
+#pragma unroll
+    for(int i = 1; i <= winsz; i++)
         cache += cols[i];
 
-    cols_cache[0] = cache;
-
-    barrier(CLK_LOCAL_MEM_FENCE);
-
-    if (x < group_size_x - winsz2)
-        cache2 = cols_cache[winsz2];
-    else
-        for(int i = winsz2 + 1; i < winsz; i++)
-            cache2 += cols[i];
-
-    return cols[0] + cache + cache2;
+    return cache;
 }
 
 #define RpT (2 * ROWSperTHREAD)  // got experimentally
@@ -301,8 +287,7 @@ __kernel void textureness_kernel(__global unsigned char *disp, int disp_rows, in
     int beg_row = group_id_y * RpT;
     int end_row = min(beg_row + RpT, disp_rows);
 
-//   if (x < disp_cols)
-//   {
+
     int y = beg_row;
 
     float sum = 0;
@@ -340,11 +325,15 @@ __kernel void textureness_kernel(__global unsigned char *disp, int disp_rows, in
         }
 
         barrier(CLK_LOCAL_MEM_FENCE);
-        float sum_win = CalcSums(cols, cols_cache + local_id_x, winsz) * 255;
-        if (sum_win < threshold)
-            disp[y * disp_step + x] = 0;
+
+        if (x < disp_cols)
+        {
+            float sum_win = CalcSums(cols, cols_cache + local_id_x, winsz) * 255;
+            if (sum_win < threshold)
+                disp[y * disp_step + x] = 0;
+        }
 
         barrier(CLK_LOCAL_MEM_FENCE);
     }
-    //  }
+
 }
index 4d13f80..8a71629 100644 (file)
 
 #ifdef T_FLOAT
 #define T float
+#define T4 float4
 #else
 #define T short
+#define T4 short4
 #endif
 
 ///////////////////////////////////////////////////////////////
@@ -71,6 +73,14 @@ T saturate_cast(float v){
 #endif
 }
 
+T4 saturate_cast4(float4 v){
+#ifdef T_SHORT
+    return convert_short4_sat_rte(v); 
+#else
+    return v;
+#endif
+}
+
 #define FLOAT_MAX 3.402823466e+38f
 typedef struct
 {
@@ -84,29 +94,14 @@ typedef struct
 ////////////////////////// comp data //////////////////////////
 ///////////////////////////////////////////////////////////////
 
-float pix_diff_1(__global const uchar *ls, __global const uchar *rs)
+inline float pix_diff_1(const uchar4 l, __global const uchar *rs)
 {
-    return abs((int)(*ls) - *rs); 
+    return abs((int)(l.x) - *rs); 
 }
 
-float pix_diff_3(__global const uchar *ls, __global const uchar *rs)
+float pix_diff_4(const uchar4 l, __global const uchar *rs)
 {
-    const float tr = 0.299f;
-    const float tg = 0.587f;
-    const float tb = 0.114f;
-
-    float val;
-
-    val =  tb * abs((int)ls[0] - rs[0]);
-    val += tg * abs((int)ls[1] - rs[1]);
-    val += tr * abs((int)ls[2] - rs[2]);
-
-    return val;
-}
-float pix_diff_4(__global const uchar *ls, __global const uchar *rs)
-{
-    uchar4 l, r;
-    l = *((__global uchar4 *)ls);
+    uchar4 r;
     r = *((__global uchar4 *)rs);
 
     const float tr = 0.299f;
@@ -122,11 +117,19 @@ float pix_diff_4(__global const uchar *ls, __global const uchar *rs)
     return val;
 }
 
+inline float pix_diff_3(const uchar4 l, __global const uchar *rs)
+{
+    return pix_diff_4(l, rs);
+}
 
 #ifndef CN
 #define CN 4
 #endif
 
+#ifndef CNDISP
+#define CNDISP 64
+#endif
+
 #define CAT(X,Y) X##Y
 #define CAT2(X,Y) CAT(X,Y)
 
@@ -149,19 +152,20 @@ __kernel void comp_data(__global uchar *left,  int left_rows,  int left_cols,  i
         __global T *ds = data + y * data_step + x;
 
         const unsigned int disp_step = data_step * left_rows;
+        const float weightXterm = con_st -> cdata_weight * con_st -> cmax_data_term;
+        const uchar4 ls_data = vload4(0, ls);
 
         for (int disp = 0; disp < con_st -> cndisp; disp++)
         {
             if (x - disp >= 1)
             {
                 float val = 0;
-                val = PIX_DIFF(ls, rs - disp * CN);
-                ds[disp * disp_step] =  saturate_cast(fmin(con_st -> cdata_weight * val, 
-                    con_st -> cdata_weight * con_st -> cmax_data_term));
+                val = PIX_DIFF(ls_data, rs - disp * CN);
+                ds[disp * disp_step] =  saturate_cast(fmin(con_st -> cdata_weight * val, weightXterm));
             }
             else
             {
-                ds[disp * disp_step] =  saturate_cast(con_st -> cdata_weight * con_st -> cmax_data_term);
+                ds[disp * disp_step] =  saturate_cast(weightXterm);
             }
         }
     }
@@ -182,13 +186,20 @@ __kernel void data_step_down(__global T *src, int src_rows,
     {
         src_step /= sizeof(T);
         dst_step /= sizeof(T);
+        int4 coor_step = (int4)(src_rows * src_step);
+        int4 coor = (int4)(min(2*y+0, src_rows-1) * src_step + 2*x+0,
+                           min(2*y+1, src_rows-1) * src_step + 2*x+0,
+                           min(2*y+0, src_rows-1) * src_step + 2*x+1,
+                           min(2*y+1, src_rows-1) * src_step + 2*x+1);
+
         for (int d = 0; d < cndisp; ++d)
         {
             float dst_reg;
-            dst_reg  = src[(d * src_rows + min(2*y+0, src_rows-1)) * src_step + 2*x+0];
-            dst_reg += src[(d * src_rows + min(2*y+1, src_rows-1)) * src_step + 2*x+0];
-            dst_reg += src[(d * src_rows + min(2*y+0, src_rows-1)) * src_step + 2*x+1];
-            dst_reg += src[(d * src_rows + min(2*y+1, src_rows-1)) * src_step + 2*x+1];
+            dst_reg  = src[coor.x];
+            dst_reg += src[coor.y];
+            dst_reg += src[coor.z];
+            dst_reg += src[coor.w];
+            coor += coor_step;
 
             dst[(d * dst_rows + y) * dst_step + x] = saturate_cast(dst_reg);
         }
@@ -224,85 +235,95 @@ __kernel void level_up_message(__global T *src, int src_rows, int src_step,
 ///////////////////////////////////////////////////////////////
 ////////////////////  calc all iterations /////////////////////
 ///////////////////////////////////////////////////////////////
-void calc_min_linear_penalty(__global T * dst, int disp_step, 
-                             int cndisp, float cdisc_single_jump)
+void message(__global T *us_, __global T *ds_, __global T *ls_, __global T *rs_,
+              const __global T *dt,
+              int u_step, int msg_disp_step, int data_disp_step,
+              float4 cmax_disc_term, float4 cdisc_single_jump)
 {
-    float prev = dst[0];
-    float cur;
+    __global T *us = us_ + u_step;
+    __global T *ds = ds_ - u_step;
+    __global T *ls = ls_ + 1;
+    __global T *rs = rs_ - 1;
 
-    for (int disp = 1; disp < cndisp; ++disp)
-    {
-        prev += cdisc_single_jump;
-        cur = dst[disp_step * disp];
+    float4 minimum = (float4)(FLOAT_MAX);
 
-        if (prev < cur)
-        {
-            cur = prev;
-            dst[disp_step * disp] = saturate_cast(prev);
-        }
+    T4 t_dst[CNDISP];
+    float4 dst_reg;
+    float4 prev;
+    float4 cur;
 
-        prev = cur;
-    }
+    T t_us = us[0];
+    T t_ds = ds[0];
+    T t_ls = ls[0];
+    T t_rs = rs[0];
+    T t_dt = dt[0];
+
+    prev = (float4)(t_us + t_ls + t_rs + t_dt,
+                    t_ds + t_ls + t_rs + t_dt,
+                    t_us + t_ds + t_rs + t_dt,
+                    t_us + t_ds + t_ls + t_dt);
+
+    minimum = min(prev, minimum);
+
+    t_dst[0] = saturate_cast4(prev);
 
-    prev = dst[(cndisp - 1) * disp_step];
-    for (int disp = cndisp - 2; disp >= 0; disp--)
+    for(int i = 1, idx = msg_disp_step; i < CNDISP; ++i, idx+=msg_disp_step)
     {
+        t_us = us[idx];
+        t_ds = ds[idx];
+        t_ls = ls[idx];
+        t_rs = rs[idx];
+        t_dt = dt[data_disp_step * i];
+
+        dst_reg = (float4)(t_us + t_ls + t_rs + t_dt,
+                           t_ds + t_ls + t_rs + t_dt,
+                           t_us + t_ds + t_rs + t_dt,
+                           t_us + t_ds + t_ls + t_dt);
+
+        minimum = min(dst_reg, minimum);
+
         prev += cdisc_single_jump;
-        cur = dst[disp_step * disp];
+        prev = min(prev, dst_reg);
 
-        if (prev < cur)
-        {
-            cur = prev;
-            dst[disp_step * disp] = saturate_cast(prev);
-        }
-        prev = cur;
+        t_dst[i] = saturate_cast4(prev);
     }
-}
-void message(const __global T *msg1, const __global T *msg2,
-             const __global T *msg3, const __global T *data, __global T *dst,
-             int msg_disp_step, int data_disp_step, int cndisp, float cmax_disc_term, float cdisc_single_jump)
-{
-    float minimum = FLOAT_MAX;
 
-    for(int i = 0; i < cndisp; ++i)
+    minimum += cmax_disc_term;
+    
+    float4 sum = 0;
+    prev = convert_float4(t_dst[CNDISP - 1]);
+    for (int disp = CNDISP - 2; disp >= 0; disp--)
     {
-        float dst_reg;
-        dst_reg  = msg1[msg_disp_step * i];
-        dst_reg += msg2[msg_disp_step * i];
-        dst_reg += msg3[msg_disp_step * i];
-        dst_reg += data[data_disp_step * i];
-
-        if (dst_reg < minimum)
-            minimum = dst_reg;
+        prev += cdisc_single_jump;
+        cur = convert_float4(t_dst[disp]);
+        prev = min(prev, cur);
+        cur = min(prev, minimum);
+        sum += cur;
 
-        dst[msg_disp_step * i] = saturate_cast(dst_reg);
+        t_dst[disp] = saturate_cast4(cur);
     }
 
-    calc_min_linear_penalty(dst, msg_disp_step, cndisp, cdisc_single_jump);
+    dst_reg = convert_float4(t_dst[CNDISP - 1]);
+    dst_reg = min(dst_reg, minimum);
+    t_dst[CNDISP - 1] = saturate_cast4(dst_reg);
+    sum += dst_reg;
 
-    minimum += cmax_disc_term;
-
-    float sum = 0;
-    for(int i = 0; i < cndisp; ++i)
+    sum /= CNDISP;
+#pragma unroll
+    for(int i = 0, idx = 0; i < CNDISP; ++i, idx+=msg_disp_step)
     {
-        float dst_reg = dst[msg_disp_step * i];
-        if (dst_reg > minimum)
-        {
-            dst_reg = minimum;
-            dst[msg_disp_step * i] = saturate_cast(minimum);
-        }
-        sum += dst_reg;
+        T4 dst = t_dst[i];
+        us_[idx] = dst.x - sum.x;
+        ds_[idx] = dst.y - sum.y;
+        rs_[idx] = dst.z - sum.z;
+        ls_[idx] = dst.w - sum.w;
     }
-    sum /= cndisp;
-
-    for(int i = 0; i < cndisp; ++i)
-        dst[msg_disp_step * i] -= sum;
 }
 __kernel void one_iteration(__global T *u,    int u_step,
                             __global T *data, int data_step,
                             __global T *d,    __global T *l, __global T *r,
                             int t, int cols, int rows, 
-                            int cndisp, float cmax_disc_term, float cdisc_single_jump)
+                            float cmax_disc_term, float cdisc_single_jump)
 {
     const int y = get_global_id(1);
     const int x = ((get_global_id(0)) << 1) + ((y + t) & 1);
@@ -321,15 +342,9 @@ __kernel void one_iteration(__global T *u,    int u_step,
         int msg_disp_step = u_step * rows;
         int data_disp_step = data_step * rows;
 
-        message(us + u_step, ls      + 1, rs - 1, dt, us, msg_disp_step, data_disp_step, cndisp, 
-            cmax_disc_term, cdisc_single_jump);
-        message(ds - u_step, ls      + 1, rs - 1, dt, ds, msg_disp_step, data_disp_step, cndisp,
-            cmax_disc_term, cdisc_single_jump);
-
-        message(us + u_step, ds - u_step, rs - 1, dt, rs, msg_disp_step, data_disp_step, cndisp,
-            cmax_disc_term, cdisc_single_jump);
-        message(us + u_step, ds - u_step, ls + 1, dt, ls, msg_disp_step, data_disp_step, cndisp,
-            cmax_disc_term, cdisc_single_jump);
+        message(us, ds, ls, rs, dt,
+                u_step, msg_disp_step, data_disp_step,
+                (float4)(cmax_disc_term), (float4)(cdisc_single_jump));
     }
 }
 
diff --git a/modules/ocl/src/optical_flow_farneback.cpp b/modules/ocl/src/optical_flow_farneback.cpp
new file mode 100644 (file)
index 0000000..e622446
--- /dev/null
@@ -0,0 +1,540 @@
+/*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) 2010-2012, Multicoreware, Inc., all rights reserved.
+// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//      Sen Liu, swjtuls1987@126.com
+//
+// 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 oclMaterials 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"
+#include "opencv2/video/tracking.hpp"
+
+using namespace std;
+using namespace cv;
+using namespace cv::ocl;
+
+#define MIN_SIZE 32
+
+namespace cv
+{
+namespace ocl
+{
+///////////////////////////OpenCL kernel strings///////////////////////////
+extern const char *optical_flow_farneback;
+}
+}
+
+namespace cv {
+namespace ocl {
+namespace optflow_farneback
+{
+oclMat g;
+oclMat xg;
+oclMat xxg;
+oclMat gKer;
+
+float ig[4];
+
+inline int divUp(int total, int grain)
+{
+    return (total + grain - 1) / grain;
+}
+
+inline void setGaussianBlurKernel(const float *c_gKer, int ksizeHalf)
+{
+    cv::Mat t_gKer(1, ksizeHalf + 1, CV_32FC1, const_cast<float *>(c_gKer));
+    gKer.upload(t_gKer);
+}
+
+static void gaussianBlurOcl(const oclMat &src, int ksizeHalf, oclMat &dst)
+{
+    string kernelName("gaussianBlur");
+    size_t localThreads[3] = { 256, 1, 1 };
+    size_t globalThreads[3] = { divUp(src.cols, localThreads[0]) * localThreads[0], src.rows, 1 };
+    int smem_size = (localThreads[0] + 2*ksizeHalf) * sizeof(float);
+
+    CV_Assert(dst.size() == src.size());
+    std::vector< std::pair<size_t, const void *> > args;
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&dst.data));
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&src.data));
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&gKer.data));
+    args.push_back(std::make_pair(smem_size, (void *)NULL));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&dst.rows));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&dst.cols));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&dst.step));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&src.step));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&ksizeHalf));
+
+    openCLExecuteKernel(Context::getContext(), &optical_flow_farneback, kernelName,
+                        globalThreads, localThreads, args, -1, -1);
+}
+
+static void polynomialExpansionOcl(const oclMat &src, int polyN, oclMat &dst)
+{
+    string kernelName("polynomialExpansion");
+    size_t localThreads[3] = { 256, 1, 1 };
+    size_t globalThreads[3] = { divUp(src.cols, localThreads[0] - 2*polyN) * localThreads[0], src.rows, 1 };
+    int smem_size = 3 * localThreads[0] * sizeof(float);
+
+    std::vector< std::pair<size_t, const void *> > args;
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&dst.data));
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&src.data));
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&g.data));
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&xg.data));
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&xxg.data));
+    args.push_back(std::make_pair(smem_size, (void *)NULL));
+    args.push_back(std::make_pair(sizeof(cl_float4), (void *)&ig));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&src.rows));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&src.cols));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&dst.step));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&src.step));
+
+    char opt [128];
+    sprintf(opt, "-D polyN=%d", polyN);
+
+    openCLExecuteKernel(Context::getContext(), &optical_flow_farneback, kernelName,
+                        globalThreads, localThreads, args, -1, -1, opt);
+}
+
+static void updateMatricesOcl(const oclMat &flowx, const oclMat &flowy, const oclMat &R0, const oclMat &R1, oclMat &M)
+{
+    string kernelName("updateMatrices");
+    size_t localThreads[3] = { 32, 8, 1 };
+    size_t globalThreads[3] = { divUp(flowx.cols, localThreads[0]) * localThreads[0],
+                                divUp(flowx.rows, localThreads[1]) * localThreads[1],
+                                1
+                              };
+
+    std::vector< std::pair<size_t, const void *> > args;
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&M.data));
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&flowx.data));
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&flowy.data));
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&R0.data));
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&R1.data));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&flowx.rows));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&flowx.cols));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&M.step));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&flowx.step));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&flowy.step));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&R0.step));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&R1.step));
+
+    openCLExecuteKernel(Context::getContext(), &optical_flow_farneback, kernelName,
+                        globalThreads, localThreads, args, -1, -1);
+}
+
+static void boxFilter5Ocl(const oclMat &src, int ksizeHalf, oclMat &dst)
+{
+    string kernelName("boxFilter5");
+    int height = src.rows / 5;
+    size_t localThreads[3] = { 256, 1, 1 };
+    size_t globalThreads[3] = { divUp(src.cols, localThreads[0]) * localThreads[0], height, 1 };
+    int smem_size = (localThreads[0] + 2*ksizeHalf) * 5 * sizeof(float);
+
+    std::vector< std::pair<size_t, const void *> > args;
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&dst.data));
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&src.data));
+    args.push_back(std::make_pair(smem_size, (void *)NULL));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&height));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&src.cols));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&dst.step));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&src.step));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&ksizeHalf));
+
+    openCLExecuteKernel(Context::getContext(), &optical_flow_farneback, kernelName,
+                        globalThreads, localThreads, args, -1, -1);
+}
+
+static void updateFlowOcl(const oclMat &M, oclMat &flowx, oclMat &flowy)
+{
+    string kernelName("updateFlow");
+    int cols = divUp(flowx.cols, 4);
+    size_t localThreads[3] = { 32, 8, 1 };
+    size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                divUp(flowx.rows, localThreads[1]) * localThreads[0],
+                                1
+                              };
+
+    std::vector< std::pair<size_t, const void *> > args;
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&flowx.data));
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&flowy.data));
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&M.data));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&flowx.rows));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&cols));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&flowx.step));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&flowy.step));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&M.step));
+
+    openCLExecuteKernel(Context::getContext(), &optical_flow_farneback, kernelName,
+                        globalThreads, localThreads, args, -1, -1);
+}
+
+static void gaussianBlur5Ocl(const oclMat &src, int ksizeHalf, oclMat &dst)
+{
+    string kernelName("gaussianBlur5");
+    int height = src.rows / 5;
+    int width = src.cols;
+    size_t localThreads[3] = { 256, 1, 1 };
+    size_t globalThreads[3] = { divUp(width, localThreads[0]) * localThreads[0], height, 1 };
+    int smem_size = (localThreads[0] + 2*ksizeHalf) * 5 * sizeof(float);
+
+    std::vector< std::pair<size_t, const void *> > args;
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&dst.data));
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&src.data));
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&gKer.data));
+    args.push_back(std::make_pair(smem_size, (void *)NULL));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&height));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&width));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&dst.step));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&src.step));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&ksizeHalf));
+
+    openCLExecuteKernel(Context::getContext(), &optical_flow_farneback, kernelName,
+                        globalThreads, localThreads, args, -1, -1);
+}
+}
+}
+} // namespace cv { namespace ocl { namespace optflow_farneback
+
+static oclMat allocMatFromBuf(int rows, int cols, int type, oclMat &mat)
+{
+    if (!mat.empty() && mat.type() == type && mat.rows >= rows && mat.cols >= cols)
+        return mat(Rect(0, 0, cols, rows));
+    return mat = oclMat(rows, cols, type);
+}
+
+cv::ocl::FarnebackOpticalFlow::FarnebackOpticalFlow()
+{
+    numLevels = 5;
+    pyrScale = 0.5;
+    fastPyramids = false;
+    winSize = 13;
+    numIters = 10;
+    polyN = 5;
+    polySigma = 1.1;
+    flags = 0;
+}
+
+void cv::ocl::FarnebackOpticalFlow::releaseMemory()
+{
+    frames_[0].release();
+    frames_[1].release();
+    pyrLevel_[0].release();
+    pyrLevel_[1].release();
+    M_.release();
+    bufM_.release();
+    R_[0].release();
+    R_[1].release();
+    blurredFrame_[0].release();
+    blurredFrame_[1].release();
+    pyramid0_.clear();
+    pyramid1_.clear();
+}
+
+void cv::ocl::FarnebackOpticalFlow::prepareGaussian(
+    int n, double sigma, float *g, float *xg, float *xxg,
+    double &ig11, double &ig03, double &ig33, double &ig55)
+{
+    double s = 0.;
+    for (int x = -n; x <= n; x++)
+    {
+        g[x] = (float)std::exp(-x*x/(2*sigma*sigma));
+        s += g[x];
+    }
+
+    s = 1./s;
+    for (int x = -n; x <= n; x++)
+    {
+        g[x] = (float)(g[x]*s);
+        xg[x] = (float)(x*g[x]);
+        xxg[x] = (float)(x*x*g[x]);
+    }
+
+    Mat_<double> G(6, 6);
+    G.setTo(0);
+
+    for (int y = -n; y <= n; y++)
+    {
+        for (int x = -n; x <= n; x++)
+        {
+            G(0,0) += g[y]*g[x];
+            G(1,1) += g[y]*g[x]*x*x;
+            G(3,3) += g[y]*g[x]*x*x*x*x;
+            G(5,5) += g[y]*g[x]*x*x*y*y;
+        }
+    }
+
+    //G[0][0] = 1.;
+    G(2,2) = G(0,3) = G(0,4) = G(3,0) = G(4,0) = G(1,1);
+    G(4,4) = G(3,3);
+    G(3,4) = G(4,3) = G(5,5);
+
+    // invG:
+    // [ x        e  e    ]
+    // [    y             ]
+    // [       y          ]
+    // [ e        z       ]
+    // [ e           z    ]
+    // [                u ]
+    Mat_<double> invG = G.inv(DECOMP_CHOLESKY);
+
+    ig11 = invG(1,1);
+    ig03 = invG(0,3);
+    ig33 = invG(3,3);
+    ig55 = invG(5,5);
+}
+
+void cv::ocl::FarnebackOpticalFlow::setPolynomialExpansionConsts(int n, double sigma)
+{
+    vector<float> buf(n*6 + 3);
+    float* g = &buf[0] + n;
+    float* xg = g + n*2 + 1;
+    float* xxg = xg + n*2 + 1;
+
+    if (sigma < FLT_EPSILON)
+        sigma = n*0.3;
+
+    double ig11, ig03, ig33, ig55;
+    prepareGaussian(n, sigma, g, xg, xxg, ig11, ig03, ig33, ig55);
+
+    cv::Mat t_g(1, n + 1, CV_32FC1, g);
+    cv::Mat t_xg(1, n + 1, CV_32FC1, xg);
+    cv::Mat t_xxg(1, n + 1, CV_32FC1, xxg);
+
+    optflow_farneback::g.upload(t_g);
+    optflow_farneback::xg.upload(t_xg);
+    optflow_farneback::xxg.upload(t_xxg);
+
+    optflow_farneback::ig[0] = static_cast<float>(ig11);
+    optflow_farneback::ig[1] = static_cast<float>(ig03);
+    optflow_farneback::ig[2] = static_cast<float>(ig33);
+    optflow_farneback::ig[3] = static_cast<float>(ig55);
+}
+
+void cv::ocl::FarnebackOpticalFlow::updateFlow_boxFilter(
+    const oclMat& R0, const oclMat& R1, oclMat& flowx, oclMat &flowy,
+    oclMat& M, oclMat &bufM, int blockSize, bool updateMatrices)
+{
+    optflow_farneback::boxFilter5Ocl(M, blockSize/2, bufM);
+
+    swap(M, bufM);
+
+    finish();
+
+    optflow_farneback::updateFlowOcl(M, flowx, flowy);
+
+    if (updateMatrices)
+        optflow_farneback::updateMatricesOcl(flowx, flowy, R0, R1, M);
+}
+
+
+void cv::ocl::FarnebackOpticalFlow::updateFlow_gaussianBlur(
+    const oclMat& R0, const oclMat& R1, oclMat& flowx, oclMat& flowy,
+    oclMat& M, oclMat &bufM, int blockSize, bool updateMatrices)
+{
+    optflow_farneback::gaussianBlur5Ocl(M, blockSize/2, bufM);
+
+    swap(M, bufM);
+
+    optflow_farneback::updateFlowOcl(M, flowx, flowy);
+
+    if (updateMatrices)
+        optflow_farneback::updateMatricesOcl(flowx, flowy, R0, R1, M);
+}
+
+
+void cv::ocl::FarnebackOpticalFlow::operator ()(
+    const oclMat &frame0, const oclMat &frame1, oclMat &flowx, oclMat &flowy)
+{
+    CV_Assert(frame0.channels() == 1 && frame1.channels() == 1);
+    CV_Assert(frame0.size() == frame1.size());
+    CV_Assert(polyN == 5 || polyN == 7);
+    CV_Assert(!fastPyramids || std::abs(pyrScale - 0.5) < 1e-6);
+
+    Size size = frame0.size();
+    oclMat prevFlowX, prevFlowY, curFlowX, curFlowY;
+
+    flowx.create(size, CV_32F);
+    flowy.create(size, CV_32F);
+    oclMat flowx0 = flowx;
+    oclMat flowy0 = flowy;
+
+    // Crop unnecessary levels
+    double scale = 1;
+    int numLevelsCropped = 0;
+    for (; numLevelsCropped < numLevels; numLevelsCropped++)
+    {
+        scale *= pyrScale;
+        if (size.width*scale < MIN_SIZE || size.height*scale < MIN_SIZE)
+            break;
+    }
+
+    frame0.convertTo(frames_[0], CV_32F);
+    frame1.convertTo(frames_[1], CV_32F);
+
+    if (fastPyramids)
+    {
+        // Build Gaussian pyramids using pyrDown()
+        pyramid0_.resize(numLevelsCropped + 1);
+        pyramid1_.resize(numLevelsCropped + 1);
+        pyramid0_[0] = frames_[0];
+        pyramid1_[0] = frames_[1];
+        for (int i = 1; i <= numLevelsCropped; ++i)
+        {
+            pyrDown(pyramid0_[i - 1], pyramid0_[i]);
+            pyrDown(pyramid1_[i - 1], pyramid1_[i]);
+        }
+    }
+
+    setPolynomialExpansionConsts(polyN, polySigma);
+
+    for (int k = numLevelsCropped; k >= 0; k--)
+    {
+        scale = 1;
+        for (int i = 0; i < k; i++)
+            scale *= pyrScale;
+
+        double sigma = (1./scale - 1) * 0.5;
+        int smoothSize = cvRound(sigma*5) | 1;
+        smoothSize = std::max(smoothSize, 3);
+
+        int width = cvRound(size.width*scale);
+        int height = cvRound(size.height*scale);
+
+        if (fastPyramids)
+        {
+            width = pyramid0_[k].cols;
+            height = pyramid0_[k].rows;
+        }
+
+        if (k > 0)
+        {
+            curFlowX.create(height, width, CV_32F);
+            curFlowY.create(height, width, CV_32F);
+        }
+        else
+        {
+            curFlowX = flowx0;
+            curFlowY = flowy0;
+        }
+
+        if (!prevFlowX.data)
+        {
+            if (flags & cv::OPTFLOW_USE_INITIAL_FLOW)
+            {
+                resize(flowx0, curFlowX, Size(width, height), 0, 0, INTER_LINEAR);
+                resize(flowy0, curFlowY, Size(width, height), 0, 0, INTER_LINEAR);
+                multiply(scale, curFlowX, curFlowX);
+                multiply(scale, curFlowY, curFlowY);
+            }
+            else
+            {
+                curFlowX.setTo(0);
+                curFlowY.setTo(0);
+            }
+        }
+        else
+        {
+            resize(prevFlowX, curFlowX, Size(width, height), 0, 0, INTER_LINEAR);
+            resize(prevFlowY, curFlowY, Size(width, height), 0, 0, INTER_LINEAR);
+            multiply(1./pyrScale, curFlowX, curFlowX);
+            multiply(1./pyrScale, curFlowY, curFlowY);
+        }
+
+        oclMat M = allocMatFromBuf(5*height, width, CV_32F, M_);
+        oclMat bufM = allocMatFromBuf(5*height, width, CV_32F, bufM_);
+        oclMat R[2] =
+        {
+            allocMatFromBuf(5*height, width, CV_32F, R_[0]),
+            allocMatFromBuf(5*height, width, CV_32F, R_[1])
+        };
+
+        if (fastPyramids)
+        {
+            optflow_farneback::polynomialExpansionOcl(pyramid0_[k], polyN, R[0]);
+            optflow_farneback::polynomialExpansionOcl(pyramid1_[k], polyN, R[1]);
+        }
+        else
+        {
+            oclMat blurredFrame[2] =
+            {
+                allocMatFromBuf(size.height, size.width, CV_32F, blurredFrame_[0]),
+                allocMatFromBuf(size.height, size.width, CV_32F, blurredFrame_[1])
+            };
+            oclMat pyrLevel[2] =
+            {
+                allocMatFromBuf(height, width, CV_32F, pyrLevel_[0]),
+                allocMatFromBuf(height, width, CV_32F, pyrLevel_[1])
+            };
+
+            Mat g = getGaussianKernel(smoothSize, sigma, CV_32F);
+            optflow_farneback::setGaussianBlurKernel(g.ptr<float>(smoothSize/2), smoothSize/2);
+
+            for (int i = 0; i < 2; i++)
+            {
+                optflow_farneback::gaussianBlurOcl(frames_[i], smoothSize/2, blurredFrame[i]);
+                resize(blurredFrame[i], pyrLevel[i], Size(width, height), INTER_LINEAR);
+                optflow_farneback::polynomialExpansionOcl(pyrLevel[i], polyN, R[i]);
+            }
+        }
+
+        optflow_farneback::updateMatricesOcl(curFlowX, curFlowY, R[0], R[1], M);
+
+        if (flags & OPTFLOW_FARNEBACK_GAUSSIAN)
+        {
+            Mat g = getGaussianKernel(winSize, winSize/2*0.3f, CV_32F);
+            optflow_farneback::setGaussianBlurKernel(g.ptr<float>(winSize/2), winSize/2);
+        }
+        for (int i = 0; i < numIters; i++)
+        {
+            if (flags & OPTFLOW_FARNEBACK_GAUSSIAN)
+                updateFlow_gaussianBlur(R[0], R[1], curFlowX, curFlowY, M, bufM, winSize, i < numIters-1);
+            else
+                updateFlow_boxFilter(R[0], R[1], curFlowX, curFlowY, M, bufM, winSize, i < numIters-1);
+        }
+
+        prevFlowX = curFlowX;
+        prevFlowY = curFlowY;
+    }
+
+    flowx = curFlowX;
+    flowy = curFlowY;
+}
index 4f93eac..8050b90 100644 (file)
@@ -52,9 +52,7 @@
 #pragma warning( disable: 4267 4324 4244 4251 4710 4711 4514 4996 )
 #endif
 
-#ifdef HAVE_CVCONFIG_H
 #include "cvconfig.h"
-#endif
 
 #include <map>
 #include <iostream>
diff --git a/modules/ocl/src/sort_by_key.cpp b/modules/ocl/src/sort_by_key.cpp
new file mode 100644 (file)
index 0000000..32af2a2
--- /dev/null
@@ -0,0 +1,454 @@
+/*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) 2010-2012, Multicoreware, Inc., all rights reserved.
+// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Peng Xiao, pengxiao@outlook.com
+//
+// 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 oclMaterials 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 <iomanip>
+#include "precomp.hpp"
+
+namespace cv
+{
+namespace ocl
+{
+
+extern const char * kernel_sort_by_key;
+extern const char * kernel_stablesort_by_key;
+extern const char * kernel_radix_sort_by_key;
+
+void sortByKey(oclMat& keys, oclMat& vals, size_t vecSize, int method, bool isGreaterThan);
+
+//TODO(pengx17): change this value depending on device other than a constant
+const static unsigned int GROUP_SIZE = 256;
+
+const char * depth_strings[] =
+{
+    "uchar",   //CV_8U
+    "char",    //CV_8S
+    "ushort",  //CV_16U
+    "short",   //CV_16S
+    "int",     //CV_32S
+    "float",   //CV_32F
+    "double"   //CV_64F
+};
+
+void static genSortBuildOption(const oclMat& keys, const oclMat& vals, bool isGreaterThan, char * build_opt_buf)
+{
+    sprintf(build_opt_buf, "-D IS_GT=%d -D K_T=%s -D V_T=%s",
+            isGreaterThan?1:0, depth_strings[keys.depth()], depth_strings[vals.depth()]);
+    if(vals.oclchannels() > 1)
+    {
+        sprintf( build_opt_buf + strlen(build_opt_buf), "%d", vals.oclchannels());
+    }
+}
+inline bool isSizePowerOf2(size_t size)
+{
+    return ((size - 1) & (size)) == 0;
+}
+
+namespace bitonic_sort
+{
+static void sortByKey(oclMat& keys, oclMat& vals, size_t vecSize, bool isGreaterThan)
+{
+    CV_Assert(isSizePowerOf2(vecSize));
+
+    Context * cxt = Context::getContext();
+    size_t globalThreads[3] = {vecSize / 2, 1, 1};
+    size_t localThreads[3]  = {GROUP_SIZE, 1, 1};
+
+    // 2^numStages should be equal to vecSize or the output is invalid
+    int numStages = 0;
+    for(int i = vecSize; i > 1; i >>= 1)
+    {
+        ++numStages;
+    }
+    char build_opt_buf [100];
+    genSortBuildOption(keys, vals, isGreaterThan, build_opt_buf);
+    const int argc = 5;
+    std::vector< std::pair<size_t, const void *> > args(argc);
+    String kernelname = "bitonicSort";
+
+    args[0] = std::make_pair(sizeof(cl_mem), (void *)&keys.data);
+    args[1] = std::make_pair(sizeof(cl_mem), (void *)&vals.data);
+    args[2] = std::make_pair(sizeof(cl_int), (void *)&vecSize);
+
+    for(int stage = 0; stage < numStages; ++stage)
+    {
+        args[3] = std::make_pair(sizeof(cl_int), (void *)&stage);
+        for(int passOfStage = 0; passOfStage < stage + 1; ++passOfStage)
+        {
+            args[4] = std::make_pair(sizeof(cl_int), (void *)&passOfStage);
+            openCLExecuteKernel(cxt, &kernel_sort_by_key, kernelname, globalThreads, localThreads, args, -1, -1, build_opt_buf);
+        }
+    }
+}
+}  /* bitonic_sort */
+
+namespace selection_sort
+{
+// FIXME:
+// This function cannot sort arrays with duplicated keys
+static void sortByKey(oclMat& keys, oclMat& vals, size_t vecSize, bool isGreaterThan)
+{
+    CV_Error(-1, "This function is incorrect at the moment.");
+    Context * cxt = Context::getContext();
+
+    size_t globalThreads[3] = {vecSize, 1, 1};
+    size_t localThreads[3]  = {GROUP_SIZE, 1, 1};
+
+    std::vector< std::pair<size_t, const void *> > args;
+    char build_opt_buf [100];
+    genSortBuildOption(keys, vals, isGreaterThan, build_opt_buf);
+
+    //local
+    String kernelname = "selectionSortLocal";
+    int lds_size = GROUP_SIZE * keys.elemSize();
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&keys.data));
+    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&vals.data));
+    args.push_back(std::make_pair(sizeof(cl_int), (void *)&vecSize));
+    args.push_back(std::make_pair(lds_size,       (void*)NULL));
+
+    openCLExecuteKernel(cxt, &kernel_sort_by_key, kernelname, globalThreads, localThreads, args, -1, -1, build_opt_buf);
+
+    //final
+    kernelname = "selectionSortFinal";
+    args.pop_back();
+    openCLExecuteKernel(cxt, &kernel_sort_by_key, kernelname, globalThreads, localThreads, args, -1, -1, build_opt_buf);
+}
+
+}  /* selection_sort */
+
+
+namespace radix_sort
+{
+//FIXME(pengx17): 
+// exclusive scan, need to be optimized as this is too naive...
+//void naive_scan_addition(oclMat& input, oclMat& output)
+//{
+//    Context * cxt = Context::getContext();
+//    size_t vecSize = input.cols;
+//    size_t globalThreads[3] = {1, 1, 1};
+//    size_t localThreads[3]  = {1, 1, 1};
+//
+//    String kernelname = "naiveScanAddition";
+//
+//    std::vector< std::pair<size_t, const void *> > args;
+//    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&input.data));
+//    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&output.data));
+//    args.push_back(std::make_pair(sizeof(cl_int), (void *)&vecSize));
+//    openCLExecuteKernel(cxt, &kernel_radix_sort_by_key, kernelname, globalThreads, localThreads, args, -1, -1);
+//}
+
+void static naive_scan_addition_cpu(oclMat& input, oclMat& output)
+{
+    Mat m_input = input, m_output(output.size(), output.type());
+    MatIterator_<int> i_mit = m_input.begin<int>();
+    MatIterator_<int> o_mit = m_output.begin<int>();
+    *o_mit = 0;
+    ++i_mit;
+    ++o_mit;
+    for(; i_mit != m_input.end<int>(); ++i_mit, ++o_mit)
+    {
+        *o_mit = *(o_mit - 1) + *(i_mit - 1);
+    }
+    output = m_output;
+}
+
+
+//radix sort ported from Bolt
+static void sortByKey(oclMat& keys, oclMat& vals, size_t origVecSize, bool isGreaterThan)
+{
+    CV_Assert(keys.depth() == CV_32S || keys.depth() == CV_32F); // we assume keys are 4 bytes
+
+    bool isKeyFloat = keys.type() == CV_32F;
+
+    const int RADIX = 4; //Now you cannot replace this with Radix 8 since there is a
+                         //local array of 16 elements in the histogram kernel.
+    const int RADICES = (1 << RADIX); //Values handeled by each work-item?
+
+    bool  newBuffer = false;
+    size_t vecSize = origVecSize;
+
+    unsigned int groupSize  = RADICES;
+
+    size_t mulFactor = groupSize * RADICES;
+
+    oclMat buffer_keys, buffer_vals;
+
+    if(origVecSize % mulFactor != 0)
+    {
+        vecSize = ((vecSize + mulFactor) / mulFactor) * mulFactor;
+        buffer_keys.create(1, vecSize, keys.type());
+        buffer_vals.create(1, vecSize, vals.type());
+        Scalar padding_value;
+        oclMat roi_buffer_vals = buffer_vals(Rect(0,0,origVecSize,1));
+
+        if(isGreaterThan)
+        {
+            switch(buffer_keys.depth())
+            {
+            case CV_32F:
+                padding_value = Scalar::all(-FLT_MAX);
+                break;
+            case CV_32S:
+                padding_value = Scalar::all(INT_MIN);
+                break;
+            }
+        }
+        else
+        {
+            switch(buffer_keys.depth())
+            {
+            case CV_32F:
+                padding_value = Scalar::all(FLT_MAX);
+                break;
+            case CV_32S:
+                padding_value = Scalar::all(INT_MAX);
+                break;
+            }
+        }
+        ocl::copyMakeBorder(
+            keys(Rect(0,0,origVecSize,1)), buffer_keys, 
+            0, 0, 0, vecSize - origVecSize, 
+            BORDER_CONSTANT, padding_value);
+        vals(Rect(0,0,origVecSize,1)).copyTo(roi_buffer_vals);
+        newBuffer = true;
+    }
+    else
+    {
+        buffer_keys = keys;
+        buffer_vals = vals;
+        newBuffer = false;
+    }
+    oclMat swap_input_keys(1, vecSize, keys.type());
+    oclMat swap_input_vals(1, vecSize, vals.type());
+    oclMat hist_bin_keys(1, vecSize, CV_32SC1);
+    oclMat hist_bin_dest_keys(1, vecSize, CV_32SC1);
+
+    Context * cxt = Context::getContext();
+
+    size_t globalThreads[3] = {vecSize / RADICES, 1, 1};
+    size_t localThreads[3]  = {groupSize, 1, 1};
+
+    std::vector< std::pair<size_t, const void *> > args;
+    char build_opt_buf [100];
+    genSortBuildOption(keys, vals, isGreaterThan, build_opt_buf);
+
+    //additional build option for radix sort
+    sprintf(build_opt_buf + strlen(build_opt_buf), " -D K_%s", isKeyFloat?"FLT":"INT"); 
+
+    String kernelnames[2] = {String("histogramRadixN"), String("permuteRadixN")};
+
+    int swap = 0;
+    for(int bits = 0; bits < (static_cast<int>(keys.elemSize()) * 8); bits += RADIX)
+    {
+        args.clear();
+        //Do a histogram pass locally
+        if(swap == 0)
+        {
+            args.push_back(std::make_pair(sizeof(cl_mem), (void *)&buffer_keys.data));
+        }
+        else
+        {
+            args.push_back(std::make_pair(sizeof(cl_mem), (void *)&swap_input_keys.data));
+        }
+        args.push_back(std::make_pair(sizeof(cl_mem), (void *)&hist_bin_keys.data));
+        args.push_back(std::make_pair(sizeof(cl_int), (void *)&bits));
+        openCLExecuteKernel(cxt, &kernel_radix_sort_by_key, kernelnames[0], globalThreads, localThreads,
+            args, -1, -1, build_opt_buf);
+
+        args.clear();
+        //Perform a global scan
+        naive_scan_addition_cpu(hist_bin_keys, hist_bin_dest_keys);
+        // end of scan
+        if(swap == 0)
+        {
+            args.push_back(std::make_pair(sizeof(cl_mem), (void *)&buffer_keys.data));
+            args.push_back(std::make_pair(sizeof(cl_mem), (void *)&buffer_vals.data));
+        }
+        else
+        {
+            args.push_back(std::make_pair(sizeof(cl_mem), (void *)&swap_input_keys.data));
+            args.push_back(std::make_pair(sizeof(cl_mem), (void *)&swap_input_vals.data));
+        }
+        args.push_back(std::make_pair(sizeof(cl_mem), (void *)&hist_bin_dest_keys.data));
+        args.push_back(std::make_pair(sizeof(cl_int), (void *)&bits));
+
+        if(swap == 0)
+        {
+            args.push_back(std::make_pair(sizeof(cl_mem), (void *)&swap_input_keys.data));
+            args.push_back(std::make_pair(sizeof(cl_mem), (void *)&swap_input_vals.data));
+        }
+        else
+        {
+            args.push_back(std::make_pair(sizeof(cl_mem), (void *)&buffer_keys.data));
+            args.push_back(std::make_pair(sizeof(cl_mem), (void *)&buffer_vals.data));
+        }
+        openCLExecuteKernel(cxt, &kernel_radix_sort_by_key, kernelnames[1], globalThreads, localThreads,
+            args, -1, -1, build_opt_buf);
+        swap = swap ? 0 : 1;
+    }
+    if(newBuffer)
+    {
+        buffer_keys(Rect(0,0,origVecSize,1)).copyTo(keys);
+        buffer_vals(Rect(0,0,origVecSize,1)).copyTo(vals);
+    }
+}
+
+}  /* radix_sort */
+
+namespace merge_sort
+{
+static void sortByKey(oclMat& keys, oclMat& vals, size_t vecSize, bool isGreaterThan)
+{
+    Context * cxt = Context::getContext();
+
+    size_t globalThreads[3] = {vecSize, 1, 1};
+    size_t localThreads[3]  = {GROUP_SIZE, 1, 1};
+
+    std::vector< std::pair<size_t, const void *> > args;
+    char build_opt_buf [100];
+    genSortBuildOption(keys, vals, isGreaterThan, build_opt_buf);
+
+    String kernelname[] = {String("blockInsertionSort"), String("merge")};
+    int keylds_size = GROUP_SIZE * keys.elemSize();
+    int vallds_size = GROUP_SIZE * vals.elemSize();
+    args.push_back(std::make_pair(sizeof(cl_mem),  (void *)&keys.data));
+    args.push_back(std::make_pair(sizeof(cl_mem),  (void *)&vals.data));
+    args.push_back(std::make_pair(sizeof(cl_uint), (void *)&vecSize));
+    args.push_back(std::make_pair(keylds_size,     (void*)NULL));
+    args.push_back(std::make_pair(vallds_size,     (void*)NULL));
+
+    openCLExecuteKernel(cxt, &kernel_stablesort_by_key, kernelname[0], globalThreads, localThreads, args, -1, -1, build_opt_buf);
+
+    //  Early exit for the case of no merge passes, values are already in destination vector
+    if(vecSize <= GROUP_SIZE)
+    {
+        return;
+    }
+
+    //  An odd number of elements requires an extra merge pass to sort
+    size_t numMerges = 0;
+    //  Calculate the log2 of vecSize, taking into acvecSize our block size from kernel 1 is 64
+    //  this is how many merge passes we want
+    size_t log2BlockSize = vecSize >> 6;
+    for( ; log2BlockSize > 1; log2BlockSize >>= 1 )
+    {
+        ++numMerges;
+    }
+    //  Check to see if the input vector size is a power of 2, if not we will need last merge pass
+    numMerges += isSizePowerOf2(vecSize)? 1: 0;
+
+    //  Allocate a flipflop buffer because the merge passes are out of place
+    oclMat tmpKeyBuffer(keys.size(), keys.type());
+    oclMat tmpValBuffer(vals.size(), vals.type());
+    args.resize(8);
+
+    args[4] = std::make_pair(sizeof(cl_uint), (void *)&vecSize);
+    args[6] = std::make_pair(keylds_size,    (void*)NULL);
+    args[7] = std::make_pair(vallds_size,    (void*)NULL);
+
+    for(size_t pass = 1; pass <= numMerges; ++pass )
+    {
+        //  For each pass, flip the input-output buffers
+        if( pass & 0x1 )
+        {
+            args[0] = std::make_pair(sizeof(cl_mem), (void *)&keys.data);
+            args[1] = std::make_pair(sizeof(cl_mem), (void *)&vals.data);
+            args[2] = std::make_pair(sizeof(cl_mem), (void *)&tmpKeyBuffer.data);
+            args[3] = std::make_pair(sizeof(cl_mem), (void *)&tmpValBuffer.data);
+        }
+        else
+        {
+            args[0] = std::make_pair(sizeof(cl_mem), (void *)&tmpKeyBuffer.data);
+            args[1] = std::make_pair(sizeof(cl_mem), (void *)&tmpValBuffer.data);
+            args[2] = std::make_pair(sizeof(cl_mem), (void *)&keys.data);
+            args[3] = std::make_pair(sizeof(cl_mem), (void *)&vals.data);
+        }
+        //  For each pass, the merge window doubles
+        unsigned int srcLogicalBlockSize = static_cast<unsigned int>( localThreads[0] << (pass-1) );
+        args[5] = std::make_pair(sizeof(cl_uint), (void *)&srcLogicalBlockSize);
+        openCLExecuteKernel(cxt, &kernel_stablesort_by_key, kernelname[1], globalThreads, localThreads, args, -1, -1, build_opt_buf);
+    }
+    //  If there are an odd number of merges, then the output data is sitting in the temp buffer.  We need to copy
+    //  the results back into the input array
+    if( numMerges & 1 )
+    {
+        tmpKeyBuffer.copyTo(keys);
+        tmpValBuffer.copyTo(vals);
+    }
+}
+}  /* merge_sort */
+
+}
+} /* namespace cv { namespace ocl */
+
+
+void cv::ocl::sortByKey(oclMat& keys, oclMat& vals, size_t vecSize, int method, bool isGreaterThan)
+{
+    CV_Assert( keys.rows == 1 ); // we only allow one dimensional input
+    CV_Assert( keys.channels() == 1 ); // we only allow one channel keys
+    CV_Assert( vecSize <= static_cast<size_t>(keys.cols) );
+    switch(method)
+    {
+    case SORT_BITONIC:
+        bitonic_sort::sortByKey(keys, vals, vecSize, isGreaterThan);
+        break;
+    case SORT_SELECTION:
+        selection_sort::sortByKey(keys, vals, vecSize, isGreaterThan);
+        break;
+    case SORT_RADIX:
+        radix_sort::sortByKey(keys, vals, vecSize, isGreaterThan);
+        break;
+    case SORT_MERGE:
+        merge_sort::sortByKey(keys, vals, vecSize, isGreaterThan);
+        break;
+    }
+}
+
+void cv::ocl::sortByKey(oclMat& keys, oclMat& vals, int method, bool isGreaterThan)
+{
+    CV_Assert( keys.size() == vals.size() );
+    CV_Assert( keys.rows == 1 ); // we only allow one dimensional input
+    size_t vecSize = static_cast<size_t>(keys.cols);
+    sortByKey(keys, vals, vecSize, method, isGreaterThan);
+}
index bd88ec0..cca1db3 100644 (file)
@@ -236,13 +236,13 @@ namespace cv
                 args.push_back( make_pair( sizeof(cl_int) , (void *)&t));
                 args.push_back( make_pair( sizeof(cl_int) , (void *)&cols));
                 args.push_back( make_pair( sizeof(cl_int) , (void *)&rows));
-                args.push_back( make_pair( sizeof(cl_int) , (void *)&cndisp));
                 args.push_back( make_pair( sizeof(cl_float) , (void *)&cmax_disc_term));
                 args.push_back( make_pair( sizeof(cl_float) , (void *)&cdisc_single_jump));
 
                 size_t gt[3] = {cols, rows, 1}, lt[3] = {16, 16, 1};
-                const char* t_opt  = data_type == CV_16S ? "-D T_SHORT":"-D T_FLOAT";
-                openCLExecuteKernel(clCxt, &stereobp, kernelName, gt, lt, args, -1, -1, t_opt);
+                char opt[80] = "";
+                sprintf(opt, "-D %s -D CNDISP=%d", data_type == CV_16S ? "T_SHORT":"T_FLOAT", cndisp);
+                openCLExecuteKernel(clCxt, &stereobp, kernelName, gt, lt, args, -1, -1, opt);
             }
 
             static void calc_all_iterations_calls(int cols, int rows, int iters, oclMat &u,
index dd46ff6..594c196 100644 (file)
@@ -39,7 +39,7 @@
 //
 //M*/
 
-#include "precomp.hpp"
+#include "test_precomp.hpp"
 
 #ifdef HAVE_OPENCL
 
@@ -73,14 +73,12 @@ void print_info()
 #endif
 
 }
-std::string workdir;
 int main(int argc, char **argv)
 {
-    TS::ptr()->init("ocl");
+    TS::ptr()->init(".");
     InitGoogleTest(&argc, argv);
     const char *keys =
         "{ h | help     | false              | print help message }"
-        "{ w | workdir  | ../../../samples/c/| set working directory }"
         "{ t | type     | gpu                | set device type:cpu or gpu}"
         "{ p | platform | 0                  | set platform id }"
         "{ d | device   | 0                  | set device id }";
@@ -92,7 +90,6 @@ int main(int argc, char **argv)
         cmd.printParams();
         return 0;
     }
-    workdir = cmd.get<string>("workdir");
     string type = cmd.get<string>("type");
     unsigned int pid = cmd.get<unsigned int>("platform");
     int device = cmd.get<int>("device");
@@ -118,6 +115,8 @@ int main(int argc, char **argv)
 
     setDevice(oclinfo[pid], device);
 
+    setBinaryDiskCache(CACHE_UPDATE);
+
     cout << "Device type:" << type << endl << "Device name:" << oclinfo[pid].DeviceName[device] << endl;
     return RUN_ALL_TESTS();
 }
diff --git a/modules/ocl/test/precomp.cpp b/modules/ocl/test/precomp.cpp
deleted file mode 100644 (file)
index 7d28700..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*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 "precomp.hpp"
-
-
index d12cef0..149c172 100644 (file)
@@ -54,7 +54,7 @@
 //#define PRINT_TIME
 
 
-#include "precomp.hpp"
+#include "test_precomp.hpp"
 #include <iomanip>
 
 #ifdef HAVE_OPENCL
index fa1aea1..9341981 100644 (file)
@@ -42,7 +42,7 @@
 // the use of this software, even if advised of the possibility of such damage.
 //
 //M*/
-#include "precomp.hpp"
+#include "test_precomp.hpp"
 #include <iomanip>
 
 using namespace cv;
index 11fdbb3..7d8fc36 100644 (file)
@@ -43,7 +43,7 @@
 //
 //M*/
 
-#include "precomp.hpp"
+#include "test_precomp.hpp"
 #ifdef HAVE_OPENCL
 namespace
 {
index 14fb31f..7e5c4a4 100644 (file)
 //
 //M*/
 
-#include "precomp.hpp"
+#include "test_precomp.hpp"
 #include <iomanip>
 
 #ifdef HAVE_OPENCL
 
 using namespace cv;
 
-extern std::string workdir;
 PARAM_TEST_CASE(StereoMatchBM, int, int)
 {
     int n_disp;
@@ -66,9 +65,9 @@ PARAM_TEST_CASE(StereoMatchBM, int, int)
 TEST_P(StereoMatchBM, Regression)
 {
 
-    Mat left_image  = readImage("stereobm/aloe-L.png", IMREAD_GRAYSCALE);
-    Mat right_image = readImage("stereobm/aloe-R.png", IMREAD_GRAYSCALE);
-    Mat disp_gold   = readImage("stereobm/aloe-disp.png", IMREAD_GRAYSCALE);
+    Mat left_image  = readImage("gpu/stereobm/aloe-L.png", IMREAD_GRAYSCALE);
+    Mat right_image = readImage("gpu/stereobm/aloe-R.png", IMREAD_GRAYSCALE);
+    Mat disp_gold   = readImage("gpu/stereobm/aloe-disp.png", IMREAD_GRAYSCALE);
     ocl::oclMat d_left, d_right;
     ocl::oclMat d_disp(left_image.size(), CV_8U);
     Mat  disp;
@@ -113,9 +112,9 @@ PARAM_TEST_CASE(StereoMatchBP, int, int, int, float, float, float, float)
 };
 TEST_P(StereoMatchBP, Regression)
 {
-    Mat left_image  = readImage("stereobp/aloe-L.png");
-    Mat right_image = readImage("stereobp/aloe-R.png");
-    Mat disp_gold   = readImage("stereobp/aloe-disp.png", IMREAD_GRAYSCALE);
+    Mat left_image  = readImage("gpu/stereobp/aloe-L.png");
+    Mat right_image = readImage("gpu/stereobp/aloe-R.png");
+    Mat disp_gold   = readImage("gpu/stereobp/aloe-disp.png", IMREAD_GRAYSCALE);
     ocl::oclMat d_left, d_right;
     ocl::oclMat d_disp;
     Mat  disp;
@@ -166,9 +165,9 @@ PARAM_TEST_CASE(StereoMatchConstSpaceBP, int, int, int, int, float, float, float
 };
 TEST_P(StereoMatchConstSpaceBP, Regression)
 {
-    Mat left_image  = readImage("csstereobp/aloe-L.png");
-    Mat right_image = readImage("csstereobp/aloe-R.png");
-    Mat disp_gold   = readImage("csstereobp/aloe-disp.png", IMREAD_GRAYSCALE);
+    Mat left_image  = readImage("gpu/csstereobp/aloe-L.png");
+    Mat right_image = readImage("gpu/csstereobp/aloe-R.png");
+    Mat disp_gold   = readImage("gpu/csstereobp/aloe-disp.png", IMREAD_GRAYSCALE);
 
     ocl::oclMat d_left, d_right;
     ocl::oclMat d_disp;
index 10032e8..6c6ea4e 100644 (file)
 //
 //M*/
 
-#include "precomp.hpp"
+#include "test_precomp.hpp"
 #ifdef HAVE_OPENCL
 
 ////////////////////////////////////////////////////////
 // Canny
-extern std::string workdir;
 IMPLEMENT_PARAM_CLASS(AppertureSize, int);
 IMPLEMENT_PARAM_CLASS(L2gradient, bool);
 
@@ -67,7 +66,7 @@ PARAM_TEST_CASE(Canny, AppertureSize, L2gradient)
 
 TEST_P(Canny, Accuracy)
 {
-    cv::Mat img = readImage(workdir + "fruits.jpg", cv::IMREAD_GRAYSCALE);
+    cv::Mat img = readImage("cv/shared/fruits.png", cv::IMREAD_GRAYSCALE);
     ASSERT_FALSE(img.empty());
 
     double low_thresh = 50.0;
index 9748104..a0293fc 100644 (file)
@@ -43,7 +43,7 @@
 //
 //M*/
 
-#include "precomp.hpp"
+#include "test_precomp.hpp"
 #ifdef HAVE_OPENCL
 
 //#define MAT_DEBUG
index fda55dd..08e70e2 100644 (file)
@@ -43,7 +43,7 @@
 //
 //M*/
 
-#include "precomp.hpp"
+#include "test_precomp.hpp"
 using namespace std;
 #ifdef HAVE_CLAMDFFT
 ////////////////////////////////////////////////////////////////////////////
index cfd5741..ec46a5c 100644 (file)
@@ -48,7 +48,7 @@
 //
 //M*/
 
-#include "precomp.hpp"
+#include "test_precomp.hpp"
 
 #ifdef HAVE_OPENCL
 
index 5548456..00d4287 100644 (file)
@@ -43,7 +43,7 @@
 //M*/
 
 
-#include "precomp.hpp"
+#include "test_precomp.hpp"
 using namespace std;
 #ifdef HAVE_CLAMDBLAS
 ////////////////////////////////////////////////////////////////////////////
diff --git a/modules/ocl/test/test_haar.cpp b/modules/ocl/test/test_haar.cpp
deleted file mode 100644 (file)
index 52ddbb7..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-/*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) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved.
-// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
-// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
-// Third party copyrights are property of their respective owners.
-//
-// @Authors
-//    Jia Haipeng, jiahaipeng95@gmail.com
-//    Sen Liu, swjutls1987@126.com
-//
-// 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 oclMaterials 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/objdetect/objdetect.hpp"
-#include "precomp.hpp"
-
-#ifdef HAVE_OPENCL
-
-using namespace cvtest;
-using namespace testing;
-using namespace std;
-using namespace cv;
-extern string workdir;
-
-namespace
-{
-IMPLEMENT_PARAM_CLASS(CascadeName, std::string);
-CascadeName cascade_frontalface_alt(std::string("haarcascade_frontalface_alt.xml"));
-CascadeName cascade_frontalface_alt2(std::string("haarcascade_frontalface_alt2.xml"));
-struct getRect
-{
-    Rect operator ()(const CvAvgComp &e) const
-    {
-        return e.rect;
-    }
-};
-}
-
-PARAM_TEST_CASE(Haar, double, int, CascadeName)
-{
-    cv::ocl::OclCascadeClassifier cascade, nestedCascade;
-    cv::CascadeClassifier cpucascade, cpunestedCascade;
-
-    double scale;
-    int flags;
-    std::string cascadeName;
-
-    virtual void SetUp()
-    {
-        scale = GET_PARAM(0);
-        flags = GET_PARAM(1);
-        cascadeName = (workdir + "../../data/haarcascades/").append(GET_PARAM(2));
-
-        if( (!cascade.load( cascadeName )) || (!cpucascade.load(cascadeName)) )
-        {
-            cout << "ERROR: Could not load classifier cascade" << endl;
-            return;
-        }
-    }
-};
-
-////////////////////////////////faceDetect/////////////////////////////////////////////////
-TEST_P(Haar, FaceDetect)
-{
-    string imgName = workdir + "lena.jpg";
-    Mat img = imread( imgName, 1 );
-
-    if(img.empty())
-    {
-        std::cout << "Couldn't read " << imgName << std::endl;
-        return ;
-    }
-
-    vector<Rect> faces, oclfaces;
-
-    Mat gray, smallImg(cvRound (img.rows / scale), cvRound(img.cols / scale), CV_8UC1 );
-    MemStorage storage(cvCreateMemStorage(0));
-    cvtColor( img, gray, CV_BGR2GRAY );
-    resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR );
-    equalizeHist( smallImg, smallImg );
-
-    cv::ocl::oclMat image;
-    CvSeq *_objects;
-    image.upload(smallImg);
-    _objects = cascade.oclHaarDetectObjects( image, storage, 1.1,
-                   3, flags, Size(30, 30), Size(0, 0) );
-    vector<CvAvgComp> vecAvgComp;
-    Seq<CvAvgComp>(_objects).copyTo(vecAvgComp);
-    oclfaces.resize(vecAvgComp.size());
-    std::transform(vecAvgComp.begin(), vecAvgComp.end(), oclfaces.begin(), getRect());
-    
-    cpucascade.detectMultiScale( smallImg, faces,  1.1, 3,
-                                 flags,
-                                 Size(30, 30), Size(0, 0) );
-    EXPECT_EQ(faces.size(), oclfaces.size());
-}
-
-TEST_P(Haar, FaceDetectUseBuf)
-{
-    string imgName = workdir + "lena.jpg";
-    Mat img = imread( imgName, 1 );
-
-    if(img.empty())
-    {
-        std::cout << "Couldn't read " << imgName << std::endl;
-        return ;
-    }
-
-    vector<Rect> faces, oclfaces;
-
-    Mat gray, smallImg(cvRound (img.rows / scale), cvRound(img.cols / scale), CV_8UC1 );
-    cvtColor( img, gray, CV_BGR2GRAY );
-    resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR );
-    equalizeHist( smallImg, smallImg );
-
-    cv::ocl::oclMat image;
-    image.upload(smallImg);
-
-    cv::ocl::OclCascadeClassifierBuf cascadebuf;
-    if( !cascadebuf.load( cascadeName ) )
-    {
-        cout << "ERROR: Could not load classifier cascade for FaceDetectUseBuf!" << endl;
-        return;
-    }
-    cascadebuf.detectMultiScale( image, oclfaces,  1.1, 3,
-                                 flags,
-                                 Size(30, 30), Size(0, 0) );
-
-    cpucascade.detectMultiScale( smallImg, faces,  1.1, 3,
-                                 flags,
-                                 Size(30, 30), Size(0, 0) );
-    EXPECT_EQ(faces.size(), oclfaces.size());
-
-    // intentionally run ocl facedetect again and check if it still works after the first run
-    cascadebuf.detectMultiScale( image, oclfaces,  1.1, 3,
-        flags,
-        Size(30, 30));
-    cascadebuf.release();
-    EXPECT_EQ(faces.size(), oclfaces.size());
-}
-
-INSTANTIATE_TEST_CASE_P(FaceDetect, Haar,
-    Combine(Values(1.0),
-            Values(CV_HAAR_SCALE_IMAGE, 0), Values(cascade_frontalface_alt, cascade_frontalface_alt2)));
-
-#endif // HAVE_OPENCL
diff --git a/modules/ocl/test/test_hog.cpp b/modules/ocl/test/test_hog.cpp
deleted file mode 100644 (file)
index cfc4e39..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-/*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) 2010-2012, Multicoreware, Inc., all rights reserved.
-// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
-// Third party copyrights are property of their respective owners.
-//
-// @Authors
-//             Wenju He, wenju@multicorewareinc.com
-//
-// 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 "precomp.hpp"
-#include "opencv2/core/core.hpp"
-using namespace std;
-#ifdef HAVE_OPENCL
-
-extern string workdir;
-PARAM_TEST_CASE(HOG, cv::Size, int)
-{
-    cv::Size winSize;
-    int type;
-    virtual void SetUp()
-    {
-        winSize = GET_PARAM(0);
-        type = GET_PARAM(1);
-    }
-};
-
-TEST_P(HOG, GetDescriptors)
-{
-    // Load image
-    cv::Mat img_rgb = readImage(workdir + "lena.jpg");
-    ASSERT_FALSE(img_rgb.empty());
-
-    // Convert image
-    cv::Mat img;
-    switch (type)
-    {
-    case CV_8UC1:
-        cv::cvtColor(img_rgb, img, CV_BGR2GRAY);
-        break;
-    case CV_8UC4:
-    default:
-        cv::cvtColor(img_rgb, img, CV_BGR2BGRA);
-        break;
-    }
-    cv::ocl::oclMat d_img(img);
-
-    // HOGs
-    cv::ocl::HOGDescriptor ocl_hog;
-    ocl_hog.gamma_correction = true;
-    cv::HOGDescriptor hog;
-    hog.gammaCorrection = true;
-
-    // Compute descriptor
-    cv::ocl::oclMat d_descriptors;
-    ocl_hog.getDescriptors(d_img, ocl_hog.win_size, d_descriptors, ocl_hog.DESCR_FORMAT_COL_BY_COL);
-    cv::Mat down_descriptors;
-    d_descriptors.download(down_descriptors);
-    down_descriptors = down_descriptors.reshape(0, down_descriptors.cols * down_descriptors.rows);
-
-    hog.setSVMDetector(hog.getDefaultPeopleDetector());
-    std::vector<float> descriptors;
-    switch (type)
-    {
-    case CV_8UC1:
-        hog.compute(img, descriptors, ocl_hog.win_size);
-        break;
-    case CV_8UC4:
-    default:
-        hog.compute(img_rgb, descriptors, ocl_hog.win_size);
-        break;
-    }
-    cv::Mat cpu_descriptors(descriptors);
-
-    EXPECT_MAT_SIMILAR(down_descriptors, cpu_descriptors, 1e-2);
-}
-
-
-bool match_rect(cv::Rect r1, cv::Rect r2, int threshold)
-{
-    return ((abs(r1.x - r2.x) < threshold) && (abs(r1.y - r2.y) < threshold) &&
-            (abs(r1.width - r2.width) < threshold) && (abs(r1.height - r2.height) < threshold));
-}
-
-TEST_P(HOG, Detect)
-{
-    // Load image
-    cv::Mat img_rgb = readImage(workdir + "lena.jpg");
-    ASSERT_FALSE(img_rgb.empty());
-
-    // Convert image
-    cv::Mat img;
-    switch (type)
-    {
-    case CV_8UC1:
-        cv::cvtColor(img_rgb, img, CV_BGR2GRAY);
-        break;
-    case CV_8UC4:
-    default:
-        cv::cvtColor(img_rgb, img, CV_BGR2BGRA);
-        break;
-    }
-    cv::ocl::oclMat d_img(img);
-
-    // HOGs
-    if ((winSize != cv::Size(48, 96)) && (winSize != cv::Size(64, 128)))
-        winSize = cv::Size(64, 128);
-    cv::ocl::HOGDescriptor ocl_hog(winSize);
-    ocl_hog.gamma_correction = true;
-
-    cv::HOGDescriptor hog;
-    hog.winSize = winSize;
-    hog.gammaCorrection = true;
-
-    if (winSize.width == 48 && winSize.height == 96)
-    {
-        // daimler's base
-        ocl_hog.setSVMDetector(ocl_hog.getPeopleDetector48x96());
-        hog.setSVMDetector(hog.getDaimlerPeopleDetector());
-    }
-    else if (winSize.width == 64 && winSize.height == 128)
-    {
-        ocl_hog.setSVMDetector(ocl_hog.getPeopleDetector64x128());
-        hog.setSVMDetector(hog.getDefaultPeopleDetector());
-    }
-    else
-    {
-        ocl_hog.setSVMDetector(ocl_hog.getDefaultPeopleDetector());
-        hog.setSVMDetector(hog.getDefaultPeopleDetector());
-    }
-
-    // OpenCL detection
-    std::vector<cv::Rect> d_found;
-    ocl_hog.detectMultiScale(d_img, d_found, 0, cv::Size(8, 8), cv::Size(0, 0), 1.05, 2);
-
-    // CPU detection
-    std::vector<cv::Rect> found;
-    switch (type)
-    {
-    case CV_8UC1:
-        hog.detectMultiScale(img, found, 0, cv::Size(8, 8), cv::Size(0, 0), 1.05, 2);
-        break;
-    case CV_8UC4:
-    default:
-        hog.detectMultiScale(img_rgb, found, 0, cv::Size(8, 8), cv::Size(0, 0), 1.05, 2);
-        break;
-    }
-
-    // Ground-truth rectangular people window
-    cv::Rect win1_64x128(231, 190, 72, 144);
-    cv::Rect win2_64x128(621, 156, 97, 194);
-    cv::Rect win1_48x96(238, 198, 63, 126);
-    cv::Rect win2_48x96(619, 161, 92, 185);
-    cv::Rect win3_48x96(488, 136, 56, 112);
-
-    // Compare whether ground-truth windows are detected and compare the number of windows detected.
-    std::vector<int> d_comp(4);
-    std::vector<int> comp(4);
-    for(int i = 0; i < (int)d_comp.size(); i++)
-    {
-        d_comp[i] = 0;
-        comp[i] = 0;
-    }
-
-    int threshold = 10;
-    int val = 32;
-    d_comp[0] = (int)d_found.size();
-    comp[0] = (int)found.size();
-    if (winSize == cv::Size(48, 96))
-    {
-        for(int i = 0; i < (int)d_found.size(); i++)
-        {
-            if (match_rect(d_found[i], win1_48x96, threshold))
-                d_comp[1] = val;
-            if (match_rect(d_found[i], win2_48x96, threshold))
-                d_comp[2] = val;
-            if (match_rect(d_found[i], win3_48x96, threshold))
-                d_comp[3] = val;
-        }
-        for(int i = 0; i < (int)found.size(); i++)
-        {
-            if (match_rect(found[i], win1_48x96, threshold))
-                comp[1] = val;
-            if (match_rect(found[i], win2_48x96, threshold))
-                comp[2] = val;
-            if (match_rect(found[i], win3_48x96, threshold))
-                comp[3] = val;
-        }
-    }
-    else if (winSize == cv::Size(64, 128))
-    {
-        for(int i = 0; i < (int)d_found.size(); i++)
-        {
-            if (match_rect(d_found[i], win1_64x128, threshold))
-                d_comp[1] = val;
-            if (match_rect(d_found[i], win2_64x128, threshold))
-                d_comp[2] = val;
-        }
-        for(int i = 0; i < (int)found.size(); i++)
-        {
-            if (match_rect(found[i], win1_64x128, threshold))
-                comp[1] = val;
-            if (match_rect(found[i], win2_64x128, threshold))
-                comp[2] = val;
-        }
-    }
-
-    EXPECT_MAT_NEAR(cv::Mat(d_comp), cv::Mat(comp), 3);
-}
-
-
-INSTANTIATE_TEST_CASE_P(OCL_ObjDetect, HOG, testing::Combine(
-                            testing::Values(cv::Size(64, 128), cv::Size(48, 96)),
-                            testing::Values(MatType(CV_8UC1), MatType(CV_8UC4))));
-
-
-#endif //HAVE_OPENCL
index b9f4740..225925c 100644 (file)
@@ -51,7 +51,7 @@
 //
 //M*/
 
-#include "precomp.hpp"
+#include "test_precomp.hpp"
 
 #ifdef HAVE_OPENCL
 
@@ -1425,7 +1425,7 @@ PARAM_TEST_CASE(CLAHE, cv::Size, ClipLimit)
 
 TEST_P(CLAHE, Accuracy)
 {
-    cv::Ptr<cv::ocl::CLAHE> clahe = cv::ocl::createCLAHE(clipLimit);
+    cv::Ptr<cv::CLAHE> clahe = cv::ocl::createCLAHE(clipLimit);
     clahe->apply(g_src, g_dst);
     cv::Mat dst(g_dst);
 
@@ -1573,6 +1573,47 @@ TEST_P(Convolve, Mat)
     }
 }
 
+//////////////////////////////// ColumnSum //////////////////////////////////////
+PARAM_TEST_CASE(ColumnSum, cv::Size)
+{
+    cv::Size size;
+    cv::Mat src;
+
+    virtual void SetUp()
+    {
+        size = GET_PARAM(0);
+    }
+};
+
+TEST_P(ColumnSum, Accuracy)
+{
+    cv::Mat src = randomMat(size, CV_32FC1);
+    cv::ocl::oclMat d_dst;
+    cv::ocl::oclMat d_src(src);
+
+    cv::ocl::columnSum(d_src, d_dst);
+
+    cv::Mat dst(d_dst);
+
+    for (int j = 0; j < src.cols; ++j)
+    {
+        float gold = src.at<float>(0, j);
+        float res = dst.at<float>(0, j);
+        ASSERT_NEAR(res, gold, 1e-5);
+    }
+
+    for (int i = 1; i < src.rows; ++i)
+    {
+        for (int j = 0; j < src.cols; ++j)
+        {
+            float gold = src.at<float>(i, j) += src.at<float>(i - 1, j);
+            float res = dst.at<float>(i, j);
+            ASSERT_NEAR(res, gold, 1e-5);
+        }
+    }
+}
+/////////////////////////////////////////////////////////////////////////////////////
+
 INSTANTIATE_TEST_CASE_P(ImgprocTestBase, equalizeHist, Combine(
                             ONE_TYPE(CV_8UC1),
                             NULL_TYPE,
@@ -1688,7 +1729,6 @@ INSTANTIATE_TEST_CASE_P(ImgProc, CLAHE, Combine(
                         Values(cv::Size(128, 128), cv::Size(113, 113), cv::Size(1300, 1300)),
                         Values(0.0, 40.0)));
 
-//INSTANTIATE_TEST_CASE_P(ConvolveTestBase, Convolve, Combine(
-//                            Values(CV_32FC1, CV_32FC1),
-//                            Values(false))); // Values(false) is the reserved parameter
+INSTANTIATE_TEST_CASE_P(OCL_ImgProc, ColumnSum, DIFFERENT_SIZES);
+
 #endif // HAVE_OPENCL
diff --git a/modules/ocl/test/test_kmeans.cpp b/modules/ocl/test/test_kmeans.cpp
new file mode 100644 (file)
index 0000000..a3e472b
--- /dev/null
@@ -0,0 +1,162 @@
+/*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) 2010-2012, Multicoreware, Inc., all rights reserved.
+// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Erping Pang,   pang_er_ping@163.com
+//    Xiaopeng Fu,   fuxiaopeng2222@163.com
+//
+// 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 oclMaterials 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"
+
+#ifdef HAVE_OPENCL
+
+using namespace cvtest;
+using namespace testing;
+using namespace std;
+using namespace cv;
+
+#define OCL_KMEANS_USE_INITIAL_LABELS 1
+#define OCL_KMEANS_PP_CENTERS         2
+
+PARAM_TEST_CASE(Kmeans, int, int, int)
+{
+    int type;
+    int K;
+    int flags;
+    cv::Mat src ;
+    ocl::oclMat d_src, d_dists;
+
+    Mat labels, centers;
+    ocl::oclMat d_labels, d_centers;
+    cv::RNG rng ;
+    virtual void SetUp(){
+        K = GET_PARAM(0);
+        type = GET_PARAM(1);
+        flags = GET_PARAM(2);
+        rng = TS::ptr()->get_rng();
+
+        // MWIDTH=256, MHEIGHT=256. defined in utility.hpp
+        cv::Size size = cv::Size(MWIDTH, MHEIGHT);
+        src.create(size, type);
+        int row_idx = 0;
+        const int max_neighbour = MHEIGHT / K - 1;
+        CV_Assert(K <= MWIDTH);
+        for(int i = 0; i < K; i++ )
+        {
+            Mat center_row_header = src.row(row_idx);
+            center_row_header.setTo(0);
+            int nchannel = center_row_header.channels();
+            for(int j = 0; j < nchannel; j++)
+                center_row_header.at<float>(0, i*nchannel+j) = 50000.0;
+
+            for(int j = 0; (j < max_neighbour) || 
+                           (i == K-1 && j < max_neighbour + MHEIGHT%K); j ++)
+            {
+                Mat cur_row_header = src.row(row_idx + 1 + j);
+                center_row_header.copyTo(cur_row_header);
+                Mat tmpmat = randomMat(rng, cur_row_header.size(), cur_row_header.type(), -200, 200, false);
+                cur_row_header += tmpmat;
+            }
+            row_idx += 1 + max_neighbour;
+        }
+    }
+};
+TEST_P(Kmeans, Mat){
+
+    if(flags & KMEANS_USE_INITIAL_LABELS)
+    {
+        // inital a given labels
+        labels.create(src.rows, 1, CV_32S);
+        int *label = labels.ptr<int>();
+        for(int i = 0; i < src.rows; i++)
+            label[i] = rng.uniform(0, K);
+        d_labels.upload(labels);
+    }
+    d_src.upload(src);
+
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        kmeans(src, K, labels,
+            TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 100, 0),
+            1, flags, centers);
+
+        ocl::kmeans(d_src, K, d_labels,
+            TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 100, 0),
+            1, flags, d_centers);
+  
+        Mat dd_labels(d_labels);
+        Mat dd_centers(d_centers);
+        if(flags & KMEANS_USE_INITIAL_LABELS)
+        {
+            EXPECT_MAT_NEAR(labels, dd_labels, 0);
+            EXPECT_MAT_NEAR(centers, dd_centers, 1e-3);
+        } 
+        else 
+        {
+            int row_idx = 0;
+            for(int i = 0; i < K; i++)
+            {
+                // verify lables with ground truth resutls
+                int label = labels.at<int>(row_idx);
+                int header_label = dd_labels.at<int>(row_idx);
+                for(int j = 0; (j < MHEIGHT/K)||(i == K-1 && j < MHEIGHT/K+MHEIGHT%K); j++)
+                {
+                    ASSERT_NEAR(labels.at<int>(row_idx+j), label, 0);
+                    ASSERT_NEAR(dd_labels.at<int>(row_idx+j), header_label, 0);
+                }
+
+                // verify centers
+                float *center = centers.ptr<float>(label);
+                float *header_center = dd_centers.ptr<float>(header_label);
+                for(int t = 0; t < centers.cols; t++)
+                    ASSERT_NEAR(center[t], header_center[t], 1e-3);
+
+                row_idx += MHEIGHT/K;
+            }
+        }
+    }
+}
+INSTANTIATE_TEST_CASE_P(OCL_ML, Kmeans, Combine(
+    Values(3, 5, 8),
+    Values(CV_32FC1, CV_32FC2, CV_32FC4),
+    Values(OCL_KMEANS_USE_INITIAL_LABELS/*, OCL_KMEANS_PP_CENTERS*/))); 
+
+#endif
index a393abd..551c9ff 100644 (file)
@@ -43,7 +43,7 @@
 //M*/
 
 
-#include "precomp.hpp"
+#include "test_precomp.hpp"
 
 #ifdef HAVE_OPENCL
 ////////////////////////////////////////////////////////////////////////////////
index 92d8108..e8b5022 100644 (file)
@@ -44,7 +44,7 @@
 //
 //M*/
 
-#include "precomp.hpp"
+#include "test_precomp.hpp"
 
 #ifdef HAVE_OPENCL
 
index 98c66de..65034ac 100644 (file)
@@ -1,4 +1,4 @@
-#include "precomp.hpp"
+#include "test_precomp.hpp"
 #include <iomanip>
 #include "opencv2/imgproc/imgproc_c.h"
 
@@ -45,12 +45,12 @@ TEST_P(MomentsTest, Mat)
     {
         if(test_contours)
         {
-            Mat src = imread( workdir + "../cpp/pic3.png", 1 );
-            Mat src_gray, canny_output;
-            cvtColor( src, src_gray, CV_BGR2GRAY );
+            Mat src = readImage( "cv/shared/pic3.png", IMREAD_GRAYSCALE );
+            ASSERT_FALSE(src.empty());
+            Mat canny_output;
             vector<vector<Point> > contours;
             vector<Vec4i> hierarchy;
-            Canny( src_gray, canny_output, 100, 200, 3 );
+            Canny( src, canny_output, 100, 200, 3 );
             findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
             for( size_t i = 0; i < contours.size(); i++ )
             {
diff --git a/modules/ocl/test/test_objdetect.cpp b/modules/ocl/test/test_objdetect.cpp
new file mode 100644 (file)
index 0000000..d75d991
--- /dev/null
@@ -0,0 +1,267 @@
+/*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) 2010-2012, Multicoreware, Inc., all rights reserved.
+// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//             Yao Wang, bitwangyaoyao@gmail.com
+//
+// 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"
+#include "opencv2/core/core.hpp"
+#include "opencv2/objdetect/objdetect.hpp"
+
+using namespace cv;
+using namespace testing;
+#ifdef HAVE_OPENCL
+
+extern string workdir;
+
+///////////////////// HOG /////////////////////////////
+PARAM_TEST_CASE(HOG, Size, int)
+{
+    Size winSize;
+    int type;
+    Mat img_rgb;
+    virtual void SetUp()
+    {
+        winSize = GET_PARAM(0);
+        type = GET_PARAM(1);
+        img_rgb = readImage("gpu/hog/road.png");
+        ASSERT_FALSE(img_rgb.empty());
+    }
+};
+
+TEST_P(HOG, GetDescriptors)
+{
+    // Convert image
+    Mat img;
+    switch (type)
+    {
+    case CV_8UC1:
+        cvtColor(img_rgb, img, CV_BGR2GRAY);
+        break;
+    case CV_8UC4:
+    default:
+        cvtColor(img_rgb, img, CV_BGR2BGRA);
+        break;
+    }
+    ocl::oclMat d_img(img);
+
+    // HOGs
+    ocl::HOGDescriptor ocl_hog;
+    ocl_hog.gamma_correction = true;
+    HOGDescriptor hog;
+    hog.gammaCorrection = true;
+
+    // Compute descriptor
+    ocl::oclMat d_descriptors;
+    ocl_hog.getDescriptors(d_img, ocl_hog.win_size, d_descriptors, ocl_hog.DESCR_FORMAT_COL_BY_COL);
+    Mat down_descriptors;
+    d_descriptors.download(down_descriptors);
+    down_descriptors = down_descriptors.reshape(0, down_descriptors.cols * down_descriptors.rows);
+
+    hog.setSVMDetector(hog.getDefaultPeopleDetector());
+    std::vector<float> descriptors;
+    switch (type)
+    {
+    case CV_8UC1:
+        hog.compute(img, descriptors, ocl_hog.win_size);
+        break;
+    case CV_8UC4:
+    default:
+        hog.compute(img_rgb, descriptors, ocl_hog.win_size);
+        break;
+    }
+    Mat cpu_descriptors(descriptors);
+
+    EXPECT_MAT_SIMILAR(down_descriptors, cpu_descriptors, 1e-2);
+}
+
+TEST_P(HOG, Detect)
+{
+    // Convert image
+    Mat img;
+    switch (type)
+    {
+    case CV_8UC1:
+        cvtColor(img_rgb, img, CV_BGR2GRAY);
+        break;
+    case CV_8UC4:
+    default:
+        cvtColor(img_rgb, img, CV_BGR2BGRA);
+        break;
+    }
+    ocl::oclMat d_img(img);
+
+    // HOGs
+    if ((winSize != Size(48, 96)) && (winSize != Size(64, 128)))
+        winSize = Size(64, 128);
+    ocl::HOGDescriptor ocl_hog(winSize);
+    ocl_hog.gamma_correction = true;
+
+    HOGDescriptor hog;
+    hog.winSize = winSize;
+    hog.gammaCorrection = true;
+
+    if (winSize.width == 48 && winSize.height == 96)
+    {
+        // daimler's base
+        ocl_hog.setSVMDetector(hog.getDaimlerPeopleDetector());
+        hog.setSVMDetector(hog.getDaimlerPeopleDetector());
+    }
+    else if (winSize.width == 64 && winSize.height == 128)
+    {
+        ocl_hog.setSVMDetector(hog.getDefaultPeopleDetector());
+        hog.setSVMDetector(hog.getDefaultPeopleDetector());
+    }
+    else
+    {
+        ocl_hog.setSVMDetector(hog.getDefaultPeopleDetector());
+        hog.setSVMDetector(hog.getDefaultPeopleDetector());
+    }
+
+    // OpenCL detection
+    std::vector<Rect> d_found;
+    ocl_hog.detectMultiScale(d_img, d_found, 0, Size(8, 8), Size(0, 0), 1.05, 6);
+
+    // CPU detection
+    std::vector<Rect> found;
+    switch (type)
+    {
+    case CV_8UC1:
+        hog.detectMultiScale(img, found, 0, Size(8, 8), Size(0, 0), 1.05, 6);
+        break;
+    case CV_8UC4:
+    default:
+        hog.detectMultiScale(img_rgb, found, 0, Size(8, 8), Size(0, 0), 1.05, 6);
+        break;
+    }
+
+    EXPECT_LT(checkRectSimilarity(img.size(), found, d_found), 1.0);
+}
+
+
+INSTANTIATE_TEST_CASE_P(OCL_ObjDetect, HOG, testing::Combine(
+                            testing::Values(Size(64, 128), Size(48, 96)),
+                            testing::Values(MatType(CV_8UC1), MatType(CV_8UC4))));
+
+///////////////////////////// Haar //////////////////////////////
+IMPLEMENT_PARAM_CLASS(CascadeName, std::string);
+CascadeName cascade_frontalface_alt(std::string("haarcascade_frontalface_alt.xml"));
+CascadeName cascade_frontalface_alt2(std::string("haarcascade_frontalface_alt2.xml"));
+struct getRect
+{
+    Rect operator ()(const CvAvgComp &e) const
+    {
+        return e.rect;
+    }
+};
+
+PARAM_TEST_CASE(Haar, int, CascadeName)
+{
+    ocl::OclCascadeClassifier cascade, nestedCascade;
+    CascadeClassifier cpucascade, cpunestedCascade;
+
+    int flags;
+    std::string cascadeName;
+    vector<Rect> faces, oclfaces;
+    Mat img;
+    ocl::oclMat d_img;
+
+    virtual void SetUp()
+    {
+        flags = GET_PARAM(0);
+        cascadeName = (string(cvtest::TS::ptr()->get_data_path()) + "cv/cascadeandhog/cascades/").append(GET_PARAM(1));
+        ASSERT_TRUE(cascade.load( cascadeName ));
+        ASSERT_TRUE(cpucascade.load(cascadeName));
+        img = readImage("cv/shared/lena.png", IMREAD_GRAYSCALE);
+        ASSERT_FALSE(img.empty());
+        equalizeHist(img, img);
+        d_img.upload(img);
+    }
+};
+
+TEST_P(Haar, FaceDetect)
+{
+    MemStorage storage(cvCreateMemStorage(0));
+    CvSeq *_objects;
+    _objects = cascade.oclHaarDetectObjects(d_img, storage, 1.1, 3, 
+                                            flags, Size(30, 30), Size(0, 0));
+    vector<CvAvgComp> vecAvgComp;
+    Seq<CvAvgComp>(_objects).copyTo(vecAvgComp);
+    oclfaces.resize(vecAvgComp.size());
+    std::transform(vecAvgComp.begin(), vecAvgComp.end(), oclfaces.begin(), getRect());
+    
+    cpucascade.detectMultiScale(img, faces,  1.1, 3,
+                                flags,
+                                Size(30, 30), Size(0, 0));
+
+    EXPECT_LT(checkRectSimilarity(img.size(), faces, oclfaces), 1.0);
+}
+
+TEST_P(Haar, FaceDetectUseBuf)
+{
+    ocl::OclCascadeClassifierBuf cascadebuf;
+    if(!cascadebuf.load(cascadeName))
+    {
+        std::cout << "ERROR: Could not load classifier cascade for FaceDetectUseBuf!" << std::endl;
+        return;
+    }
+    cascadebuf.detectMultiScale(d_img, oclfaces,  1.1, 3,
+                                flags,
+                                Size(30, 30), Size(0, 0));
+    cpucascade.detectMultiScale(img, faces,  1.1, 3,
+                                flags,
+                                Size(30, 30), Size(0, 0));
+
+    // intentionally run ocl facedetect again and check if it still works after the first run
+    cascadebuf.detectMultiScale(d_img, oclfaces,  1.1, 3,
+                                flags,
+                                Size(30, 30));
+    cascadebuf.release();
+
+    EXPECT_LT(checkRectSimilarity(img.size(), faces, oclfaces), 1.0);
+}
+
+INSTANTIATE_TEST_CASE_P(OCL_ObjDetect, Haar,
+    Combine(Values(CV_HAAR_SCALE_IMAGE, 0), 
+            Values(cascade_frontalface_alt/*, cascade_frontalface_alt2*/)));
+
+#endif //HAVE_OPENCL
\ No newline at end of file
index 0121be8..4693d46 100644 (file)
@@ -43,7 +43,7 @@
 //
 //M*/
 
-#include "precomp.hpp"
+#include "test_precomp.hpp"
 #include <iomanip>
 
 #ifdef HAVE_OPENCL
@@ -75,7 +75,7 @@ PARAM_TEST_CASE(GoodFeaturesToTrack, MinDistance)
 
 TEST_P(GoodFeaturesToTrack, Accuracy)
 {
-    cv::Mat frame = readImage(workdir + "../gpu/rubberwhale1.png", cv::IMREAD_GRAYSCALE);
+    cv::Mat frame = readImage("gpu/opticalflow/rubberwhale1.png", cv::IMREAD_GRAYSCALE);
     ASSERT_FALSE(frame.empty());
 
     int maxCorners = 1000;
@@ -146,10 +146,10 @@ PARAM_TEST_CASE(TVL1, bool)
 
 TEST_P(TVL1, Accuracy)
 {
-    cv::Mat frame0 = readImage(workdir + "../gpu/rubberwhale1.png", cv::IMREAD_GRAYSCALE);
+    cv::Mat frame0 = readImage("gpu/opticalflow/rubberwhale1.png", cv::IMREAD_GRAYSCALE);
     ASSERT_FALSE(frame0.empty());
 
-    cv::Mat frame1 = readImage(workdir + "../gpu/rubberwhale2.png", cv::IMREAD_GRAYSCALE);
+    cv::Mat frame1 = readImage("gpu/opticalflow/rubberwhale2.png", cv::IMREAD_GRAYSCALE);
     ASSERT_FALSE(frame1.empty());
 
     cv::ocl::OpticalFlowDual_TVL1_OCL d_alg;
@@ -188,10 +188,10 @@ PARAM_TEST_CASE(Sparse, bool, bool)
 
 TEST_P(Sparse, Mat)
 {
-    cv::Mat frame0 = readImage(workdir + "../gpu/rubberwhale1.png", useGray ? cv::IMREAD_GRAYSCALE : cv::IMREAD_COLOR);
+    cv::Mat frame0 = readImage("gpu/opticalflow/rubberwhale1.png", useGray ? cv::IMREAD_GRAYSCALE : cv::IMREAD_COLOR);
     ASSERT_FALSE(frame0.empty());
 
-    cv::Mat frame1 = readImage(workdir + "../gpu/rubberwhale2.png", useGray ? cv::IMREAD_GRAYSCALE : cv::IMREAD_COLOR);
+    cv::Mat frame1 = readImage("gpu/opticalflow/rubberwhale2.png", useGray ? cv::IMREAD_GRAYSCALE : cv::IMREAD_COLOR);
     ASSERT_FALSE(frame1.empty());
 
     cv::Mat gray_frame;
@@ -272,6 +272,78 @@ TEST_P(Sparse, Mat)
 INSTANTIATE_TEST_CASE_P(OCL_Video, Sparse, Combine(
     Values(false, true),
     Values(false, true)));
+//////////////////////////////////////////////////////
+// FarnebackOpticalFlow
+
+namespace
+{
+    IMPLEMENT_PARAM_CLASS(PyrScale, double)
+        IMPLEMENT_PARAM_CLASS(PolyN, int)
+        CV_FLAGS(FarnebackOptFlowFlags, 0, OPTFLOW_FARNEBACK_GAUSSIAN)
+        IMPLEMENT_PARAM_CLASS(UseInitFlow, bool)
+}
+
+PARAM_TEST_CASE(Farneback, PyrScale, PolyN, FarnebackOptFlowFlags, UseInitFlow)
+{
+    double pyrScale;
+    int polyN;
+    int flags;
+    bool useInitFlow;
+
+    virtual void SetUp()
+    {
+        pyrScale = GET_PARAM(0);
+        polyN = GET_PARAM(1);
+        flags = GET_PARAM(2);
+        useInitFlow = GET_PARAM(3);
+    }
+};
+
+TEST_P(Farneback, Accuracy)
+{
+    cv::Mat frame0 = readImage("gpu/opticalflow/rubberwhale1.png", cv::IMREAD_GRAYSCALE);
+    ASSERT_FALSE(frame0.empty());
+
+    cv::Mat frame1 = readImage("gpu/opticalflow/rubberwhale2.png", cv::IMREAD_GRAYSCALE);
+    ASSERT_FALSE(frame1.empty());
+
+    double polySigma = polyN <= 5 ? 1.1 : 1.5;
+
+    cv::ocl::FarnebackOpticalFlow farn;
+    farn.pyrScale = pyrScale;
+    farn.polyN = polyN;
+    farn.polySigma = polySigma;
+    farn.flags = flags;
+
+    cv::ocl::oclMat d_flowx, d_flowy;
+    farn(oclMat(frame0), oclMat(frame1), d_flowx, d_flowy);
+
+    cv::Mat flow;
+    if (useInitFlow)
+    {
+        cv::Mat flowxy[] = {cv::Mat(d_flowx), cv::Mat(d_flowy)};
+        cv::merge(flowxy, 2, flow);
+
+        farn.flags |= cv::OPTFLOW_USE_INITIAL_FLOW;
+        farn(oclMat(frame0), oclMat(frame1), d_flowx, d_flowy);
+    }
+
+    cv::calcOpticalFlowFarneback(
+        frame0, frame1, flow, farn.pyrScale, farn.numLevels, farn.winSize,
+        farn.numIters, farn.polyN, farn.polySigma, farn.flags);
+
+    std::vector<cv::Mat> flowxy;
+    cv::split(flow, flowxy);
+
+    EXPECT_MAT_SIMILAR(flowxy[0], d_flowx, 0.1);
+    EXPECT_MAT_SIMILAR(flowxy[1], d_flowy, 0.1);
+}
+
+INSTANTIATE_TEST_CASE_P(OCL_Video, Farneback, testing::Combine(
+    testing::Values(PyrScale(0.3), PyrScale(0.5), PyrScale(0.8)),
+    testing::Values(PolyN(5), PolyN(7)),
+    testing::Values(FarnebackOptFlowFlags(0), FarnebackOptFlowFlags(cv::OPTFLOW_FARNEBACK_GAUSSIAN)),
+    testing::Values(UseInitFlow(false), UseInitFlow(true))));
 
 #endif // HAVE_OPENCL
 
similarity index 75%
rename from modules/ocl/test/test_pyrdown.cpp
rename to modules/ocl/test/test_pyramids.cpp
index 6d00fb5..b7bc752 100644 (file)
@@ -15,7 +15,6 @@
 // Third party copyrights are property of their respective owners.
 //
 // @Authors
-//    Dachuan Zhao, dachuan@multicorewareinc.com
 //    Yao Wang yao@multicorewareinc.com
 //
 // Redistribution and use in source and binary forms, with or without modification,
@@ -45,7 +44,7 @@
 //M*/
 
 
-#include "precomp.hpp"
+#include "test_precomp.hpp"
 #include <iomanip>
 
 #ifdef HAVE_OPENCL
@@ -56,11 +55,12 @@ using namespace cvtest;
 using namespace testing;
 using namespace std;
 
-PARAM_TEST_CASE(PyrDown, MatType, int)
+PARAM_TEST_CASE(PyrBase, MatType, int)
 {
     int type;
     int channels;
-
+    Mat dst_cpu;
+    oclMat gdst;
     virtual void SetUp()
     {
         type = GET_PARAM(0);
@@ -69,19 +69,19 @@ PARAM_TEST_CASE(PyrDown, MatType, int)
 
 };
 
+/////////////////////// PyrDown //////////////////////////
+struct PyrDown : PyrBase {};
 
 TEST_P(PyrDown, Mat)
 {
     for(int j = 0; j < LOOP_TIMES; j++)
     {
-        cv::Size size(MWIDTH, MHEIGHT);
-        cv::RNG &rng = TS::ptr()->get_rng();
-        cv::Mat src = randomMat(rng, size, CV_MAKETYPE(type, channels), 0, 100, false);
-
-        cv::ocl::oclMat gsrc(src), gdst;
-        cv::Mat dst_cpu;
-        cv::pyrDown(src, dst_cpu);
-        cv::ocl::pyrDown(gsrc, gdst);
+        Size size(MWIDTH, MHEIGHT);
+        Mat src = randomMat(size, CV_MAKETYPE(type, channels));
+        oclMat gsrc(src);
+        
+        pyrDown(src, dst_cpu);
+        pyrDown(gsrc, gdst);
 
         EXPECT_MAT_NEAR(dst_cpu, Mat(gdst), type == CV_32F ? 1e-4f : 1.0f);
     }
@@ -90,5 +90,27 @@ TEST_P(PyrDown, Mat)
 INSTANTIATE_TEST_CASE_P(OCL_ImgProc, PyrDown, Combine(
                             Values(CV_8U, CV_32F), Values(1, 3, 4)));
 
+/////////////////////// PyrUp //////////////////////////
+
+struct PyrUp : PyrBase {};
+
+TEST_P(PyrUp, Accuracy)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        Size size(MWIDTH, MHEIGHT);
+        Mat src = randomMat(size, CV_MAKETYPE(type, channels));
+        oclMat gsrc(src);
+
+        pyrUp(src, dst_cpu);
+        pyrUp(gsrc, gdst);
+
+        EXPECT_MAT_NEAR(dst_cpu, Mat(gdst), (type == CV_32F ? 1e-4f : 1.0));
+    }
 
+}
+
+
+INSTANTIATE_TEST_CASE_P(OCL_ImgProc, PyrUp, testing::Combine(
+                            Values(CV_8U, CV_32F), Values(1, 3, 4)));
 #endif // HAVE_OPENCL
diff --git a/modules/ocl/test/test_sort.cpp b/modules/ocl/test/test_sort.cpp
new file mode 100644 (file)
index 0000000..83326a5
--- /dev/null
@@ -0,0 +1,244 @@
+/*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) 2010-2012, Multicoreware, Inc., all rights reserved.
+// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Peng Xiao, pengxiao@outlook.com
+//
+// 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 oclMaterials 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 <map>
+#include <functional>
+#include "test_precomp.hpp"
+
+using namespace std;
+using namespace cvtest;
+using namespace testing;
+using namespace cv;
+
+
+namespace
+{
+IMPLEMENT_PARAM_CLASS(IsGreaterThan, bool)
+IMPLEMENT_PARAM_CLASS(InputSize, int)
+IMPLEMENT_PARAM_CLASS(SortMethod, int)
+
+
+template<class T> 
+struct KV_CVTYPE{ static int toType() {return 0;} };
+
+template<> struct KV_CVTYPE<int>  { static int toType() {return CV_32SC1;} };
+template<> struct KV_CVTYPE<float>{ static int toType() {return CV_32FC1;} };
+template<> struct KV_CVTYPE<Vec2i>{ static int toType() {return CV_32SC2;} };
+template<> struct KV_CVTYPE<Vec2f>{ static int toType() {return CV_32FC2;} };
+
+template<class key_type, class val_type>
+bool kvgreater(pair<key_type, val_type> p1, pair<key_type, val_type> p2)
+{
+    return p1.first > p2.first;
+}
+
+template<class key_type, class val_type>
+bool kvless(pair<key_type, val_type> p1, pair<key_type, val_type> p2)
+{
+    return p1.first < p2.first;
+}
+
+template<class key_type, class val_type>
+void toKVPair(
+    MatConstIterator_<key_type> kit,
+    MatConstIterator_<val_type> vit,
+    int vecSize,
+    vector<pair<key_type, val_type> >& kvres
+    )
+{
+    kvres.clear();
+    for(int i = 0; i < vecSize; i ++)
+    {
+        kvres.push_back(make_pair(*kit, *vit));
+        ++kit;
+        ++vit;
+    }
+}
+
+template<class key_type, class val_type>
+void kvquicksort(Mat& keys, Mat& vals, bool isGreater = false)
+{
+    vector<pair<key_type, val_type> > kvres;
+    toKVPair(keys.begin<key_type>(), vals.begin<val_type>(), keys.cols, kvres);
+    
+    if(isGreater)
+    {
+        std::sort(kvres.begin(), kvres.end(), kvgreater<key_type, val_type>);
+    }
+    else
+    {
+        std::sort(kvres.begin(), kvres.end(), kvless<key_type, val_type>);
+    }
+    key_type * kptr = keys.ptr<key_type>();
+    val_type * vptr = vals.ptr<val_type>();
+    for(int i = 0; i < keys.cols; i ++)
+    {
+        kptr[i] = kvres[i].first;
+        vptr[i] = kvres[i].second;
+    }
+}
+
+class SortByKey_STL
+{
+public:
+    static void sort(cv::Mat&, cv::Mat&, bool is_gt);
+private:
+    typedef void (*quick_sorter)(cv::Mat&, cv::Mat&, bool);
+    SortByKey_STL();
+    quick_sorter quick_sorters[CV_64FC4][CV_64FC4];
+    static SortByKey_STL instance;
+};
+
+SortByKey_STL SortByKey_STL::instance = SortByKey_STL();
+
+SortByKey_STL::SortByKey_STL()
+{
+    memset(instance.quick_sorters, 0, sizeof(quick_sorters));
+#define NEW_SORTER(KT, VT) \
+    instance.quick_sorters[KV_CVTYPE<KT>::toType()][KV_CVTYPE<VT>::toType()] = kvquicksort<KT, VT>;
+
+    NEW_SORTER(int, int);
+    NEW_SORTER(int, Vec2i);
+    NEW_SORTER(int, float);
+    NEW_SORTER(int, Vec2f);
+
+    NEW_SORTER(float, int);
+    NEW_SORTER(float, Vec2i);
+    NEW_SORTER(float, float);
+    NEW_SORTER(float, Vec2f);
+#undef NEW_SORTER
+}
+
+void SortByKey_STL::sort(cv::Mat& keys, cv::Mat& vals, bool is_gt)
+{
+    instance.quick_sorters[keys.type()][vals.type()](keys, vals, is_gt);
+}
+
+bool checkUnstableSorterResult(const Mat& gkeys_, const Mat& gvals_,
+                               const Mat& /*dkeys_*/, const Mat& dvals_)
+{
+    int cn_val = gvals_.channels();
+    int count  = gkeys_.cols;
+
+    //for convenience we convert depth to float and channels to 1
+    Mat gkeys, gvals, dkeys, dvals;
+    gkeys_.reshape(1).convertTo(gkeys, CV_32F);
+    gvals_.reshape(1).convertTo(gvals, CV_32F);
+    //dkeys_.reshape(1).convertTo(dkeys, CV_32F);
+    dvals_.reshape(1).convertTo(dvals, CV_32F);
+    float * gkptr = gkeys.ptr<float>();
+    float * gvptr = gvals.ptr<float>();
+    //float * dkptr = dkeys.ptr<float>();
+    float * dvptr = dvals.ptr<float>();
+
+    for(int i = 0; i < count - 1; ++i)
+    {
+        int iden_count = 0;
+        // firstly calculate the number of identical keys
+        while(gkptr[i + iden_count] == gkptr[i + 1 + iden_count])
+        {
+            ++ iden_count;
+        }
+        
+        // sort dv and gv
+        int num_of_val = (iden_count + 1) * cn_val;
+        std::sort(gvptr + i * cn_val, gvptr + i * cn_val + num_of_val);
+        std::sort(dvptr + i * cn_val, dvptr + i * cn_val + num_of_val);
+
+        // then check if [i, i + iden_count) is the same
+        for(int j = 0; j < num_of_val; ++j)
+        {
+            if(gvptr[i + j] != dvptr[i + j])
+            {
+                return false;
+            }
+        }
+        i += iden_count;
+    }
+    return true;
+}
+}
+
+#define INPUT_SIZES  Values(InputSize(0x10), InputSize(0x100), InputSize(0x10000)) //2^4, 2^8, 2^16
+#define KEY_TYPES    Values(MatType(CV_32SC1), MatType(CV_32FC1))
+#define VAL_TYPES    Values(MatType(CV_32SC1), MatType(CV_32SC2), MatType(CV_32FC1), MatType(CV_32FC2))
+#define SORT_METHODS Values(SortMethod(cv::ocl::SORT_BITONIC),SortMethod(cv::ocl::SORT_MERGE),SortMethod(cv::ocl::SORT_RADIX)/*,SortMethod(cv::ocl::SORT_SELECTION)*/)
+#define F_OR_T       Values(IsGreaterThan(false), IsGreaterThan(true))
+
+PARAM_TEST_CASE(SortByKey, InputSize, MatType, MatType, SortMethod, IsGreaterThan)
+{
+    InputSize input_size;
+    MatType key_type, val_type;
+    SortMethod method;
+    IsGreaterThan is_gt;
+
+    Mat mat_key, mat_val;
+    virtual void SetUp()
+    {
+        input_size = GET_PARAM(0);
+        key_type   = GET_PARAM(1);
+        val_type   = GET_PARAM(2);
+        method     = GET_PARAM(3);
+        is_gt      = GET_PARAM(4);
+
+        using namespace cv;
+        // fill key and val
+        mat_key = randomMat(Size(input_size, 1), key_type, INT_MIN, INT_MAX);
+        mat_val = randomMat(Size(input_size, 1), val_type, INT_MIN, INT_MAX);
+    }
+};
+
+TEST_P(SortByKey, Accuracy)
+{
+    using namespace cv;
+    ocl::oclMat oclmat_key(mat_key);
+    ocl::oclMat oclmat_val(mat_val);
+
+    ocl::sortByKey(oclmat_key, oclmat_val, method, is_gt);
+    SortByKey_STL::sort(mat_key, mat_val, is_gt);
+
+    EXPECT_MAT_NEAR(mat_key, oclmat_key, 0.0);
+    EXPECT_TRUE(checkUnstableSorterResult(mat_key, mat_val, oclmat_key, oclmat_val));
+}
+INSTANTIATE_TEST_CASE_P(OCL_SORT, SortByKey, Combine(INPUT_SIZES, KEY_TYPES, VAL_TYPES, SORT_METHODS, F_OR_T));
index 854ce30..9663f53 100644 (file)
@@ -44,7 +44,7 @@
 //
 //M*/
 
-#include "precomp.hpp"
+#include "test_precomp.hpp"
 
 #ifdef HAVE_OPENCL
 
index 4b21081..440a89d 100644 (file)
@@ -39,7 +39,7 @@
 //
 //M*/
 
-#include "precomp.hpp"
+#include "test_precomp.hpp"
 #define VARNAME(A) #A
 using namespace std;
 using namespace cv;
@@ -100,12 +100,6 @@ Mat randomMat(Size size, int type, double minVal, double maxVal)
     return randomMat(TS::ptr()->get_rng(), size, type, minVal, maxVal, false);
 }
 
-
-
-
-
-
-
 /*
 void showDiff(InputArray gold_, InputArray actual_, double eps)
 {
@@ -137,58 +131,7 @@ void showDiff(InputArray gold_, InputArray actual_, double eps)
 }
 */
 
-/*
-bool supportFeature(const DeviceInfo& info, FeatureSet feature)
-{
-    return TargetArchs::builtWith(feature) && info.supports(feature);
-}
-
-const vector<DeviceInfo>& devices()
-{
-    static vector<DeviceInfo> devs;
-    static bool first = true;
-
-    if (first)
-    {
-        int deviceCount = getCudaEnabledDeviceCount();
-
-        devs.reserve(deviceCount);
-
-        for (int i = 0; i < deviceCount; ++i)
-        {
-            DeviceInfo info(i);
-            if (info.isCompatible())
-                devs.push_back(info);
-        }
-
-        first = false;
-    }
-
-    return devs;
-}
 
-vector<DeviceInfo> devices(FeatureSet feature)
-{
-    const vector<DeviceInfo>& d = devices();
-
-    vector<DeviceInfo> devs_filtered;
-
-    if (TargetArchs::builtWith(feature))
-    {
-        devs_filtered.reserve(d.size());
-
-        for (size_t i = 0, size = d.size(); i < size; ++i)
-        {
-            const DeviceInfo& info = d[i];
-
-            if (info.supports(feature))
-                devs_filtered.push_back(info);
-        }
-    }
-
-    return devs_filtered;
-}
-*/
 
 vector<MatType> types(int depth_start, int depth_end, int cn_start, int cn_end)
 {
@@ -264,3 +207,48 @@ void PrintTo(const Inverse &inverse, std::ostream *os)
         (*os) << "direct";
 }
 
+double checkRectSimilarity(Size sz, std::vector<Rect>& ob1, std::vector<Rect>& ob2)
+{
+    double final_test_result = 0.0;
+    size_t sz1 = ob1.size();
+    size_t sz2 = ob2.size();
+
+    if(sz1 != sz2)
+    {
+        return sz1 > sz2 ? (double)(sz1 - sz2) : (double)(sz2 - sz1);
+    }
+    else
+    {
+        if(sz1==0 && sz2==0)
+            return 0;
+        cv::Mat cpu_result(sz, CV_8UC1);
+        cpu_result.setTo(0);
+
+        for(vector<Rect>::const_iterator r = ob1.begin(); r != ob1.end(); r++)
+        {      
+            cv::Mat cpu_result_roi(cpu_result, *r);
+            cpu_result_roi.setTo(1);
+            cpu_result.copyTo(cpu_result);
+        }
+        int cpu_area = cv::countNonZero(cpu_result > 0);
+
+        cv::Mat gpu_result(sz, CV_8UC1);
+        gpu_result.setTo(0);
+        for(vector<Rect>::const_iterator r2 = ob2.begin(); r2 != ob2.end(); r2++)
+        {
+            cv::Mat gpu_result_roi(gpu_result, *r2);
+            gpu_result_roi.setTo(1);
+            gpu_result.copyTo(gpu_result);
+        }
+
+        cv::Mat result_;
+        multiply(cpu_result, gpu_result, result_);
+        int result = cv::countNonZero(result_ > 0);
+        if(cpu_area!=0 && result!=0)
+            final_test_result = 1.0 - (double)result/(double)cpu_area;
+        else if(cpu_area==0 && result!=0)
+            final_test_result = -1;
+    }
+    return final_test_result;
+}
+
index 42fa693..0b101ec 100644 (file)
@@ -55,13 +55,12 @@ cv::Mat randomMat(cv::Size size, int type, double minVal = 0.0, double maxVal =
 
 void showDiff(cv::InputArray gold, cv::InputArray actual, double eps);
 
-//! return true if device supports specified feature and gpu module was built with support the feature.
-//bool supportFeature(const cv::gpu::DeviceInfo& info, cv::gpu::FeatureSet feature);
+// This function test if gpu_rst matches cpu_rst.
+// If the two vectors are not equal, it will return the difference in vector size
+// Else it will return (total diff of each cpu and gpu rects covered pixels)/(total cpu rects covered pixels)
+// The smaller, the better matched
+double checkRectSimilarity(cv::Size sz, std::vector<cv::Rect>& ob1, std::vector<cv::Rect>& ob2);
 
-//! return all devices compatible with current gpu module build.
-//const std::vector<cv::ocl::DeviceInfo>& devices();
-//! return all devices compatible with current gpu module build which support specified feature.
-//std::vector<cv::ocl::DeviceInfo> devices(cv::gpu::FeatureSet feature);
 
 //! read image from testdata folder.
 cv::Mat readImage(const std::string &fileName, int flags = cv::IMREAD_COLOR);
index ef69ebc..6c96796 100644 (file)
@@ -31,3 +31,9 @@ Restores the selected region in an image using the region neighborhood.
 The function reconstructs the selected image area from the pixel near the area boundary. The function may be used to remove dust and scratches from a scanned photo, or to remove undesirable objects from still images or video. See
 http://en.wikipedia.org/wiki/Inpainting
 for more details.
+
+.. note::
+
+   * An example using the inpainting technique can be found at opencv_source_code/samples/cpp/inpaint.cpp
+
+   * (Python) An example using the inpainting technique can be found at opencv_source_code/samples/python2/inpaint.py
\ No newline at end of file
diff --git a/modules/photo/perf/perf_precomp.cpp b/modules/photo/perf/perf_precomp.cpp
deleted file mode 100644 (file)
index 8552ac3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "perf_precomp.hpp"
diff --git a/modules/photo/src/precomp.cpp b/modules/photo/src/precomp.cpp
deleted file mode 100644 (file)
index 3e0ec42..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*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 "precomp.hpp"
-
-/* End of file. */
index 3185a18..1968676 100644 (file)
@@ -43,9 +43,7 @@
 #ifndef __OPENCV_PRECOMP_H__
 #define __OPENCV_PRECOMP_H__
 
-#ifdef HAVE_CVCONFIG_H
 #include "cvconfig.h"
-#endif
 
 #include "opencv2/photo/photo.hpp"
 
diff --git a/modules/photo/test/test_precomp.cpp b/modules/photo/test/test_precomp.cpp
deleted file mode 100644 (file)
index 5956e13..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "test_precomp.hpp"
index 610d718..745914c 100644 (file)
@@ -6,6 +6,7 @@
 
 #define MODULESTR "cv2"
 
+#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
 #include "numpy/ndarrayobject.h"
 
 #include "opencv2/core/core.hpp"
@@ -194,10 +195,10 @@ public:
         if(!o)
             CV_Error_(CV_StsError, ("The numpy array of typenum=%d, ndims=%d can not be created", typenum, dims));
         refcount = refcountFromPyObject(o);
-        npy_intp* _strides = PyArray_STRIDES(o);
+        npy_intp* _strides = PyArray_STRIDES((PyArrayObject*) o);
         for( i = 0; i < dims - (cn > 1); i++ )
             step[i] = (size_t)_strides[i];
-        datastart = data = (uchar*)PyArray_DATA(o);
+        datastart = data = (uchar*)PyArray_DATA((PyArrayObject*) o);
     }
 
     void deallocate(int* refcount, uchar*, uchar*)
@@ -264,8 +265,10 @@ static int pyopencv_to(const PyObject* o, Mat& m, const ArgInfo info, bool allow
         return false;
     }
 
+    PyArrayObject* oarr = (PyArrayObject*) o;
+
     bool needcopy = false, needcast = false;
-    int typenum = PyArray_TYPE(o), new_typenum = typenum;
+    int typenum = PyArray_TYPE(oarr), new_typenum = typenum;
     int type = typenum == NPY_UBYTE ? CV_8U :
                typenum == NPY_BYTE ? CV_8S :
                typenum == NPY_USHORT ? CV_16U :
@@ -290,7 +293,7 @@ static int pyopencv_to(const PyObject* o, Mat& m, const ArgInfo info, bool allow
         }
     }
 
-    int ndims = PyArray_NDIM(o);
+    int ndims = PyArray_NDIM(oarr);
     if(ndims >= CV_MAX_DIM)
     {
         failmsg("%s dimensionality (=%d) is too high", info.name, ndims);
@@ -299,8 +302,8 @@ static int pyopencv_to(const PyObject* o, Mat& m, const ArgInfo info, bool allow
 
     int size[CV_MAX_DIM+1];
     size_t step[CV_MAX_DIM+1], elemsize = CV_ELEM_SIZE1(type);
-    const npy_intp* _sizes = PyArray_DIMS(o);
-    const npy_intp* _strides = PyArray_STRIDES(o);
+    const npy_intp* _sizes = PyArray_DIMS(oarr);
+    const npy_intp* _strides = PyArray_STRIDES(oarr);
     bool ismultichannel = ndims == 3 && _sizes[2] <= CV_CN_MAX;
 
     for( int i = ndims-1; i >= 0 && !needcopy; i-- )
@@ -324,11 +327,17 @@ static int pyopencv_to(const PyObject* o, Mat& m, const ArgInfo info, bool allow
             failmsg("Layout of the output array %s is incompatible with cv::Mat (step[ndims-1] != elemsize or step[1] != elemsize*nchannels)", info.name);
             return false;
         }
-        if( needcast )
-            o = (PyObject*)PyArray_Cast((PyArrayObject*)o, new_typenum);
-        else
-            o = (PyObject*)PyArray_GETCONTIGUOUS((PyArrayObject*)o);
-        _strides = PyArray_STRIDES(o);
+
+        if( needcast ) {
+            o = PyArray_Cast(oarr, new_typenum);
+            oarr = (PyArrayObject*) o;
+        }
+        else {
+            oarr = PyArray_GETCONTIGUOUS(oarr);
+            o = (PyObject*) oarr;
+        }
+
+        _strides = PyArray_STRIDES(oarr);
     }
 
     for(int i = 0; i < ndims; i++)
@@ -356,7 +365,7 @@ static int pyopencv_to(const PyObject* o, Mat& m, const ArgInfo info, bool allow
         return false;
     }
 
-    m = Mat(ndims, size, type, PyArray_DATA(o), step);
+    m = Mat(ndims, size, type, PyArray_DATA(oarr), step);
 
     if( m.data )
     {
index 06c37cb..31bb776 100644 (file)
@@ -510,7 +510,11 @@ static void arrayinterface_common(PyArrayInterface *s, int mtype)
     assert(0);
   }
 
+#ifdef NPY_1_7_API_VERSION
+  s->flags = NPY_ARRAY_WRITEABLE | NPY_ARRAY_NOTSWAPPED;
+#else
   s->flags = NPY_WRITEABLE | NPY_NOTSWAPPED;
+#endif
 }
 
 static PyObject *cvmat_array_struct(cvmat_t *cva)
index 48138cb..10f3226 100755 (executable)
@@ -1646,7 +1646,7 @@ class AreaTests(OpenCVTests):
             cv.SetData(imagefiledata, filedata, len(filedata))
             return cv.DecodeImageM(imagefiledata)
 
-        urllib.urlretrieve("http://opencv.itseez.com/data/camera_calibration.tar.gz", "camera_calibration.tar.gz")
+        urllib.urlretrieve("http://docs.opencv.org/data/camera_calibration.tar.gz", "camera_calibration.tar.gz")
         tf = tarfile.open("camera_calibration.tar.gz")
 
         num_x_ints = 8
index 5834072..07e7850 100644 (file)
@@ -88,6 +88,11 @@ High level image stitcher. It's possible to use this class without being aware o
         /* hidden */
     };
 
+.. note::
+
+   * A basic example on image stitching can be found at opencv_source_code/samples/cpp/stitching.cpp
+   * A detailed example on image stitching can be found at opencv_source_code/samples/cpp/stitching_detailed.cpp
+
 Stitcher::createDefault
 -----------------------
 Creates a stitcher with the default parameters.
diff --git a/modules/stitching/perf/perf_precomp.cpp b/modules/stitching/perf/perf_precomp.cpp
deleted file mode 100644 (file)
index 8552ac3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "perf_precomp.hpp"
diff --git a/modules/stitching/src/precomp.cpp b/modules/stitching/src/precomp.cpp
deleted file mode 100644 (file)
index 390dbfb..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*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 "precomp.hpp"
\ No newline at end of file
index 4849ace..1050856 100644 (file)
@@ -43,9 +43,7 @@
 #ifndef __OPENCV_STITCHING_PRECOMP_H__
 #define __OPENCV_STITCHING_PRECOMP_H__
 
-#ifdef HAVE_CVCONFIG_H
 #include "cvconfig.h"
-#endif
 #include "opencv2/opencv_modules.hpp"
 
 #include <vector>
diff --git a/modules/stitching/test/test_precomp.cpp b/modules/stitching/test/test_precomp.cpp
deleted file mode 100644 (file)
index 14a070e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "test_precomp.hpp"
\ No newline at end of file
index 6c6022c..44e9dc0 100644 (file)
@@ -4,4 +4,4 @@ endif()
 
 set(the_description "Super Resolution")
 ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127 -Wundef)
-ocv_define_module(superres opencv_imgproc opencv_video OPTIONAL opencv_gpu opencv_highgui)
+ocv_define_module(superres opencv_imgproc opencv_video OPTIONAL opencv_gpu opencv_highgui opencv_ocl)
index 7a0ed83..d51ce79 100644 (file)
@@ -58,15 +58,18 @@ namespace cv
 
         CV_EXPORTS Ptr<DenseOpticalFlowExt> createOptFlow_Farneback();
         CV_EXPORTS Ptr<DenseOpticalFlowExt> createOptFlow_Farneback_GPU();
+        CV_EXPORTS Ptr<DenseOpticalFlowExt> createOptFlow_Farneback_OCL();
 
         CV_EXPORTS Ptr<DenseOpticalFlowExt> createOptFlow_Simple();
 
         CV_EXPORTS Ptr<DenseOpticalFlowExt> createOptFlow_DualTVL1();
         CV_EXPORTS Ptr<DenseOpticalFlowExt> createOptFlow_DualTVL1_GPU();
+        CV_EXPORTS Ptr<DenseOpticalFlowExt> createOptFlow_DualTVL1_OCL();
 
         CV_EXPORTS Ptr<DenseOpticalFlowExt> createOptFlow_Brox_GPU();
 
         CV_EXPORTS Ptr<DenseOpticalFlowExt> createOptFlow_PyrLK_GPU();
+        CV_EXPORTS Ptr<DenseOpticalFlowExt> createOptFlow_PyrLK_OCL();
     }
 }
 
index 1245c12..8daeb5b 100644 (file)
@@ -92,6 +92,7 @@ namespace cv
         // Dennis Mitzel, Thomas Pock, Thomas Schoenemann, Daniel Cremers. Video Super Resolution using Duality Based TV-L1 Optical Flow.
         CV_EXPORTS Ptr<SuperResolution> createSuperResolution_BTVL1();
         CV_EXPORTS Ptr<SuperResolution> createSuperResolution_BTVL1_GPU();
+        CV_EXPORTS Ptr<SuperResolution> createSuperResolution_BTVL1_OCL();
     }
 }
 
index adc69e6..0a8ab5d 100644 (file)
 
 using namespace perf;
 
-CV_PERF_TEST_MAIN(superres, printCudaInfo())
+static const char * impls[] = {
+#ifdef HAVE_CUDA
+    "cuda",
+#endif
+    "plain"
+};
+
+CV_PERF_TEST_MAIN_WITH_IMPLS(superres, impls, printCudaInfo())
diff --git a/modules/superres/perf/perf_precomp.cpp b/modules/superres/perf/perf_precomp.cpp
deleted file mode 100644 (file)
index 81f16e8..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*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 "perf_precomp.hpp"
index f052037..d64d500 100644 (file)
@@ -51,9 +51,7 @@
 #ifndef __OPENCV_PERF_PRECOMP_HPP__
 #define __OPENCV_PERF_PRECOMP_HPP__
 
-#ifdef HAVE_CVCONFIG_H
 #include "cvconfig.h"
-#endif
 
 #include "opencv2/ts/ts.hpp"
 #include "opencv2/ts/gpu_perf.hpp"
diff --git a/modules/superres/perf/perf_superres_ocl.cpp b/modules/superres/perf/perf_superres_ocl.cpp
new file mode 100644 (file)
index 0000000..0b9864c
--- /dev/null
@@ -0,0 +1,146 @@
+/*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) 2010-2012, Multicoreware, Inc., all rights reserved.
+// Copyright (C) 2010-2012, Advanced Micro Devices, 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 "perf_precomp.hpp"
+
+#ifdef HAVE_OPENCL
+
+#include "opencv2/ocl/ocl.hpp"
+using namespace std;
+using namespace testing;
+using namespace perf;
+using namespace cv;
+using namespace cv::superres;
+
+namespace
+{
+    class OneFrameSource_OCL : public FrameSource
+    {
+    public:
+        explicit OneFrameSource_OCL(const ocl::oclMat& frame) : frame_(frame) {}
+
+        void nextFrame(OutputArray frame)
+        {
+            ocl::getOclMatRef(frame) = frame_;
+        }
+        void reset()
+        {
+        }
+
+    private:
+        ocl::oclMat frame_;
+    };
+
+
+    class ZeroOpticalFlowOCL : public DenseOpticalFlowExt
+    {
+    public:
+        void calc(InputArray frame0, InputArray, OutputArray flow1, OutputArray flow2)
+        {
+            ocl::oclMat& frame0_ = ocl::getOclMatRef(frame0);
+            ocl::oclMat& flow1_ = ocl::getOclMatRef(flow1);
+            ocl::oclMat& flow2_ = ocl::getOclMatRef(flow2);
+
+            cv::Size size = frame0_.size();
+
+            if(!flow2.needed())
+            {
+                flow1_.create(size, CV_32FC2);
+                flow1_.setTo(Scalar::all(0));
+            }
+            else
+            {
+                flow1_.create(size, CV_32FC1);
+                flow2_.create(size, CV_32FC1);
+
+                flow1_.setTo(Scalar::all(0));
+                flow2_.setTo(Scalar::all(0));
+            }
+        }
+
+        void collectGarbage()
+        {
+        }
+    };
+}
+
+PERF_TEST_P(Size_MatType, SuperResolution_BTVL1_OCL,
+    Combine(Values(szSmall64, szSmall128),
+    Values(MatType(CV_8UC1), MatType(CV_8UC3))))
+{
+    std::vector<cv::ocl::Info>info;
+    cv::ocl::getDevice(info);
+
+    declare.time(5 * 60);
+
+    const Size size = std::tr1::get<0>(GetParam());
+    const int type = std::tr1::get<1>(GetParam());
+
+    Mat frame(size, type);
+    declare.in(frame, WARMUP_RNG);
+
+    ocl::oclMat frame_ocl;
+    frame_ocl.upload(frame);
+
+
+    const int scale = 2;
+    const int iterations = 50;
+    const int temporalAreaRadius = 1;
+    Ptr<DenseOpticalFlowExt> opticalFlowOcl(new ZeroOpticalFlowOCL);
+
+    Ptr<SuperResolution> superRes_ocl = createSuperResolution_BTVL1_OCL();
+
+    superRes_ocl->set("scale", scale);
+    superRes_ocl->set("iterations", iterations);
+    superRes_ocl->set("temporalAreaRadius", temporalAreaRadius);
+    superRes_ocl->set("opticalFlow", opticalFlowOcl);
+
+    superRes_ocl->setInput(new OneFrameSource_OCL(frame_ocl));
+
+    ocl::oclMat dst_ocl;
+    superRes_ocl->nextFrame(dst_ocl);
+
+    TEST_CYCLE_N(10) superRes_ocl->nextFrame(dst_ocl);
+    frame_ocl.release();
+    CPU_SANITY_CHECK(dst_ocl);
+}
+#endif
diff --git a/modules/superres/src/btv_l1_ocl.cpp b/modules/superres/src/btv_l1_ocl.cpp
new file mode 100644 (file)
index 0000000..5f9e326
--- /dev/null
@@ -0,0 +1,748 @@
+/*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) 2010-2012, Multicoreware, Inc., all rights reserved.
+// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//             Jin Ma, jin@multicorewareinc.com
+// 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*/
+
+// S. Farsiu , D. Robinson, M. Elad, P. Milanfar. Fast and robust multiframe super resolution.
+// Dennis Mitzel, Thomas Pock, Thomas Schoenemann, Daniel Cremers. Video Super Resolution using Duality Based TV-L1 Optical Flow.
+
+#include "precomp.hpp"
+
+#if !defined(HAVE_OPENCL) || !defined(HAVE_OPENCV_OCL)
+
+cv::Ptr<cv::superres::SuperResolution> cv::superres::createSuperResolution_BTVL1_OCL()
+{
+    CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform");
+    return Ptr<SuperResolution>();
+}
+
+#else
+
+using namespace std;
+using namespace cv;
+using namespace cv::ocl;
+using namespace cv::superres;
+using namespace cv::superres::detail;
+
+namespace cv
+{
+    namespace ocl
+    {
+        extern const char* superres_btvl1;
+
+        float* btvWeights_ = NULL;
+        size_t btvWeights_size = 0;
+    }
+}
+
+namespace btv_l1_device_ocl
+{
+    void buildMotionMaps(const oclMat& forwardMotionX, const oclMat& forwardMotionY,
+        const oclMat& backwardMotionX, const oclMat& bacwardMotionY,
+        oclMat& forwardMapX, oclMat& forwardMapY,
+        oclMat& backwardMapX, oclMat& backwardMapY);
+
+    void upscale(const oclMat& src, oclMat& dst, int scale);
+
+    float diffSign(float a, float b);
+
+    Point3f diffSign(Point3f a, Point3f b);
+
+    void diffSign(const oclMat& src1, const oclMat& src2, oclMat& dst);
+
+    void calcBtvRegularization(const oclMat& src, oclMat& dst, int ksize);
+}
+
+void btv_l1_device_ocl::buildMotionMaps(const oclMat& forwardMotionX, const oclMat& forwardMotionY,
+    const oclMat& backwardMotionX, const oclMat& backwardMotionY,
+    oclMat& forwardMapX, oclMat& forwardMapY,
+    oclMat& backwardMapX, oclMat& backwardMapY)
+{
+    Context* clCxt = Context::getContext();
+
+    size_t local_thread[] = {32, 8, 1};
+    size_t global_thread[] = {forwardMapX.cols, forwardMapX.rows, 1};
+
+    int forwardMotionX_step = (int)(forwardMotionX.step/forwardMotionX.elemSize());
+    int forwardMotionY_step = (int)(forwardMotionY.step/forwardMotionY.elemSize());
+    int backwardMotionX_step = (int)(backwardMotionX.step/backwardMotionX.elemSize());
+    int backwardMotionY_step = (int)(backwardMotionY.step/backwardMotionY.elemSize());
+    int forwardMapX_step = (int)(forwardMapX.step/forwardMapX.elemSize());
+    int forwardMapY_step = (int)(forwardMapY.step/forwardMapY.elemSize());
+    int backwardMapX_step = (int)(backwardMapX.step/backwardMapX.elemSize());
+    int backwardMapY_step = (int)(backwardMapY.step/backwardMapY.elemSize());
+
+    String kernel_name = "buildMotionMapsKernel";
+    vector< pair<size_t, const void*> > args;
+
+    args.push_back(make_pair(sizeof(cl_mem), (void*)&forwardMotionX.data));
+    args.push_back(make_pair(sizeof(cl_mem), (void*)&forwardMotionY.data));
+    args.push_back(make_pair(sizeof(cl_mem), (void*)&backwardMotionX.data));
+    args.push_back(make_pair(sizeof(cl_mem), (void*)&backwardMotionY.data));
+    args.push_back(make_pair(sizeof(cl_mem), (void*)&forwardMapX.data));
+    args.push_back(make_pair(sizeof(cl_mem), (void*)&forwardMapY.data));
+    args.push_back(make_pair(sizeof(cl_mem), (void*)&backwardMapX.data));
+    args.push_back(make_pair(sizeof(cl_mem), (void*)&backwardMapY.data));
+
+    args.push_back(make_pair(sizeof(cl_int), (void*)&forwardMotionX.rows));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&forwardMotionY.cols));
+
+    args.push_back(make_pair(sizeof(cl_int), (void*)&forwardMotionX_step));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&forwardMotionY_step));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&backwardMotionX_step));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&backwardMotionY_step));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&forwardMapX_step));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&forwardMapY_step));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&backwardMapX_step));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&backwardMapY_step));
+
+    openCLExecuteKernel(clCxt, &superres_btvl1, kernel_name, global_thread, local_thread, args, -1, -1);
+}
+
+void btv_l1_device_ocl::upscale(const oclMat& src, oclMat& dst, int scale)
+{
+    Context* clCxt = Context::getContext();
+
+    size_t local_thread[] = {32, 8, 1};
+    size_t global_thread[] = {src.cols, src.rows, 1};
+
+    int src_step = (int)(src.step/src.elemSize());
+    int dst_step = (int)(dst.step/dst.elemSize());
+
+    String kernel_name = "upscaleKernel";
+    vector< pair<size_t, const void*> > args;
+
+    int cn = src.oclchannels();
+
+    args.push_back(make_pair(sizeof(cl_mem), (void*)&src.data));
+    args.push_back(make_pair(sizeof(cl_mem), (void*)&dst.data));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&src_step));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&dst_step));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&src.rows));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&src.cols));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&scale));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&cn));    
+
+    openCLExecuteKernel(clCxt, &superres_btvl1, kernel_name, global_thread, local_thread, args, -1, -1);
+
+}
+
+float btv_l1_device_ocl::diffSign(float a, float b)
+{
+    return a > b ? 1.0f : a < b ? -1.0f : 0.0f;
+}
+
+Point3f btv_l1_device_ocl::diffSign(Point3f a, Point3f b)
+{
+    return Point3f(
+        a.x > b.x ? 1.0f : a.x < b.x ? -1.0f : 0.0f,
+        a.y > b.y ? 1.0f : a.y < b.y ? -1.0f : 0.0f,
+        a.z > b.z ? 1.0f : a.z < b.z ? -1.0f : 0.0f
+        );
+}
+
+void btv_l1_device_ocl::diffSign(const oclMat& src1, const oclMat& src2, oclMat& dst)
+{
+    Context* clCxt = Context::getContext();
+
+    oclMat src1_ = src1.reshape(1);
+    oclMat src2_ = src2.reshape(1);
+    oclMat dst_ = dst.reshape(1);
+
+    int src1_step = (int)(src1_.step/src1_.elemSize());
+    int src2_step = (int)(src2_.step/src2_.elemSize());
+    int dst_step = (int)(dst_.step/dst_.elemSize());
+
+    size_t local_thread[] = {32, 8, 1};
+    size_t global_thread[] = {src1_.cols, src1_.rows, 1};
+
+    String kernel_name = "diffSignKernel";
+    vector< pair<size_t, const void*> > args;
+
+    args.push_back(make_pair(sizeof(cl_mem), (void*)&src1_.data));
+    args.push_back(make_pair(sizeof(cl_mem), (void*)&src2_.data));
+    args.push_back(make_pair(sizeof(cl_mem), (void*)&dst_.data));
+
+    args.push_back(make_pair(sizeof(cl_int), (void*)&src1_.rows));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&src1_.cols));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&dst_step));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&src1_step));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&src2_step));
+
+    openCLExecuteKernel(clCxt, &superres_btvl1, kernel_name, global_thread, local_thread, args, -1, -1);
+}
+
+void btv_l1_device_ocl::calcBtvRegularization(const oclMat& src, oclMat& dst, int ksize)
+{
+    Context* clCxt = Context::getContext();
+
+    oclMat src_ = src.reshape(1);
+    oclMat dst_ = dst.reshape(1);
+
+    size_t local_thread[] = {32, 8, 1};
+    size_t global_thread[] = {src.cols, src.rows, 1};
+
+    int src_step = (int)(src_.step/src_.elemSize());
+    int dst_step = (int)(dst_.step/dst_.elemSize());
+
+    String kernel_name = "calcBtvRegularizationKernel";
+    vector< pair<size_t, const void*> > args;
+
+    int cn = src.oclchannels();
+
+    cl_mem c_btvRegWeights;
+    size_t count = btvWeights_size * sizeof(float);
+    c_btvRegWeights = openCLCreateBuffer(clCxt, CL_MEM_READ_ONLY, count);
+    int cl_safe_check = clEnqueueWriteBuffer((cl_command_queue)clCxt->oclCommandQueue(), c_btvRegWeights, 1, 0, count, btvWeights_, 0, NULL, NULL);
+    CV_Assert(cl_safe_check == CL_SUCCESS);
+
+    args.push_back(make_pair(sizeof(cl_mem), (void*)&src_.data));
+    args.push_back(make_pair(sizeof(cl_mem), (void*)&dst_.data));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&src_step));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&dst_step));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&src.rows));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&src.cols));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&ksize));
+    args.push_back(make_pair(sizeof(cl_int), (void*)&cn));
+    args.push_back(make_pair(sizeof(cl_mem), (void*)&c_btvRegWeights));
+
+    openCLExecuteKernel(clCxt, &superres_btvl1, kernel_name, global_thread, local_thread, args, -1, -1);
+    cl_safe_check = clReleaseMemObject(c_btvRegWeights);
+    CV_Assert(cl_safe_check == CL_SUCCESS);
+}
+
+namespace
+{
+    void calcRelativeMotions(const vector<pair<oclMat, oclMat> >& forwardMotions, const vector<pair<oclMat, oclMat> >& backwardMotions,
+        vector<pair<oclMat, oclMat> >& relForwardMotions, vector<pair<oclMat, oclMat> >& relBackwardMotions,
+        int baseIdx, Size size)
+    {
+        const int count = static_cast<int>(forwardMotions.size());
+
+        relForwardMotions.resize(count);
+        relForwardMotions[baseIdx].first.create(size, CV_32FC1);
+        relForwardMotions[baseIdx].first.setTo(Scalar::all(0));
+        relForwardMotions[baseIdx].second.create(size, CV_32FC1);
+        relForwardMotions[baseIdx].second.setTo(Scalar::all(0));
+
+        relBackwardMotions.resize(count);
+        relBackwardMotions[baseIdx].first.create(size, CV_32FC1);
+        relBackwardMotions[baseIdx].first.setTo(Scalar::all(0));
+        relBackwardMotions[baseIdx].second.create(size, CV_32FC1);
+        relBackwardMotions[baseIdx].second.setTo(Scalar::all(0));
+
+        for (int i = baseIdx - 1; i >= 0; --i)
+        {
+            ocl::add(relForwardMotions[i + 1].first, forwardMotions[i].first, relForwardMotions[i].first);
+            ocl::add(relForwardMotions[i + 1].second, forwardMotions[i].second, relForwardMotions[i].second);
+
+            ocl::add(relBackwardMotions[i + 1].first, backwardMotions[i + 1].first, relBackwardMotions[i].first);
+            ocl::add(relBackwardMotions[i + 1].second, backwardMotions[i + 1].second, relBackwardMotions[i].second);
+        }
+
+        for (int i = baseIdx + 1; i < count; ++i)
+        {
+            ocl::add(relForwardMotions[i - 1].first, backwardMotions[i].first, relForwardMotions[i].first);
+            ocl::add(relForwardMotions[i - 1].second, backwardMotions[i].second, relForwardMotions[i].second);
+
+            ocl::add(relBackwardMotions[i - 1].first, forwardMotions[i - 1].first, relBackwardMotions[i].first);
+            ocl::add(relBackwardMotions[i - 1].second, forwardMotions[i - 1].second, relBackwardMotions[i].second);
+        }
+    }
+
+    void upscaleMotions(const vector<pair<oclMat, oclMat> >& lowResMotions, vector<pair<oclMat, oclMat> >& highResMotions, int scale)
+    {
+        highResMotions.resize(lowResMotions.size());
+
+        for (size_t i = 0; i < lowResMotions.size(); ++i)
+        {
+            ocl::resize(lowResMotions[i].first, highResMotions[i].first, Size(), scale, scale, INTER_LINEAR);
+            ocl::resize(lowResMotions[i].second, highResMotions[i].second, Size(), scale, scale, INTER_LINEAR);
+
+            ocl::multiply(scale, highResMotions[i].first, highResMotions[i].first);
+            ocl::multiply(scale, highResMotions[i].second, highResMotions[i].second);
+        }
+    }
+
+    void buildMotionMaps(const pair<oclMat, oclMat>& forwardMotion, const pair<oclMat, oclMat>& backwardMotion,
+        pair<oclMat, oclMat>& forwardMap, pair<oclMat, oclMat>& backwardMap)
+    {
+        forwardMap.first.create(forwardMotion.first.size(), CV_32FC1);
+        forwardMap.second.create(forwardMotion.first.size(), CV_32FC1);
+
+        backwardMap.first.create(forwardMotion.first.size(), CV_32FC1);
+        backwardMap.second.create(forwardMotion.first.size(), CV_32FC1);
+
+        btv_l1_device_ocl::buildMotionMaps(forwardMotion.first, forwardMotion.second,
+            backwardMotion.first, backwardMotion.second,
+            forwardMap.first, forwardMap.second,
+            backwardMap.first, backwardMap.second);
+    }
+
+    void upscale(const oclMat& src, oclMat& dst, int scale)
+    {
+        CV_Assert( src.channels() == 1 || src.channels() == 3 || src.channels() == 4 );
+
+        dst.create(src.rows * scale, src.cols * scale, src.type());
+        dst.setTo(Scalar::all(0));
+
+        btv_l1_device_ocl::upscale(src, dst, scale);
+    }
+
+    void diffSign(const oclMat& src1, const oclMat& src2, oclMat& dst)
+    {
+        dst.create(src1.size(), src1.type());
+
+        btv_l1_device_ocl::diffSign(src1, src2, dst);
+    }
+
+    void calcBtvWeights(int btvKernelSize, double alpha, vector<float>& btvWeights)
+    {
+        const size_t size = btvKernelSize * btvKernelSize;
+
+        btvWeights.resize(size);
+
+        const int ksize = (btvKernelSize - 1) / 2;
+        const float alpha_f = static_cast<float>(alpha);
+
+        for (int m = 0, ind = 0; m <= ksize; ++m)
+        {
+            for (int l = ksize; l + m >= 0; --l, ++ind)
+                btvWeights[ind] = pow(alpha_f, std::abs(m) + std::abs(l));
+        }
+
+        btvWeights_ = &btvWeights[0];
+        btvWeights_size = size;
+    }
+
+    void calcBtvRegularization(const oclMat& src, oclMat& dst, int btvKernelSize)
+    {
+        dst.create(src.size(), src.type());
+        dst.setTo(Scalar::all(0));
+
+        const int ksize = (btvKernelSize - 1) / 2;
+
+        btv_l1_device_ocl::calcBtvRegularization(src, dst, ksize);
+    }
+
+    class BTVL1_OCL_Base
+    {
+    public:
+        BTVL1_OCL_Base();
+
+        void process(const vector<oclMat>& src, oclMat& dst,
+            const vector<pair<oclMat, oclMat> >& forwardMotions, const vector<pair<oclMat, oclMat> >& backwardMotions,
+            int baseIdx);
+
+        void collectGarbage();
+
+    protected:
+        int scale_;
+        int iterations_;
+        double lambda_;
+        double tau_;
+        double alpha_;
+        int btvKernelSize_;
+        int blurKernelSize_;
+        double blurSigma_;
+        Ptr<DenseOpticalFlowExt> opticalFlow_;
+
+    private:
+        vector<Ptr<cv::ocl::FilterEngine_GPU> > filters_;
+        int curBlurKernelSize_;
+        double curBlurSigma_;
+        int curSrcType_;
+
+        vector<float> btvWeights_;
+        int curBtvKernelSize_;
+        double curAlpha_;
+
+        vector<pair<oclMat, oclMat> > lowResForwardMotions_;
+        vector<pair<oclMat, oclMat> > lowResBackwardMotions_;
+
+        vector<pair<oclMat, oclMat> > highResForwardMotions_;
+        vector<pair<oclMat, oclMat> > highResBackwardMotions_;
+
+        vector<pair<oclMat, oclMat> > forwardMaps_;
+        vector<pair<oclMat, oclMat> > backwardMaps_;
+
+        oclMat highRes_;
+
+        vector<oclMat> diffTerms_;
+        vector<oclMat> a_, b_, c_;
+        oclMat regTerm_;
+    };
+
+    BTVL1_OCL_Base::BTVL1_OCL_Base()
+    {
+        scale_ = 4;
+        iterations_ = 180;
+        lambda_ = 0.03;
+        tau_ = 1.3;
+        alpha_ = 0.7;
+        btvKernelSize_ = 7;
+        blurKernelSize_ = 5;
+        blurSigma_ = 0.0;
+        opticalFlow_ = createOptFlow_DualTVL1_OCL();
+
+        curBlurKernelSize_ = -1;
+        curBlurSigma_ = -1.0;
+        curSrcType_ = -1;
+
+        curBtvKernelSize_ = -1;
+        curAlpha_ = -1.0;
+    }
+
+    void BTVL1_OCL_Base::process(const vector<oclMat>& src, oclMat& dst,
+        const vector<pair<oclMat, oclMat> >& forwardMotions, const vector<pair<oclMat, oclMat> >& backwardMotions,
+        int baseIdx)
+    {
+        CV_Assert( scale_ > 1 );
+        CV_Assert( iterations_ > 0 );
+        CV_Assert( tau_ > 0.0 );
+        CV_Assert( alpha_ > 0.0 );
+        CV_Assert( btvKernelSize_ > 0 && btvKernelSize_ <= 16 );
+        CV_Assert( blurKernelSize_ > 0 );
+        CV_Assert( blurSigma_ >= 0.0 );
+
+        // update blur filter and btv weights
+
+        if (filters_.size() != src.size() || blurKernelSize_ != curBlurKernelSize_ || blurSigma_ != curBlurSigma_ || src[0].type() != curSrcType_)
+        {
+            filters_.resize(src.size());
+            for (size_t i = 0; i < src.size(); ++i)
+                filters_[i] = cv::ocl::createGaussianFilter_GPU(src[0].type(), Size(blurKernelSize_, blurKernelSize_), blurSigma_);
+            curBlurKernelSize_ = blurKernelSize_;
+            curBlurSigma_ = blurSigma_;
+            curSrcType_ = src[0].type();
+        }
+
+        if (btvWeights_.empty() || btvKernelSize_ != curBtvKernelSize_ || alpha_ != curAlpha_)
+        {
+            calcBtvWeights(btvKernelSize_, alpha_, btvWeights_);
+            curBtvKernelSize_ = btvKernelSize_;
+            curAlpha_ = alpha_;
+        }
+
+        // calc motions between input frames
+
+        calcRelativeMotions(forwardMotions, backwardMotions, 
+            lowResForwardMotions_, lowResBackwardMotions_, 
+            baseIdx, src[0].size());
+
+        upscaleMotions(lowResForwardMotions_, highResForwardMotions_, scale_);
+        upscaleMotions(lowResBackwardMotions_, highResBackwardMotions_, scale_);
+
+        forwardMaps_.resize(highResForwardMotions_.size());
+        backwardMaps_.resize(highResForwardMotions_.size());
+        for (size_t i = 0; i < highResForwardMotions_.size(); ++i)
+        {
+            buildMotionMaps(highResForwardMotions_[i], highResBackwardMotions_[i], forwardMaps_[i], backwardMaps_[i]);
+        }
+        // initial estimation
+
+        const Size lowResSize = src[0].size();
+        const Size highResSize(lowResSize.width * scale_, lowResSize.height * scale_);
+
+        ocl::resize(src[baseIdx], highRes_, highResSize, 0, 0, INTER_LINEAR);
+
+        // iterations
+
+        diffTerms_.resize(src.size());
+        a_.resize(src.size());
+        b_.resize(src.size());
+        c_.resize(src.size());
+
+        for (int i = 0; i < iterations_; ++i)
+        {
+            for (size_t k = 0; k < src.size(); ++k)
+            {
+                diffTerms_[k].create(highRes_.size(), highRes_.type());
+                a_[k].create(highRes_.size(), highRes_.type());
+                b_[k].create(highRes_.size(), highRes_.type());
+                c_[k].create(lowResSize, highRes_.type());
+
+                // a = M * Ih
+                ocl::remap(highRes_, a_[k], backwardMaps_[k].first, backwardMaps_[k].second, INTER_NEAREST, BORDER_CONSTANT, Scalar());
+                // b = HM * Ih
+                filters_[k]->apply(a_[k], b_[k], Rect(0,0,-1,-1));
+                // c = DHF * Ih
+                ocl::resize(b_[k], c_[k], lowResSize, 0, 0, INTER_NEAREST);
+
+                diffSign(src[k], c_[k], c_[k]);
+
+                // a = Dt * diff
+                upscale(c_[k], a_[k], scale_);
+                // b = HtDt * diff
+                filters_[k]->apply(a_[k], b_[k], Rect(0,0,-1,-1));
+                // diffTerm = MtHtDt * diff
+                ocl::remap(b_[k], diffTerms_[k], forwardMaps_[k].first, forwardMaps_[k].second, INTER_NEAREST, BORDER_CONSTANT, Scalar());
+            }
+
+            if (lambda_ > 0)
+            {
+                calcBtvRegularization(highRes_, regTerm_, btvKernelSize_);
+                ocl::addWeighted(highRes_, 1.0, regTerm_, -tau_ * lambda_, 0.0, highRes_);
+            }
+
+            for (size_t k = 0; k < src.size(); ++k)
+            {
+                ocl::addWeighted(highRes_, 1.0, diffTerms_[k], tau_, 0.0, highRes_);
+            }
+        }
+
+        Rect inner(btvKernelSize_, btvKernelSize_, highRes_.cols - 2 * btvKernelSize_, highRes_.rows - 2 * btvKernelSize_);
+        highRes_(inner).copyTo(dst);
+    }
+
+    void BTVL1_OCL_Base::collectGarbage()
+    {
+        filters_.clear();
+
+        lowResForwardMotions_.clear();
+        lowResBackwardMotions_.clear();
+
+        highResForwardMotions_.clear();
+        highResBackwardMotions_.clear();
+
+        forwardMaps_.clear();
+        backwardMaps_.clear();
+
+        highRes_.release();
+
+        diffTerms_.clear();
+        a_.clear();
+        b_.clear();
+        c_.clear();
+        regTerm_.release();
+    }
+
+    ////////////////////////////////////////////////////////////
+
+    class BTVL1_OCL : public SuperResolution, private BTVL1_OCL_Base
+    {
+    public:
+        AlgorithmInfo* info() const;
+
+        BTVL1_OCL();
+
+        void collectGarbage();
+
+    protected:
+        void initImpl(Ptr<FrameSource>& frameSource);
+        void processImpl(Ptr<FrameSource>& frameSource, OutputArray output);
+
+    private:
+        int temporalAreaRadius_;
+
+        void readNextFrame(Ptr<FrameSource>& frameSource);
+        void processFrame(int idx);
+
+        oclMat curFrame_;
+        oclMat prevFrame_;
+
+        vector<oclMat> frames_;
+        vector<pair<oclMat, oclMat> > forwardMotions_;
+        vector<pair<oclMat, oclMat> > backwardMotions_;
+        vector<oclMat> outputs_;
+
+        int storePos_;
+        int procPos_;
+        int outPos_;
+
+        vector<oclMat> srcFrames_;
+        vector<pair<oclMat, oclMat> > srcForwardMotions_;
+        vector<pair<oclMat, oclMat> > srcBackwardMotions_;
+        oclMat finalOutput_;
+    };
+
+    CV_INIT_ALGORITHM(BTVL1_OCL, "SuperResolution.BTVL1_OCL",
+    obj.info()->addParam(obj, "scale", obj.scale_, false, 0, 0, "Scale factor.");
+    obj.info()->addParam(obj, "iterations", obj.iterations_, false, 0, 0, "Iteration count.");
+    obj.info()->addParam(obj, "tau", obj.tau_, false, 0, 0, "Asymptotic value of steepest descent method.");
+    obj.info()->addParam(obj, "lambda", obj.lambda_, false, 0, 0, "Weight parameter to balance data term and smoothness term.");
+    obj.info()->addParam(obj, "alpha", obj.alpha_, false, 0, 0, "Parameter of spacial distribution in Bilateral-TV.");
+    obj.info()->addParam(obj, "btvKernelSize", obj.btvKernelSize_, false, 0, 0, "Kernel size of Bilateral-TV filter.");
+    obj.info()->addParam(obj, "blurKernelSize", obj.blurKernelSize_, false, 0, 0, "Gaussian blur kernel size.");
+    obj.info()->addParam(obj, "blurSigma", obj.blurSigma_, false, 0, 0, "Gaussian blur sigma.");
+    obj.info()->addParam(obj, "temporalAreaRadius", obj.temporalAreaRadius_, false, 0, 0, "Radius of the temporal search area.");
+    obj.info()->addParam<DenseOpticalFlowExt>(obj, "opticalFlow", obj.opticalFlow_, false, 0, 0, "Dense optical flow algorithm."));
+
+    BTVL1_OCL::BTVL1_OCL()
+    {
+        temporalAreaRadius_ = 4;
+    }
+
+    void BTVL1_OCL::collectGarbage()
+    {
+        curFrame_.release();
+        prevFrame_.release();
+
+        frames_.clear();
+        forwardMotions_.clear();
+        backwardMotions_.clear();
+        outputs_.clear();
+
+        srcFrames_.clear();
+        srcForwardMotions_.clear();
+        srcBackwardMotions_.clear();
+        finalOutput_.release();
+
+        SuperResolution::collectGarbage();
+        BTVL1_OCL_Base::collectGarbage();
+    }
+
+    void BTVL1_OCL::initImpl(Ptr<FrameSource>& frameSource)
+    {
+        const int cacheSize = 2 * temporalAreaRadius_ + 1;
+
+        frames_.resize(cacheSize);
+        forwardMotions_.resize(cacheSize);
+        backwardMotions_.resize(cacheSize);
+        outputs_.resize(cacheSize);
+
+        storePos_ = -1;
+
+        for (int t = -temporalAreaRadius_; t <= temporalAreaRadius_; ++t)
+            readNextFrame(frameSource);
+
+        for (int i = 0; i <= temporalAreaRadius_; ++i)
+            processFrame(i);
+
+        procPos_ = temporalAreaRadius_;
+        outPos_ = -1;
+    }
+
+    void BTVL1_OCL::processImpl(Ptr<FrameSource>& frameSource, OutputArray _output)
+    {
+        if (outPos_ >= storePos_)
+        {
+            if(_output.kind() == _InputArray::OCL_MAT)
+            {
+                getOclMatRef(_output).release();
+            }
+            else
+            {
+                _output.release();
+            }
+            return;
+        }
+
+        readNextFrame(frameSource);
+
+        if (procPos_ < storePos_)
+        {
+            ++procPos_;
+            processFrame(procPos_);
+        }
+
+        ++outPos_;
+        const oclMat& curOutput = at(outPos_, outputs_);
+
+        if (_output.kind() == _InputArray::OCL_MAT)
+            curOutput.convertTo(getOclMatRef(_output), CV_8U);
+        else
+        {
+            curOutput.convertTo(finalOutput_, CV_8U);
+            arrCopy(finalOutput_, _output);
+        }
+    }
+
+    void BTVL1_OCL::readNextFrame(Ptr<FrameSource>& frameSource)
+    {
+        curFrame_.release();
+        frameSource->nextFrame(curFrame_);
+
+        if (curFrame_.empty())
+            return;
+
+        ++storePos_;
+        curFrame_.convertTo(at(storePos_, frames_), CV_32F);
+
+        if (storePos_ > 0)
+        {
+            pair<oclMat, oclMat>& forwardMotion = at(storePos_ - 1, forwardMotions_);
+            pair<oclMat, oclMat>& backwardMotion = at(storePos_, backwardMotions_);
+
+            opticalFlow_->calc(prevFrame_, curFrame_, forwardMotion.first, forwardMotion.second);
+            opticalFlow_->calc(curFrame_, prevFrame_, backwardMotion.first, backwardMotion.second);
+        }
+
+        curFrame_.copyTo(prevFrame_);
+    }
+
+    void BTVL1_OCL::processFrame(int idx)
+    {
+        const int startIdx = max(idx - temporalAreaRadius_, 0);
+        const int procIdx = idx;
+        const int endIdx = min(startIdx + 2 * temporalAreaRadius_, storePos_);
+
+        const int count = endIdx - startIdx + 1;
+
+        srcFrames_.resize(count);
+        srcForwardMotions_.resize(count);
+        srcBackwardMotions_.resize(count);
+
+        int baseIdx = -1;
+
+        for (int i = startIdx, k = 0; i <= endIdx; ++i, ++k)
+        {
+            if (i == procIdx)
+                baseIdx = k;
+
+            srcFrames_[k] = at(i, frames_);
+
+            if (i < endIdx)
+                srcForwardMotions_[k] = at(i, forwardMotions_);
+            if (i > startIdx)
+                srcBackwardMotions_[k] = at(i, backwardMotions_);
+        }
+
+        process(srcFrames_, at(idx, outputs_), srcForwardMotions_, srcBackwardMotions_, baseIdx);
+    }
+}
+
+Ptr<SuperResolution> cv::superres::createSuperResolution_BTVL1_OCL()
+{
+    return new BTVL1_OCL;
+}
+#endif
\ No newline at end of file
index 0521416..20e45d9 100644 (file)
@@ -119,11 +119,23 @@ namespace
         {
             vc_ >> _frame.getMatRef();
         }
-        else
+        else if(_frame.kind() == _InputArray::GPU_MAT)
         {
             vc_ >> frame_;
             arrCopy(frame_, _frame);
         }
+        else if(_frame.kind() == _InputArray::OCL_MAT)
+        {
+            vc_ >> frame_;
+            if(!frame_.empty())
+            {
+                arrCopy(frame_, _frame);
+            }
+        }
+        else
+        {
+            //should never get here
+        }
     }
 
     class VideoFrameSource : public CaptureFrameSource
index 5a66825..075cf95 100644 (file)
@@ -125,30 +125,59 @@ namespace
     {
         src.getGpuMat().copyTo(dst.getGpuMatRef());
     }
+#ifdef HAVE_OPENCV_OCL
+    void ocl2mat(InputArray src, OutputArray dst)
+    {
+        dst.getMatRef() = (Mat)ocl::getOclMatRef(src);
+    }
+    void mat2ocl(InputArray src, OutputArray dst)
+    {
+        Mat m = src.getMat();
+        ocl::getOclMatRef(dst) = (ocl::oclMat)m;
+    }
+    void ocl2ocl(InputArray src, OutputArray dst)
+    {
+        ocl::getOclMatRef(src).copyTo(ocl::getOclMatRef(dst));
+    }
+#else
+    void ocl2mat(InputArray, OutputArray)
+    {
+        CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform");;
+    }
+    void mat2ocl(InputArray, OutputArray)
+    {
+        CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform");;
+    }
+    void ocl2ocl(InputArray, OutputArray)
+    {
+        CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform");
+    }
+#endif
 }
 
 void cv::superres::arrCopy(InputArray src, OutputArray dst)
 {
     typedef void (*func_t)(InputArray src, OutputArray dst);
-    static const func_t funcs[10][10] =
+    static const func_t funcs[11][11] =
     {
         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, arr2tex, mat2gpu},
-        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, arr2tex, mat2gpu},
-        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, arr2tex, mat2gpu},
-        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, arr2tex, mat2gpu},
-        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, arr2tex, mat2gpu},
-        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, arr2tex, mat2gpu},
-        {0, buf2arr, buf2arr, buf2arr, buf2arr, buf2arr, buf2arr, buf2arr, buf2arr, buf2arr},
-        {0, tex2arr, tex2arr, tex2arr, tex2arr, tex2arr, tex2arr, tex2arr, tex2arr, tex2arr},
-        {0, gpu2mat, gpu2mat, gpu2mat, gpu2mat, gpu2mat, gpu2mat, arr2buf, arr2tex, gpu2gpu}
+        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, arr2tex, mat2gpu, mat2ocl},
+        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, arr2tex, mat2gpu, mat2ocl},
+        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, arr2tex, mat2gpu, mat2ocl},
+        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, arr2tex, mat2gpu, mat2ocl},
+        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, arr2tex, mat2gpu, mat2ocl},
+        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, arr2tex, mat2gpu, mat2ocl},
+        {0, buf2arr, buf2arr, buf2arr, buf2arr, buf2arr, buf2arr, buf2arr, buf2arr, buf2arr, 0      },
+        {0, tex2arr, tex2arr, tex2arr, tex2arr, tex2arr, tex2arr, tex2arr, tex2arr, tex2arr, 0      },
+        {0, gpu2mat, gpu2mat, gpu2mat, gpu2mat, gpu2mat, gpu2mat, arr2buf, arr2tex, gpu2gpu, 0      },
+        {0, ocl2mat, ocl2mat, ocl2mat, ocl2mat, ocl2mat, ocl2mat, 0,       0,       0,       ocl2ocl}
     };
 
     const int src_kind = src.kind() >> _InputArray::KIND_SHIFT;
     const int dst_kind = dst.kind() >> _InputArray::KIND_SHIFT;
 
-    CV_DbgAssert( src_kind >= 0 && src_kind < 10 );
-    CV_DbgAssert( dst_kind >= 0 && dst_kind < 10 );
+    CV_DbgAssert( src_kind >= 0 && src_kind < 11 );
+    CV_DbgAssert( dst_kind >= 0 && dst_kind < 11 );
 
     const func_t func = funcs[src_kind][dst_kind];
     CV_DbgAssert( func != 0 );
@@ -190,7 +219,6 @@ namespace
             break;
         }
     }
-
     void convertToDepth(InputArray src, OutputArray dst, int depth)
     {
         CV_Assert( src.depth() <= CV_64F );
@@ -271,3 +299,70 @@ GpuMat cv::superres::convertToType(const GpuMat& src, int type, GpuMat& buf0, Gp
     convertToDepth(buf0, buf1, depth);
     return buf1;
 }
+#ifdef HAVE_OPENCV_OCL
+namespace
+{
+    // TODO(pengx17): remove these overloaded functions until IntputArray fully supports oclMat
+    void convertToCn(const ocl::oclMat& src, ocl::oclMat& dst, int cn)
+    {
+        CV_Assert( src.channels() == 1 || src.channels() == 3 || src.channels() == 4 );
+        CV_Assert( cn == 1 || cn == 3 || cn == 4 );
+
+        static const int codes[5][5] =
+        {
+            {-1, -1, -1, -1, -1},
+            {-1, -1, -1, COLOR_GRAY2BGR, COLOR_GRAY2BGRA},
+            {-1, -1, -1, -1, -1},
+            {-1, COLOR_BGR2GRAY, -1, -1, COLOR_BGR2BGRA},
+            {-1, COLOR_BGRA2GRAY, -1, COLOR_BGRA2BGR, -1},
+        };
+
+        const int code = codes[src.channels()][cn];
+        CV_DbgAssert( code >= 0 );
+
+        ocl::cvtColor(src, dst, code, cn);
+    }
+    void convertToDepth(const ocl::oclMat& src, ocl::oclMat& dst, int depth)
+    {
+        CV_Assert( src.depth() <= CV_64F );
+        CV_Assert( depth == CV_8U || depth == CV_32F );
+
+        static const double maxVals[] =
+        {
+            std::numeric_limits<uchar>::max(),
+            std::numeric_limits<schar>::max(),
+            std::numeric_limits<ushort>::max(),
+            std::numeric_limits<short>::max(),
+            std::numeric_limits<int>::max(),
+            1.0,
+            1.0,
+        };
+        const double scale = maxVals[depth] / maxVals[src.depth()];
+        src.convertTo(dst, depth, scale);
+    }
+}
+ocl::oclMat cv::superres::convertToType(const ocl::oclMat& src, int type, ocl::oclMat& buf0, ocl::oclMat& buf1)
+{
+    if (src.type() == type)
+        return src;
+
+    const int depth = CV_MAT_DEPTH(type);
+    const int cn = CV_MAT_CN(type);
+
+    if (src.depth() == depth)
+    {
+        convertToCn(src, buf0, cn);
+        return buf0;
+    }
+
+    if (src.channels() == cn)
+    {
+        convertToDepth(src, buf1, depth);
+        return buf1;
+    }
+
+    convertToCn(src, buf0, cn);
+    convertToDepth(buf0, buf1, depth);
+    return buf1;
+}
+#endif
index 975783d..9fa63da 100644 (file)
@@ -45,6 +45,9 @@
 
 #include "opencv2/core/core.hpp"
 #include "opencv2/core/gpumat.hpp"
+#ifdef HAVE_OPENCV_OCL
+#include "opencv2/ocl/ocl.hpp"
+#endif
 
 namespace cv
 {
@@ -57,6 +60,10 @@ namespace cv
 
         CV_EXPORTS Mat convertToType(const Mat& src, int type, Mat& buf0, Mat& buf1);
         CV_EXPORTS gpu::GpuMat convertToType(const gpu::GpuMat& src, int type, gpu::GpuMat& buf0, gpu::GpuMat& buf1);
+
+#ifdef HAVE_OPENCV_OCL
+        CV_EXPORTS ocl::oclMat convertToType(const ocl::oclMat& src, int type, ocl::oclMat& buf0, ocl::oclMat& buf1);
+#endif
     }
 }
 
diff --git a/modules/superres/src/opencl/superres_btvl1.cl b/modules/superres/src/opencl/superres_btvl1.cl
new file mode 100644 (file)
index 0000000..0efa170
--- /dev/null
@@ -0,0 +1,261 @@
+/*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) 2010-2012, Multicoreware, Inc., all rights reserved.
+// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jin Ma jin@multicorewareinc.com
+//
+// 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 oclMaterials 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*/
+
+__kernel void buildMotionMapsKernel(__global float* forwardMotionX,
+    __global float* forwardMotionY,
+    __global float* backwardMotionX,
+    __global float* backwardMotionY,
+    __global float* forwardMapX,
+    __global float* forwardMapY,
+    __global float* backwardMapX,
+    __global float* backwardMapY,
+    int forwardMotionX_row,
+    int forwardMotionX_col,
+    int forwardMotionX_step,
+    int forwardMotionY_step,
+    int backwardMotionX_step,
+    int backwardMotionY_step,
+    int forwardMapX_step,
+    int forwardMapY_step,
+    int backwardMapX_step,
+    int backwardMapY_step
+    )
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if(x < forwardMotionX_col && y < forwardMotionX_row)
+    {
+        float fx = forwardMotionX[y * forwardMotionX_step + x];
+        float fy = forwardMotionY[y * forwardMotionY_step + x];
+
+        float bx = backwardMotionX[y * backwardMotionX_step + x];
+        float by = backwardMotionY[y * backwardMotionY_step + x];
+
+        forwardMapX[y * forwardMapX_step + x] = x + bx;
+        forwardMapY[y * forwardMapY_step + x] = y + by;
+
+        backwardMapX[y * backwardMapX_step + x] = x + fx;
+        backwardMapY[y * backwardMapY_step + x] = y + fy;
+    }
+}
+
+__kernel void upscaleKernel(__global float* src,
+    __global float* dst,
+    int src_step,
+    int dst_step,
+    int src_row,
+    int src_col,
+    int scale,
+    int channels
+    )
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if(x < src_col && y < src_row)
+    {
+        if(channels == 1)
+        {
+            dst[y * scale * dst_step + x * scale] = src[y * src_step + x];
+        }else if(channels == 3)
+        {
+            dst[y * channels * scale * dst_step + 3 * x * scale + 0] = src[y * channels * src_step + 3 * x + 0];
+            dst[y * channels * scale * dst_step + 3 * x * scale + 1] = src[y * channels * src_step + 3 * x + 1];
+            dst[y * channels * scale * dst_step + 3 * x * scale + 2] = src[y * channels * src_step + 3 * x + 2];
+        }else
+        {
+            dst[y * channels * scale * dst_step + 4 * x * scale + 0] = src[y * channels * src_step + 4 * x + 0];
+            dst[y * channels * scale * dst_step + 4 * x * scale + 1] = src[y * channels * src_step + 4 * x + 1];
+            dst[y * channels * scale * dst_step + 4 * x * scale + 2] = src[y * channels * src_step + 4 * x + 2];
+            dst[y * channels * scale * dst_step + 4 * x * scale + 3] = src[y * channels * src_step + 4 * x + 3];            
+        }
+    }
+}
+
+
+float diffSign(float a, float b)
+{
+    return a > b ? 1.0f : a < b ? -1.0f : 0.0f;
+}
+
+float3 diffSign3(float3 a, float3 b)
+{
+    float3 pos;
+    pos.x = a.x > b.x ? 1.0f : a.x < b.x ? -1.0f : 0.0f;
+    pos.y = a.y > b.y ? 1.0f : a.y < b.y ? -1.0f : 0.0f;
+    pos.z = a.z > b.z ? 1.0f : a.z < b.z ? -1.0f : 0.0f;
+    return pos;
+}
+
+float4 diffSign4(float4 a, float4 b)
+{
+    float4 pos;
+    pos.x = a.x > b.x ? 1.0f : a.x < b.x ? -1.0f : 0.0f;
+    pos.y = a.y > b.y ? 1.0f : a.y < b.y ? -1.0f : 0.0f;
+    pos.z = a.z > b.z ? 1.0f : a.z < b.z ? -1.0f : 0.0f;
+    pos.w = 0.0f;
+    return pos;
+}
+
+__kernel void diffSignKernel(__global float* src1,
+    __global float* src2,
+    __global float* dst,
+    int src1_row,
+    int src1_col,
+    int dst_step,
+    int src1_step,
+    int src2_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if(x < src1_col && y < src1_row)
+    {
+        dst[y * dst_step + x] = diffSign(src1[y * src1_step + x], src2[y * src2_step + x]);
+    }
+    barrier(CLK_LOCAL_MEM_FENCE);
+}
+
+__kernel void calcBtvRegularizationKernel(__global float* src,
+    __global float* dst,
+    int src_step,
+    int dst_step,
+    int src_row,
+    int src_col,
+    int ksize,
+    int channels,
+    __global float* c_btvRegWeights
+    )
+{
+    int x = get_global_id(0) + ksize;
+    int y = get_global_id(1) + ksize;
+
+    if ((y < src_row - ksize) && (x < src_col - ksize))
+    {
+        if(channels == 1)
+        {
+            const float srcVal = src[y * src_step + x];
+            float dstVal = 0.0f;
+
+            for (int m = 0, count = 0; m <= ksize; ++m)
+            {
+                for (int l = ksize; l + m >= 0; --l, ++count)
+                    dstVal = dstVal + c_btvRegWeights[count] * (diffSign(srcVal, src[(y + m) * src_step + (x + l)]) - diffSign(src[(y - m) * src_step + (x - l)], srcVal));
+            }
+            dst[y * dst_step + x] = dstVal;
+        }else if(channels == 3)
+        {
+            float3 srcVal;
+            srcVal.x = src[y * src_step + 3 * x + 0];
+            srcVal.y = src[y * src_step + 3 * x + 1];
+            srcVal.z = src[y * src_step + 3 * x + 2];
+
+            float3 dstVal;
+            dstVal.x = 0.0f;
+            dstVal.y = 0.0f;
+            dstVal.z = 0.0f;
+
+            for (int m = 0, count = 0; m <= ksize; ++m)
+            {
+                for (int l = ksize; l + m >= 0; --l, ++count)
+                {
+                    float3 src1;
+                    src1.x = src[(y + m) * src_step + 3 * (x + l) + 0];
+                    src1.y = src[(y + m) * src_step + 3 * (x + l) + 1];
+                    src1.z = src[(y + m) * src_step + 3 * (x + l) + 2];
+
+                    float3 src2;
+                    src2.x = src[(y - m) * src_step + 3 * (x - l) + 0];
+                    src2.y = src[(y - m) * src_step + 3 * (x - l) + 1];
+                    src2.z = src[(y - m) * src_step + 3 * (x - l) + 2];
+
+                    dstVal = dstVal + c_btvRegWeights[count] * (diffSign3(srcVal, src1) - diffSign3(src2, srcVal));
+                }
+            }
+            dst[y * dst_step + 3 * x + 0] = dstVal.x;
+            dst[y * dst_step + 3 * x + 1] = dstVal.y;
+            dst[y * dst_step + 3 * x + 2] = dstVal.z;
+        }else
+        {
+            float4 srcVal;
+            srcVal.x = src[y * src_step + 4 * x + 0];//r type =float
+            srcVal.y = src[y * src_step + 4 * x + 1];//g
+            srcVal.z = src[y * src_step + 4 * x + 2];//b
+            srcVal.w = src[y * src_step + 4 * x + 3];//a
+
+            float4 dstVal;
+            dstVal.x = 0.0f;
+            dstVal.y = 0.0f;
+            dstVal.z = 0.0f;
+            dstVal.w = 0.0f;
+
+            for (int m = 0, count = 0; m <= ksize; ++m)
+            {
+                for (int l = ksize; l + m >= 0; --l, ++count)
+                {
+                    float4 src1;
+                    src1.x = src[(y + m) * src_step + 4 * (x + l) + 0];
+                    src1.y = src[(y + m) * src_step + 4 * (x + l) + 1];
+                    src1.z = src[(y + m) * src_step + 4 * (x + l) + 2];
+                    src1.w = src[(y + m) * src_step + 4 * (x + l) + 3];
+
+                    float4 src2;
+                    src2.x = src[(y - m) * src_step + 4 * (x - l) + 0];
+                    src2.y = src[(y - m) * src_step + 4 * (x - l) + 1];
+                    src2.z = src[(y - m) * src_step + 4 * (x - l) + 2];
+                    src2.w = src[(y - m) * src_step + 4 * (x - l) + 3];
+
+                    dstVal = dstVal + c_btvRegWeights[count] * (diffSign4(srcVal, src1) - diffSign4(src2, srcVal));
+
+                }
+            }
+            dst[y * dst_step + 4 * x + 0] = dstVal.x;
+            dst[y * dst_step + 4 * x + 1] = dstVal.y;
+            dst[y * dst_step + 4 * x + 2] = dstVal.z;
+            dst[y * dst_step + 4 * x + 3] = dstVal.w;
+        }
+    }
+}
\ No newline at end of file
index 1264217..125969b 100644 (file)
@@ -719,3 +719,269 @@ Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_DualTVL1_GPU()
 }
 
 #endif // HAVE_OPENCV_GPU
+#ifdef HAVE_OPENCV_OCL
+
+namespace
+{
+    class oclOpticalFlow : public DenseOpticalFlowExt
+    {
+    public:
+        explicit oclOpticalFlow(int work_type);
+
+        void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2);
+        void collectGarbage();
+
+    protected:
+        virtual void impl(const cv::ocl::oclMat& input0, const cv::ocl::oclMat& input1, cv::ocl::oclMat& dst1, cv::ocl::oclMat& dst2) = 0;
+
+    private:
+        int work_type_;
+        cv::ocl::oclMat buf_[6];
+        cv::ocl::oclMat u_, v_, flow_;
+    };
+
+    oclOpticalFlow::oclOpticalFlow(int work_type) : work_type_(work_type)
+    {
+    }
+
+    void oclOpticalFlow::calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2)
+    {
+        ocl::oclMat& _frame0 = ocl::getOclMatRef(frame0);
+        ocl::oclMat& _frame1 = ocl::getOclMatRef(frame1);
+        ocl::oclMat& _flow1  = ocl::getOclMatRef(flow1);
+        ocl::oclMat& _flow2  = ocl::getOclMatRef(flow2);
+
+        CV_Assert( _frame1.type() == _frame0.type() );
+        CV_Assert( _frame1.size() == _frame0.size() );
+
+        cv::ocl::oclMat input0_ = convertToType(_frame0, work_type_, buf_[2], buf_[3]);
+        cv::ocl::oclMat input1_ = convertToType(_frame1, work_type_, buf_[4], buf_[5]);
+
+        impl(input0_, input1_, u_, v_);//go to tvl1 algorithm
+
+        u_.copyTo(_flow1);
+        v_.copyTo(_flow2);
+    }
+
+    void oclOpticalFlow::collectGarbage()
+    {
+        for (int i = 0; i < 6; ++i)
+            buf_[i].release();
+        u_.release();
+        v_.release();
+        flow_.release();
+    }
+}
+///////////////////////////////////////////////////////////////////
+// PyrLK_OCL
+
+namespace
+{
+    class PyrLK_OCL : public oclOpticalFlow
+    {
+    public:
+        AlgorithmInfo* info() const;
+
+        PyrLK_OCL();
+
+        void collectGarbage();
+
+    protected:
+        void impl(const ocl::oclMat& input0, const ocl::oclMat& input1, ocl::oclMat& dst1, ocl::oclMat& dst2);
+
+    private:
+        int winSize_;
+        int maxLevel_;
+        int iterations_;
+
+        ocl::PyrLKOpticalFlow alg_;
+    };
+
+    CV_INIT_ALGORITHM(PyrLK_OCL, "DenseOpticalFlowExt.PyrLK_OCL",
+        obj.info()->addParam(obj, "winSize", obj.winSize_);
+    obj.info()->addParam(obj, "maxLevel", obj.maxLevel_);
+    obj.info()->addParam(obj, "iterations", obj.iterations_));
+
+    PyrLK_OCL::PyrLK_OCL() : oclOpticalFlow(CV_8UC1)
+    {
+        winSize_ = alg_.winSize.width;
+        maxLevel_ = alg_.maxLevel;
+        iterations_ = alg_.iters;
+    }
+
+    void PyrLK_OCL::impl(const cv::ocl::oclMat& input0, const cv::ocl::oclMat& input1, cv::ocl::oclMat& dst1, cv::ocl::oclMat& dst2)
+    {
+        alg_.winSize.width = winSize_;
+        alg_.winSize.height = winSize_;
+        alg_.maxLevel = maxLevel_;
+        alg_.iters = iterations_;
+
+        alg_.dense(input0, input1, dst1, dst2);
+    }
+
+    void PyrLK_OCL::collectGarbage()
+    {
+        alg_.releaseMemory();
+        oclOpticalFlow::collectGarbage();
+    }
+}
+
+Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_PyrLK_OCL()
+{
+    return new PyrLK_OCL;
+}
+
+///////////////////////////////////////////////////////////////////
+// DualTVL1_OCL
+
+namespace
+{
+    class DualTVL1_OCL : public oclOpticalFlow
+    {
+    public:
+        AlgorithmInfo* info() const;
+
+        DualTVL1_OCL();
+
+        void collectGarbage();
+
+    protected:
+        void impl(const cv::ocl::oclMat& input0, const cv::ocl::oclMat& input1, cv::ocl::oclMat& dst1, cv::ocl::oclMat& dst2);
+
+    private:
+        double tau_;
+        double lambda_;
+        double theta_;
+        int nscales_;
+        int warps_;
+        double epsilon_;
+        int iterations_;
+        bool useInitialFlow_;
+
+        ocl::OpticalFlowDual_TVL1_OCL alg_;
+    };
+
+    CV_INIT_ALGORITHM(DualTVL1_OCL, "DenseOpticalFlowExt.DualTVL1_OCL",
+    obj.info()->addParam(obj, "tau", obj.tau_);
+    obj.info()->addParam(obj, "lambda", obj.lambda_);
+    obj.info()->addParam(obj, "theta", obj.theta_);
+    obj.info()->addParam(obj, "nscales", obj.nscales_);
+    obj.info()->addParam(obj, "warps", obj.warps_);
+    obj.info()->addParam(obj, "epsilon", obj.epsilon_);
+    obj.info()->addParam(obj, "iterations", obj.iterations_);
+    obj.info()->addParam(obj, "useInitialFlow", obj.useInitialFlow_));
+
+    DualTVL1_OCL::DualTVL1_OCL() : oclOpticalFlow(CV_8UC1)
+    {
+        tau_ = alg_.tau;
+        lambda_ = alg_.lambda;
+        theta_ = alg_.theta;
+        nscales_ = alg_.nscales;
+        warps_ = alg_.warps;
+        epsilon_ = alg_.epsilon;
+        iterations_ = alg_.iterations;
+        useInitialFlow_ = alg_.useInitialFlow;
+    }
+
+    void DualTVL1_OCL::impl(const cv::ocl::oclMat& input0, const cv::ocl::oclMat& input1, cv::ocl::oclMat& dst1, cv::ocl::oclMat& dst2)
+    {
+        alg_.tau = tau_;
+        alg_.lambda = lambda_;
+        alg_.theta = theta_;
+        alg_.nscales = nscales_;
+        alg_.warps = warps_;
+        alg_.epsilon = epsilon_;
+        alg_.iterations = iterations_;
+        alg_.useInitialFlow = useInitialFlow_;
+
+        alg_(input0, input1, dst1, dst2);
+
+    }
+
+    void DualTVL1_OCL::collectGarbage()
+    {
+        alg_.collectGarbage();
+        oclOpticalFlow::collectGarbage();
+    }
+}
+
+Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_DualTVL1_OCL()
+{
+    return new DualTVL1_OCL;
+}
+
+///////////////////////////////////////////////////////////////////
+// FarneBack
+
+namespace
+{
+    class FarneBack_OCL : public oclOpticalFlow
+    {
+    public:
+        AlgorithmInfo* info() const;
+
+        FarneBack_OCL();
+
+        void collectGarbage();
+
+    protected:
+        void impl(const cv::ocl::oclMat& input0, const cv::ocl::oclMat& input1, cv::ocl::oclMat& dst1, cv::ocl::oclMat& dst2);
+
+    private:
+        double pyrScale_;
+        int numLevels_;
+        int winSize_;
+        int numIters_;
+        int polyN_;
+        double polySigma_;
+        int flags_;
+
+        ocl::FarnebackOpticalFlow alg_;
+    };
+
+    CV_INIT_ALGORITHM(FarneBack_OCL, "DenseOpticalFlowExt.FarneBack_OCL",
+        obj.info()->addParam(obj, "pyrScale", obj.pyrScale_);
+    obj.info()->addParam(obj, "numLevels", obj.numLevels_);
+    obj.info()->addParam(obj, "winSize", obj.winSize_);
+    obj.info()->addParam(obj, "numIters", obj.numIters_);
+    obj.info()->addParam(obj, "polyN", obj.polyN_);
+    obj.info()->addParam(obj, "polySigma", obj.polySigma_);
+    obj.info()->addParam(obj, "flags", obj.flags_));
+
+    FarneBack_OCL::FarneBack_OCL() : oclOpticalFlow(CV_8UC1)
+    {
+        pyrScale_ = alg_.pyrScale;
+        numLevels_ = alg_.numLevels;
+        winSize_ = alg_.winSize;
+        numIters_ = alg_.numIters;
+        polyN_ = alg_.polyN;
+        polySigma_ = alg_.polySigma;
+        flags_ = alg_.flags;
+    }
+
+    void FarneBack_OCL::impl(const cv::ocl::oclMat& input0, const cv::ocl::oclMat& input1, cv::ocl::oclMat& dst1, cv::ocl::oclMat& dst2)
+    {
+        alg_.pyrScale = pyrScale_;
+        alg_.numLevels = numLevels_;
+        alg_.winSize = winSize_;
+        alg_.numIters = numIters_;
+        alg_.polyN = polyN_;
+        alg_.polySigma = polySigma_;
+        alg_.flags = flags_;
+
+        alg_(input0, input1, dst1, dst2);
+    }
+
+    void FarneBack_OCL::collectGarbage()
+    {
+        alg_.releaseMemory();
+        oclOpticalFlow::collectGarbage();
+    }
+}
+
+Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_Farneback_OCL()
+{
+    return new FarneBack_OCL;
+}
+
+#endif
\ No newline at end of file
diff --git a/modules/superres/src/precomp.cpp b/modules/superres/src/precomp.cpp
deleted file mode 100644 (file)
index 3c01a25..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*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 "precomp.hpp"
index 82b591b..4cf4941 100644 (file)
@@ -46,9 +46,7 @@
 #include <vector>
 #include <limits>
 
-#ifdef HAVE_CVCONFIG_H
   #include "cvconfig.h"
-#endif
 
 #include "opencv2/opencv_modules.hpp"
 #include "opencv2/core/core.hpp"
     #endif
 #endif
 
+#ifdef HAVE_OPENCV_OCL
+    #include "opencv2/ocl/private/util.hpp"
+#endif
+
 #ifdef HAVE_OPENCV_HIGHGUI
     #include "opencv2/highgui/highgui.hpp"
 #endif
diff --git a/modules/superres/test/test_precomp.cpp b/modules/superres/test/test_precomp.cpp
deleted file mode 100644 (file)
index 0fb6521..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*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"
index 0371c34..8102d43 100644 (file)
@@ -51,9 +51,7 @@
 #ifndef __OPENCV_TEST_PRECOMP_HPP__
 #define __OPENCV_TEST_PRECOMP_HPP__
 
-#ifdef HAVE_CVCONFIG_H
 #include "cvconfig.h"
-#endif
 
 #include "opencv2/opencv_modules.hpp"
 #include "opencv2/core/core.hpp"
index b4a546c..9aa9a44 100644 (file)
@@ -274,5 +274,12 @@ TEST_F(SuperResolution, BTVL1_GPU)
 {
     RunTest(cv::superres::createSuperResolution_BTVL1_GPU());
 }
-
 #endif
+#if defined(HAVE_OPENCV_OCL) && defined(HAVE_OPENCL)
+TEST_F(SuperResolution, BTVL1_OCL)
+{
+    std::vector<cv::ocl::Info> infos;
+    cv::ocl::getDevice(infos);
+    RunTest(cv::superres::createSuperResolution_BTVL1_OCL());
+}
+#endif 
index 1eaeb39..4af917b 100644 (file)
@@ -4,10 +4,7 @@ if(IOS)
   ocv_module_disable(ts)
 endif()
 
-if(MINGW)
-  set(OPENCV_MODULE_TYPE STATIC)
-endif()
-
+set(OPENCV_MODULE_TYPE STATIC)
 set(OPENCV_MODULE_IS_PART_OF_WORLD FALSE)
 
 if(HAVE_CUDA)
@@ -22,10 +19,4 @@ ocv_glob_module_sources()
 ocv_module_include_directories()
 ocv_create_module()
 
-if(BUILD_SHARED_LIBS AND NOT MINGW)
-  add_definitions(-DGTEST_CREATE_SHARED_LIBRARY=1)
-else()
-  add_definitions(-DGTEST_CREATE_SHARED_LIBRARY=0)
-endif()
-
 ocv_add_precompiled_headers(${the_module})
index fcef589..2f32c24 100644 (file)
@@ -1,17 +1,12 @@
 #ifndef __OPENCV_GTESTCV_HPP__
 #define __OPENCV_GTESTCV_HPP__
 
-#ifdef HAVE_CVCONFIG_H
-#include "cvconfig.h"
-#endif
-#ifndef GTEST_CREATE_SHARED_LIBRARY
-#ifdef BUILD_SHARED_LIBS
-#define GTEST_LINKED_AS_SHARED_LIBRARY 1
-#endif
-#endif
-
 #include <stdarg.h> // for va_list
 
+#ifdef HAVE_WINRT
+    #pragma warning(disable:4447) // Disable warning 'main' signature found without threading model
+#endif
+
 #ifdef _MSC_VER
 #pragma warning( disable: 4127 )
 #endif
@@ -578,6 +573,13 @@ int main(int argc, char **argv) \
     return RUN_ALL_TESTS(); \
 }
 
+// This usually only makes sense in perf tests with several implementations,
+// some of which are not available.
+#define CV_TEST_FAIL_NO_IMPL() do { \
+    ::testing::Test::RecordProperty("custom_status", "noimpl"); \
+    FAIL() << "No equivalent implementation."; \
+} while (0)
+
 #endif
 
 #include "ts_perf.hpp"
index 2d1227e..80b410b 100644 (file)
@@ -17566,6 +17566,9 @@ GTEST_DECLARE_string_(color);
 // the tests to run. If the filter is not given all tests are executed.
 GTEST_DECLARE_string_(filter);
 
+// OpenCV extension: same as filter, but for the parameters string.
+GTEST_DECLARE_string_(param_filter);
+
 // This flag causes the Google Test to list tests. None of the tests listed
 // are actually run if the flag is provided.
 GTEST_DECLARE_bool_(list_tests);
index fe57655..fa88dad 100644 (file)
@@ -210,18 +210,13 @@ private:
 #define SANITY_CHECK_KEYPOINTS(array, ...) ::perf::Regression::addKeypoints(this, #array, array , ## __VA_ARGS__)
 #define SANITY_CHECK_MATCHES(array, ...) ::perf::Regression::addMatches(this, #array, array , ## __VA_ARGS__)
 
-#ifdef HAVE_CUDA
 class CV_EXPORTS GpuPerf
 {
 public:
   static bool targetDevice();
 };
 
-# define PERF_RUN_GPU()  ::perf::GpuPerf::targetDevice()
-#else
-# define PERF_RUN_GPU()  false
-#endif
-
+#define PERF_RUN_GPU()  ::perf::GpuPerf::targetDevice()
 
 /*****************************************************************************************\
 *                            Container for performance metrics                            *
@@ -263,7 +258,11 @@ public:
     TestBase();
 
     static void Init(int argc, const char* const argv[]);
+    static void Init(const std::vector<std::string> & availableImpls,
+                     int argc, const char* const argv[]);
+    static void RecordRunParameters();
     static std::string getDataPath(const std::string& relativePath);
+    static std::string getSelectedImpl();
 
 protected:
     virtual void PerfTestBody() = 0;
@@ -476,16 +475,37 @@ CV_EXPORTS void PrintTo(const Size& sz, ::std::ostream* os);
     INSTANTIATE_TEST_CASE_P(/*none*/, fixture##_##name, params);\
     void fixture##_##name::PerfTestBody()
 
+#if defined(_MSC_VER) && (_MSC_VER <= 1400)
+#define CV_PERF_TEST_MAIN_INTERNALS_ARGS(...)  \
+    while (++argc >= (--argc,-1)) {__VA_ARGS__; break;} /*this ugly construction is needed for VS 2005*/
+#else
+#define CV_PERF_TEST_MAIN_INTERNALS_ARGS(...)  \
+    __VA_ARGS__;
+#endif
 
-#define CV_PERF_TEST_MAIN(testsuitname, ...) \
-int main(int argc, char **argv)\
-{\
-    while (++argc >= (--argc,-1)) {__VA_ARGS__; break;} /*this ugly construction is needed for VS 2005*/\
-    ::perf::Regression::Init(#testsuitname);\
-    ::perf::TestBase::Init(argc, argv);\
+#define CV_PERF_TEST_MAIN_INTERNALS(modulename, impls, ...)    \
+    CV_PERF_TEST_MAIN_INTERNALS_ARGS(__VA_ARGS__) \
+    ::perf::Regression::Init(#modulename);\
+    ::perf::TestBase::Init(std::vector<std::string>(impls, impls + sizeof impls / sizeof *impls),\
+                           argc, argv);\
     ::testing::InitGoogleTest(&argc, argv);\
     cvtest::printVersionInfo();\
-    return RUN_ALL_TESTS();\
+    ::testing::Test::RecordProperty("cv_module_name", #modulename);\
+    ::perf::TestBase::RecordRunParameters();\
+    return RUN_ALL_TESTS();
+
+// impls must be an array, not a pointer; "plain" should always be one of the implementations
+#define CV_PERF_TEST_MAIN_WITH_IMPLS(modulename, impls, ...) \
+int main(int argc, char **argv)\
+{\
+    CV_PERF_TEST_MAIN_INTERNALS(modulename, impls, __VA_ARGS__)\
+}
+
+#define CV_PERF_TEST_MAIN(modulename, ...) \
+int main(int argc, char **argv)\
+{\
+    const char * plain_only[] = { "plain" };\
+    CV_PERF_TEST_MAIN_INTERNALS(modulename, plain_only, __VA_ARGS__)\
 }
 
 #define TEST_CYCLE_N(n) for(declare.iterations(n); startTimer(), next(); stopTimer())
index 7ae6aa5..4ab0a3e 100755 (executable)
@@ -1,6 +1,9 @@
 #!/usr/bin/env python
 
-import sys, re, os.path
+import collections
+import re
+import os.path
+import sys
 from xml.dom.minidom import parse
 
 class TestInfo(object):
@@ -10,10 +13,17 @@ class TestInfo(object):
         self.name = xmlnode.getAttribute("name")
         self.value_param = xmlnode.getAttribute("value_param")
         self.type_param = xmlnode.getAttribute("type_param")
-        if xmlnode.getElementsByTagName("failure"):
+
+        custom_status = xmlnode.getAttribute("custom_status")
+        failures = xmlnode.getElementsByTagName("failure")
+
+        if len(custom_status) > 0:
+            self.status = custom_status
+        elif len(failures) > 0:
             self.status = "failed"
         else:
             self.status = xmlnode.getAttribute("status")
+
         if self.name.startswith("DISABLED_"):
             self.status = "disabled"
             self.fixture = self.fixture.replace("DISABLED_", "")
@@ -100,34 +110,39 @@ class TestInfo(object):
     def dump(self, units="ms"):
         print "%s ->\t\033[1;31m%s\033[0m = \t%.2f%s" % (str(self), self.status, self.get("gmean", units), units)
 
-    def shortName(self):
+
+    def getName(self):
         pos = self.name.find("/")
         if pos > 0:
-            name = self.name[:pos]
-        else:
-            name = self.name
-        if self.fixture.endswith(name):
-            fixture = self.fixture[:-len(name)]
+            return self.name[:pos]
+        return self.name
+
+
+    def getFixture(self):
+        if self.fixture.endswith(self.getName()):
+            fixture = self.fixture[:-len(self.getName())]
         else:
             fixture = self.fixture
         if fixture.endswith("_"):
             fixture = fixture[:-1]
+        return fixture
+
+
+    def param(self):
+        return '::'.join(filter(None, [self.type_param, self.value_param]))
+
+    def shortName(self):
+        name = self.getName()
+        fixture = self.getFixture()
         return '::'.join(filter(None, [name, fixture]))
 
+
     def __str__(self):
-        pos = self.name.find("/")
-        if pos > 0:
-            name = self.name[:pos]
-        else:
-            name = self.name
-        if self.fixture.endswith(name):
-            fixture = self.fixture[:-len(name)]
-        else:
-            fixture = self.fixture
-        if fixture.endswith("_"):
-            fixture = fixture[:-1]
+        name = self.getName()
+        fixture = self.getFixture()
         return '::'.join(filter(None, [name, fixture, self.type_param, self.value_param]))
 
+
     def __cmp__(self, other):
         r = cmp(self.fixture, other.fixture);
         if r != 0:
@@ -154,12 +169,31 @@ class TestInfo(object):
                 return 1
         return 0
 
+# This is a Sequence for compatibility with old scripts,
+# which treat parseLogFile's return value as a list.
+class TestRunInfo(collections.Sequence):
+    def __init__(self, properties, tests):
+        self.properties = properties
+        self.tests = tests
+
+    def __len__(self):
+        return len(self.tests)
+
+    def __getitem__(self, key):
+        return self.tests[key]
+
 def parseLogFile(filename):
-    tests = []
     log = parse(filename)
-    for case in log.getElementsByTagName("testcase"):
-        tests.append(TestInfo(case))
-    return tests
+
+    properties = {
+        attr_name[3:]: attr_value
+        for (attr_name, attr_value) in log.documentElement.attributes.items()
+        if attr_name.startswith('cv_')
+    }
+
+    tests = map(TestInfo, log.getElementsByTagName("testcase"))
+
+    return TestRunInfo(properties, tests)
 
 
 if __name__ == "__main__":
@@ -168,8 +202,18 @@ if __name__ == "__main__":
         exit(0)
 
     for arg in sys.argv[1:]:
-        print "Tests found in", arg
-        tests = parseLogFile(arg)
-        for t in sorted(tests):
+        print "Processing {}...".format(arg)
+
+        run = parseLogFile(arg)
+
+        print "Properties:"
+
+        for (prop_name, prop_value) in run.properties.items():
+          print "\t{} = {}".format(prop_name, prop_value)
+
+        print "Tests:"
+
+        for t in sorted(run.tests):
             t.dump()
+
         print
diff --git a/modules/ts/misc/xls-report.py b/modules/ts/misc/xls-report.py
new file mode 100755 (executable)
index 0000000..e71a7f6
--- /dev/null
@@ -0,0 +1,371 @@
+#!/usr/bin/env python
+
+"""
+    This script can generate XLS reports from OpenCV tests' XML output files.
+
+    To use it, first, create a directory for each machine you ran tests on.
+    Each such directory will become a sheet in the report. Put each XML file
+    into the corresponding directory.
+
+    Then, create your configuration file(s). You can have a global configuration
+    file (specified with the -c option), and per-sheet configuration files, which
+    must be called sheet.conf and placed in the directory corresponding to the sheet.
+    The settings in the per-sheet configuration file will override those in the
+    global configuration file, if both are present.
+
+    A configuration file must consist of a Python dictionary. The following keys
+    will be recognized:
+
+    * 'comparisons': [{'from': string, 'to': string}]
+        List of configurations to compare performance between. For each item,
+        the sheet will have a column showing speedup from configuration named
+        'from' to configuration named "to".
+
+    * 'configuration_matchers': [{'properties': {string: object}, 'name': string}]
+        Instructions for matching test run property sets to configuration names.
+
+        For each found XML file:
+
+        1) All attributes of the root element starting with the prefix 'cv_' are
+           placed in a dictionary, with the cv_ prefix stripped and the cv_module_name
+           element deleted.
+
+        2) The first matcher for which the XML's file property set contains the same
+           keys with equal values as its 'properties' dictionary is searched for.
+           A missing property can be matched by using None as the value.
+
+           Corollary 1: you should place more specific matchers before less specific
+           ones.
+
+           Corollary 2: an empty 'properties' dictionary matches every property set.
+
+        3) If a matching matcher is found, its 'name' string is presumed to be the name
+           of the configuration the XML file corresponds to. A warning is printed if
+           two different property sets match to the same configuration name.
+
+        4) If a such a matcher isn't found, if --include-unmatched was specified, the
+           configuration name is assumed to be the relative path from the sheet's
+           directory to the XML file's containing directory. If the XML file isinstance
+           directly inside the sheet's directory, the configuration name is instead
+           a dump of all its properties. If --include-unmatched wasn't specified,
+           the XML file is ignored and a warning is printed.
+
+    * 'configurations': [string]
+        List of names for compile-time and runtime configurations of OpenCV.
+        Each item will correspond to a column of the sheet.
+
+    * 'module_colors': {string: string}
+        Mapping from module name to color name. In the sheet, cells containing module
+        names from this mapping will be colored with the corresponding color. You can
+        find the list of available colors here:
+        <http://www.simplistix.co.uk/presentations/python-excel.pdf>.
+
+    * 'sheet_name': string
+        Name for the sheet. If this parameter is missing, the name of sheet's directory
+        will be used.
+
+    * 'sheet_properties': [(string, string)]
+        List of arbitrary (key, value) pairs that somehow describe the sheet. Will be
+        dumped into the first row of the sheet in string form.
+
+    Note that all keys are optional, although to get useful results, you'll want to
+    specify at least 'configurations' and 'configuration_matchers'.
+
+    Finally, run the script. Use the --help option for usage information.
+"""
+
+from __future__ import division
+
+import ast
+import errno
+import fnmatch
+import logging
+import numbers
+import os, os.path
+import re
+
+from argparse import ArgumentParser
+from glob import glob
+from itertools import ifilter
+
+import xlwt
+
+from testlog_parser import parseLogFile
+
+re_image_size = re.compile(r'^ \d+ x \d+$', re.VERBOSE)
+re_data_type = re.compile(r'^ (?: 8 | 16 | 32 | 64 ) [USF] C [1234] $', re.VERBOSE)
+
+time_style = xlwt.easyxf(num_format_str='#0.00')
+no_time_style = xlwt.easyxf('pattern: pattern solid, fore_color gray25')
+
+speedup_style = time_style
+good_speedup_style = xlwt.easyxf('font: color green', num_format_str='#0.00')
+bad_speedup_style = xlwt.easyxf('font: color red', num_format_str='#0.00')
+no_speedup_style = no_time_style
+error_speedup_style = xlwt.easyxf('pattern: pattern solid, fore_color orange')
+header_style = xlwt.easyxf('font: bold true; alignment: horizontal centre, vertical top, wrap True')
+subheader_style = xlwt.easyxf('alignment: horizontal centre, vertical top')
+
+class Collector(object):
+    def __init__(self, config_match_func, include_unmatched):
+        self.__config_cache = {}
+        self.config_match_func = config_match_func
+        self.include_unmatched = include_unmatched
+        self.tests = {}
+        self.extra_configurations = set()
+
+    # Format a sorted sequence of pairs as if it was a dictionary.
+    # We can't just use a dictionary instead, since we want to preserve the sorted order of the keys.
+    @staticmethod
+    def __format_config_cache_key(pairs, multiline=False):
+        return (
+          ('{\n' if multiline else '{') +
+          (',\n' if multiline else ', ').join(
+             ('  ' if multiline else '') + repr(k) + ': ' + repr(v) for (k, v) in pairs) +
+          ('\n}\n' if multiline else '}')
+        )
+
+    def collect_from(self, xml_path, default_configuration):
+        run = parseLogFile(xml_path)
+
+        module = run.properties['module_name']
+
+        properties = run.properties.copy()
+        del properties['module_name']
+
+        props_key = tuple(sorted(properties.iteritems())) # dicts can't be keys
+
+        if props_key in self.__config_cache:
+            configuration = self.__config_cache[props_key]
+        else:
+            configuration = self.config_match_func(properties)
+
+            if configuration is None:
+                if self.include_unmatched:
+                    if default_configuration is not None:
+                        configuration = default_configuration
+                    else:
+                        configuration = Collector.__format_config_cache_key(props_key, multiline=True)
+
+                    self.extra_configurations.add(configuration)
+                else:
+                    logging.warning('failed to match properties to a configuration: %s',
+                        Collector.__format_config_cache_key(props_key))
+
+            else:
+                same_config_props = [it[0] for it in self.__config_cache.iteritems() if it[1] == configuration]
+                if len(same_config_props) > 0:
+                    logging.warning('property set %s matches the same configuration %r as property set %s',
+                        Collector.__format_config_cache_key(props_key),
+                        configuration,
+                        Collector.__format_config_cache_key(same_config_props[0]))
+
+            self.__config_cache[props_key] = configuration
+
+        if configuration is None: return
+
+        module_tests = self.tests.setdefault(module, {})
+
+        for test in run.tests:
+            test_results = module_tests.setdefault((test.shortName(), test.param()), {})
+            new_result = test.get("gmean") if test.status == 'run' else test.status
+            test_results[configuration] = min(
+              test_results.get(configuration), new_result,
+              key=lambda r: (1, r) if isinstance(r, numbers.Number) else
+                            (2,) if r is not None else
+                            (3,)
+            ) # prefer lower result; prefer numbers to errors and errors to nothing
+
+def make_match_func(matchers):
+    def match_func(properties):
+        for matcher in matchers:
+            if all(properties.get(name) == value
+                   for (name, value) in matcher['properties'].iteritems()):
+                return matcher['name']
+
+        return None
+
+    return match_func
+
+def main():
+    arg_parser = ArgumentParser(description='Build an XLS performance report.')
+    arg_parser.add_argument('sheet_dirs', nargs='+', metavar='DIR', help='directory containing perf test logs')
+    arg_parser.add_argument('-o', '--output', metavar='XLS', default='report.xls', help='name of output file')
+    arg_parser.add_argument('-c', '--config', metavar='CONF', help='global configuration file')
+    arg_parser.add_argument('--include-unmatched', action='store_true',
+        help='include results from XML files that were not recognized by configuration matchers')
+    arg_parser.add_argument('--show-times-per-pixel', action='store_true',
+        help='for tests that have an image size parameter, show per-pixel time, as well as total time')
+
+    args = arg_parser.parse_args()
+
+    logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.DEBUG)
+
+    if args.config is not None:
+        with open(args.config) as global_conf_file:
+            global_conf = ast.literal_eval(global_conf_file.read())
+    else:
+        global_conf = {}
+
+    wb = xlwt.Workbook()
+
+    for sheet_path in args.sheet_dirs:
+        try:
+            with open(os.path.join(sheet_path, 'sheet.conf')) as sheet_conf_file:
+                sheet_conf = ast.literal_eval(sheet_conf_file.read())
+        except IOError as ioe:
+            if ioe.errno != errno.ENOENT: raise
+            sheet_conf = {}
+            logging.debug('no sheet.conf for %s', sheet_path)
+
+        sheet_conf = dict(global_conf.items() + sheet_conf.items())
+
+        config_names = sheet_conf.get('configurations', [])
+        config_matchers = sheet_conf.get('configuration_matchers', [])
+
+        collector = Collector(make_match_func(config_matchers), args.include_unmatched)
+
+        for root, _, filenames in os.walk(sheet_path):
+            logging.info('looking in %s', root)
+            for filename in fnmatch.filter(filenames, '*.xml'):
+                if os.path.normpath(sheet_path) == os.path.normpath(root):
+                  default_conf = None
+                else:
+                  default_conf = os.path.relpath(root, sheet_path)
+                collector.collect_from(os.path.join(root, filename), default_conf)
+
+        config_names.extend(sorted(collector.extra_configurations - set(config_names)))
+
+        sheet = wb.add_sheet(sheet_conf.get('sheet_name', os.path.basename(os.path.abspath(sheet_path))))
+
+        sheet_properties = sheet_conf.get('sheet_properties', [])
+
+        sheet.write(0, 0, 'Properties:')
+
+        sheet.write(0, 1,
+          'N/A' if len(sheet_properties) == 0 else
+          ' '.join(str(k) + '=' + repr(v) for (k, v) in sheet_properties))
+
+        sheet.row(2).height = 800
+        sheet.panes_frozen = True
+        sheet.remove_splits = True
+
+        sheet_comparisons = sheet_conf.get('comparisons', [])
+
+        row = 2
+
+        col = 0
+
+        for (w, caption) in [
+                (2500, 'Module'),
+                (10000, 'Test'),
+                (2000, 'Image\nwidth'),
+                (2000, 'Image\nheight'),
+                (2000, 'Data\ntype'),
+                (7500, 'Other parameters')]:
+            sheet.col(col).width = w
+            if args.show_times_per_pixel:
+                sheet.write_merge(row, row + 1, col, col, caption, header_style)
+            else:
+                sheet.write(row, col, caption, header_style)
+            col += 1
+
+        for config_name in config_names:
+            if args.show_times_per_pixel:
+                sheet.col(col).width = 3000
+                sheet.col(col + 1).width = 3000
+                sheet.write_merge(row, row, col, col + 1, config_name, header_style)
+                sheet.write(row + 1, col, 'total, ms', subheader_style)
+                sheet.write(row + 1, col + 1, 'per pixel, ns', subheader_style)
+                col += 2
+            else:
+                sheet.col(col).width = 4000
+                sheet.write(row, col, config_name, header_style)
+                col += 1
+
+        col += 1 # blank column between configurations and comparisons
+
+        for comp in sheet_comparisons:
+            sheet.col(col).width = 4000
+            caption = comp['to'] + '\nvs\n' + comp['from']
+            if args.show_times_per_pixel:
+                sheet.write_merge(row, row + 1, col, col, caption, header_style)
+            else:
+                sheet.write(row, col, caption, header_style)
+            col += 1
+
+        row += 2 if args.show_times_per_pixel else 1
+
+        sheet.horz_split_pos = row
+        sheet.horz_split_first_visible = row
+
+        module_colors = sheet_conf.get('module_colors', {})
+        module_styles = {module: xlwt.easyxf('pattern: pattern solid, fore_color {}'.format(color))
+                         for module, color in module_colors.iteritems()}
+
+        for module, tests in sorted(collector.tests.iteritems()):
+            for ((test, param), configs) in sorted(tests.iteritems()):
+                sheet.write(row, 0, module, module_styles.get(module, xlwt.Style.default_style))
+                sheet.write(row, 1, test)
+
+                param_list = param[1:-1].split(', ') if param.startswith('(') and param.endswith(')') else [param]
+
+                image_size = next(ifilter(re_image_size.match, param_list), None)
+                if image_size is not None:
+                    (image_width, image_height) = map(int, image_size.split('x', 1))
+                    sheet.write(row, 2, image_width)
+                    sheet.write(row, 3, image_height)
+                    del param_list[param_list.index(image_size)]
+
+                data_type = next(ifilter(re_data_type.match, param_list), None)
+                if data_type is not None:
+                    sheet.write(row, 4, data_type)
+                    del param_list[param_list.index(data_type)]
+
+                sheet.row(row).write(5, ' | '.join(param_list))
+
+                col = 6
+
+                for c in config_names:
+                    if c in configs:
+                        sheet.write(row, col, configs[c], time_style)
+                    else:
+                        sheet.write(row, col, None, no_time_style)
+                    col += 1
+                    if args.show_times_per_pixel:
+                        sheet.write(row, col,
+                          xlwt.Formula('{0} * 1000000 / ({1} * {2})'.format(
+                              xlwt.Utils.rowcol_to_cell(row, col - 1),
+                              xlwt.Utils.rowcol_to_cell(row, 2),
+                              xlwt.Utils.rowcol_to_cell(row, 3)
+                          )),
+                          time_style
+                        )
+                        col += 1
+
+                col += 1 # blank column
+
+                for comp in sheet_comparisons:
+                    cmp_from = configs.get(comp["from"])
+                    cmp_to = configs.get(comp["to"])
+
+                    if isinstance(cmp_from, numbers.Number) and isinstance(cmp_to, numbers.Number):
+                        try:
+                            speedup = cmp_from / cmp_to
+                            sheet.write(row, col, speedup, good_speedup_style if speedup > 1.1 else
+                                                           bad_speedup_style  if speedup < 0.9 else
+                                                           speedup_style)
+                        except ArithmeticError as e:
+                            sheet.write(row, col, None, error_speedup_style)
+                    else:
+                        sheet.write(row, col, None, no_speedup_style)
+
+                    col += 1
+
+                row += 1
+                if row % 1000 == 0: sheet.flush_row_data()
+
+    wb.save(args.output)
+
+if __name__ == '__main__':
+    main()
diff --git a/modules/ts/src/precomp.cpp b/modules/ts/src/precomp.cpp
deleted file mode 100644 (file)
index c149df1..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "precomp.hpp"
index 10acd7a..a74417d 100644 (file)
@@ -1,4 +1,5 @@
 #include "opencv2/core/core_c.h"
+#include "opencv2/core/internal.hpp"
 #include "opencv2/ts/ts.hpp"
 
 #ifdef GTEST_LINKED_AS_SHARED_LIBRARY
index 1d636e6..38a2370 100644 (file)
@@ -2,6 +2,10 @@
 #include <float.h>
 #include <limits.h>
 
+#ifdef HAVE_TEGRA_OPTIMIZATION
+#include "tegra.hpp"
+#endif
+
 using namespace cv;
 
 namespace cvtest
@@ -2936,28 +2940,75 @@ MatComparator::operator()(const char* expr1, const char* expr2,
 
 void printVersionInfo(bool useStdOut)
 {
-    ::testing::Test::RecordProperty("CV_VERSION", CV_VERSION);
+    ::testing::Test::RecordProperty("cv_version", CV_VERSION);
     if(useStdOut) std::cout << "OpenCV version: " << CV_VERSION << std::endl;
 
     std::string buildInfo( cv::getBuildInformation() );
 
     size_t pos1 = buildInfo.find("Version control");
-    size_t pos2 = buildInfo.find("\n", pos1);\
+    size_t pos2 = buildInfo.find('\n', pos1);
     if(pos1 != std::string::npos && pos2 != std::string::npos)
     {
-        std::string ver( buildInfo.substr(pos1, pos2-pos1) );
-        ::testing::Test::RecordProperty("Version_control", ver);
-        if(useStdOut) std::cout << ver << std::endl;
+        size_t value_start = buildInfo.rfind(' ', pos2) + 1;
+        std::string ver( buildInfo.substr(value_start, pos2 - value_start) );
+        ::testing::Test::RecordProperty("cv_vcs_version", ver);
+        if (useStdOut) std::cout << "OpenCV VCS version: " << ver << std::endl;
     }
 
     pos1 = buildInfo.find("inner version");
-    pos2 = buildInfo.find("\n", pos1);\
+    pos2 = buildInfo.find('\n', pos1);
     if(pos1 != std::string::npos && pos2 != std::string::npos)
     {
-        std::string ver( buildInfo.substr(pos1, pos2-pos1) );
-        ::testing::Test::RecordProperty("inner_version", ver);
-        if(useStdOut) std::cout << ver << std::endl;
-    }
+        size_t value_start = buildInfo.rfind(' ', pos2) + 1;
+        std::string ver( buildInfo.substr(value_start, pos2 - value_start) );
+        ::testing::Test::RecordProperty("cv_inner_vcs_version", ver);
+        if(useStdOut) std::cout << "Inner VCS version: " << ver << std::endl;
+    }
+
+    const char* parallel_framework = currentParallelFramework();
+
+    if (parallel_framework) {
+        ::testing::Test::RecordProperty("cv_parallel_framework", parallel_framework);
+        if (useStdOut) std::cout << "Parallel framework: " << parallel_framework << std::endl;
+    }
+
+    std::string cpu_features;
+
+#if CV_SSE
+    if (checkHardwareSupport(CV_CPU_SSE)) cpu_features += " sse";
+#endif
+#if CV_SSE2
+    if (checkHardwareSupport(CV_CPU_SSE2)) cpu_features += " sse2";
+#endif
+#if CV_SSE3
+    if (checkHardwareSupport(CV_CPU_SSE3)) cpu_features += " sse3";
+#endif
+#if CV_SSSE3
+    if (checkHardwareSupport(CV_CPU_SSSE3)) cpu_features += " ssse3";
+#endif
+#if CV_SSE4_1
+    if (checkHardwareSupport(CV_CPU_SSE4_1)) cpu_features += " sse4.1";
+#endif
+#if CV_SSE4_2
+    if (checkHardwareSupport(CV_CPU_SSE4_2)) cpu_features += " sse4.2";
+#endif
+#if CV_AVX
+    if (checkHardwareSupport(CV_CPU_AVX)) cpu_features += " avx";
+#endif
+#if CV_NEON
+    cpu_features += " neon"; // NEON is currently not checked at runtime
+#endif
+
+    cpu_features.erase(0, 1); // erase initial space
+
+    ::testing::Test::RecordProperty("cv_cpu_features", cpu_features);
+    if (useStdOut) std::cout << "CPU features: " << cpu_features << std::endl;
+
+#ifdef HAVE_TEGRA_OPTIMIZATION
+    const char * tegra_optimization = tegra::isDeviceSupported() ? "enabled" : "disabled";
+    ::testing::Test::RecordProperty("cv_tegra_optimization", tegra_optimization);
+    if (useStdOut) std::cout << "Tegra optimization: " << tegra_optimization << std::endl;
+#endif
 }
 
 } //namespace cvtest
index 7c388cb..4887091 100644 (file)
@@ -497,6 +497,7 @@ const char kBreakOnFailureFlag[] = "break_on_failure";
 const char kCatchExceptionsFlag[] = "catch_exceptions";
 const char kColorFlag[] = "color";
 const char kFilterFlag[] = "filter";
+const char kParamFilterFlag[] = "param_filter";
 const char kListTestsFlag[] = "list_tests";
 const char kOutputFlag[] = "output";
 const char kPrintTimeFlag[] = "print_time";
@@ -575,6 +576,7 @@ class GTestFlagSaver {
     death_test_style_ = GTEST_FLAG(death_test_style);
     death_test_use_fork_ = GTEST_FLAG(death_test_use_fork);
     filter_ = GTEST_FLAG(filter);
+    param_filter_ = GTEST_FLAG(param_filter);
     internal_run_death_test_ = GTEST_FLAG(internal_run_death_test);
     list_tests_ = GTEST_FLAG(list_tests);
     output_ = GTEST_FLAG(output);
@@ -596,6 +598,7 @@ class GTestFlagSaver {
     GTEST_FLAG(death_test_style) = death_test_style_;
     GTEST_FLAG(death_test_use_fork) = death_test_use_fork_;
     GTEST_FLAG(filter) = filter_;
+    GTEST_FLAG(param_filter) = param_filter_;
     GTEST_FLAG(internal_run_death_test) = internal_run_death_test_;
     GTEST_FLAG(list_tests) = list_tests_;
     GTEST_FLAG(output) = output_;
@@ -617,6 +620,7 @@ class GTestFlagSaver {
   std::string death_test_style_;
   bool death_test_use_fork_;
   std::string filter_;
+  std::string param_filter_;
   std::string internal_run_death_test_;
   bool list_tests_;
   std::string output_;
@@ -1699,6 +1703,12 @@ GTEST_DEFINE_string_(
     "exclude).  A test is run if it matches one of the positive "
     "patterns and does not match any of the negative patterns.");
 
+GTEST_DEFINE_string_(
+    param_filter,
+    internal::StringFromGTestEnv("param_filter", kUniversalFilter),
+    "Same syntax and semantics as for param, but these patterns "
+    "have to match the test's parameters.");
+
 GTEST_DEFINE_bool_(list_tests, false,
                    "List all tests without running them.");
 
@@ -4188,6 +4198,14 @@ void PrettyUnitTestResultPrinter::OnTestIterationStart(
                   "Note: %s filter = %s\n", GTEST_NAME_, filter);
   }
 
+  const char* const param_filter = GTEST_FLAG(param_filter).c_str();
+
+  // Ditto.
+  if (!String::CStringEquals(param_filter, kUniversalFilter)) {
+    ColoredPrintf(COLOR_YELLOW,
+                  "Note: %s parameter filter = %s\n", GTEST_NAME_, param_filter);
+  }
+
   if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) {
     const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1);
     ColoredPrintf(COLOR_YELLOW,
@@ -5873,9 +5891,15 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
                                                    kDisableTestFilter);
       test_info->is_disabled_ = is_disabled;
 
+      const std::string value_param(test_info->value_param() == NULL ?
+                                    "" : test_info->value_param());
+
       const bool matches_filter =
           internal::UnitTestOptions::FilterMatchesTest(test_case_name,
-                                                       test_name);
+                                                       test_name) &&
+          internal::UnitTestOptions::MatchesFilter(value_param,
+                                                   GTEST_FLAG(param_filter).c_str());
+
       test_info->matches_filter_ = matches_filter;
 
       const bool is_runnable =
@@ -6223,6 +6247,12 @@ static const char kColorEncodedHelpMessage[] =
 "      Run only the tests whose name matches one of the positive patterns but\n"
 "      none of the negative patterns. '?' matches any single character; '*'\n"
 "      matches any substring; ':' separates two patterns.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "param_filter=@YPOSITIVE_PATTERNS"
+    "[@G-@YNEGATIVE_PATTERNS]@D\n"
+"      Like @G--" GTEST_FLAG_PREFIX_
+                      "filter@D, but applies to the test's parameter. If a\n"
+"      test is not parameterized, its parameter is considered to be the\n"
+"      empty string.\n"
 "  @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n"
 "      Run all disabled tests too.\n"
 "\n"
@@ -6300,6 +6330,7 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
         ParseBoolFlag(arg, kDeathTestUseFork,
                       &GTEST_FLAG(death_test_use_fork)) ||
         ParseStringFlag(arg, kFilterFlag, &GTEST_FLAG(filter)) ||
+        ParseStringFlag(arg, kParamFilterFlag, &GTEST_FLAG(param_filter)) ||
         ParseStringFlag(arg, kInternalRunDeathTestFlag,
                         &GTEST_FLAG(internal_run_death_test)) ||
         ParseBoolFlag(arg, kListTestsFlag, &GTEST_FLAG(list_tests)) ||
index c375e7c..d84db18 100644 (file)
@@ -14,30 +14,10 @@ int64 TestBase::timeLimitDefault = 0;
 unsigned int TestBase::iterationsLimitDefault = (unsigned int)(-1);
 int64 TestBase::_timeadjustment = 0;
 
-const std::string command_line_keys =
-    "{   |perf_max_outliers   |8        |percent of allowed outliers}"
-    "{   |perf_min_samples    |10       |minimal required numer of samples}"
-    "{   |perf_force_samples  |100      |force set maximum number of samples for all tests}"
-    "{   |perf_seed           |809564   |seed for random numbers generator}"
-    "{   |perf_threads        |-1       |the number of worker threads, if parallel execution is enabled}"
-    "{   |perf_write_sanity   |false    |create new records for sanity checks}"
-    "{   |perf_verify_sanity  |false    |fail tests having no regression data for sanity checks}"
-#ifdef ANDROID
-    "{   |perf_time_limit     |6.0      |default time limit for a single test (in seconds)}"
-    "{   |perf_affinity_mask  |0        |set affinity mask for the main thread}"
-    "{   |perf_log_power_checkpoints  | |additional xml logging for power measurement}"
-#else
-    "{   |perf_time_limit     |3.0      |default time limit for a single test (in seconds)}"
-#endif
-    "{   |perf_max_deviation  |1.0      |}"
-    "{h  |help                |false    |print help info}"
-#ifdef HAVE_CUDA
-    "{   |perf_run_cpu        |false    |run GPU performance tests for analogical CPU functions}"
-    "{   |perf_cuda_device    |0        |run GPU test suite onto specific CUDA capable device}"
-    "{   |perf_cuda_info_only |false    |print an information about system and an available CUDA devices and then exit.}"
-#endif
-;
+// Item [0] will be considered the default implementation.
+static std::vector<std::string> available_impls;
 
+static std::string  param_impl;
 static double       param_max_outliers;
 static double       param_max_deviation;
 static unsigned int param_min_samples;
@@ -48,7 +28,6 @@ static int          param_threads;
 static bool         param_write_sanity;
 static bool         param_verify_sanity;
 #ifdef HAVE_CUDA
-static bool         param_run_cpu;
 static int          param_cuda_device;
 #endif
 
@@ -72,10 +51,6 @@ static void setCurrentThreadAffinityMask(int mask)
 }
 #endif
 
-#ifdef HAVE_CUDA
-# include <opencv2/core/gpumat.hpp>
-#endif
-
 namespace {
 
 class PerfEnvironment: public ::testing::Environment
@@ -156,7 +131,7 @@ Regression& Regression::addKeypoints(TestBase* test, const std::string& name, co
 
 Regression& Regression::addMatches(TestBase* test, const std::string& name, const std::vector<cv::DMatch>& array, double eps, ERROR_TYPE err)
 {
-    int len = (int)array.size();      
+    int len = (int)array.size();
     cv::Mat queryIdx(len, 1, CV_32SC1, len ? (void*)&array[0].queryIdx : 0, sizeof(cv::DMatch));
     cv::Mat trainIdx(len, 1, CV_32SC1, len ? (void*)&array[0].trainIdx : 0, sizeof(cv::DMatch));
     cv::Mat imgIdx  (len, 1, CV_32SC1, len ? (void*)&array[0].imgIdx : 0,   sizeof(cv::DMatch));
@@ -577,12 +552,6 @@ Regression& Regression::operator() (const std::string& name, cv::InputArray arra
 
     std::string nodename = getCurrentTestNodeName();
 
-#ifdef HAVE_CUDA
-    static const std::string prefix = (param_run_cpu)? "CPU_" : "GPU_";
-    if(suiteName == "gpu")
-        nodename = prefix + nodename;
-#endif
-
     cv::FileNode n = rootIn[nodename];
     if(n.isNone())
     {
@@ -646,6 +615,43 @@ performance_metrics::performance_metrics()
 
 void TestBase::Init(int argc, const char* const argv[])
 {
+    std::vector<std::string> plain_only;
+    plain_only.push_back("plain");
+    TestBase::Init(plain_only, argc, argv);
+}
+
+void TestBase::Init(const std::vector<std::string> & availableImpls,
+                 int argc, const char* const argv[])
+{
+    available_impls = availableImpls;
+
+    const std::string command_line_keys =
+        "{   |perf_max_outliers           |8        |percent of allowed outliers}"
+        "{   |perf_min_samples            |10       |minimal required numer of samples}"
+        "{   |perf_force_samples          |100      |force set maximum number of samples for all tests}"
+        "{   |perf_seed                   |809564   |seed for random numbers generator}"
+        "{   |perf_threads                |-1       |the number of worker threads, if parallel execution is enabled}"
+        "{   |perf_write_sanity           |false    |create new records for sanity checks}"
+        "{   |perf_verify_sanity          |false    |fail tests having no regression data for sanity checks}"
+        "{   |perf_impl                   |" + available_impls[0] +
+                                                   "|the implementation variant of functions under test}"
+        "{   |perf_list_impls             |false    |list available implementation variants and exit}"
+        "{   |perf_run_cpu                |false    |deprecated, equivalent to --perf_impl=plain}"
+#ifdef ANDROID
+        "{   |perf_time_limit             |6.0      |default time limit for a single test (in seconds)}"
+        "{   |perf_affinity_mask          |0        |set affinity mask for the main thread}"
+        "{   |perf_log_power_checkpoints  |         |additional xml logging for power measurement}"
+#else
+        "{   |perf_time_limit             |3.0      |default time limit for a single test (in seconds)}"
+#endif
+        "{   |perf_max_deviation          |1.0      |}"
+        "{h  |help                        |false    |print help info}"
+#ifdef HAVE_CUDA
+        "{   |perf_cuda_device            |0        |run GPU test suite onto specific CUDA capable device}"
+        "{   |perf_cuda_info_only         |false    |print an information about system and an available CUDA devices and then exit.}"
+#endif
+    ;
+
     cv::CommandLineParser args(argc, argv, command_line_keys.c_str());
     if (args.get<bool>("help"))
     {
@@ -656,6 +662,7 @@ void TestBase::Init(int argc, const char* const argv[])
 
     ::testing::AddGlobalTestEnvironment(new PerfEnvironment);
 
+    param_impl          = args.get<bool>("perf_run_cpu") ? "plain" : args.get<std::string>("perf_impl");
     param_max_outliers  = std::min(100., std::max(0., args.get<double>("perf_max_outliers")));
     param_min_samples   = std::max(1u, args.get<unsigned int>("perf_min_samples"));
     param_max_deviation = std::max(0., args.get<double>("perf_max_deviation"));
@@ -670,19 +677,41 @@ void TestBase::Init(int argc, const char* const argv[])
     log_power_checkpoints = args.get<bool>("perf_log_power_checkpoints");
 #endif
 
+    bool param_list_impls = args.get<bool>("perf_list_impls");
+
+    if (param_list_impls)
+    {
+        fputs("Available implementation variants:", stdout);
+        for (size_t i = 0; i < available_impls.size(); ++i) {
+            putchar(' ');
+            fputs(available_impls[i].c_str(), stdout);
+        }
+        putchar('\n');
+        exit(0);
+    }
+
+    if (std::find(available_impls.begin(), available_impls.end(), param_impl) == available_impls.end())
+    {
+        printf("No such implementation: %s\n", param_impl.c_str());
+        exit(1);
+    }
+
 #ifdef HAVE_CUDA
 
     bool printOnly        = args.get<bool>("perf_cuda_info_only");
 
     if (printOnly)
         exit(0);
+#endif
+
+    if (available_impls.size() > 1)
+        printf("[----------]\n[   INFO   ] \tImplementation variant: %s.\n[----------]\n", param_impl.c_str()), fflush(stdout);
+
+#ifdef HAVE_CUDA
 
-    param_run_cpu         = args.get<bool>("perf_run_cpu");
     param_cuda_device      = std::max(0, std::min(cv::gpu::getCudaEnabledDeviceCount(), args.get<int>("perf_cuda_device")));
 
-    if (param_run_cpu)
-        printf("[----------]\n[ GPU INFO ] \tRun test suite on CPU.\n[----------]\n"), fflush(stdout);
-    else
+    if (param_impl == "cuda")
     {
         cv::gpu::DeviceInfo info(param_cuda_device);
         if (!info.isCompatible())
@@ -708,6 +737,18 @@ void TestBase::Init(int argc, const char* const argv[])
     _timeadjustment = _calibrate();
 }
 
+void TestBase::RecordRunParameters()
+{
+    ::testing::Test::RecordProperty("cv_implementation", param_impl);
+    ::testing::Test::RecordProperty("cv_num_threads", param_threads);
+}
+
+std::string TestBase::getSelectedImpl()
+{
+    return param_impl;
+}
+
+
 int64 TestBase::_calibrate()
 {
     class _helper : public ::perf::TestBase
@@ -1325,12 +1366,10 @@ void perf::sort(std::vector<cv::KeyPoint>& pts, cv::InputOutputArray descriptors
 /*****************************************************************************************\
 *                                  ::perf::GpuPerf
 \*****************************************************************************************/
-#ifdef HAVE_CUDA
 bool perf::GpuPerf::targetDevice()
 {
-    return !param_run_cpu;
+    return param_impl == "cuda";
 }
-#endif
 
 /*****************************************************************************************\
 *                                  ::perf::PrintTo
index 5653e21..8f9f41f 100644 (file)
@@ -42,6 +42,13 @@ Calculates an optical flow for a sparse feature set using the iterative Lucas-Ka
 
 The function implements a sparse iterative version of the Lucas-Kanade optical flow in pyramids. See [Bouguet00]_. The function is parallelized with the TBB library.
 
+.. note::
+
+   * An example using the Lucas-Kanade optical flow algorithm can be found at opencv_source_code/samples/cpp/lkdemo.cpp
+
+   * (Python) An example using the Lucas-Kanade optical flow algorithm can be found at opencv_source_code/samples/python2/lk_track.py
+   * (Python) An example using the Lucas-Kanade tracker for homography matching can be found at opencv_source_code/samples/python2/lk_homography.py
+
 buildOpticalFlowPyramid
 -----------------------
 Constructs the image pyramid which can be passed to :ocv:func:`calcOpticalFlowPyrLK`.
@@ -109,6 +116,11 @@ The function finds an optical flow for each ``prev`` pixel using the [Farneback2
 
     \texttt{prev} (y,x)  \sim \texttt{next} ( y + \texttt{flow} (y,x)[1],  x + \texttt{flow} (y,x)[0])
 
+.. note::
+
+   * An example using the optical flow algorithm described by Gunnar Farneback can be found at opencv_source_code/samples/cpp/fback.cpp
+
+   * (Python) An example using the optical flow algorithm described by Gunnar Farneback can be found at opencv_source_code/samples/python2/opt_flow.py
 
 estimateRigidTransform
 --------------------------
@@ -227,7 +239,9 @@ In fact,
 :ocv:func:`fastAtan2` and
 :ocv:func:`phase` are used so that the computed angle is measured in degrees and covers the full range 0..360. Also, the ``mask`` is filled to indicate pixels where the computed angle is valid.
 
+.. note::
 
+   * (Python) An example on how to perform a motion template technique can be found at opencv_source_code/samples/python2/motempl.py
 
 calcGlobalOrientation
 -------------------------
@@ -313,7 +327,9 @@ First, it finds an object center using
 
 See the OpenCV sample ``camshiftdemo.c`` that tracks colored objects.
 
+.. note::
 
+   * (Python) A sample explaining the camshift tracking algorithm can be found at opencv_source_code/samples/python2/camshift.py
 
 meanShift
 ---------
@@ -342,7 +358,9 @@ The function implements the iterative object search algorithm. It takes the inpu
 :ocv:func:`contourArea` ), and rendering the  remaining contours with
 :ocv:func:`drawContours` .
 
+.. note::
 
+   * A mean-shift tracking sample can be found at opencv_source_code/samples/cpp/camshiftdemo.cpp
 
 KalmanFilter
 ------------
@@ -353,7 +371,9 @@ KalmanFilter
 The class implements a standard Kalman filter
 http://en.wikipedia.org/wiki/Kalman_filter, [Welch95]_. However, you can modify ``transitionMatrix``, ``controlMatrix``, and ``measurementMatrix`` to get an extended Kalman filter functionality. See the OpenCV sample ``kalman.cpp`` .
 
+.. note::
 
+   * An example using the standard Kalman filter can be found at opencv_source_code/samples/cpp/kalman.cpp
 
 
 KalmanFilter::KalmanFilter
@@ -641,7 +661,9 @@ Calculate an optical flow using "SimpleFlow" algorithm.
 
 See [Tao2012]_. And site of project - http://graphics.berkeley.edu/papers/Tao-SAN-2012-05/.
 
+.. note::
 
+   * An example using the simpleFlow algorithm can be found at opencv_source_code/samples/cpp/simpleflow_demo.cpp
 
 createOptFlow_DualTVL1
 ----------------------
diff --git a/modules/video/perf/perf_precomp.cpp b/modules/video/perf/perf_precomp.cpp
deleted file mode 100644 (file)
index 8552ac3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "perf_precomp.hpp"
diff --git a/modules/video/src/precomp.cpp b/modules/video/src/precomp.cpp
deleted file mode 100644 (file)
index 3e0ec42..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*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 "precomp.hpp"
-
-/* End of file. */
index 58fc550..9b6077f 100644 (file)
@@ -43,9 +43,7 @@
 #ifndef __OPENCV_PRECOMP_H__
 #define __OPENCV_PRECOMP_H__
 
-#ifdef HAVE_CVCONFIG_H
 #include "cvconfig.h"
-#endif
 
 #include "opencv2/video/tracking.hpp"
 #include "opencv2/video/background_segm.hpp"
diff --git a/modules/video/test/test_precomp.cpp b/modules/video/test/test_precomp.cpp
deleted file mode 100644 (file)
index 5956e13..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "test_precomp.hpp"
diff --git a/modules/videostab/src/precomp.cpp b/modules/videostab/src/precomp.cpp
deleted file mode 100644 (file)
index 1113852..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*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"
index c1d8e30..f718d0e 100644 (file)
@@ -43,9 +43,7 @@
 #ifndef __OPENCV_PRECOMP_HPP__
 #define __OPENCV_PRECOMP_HPP__
 
-#ifdef HAVE_CVCONFIG_H
 #include "cvconfig.h"
-#endif
 
 #include <stdexcept>
 #include <iostream>
diff --git a/modules/world/src/precomp.cpp b/modules/world/src/precomp.cpp
deleted file mode 100644 (file)
index e69de29..0000000
index 2630957..4d88e8c 100644 (file)
@@ -43,9 +43,7 @@
 #ifndef __OPENCV_PRECOMP_H__
 #define __OPENCV_PRECOMP_H__
 
-#ifdef HAVE_CVCONFIG_H
 #include "cvconfig.h"
-#endif
 
 #include "opencv2/opencv_modules.hpp"
 #ifdef HAVE_OPENCV_VIDEO
index 71915c4..f8c30a8 100644 (file)
@@ -48,7 +48,7 @@ See the "15-puzzle" OpenCV sample for details.
         super.onResume();
 
         Log.i(TAG, "Trying to load OpenCV library");
-        if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_4, this, mOpenCVCallBack))
+        if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_6, this, mOpenCVCallBack))
         {
             Log.e(TAG, "Cannot connect to OpenCV Manager");
         }
index e90b016..9262a7c 100644 (file)
@@ -55,3 +55,7 @@ OpenCV version constants
 .. data:: OPENCV_VERSION_2_4_5
 
     OpenCV Library version 2.4.5
+
+.. data:: OPENCV_VERSION_2_4_6
+
+    OpenCV Library version 2.4.6
index 9549556..8eb0668 100644 (file)
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="org.opencv.engine"
-    android:versionCode="27@ANDROID_PLATFORM_VERSION_CODE@"
-    android:versionName="2.7" >
+    android:versionCode="29@ANDROID_PLATFORM_VERSION_CODE@"
+    android:versionName="2.9" >
 
     <uses-sdk android:minSdkVersion="@ANDROID_NATIVE_API_LEVEL@" />
     <uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
index 274e36a..b0b2b51 100644 (file)
@@ -15,7 +15,7 @@ using namespace android;
 
 const int OpenCVEngine::Platform = DetectKnownPlatforms();
 const int OpenCVEngine::CpuID = GetCpuID();
-const int OpenCVEngine::KnownVersions[] = {2040000, 2040100, 2040200, 2040300, 2040301, 2040302, 2040400, 2040500};
+const int OpenCVEngine::KnownVersions[] = {2040000, 2040100, 2040200, 2040300, 2040301, 2040302, 2040400, 2040500, 2040600};
 
 bool OpenCVEngine::ValidateVersion(int version)
 {
index f4e65eb..6255df5 100644 (file)
@@ -14,20 +14,20 @@ manually using adb tool:
 
 .. code-block:: sh
 
-    adb install OpenCV-2.4.5-android-sdk/apk/OpenCV_2.4.5_Manager_2.7_<platform>.apk
+    adb install OpenCV-2.4.6-android-sdk/apk/OpenCV_2.4.6_Manager_2.9_<platform>.apk
 
 Use the table below to determine proper OpenCV Manager package for your device:
 
 +------------------------------+--------------+---------------------------------------------------+
 | Hardware Platform            | Android ver. | Package name                                      |
 +==============================+==============+===================================================+
-| armeabi-v7a (ARMv7-A + NEON) |    >= 2.3    | OpenCV_2.4.5_Manager_2.7_armv7a-neon.apk          |
+| armeabi-v7a (ARMv7-A + NEON) |    >= 2.3    | OpenCV_2.4.6_Manager_2.9_armv7a-neon.apk          |
 +------------------------------+--------------+---------------------------------------------------+
-| armeabi-v7a (ARMv7-A + NEON) |     = 2.2    | OpenCV_2.4.5_Manager_2.7_armv7a-neon-android8.apk |
+| armeabi-v7a (ARMv7-A + NEON) |     = 2.2    | OpenCV_2.4.6_Manager_2.9_armv7a-neon-android8.apk |
 +------------------------------+--------------+---------------------------------------------------+
-| armeabi (ARMv5, ARMv6)       |    >= 2.3    | OpenCV_2.4.5_Manager_2.7_armeabi.apk              |
+| armeabi (ARMv5, ARMv6)       |    >= 2.3    | OpenCV_2.4.6_Manager_2.9_armeabi.apk              |
 +------------------------------+--------------+---------------------------------------------------+
-| Intel x86                    |    >= 2.3    | OpenCV_2.4.5_Manager_2.7_x86.apk                  |
+| Intel x86                    |    >= 2.3    | OpenCV_2.4.6_Manager_2.9_x86.apk                  |
 +------------------------------+--------------+---------------------------------------------------+
-| MIPS                         |    >= 2.3    | OpenCV_2.4.5_Manager_2.7_mips.apk                 |
+| MIPS                         |    >= 2.3    | OpenCV_2.4.6_Manager_2.9_mips.apk                 |
 +------------------------------+--------------+---------------------------------------------------+
similarity index 93%
rename from ios/Info.plist.in
rename to platforms/ios/Info.plist.in
index 89ef386..6bcfe86 100644 (file)
@@ -5,7 +5,7 @@
     <key>CFBundleName</key>
     <string>OpenCV</string>
     <key>CFBundleIdentifier</key>
-    <string>com.itseez.opencv</string>
+    <string>org.opencv</string>
     <key>CFBundleVersion</key>
     <string>${VERSION}</string>
     <key>CFBundleShortVersionString</key>
similarity index 95%
rename from ios/build_framework.py
rename to platforms/ios/build_framework.py
index ceef4b7..bc385bb 100755 (executable)
@@ -38,7 +38,7 @@ def build_opencv(srcroot, buildroot, target, arch):
     # for some reason, if you do not specify CMAKE_BUILD_TYPE, it puts libs to "RELEASE" rather than "Release"
     cmakeargs = ("-GXcode " +
                 "-DCMAKE_BUILD_TYPE=Release " +
-                "-DCMAKE_TOOLCHAIN_FILE=%s/ios/cmake/Toolchains/Toolchain-%s_Xcode.cmake " +
+                "-DCMAKE_TOOLCHAIN_FILE=%s/platforms/ios/cmake/Toolchains/Toolchain-%s_Xcode.cmake " +
                 "-DBUILD_opencv_world=ON " +
                 "-DCMAKE_INSTALL_PREFIX=install") % (srcroot, target)
     # if cmake cache exists, just rerun cmake to update OpenCV.xproj if necessary
@@ -92,16 +92,13 @@ def put_framework_together(srcroot, dstroot):
     os.system("lipo -create " + wlist + " -o " + dstdir + "/opencv2")
 
     # form Info.plist
-    srcfile = open(srcroot + "/ios/Info.plist.in", "rt")
+    srcfile = open(srcroot + "/platforms/ios/Info.plist.in", "rt")
     dstfile = open(dstdir + "/Resources/Info.plist", "wt")
     for l in srcfile.readlines():
         dstfile.write(l.replace("${VERSION}", opencv_version))
     srcfile.close()
     dstfile.close()
 
-    # copy cascades
-    # TODO ...
-
     # make symbolic links
     os.symlink("A", "Versions/Current")
     os.symlink("Versions/Current/Headers", "Headers")
@@ -125,4 +122,4 @@ if __name__ == "__main__":
         print "Usage:\n\t./build_framework.py <outputdir>\n\n"
         sys.exit(0)
 
-    build_framework(os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "..")), os.path.abspath(sys.argv[1]))
\ No newline at end of file
+    build_framework(os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "../..")), os.path.abspath(sys.argv[1]))
\ No newline at end of file
@@ -4,12 +4,12 @@ set (IPHONEOS TRUE)
 # Standard settings
 set (CMAKE_SYSTEM_NAME iOS)
 # Include extra modules for the iOS platform files
-set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/ios/cmake/Modules")
+set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/cmake/Modules")
 
-# Force the compilers to gcc for iOS
+# Force the compilers to clang for iOS
 include (CMakeForceCompiler)
-#CMAKE_FORCE_C_COMPILER (gcc gcc)
-#CMAKE_FORCE_CXX_COMPILER (g++ g++)
+#CMAKE_FORCE_C_COMPILER (clang GNU)
+#CMAKE_FORCE_CXX_COMPILER (clang++ GNU)
 
 set (CMAKE_C_SIZEOF_DATA_PTR 4)
 set (CMAKE_C_HAS_ISYSROOT 1)
@@ -4,12 +4,12 @@ set (IPHONESIMULATOR TRUE)
 # Standard settings
 set (CMAKE_SYSTEM_NAME iOS)
 # Include extra modules for the iOS platform files
-set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/ios/cmake/Modules")
+set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/cmake/Modules")
 
-# Force the compilers to gcc for iOS
+# Force the compilers to clang for iOS
 include (CMakeForceCompiler)
-#CMAKE_FORCE_C_COMPILER (gcc gcc)
-#CMAKE_FORCE_CXX_COMPILER (g++ g++)
+#CMAKE_FORCE_C_COMPILER (clang GNU)
+#CMAKE_FORCE_CXX_COMPILER (clang++ GNU)
 
 set (CMAKE_C_SIZEOF_DATA_PTR 4)
 set (CMAKE_C_HAS_ISYSROOT 1)
diff --git a/platforms/ios/readme.txt b/platforms/ios/readme.txt
new file mode 100644 (file)
index 0000000..8f1f206
--- /dev/null
@@ -0,0 +1,7 @@
+Building OpenCV from Source, using CMake and Command Line
+=========================================================
+
+cd ~/<my_working_directory>
+python opencv/platforms/ios/build_framework.py ios
+
+If everything's fine, a few minutes later you will get ~/<my_working_directory>/ios/opencv2.framework. You can add this framework to your Xcode projects.
\ No newline at end of file
index 7e1c455..dfe0461 100644 (file)
@@ -1 +1,3 @@
-This folder contains toolchains and additional files that are needed for cross compitation.
\ No newline at end of file
+This folder contains toolchains and additional files that are needed for cross compilation.
+For more information see introduction tutorials for target platform in documentation:
+http://docs.opencv.org/doc/tutorials/introduction/table_of_content_introduction/table_of_content_introduction.html#table-of-content-introduction
\ No newline at end of file
index fdabf00..d7cc372 100755 (executable)
@@ -6,7 +6,7 @@ import os
 
 
 architecture = 'armeabi'
-excludedHeaders = set(['hdf5.h', 'cap_ios.h', 'eigen.hpp', 'cxeigen.hpp']) #TOREMOVE
+excludedHeaders = set(['hdf5.h', 'cap_ios.h', 'ios.h', 'eigen.hpp', 'cxeigen.hpp']) #TOREMOVE
 systemIncludes = ['sources/cxx-stl/gnu-libstdc++/4.6/include', \
     '/opt/android-ndk-r8c/platforms/android-8/arch-arm', # TODO: check if this one could be passed as command line arg
     'sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/include']
index e72fddd..7392f91 100644 (file)
@@ -21,3 +21,7 @@ native_camera_r4.2.0; armeabi-v7a; 14; /home/alexander/Projects/AndroidSource/4.
 native_camera_r4.2.0; armeabi;     14; /home/alexander/Projects/AndroidSource/4.2
 native_camera_r4.2.0; x86;         14; /home/alexander/Projects/AndroidSource/4.2
 native_camera_r4.2.0; mips;        14; /home/alexander/Projects/AndroidSource/4.2
+native_camera_r4.3.0; armeabi;     14; /home/alexander/Projects/AndroidSource/4.3
+native_camera_r4.3.0; armeabi-v7a; 14; /home/alexander/Projects/AndroidSource/4.3
+native_camera_r4.3.0; x86;         14; /home/alexander/Projects/AndroidSource/4.3
+native_camera_r4.3.0; mips;        14; /home/alexander/Projects/AndroidSource/4.3
index aafed7d..df70e85 100644 (file)
@@ -1,6 +1,6 @@
-mkdir build
-cd build
+mkdir build_winrt_arm
+cd build_winrt_arm
 
 rem call "C:\Program Files\Microsoft Visual Studio 11.0\VC\bin\x86_arm\vcvarsx86_arm.bat"
 
-cmake.exe -GNinja -DCMAKE_BUILD_TYPE=Release -DWITH_FFMPEG=OFF -DBUILD_opencv_gpu=OFF -DBUILD_opencv_python=OFF -DCMAKE_TOOLCHAIN_FILE=..\..\winrt\arm.winrt.toolchain.cmake ..\..\..
+cmake.exe -GNinja -DWITH_TBB=ON -DBUILD_TBB=ON -DCMAKE_BUILD_TYPE=Release -DWITH_FFMPEG=OFF -DBUILD_opencv_gpu=OFF -DBUILD_opencv_python=OFF -DCMAKE_TOOLCHAIN_FILE=..\winrt\arm.winrt.toolchain.cmake ..\..
index c0b626d..0dc4a3c 100644 (file)
@@ -9,6 +9,7 @@ ocv_warnings_disable(CMAKE_CXX_FLAGS -Wmissing-declarations)
 add_subdirectory(15-puzzle)
 add_subdirectory(face-detection)
 add_subdirectory(image-manipulations)
+add_subdirectory(camera-calibration)
 add_subdirectory(color-blob-detection)
 add_subdirectory(tutorial-1-camerapreview)
 add_subdirectory(tutorial-2-mixedprocessing)
diff --git a/samples/android/camera-calibration/.classpath b/samples/android/camera-calibration/.classpath
new file mode 100644 (file)
index 0000000..46c3d46
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>\r
+       <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>\r
+       <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>\r
+       <classpathentry kind="src" path="src"/>\r
+       <classpathentry kind="src" path="gen"/>\r
+       <classpathentry kind="output" path="bin/classes"/>\r
+</classpath>\r
diff --git a/samples/android/camera-calibration/.project b/samples/android/camera-calibration/.project
new file mode 100644 (file)
index 0000000..eae413e
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>OpenCV Sample - camera-calibration</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>com.android.ide.eclipse.adt.ApkBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>com.android.ide.eclipse.adt.AndroidNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/samples/android/camera-calibration/.settings/org.eclipse.jdt.core.prefs b/samples/android/camera-calibration/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..48ab4c6
--- /dev/null
@@ -0,0 +1,4 @@
+eclipse.preferences.version=1\r
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6\r
+org.eclipse.jdt.core.compiler.compliance=1.6\r
+org.eclipse.jdt.core.compiler.source=1.6\r
diff --git a/samples/android/camera-calibration/AndroidManifest.xml b/samples/android/camera-calibration/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..5f2dad7
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="org.opencv.samples.cameracalibration"
+          android:versionCode="1"
+          android:versionName="1.0">
+
+    <application
+        android:label="@string/app_name"
+        android:icon="@drawable/icon"
+        android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
+
+        <activity android:name="CameraCalibrationActivity"
+                  android:label="@string/app_name"
+                  android:screenOrientation="landscape"
+                  android:configChanges="keyboardHidden|orientation">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+    
+    <supports-screens android:resizeable="true"
+                      android:smallScreens="true"
+                      android:normalScreens="true"
+                      android:largeScreens="true"
+                      android:anyDensity="true" />
+
+    <uses-sdk android:minSdkVersion="8" />
+
+    <uses-permission android:name="android.permission.CAMERA"/>
+
+    <uses-feature android:name="android.hardware.camera" android:required="false"/>
+    <uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
+    <uses-feature android:name="android.hardware.camera.front" android:required="false"/>
+    <uses-feature android:name="android.hardware.camera.front.autofocus" android:required="false"/>
+
+</manifest>
diff --git a/samples/android/camera-calibration/CMakeLists.txt b/samples/android/camera-calibration/CMakeLists.txt
new file mode 100644 (file)
index 0000000..83b11b3
--- /dev/null
@@ -0,0 +1,6 @@
+set(sample example-camera-calibration)
+
+add_android_project(${sample} "${CMAKE_CURRENT_SOURCE_DIR}" LIBRARY_DEPS ${OpenCV_BINARY_DIR} SDK_TARGET 11 ${ANDROID_SDK_TARGET})
+if(TARGET ${sample})
+  add_dependencies(opencv_android_examples ${sample})
+endif()
diff --git a/samples/android/camera-calibration/res/drawable/icon.png b/samples/android/camera-calibration/res/drawable/icon.png
new file mode 100644 (file)
index 0000000..79ad948
Binary files /dev/null and b/samples/android/camera-calibration/res/drawable/icon.png differ
diff --git a/samples/android/camera-calibration/res/layout/camera_calibration_surface_view.xml b/samples/android/camera-calibration/res/layout/camera_calibration_surface_view.xml
new file mode 100644 (file)
index 0000000..0feccde
--- /dev/null
@@ -0,0 +1,12 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
+    xmlns:tools="http://schemas.android.com/tools"\r
+    xmlns:opencv="http://schemas.android.com/apk/res-auto"\r
+    android:layout_width="match_parent"\r
+    android:layout_height="match_parent" >\r
+\r
+    <org.opencv.android.JavaCameraView\r
+        android:layout_width="fill_parent"\r
+        android:layout_height="fill_parent"\r
+        android:id="@+id/camera_calibration_java_surface_view" />\r
+\r
+</LinearLayout>\r
diff --git a/samples/android/camera-calibration/res/menu/calibration.xml b/samples/android/camera-calibration/res/menu/calibration.xml
new file mode 100644 (file)
index 0000000..9c90f12
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >\r
+    <group android:checkableBehavior="single">\r
+        <item android:id="@+id/calibrate"\r
+              android:title="@string/action_calibrate"\r
+              android:showAsAction="ifRoom|withText" />\r
+        <item android:id="@+id/preview_mode"\r
+              android:title="@string/preview_mode">\r
+              <menu>\r
+                  <group android:checkableBehavior="single">\r
+                      <item android:id="@+id/calibration"\r
+                            android:title="@string/calibration"\r
+                            android:checked="true" />\r
+                      <item android:id="@+id/undistortion"\r
+                            android:title="@string/undistortion" />\r
+                      <item android:id="@+id/comparison"\r
+                            android:title="@string/comparison" />\r
+                  </group>\r
+              </menu>\r
+        </item>\r
+    </group>\r
+</menu>\r
diff --git a/samples/android/camera-calibration/res/values/strings.xml b/samples/android/camera-calibration/res/values/strings.xml
new file mode 100644 (file)
index 0000000..e1ce932
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>\r
+\r
+    <string name="app_name">OCV Camera Calibration</string>\r
+    <string name="action_calibrate">Calibrate</string>
+    <string name="calibration">Calibration</string>
+    <string name="undistortion">Undistortion</string>
+    <string name="comparison">Comparison</string>
+    <string name="preview_mode">Preview mode</string>
+    <string name="calibration_successful">Successfully calibrated!\nAvg. re-projection error:</string>
+    <string name="calibration_unsuccessful">Unsuccessful calibration.\nTry again</string>
+    <string name="more_samples">Please, capture more samples</string>
+    <string name="calibrating">Calibrating...</string>
+    <string name="please_wait">Please, wait</string>
+    <string name="original">Original</string>
+    <string name="undistorted">Undistorted</string>\r
+\r
+</resources>\r
diff --git a/samples/android/camera-calibration/src/org/opencv/samples/cameracalibration/CalibrationResult.java b/samples/android/camera-calibration/src/org/opencv/samples/cameracalibration/CalibrationResult.java
new file mode 100644 (file)
index 0000000..4b03d59
--- /dev/null
@@ -0,0 +1,69 @@
+package org.opencv.samples.cameracalibration;
+
+import org.opencv.core.Mat;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.util.Log;
+
+public abstract class CalibrationResult {
+    private static final String TAG = "OCVSample::CalibrationResult";
+
+    private static final int CAMERA_MATRIX_ROWS = 3;
+    private static final int CAMERA_MATRIX_COLS = 3;
+    private static final int DISTORTION_COEFFICIENTS_SIZE = 5;
+
+    public static void save(Activity activity, Mat cameraMatrix, Mat distortionCoefficients) {
+        SharedPreferences sharedPref = activity.getPreferences(Context.MODE_PRIVATE);
+        SharedPreferences.Editor editor = sharedPref.edit();
+
+        double[] cameraMatrixArray = new double[CAMERA_MATRIX_ROWS * CAMERA_MATRIX_COLS];
+        cameraMatrix.get(0,  0, cameraMatrixArray);
+        for (int i = 0; i < CAMERA_MATRIX_ROWS; i++) {
+            for (int j = 0; j < CAMERA_MATRIX_COLS; j++) {
+                Integer id = i * CAMERA_MATRIX_ROWS + j;
+                editor.putFloat(id.toString(), (float)cameraMatrixArray[id]);
+            }
+        }
+
+        double[] distortionCoefficientsArray = new double[DISTORTION_COEFFICIENTS_SIZE];
+        distortionCoefficients.get(0, 0, distortionCoefficientsArray);
+        int shift = CAMERA_MATRIX_ROWS * CAMERA_MATRIX_COLS;
+        for (Integer i = shift; i < DISTORTION_COEFFICIENTS_SIZE + shift; i++) {
+            editor.putFloat(i.toString(), (float)distortionCoefficientsArray[i-shift]);
+        }
+
+        editor.commit();
+        Log.i(TAG, "Saved camera matrix: " + cameraMatrix.dump());
+        Log.i(TAG, "Saved distortion coefficients: " + distortionCoefficients.dump());
+    }
+
+    public static boolean tryLoad(Activity activity, Mat cameraMatrix, Mat distortionCoefficients) {
+        SharedPreferences sharedPref = activity.getPreferences(Context.MODE_PRIVATE);
+        if (sharedPref.getFloat("0", -1) == -1) {
+            Log.i(TAG, "No previous calibration results found");
+            return false;
+        }
+
+        double[] cameraMatrixArray = new double[CAMERA_MATRIX_ROWS * CAMERA_MATRIX_COLS];
+        for (int i = 0; i < CAMERA_MATRIX_ROWS; i++) {
+            for (int j = 0; j < CAMERA_MATRIX_COLS; j++) {
+                Integer id = i * CAMERA_MATRIX_ROWS + j;
+                cameraMatrixArray[id] = sharedPref.getFloat(id.toString(), -1);
+            }
+        }
+        cameraMatrix.put(0, 0, cameraMatrixArray);
+        Log.i(TAG, "Loaded camera matrix: " + cameraMatrix.dump());
+
+        double[] distortionCoefficientsArray = new double[DISTORTION_COEFFICIENTS_SIZE];
+        int shift = CAMERA_MATRIX_ROWS * CAMERA_MATRIX_COLS;
+        for (Integer i = shift; i < DISTORTION_COEFFICIENTS_SIZE + shift; i++) {
+            distortionCoefficientsArray[i - shift] = sharedPref.getFloat(i.toString(), -1);
+        }
+        distortionCoefficients.put(0, 0, distortionCoefficientsArray);
+        Log.i(TAG, "Loaded distortion coefficients: " + distortionCoefficients.dump());
+
+        return true;
+    }
+}
diff --git a/samples/android/camera-calibration/src/org/opencv/samples/cameracalibration/CameraCalibrationActivity.java b/samples/android/camera-calibration/src/org/opencv/samples/cameracalibration/CameraCalibrationActivity.java
new file mode 100644 (file)
index 0000000..33c9bbb
--- /dev/null
@@ -0,0 +1,216 @@
+// This sample is based on "Camera calibration With OpenCV" tutorial:
+// http://docs.opencv.org/doc/tutorials/calib3d/camera_calibration/camera_calibration.html
+//
+// It uses standard OpenCV asymmetric circles grid pattern 11x4:
+// https://github.com/Itseez/opencv/blob/2.4/doc/acircles_pattern.png.
+// The results are the camera matrix and 5 distortion coefficients.
+//
+// Tap on highlighted pattern to capture pattern corners for calibration.
+// Move pattern along the whole screen and capture data.
+//
+// When you've captured necessary amount of pattern corners (usually ~20 are enough),
+// press "Calibrate" button for performing camera calibration.
+
+package org.opencv.samples.cameracalibration;
+
+import org.opencv.android.BaseLoaderCallback;
+import org.opencv.android.CameraBridgeViewBase;
+import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
+import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
+import org.opencv.android.LoaderCallbackInterface;
+import org.opencv.android.OpenCVLoader;
+import org.opencv.core.Mat;
+
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.content.res.Resources;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.View.OnTouchListener;
+import android.view.WindowManager;
+import android.widget.Toast;
+
+public class CameraCalibrationActivity extends Activity implements CvCameraViewListener2, OnTouchListener {
+    private static final String TAG = "OCVSample::Activity";
+
+    private CameraBridgeViewBase mOpenCvCameraView;
+    private CameraCalibrator mCalibrator;
+    private OnCameraFrameRender mOnCameraFrameRender;
+    private int mWidth;
+    private int mHeight;
+
+    private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
+        @Override
+        public void onManagerConnected(int status) {
+            switch (status) {
+            case LoaderCallbackInterface.SUCCESS:
+            {
+                Log.i(TAG, "OpenCV loaded successfully");
+                mOpenCvCameraView.enableView();
+                mOpenCvCameraView.setOnTouchListener(CameraCalibrationActivity.this);
+            } break;
+            default:
+            {
+                super.onManagerConnected(status);
+            } break;
+            }
+        }
+    };
+
+    public CameraCalibrationActivity() {
+        Log.i(TAG, "Instantiated new " + this.getClass());
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        Log.i(TAG, "called onCreate");
+        super.onCreate(savedInstanceState);
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+
+        setContentView(R.layout.camera_calibration_surface_view);
+
+        mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.camera_calibration_java_surface_view);
+        mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
+        mOpenCvCameraView.setCvCameraViewListener(this);
+    }
+
+    @Override
+    public void onPause()
+    {
+        super.onPause();
+        if (mOpenCvCameraView != null)
+            mOpenCvCameraView.disableView();
+    }
+
+    @Override
+    public void onResume()
+    {
+        super.onResume();
+        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mLoaderCallback);
+    }
+
+    public void onDestroy() {
+        super.onDestroy();
+        if (mOpenCvCameraView != null)
+            mOpenCvCameraView.disableView();
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        getMenuInflater().inflate(R.menu.calibration, menu);
+
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu (Menu menu) {
+        super.onPrepareOptionsMenu(menu);
+        menu.findItem(R.id.preview_mode).setEnabled(true);
+        if (!mCalibrator.isCalibrated())
+            menu.findItem(R.id.preview_mode).setEnabled(false);
+
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+        case R.id.calibration:
+            mOnCameraFrameRender =
+                new OnCameraFrameRender(new CalibrationFrameRender(mCalibrator));
+            item.setChecked(true);
+            return true;
+        case R.id.undistortion:
+            mOnCameraFrameRender =
+                new OnCameraFrameRender(new UndistortionFrameRender(mCalibrator));
+            item.setChecked(true);
+            return true;
+        case R.id.comparison:
+            mOnCameraFrameRender =
+                new OnCameraFrameRender(new ComparisonFrameRender(mCalibrator, mWidth, mHeight, getResources()));
+            item.setChecked(true);
+            return true;
+        case R.id.calibrate:
+            final Resources res = getResources();
+            if (mCalibrator.getCornersBufferSize() < 2) {
+                (Toast.makeText(this, res.getString(R.string.more_samples), Toast.LENGTH_SHORT)).show();
+                return true;
+            }
+
+            mOnCameraFrameRender = new OnCameraFrameRender(new PreviewFrameRender());
+            new AsyncTask<Void, Void, Void>() {
+                private ProgressDialog calibrationProgress;
+
+                @Override
+                protected void onPreExecute() {
+                    calibrationProgress = new ProgressDialog(CameraCalibrationActivity.this);
+                    calibrationProgress.setTitle(res.getString(R.string.calibrating));
+                    calibrationProgress.setMessage(res.getString(R.string.please_wait));
+                    calibrationProgress.setCancelable(false);
+                    calibrationProgress.setIndeterminate(true);
+                    calibrationProgress.show();
+                }
+
+                @Override
+                protected Void doInBackground(Void... arg0) {
+                    mCalibrator.calibrate();
+                    return null;
+                }
+
+                @Override
+                protected void onPostExecute(Void result) {
+                    calibrationProgress.dismiss();
+                    mCalibrator.clearCorners();
+                    mOnCameraFrameRender = new OnCameraFrameRender(new CalibrationFrameRender(mCalibrator));
+                    String resultMessage = (mCalibrator.isCalibrated()) ?
+                            res.getString(R.string.calibration_successful)  + " " + mCalibrator.getAvgReprojectionError() :
+                            res.getString(R.string.calibration_unsuccessful);
+                    (Toast.makeText(CameraCalibrationActivity.this, resultMessage, Toast.LENGTH_SHORT)).show();
+
+                    if (mCalibrator.isCalibrated()) {
+                        CalibrationResult.save(CameraCalibrationActivity.this,
+                                mCalibrator.getCameraMatrix(), mCalibrator.getDistortionCoefficients());
+                    }
+                }
+            }.execute();
+            return true;
+        default:
+            return super.onOptionsItemSelected(item);
+        }
+    }
+
+    public void onCameraViewStarted(int width, int height) {
+        if (mWidth != width || mHeight != height) {
+            mWidth = width;
+            mHeight = height;
+            mCalibrator = new CameraCalibrator(mWidth, mHeight);
+            if (CalibrationResult.tryLoad(this, mCalibrator.getCameraMatrix(), mCalibrator.getDistortionCoefficients())) {
+                mCalibrator.setCalibrated();
+            }
+
+            mOnCameraFrameRender = new OnCameraFrameRender(new CalibrationFrameRender(mCalibrator));
+        }
+    }
+
+    public void onCameraViewStopped() {
+    }
+
+    public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
+        return mOnCameraFrameRender.render(inputFrame);
+    }
+
+    @Override
+    public boolean onTouch(View v, MotionEvent event) {
+        Log.d(TAG, "onTouch invoked");
+
+        mCalibrator.addCorners();
+        return false;
+    }
+}
diff --git a/samples/android/camera-calibration/src/org/opencv/samples/cameracalibration/CameraCalibrator.java b/samples/android/camera-calibration/src/org/opencv/samples/cameracalibration/CameraCalibrator.java
new file mode 100644 (file)
index 0000000..f0cd230
--- /dev/null
@@ -0,0 +1,169 @@
+package org.opencv.samples.cameracalibration;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opencv.calib3d.Calib3d;
+import org.opencv.core.Core;
+import org.opencv.core.CvType;
+import org.opencv.core.Mat;
+import org.opencv.core.MatOfDouble;
+import org.opencv.core.MatOfPoint2f;
+import org.opencv.core.MatOfPoint3f;
+import org.opencv.core.Point;
+import org.opencv.core.Scalar;
+import org.opencv.core.Size;
+
+import android.util.Log;
+
+public class CameraCalibrator {
+    private static final String TAG = "OCVSample::CameraCalibrator";
+
+    private final Size mPatternSize = new Size(4, 11);
+    private final int mCornersSize = (int)(mPatternSize.width * mPatternSize.height);
+    private boolean mPatternWasFound = false;
+    private MatOfPoint2f mCorners = new MatOfPoint2f();
+    private List<Mat> mCornersBuffer = new ArrayList<Mat>();
+    private boolean mIsCalibrated = false;
+
+    private Mat mCameraMatrix = new Mat();
+    private Mat mDistortionCoefficients = new Mat();
+    private int mFlags;
+    private double mRms;
+    private double mSquareSize = 0.0181;
+    private Size mImageSize;
+
+    public CameraCalibrator(int width, int height) {
+        mImageSize = new Size(width, height);
+        mFlags = Calib3d.CALIB_FIX_PRINCIPAL_POINT +
+                 Calib3d.CALIB_ZERO_TANGENT_DIST +
+                 Calib3d.CALIB_FIX_ASPECT_RATIO +
+                 Calib3d.CALIB_FIX_K4 +
+                 Calib3d.CALIB_FIX_K5;
+        Mat.eye(3, 3, CvType.CV_64FC1).copyTo(mCameraMatrix);
+        mCameraMatrix.put(0, 0, 1.0);
+        Mat.zeros(5, 1, CvType.CV_64FC1).copyTo(mDistortionCoefficients);
+        Log.i(TAG, "Instantiated new " + this.getClass());
+    }
+
+    public void processFrame(Mat grayFrame, Mat rgbaFrame) {
+        findPattern(grayFrame);
+        renderFrame(rgbaFrame);
+    }
+
+    public void calibrate() {
+        ArrayList<Mat> rvecs = new ArrayList<Mat>();
+        ArrayList<Mat> tvecs = new ArrayList<Mat>();
+        Mat reprojectionErrors = new Mat();
+        ArrayList<Mat> objectPoints = new ArrayList<Mat>();
+        objectPoints.add(Mat.zeros(mCornersSize, 1, CvType.CV_32FC3));
+        calcBoardCornerPositions(objectPoints.get(0));
+        for (int i = 1; i < mCornersBuffer.size(); i++) {
+            objectPoints.add(objectPoints.get(0));
+        }
+
+        Calib3d.calibrateCamera(objectPoints, mCornersBuffer, mImageSize,
+                mCameraMatrix, mDistortionCoefficients, rvecs, tvecs, mFlags);
+
+        mIsCalibrated = Core.checkRange(mCameraMatrix)
+                && Core.checkRange(mDistortionCoefficients);
+
+        mRms = computeReprojectionErrors(objectPoints, rvecs, tvecs, reprojectionErrors);
+        Log.i(TAG, String.format("Average re-projection error: %f", mRms));
+        Log.i(TAG, "Camera matrix: " + mCameraMatrix.dump());
+        Log.i(TAG, "Distortion coefficients: " + mDistortionCoefficients.dump());
+    }
+
+    public void clearCorners() {
+        mCornersBuffer.clear();
+    }
+
+    private void calcBoardCornerPositions(Mat corners) {
+        final int cn = 3;
+        float positions[] = new float[mCornersSize * cn];
+
+        for (int i = 0; i < mPatternSize.height; i++) {
+            for (int j = 0; j < mPatternSize.width * cn; j += cn) {
+                positions[(int) (i * mPatternSize.width * cn + j + 0)] =
+                        (2 * (j / cn) + i % 2) * (float) mSquareSize;
+                positions[(int) (i * mPatternSize.width * cn + j + 1)] =
+                        i * (float) mSquareSize;
+                positions[(int) (i * mPatternSize.width * cn + j + 2)] = 0;
+            }
+        }
+        corners.create(mCornersSize, 1, CvType.CV_32FC3);
+        corners.put(0, 0, positions);
+    }
+
+    private double computeReprojectionErrors(List<Mat> objectPoints,
+            List<Mat> rvecs, List<Mat> tvecs, Mat perViewErrors) {
+        MatOfPoint2f cornersProjected = new MatOfPoint2f();
+        double totalError = 0;
+        double error;
+        float viewErrors[] = new float[objectPoints.size()];
+
+        MatOfDouble distortionCoefficients = new MatOfDouble(mDistortionCoefficients);
+        int totalPoints = 0;
+        for (int i = 0; i < objectPoints.size(); i++) {
+            MatOfPoint3f points = new MatOfPoint3f(objectPoints.get(i));
+            Calib3d.projectPoints(points, rvecs.get(i), tvecs.get(i),
+                    mCameraMatrix, distortionCoefficients, cornersProjected);
+            error = Core.norm(mCornersBuffer.get(i), cornersProjected, Core.NORM_L2);
+
+            int n = objectPoints.get(i).rows();
+            viewErrors[i] = (float) Math.sqrt(error * error / n);
+            totalError  += error * error;
+            totalPoints += n;
+        }
+        perViewErrors.create(objectPoints.size(), 1, CvType.CV_32FC1);
+        perViewErrors.put(0, 0, viewErrors);
+
+        return Math.sqrt(totalError / totalPoints);
+    }
+
+    private void findPattern(Mat grayFrame) {
+        mPatternWasFound = Calib3d.findCirclesGridDefault(grayFrame, mPatternSize,
+                mCorners, Calib3d.CALIB_CB_ASYMMETRIC_GRID);
+    }
+
+    public void addCorners() {
+        if (mPatternWasFound) {
+            mCornersBuffer.add(mCorners.clone());
+        }
+    }
+
+    private void drawPoints(Mat rgbaFrame) {
+        Calib3d.drawChessboardCorners(rgbaFrame, mPatternSize, mCorners, mPatternWasFound);
+    }
+
+    private void renderFrame(Mat rgbaFrame) {
+        drawPoints(rgbaFrame);
+
+        Core.putText(rgbaFrame, "Captured: " + mCornersBuffer.size(), new Point(rgbaFrame.cols() / 3 * 2, rgbaFrame.rows() * 0.1),
+                Core.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(255, 255, 0));
+    }
+
+    public Mat getCameraMatrix() {
+        return mCameraMatrix;
+    }
+
+    public Mat getDistortionCoefficients() {
+        return mDistortionCoefficients;
+    }
+
+    public int getCornersBufferSize() {
+        return mCornersBuffer.size();
+    }
+
+    public double getAvgReprojectionError() {
+        return mRms;
+    }
+
+    public boolean isCalibrated() {
+        return mIsCalibrated;
+    }
+
+    public void setCalibrated() {
+        mIsCalibrated = true;
+    }
+}
diff --git a/samples/android/camera-calibration/src/org/opencv/samples/cameracalibration/OnCameraFrameRender.java b/samples/android/camera-calibration/src/org/opencv/samples/cameracalibration/OnCameraFrameRender.java
new file mode 100644 (file)
index 0000000..3f155c2
--- /dev/null
@@ -0,0 +1,102 @@
+package org.opencv.samples.cameracalibration;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
+import org.opencv.core.Core;
+import org.opencv.core.Mat;
+import org.opencv.core.MatOfPoint;
+import org.opencv.core.Point;
+import org.opencv.core.Range;
+import org.opencv.core.Scalar;
+import org.opencv.imgproc.Imgproc;
+
+import android.content.res.Resources;
+
+abstract class FrameRender {
+    protected CameraCalibrator mCalibrator;
+
+    public abstract Mat render(CvCameraViewFrame inputFrame);
+}
+
+class PreviewFrameRender extends FrameRender {
+    @Override
+    public Mat render(CvCameraViewFrame inputFrame) {
+        return inputFrame.rgba();
+    }
+}
+
+class CalibrationFrameRender extends FrameRender {
+    public CalibrationFrameRender(CameraCalibrator calibrator) {
+        mCalibrator = calibrator;
+    }
+
+    @Override
+    public Mat render(CvCameraViewFrame inputFrame) {
+        Mat rgbaFrame = inputFrame.rgba();
+        Mat grayFrame = inputFrame.gray();
+        mCalibrator.processFrame(grayFrame, rgbaFrame);
+
+        return rgbaFrame;
+    }
+}
+
+class UndistortionFrameRender extends FrameRender {
+    public UndistortionFrameRender(CameraCalibrator calibrator) {
+        mCalibrator = calibrator;
+    }
+
+    @Override
+    public Mat render(CvCameraViewFrame inputFrame) {
+        Mat renderedFrame = new Mat(inputFrame.rgba().size(), inputFrame.rgba().type());
+        Imgproc.undistort(inputFrame.rgba(), renderedFrame,
+                mCalibrator.getCameraMatrix(), mCalibrator.getDistortionCoefficients());
+
+        return renderedFrame;
+    }
+}
+
+class ComparisonFrameRender extends FrameRender {
+    private int mWidth;
+    private int mHeight;
+    private Resources mResources;
+    public ComparisonFrameRender(CameraCalibrator calibrator, int width, int height, Resources resources) {
+        mCalibrator = calibrator;
+        mWidth = width;
+        mHeight = height;
+        mResources = resources;
+    }
+
+    @Override
+    public Mat render(CvCameraViewFrame inputFrame) {
+        Mat undistortedFrame = new Mat(inputFrame.rgba().size(), inputFrame.rgba().type());
+        Imgproc.undistort(inputFrame.rgba(), undistortedFrame,
+                mCalibrator.getCameraMatrix(), mCalibrator.getDistortionCoefficients());
+
+        Mat comparisonFrame = inputFrame.rgba();
+        undistortedFrame.colRange(new Range(0, mWidth / 2)).copyTo(comparisonFrame.colRange(new Range(mWidth / 2, mWidth)));
+        List<MatOfPoint> border = new ArrayList<MatOfPoint>();
+        final int shift = (int)(mWidth * 0.005);
+        border.add(new MatOfPoint(new Point(mWidth / 2 - shift, 0), new Point(mWidth / 2 + shift, 0),
+                new Point(mWidth / 2 + shift, mHeight), new Point(mWidth / 2 - shift, mHeight)));
+        Core.fillPoly(comparisonFrame, border, new Scalar(255, 255, 255));
+
+        Core.putText(comparisonFrame, mResources.getString(R.string.original), new Point(mWidth * 0.1, mHeight * 0.1),
+                Core.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(255, 255, 0));
+        Core.putText(comparisonFrame, mResources.getString(R.string.undistorted), new Point(mWidth * 0.6, mHeight * 0.1),
+                Core.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(255, 255, 0));
+
+        return comparisonFrame;
+    }
+}
+
+class OnCameraFrameRender {
+    private FrameRender mFrameRender;
+    public OnCameraFrameRender(FrameRender frameRender) {
+        mFrameRender = frameRender;
+    }
+    public Mat render(CvCameraViewFrame inputFrame) {
+        return mFrameRender.render(inputFrame);
+    }
+}
index 44aadfe..83ca04b 100644 (file)
@@ -20,7 +20,7 @@
                                        <folderInfo id="0.882924228." name="/" resourcePath="">
                                                <toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.1667980868" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
                                                        <targetPlatform id="org.eclipse.cdt.build.core.prefbase.toolchain.1667980868.2108168132" name=""/>
-                                                       <builder autoBuildTarget="" command="&quot;${NDKROOT}/ndk-build.cmd&quot;" enableAutoBuild="true" enableCleanBuild="false" id="org.eclipse.cdt.build.core.settings.default.builder.328915772" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
+                                                       <builder autoBuildTarget="" command="${NDKROOT}/ndk-build.cmd" enableAutoBuild="true" enableCleanBuild="false" id="org.eclipse.cdt.build.core.settings.default.builder.328915772" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
                                                        <tool id="org.eclipse.cdt.build.core.settings.holder.libs.630148311" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
                                                        <tool id="org.eclipse.cdt.build.core.settings.holder.525090327" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
                                                                <inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1491216279" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
index 369bc75..55b696b 100644 (file)
@@ -10,6 +10,7 @@
 
         <activity android:name="CvNativeActivity"
                   android:label="@string/app_name"
+                  android:screenOrientation="landscape"
                   android:configChanges="orientation|keyboardHidden">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -17,7 +18,9 @@
                 </intent-filter>
             </activity>
         <activity android:name="android.app.NativeActivity"
-                  android:label="@string/app_name">
+                  android:label="@string/app_name"
+                  android:screenOrientation="landscape"
+                  android:configChanges="keyboardHidden|orientation">
             <meta-data android:name="android.app.lib_name"
                     android:value="native_activity" />
         </activity>
index fd4fd2b..7ae31e2 100644 (file)
@@ -7,7 +7,7 @@ include ../../sdk/native/jni/OpenCV.mk
 LOCAL_MODULE    := native_activity
 LOCAL_SRC_FILES := native.cpp
 LOCAL_LDLIBS    += -lm -llog -landroid
-LOCAL_STATIC_LIBRARIES := android_native_app_glue
+LOCAL_STATIC_LIBRARIES += android_native_app_glue
 
 include $(BUILD_SHARED_LIBRARY)
 
index 5cfb3a9..0054da9 100644 (file)
@@ -78,18 +78,29 @@ static void engine_draw_frame(Engine* engine, const cv::Mat& frame)
         return;
     }
 
-    void* pixels = buffer.bits;
+    int32_t* pixels = (int32_t*)buffer.bits;
 
     int left_indent = (buffer.width-frame.cols)/2;
     int top_indent = (buffer.height-frame.rows)/2;
 
-    for (int yy = top_indent; yy < std::min(frame.rows+top_indent, buffer.height); yy++)
+    if (top_indent > 0)
     {
-        unsigned char* line = (unsigned char*)pixels + left_indent*4*sizeof(unsigned char);
-        size_t line_size = std::min(frame.cols, buffer.width)*4*sizeof(unsigned char);
+        memset(pixels, 0, top_indent*buffer.stride*sizeof(int32_t));
+        pixels += top_indent*buffer.stride;
+    }
+
+    for (int yy = 0; yy < frame.rows; yy++)
+    {
+        if (left_indent > 0)
+        {
+            memset(pixels, 0, left_indent*sizeof(int32_t));
+            memset(pixels+left_indent+frame.cols, 0, (buffer.stride-frame.cols-left_indent)*sizeof(int32_t));
+        }
+        int32_t* line = pixels + left_indent;
+        size_t line_size = frame.cols*4*sizeof(unsigned char);
         memcpy(line, frame.ptr<unsigned char>(yy), line_size);
         // go to next line
-        pixels = (int32_t*)pixels + buffer.stride;
+        pixels += buffer.stride;
     }
     ANativeWindow_unlockAndPost(engine->app->window);
 }
index 5112eae..fd4eea4 100644 (file)
@@ -56,7 +56,7 @@ static void help( char** argv )
 }
 
 int main( int argc, char** argv ) {
-    // check http://opencv.itseez.com/doc/tutorials/features2d/table_of_content_features2d/table_of_content_features2d.html
+    // check http://docs.opencv.org/doc/tutorials/features2d/table_of_content_features2d/table_of_content_features2d.html
     // for OpenCV general detection/matching framework details
 
     if( argc != 3 ) {
index d210512..619c54b 100644 (file)
@@ -3,7 +3,7 @@
 #include "opencv2/highgui/highgui.hpp"
 #include "opencv2/contrib/contrib.hpp"
 
-#ifdef WIN32
+#if defined(WIN32) || defined(_WIN32)
 #include <io.h>
 #else
 #include <dirent.h>
@@ -67,7 +67,7 @@ static void readDirectory( const string& directoryName, vector<string>& filename
 {
     filenames.clear();
 
-#ifdef WIN32
+#if defined(WIN32) | defined(_WIN32)
     struct _finddata_t s_file;
     string str = directoryName + "\\*.*";
 
index 07621ce..2c65fb0 100644 (file)
      Or: http://oreilly.com/catalog/9780596516130/
      ISBN-10: 0596516134 or: ISBN-13: 978-0596516130
 
-   OTHER OPENCV SITES:
-   * The source code is on sourceforge at:
-     http://sourceforge.net/projects/opencvlibrary/
-   * The OpenCV wiki page (As of Oct 1, 2008 this is down for changing over servers, but should come back):
-     http://opencvlibrary.sourceforge.net/
-   * An active user group is at:
-     http://tech.groups.yahoo.com/group/OpenCV/
-   * The minutes of weekly OpenCV development meetings are at:
-     http://code.opencv.org/projects/opencv/wiki/Meeting_notes
+   OPENCV WEBSITES:
+     Homepage:      http://opencv.org
+     Online docs:   http://docs.opencv.org
+     Q&A forum:     http://answers.opencv.org
+     Issue tracker: http://code.opencv.org
+     GitHub:        https://github.com/Itseez/opencv/
    ************************************************** */
 
 #include "opencv2/calib3d/calib3d.hpp"
index cdcf2f3..a201d83 100644 (file)
@@ -27,7 +27,7 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND)
     target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${OPENCV_OCL_SAMPLES_REQUIRED_DEPS})
 
     set_target_properties(${the_target} PROPERTIES
-      OUTPUT_NAME "${name}_${project}"
+      OUTPUT_NAME "${project}-example-${name}"
       PROJECT_LABEL "(EXAMPLE_${project_upper}) ${name}")
 
     if(ENABLE_SOLUTION_FOLDERS)
diff --git a/samples/ocl/clahe.cpp b/samples/ocl/clahe.cpp
new file mode 100644 (file)
index 0000000..72fc2fb
--- /dev/null
@@ -0,0 +1,108 @@
+#include <iostream>
+#include "opencv2/core/core.hpp"
+#include "opencv2/imgproc/imgproc.hpp"
+#include "opencv2/highgui/highgui.hpp"
+#include "opencv2/ocl/ocl.hpp"
+using namespace cv;
+using namespace std;
+
+Ptr<CLAHE> pFilter;
+int tilesize;
+int cliplimit;
+string outfile;
+
+static void TSize_Callback(int pos)
+{
+    if(pos==0)
+    {
+        pFilter->setTilesGridSize(Size(1,1));
+    }
+    pFilter->setTilesGridSize(Size(tilesize,tilesize));
+}
+
+static void Clip_Callback(int)
+{
+    pFilter->setClipLimit(cliplimit);
+}
+
+int main(int argc, char** argv)
+{
+    const char* keys =
+        "{ i | input   |                    | specify input image }"
+        "{ c | camera  |    0               | specify camera id   }"
+        "{ s | use_cpu |    false           | use cpu algorithm   }"
+        "{ o | output  | clahe_output.jpg   | specify output save path}";
+
+    CommandLineParser cmd(argc, argv, keys);
+    string infile = cmd.get<string>("i");
+    outfile = cmd.get<string>("o");
+    int camid = cmd.get<int>("c");
+    bool use_cpu = cmd.get<bool>("s");
+    CvCapture* capture = 0;
+    bool running = true;
+
+    namedWindow("CLAHE");
+    createTrackbar("Tile Size", "CLAHE", &tilesize, 32, (TrackbarCallback)TSize_Callback);
+    createTrackbar("Clip Limit", "CLAHE", &cliplimit, 20, (TrackbarCallback)Clip_Callback);
+    Mat frame, outframe;
+    ocl::oclMat d_outframe;
+    
+    int cur_clip;
+    Size cur_tilesize;
+    if(use_cpu)
+    {
+        pFilter = createCLAHE();
+    }
+    else
+    {
+        pFilter = ocl::createCLAHE();
+    }
+    cur_clip = (int)pFilter->getClipLimit();
+    cur_tilesize = pFilter->getTilesGridSize();
+    setTrackbarPos("Tile Size", "CLAHE", cur_tilesize.width);
+    setTrackbarPos("Clip Limit", "CLAHE", cur_clip);
+    if(infile != "")
+    {
+        frame = imread(infile);
+        if(frame.empty())
+        {
+            cout << "error read image: " << infile << endl;
+            return -1;
+        }
+    }
+    else
+    {
+        capture = cvCaptureFromCAM(camid);
+    }
+    cout << "\nControls:\n"
+         << "\to - save output image\n"
+         << "\tESC - exit\n";
+    while(running)
+    {
+        if(capture)
+            frame = cvQueryFrame(capture);
+        else
+            frame = imread(infile);
+        if(frame.empty())
+        {
+            continue;
+        }
+        if(use_cpu)
+        {
+            cvtColor(frame, frame, COLOR_BGR2GRAY);
+            pFilter->apply(frame, outframe);
+        }
+        else
+        {
+            ocl::oclMat d_frame(frame);
+            ocl::cvtColor(d_frame, d_outframe, COLOR_BGR2GRAY);
+            pFilter->apply(d_outframe, d_outframe);
+            d_outframe.download(outframe);
+        }
+        imshow("CLAHE", outframe);
+        char key = (char)cvWaitKey(3);
+        if(key == 'o') imwrite(outfile, outframe);
+        else if(key == 27) running = false;
+    }
+    return 0;
+}
index 684c2d9..49148bd 100644 (file)
@@ -7,55 +7,67 @@
 
 using namespace std;
 using namespace cv;
-#define LOOP_NUM 10 
+#define LOOP_NUM 10
 
 const static Scalar colors[] =  { CV_RGB(0,0,255),
-        CV_RGB(0,128,255),
-        CV_RGB(0,255,255),
-        CV_RGB(0,255,0),
-        CV_RGB(255,128,0),
-        CV_RGB(255,255,0),
-        CV_RGB(255,0,0),
-        CV_RGB(255,0,255)} ;
+                                  CV_RGB(0,128,255),
+                                  CV_RGB(0,255,255),
+                                  CV_RGB(0,255,0),
+                                  CV_RGB(255,128,0),
+                                  CV_RGB(255,255,0),
+                                  CV_RGB(255,0,0),
+                                  CV_RGB(255,0,255)
+                                } ;
+
 
 int64 work_begin = 0;
 int64 work_end = 0;
+string outputName;
 
-static void workBegin() 
-{ 
+static void workBegin()
+{
     work_begin = getTickCount();
 }
 static void workEnd()
 {
     work_end += (getTickCount() - work_begin);
 }
-static double getTime(){
+static double getTime()
+{
     return work_end /((double)cvGetTickFrequency() * 1000.);
 }
 
-void detect( Mat& img, vector<Rect>& faces, 
-    cv::ocl::OclCascadeClassifierBuf& cascade, 
-    double scale, bool calTime);
 
-void detectCPU( Mat& img, vector<Rect>& faces, 
-    CascadeClassifier& cascade, 
-    double scale, bool calTime);
+void detect( Mat& img, vector<Rect>& faces,
+             ocl::OclCascadeClassifierBuf& cascade,
+             double scale, bool calTime);
+
+
+void detectCPU( Mat& img, vector<Rect>& faces,
+                CascadeClassifier& cascade,
+                double scale, bool calTime);
+
 
 void Draw(Mat& img, vector<Rect>& faces, double scale);
 
+
 // This function test if gpu_rst matches cpu_rst.
 // If the two vectors are not equal, it will return the difference in vector size
 // Else if will return (total diff of each cpu and gpu rects covered pixels)/(total cpu rects covered pixels)
-double checkRectSimilarity(Size sz, std::vector<Rect>& cpu_rst, std::vector<Rect>& gpu_rst);
+double checkRectSimilarity(Size sz, vector<Rect>& cpu_rst, vector<Rect>& gpu_rst);
+
 
 int main( int argc, const char** argv )
 {
     const char* keys =
         "{ h | help       | false       | print help message }"
         "{ i | input      |             | specify input image }"
-        "{ t | template   | ../../../data/haarcascades/haarcascade_frontalface_alt.xml  | specify template file }"
+        "{ t | template   | haarcascade_frontalface_alt.xml |"
+        " specify template file path }"
         "{ c | scale      |   1.0       | scale image }"
-        "{ s | use_cpu    | false       | use cpu or gpu to process the image }";
+        "{ s | use_cpu    | false       | use cpu or gpu to process the image }"
+        "{ o | output     | facedetect_output.jpg  |"
+        " specify output image save path(only works when input is images) }";
 
     CommandLineParser cmd(argc, argv, keys);
     if (cmd.get<bool>("help"))
@@ -69,9 +81,10 @@ int main( int argc, const char** argv )
 
     bool useCPU = cmd.get<bool>("s");
     string inputName = cmd.get<string>("i");
+    outputName = cmd.get<string>("o");
     string cascadeName = cmd.get<string>("t");
     double scale = cmd.get<double>("c");
-    cv::ocl::OclCascadeClassifierBuf cascade;
+    ocl::OclCascadeClassifierBuf cascade;
     CascadeClassifier  cpu_cascade;
 
     if( !cascade.load( cascadeName ) || !cpu_cascade.load(cascadeName) )
@@ -83,7 +96,7 @@ int main( int argc, const char** argv )
     if( inputName.empty() )
     {
         capture = cvCaptureFromCAM(0);
-        if(!capture) 
+        if(!capture)
             cout << "Capture from CAM 0 didn't work" << endl;
     }
     else if( inputName.size() )
@@ -92,7 +105,7 @@ int main( int argc, const char** argv )
         if( image.empty() )
         {
             capture = cvCaptureFromAVI( inputName.c_str() );
-            if(!capture) 
+            if(!capture)
                 cout << "Capture from AVI didn't work" << endl;
             return -1;
         }
@@ -100,14 +113,15 @@ int main( int argc, const char** argv )
     else
     {
         image = imread( "lena.jpg", 1 );
-        if(image.empty()) 
+        if(image.empty())
             cout << "Couldn't read lena.jpg" << endl;
         return -1;
     }
 
+
     cvNamedWindow( "result", 1 );
-    std::vector<cv::ocl::Info> oclinfo;
-    int devnums = cv::ocl::getDevice(oclinfo);
+    vector<ocl::Info> oclinfo;
+    int devnums = ocl::getDevice(oclinfo);
     if( devnums < 1 )
     {
         std::cout << "no device found\n";
@@ -130,19 +144,23 @@ int main( int argc, const char** argv )
                 frame.copyTo( frameCopy );
             else
                 flip( frame, frameCopy, 0 );
-            if(useCPU){
+            if(useCPU)
+            {
                 detectCPU(frameCopy, faces, cpu_cascade, scale, false);
             }
-            else{
-                detect(frameCopy, faces, cascade, scale, false);     
+            else
+            {
+                detect(frameCopy, faces, cascade, scale, false);
             }
             Draw(frameCopy, faces, scale);
             if( waitKey( 10 ) >= 0 )
                 goto _cleanup_;
         }
 
+
         waitKey(0);
 
+
 _cleanup_:
         cvReleaseCapture( &capture );
     }
@@ -152,18 +170,21 @@ _cleanup_:
         vector<Rect> faces;
         vector<Rect> ref_rst;
         double accuracy = 0.;
-        for(int i = 0; i <= LOOP_NUM;i ++) 
+        for(int i = 0; i <= LOOP_NUM; i ++)
         {
             cout << "loop" << i << endl;
-            if(useCPU){
-                detectCPU(image, faces, cpu_cascade, scale, i==0?false:true);  
+            if(useCPU)
+            {
+                detectCPU(image, faces, cpu_cascade, scale, i==0?false:true);
             }
-            else{
+            else
+            {
                 detect(image, faces, cascade, scale, i==0?false:true);
-                if(i == 0){
+                if(i == 0)
+                {
                     detectCPU(image, ref_rst, cpu_cascade, scale, false);
                     accuracy = checkRectSimilarity(image.size(), ref_rst, faces);
-                }                    
+                }
             }
             if (i == LOOP_NUM)
             {
@@ -180,31 +201,31 @@ _cleanup_:
     }
 
     cvDestroyWindow("result");
-
     return 0;
 }
 
-void detect( Mat& img, vector<Rect>& faces, 
-    cv::ocl::OclCascadeClassifierBuf& cascade, 
-    double scale, bool calTime)
+void detect( Mat& img, vector<Rect>& faces,
+             ocl::OclCascadeClassifierBuf& cascade,
+             double scale, bool calTime)
 {
-    cv::ocl::oclMat image(img);
-    cv::ocl::oclMat gray, smallImg( cvRound (img.rows/scale), cvRound(img.cols/scale), CV_8UC1 );
+    ocl::oclMat image(img);
+    ocl::oclMat gray, smallImg( cvRound (img.rows/scale), cvRound(img.cols/scale), CV_8UC1 );
     if(calTime) workBegin();
-    cv::ocl::cvtColor( image, gray, CV_BGR2GRAY );
-    cv::ocl::resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR );
-    cv::ocl::equalizeHist( smallImg, smallImg );
+    ocl::cvtColor( image, gray, CV_BGR2GRAY );
+    ocl::resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR );
+    ocl::equalizeHist( smallImg, smallImg );
 
     cascade.detectMultiScale( smallImg, faces, 1.1,
-        3, 0
-        |CV_HAAR_SCALE_IMAGE
-        , Size(30,30), Size(0, 0) );
+                              3, 0
+                              |CV_HAAR_SCALE_IMAGE
+                              , Size(30,30), Size(0, 0) );
     if(calTime) workEnd();
 }
 
-void detectCPU( Mat& img, vector<Rect>& faces, 
-    CascadeClassifier& cascade, 
-    double scale, bool calTime)
+
+void detectCPU( Mat& img, vector<Rect>& faces,
+                CascadeClassifier& cascade,
+                double scale, bool calTime)
 {
     if(calTime) workBegin();
     Mat cpu_gray, cpu_smallImg( cvRound (img.rows/scale), cvRound(img.cols/scale), CV_8UC1 );
@@ -212,11 +233,12 @@ void detectCPU( Mat& img, vector<Rect>& faces,
     resize(cpu_gray, cpu_smallImg, cpu_smallImg.size(), 0, 0, INTER_LINEAR);
     equalizeHist(cpu_smallImg, cpu_smallImg);
     cascade.detectMultiScale(cpu_smallImg, faces, 1.1,
-        3, 0 | CV_HAAR_SCALE_IMAGE,
-        Size(30, 30), Size(0, 0));
-    if(calTime) workEnd(); 
+                             3, 0 | CV_HAAR_SCALE_IMAGE,
+                             Size(30, 30), Size(0, 0));
+    if(calTime) workEnd();
 }
 
+
 void Draw(Mat& img, vector<Rect>& faces, double scale)
 {
     int i = 0;
@@ -230,31 +252,43 @@ void Draw(Mat& img, vector<Rect>& faces, double scale)
         radius = cvRound((r->width + r->height)*0.25*scale);
         circle( img, center, radius, color, 3, 8, 0 );
     }
-    cv::imshow( "result", img );
+    imwrite( outputName, img );
+    if(abs(scale-1.0)>.001)
+    {
+        resize(img, img, Size((int)(img.cols/scale), (int)(img.rows/scale)));
+    }
+    imshow( "result", img );
+    
 }
 
-double checkRectSimilarity(Size sz, std::vector<Rect>& ob1, std::vector<Rect>& ob2)
+
+double checkRectSimilarity(Size sz, vector<Rect>& ob1, vector<Rect>& ob2)
 {
     double final_test_result = 0.0;
     size_t sz1 = ob1.size();
     size_t sz2 = ob2.size();
 
     if(sz1 != sz2)
+    {
         return sz1 > sz2 ? (double)(sz1 - sz2) : (double)(sz2 - sz1);
+    }
     else
     {
-        cv::Mat cpu_result(sz, CV_8UC1);
+        if(sz1==0 && sz2==0)
+            return 0;
+        Mat cpu_result(sz, CV_8UC1);
         cpu_result.setTo(0);
 
         for(vector<Rect>::const_iterator r = ob1.begin(); r != ob1.end(); r++)
-        {      
-            cv::Mat cpu_result_roi(cpu_result, *r);
+        {
+            Mat cpu_result_roi(cpu_result, *r);
             cpu_result_roi.setTo(1);
             cpu_result.copyTo(cpu_result);
         }
-        int cpu_area = cv::countNonZero(cpu_result > 0);
+        int cpu_area = countNonZero(cpu_result > 0);
+
 
-        cv::Mat gpu_result(sz, CV_8UC1);
+        Mat gpu_result(sz, CV_8UC1);
         gpu_result.setTo(0);
         for(vector<Rect>::const_iterator r2 = ob2.begin(); r2 != ob2.end(); r2++)
         {
@@ -263,11 +297,13 @@ double checkRectSimilarity(Size sz, std::vector<Rect>& ob1, std::vector<Rect>& o
             gpu_result.copyTo(gpu_result);
         }
 
-        cv::Mat result_;
+        Mat result_;
         multiply(cpu_result, gpu_result, result_);
-        int result = cv::countNonZero(result_ > 0);
-
-        final_test_result = 1.0 - (double)result/(double)cpu_area;
+        int result = countNonZero(result_ > 0);
+        if(cpu_area!=0 && result!=0)
+            final_test_result = 1.0 - (double)result/(double)cpu_area;
+        else if(cpu_area==0 && result!=0)
+            final_test_result = -1;
     }
     return final_test_result;
 }
index 28be6fa..a8f6b06 100644 (file)
 using namespace std;
 using namespace cv;
 
-bool help_showed = false;
-
-class Args
-{
-public:
-    Args();
-    static Args read(int argc, char** argv);
-
-    string src;
-    bool src_is_video;
-    bool src_is_camera;
-    int camera_id;
-
-    bool write_video;
-    string dst_video;
-    double dst_video_fps;
-
-    bool make_gray;
-
-    bool resize_src;
-    int width, height;
-
-    double scale;
-    int nlevels;
-    int gr_threshold;
-
-    double hit_threshold;
-    bool hit_threshold_auto;
-
-    int win_width;
-    int win_stride_width, win_stride_height;
-
-    bool gamma_corr;
-};
-
 class App
 {
 public:
-    App(const Args& s);
+    App(CommandLineParser& cmd);
     void run();
-
     void handleKey(char key);
-
     void hogWorkBegin();
     void hogWorkEnd();
     string hogWorkFps() const;
-
     void workBegin();
     void workEnd();
     string workFps() const;
-
     string message() const;
 
+
 // This function test if gpu_rst matches cpu_rst.
 // If the two vectors are not equal, it will return the difference in vector size
-// Else if will return 
+// Else if will return
 // (total diff of each cpu and gpu rects covered pixels)/(total cpu rects covered pixels)
-    double checkRectSimilarity(Size sz, 
-                               std::vector<Rect>& cpu_rst, 
+    double checkRectSimilarity(Size sz,
+                               std::vector<Rect>& cpu_rst,
                                std::vector<Rect>& gpu_rst);
 private:
     App operator=(App&);
 
-    Args args;
+    //Args args;
     bool running;
-
     bool use_gpu;
     bool make_gray;
     double scale;
+    double resize_scale;
+    int win_width;
+    int win_stride_width, win_stride_height;
     int gr_threshold;
     int nlevels;
     double hit_threshold;
@@ -86,179 +50,112 @@ private:
 
     int64 hog_work_begin;
     double hog_work_fps;
-
     int64 work_begin;
     double work_fps;
-};
 
-static void printHelp()
-{
-    cout << "Histogram of Oriented Gradients descriptor and detector sample.\n"
-         << "\nUsage: hog_gpu\n"
-         << "  (<image>|--video <vide>|--camera <camera_id>) # frames source\n"
-         << "  [--make_gray <true/false>] # convert image to gray one or not\n"
-         << "  [--resize_src <true/false>] # do resize of the source image or not\n"
-         << "  [--width <int>] # resized image width\n"
-         << "  [--height <int>] # resized image height\n"
-         << "  [--hit_threshold <double>] # classifying plane distance threshold (0.0 usually)\n"
-         << "  [--scale <double>] # HOG window scale factor\n"
-         << "  [--nlevels <int>] # max number of HOG window scales\n"
-         << "  [--win_width <int>] # width of the window (48 or 64)\n"
-         << "  [--win_stride_width <int>] # distance by OX axis between neighbour wins\n"
-         << "  [--win_stride_height <int>] # distance by OY axis between neighbour wins\n"
-         << "  [--gr_threshold <int>] # merging similar rects constant\n"
-         << "  [--gamma_correct <int>] # do gamma correction or not\n"
-         << "  [--write_video <bool>] # write video or not\n"
-         << "  [--dst_video <path>] # output video path\n"
-         << "  [--dst_video_fps <double>] # output video fps\n";
-    help_showed = true;
-}
+    string img_source;
+    string vdo_source;
+    string output;
+    int camera_id;
+    bool write_once;
+};
 
 int main(int argc, char** argv)
 {
+    const char* keys =
+        "{ h |  help    | false          | print help message }"
+        "{ i |  input   |                | specify input image}"
+        "{ c | camera   | -1             | enable camera capturing }"
+        "{ v | video    |                | use video as input }"
+        "{ g |  gray    | false          | convert image to gray one or not}"
+        "{ s |  scale   | 1.0            | resize the image before detect}"
+        "{ l |larger_win| false          | use 64x128 window}"
+        "{ o |  output  |                | specify output path when input is images}";
+    CommandLineParser cmd(argc, argv, keys);
+    App app(cmd);
     try
     {
-        if (argc < 2)
-            printHelp();
-        Args args = Args::read(argc, argv);
-        if (help_showed)
-            return -1;
-        App app(args);
         app.run();
     }
-    catch (const Exception& e) { return cout << "error: "  << e.what() << endl, 1; }
-    catch (const exception& e) { return cout << "error: "  << e.what() << endl, 1; }
-    catch(...) { return cout << "unknown exception" << endl, 1; }
-    return 0;
-}
-
-
-Args::Args()
-{
-    src_is_video = false;
-    src_is_camera = false;
-    camera_id = 0;
-
-    write_video = false;
-    dst_video_fps = 24.;
-
-    make_gray = false;
-
-    resize_src = false;
-    width = 640;
-    height = 480;
-
-    scale = 1.05;
-    nlevels = 13;
-    gr_threshold = 8;
-    hit_threshold = 1.4;
-    hit_threshold_auto = true;
-
-    win_width = 48;
-    win_stride_width = 8;
-    win_stride_height = 8;
-
-    gamma_corr = true;
-}
-
-
-Args Args::read(int argc, char** argv)
-{
-    Args args;
-    for (int i = 1; i < argc; i++)
+    catch (const Exception& e)
     {
-        if (string(argv[i]) == "--make_gray") args.make_gray = (string(argv[++i]) == "true");
-        else if (string(argv[i]) == "--resize_src") args.resize_src = (string(argv[++i]) == "true");
-        else if (string(argv[i]) == "--width") args.width = atoi(argv[++i]);
-        else if (string(argv[i]) == "--height") args.height = atoi(argv[++i]);
-        else if (string(argv[i]) == "--hit_threshold")
-        {
-            args.hit_threshold = atof(argv[++i]);
-            args.hit_threshold_auto = false;
-        }
-        else if (string(argv[i]) == "--scale") args.scale = atof(argv[++i]);
-        else if (string(argv[i]) == "--nlevels") args.nlevels = atoi(argv[++i]);
-        else if (string(argv[i]) == "--win_width") args.win_width = atoi(argv[++i]);
-        else if (string(argv[i]) == "--win_stride_width") args.win_stride_width = atoi(argv[++i]);
-        else if (string(argv[i]) == "--win_stride_height") args.win_stride_height = atoi(argv[++i]);
-        else if (string(argv[i]) == "--gr_threshold") args.gr_threshold = atoi(argv[++i]);
-        else if (string(argv[i]) == "--gamma_correct") args.gamma_corr = (string(argv[++i]) == "true");
-        else if (string(argv[i]) == "--write_video") args.write_video = (string(argv[++i]) == "true");
-        else if (string(argv[i]) == "--dst_video") args.dst_video = argv[++i];
-        else if (string(argv[i]) == "--dst_video_fps") args.dst_video_fps = atof(argv[++i]);
-        else if (string(argv[i]) == "--help") printHelp();
-        else if (string(argv[i]) == "--video") { args.src = argv[++i]; args.src_is_video = true; }
-        else if (string(argv[i]) == "--camera") { args.camera_id = atoi(argv[++i]); args.src_is_camera = true; }
-        else if (args.src.empty()) args.src = argv[i];
-        else throw runtime_error((string("unknown key: ") + argv[i]));
+        return cout << "error: "  << e.what() << endl, 1;
     }
-    return args;
+    catch (const exception& e)
+    {
+        return cout << "error: "  << e.what() << endl, 1;
+    }
+    catch(...)
+    {
+        return cout << "unknown exception" << endl, 1;
+    }
+    return 0;
 }
 
-
-App::App(const Args& s)
+App::App(CommandLineParser& cmd)
 {
-    args = s;
     cout << "\nControls:\n"
          << "\tESC - exit\n"
          << "\tm - change mode GPU <-> CPU\n"
          << "\tg - convert image to gray or not\n"
+         << "\to - save output image once, or switch on/off video save\n"
          << "\t1/q - increase/decrease HOG scale\n"
          << "\t2/w - increase/decrease levels count\n"
          << "\t3/e - increase/decrease HOG group threshold\n"
          << "\t4/r - increase/decrease hit threshold\n"
          << endl;
 
-    use_gpu = true;
-    make_gray = args.make_gray;
-    scale = args.scale;
-    gr_threshold = args.gr_threshold;
-    nlevels = args.nlevels;
-
-    if (args.hit_threshold_auto)
-        args.hit_threshold = args.win_width == 48 ? 1.4 : 0.;
-    hit_threshold = args.hit_threshold;
 
-    gamma_corr = args.gamma_corr;
+    use_gpu = true;
+    make_gray = cmd.get<bool>("g");
+    resize_scale = cmd.get<double>("s");
+    win_width = cmd.get<bool>("l") == true ? 64 : 48;
+    vdo_source = cmd.get<string>("v");
+    img_source = cmd.get<string>("i");
+    output = cmd.get<string>("o");
+    camera_id = cmd.get<int>("c");
 
-    if (args.win_width != 64 && args.win_width != 48)
-        args.win_width = 64;
+    win_stride_width = 8;
+    win_stride_height = 8;
+    gr_threshold = 8;
+    nlevels = 13;
+    hit_threshold = win_width == 48 ? 1.4 : 0.;
+    scale = 1.05;
+    gamma_corr = true;
+    write_once = false;
 
-    cout << "Scale: " << scale << endl;
-    if (args.resize_src)
-        cout << "Resized source: (" << args.width << ", " << args.height << ")\n";
     cout << "Group threshold: " << gr_threshold << endl;
     cout << "Levels number: " << nlevels << endl;
-    cout << "Win width: " << args.win_width << endl;
-    cout << "Win stride: (" << args.win_stride_width << ", " << args.win_stride_height << ")\n";
+    cout << "Win width: " << win_width << endl;
+    cout << "Win stride: (" << win_stride_width << ", " << win_stride_height << ")\n";
     cout << "Hit threshold: " << hit_threshold << endl;
     cout << "Gamma correction: " << gamma_corr << endl;
     cout << endl;
 }
 
-
 void App::run()
 {
-    std::vector<ocl::Info> oclinfo;
+    vector<ocl::Info> oclinfo;
     ocl::getDevice(oclinfo);
     running = true;
-    cv::VideoWriter video_writer;
+    VideoWriter video_writer;
 
-    Size win_size(args.win_width, args.win_width * 2); //(64, 128) or (48, 96)
-    Size win_stride(args.win_stride_width, args.win_stride_height);
+    Size win_size(win_width, win_width * 2);
+    Size win_stride(win_stride_width, win_stride_height);
 
     // Create HOG descriptors and detectors here
     vector<float> detector;
     if (win_size == Size(64, 128))
-        detector = cv::ocl::HOGDescriptor::getPeopleDetector64x128();
+        detector = ocl::HOGDescriptor::getPeopleDetector64x128();
     else
-        detector = cv::ocl::HOGDescriptor::getPeopleDetector48x96();
+        detector = ocl::HOGDescriptor::getPeopleDetector48x96();
 
-    cv::ocl::HOGDescriptor gpu_hog(win_size, Size(16, 16), Size(8, 8), Size(8, 8), 9,
-                                   cv::ocl::HOGDescriptor::DEFAULT_WIN_SIGMA, 0.2, gamma_corr,
-                                   cv::ocl::HOGDescriptor::DEFAULT_NLEVELS);
-    cv::HOGDescriptor cpu_hog(win_size, Size(16, 16), Size(8, 8), Size(8, 8), 9, 1, -1,
-                              HOGDescriptor::L2Hys, 0.2, gamma_corr, cv::HOGDescriptor::DEFAULT_NLEVELS);
+
+    ocl::HOGDescriptor gpu_hog(win_size, Size(16, 16), Size(8, 8), Size(8, 8), 9,
+                               ocl::HOGDescriptor::DEFAULT_WIN_SIGMA, 0.2, gamma_corr,
+                               ocl::HOGDescriptor::DEFAULT_NLEVELS);
+    HOGDescriptor cpu_hog(win_size, Size(16, 16), Size(8, 8), Size(8, 8), 9, 1, -1,
+                          HOGDescriptor::L2Hys, 0.2, gamma_corr, cv::HOGDescriptor::DEFAULT_NLEVELS);
     gpu_hog.setSVMDetector(detector);
     cpu_hog.setSVMDetector(detector);
 
@@ -267,29 +164,29 @@ void App::run()
         VideoCapture vc;
         Mat frame;
 
-        if (args.src_is_video)
+        if (vdo_source!="")
         {
-            vc.open(args.src.c_str());
+            vc.open(vdo_source.c_str());
             if (!vc.isOpened())
-                throw runtime_error(string("can't open video file: " + args.src));
+                throw runtime_error(string("can't open video file: " + vdo_source));
             vc >> frame;
         }
-        else if (args.src_is_camera)
+        else if (camera_id != -1)
         {
-            vc.open(args.camera_id);
+            vc.open(camera_id);
             if (!vc.isOpened())
             {
                 stringstream msg;
-                msg << "can't open camera: " << args.camera_id;
+                msg << "can't open camera: " << camera_id;
                 throw runtime_error(msg.str());
             }
             vc >> frame;
         }
         else
         {
-            frame = imread(args.src);
+            frame = imread(img_source);
             if (frame.empty())
-                throw runtime_error(string("can't open image file: " + args.src));
+                throw runtime_error(string("can't open image file: " + img_source));
         }
 
         Mat img_aux, img, img_to_show;
@@ -307,13 +204,15 @@ void App::run()
             else frame.copyTo(img_aux);
 
             // Resize image
-            if (args.resize_src) resize(img_aux, img, Size(args.width, args.height));
+            if (abs(scale-1.0)>0.001)
+            {
+                Size sz((int)((double)img_aux.cols/resize_scale), (int)((double)img_aux.rows/resize_scale));
+                resize(img_aux, img, sz);
+            }
             else img = img_aux;
             img_to_show = img;
-
             gpu_hog.nlevels = nlevels;
             cpu_hog.nlevels = nlevels;
-
             vector<Rect> found;
 
             // Perform HOG classification
@@ -330,15 +229,16 @@ void App::run()
                     vector<Rect> ref_rst;
                     cvtColor(img, img, CV_BGRA2BGR);
                     cpu_hog.detectMultiScale(img, ref_rst, hit_threshold, win_stride,
-                                              Size(0, 0), scale, gr_threshold-2);
+                                             Size(0, 0), scale, gr_threshold-2);
                     double accuracy = checkRectSimilarity(img.size(), ref_rst, found);
-                    cout << "\naccuracy value: " << accuracy << endl;           
-                } 
-           }
+                    cout << "\naccuracy value: " << accuracy << endl;
+                }
+            }
             else cpu_hog.detectMultiScale(img, found, hit_threshold, win_stride,
-                                          Size(0, 0), scale, gr_threshold);
+                                              Size(0, 0), scale, gr_threshold);
             hogWorkEnd();
 
+
             // Draw positive classified windows
             for (size_t i = 0; i < found.size(); i++)
             {
@@ -353,25 +253,32 @@ void App::run()
             putText(img_to_show, "FPS (HOG only): " + hogWorkFps(), Point(5, 65), FONT_HERSHEY_SIMPLEX, 1., Scalar(255, 100, 0), 2);
             putText(img_to_show, "FPS (total): " + workFps(), Point(5, 105), FONT_HERSHEY_SIMPLEX, 1., Scalar(255, 100, 0), 2);
             imshow("opencv_gpu_hog", img_to_show);
-
-            if (args.src_is_video || args.src_is_camera) vc >> frame;
+            if (vdo_source!="" || camera_id!=-1) vc >> frame;
 
             workEnd();
 
-            if (args.write_video)
+            if (output!="" && write_once)
             {
-                if (!video_writer.isOpened())
+                if (img_source!="")     // wirte image
                 {
-                    video_writer.open(args.dst_video, CV_FOURCC('x','v','i','d'), args.dst_video_fps,
-                                      img_to_show.size(), true);
-                    if (!video_writer.isOpened())
-                        throw std::runtime_error("can't create video writer");
+                    write_once = false;
+                    imwrite(output, img_to_show);
                 }
+                else                    //write video
+                {
+                    if (!video_writer.isOpened())
+                    {
+                        video_writer.open(output, CV_FOURCC('x','v','i','d'), 24,
+                                          img_to_show.size(), true);
+                        if (!video_writer.isOpened())
+                            throw std::runtime_error("can't create video writer");
+                    }
 
-                if (make_gray) cvtColor(img_to_show, img, CV_GRAY2BGR);
-                else cvtColor(img_to_show, img, CV_BGRA2BGR);
+                    if (make_gray) cvtColor(img_to_show, img, CV_GRAY2BGR);
+                    else cvtColor(img_to_show, img, CV_BGRA2BGR);
 
-                video_writer << img;
+                    video_writer << img;
+                }
             }
 
             handleKey((char)waitKey(3));
@@ -379,7 +286,6 @@ void App::run()
     }
 }
 
-
 void App::handleKey(char key)
 {
     switch (key)
@@ -438,11 +344,18 @@ void App::handleKey(char key)
         gamma_corr = !gamma_corr;
         cout << "Gamma correction: " << gamma_corr << endl;
         break;
+    case 'o':
+    case 'O':
+        write_once = !write_once;
+        break;
     }
 }
 
 
-inline void App::hogWorkBegin() { hog_work_begin = getTickCount(); }
+inline void App::hogWorkBegin()
+{
+    hog_work_begin = getTickCount();
+}
 
 inline void App::hogWorkEnd()
 {
@@ -458,8 +371,10 @@ inline string App::hogWorkFps() const
     return ss.str();
 }
 
-
-inline void App::workBegin() { work_begin = getTickCount(); }
+inline void App::workBegin()
+{
+    work_begin = getTickCount();
+}
 
 inline void App::workEnd()
 {
@@ -475,8 +390,9 @@ inline string App::workFps() const
     return ss.str();
 }
 
-double App::checkRectSimilarity(Size sz, 
-                                std::vector<Rect>& ob1, 
+
+double App::checkRectSimilarity(Size sz,
+                                std::vector<Rect>& ob1,
                                 std::vector<Rect>& ob2)
 {
     double final_test_result = 0.0;
@@ -484,20 +400,26 @@ double App::checkRectSimilarity(Size sz,
     size_t sz2 = ob2.size();
 
     if(sz1 != sz2)
+    {
         return sz1 > sz2 ? (double)(sz1 - sz2) : (double)(sz2 - sz1);
+    }
     else
     {
+        if(sz1==0 && sz2==0)
+            return 0;
         cv::Mat cpu_result(sz, CV_8UC1);
         cpu_result.setTo(0);
 
+
         for(vector<Rect>::const_iterator r = ob1.begin(); r != ob1.end(); r++)
-        {      
+        {
             cv::Mat cpu_result_roi(cpu_result, *r);
             cpu_result_roi.setTo(1);
             cpu_result.copyTo(cpu_result);
         }
         int cpu_area = cv::countNonZero(cpu_result > 0);
 
+
         cv::Mat gpu_result(sz, CV_8UC1);
         gpu_result.setTo(0);
         for(vector<Rect>::const_iterator r2 = ob2.begin(); r2 != ob2.end(); r2++)
@@ -510,10 +432,11 @@ double App::checkRectSimilarity(Size sz,
         cv::Mat result_;
         multiply(cpu_result, gpu_result, result_);
         int result = cv::countNonZero(result_ > 0);
-
-        final_test_result = 1.0 - (double)result/(double)cpu_area;
+        if(cpu_area!=0 && result!=0)
+            final_test_result = 1.0 - (double)result/(double)cpu_area;
+        else if(cpu_area==0 && result!=0)
+            final_test_result = -1;
     }
     return final_test_result;
-
 }
 
index cc8d886..cefa928 100644 (file)
@@ -11,19 +11,20 @@ using namespace cv;
 using namespace cv::ocl;
 
 typedef unsigned char uchar;
-#define LOOP_NUM 10 
+#define LOOP_NUM 10
 int64 work_begin = 0;
 int64 work_end = 0;
 
-static void workBegin() 
-{ 
+static void workBegin()
+{
     work_begin = getTickCount();
 }
 static void workEnd()
 {
     work_end += (getTickCount() - work_begin);
 }
-static double getTime(){
+static double getTime()
+{
     return work_end * 1000. / getTickFrequency();
 }
 
@@ -93,14 +94,15 @@ int main(int argc, const char* argv[])
     //set this to save kernel compile time from second time you run
     ocl::setBinpath("./");
     const char* keys =
-        "{ h            | help           | false | print help message }"
-        "{ l            | left           |       | specify left image }"
-        "{ r            | right          |       | specify right image }"
-        "{ c            | camera         | 0     | enable camera capturing }"
-        "{ s            | use_cpu        | false | use cpu or gpu to process the image }"
-        "{ v            | video          |       | use video as input }"
-        "{ points       | points         | 1000  | specify points count [GoodFeatureToTrack] }"
-        "{ min_dist     | min_dist       | 0     | specify minimal distance between points [GoodFeatureToTrack] }";
+        "{ h   | help     | false           | print help message }"
+        "{ l   | left     |                 | specify left image }"
+        "{ r   | right    |                 | specify right image }"
+        "{ c   | camera   | 0               | specify camera id }"
+        "{ s   | use_cpu  | false           | use cpu or gpu to process the image }"
+        "{ v   | video    |                 | use video as input }"
+        "{ o   | output   | pyrlk_output.jpg| specify output save path when input is images }"
+        "{ p   | points   | 1000            | specify points count [GoodFeatureToTrack] }"
+        "{ m   | min_dist | 0               | specify minimal distance between points [GoodFeatureToTrack] }";
 
     CommandLineParser cmd(argc, argv, keys);
 
@@ -113,13 +115,13 @@ int main(int argc, const char* argv[])
     }
 
     bool defaultPicturesFail = false;
-    string fname0 = cmd.get<string>("left");
-    string fname1 = cmd.get<string>("right");
-    string vdofile = cmd.get<string>("video");
-    int points = cmd.get<int>("points");
-    double minDist = cmd.get<double>("min_dist");
+    string fname0 = cmd.get<string>("l");
+    string fname1 = cmd.get<string>("r");
+    string vdofile = cmd.get<string>("v");
+    string outfile = cmd.get<string>("o");
+    int points = cmd.get<int>("p");
+    double minDist = cmd.get<double>("m");
     bool useCPU = cmd.get<bool>("s");
-    bool useCamera = cmd.get<bool>("c");
     int inputName = cmd.get<int>("c");
 
     oclMat d_nextPts, d_status;
@@ -132,22 +134,9 @@ int main(int argc, const char* argv[])
     vector<unsigned char> status(points);
     vector<float> err;
 
-    if (frame0.empty() || frame1.empty())
-    {
-        useCamera = true;
-        defaultPicturesFail = true;
-        CvCapture* capture = 0;
-        capture = cvCaptureFromCAM( inputName );
-        if (!capture)
-        {
-            cout << "Can't load input images" << endl;
-            return -1;
-        }
-    }
-
     cout << "Points count : " << points << endl << endl;
 
-    if (useCamera)
+    if (frame0.empty() || frame1.empty())
     {
         CvCapture* capture = 0;
         Mat frame, frameCopy;
@@ -241,10 +230,10 @@ _cleanup_:
     else
     {
 nocamera:
-        for(int i = 0; i <= LOOP_NUM;i ++) 
+        for(int i = 0; i <= LOOP_NUM; i ++)
         {
             cout << "loop" << i << endl;
-            if (i > 0) workBegin();     
+            if (i > 0) workBegin();
 
             if (useCPU)
             {
@@ -274,8 +263,8 @@ nocamera:
                 cout << getTime() / LOOP_NUM << " ms" << endl;
 
                 drawArrows(frame0, pts, nextPts, status, Scalar(255, 0, 0));
-
                 imshow("PyrLK [Sparse]", frame0);
+                imwrite(outfile, frame0);
             }
         }
     }
index 6b18416..48964ff 100644 (file)
@@ -6,7 +6,6 @@
 #include "opencv2/imgproc/imgproc.hpp"
 #include "opencv2/highgui/highgui.hpp"
 #include "opencv2/ocl/ocl.hpp"
-
 #include <iostream>
 #include <math.h>
 #include <string.h>
 using namespace cv;
 using namespace std;
 
-static void help()
+#define ACCURACY_CHECK 1
+
+#if ACCURACY_CHECK
+// check if two vectors of vector of points are near or not
+// prior assumption is that they are in correct order
+static bool checkPoints(
+    vector< vector<Point> > set1,
+    vector< vector<Point> > set2,
+    int maxDiff = 5)
 {
-    cout <<
-        "\nA program using OCL module pyramid scaling, Canny, dilate functions, threshold, split; cpu contours, contour simpification and\n"
-        "memory storage (it's got it all folks) to find\n"
-        "squares in a list of images pic1-6.png\n"
-        "Returns sequence of squares detected on the image.\n"
-        "the sequence is stored in the specified memory storage\n"
-        "Call:\n"
-        "./squares\n"
-        "Using OpenCV version %s\n" << CV_VERSION << "\n" << endl;
-}
+    if(set1.size() != set2.size())
+    {
+        return false;
+    }
+
+    for(vector< vector<Point> >::iterator it1 = set1.begin(), it2 = set2.begin();
+            it1 < set1.end() && it2 < set2.end(); it1 ++, it2 ++)
+    {
+        vector<Point> pts1 = *it1;
+        vector<Point> pts2 = *it2;
 
 
+        if(pts1.size() != pts2.size())
+        {
+            return false;
+        }
+        for(size_t i = 0; i < pts1.size(); i ++)
+        {
+            Point pt1 = pts1[i], pt2 = pts2[i];
+            if(std::abs(pt1.x - pt2.x) > maxDiff ||
+                    std::abs(pt1.y - pt2.y) > maxDiff)
+            {
+                return false;
+            }
+        }
+    }
+    return true;
+}
+#endif
+
 int thresh = 50, N = 11;
 const char* wndname = "OpenCL Square Detection Demo";
 
+
 // helper function:
 // finds a cosine of angle between vectors
 // from pt0->pt1 and from pt0->pt2
@@ -43,11 +69,94 @@ static double angle( Point pt1, Point pt2, Point pt0 )
     return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
 }
 
+
 // returns sequence of squares detected on the image.
 // the sequence is stored in the specified memory storage
 static void findSquares( const Mat& image, vector<vector<Point> >& squares )
 {
     squares.clear();
+    Mat pyr, timg, gray0(image.size(), CV_8U), gray;
+
+    // down-scale and upscale the image to filter out the noise
+    pyrDown(image, pyr, Size(image.cols/2, image.rows/2));
+    pyrUp(pyr, timg, image.size());
+    vector<vector<Point> > contours;
+
+    // find squares in every color plane of the image
+    for( int c = 0; c < 3; c++ )
+    {
+        int ch[] = {c, 0};
+        mixChannels(&timg, 1, &gray0, 1, ch, 1);
+
+        // try several threshold levels
+        for( int l = 0; l < N; l++ )
+        {
+            // hack: use Canny instead of zero threshold level.
+            // Canny helps to catch squares with gradient shading
+            if( l == 0 )
+            {
+                // apply Canny. Take the upper threshold from slider
+                // and set the lower to 0 (which forces edges merging)
+                Canny(gray0, gray, 0, thresh, 5);
+                // dilate canny output to remove potential
+                // holes between edge segments
+                dilate(gray, gray, Mat(), Point(-1,-1));
+            }
+            else
+            {
+                // apply threshold if l!=0:
+                //     tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0
+                cv::threshold(gray0, gray, (l+1)*255/N, 255, THRESH_BINARY);
+            }
+
+            // find contours and store them all as a list
+            findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
+
+            vector<Point> approx;
+
+            // test each contour
+            for( size_t i = 0; i < contours.size(); i++ )
+            {
+                // approximate contour with accuracy proportional
+                // to the contour perimeter
+                approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);
+
+                // square contours should have 4 vertices after approximation
+                // relatively large area (to filter out noisy contours)
+                // and be convex.
+                // Note: absolute value of an area is used because
+                // area may be positive or negative - in accordance with the
+                // contour orientation
+                if( approx.size() == 4 &&
+                        fabs(contourArea(Mat(approx))) > 1000 &&
+                        isContourConvex(Mat(approx)) )
+                {
+                    double maxCosine = 0;
+
+                    for( int j = 2; j < 5; j++ )
+                    {
+                        // find the maximum cosine of the angle between joint edges
+                        double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
+                        maxCosine = MAX(maxCosine, cosine);
+                    }
+
+                    // if cosines of all angles are small
+                    // (all angles are ~90 degree) then write quandrange
+                    // vertices to resultant sequence
+                    if( maxCosine < 0.3 )
+                        squares.push_back(approx);
+                }
+            }
+        }
+    }
+}
+
+
+// returns sequence of squares detected on the image.
+// the sequence is stored in the specified memory storage
+static void findSquares_ocl( const Mat& image, vector<vector<Point> >& squares )
+{
+    squares.clear();
 
     Mat gray;
     cv::ocl::oclMat pyr_ocl, timg_ocl, gray0_ocl, gray_ocl;
@@ -91,7 +200,6 @@ static void findSquares( const Mat& image, vector<vector<Point> >& squares )
             findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
 
             vector<Point> approx;
-
             // test each contour
             for( size_t i = 0; i < contours.size(); i++ )
             {
@@ -106,11 +214,10 @@ static void findSquares( const Mat& image, vector<vector<Point> >& squares )
                 // area may be positive or negative - in accordance with the
                 // contour orientation
                 if( approx.size() == 4 &&
-                    fabs(contourArea(Mat(approx))) > 1000 &&
-                    isContourConvex(Mat(approx)) )
+                        fabs(contourArea(Mat(approx))) > 1000 &&
+                        isContourConvex(Mat(approx)) )
                 {
                     double maxCosine = 0;
-
                     for( int j = 2; j < 5; j++ )
                     {
                         // find the maximum cosine of the angle between joint edges
@@ -139,40 +246,93 @@ static void drawSquares( Mat& image, const vector<vector<Point> >& squares )
         int n = (int)squares[i].size();
         polylines(image, &p, &n, 1, true, Scalar(0,255,0), 3, CV_AA);
     }
+}
+
 
-    imshow(wndname, image);
+// draw both pure-C++ and ocl square results onto a single image
+static Mat drawSquaresBoth( const Mat& image,
+                            const vector<vector<Point> >& sqsCPP,
+                            const vector<vector<Point> >& sqsOCL
+)
+{
+    Mat imgToShow(Size(image.cols * 2, image.rows), image.type());
+    Mat lImg = imgToShow(Rect(Point(0, 0), image.size()));
+    Mat rImg = imgToShow(Rect(Point(image.cols, 0), image.size()));
+    image.copyTo(lImg);
+    image.copyTo(rImg);
+    drawSquares(lImg, sqsCPP);
+    drawSquares(rImg, sqsOCL);
+    float fontScale = 0.8f;
+    Scalar white = Scalar::all(255), black = Scalar::all(0);
+
+    putText(lImg, "C++", Point(10, 20), FONT_HERSHEY_COMPLEX_SMALL, fontScale, black, 2);
+    putText(rImg, "OCL", Point(10, 20), FONT_HERSHEY_COMPLEX_SMALL, fontScale, black, 2);
+    putText(lImg, "C++", Point(10, 20), FONT_HERSHEY_COMPLEX_SMALL, fontScale, white, 1);
+    putText(rImg, "OCL", Point(10, 20), FONT_HERSHEY_COMPLEX_SMALL, fontScale, white, 1);
+
+    return imgToShow;
 }
 
 
-int main(int /*argc*/, char** /*argv*/)
+int main(int argc, char** argv)
 {
+    const char* keys =
+        "{ i | input   |                    | specify input image }"
+        "{ o | output  | squares_output.jpg | specify output save path}";
+    CommandLineParser cmd(argc, argv, keys);
+    string inputName = cmd.get<string>("i");
+    string outfile = cmd.get<string>("o");
+    if(inputName.empty())
+    {
+        cout << "Avaible options:" << endl;
+        cmd.printParams();
+        return 0;
+    }
 
-    //ocl::setBinpath("F:/kernel_bin");
     vector<ocl::Info> info;
     CV_Assert(ocl::getDevice(info));
-
-    static const char* names[] = { "pic1.png", "pic2.png", "pic3.png",
-        "pic4.png", "pic5.png", "pic6.png", 0 };
-    help();
+    int iterations = 10;
     namedWindow( wndname, 1 );
-    vector<vector<Point> > squares;
+    vector<vector<Point> > squares_cpu, squares_ocl;
 
-    for( int i = 0; names[i] != 0; i++ )
+    Mat image = imread(inputName, 1);
+    if( image.empty() )
     {
-        Mat image = imread(names[i], 1);
-        if( image.empty() )
-        {
-            cout << "Couldn't load " << names[i] << endl;
-            continue;
-        }
+        cout << "Couldn't load " << inputName << endl;
+        return -1;
+    }
+    int j = iterations;
+    int64 t_ocl = 0, t_cpp = 0;
+    //warm-ups
+    cout << "warming up ..." << endl;
+    findSquares(image, squares_cpu);
+    findSquares_ocl(image, squares_ocl);
+
+
+#if ACCURACY_CHECK
+    cout << "Checking ocl accuracy ... " << endl;
+    cout << (checkPoints(squares_cpu, squares_ocl) ? "Pass" : "Failed") << endl;
+#endif
+    do
+    {
+        int64 t_start = cv::getTickCount();
+        findSquares(image, squares_cpu);
+        t_cpp += cv::getTickCount() - t_start;
 
-        findSquares(image, squares);
-        drawSquares(image, squares);
 
-        int c = waitKey();
-        if( (char)c == 27 )
-            break;
+        t_start  = cv::getTickCount();
+        findSquares_ocl(image, squares_ocl);
+        t_ocl += cv::getTickCount() - t_start;
+        cout << "run loop: " << j << endl;
     }
+    while(--j);
+    cout << "cpp average time: " << 1000.0f * (double)t_cpp / getTickFrequency() / iterations << "ms" << endl;
+    cout << "ocl average time: " << 1000.0f * (double)t_ocl / getTickFrequency() / iterations << "ms" << endl;
+
+    Mat result = drawSquaresBoth(image, squares_cpu, squares_ocl);
+    imshow(wndname, result);
+    imwrite(outfile, result);
+    cvWaitKey(0);
 
     return 0;
 }
index 7ac2c9a..8a5031e 100644 (file)
@@ -10,57 +10,46 @@ using namespace cv;
 using namespace std;
 using namespace ocl;
 
-bool help_showed = false;
-
-struct Params
-{
-    Params();
-    static Params read(int argc, char** argv);
-
-    string left;
-    string right;
-
-    string method_str() const
-    {
-        switch (method)
-        {
-        case BM: return "BM";
-        case BP: return "BP";
-        case CSBP: return "CSBP";
-        }
-        return "";
-    }
-    enum {BM, BP, CSBP} method;
-    int ndisp; // Max disparity + 1
-    enum {GPU, CPU} type;
-};
-
 
 struct App
 {
-    App(const Params& p);
+    App(CommandLineParser& cmd);
     void run();
     void handleKey(char key);
     void printParams() const;
 
-    void workBegin() { work_begin = getTickCount(); }
+    void workBegin()
+    {
+        work_begin = getTickCount();
+    }
     void workEnd()
     {
         int64 d = getTickCount() - work_begin;
         double f = getTickFrequency();
         work_fps = f / d;
     }
-
+    string method_str() const
+    {
+        switch (method)
+        {
+        case BM:
+            return "BM";
+        case BP:
+            return "BP";
+        case CSBP:
+            return "CSBP";
+        }
+        return "";
+    }
     string text() const
     {
         stringstream ss;
-        ss << "(" << p.method_str() << ") FPS: " << setiosflags(ios::left)
-            << setprecision(4) << work_fps;
+        ss << "(" << method_str() << ") FPS: " << setiosflags(ios::left)
+           << setprecision(4) << work_fps;
         return ss.str();
     }
 private:
-    Params p;
-    bool running;
+    bool running, write_once;
 
     Mat left_src, right_src;
     Mat left, right;
@@ -72,42 +61,45 @@ private:
 
     int64 work_begin;
     double work_fps;
-};
 
-static void printHelp()
-{
-    cout << "Usage: stereo_match_gpu\n"
-        << "\t--left <left_view> --right <right_view> # must be rectified\n"
-        << "\t--method <stereo_match_method> # BM | BP | CSBP\n"
-        << "\t--ndisp <number> # number of disparity levels\n"
-        << "\t--type <device_type> # cpu | CPU | gpu | GPU\n";
-    help_showed = true;
-}
+    string l_img, r_img;
+    string out_img;
+    enum {BM, BP, CSBP} method;
+    int ndisp; // Max disparity + 1
+    enum {GPU, CPU} type;
+};
 
 int main(int argc, char** argv)
 {
+    const char* keys =
+        "{ h | help     | false                     | print help message }"
+        "{ l | left     |                           | specify left image }"
+        "{ r | right    |                           | specify right image }"
+        "{ m | method   | BM                        | specify match method(BM/BP/CSBP) }"
+        "{ n | ndisp    | 64                        |  specify number of disparity levels }"
+        "{ s | cpu_ocl  | false                     | use cpu or gpu as ocl device to process the image }"
+        "{ o | output   | stereo_match_output.jpg   | specify output path when input is images}";
+    CommandLineParser cmd(argc, argv, keys);
+    if (cmd.get<bool>("help"))
+    {
+        cout << "Avaible options:" << endl;
+        cmd.printParams();
+        return 0;
+    }
     try
     {
-        if (argc < 2)
-        {
-            printHelp();
-            return 1;
-        }
-
-        Params args = Params::read(argc, argv);
-        if (help_showed)
-            return -1;
+        App app(cmd);
+        int flag = CVCL_DEVICE_TYPE_GPU;
+        if(cmd.get<bool>("s") == true)
+            flag = CVCL_DEVICE_TYPE_CPU;
 
-        int flags[2] = { CVCL_DEVICE_TYPE_GPU, CVCL_DEVICE_TYPE_CPU };
         vector<Info> info;
-
-        if(getDevice(info, flags[args.type]) == 0)
+        if(getDevice(info, flag) == 0)
         {
             throw runtime_error("Error: Did not find a valid OpenCL device!");
         }
         cout << "Device name:" << info[0].DeviceName[0] << endl;
 
-        App app(args);
         app.run();
     }
     catch (const exception& e)
@@ -117,77 +109,41 @@ int main(int argc, char** argv)
     return 0;
 }
 
-
-Params::Params()
-{
-    method = BM;
-    ndisp = 64;
-    type = GPU;
-}
-
-
-Params Params::read(int argc, char** argv)
-{
-    Params p;
-
-    for (int i = 1; i < argc; i++)
-    {
-        if (string(argv[i]) == "--left") p.left = argv[++i];
-        else if (string(argv[i]) == "--right") p.right = argv[++i];
-        else if (string(argv[i]) == "--method")
-        {
-            if (string(argv[i + 1]) == "BM") p.method = BM;
-            else if (string(argv[i + 1]) == "BP") p.method = BP;
-            else if (string(argv[i + 1]) == "CSBP") p.method = CSBP;
-            else throw runtime_error("unknown stereo match method: " + string(argv[i + 1]));
-            i++;
-        }
-        else if (string(argv[i]) == "--ndisp") p.ndisp = atoi(argv[++i]);
-        else if (string(argv[i]) == "--type")
-        {
-            string t(argv[++i]);
-            if (t == "cpu" || t == "CPU")
-            {
-                p.type = CPU;
-            } 
-            else if (t == "gpu" || t == "GPU")
-            {
-                p.type = GPU;
-            }
-            else throw runtime_error("unknown device type: " + t);
-        }
-        else if (string(argv[i]) == "--help") printHelp();
-        else throw runtime_error("unknown key: " + string(argv[i]));
-    }
-
-    return p;
-}
-
-
-App::App(const Params& params)
-    : p(params), running(false)
+App::App(CommandLineParser& cmd)
+    : running(false),method(BM)
 {
     cout << "stereo_match_ocl sample\n";
     cout << "\nControls:\n"
-        << "\tesc - exit\n"
-        << "\tp - print current parameters\n"
-        << "\tg - convert source images into gray\n"
-        << "\tm - change stereo match method\n"
-        << "\ts - change Sobel prefiltering flag (for BM only)\n"
-        << "\t1/q - increase/decrease maximum disparity\n"
-        << "\t2/w - increase/decrease window size (for BM only)\n"
-        << "\t3/e - increase/decrease iteration count (for BP and CSBP only)\n"
-        << "\t4/r - increase/decrease level count (for BP and CSBP only)\n";
+         << "\tesc - exit\n"
+         << "\to - save output image once\n"
+         << "\tp - print current parameters\n"
+         << "\tg - convert source images into gray\n"
+         << "\tm - change stereo match method\n"
+         << "\ts - change Sobel prefiltering flag (for BM only)\n"
+         << "\t1/q - increase/decrease maximum disparity\n"
+         << "\t2/w - increase/decrease window size (for BM only)\n"
+         << "\t3/e - increase/decrease iteration count (for BP and CSBP only)\n"
+         << "\t4/r - increase/decrease level count (for BP and CSBP only)\n";
+    l_img = cmd.get<string>("l");
+    r_img = cmd.get<string>("r");
+    string mstr = cmd.get<string>("m");
+    if(mstr == "BM") method = BM;
+    else if(mstr == "BP") method = BP;
+    else if(mstr == "CSBP") method = CSBP;
+    else cout << "unknown method!\n";
+    ndisp = cmd.get<int>("n");
+    out_img = cmd.get<string>("o");
+    write_once = false;
 }
 
 
 void App::run()
 {
     // Load images
-    left_src = imread(p.left);
-    right_src = imread(p.right);
-    if (left_src.empty()) throw runtime_error("can't open file \"" + p.left + "\"");
-    if (right_src.empty()) throw runtime_error("can't open file \"" + p.right + "\"");
+    left_src = imread(l_img);
+    right_src = imread(r_img);
+    if (left_src.empty()) throw runtime_error("can't open file \"" + l_img + "\"");
+    if (right_src.empty()) throw runtime_error("can't open file \"" + r_img + "\"");
 
     cvtColor(left_src, left, CV_BGR2GRAY);
     cvtColor(right_src, right, CV_BGR2GRAY);
@@ -199,9 +155,9 @@ void App::run()
     imshow("right", right);
 
     // Set common parameters
-    bm.ndisp = p.ndisp;
-    bp.ndisp = p.ndisp;
-    csbp.ndisp = p.ndisp;
+    bm.ndisp = ndisp;
+    bp.ndisp = ndisp;
+    csbp.ndisp = ndisp;
 
     cout << endl;
     printParams();
@@ -209,14 +165,13 @@ void App::run()
     running = true;
     while (running)
     {
-
         // Prepare disparity map of specified type
         Mat disp;
         oclMat d_disp;
         workBegin();
-        switch (p.method)
+        switch (method)
         {
-        case Params::BM:
+        case BM:
             if (d_left.channels() > 1 || d_right.channels() > 1)
             {
                 cout << "BM doesn't support color images\n";
@@ -230,25 +185,29 @@ void App::run()
             }
             bm(d_left, d_right, d_disp);
             break;
-        case Params::BP:
+        case BP:
             bp(d_left, d_right, d_disp);
             break;
-        case Params::CSBP:
+        case CSBP:
             csbp(d_left, d_right, d_disp);
             break;
         }
-        ocl::finish();
-        workEnd();
 
         // Show results
         d_disp.download(disp);
-        if (p.method != Params::BM)
+        workEnd();
+
+        if (method != BM)
         {
             disp.convertTo(disp, 0);
         }
         putText(disp, text(), Point(5, 25), FONT_HERSHEY_SIMPLEX, 1.0, Scalar::all(255));
         imshow("disparity", disp);
-
+        if(write_once)
+        {
+            imwrite(out_img, disp);
+            write_once = false;
+        }
         handleKey((char)waitKey(3));
     }
 }
@@ -259,19 +218,19 @@ void App::printParams() const
     cout << "--- Parameters ---\n";
     cout << "image_size: (" << left.cols << ", " << left.rows << ")\n";
     cout << "image_channels: " << left.channels() << endl;
-    cout << "method: " << p.method_str() << endl
-        << "ndisp: " << p.ndisp << endl;
-    switch (p.method)
+    cout << "method: " << method_str() << endl
+         << "ndisp: " << ndisp << endl;
+    switch (method)
     {
-    case Params::BM:
+    case BM:
         cout << "win_size: " << bm.winSize << endl;
         cout << "prefilter_sobel: " << bm.preset << endl;
         break;
-    case Params::BP:
+    case BP:
         cout << "iter_count: " << bp.iters << endl;
         cout << "level_count: " << bp.levels << endl;
         break;
-    case Params::CSBP:
+    case CSBP:
         cout << "iter_count: " << csbp.iters << endl;
         cout << "level_count: " << csbp.levels << endl;
         break;
@@ -287,11 +246,13 @@ void App::handleKey(char key)
     case 27:
         running = false;
         break;
-    case 'p': case 'P':
+    case 'p':
+    case 'P':
         printParams();
         break;
-    case 'g': case 'G':
-        if (left.channels() == 1 && p.method != Params::BM)
+    case 'g':
+    case 'G':
+        if (left.channels() == 1 && method != BM)
         {
             left = left_src;
             right = right_src;
@@ -307,23 +268,25 @@ void App::handleKey(char key)
         imshow("left", left);
         imshow("right", right);
         break;
-    case 'm': case 'M':
-        switch (p.method)
+    case 'm':
+    case 'M':
+        switch (method)
         {
-        case Params::BM:
-            p.method = Params::BP;
+        case BM:
+            method = BP;
             break;
-        case Params::BP:
-            p.method = Params::CSBP;
+        case BP:
+            method = CSBP;
             break;
-        case Params::CSBP:
-            p.method = Params::BM;
+        case CSBP:
+            method = BM;
             break;
         }
-        cout << "method: " << p.method_str() << endl;
+        cout << "method: " << method_str() << endl;
         break;
-    case 's': case 'S':
-        if (p.method == Params::BM)
+    case 's':
+    case 'S':
+        if (method == BM)
         {
             switch (bm.preset)
             {
@@ -338,81 +301,89 @@ void App::handleKey(char key)
         }
         break;
     case '1':
-        p.ndisp = p.ndisp == 1 ? 8 : p.ndisp + 8;
-        cout << "ndisp: " << p.ndisp << endl;
-        bm.ndisp = p.ndisp;
-        bp.ndisp = p.ndisp;
-        csbp.ndisp = p.ndisp;
+        ndisp == 1 ? ndisp = 8 : ndisp += 8;
+        cout << "ndisp: " << ndisp << endl;
+        bm.ndisp = ndisp;
+        bp.ndisp = ndisp;
+        csbp.ndisp = ndisp;
         break;
-    case 'q': case 'Q':
-        p.ndisp = max(p.ndisp - 8, 1);
-        cout << "ndisp: " << p.ndisp << endl;
-        bm.ndisp = p.ndisp;
-        bp.ndisp = p.ndisp;
-        csbp.ndisp = p.ndisp;
+    case 'q':
+    case 'Q':
+        ndisp = max(ndisp - 8, 1);
+        cout << "ndisp: " << ndisp << endl;
+        bm.ndisp = ndisp;
+        bp.ndisp = ndisp;
+        csbp.ndisp = ndisp;
         break;
     case '2':
-        if (p.method == Params::BM)
+        if (method == BM)
         {
             bm.winSize = min(bm.winSize + 1, 51);
             cout << "win_size: " << bm.winSize << endl;
         }
         break;
-    case 'w': case 'W':
-        if (p.method == Params::BM)
+    case 'w':
+    case 'W':
+        if (method == BM)
         {
             bm.winSize = max(bm.winSize - 1, 2);
             cout << "win_size: " << bm.winSize << endl;
         }
         break;
     case '3':
-        if (p.method == Params::BP)
+        if (method == BP)
         {
             bp.iters += 1;
             cout << "iter_count: " << bp.iters << endl;
         }
-        else if (p.method == Params::CSBP)
+        else if (method == CSBP)
         {
             csbp.iters += 1;
             cout << "iter_count: " << csbp.iters << endl;
         }
         break;
-    case 'e': case 'E':
-        if (p.method == Params::BP)
+    case 'e':
+    case 'E':
+        if (method == BP)
         {
             bp.iters = max(bp.iters - 1, 1);
             cout << "iter_count: " << bp.iters << endl;
         }
-        else if (p.method == Params::CSBP)
+        else if (method == CSBP)
         {
             csbp.iters = max(csbp.iters - 1, 1);
             cout << "iter_count: " << csbp.iters << endl;
         }
         break;
     case '4':
-        if (p.method == Params::BP)
+        if (method == BP)
         {
             bp.levels += 1;
             cout << "level_count: " << bp.levels << endl;
         }
-        else if (p.method == Params::CSBP)
+        else if (method == CSBP)
         {
             csbp.levels += 1;
             cout << "level_count: " << csbp.levels << endl;
         }
         break;
-    case 'r': case 'R':
-        if (p.method == Params::BP)
+    case 'r':
+    case 'R':
+        if (method == BP)
         {
             bp.levels = max(bp.levels - 1, 1);
             cout << "level_count: " << bp.levels << endl;
         }
-        else if (p.method == Params::CSBP)
+        else if (method == CSBP)
         {
             csbp.levels = max(csbp.levels - 1, 1);
             cout << "level_count: " << csbp.levels << endl;
         }
         break;
+    case 'o':
+    case 'O':
+        write_once = true;
+        break;
     }
 }
 
index 038a8dc..bee517f 100644 (file)
@@ -1,48 +1,3 @@
-/*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) 2010-2012, Multicoreware, Inc., all rights reserved.
-// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
-// Third party copyrights are property of their respective owners.
-//
-// @Authors
-//    Peng Xiao, pengxiao@multicorewareinc.com
-//
-// 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 oclMaterials 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 <iostream>
 #include <stdio.h>
 #include "opencv2/core/core.hpp"
@@ -61,27 +16,20 @@ const float GOOD_PORTION = 0.15f;
 
 namespace
 {
-void help();
-
-void help()
-{
-    std::cout << "\nThis program demonstrates using SURF_OCL features detector and descriptor extractor" << std::endl;
-    std::cout << "\nUsage:\n\tsurf_matcher --left <image1> --right <image2> [-c]" << std::endl;
-    std::cout << "\nExample:\n\tsurf_matcher --left box.png --right box_in_scene.png" << std::endl;
-}
 
 int64 work_begin = 0;
 int64 work_end = 0;
 
-void workBegin() 
-{ 
+void workBegin()
+{
     work_begin = getTickCount();
 }
 void workEnd()
 {
     work_end = getTickCount() - work_begin;
 }
-double getTime(){
+double getTime()
+{
     return work_end /((double)cvGetTickFrequency() * 1000.);
 }
 
@@ -114,17 +62,17 @@ struct SURFMatcher
 Mat drawGoodMatches(
     const Mat& cpu_img1,
     const Mat& cpu_img2,
-    const vector<KeyPoint>& keypoints1, 
-    const vector<KeyPoint>& keypoints2, 
+    const vector<KeyPoint>& keypoints1,
+    const vector<KeyPoint>& keypoints2,
     vector<DMatch>& matches,
     vector<Point2f>& scene_corners_
-    )
+)
 {
-    //-- Sort matches and preserve top 10% matches 
+    //-- Sort matches and preserve top 10% matches
     std::sort(matches.begin(), matches.end());
     std::vector< DMatch > good_matches;
     double minDist = matches.front().distance,
-        maxDist = matches.back().distance;
+           maxDist = matches.back().distance;
 
     const int ptsPairs = std::min(GOOD_PTS_MAX, (int)(matches.size() * GOOD_PORTION));
     for( int i = 0; i < ptsPairs; i++ )
@@ -139,8 +87,8 @@ Mat drawGoodMatches(
     // drawing the results
     Mat img_matches;
     drawMatches( cpu_img1, keypoints1, cpu_img2, keypoints2,
-        good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
-        vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS  );
+                 good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
+                 vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS  );
 
     //-- Localize the object
     std::vector<Point2f> obj;
@@ -154,28 +102,30 @@ Mat drawGoodMatches(
     }
     //-- Get the corners from the image_1 ( the object to be "detected" )
     std::vector<Point2f> obj_corners(4);
-    obj_corners[0] = cvPoint(0,0); obj_corners[1] = cvPoint( cpu_img1.cols, 0 );
-    obj_corners[2] = cvPoint( cpu_img1.cols, cpu_img1.rows ); obj_corners[3] = cvPoint( 0, cpu_img1.rows );
+    obj_corners[0] = cvPoint(0,0);
+    obj_corners[1] = cvPoint( cpu_img1.cols, 0 );
+    obj_corners[2] = cvPoint( cpu_img1.cols, cpu_img1.rows );
+    obj_corners[3] = cvPoint( 0, cpu_img1.rows );
     std::vector<Point2f> scene_corners(4);
-    
+
     Mat H = findHomography( obj, scene, CV_RANSAC );
     perspectiveTransform( obj_corners, scene_corners, H);
 
     scene_corners_ = scene_corners;
-    
+
     //-- Draw lines between the corners (the mapped object in the scene - image_2 )
-    line( img_matches, 
-        scene_corners[0] + Point2f( (float)cpu_img1.cols, 0), scene_corners[1] + Point2f( (float)cpu_img1.cols, 0), 
-        Scalar( 0, 255, 0), 2, CV_AA );
-    line( img_matches, 
-        scene_corners[1] + Point2f( (float)cpu_img1.cols, 0), scene_corners[2] + Point2f( (float)cpu_img1.cols, 0), 
-        Scalar( 0, 255, 0), 2, CV_AA );
-    line( img_matches, 
-        scene_corners[2] + Point2f( (float)cpu_img1.cols, 0), scene_corners[3] + Point2f( (float)cpu_img1.cols, 0), 
-        Scalar( 0, 255, 0), 2, CV_AA );
-    line( img_matches, 
-        scene_corners[3] + Point2f( (float)cpu_img1.cols, 0), scene_corners[0] + Point2f( (float)cpu_img1.cols, 0), 
-        Scalar( 0, 255, 0), 2, CV_AA );
+    line( img_matches,
+          scene_corners[0] + Point2f( (float)cpu_img1.cols, 0), scene_corners[1] + Point2f( (float)cpu_img1.cols, 0),
+          Scalar( 0, 255, 0), 2, CV_AA );
+    line( img_matches,
+          scene_corners[1] + Point2f( (float)cpu_img1.cols, 0), scene_corners[2] + Point2f( (float)cpu_img1.cols, 0),
+          Scalar( 0, 255, 0), 2, CV_AA );
+    line( img_matches,
+          scene_corners[2] + Point2f( (float)cpu_img1.cols, 0), scene_corners[3] + Point2f( (float)cpu_img1.cols, 0),
+          Scalar( 0, 255, 0), 2, CV_AA );
+    line( img_matches,
+          scene_corners[3] + Point2f( (float)cpu_img1.cols, 0), scene_corners[0] + Point2f( (float)cpu_img1.cols, 0),
+          Scalar( 0, 255, 0), 2, CV_AA );
     return img_matches;
 }
 
@@ -185,6 +135,21 @@ Mat drawGoodMatches(
 // use cpu findHomography interface to calculate the transformation matrix
 int main(int argc, char* argv[])
 {
+    const char* keys =
+        "{ h | help     | false           | print help message  }"
+        "{ l | left     |                 | specify left image  }"
+        "{ r | right    |                 | specify right image }"
+        "{ o | output   | SURF_output.jpg | specify output save path (only works in CPU or GPU only mode) }"
+        "{ c | use_cpu  | false           | use CPU algorithms  }"
+        "{ a | use_all  | false           | use both CPU and GPU algorithms}";
+    CommandLineParser cmd(argc, argv, keys);
+    if (cmd.get<bool>("help"))
+    {
+        std::cout << "Avaible options:" << std::endl;
+        cmd.printParams();
+        return 0;
+    }
+
     vector<cv::ocl::Info> info;
     if(cv::ocl::getDevice(info) == 0)
     {
@@ -195,54 +160,38 @@ int main(int argc, char* argv[])
 
     Mat cpu_img1, cpu_img2, cpu_img1_grey, cpu_img2_grey;
     oclMat img1, img2;
-    bool useCPU = false;
+    bool useCPU = cmd.get<bool>("c");
     bool useGPU = false;
-    bool useALL = false;
+    bool useALL = cmd.get<bool>("a");
+
+    string outpath = cmd.get<std::string>("o");
 
-    for (int i = 1; i < argc; ++i)
+    cpu_img1 = imread(cmd.get<std::string>("l"));
+    CV_Assert(!cpu_img1.empty());
+    cvtColor(cpu_img1, cpu_img1_grey, CV_BGR2GRAY);
+    img1 = cpu_img1_grey;
+
+    cpu_img2 = imread(cmd.get<std::string>("r"));
+    CV_Assert(!cpu_img2.empty());
+    cvtColor(cpu_img2, cpu_img2_grey, CV_BGR2GRAY);
+    img2 = cpu_img2_grey;
+
+    if(useALL)
     {
-        if (string(argv[i]) == "--left")
-        {
-            cpu_img1 = imread(argv[++i]);
-            CV_Assert(!cpu_img1.empty());
-            cvtColor(cpu_img1, cpu_img1_grey, CV_BGR2GRAY);
-            img1 = cpu_img1_grey;
-        }
-        else if (string(argv[i]) == "--right")
-        {
-            cpu_img2 = imread(argv[++i]);
-            CV_Assert(!cpu_img2.empty());
-            cvtColor(cpu_img2, cpu_img2_grey, CV_BGR2GRAY);
-            img2 = cpu_img2_grey;
-        }
-        else if (string(argv[i]) == "-c")
-        {
-            useCPU = true;
-            useGPU = false;
-            useALL = false;
-        }else if(string(argv[i]) == "-g")
-        {
-            useGPU = true;
-            useCPU = false;
-            useALL = false;
-        }else if(string(argv[i]) == "-a")
-        {
-            useALL = true;
-            useCPU = false;
-            useGPU = false;
-        }
-        else if (string(argv[i]) == "--help")
-        {
-            help();
-            return -1;
-        }
+        useCPU = false;
+        useGPU = false;
     }
+    else if(useCPU==false && useALL==false)
+    {
+        useGPU = true;
+    }
+
     if(!useCPU)
     {
         std::cout
-            << "Device name:"
-            << info[0].DeviceName[0]
-        << std::endl;
+                << "Device name:"
+                << info[0].DeviceName[0]
+                << std::endl;
     }
     double surf_time = 0.;
 
@@ -262,12 +211,12 @@ int main(int argc, char* argv[])
     //instantiate detectors/matchers
     SURFDetector<SURF>     cpp_surf;
     SURFDetector<SURF_OCL> ocl_surf;
-    
+
     SURFMatcher<BFMatcher>      cpp_matcher;
     SURFMatcher<BFMatcher_OCL>  ocl_matcher;
 
     //-- start of timing section
-    if (useCPU) 
+    if (useCPU)
     {
         for (int i = 0; i <= LOOP_NUM; i++)
         {
@@ -298,7 +247,8 @@ int main(int argc, char* argv[])
 
         surf_time = getTime();
         std::cout << "SURF run time: " << surf_time / LOOP_NUM << " ms" << std::endl<<"\n";
-    }else
+    }
+    else
     {
         //cpu runs
         for (int i = 0; i <= LOOP_NUM; i++)
@@ -353,14 +303,14 @@ int main(int argc, char* argv[])
             for(size_t i = 0; i < cpu_corner.size(); i++)
             {
                 if((std::abs(cpu_corner[i].x - gpu_corner[i].x) > 10)
-                    ||(std::abs(cpu_corner[i].y - gpu_corner[i].y) > 10))
+                        ||(std::abs(cpu_corner[i].y - gpu_corner[i].y) > 10))
                 {
                     std::cout<<"Failed\n";
                     result = false;
                     break;
                 }
                 result = true;
-            } 
+            }
             if(result)
                 std::cout<<"Passed\n";
         }
@@ -371,12 +321,15 @@ int main(int argc, char* argv[])
     {
         namedWindow("cpu surf matches", 0);
         imshow("cpu surf matches", img_matches);
+        imwrite(outpath, img_matches);
     }
     else if(useGPU)
     {
         namedWindow("ocl surf matches", 0);
         imshow("ocl surf matches", img_matches);
-    }else
+        imwrite(outpath, img_matches);
+    }
+    else
     {
         namedWindow("cpu surf matches", 0);
         imshow("cpu surf matches", img_matches);
diff --git a/samples/ocl/tvl1_optical_flow.cpp b/samples/ocl/tvl1_optical_flow.cpp
new file mode 100644 (file)
index 0000000..cff9692
--- /dev/null
@@ -0,0 +1,265 @@
+#include <iostream>
+#include <vector>
+#include <iomanip>
+
+#include "opencv2/highgui/highgui.hpp"
+#include "opencv2/ocl/ocl.hpp"
+#include "opencv2/video/video.hpp"
+
+using namespace std;
+using namespace cv;
+using namespace cv::ocl;
+
+typedef unsigned char uchar;
+#define LOOP_NUM 10
+int64 work_begin = 0;
+int64 work_end = 0;
+
+static void workBegin()
+{
+    work_begin = getTickCount();
+}
+static void workEnd()
+{
+    work_end += (getTickCount() - work_begin);
+}
+static double getTime()
+{
+    return work_end * 1000. / getTickFrequency();
+}
+
+template <typename T> inline T clamp (T x, T a, T b)
+{
+    return ((x) > (a) ? ((x) < (b) ? (x) : (b)) : (a));
+}
+
+template <typename T> inline T mapValue(T x, T a, T b, T c, T d)
+{
+    x = clamp(x, a, b);
+    return c + (d - c) * (x - a) / (b - a);
+}
+
+static void getFlowField(const Mat& u, const Mat& v, Mat& flowField)
+{
+    float maxDisplacement = 1.0f;
+
+    for (int i = 0; i < u.rows; ++i)
+    {
+        const float* ptr_u = u.ptr<float>(i);
+        const float* ptr_v = v.ptr<float>(i);
+
+        for (int j = 0; j < u.cols; ++j)
+        {
+            float d = max(fabsf(ptr_u[j]), fabsf(ptr_v[j]));
+
+            if (d > maxDisplacement)
+                maxDisplacement = d;
+        }
+    }
+
+    flowField.create(u.size(), CV_8UC4);
+
+    for (int i = 0; i < flowField.rows; ++i)
+    {
+        const float* ptr_u = u.ptr<float>(i);
+        const float* ptr_v = v.ptr<float>(i);
+
+
+        Vec4b* row = flowField.ptr<Vec4b>(i);
+
+        for (int j = 0; j < flowField.cols; ++j)
+        {
+            row[j][0] = 0;
+            row[j][1] = static_cast<unsigned char> (mapValue (-ptr_v[j], -maxDisplacement, maxDisplacement, 0.0f, 255.0f));
+            row[j][2] = static_cast<unsigned char> (mapValue ( ptr_u[j], -maxDisplacement, maxDisplacement, 0.0f, 255.0f));
+            row[j][3] = 255;
+        }
+    }
+}
+
+
+int main(int argc, const char* argv[])
+{
+    static std::vector<Info> ocl_info;
+    ocl::getDevice(ocl_info);
+    //if you want to use undefault device, set it here
+    setDevice(ocl_info[0]);
+
+    //set this to save kernel compile time from second time you run
+    ocl::setBinpath("./");
+    const char* keys =
+        "{ h   | help       | false           | print help message }"
+        "{ l   | left       |                 | specify left image }"
+        "{ r   | right      |                 | specify right image }"
+        "{ o   | output     | tvl1_output.jpg | specify output save path }"
+        "{ c   | camera     | 0               | enable camera capturing }"
+        "{ s   | use_cpu    | false           | use cpu or gpu to process the image }"
+        "{ v   | video      |                 | use video as input }";
+
+    CommandLineParser cmd(argc, argv, keys);
+
+    if (cmd.get<bool>("help"))
+    {
+        cout << "Usage: pyrlk_optical_flow [options]" << endl;
+        cout << "Avaible options:" << endl;
+        cmd.printParams();
+        return 0;
+    }
+
+    bool defaultPicturesFail = false;
+    string fname0 = cmd.get<string>("l");
+    string fname1 = cmd.get<string>("r");
+    string vdofile = cmd.get<string>("v");
+    string outpath = cmd.get<string>("o");
+    bool useCPU = cmd.get<bool>("s");
+    bool useCamera = cmd.get<bool>("c");
+    int inputName = cmd.get<int>("c");
+
+    Mat frame0 = imread(fname0, cv::IMREAD_GRAYSCALE);
+    Mat frame1 = imread(fname1, cv::IMREAD_GRAYSCALE);
+    cv::Ptr<cv::DenseOpticalFlow> alg = cv::createOptFlow_DualTVL1();
+    cv::ocl::OpticalFlowDual_TVL1_OCL d_alg;
+
+
+    Mat flow, show_flow;
+    Mat flow_vec[2];
+    if (frame0.empty() || frame1.empty())
+    {
+        useCamera = true;
+        defaultPicturesFail = true;
+        CvCapture* capture = 0;
+        capture = cvCaptureFromCAM( inputName );
+        if (!capture)
+        {
+            cout << "Can't load input images" << endl;
+            return -1;
+        }
+    }
+
+
+    if (useCamera)
+    {
+        CvCapture* capture = 0;
+        Mat frame, frameCopy;
+        Mat frame0Gray, frame1Gray;
+        Mat ptr0, ptr1;
+
+        if(vdofile == "")
+            capture = cvCaptureFromCAM( inputName );
+        else
+            capture = cvCreateFileCapture(vdofile.c_str());
+
+        int c = inputName ;
+        if(!capture)
+        {
+            if(vdofile == "")
+                cout << "Capture from CAM " << c << " didn't work" << endl;
+            else
+                cout << "Capture from file " << vdofile << " failed" <<endl;
+            if (defaultPicturesFail)
+            {
+                return -1;
+            }
+            goto nocamera;
+        }
+
+        cout << "In capture ..." << endl;
+        for(int i = 0;; i++)
+        {
+            frame = cvQueryFrame( capture );
+            if( frame.empty() )
+                break;
+
+            if (i == 0)
+            {
+                frame.copyTo( frame0 );
+                cvtColor(frame0, frame0Gray, COLOR_BGR2GRAY);
+            }
+            else
+            {
+                if (i%2 == 1)
+                {
+                    frame.copyTo(frame1);
+                    cvtColor(frame1, frame1Gray, COLOR_BGR2GRAY);
+                    ptr0 = frame0Gray;
+                    ptr1 = frame1Gray;
+                }
+                else
+                {
+                    frame.copyTo(frame0);
+                    cvtColor(frame0, frame0Gray, COLOR_BGR2GRAY);
+                    ptr0 = frame1Gray;
+                    ptr1 = frame0Gray;
+                }
+
+                if (useCPU)
+                {
+                    alg->calc(ptr0, ptr1, flow);
+                    split(flow, flow_vec);
+                }
+                else
+                {
+                    oclMat d_flowx, d_flowy;
+                    d_alg(oclMat(ptr0), oclMat(ptr1), d_flowx, d_flowy);
+                    d_flowx.download(flow_vec[0]);
+                    d_flowy.download(flow_vec[1]);
+                }
+                if (i%2 == 1)
+                    frame1.copyTo(frameCopy);
+                else
+                    frame0.copyTo(frameCopy);
+                getFlowField(flow_vec[0], flow_vec[1], show_flow);
+                imshow("PyrLK [Sparse]", show_flow);
+            }
+
+            if( waitKey( 10 ) >= 0 )
+                goto _cleanup_;
+        }
+
+        waitKey(0);
+
+_cleanup_:
+        cvReleaseCapture( &capture );
+    }
+    else
+    {
+nocamera:
+        oclMat d_flowx, d_flowy;
+        for(int i = 0; i <= LOOP_NUM; i ++)
+        {
+            cout << "loop" << i << endl;
+
+            if (i > 0) workBegin();
+            if (useCPU)
+            {
+                alg->calc(frame0, frame1, flow);
+                split(flow, flow_vec);
+            }
+            else
+            {
+                d_alg(oclMat(frame0), oclMat(frame1), d_flowx, d_flowy);
+                d_flowx.download(flow_vec[0]);
+                d_flowy.download(flow_vec[1]);
+            }
+            if (i > 0 && i <= LOOP_NUM)
+                workEnd();
+
+            if (i == LOOP_NUM)
+            {
+                if (useCPU)
+                    cout << "average CPU time (noCamera) : ";
+                else
+                    cout << "average GPU time (noCamera) : ";
+                cout << getTime() / LOOP_NUM << " ms" << endl;
+
+                getFlowField(flow_vec[0], flow_vec[1], show_flow);
+                imshow("PyrLK [Sparse]", show_flow);
+                imwrite(outpath, show_flow);
+            }
+        }
+    }
+
+    waitKey();
+
+    return 0;
+}
\ No newline at end of file
diff --git a/samples/winrt/ImageManipulations/AdvancedCapture.xaml b/samples/winrt/ImageManipulations/AdvancedCapture.xaml
new file mode 100644 (file)
index 0000000..07db96f
--- /dev/null
@@ -0,0 +1,75 @@
+<!--
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+-->
+
+<common:LayoutAwarePage
+    x:Class="SDKSample.MediaCapture.AdvancedCapture"
+    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+    xmlns:local="using:$rootsnamespace$"
+    xmlns:common="using:SDKSample.Common"
+    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+    mc:Ignorable="d">
+
+    <Grid x:Name="LayoutRoot" Background="White" HorizontalAlignment="Left" VerticalAlignment="Top">
+        <Grid.RowDefinitions>
+            <RowDefinition Height="Auto"/>
+            <RowDefinition Height="*"/>
+        </Grid.RowDefinitions>
+        <Grid x:Name="Input" Grid.Row="0">
+            <Grid.RowDefinitions>
+                <RowDefinition Height="Auto"/>
+                <RowDefinition Height="Auto"/>
+                <RowDefinition Height="*"/>
+            </Grid.RowDefinitions>
+            <TextBlock TextWrapping="Wrap" Grid.Row="0"  Text="This scenario shows how to enumerate cameras in the system. Choose a camera from the list to preview, record or take a photo from the chosen camera.  You can add the gray scale effect using the checkbox provided." Style="{StaticResource BasicTextStyle}" HorizontalAlignment="Left"/>
+            <StackPanel Orientation="Horizontal" Grid.Row="1" Margin="0,10,0,0">
+                <ListBox x:Name="EnumedDeviceList2" SelectionChanged="lstEnumedDevices_SelectionChanged" />
+                <Button x:Name="btnStartDevice2" Click="btnStartDevice_Click" IsEnabled="true"  Margin="0,0,10,0" Content="StartDevice"/>
+                <Button x:Name="btnStartPreview2" Click="btnStartPreview_Click" IsEnabled="true"  Margin="0,0,10,0" Content="StartPreview"/>
+                <ComboBox x:Name="EffectTypeCombo" Width="120" SelectedIndex="0">
+                    <ComboBoxItem Content="Preview"/>
+                    <ComboBoxItem Content="Grayscale"/>
+                    <ComboBoxItem Content="Canny"/>
+                    <ComboBoxItem Content="Sobel"/>
+                    <ComboBoxItem Content="Histogram"/>
+                </ComboBox>
+                <Button Content="Apply" HorizontalAlignment="Stretch" VerticalAlignment="Top" Click="Button_Click"/>
+            </StackPanel>
+            <StackPanel x:Name="EffectTypeCombo1" Orientation="Horizontal" Grid.Row="1" Margin="324,5,-324,7"/>
+        </Grid>
+
+        <Grid x:Name="Output" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1">
+            <StackPanel Orientation="Horizontal" Margin="0,10,0,0">
+                <StackPanel>
+                    <TextBlock Style="{StaticResource BasicTextStyle}"  HorizontalAlignment='Center'  VerticalAlignment='Center'  TextAlignment='Center'       Text='Preview' />
+                    <Canvas x:Name="previewCanvas2" Background="Gray">
+                        <CaptureElement x:Name="previewElement2" />
+                    </Canvas>
+                </StackPanel>
+                <StackPanel/>
+                <StackPanel/>
+            </StackPanel>
+        </Grid>
+
+        <!-- Add Storyboards to the visual states below as necessary for supporting the various layouts -->
+        <VisualStateManager.VisualStateGroups>
+            <VisualStateGroup>
+                <VisualState x:Name="FullScreenLandscape"/>
+                <VisualState x:Name="Filled"/>
+                <VisualState x:Name="FullScreenPortrait"/>
+                <VisualState x:Name="Snapped"/>
+            </VisualStateGroup>
+        </VisualStateManager.VisualStateGroups>
+    </Grid>
+
+</common:LayoutAwarePage>
diff --git a/samples/winrt/ImageManipulations/AdvancedCapture.xaml.cpp b/samples/winrt/ImageManipulations/AdvancedCapture.xaml.cpp
new file mode 100644 (file)
index 0000000..cff0a5a
--- /dev/null
@@ -0,0 +1,613 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+//
+// AdvancedCapture.xaml.cpp
+// Implementation of the AdvancedCapture class
+//
+
+#include "pch.h"
+#include "AdvancedCapture.xaml.h"
+
+using namespace SDKSample::MediaCapture;
+
+using namespace Windows::UI::Xaml;
+using namespace Windows::UI::Xaml::Navigation;
+using namespace Windows::UI::Xaml::Data;
+using namespace Windows::System;
+using namespace Windows::Foundation;
+using namespace Windows::Foundation::Collections;
+using namespace Platform;
+using namespace Windows::UI;
+using namespace Windows::UI::Core;
+using namespace Windows::UI::Xaml;
+using namespace Windows::UI::Xaml::Controls;
+using namespace Windows::UI::Xaml::Data;
+using namespace Windows::UI::Xaml::Media;
+using namespace Windows::Storage;
+using namespace Windows::Media::MediaProperties;
+using namespace Windows::Storage::Streams;
+using namespace Windows::System;
+using namespace Windows::UI::Xaml::Media::Imaging;
+using namespace Windows::Devices::Enumeration;
+
+ref class ReencodeState sealed
+{
+public:
+    ReencodeState()
+    {
+    }
+
+    virtual ~ReencodeState()
+    {
+        if (InputStream != nullptr)
+        {
+            delete InputStream;
+        }
+        if (OutputStream != nullptr)
+        {
+            delete OutputStream;
+        }
+    }
+
+internal:
+    Windows::Storage::Streams::IRandomAccessStream ^InputStream;
+    Windows::Storage::Streams::IRandomAccessStream ^OutputStream;
+    Windows::Storage::StorageFile ^PhotoStorage;
+    Windows::Graphics::Imaging::BitmapDecoder ^Decoder;
+    Windows::Graphics::Imaging::BitmapEncoder ^Encoder;
+};
+
+AdvancedCapture::AdvancedCapture()
+{
+    InitializeComponent();
+    ScenarioInit();
+}
+
+/// <summary>
+/// Invoked when this page is about to be displayed in a Frame.
+/// </summary>
+/// <param name="e">Event data that describes how this page was reached.  The Parameter
+/// property is typically used to configure the page.</param>
+void AdvancedCapture::OnNavigatedTo(NavigationEventArgs^ e)
+{
+    // A pointer back to the main page.  This is needed if you want to call methods in MainPage such
+    // as NotifyUser()
+    rootPage = MainPage::Current;
+
+    m_orientationChangedEventToken = Windows::Graphics::Display::DisplayProperties::OrientationChanged += ref new Windows::Graphics::Display::DisplayPropertiesEventHandler(this, &AdvancedCapture::DisplayProperties_OrientationChanged);
+}
+
+void AdvancedCapture::OnNavigatedFrom(NavigationEventArgs^ e)
+{
+    Windows::Media::MediaControl::SoundLevelChanged -= m_eventRegistrationToken;
+    Windows::Graphics::Display::DisplayProperties::OrientationChanged  -= m_orientationChangedEventToken;
+}
+
+void  AdvancedCapture::ScenarioInit()
+{
+    rootPage = MainPage::Current;
+    btnStartDevice2->IsEnabled = true;
+    btnStartPreview2->IsEnabled = false;
+    m_bRecording = false;
+    m_bPreviewing = false;
+    m_bEffectAdded = false;
+    previewElement2->Source = nullptr;
+    ShowStatusMessage("");
+    EffectTypeCombo->IsEnabled = false;
+    previewCanvas2->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+    EnumerateWebcamsAsync();
+    m_bSuspended = false;
+}
+
+void AdvancedCapture::ScenarioReset()
+{
+    previewCanvas2->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+    ScenarioInit();
+}
+
+void AdvancedCapture::Failed(Windows::Media::Capture::MediaCapture ^currentCaptureObject, Windows::Media::Capture::MediaCaptureFailedEventArgs^ currentFailure)
+{
+    String ^message = "Fatal error" + currentFailure->Message;
+    create_task(Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::High,
+        ref new Windows::UI::Core::DispatchedHandler([this, message]()
+    {
+        ShowStatusMessage(message);
+    })));
+}
+
+void AdvancedCapture::btnStartDevice_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+    try
+    {
+        EnableButton(false, "StartDevice");
+        ShowStatusMessage("Starting device");
+        auto mediaCapture = ref new Windows::Media::Capture::MediaCapture();
+        m_mediaCaptureMgr = mediaCapture;
+        auto settings = ref new Windows::Media::Capture::MediaCaptureInitializationSettings();
+        auto chosenDevInfo = m_devInfoCollection->GetAt(EnumedDeviceList2->SelectedIndex);
+        settings->VideoDeviceId = chosenDevInfo->Id;
+        if (chosenDevInfo->EnclosureLocation != nullptr && chosenDevInfo->EnclosureLocation->Panel == Windows::Devices::Enumeration::Panel::Back)
+        {
+            m_bRotateVideoOnOrientationChange = true;
+            m_bReversePreviewRotation = false;
+        }
+        else if (chosenDevInfo->EnclosureLocation != nullptr && chosenDevInfo->EnclosureLocation->Panel == Windows::Devices::Enumeration::Panel::Front)
+        {
+            m_bRotateVideoOnOrientationChange = true;
+            m_bReversePreviewRotation = true;
+        }
+        else
+        {
+            m_bRotateVideoOnOrientationChange = false;
+        }
+
+        create_task(mediaCapture->InitializeAsync(settings)).then([this](task<void> initTask)
+        {
+            try
+            {
+                initTask.get();
+
+                auto mediaCapture =  m_mediaCaptureMgr.Get();
+
+                DisplayProperties_OrientationChanged(nullptr);
+
+                EnableButton(true, "StartPreview");
+                EnableButton(true, "StartStopRecord");
+                EnableButton(true, "TakePhoto");
+                ShowStatusMessage("Device initialized successful");
+                EffectTypeCombo->IsEnabled = true;
+                mediaCapture->Failed += ref new Windows::Media::Capture::MediaCaptureFailedEventHandler(this, &AdvancedCapture::Failed);
+            }
+            catch (Exception ^ e)
+            {
+                ShowExceptionMessage(e);
+            }
+        });
+    }
+    catch (Platform::Exception^ e)
+    {
+        ShowExceptionMessage(e);
+    }
+}
+
+void AdvancedCapture::btnStartPreview_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+    m_bPreviewing = false;
+    try
+    {
+        ShowStatusMessage("Starting preview");
+        EnableButton(false, "StartPreview");
+
+        auto mediaCapture = m_mediaCaptureMgr.Get();
+        previewCanvas2->Visibility = Windows::UI::Xaml::Visibility::Visible;
+        previewElement2->Source = mediaCapture;
+        create_task(mediaCapture->StartPreviewAsync()).then([this](task<void> previewTask)
+        {
+            try
+            {
+                previewTask.get();
+                m_bPreviewing = true;
+                ShowStatusMessage("Start preview successful");
+            }
+            catch (Exception ^e)
+            {
+                ShowExceptionMessage(e);
+            }
+        });
+    }
+    catch (Platform::Exception^ e)
+    {
+        m_bPreviewing = false;
+        previewElement2->Source = nullptr;
+        EnableButton(true, "StartPreview");
+        ShowExceptionMessage(e);
+    }
+}
+
+void AdvancedCapture::lstEnumedDevices_SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e)
+{
+     if ( m_bPreviewing )
+     {
+         create_task(m_mediaCaptureMgr->StopPreviewAsync()).then([this](task<void> previewTask)
+         {
+             try
+             {
+                 previewTask.get();
+                 m_bPreviewing = false;
+             }
+             catch (Exception ^e)
+             {
+                ShowExceptionMessage(e);
+             }
+         });
+    }
+
+    btnStartDevice2->IsEnabled = true;
+    btnStartPreview2->IsEnabled = false;
+    m_bRecording = false;
+    previewElement2->Source = nullptr;
+    EffectTypeCombo->IsEnabled = false;
+    m_bEffectAdded = false;
+    m_bEffectAddedToRecord = false;
+    m_bEffectAddedToPhoto = false;
+    ShowStatusMessage("");
+}
+
+void AdvancedCapture::EnumerateWebcamsAsync()
+{
+    try
+    {
+        ShowStatusMessage("Enumerating Webcams...");
+        m_devInfoCollection = nullptr;
+
+        EnumedDeviceList2->Items->Clear();
+
+        task<DeviceInformationCollection^>(DeviceInformation::FindAllAsync(DeviceClass::VideoCapture)).then([this](task<DeviceInformationCollection^> findTask)
+        {
+            try
+            {
+                m_devInfoCollection = findTask.get();
+                if (m_devInfoCollection == nullptr || m_devInfoCollection->Size == 0)
+                {
+                    ShowStatusMessage("No WebCams found.");
+                }
+                else
+                {
+                    for(unsigned int i = 0; i < m_devInfoCollection->Size; i++)
+                    {
+                        auto devInfo = m_devInfoCollection->GetAt(i);
+                        EnumedDeviceList2->Items->Append(devInfo->Name);
+                    }
+                    EnumedDeviceList2->SelectedIndex = 0;
+                    ShowStatusMessage("Enumerating Webcams completed successfully.");
+                    btnStartDevice2->IsEnabled = true;
+                }
+            }
+            catch (Exception ^e)
+            {
+                ShowExceptionMessage(e);
+            }
+        });
+    }
+    catch (Platform::Exception^ e)
+    {
+        ShowExceptionMessage(e);
+    }
+}
+
+void AdvancedCapture::AddEffectToImageStream()
+{
+    auto mediaCapture = m_mediaCaptureMgr.Get();
+    Windows::Media::Capture::VideoDeviceCharacteristic charecteristic = mediaCapture->MediaCaptureSettings->VideoDeviceCharacteristic;
+
+    if((charecteristic != Windows::Media::Capture::VideoDeviceCharacteristic::AllStreamsIdentical) &&
+        (charecteristic != Windows::Media::Capture::VideoDeviceCharacteristic::PreviewPhotoStreamsIdentical) &&
+        (charecteristic != Windows::Media::Capture::VideoDeviceCharacteristic::RecordPhotoStreamsIdentical))
+    {
+        Windows::Media::MediaProperties::IMediaEncodingProperties ^props = mediaCapture->VideoDeviceController->GetMediaStreamProperties(Windows::Media::Capture::MediaStreamType::Photo);
+        if(props->Type->Equals("Image"))
+        {
+            //Switch to a video media type instead since we cant add an effect to a image media type
+            Windows::Foundation::Collections::IVectorView<Windows::Media::MediaProperties::IMediaEncodingProperties^>^ supportedPropsList = mediaCapture->VideoDeviceController->GetAvailableMediaStreamProperties(Windows::Media::Capture::MediaStreamType::Photo);
+            {
+                unsigned int i = 0;
+                while (i < supportedPropsList->Size)
+                {
+                    Windows::Media::MediaProperties::IMediaEncodingProperties^ props = supportedPropsList->GetAt(i);
+
+                    String^ s = props->Type;
+                    if(props->Type->Equals("Video"))
+                    {
+                        task<void>(mediaCapture->VideoDeviceController->SetMediaStreamPropertiesAsync(Windows::Media::Capture::MediaStreamType::Photo,props)).then([this](task<void> changeTypeTask)
+                        {
+                            try
+                            {
+                                changeTypeTask.get();
+                                ShowStatusMessage("Change type on photo stream successful");
+                                //Now add the effect on the image pin
+                                task<void>(m_mediaCaptureMgr->AddEffectAsync(Windows::Media::Capture::MediaStreamType::Photo,"OcvTransform.OcvImageManipulations", nullptr)).then([this](task<void> effectTask3)
+                                {
+                                    try
+                                    {
+                                        effectTask3.get();
+                                        m_bEffectAddedToPhoto = true;
+                                        ShowStatusMessage("Adding effect to photo stream successful");
+                                        EffectTypeCombo->IsEnabled = true;
+
+                                    }
+                                    catch(Exception ^e)
+                                    {
+                                        ShowExceptionMessage(e);
+                                        EffectTypeCombo->IsEnabled = true;
+                                    }
+                                });
+
+                            }
+                            catch(Exception ^e)
+                            {
+                                ShowExceptionMessage(e);
+                                EffectTypeCombo->IsEnabled = true;
+                            }
+
+                        });
+                        break;
+
+                    }
+                    i++;
+                }
+            }
+        }
+        else
+        {
+            //Add the effect to the image pin if the type is already "Video"
+            task<void>(mediaCapture->AddEffectAsync(Windows::Media::Capture::MediaStreamType::Photo,"OcvTransform.OcvImageManipulations", nullptr)).then([this](task<void> effectTask3)
+            {
+                try
+                {
+                    effectTask3.get();
+                    m_bEffectAddedToPhoto = true;
+                    ShowStatusMessage("Adding effect to photo stream successful");
+                    EffectTypeCombo->IsEnabled = true;
+
+                }
+                catch(Exception ^e)
+                {
+                    ShowExceptionMessage(e);
+                    EffectTypeCombo->IsEnabled = true;
+                }
+            });
+        }
+    }
+}
+
+void AdvancedCapture::ShowStatusMessage(Platform::String^ text)
+{
+    rootPage->NotifyUser(text, NotifyType::StatusMessage);
+}
+
+void AdvancedCapture::ShowExceptionMessage(Platform::Exception^ ex)
+{
+    rootPage->NotifyUser(ex->Message, NotifyType::ErrorMessage);
+}
+
+void AdvancedCapture::EnableButton(bool enabled, String^ name)
+{
+    if (name->Equals("StartDevice"))
+    {
+        btnStartDevice2->IsEnabled = enabled;
+    }
+    else if (name->Equals("StartPreview"))
+    {
+        btnStartPreview2->IsEnabled = enabled;
+    }
+}
+
+task<Windows::Storage::StorageFile^> AdvancedCapture::ReencodePhotoAsync(
+    Windows::Storage::StorageFile ^tempStorageFile,
+    Windows::Storage::FileProperties::PhotoOrientation photoRotation)
+{
+    ReencodeState ^state = ref new ReencodeState();
+
+    return create_task(tempStorageFile->OpenAsync(Windows::Storage::FileAccessMode::Read)).then([state](Windows::Storage::Streams::IRandomAccessStream ^stream)
+    {
+        state->InputStream = stream;
+        return Windows::Graphics::Imaging::BitmapDecoder::CreateAsync(state->InputStream);
+    }).then([state](Windows::Graphics::Imaging::BitmapDecoder ^decoder)
+    {
+        state->Decoder = decoder;
+        return Windows::Storage::KnownFolders::PicturesLibrary->CreateFileAsync(PHOTO_FILE_NAME, Windows::Storage::CreationCollisionOption::GenerateUniqueName);
+    }).then([state](Windows::Storage::StorageFile ^storageFile)
+    {
+        state->PhotoStorage = storageFile;
+        return state->PhotoStorage->OpenAsync(Windows::Storage::FileAccessMode::ReadWrite);
+    }).then([state](Windows::Storage::Streams::IRandomAccessStream ^stream)
+    {
+        state->OutputStream = stream;
+        state->OutputStream->Size = 0;
+        return Windows::Graphics::Imaging::BitmapEncoder::CreateForTranscodingAsync(state->OutputStream, state->Decoder);
+    }).then([state, photoRotation](Windows::Graphics::Imaging::BitmapEncoder ^encoder)
+    {
+        state->Encoder = encoder;
+        auto properties = ref new Windows::Graphics::Imaging::BitmapPropertySet();
+        properties->Insert("System.Photo.Orientation",
+            ref new Windows::Graphics::Imaging::BitmapTypedValue((unsigned short)photoRotation, Windows::Foundation::PropertyType::UInt16));
+        return create_task(state->Encoder->BitmapProperties->SetPropertiesAsync(properties));
+    }).then([state]()
+    {
+        return state->Encoder->FlushAsync();
+    }).then([tempStorageFile, state](task<void> previousTask)
+    {
+        auto result = state->PhotoStorage;
+        delete state;
+
+        tempStorageFile->DeleteAsync(Windows::Storage::StorageDeleteOption::PermanentDelete);
+
+        previousTask.get();
+
+        return result;
+    });
+}
+
+Windows::Storage::FileProperties::PhotoOrientation AdvancedCapture::GetCurrentPhotoRotation()
+{
+    bool counterclockwiseRotation = m_bReversePreviewRotation;
+
+    if (m_bRotateVideoOnOrientationChange)
+    {
+        return PhotoRotationLookup(Windows::Graphics::Display::DisplayProperties::CurrentOrientation, counterclockwiseRotation);
+    }
+    else
+    {
+        return Windows::Storage::FileProperties::PhotoOrientation::Normal;
+    }
+}
+
+void AdvancedCapture::PrepareForVideoRecording()
+{
+    Windows::Media::Capture::MediaCapture ^mediaCapture = m_mediaCaptureMgr.Get();
+    if (mediaCapture == nullptr)
+    {
+        return;
+    }
+
+    bool counterclockwiseRotation = m_bReversePreviewRotation;
+
+    if (m_bRotateVideoOnOrientationChange)
+    {
+        mediaCapture->SetRecordRotation(VideoRotationLookup(Windows::Graphics::Display::DisplayProperties::CurrentOrientation, counterclockwiseRotation));
+    }
+    else
+    {
+        mediaCapture->SetRecordRotation(Windows::Media::Capture::VideoRotation::None);
+    }
+}
+
+void AdvancedCapture::DisplayProperties_OrientationChanged(Platform::Object^ sender)
+{
+    Windows::Media::Capture::MediaCapture ^mediaCapture = m_mediaCaptureMgr.Get();
+    if (mediaCapture == nullptr)
+    {
+        return;
+    }
+
+    bool previewMirroring = mediaCapture->GetPreviewMirroring();
+    bool counterclockwiseRotation = (previewMirroring && !m_bReversePreviewRotation) ||
+        (!previewMirroring && m_bReversePreviewRotation);
+
+    if (m_bRotateVideoOnOrientationChange)
+    {
+        mediaCapture->SetPreviewRotation(VideoRotationLookup(Windows::Graphics::Display::DisplayProperties::CurrentOrientation, counterclockwiseRotation));
+    }
+    else
+    {
+        mediaCapture->SetPreviewRotation(Windows::Media::Capture::VideoRotation::None);
+    }
+}
+
+Windows::Storage::FileProperties::PhotoOrientation AdvancedCapture::PhotoRotationLookup(
+    Windows::Graphics::Display::DisplayOrientations displayOrientation, bool counterclockwise)
+{
+    switch (displayOrientation)
+    {
+    case Windows::Graphics::Display::DisplayOrientations::Landscape:
+        return Windows::Storage::FileProperties::PhotoOrientation::Normal;
+
+    case Windows::Graphics::Display::DisplayOrientations::Portrait:
+        return (counterclockwise) ? Windows::Storage::FileProperties::PhotoOrientation::Rotate270:
+            Windows::Storage::FileProperties::PhotoOrientation::Rotate90;
+
+    case Windows::Graphics::Display::DisplayOrientations::LandscapeFlipped:
+        return Windows::Storage::FileProperties::PhotoOrientation::Rotate180;
+
+    case Windows::Graphics::Display::DisplayOrientations::PortraitFlipped:
+        return (counterclockwise) ? Windows::Storage::FileProperties::PhotoOrientation::Rotate90 :
+            Windows::Storage::FileProperties::PhotoOrientation::Rotate270;
+
+    default:
+        return Windows::Storage::FileProperties::PhotoOrientation::Unspecified;
+    }
+}
+
+Windows::Media::Capture::VideoRotation AdvancedCapture::VideoRotationLookup(
+    Windows::Graphics::Display::DisplayOrientations displayOrientation, bool counterclockwise)
+{
+    switch (displayOrientation)
+    {
+    case Windows::Graphics::Display::DisplayOrientations::Landscape:
+        return Windows::Media::Capture::VideoRotation::None;
+
+    case Windows::Graphics::Display::DisplayOrientations::Portrait:
+        return (counterclockwise) ? Windows::Media::Capture::VideoRotation::Clockwise270Degrees :
+            Windows::Media::Capture::VideoRotation::Clockwise90Degrees;
+
+    case Windows::Graphics::Display::DisplayOrientations::LandscapeFlipped:
+        return Windows::Media::Capture::VideoRotation::Clockwise180Degrees;
+
+    case Windows::Graphics::Display::DisplayOrientations::PortraitFlipped:
+        return (counterclockwise) ? Windows::Media::Capture::VideoRotation::Clockwise90Degrees:
+            Windows::Media::Capture::VideoRotation::Clockwise270Degrees ;
+
+    default:
+        return Windows::Media::Capture::VideoRotation::None;
+    }
+}
+
+void SDKSample::MediaCapture::AdvancedCapture::Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+    try
+    {
+        create_task(m_mediaCaptureMgr->ClearEffectsAsync(Windows::Media::Capture::MediaStreamType::VideoPreview)).then([this](task<void> cleanTask)
+        {
+            m_bEffectAdded = true;
+            int index = EffectTypeCombo->SelectedIndex;
+            PropertySet^ props = ref new PropertySet();
+            props->Insert(L"{698649BE-8EAE-4551-A4CB-3EC98FBD3D86}", index);
+            create_task(m_mediaCaptureMgr->AddEffectAsync(Windows::Media::Capture::MediaStreamType::VideoPreview,"OcvTransform.OcvImageManipulations", props)).then([this](task<void> effectTask)
+            {
+                try
+                {
+                    effectTask.get();
+
+                    auto mediaCapture = m_mediaCaptureMgr.Get();
+                    Windows::Media::Capture::VideoDeviceCharacteristic charecteristic = mediaCapture->MediaCaptureSettings->VideoDeviceCharacteristic;
+
+                    ShowStatusMessage("Add effect successful to preview stream successful");
+                    if((charecteristic != Windows::Media::Capture::VideoDeviceCharacteristic::AllStreamsIdentical) &&
+                        (charecteristic != Windows::Media::Capture::VideoDeviceCharacteristic::PreviewRecordStreamsIdentical))
+                    {
+                        Windows::Media::MediaProperties::IMediaEncodingProperties ^props = mediaCapture->VideoDeviceController->GetMediaStreamProperties(Windows::Media::Capture::MediaStreamType::VideoRecord);
+                        Windows::Media::MediaProperties::VideoEncodingProperties ^videoEncodingProperties  = static_cast<Windows::Media::MediaProperties::VideoEncodingProperties ^>(props);
+                        if(!videoEncodingProperties->Subtype->Equals("H264")) //Cant add an effect to an H264 stream
+                        {
+                            task<void>(mediaCapture->AddEffectAsync(Windows::Media::Capture::MediaStreamType::VideoRecord,"OcvTransform.OcvImageManipulations", nullptr)).then([this](task<void> effectTask2)
+                            {
+                                try
+                                {
+                                    effectTask2.get();
+                                    ShowStatusMessage("Add effect successful to record stream successful");
+                                    m_bEffectAddedToRecord = true;
+                                    AddEffectToImageStream();
+                                    EffectTypeCombo->IsEnabled = true;
+                                }
+                                catch(Exception ^e)
+                                {
+                                    ShowExceptionMessage(e);
+                                    EffectTypeCombo->IsEnabled = true;
+                                }
+                            });
+                        }
+                        else
+                        {
+                            AddEffectToImageStream();
+                            EffectTypeCombo->IsEnabled = true;
+                        }
+
+                    }
+                    else
+                    {
+                        AddEffectToImageStream();
+                        EffectTypeCombo->IsEnabled = true;
+                    }
+                }
+                catch (Exception ^e)
+                {
+                    ShowExceptionMessage(e);
+                    EffectTypeCombo->IsEnabled = true;
+                }
+            });
+        });
+    }
+    catch (Platform::Exception ^e)
+    {
+        ShowExceptionMessage(e);
+        EffectTypeCombo->IsEnabled = true;
+    }
+}
diff --git a/samples/winrt/ImageManipulations/AdvancedCapture.xaml.h b/samples/winrt/ImageManipulations/AdvancedCapture.xaml.h
new file mode 100644 (file)
index 0000000..94fa87c
--- /dev/null
@@ -0,0 +1,95 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+//
+// AdvancedCapture.xaml.h
+// Declaration of the AdvancedCapture class
+//
+
+#pragma once
+
+#include "pch.h"
+#include "AdvancedCapture.g.h"
+#include "MainPage.xaml.h"
+#include <ppl.h>
+
+#define VIDEO_FILE_NAME "video.mp4"
+#define PHOTO_FILE_NAME "photo.jpg"
+#define TEMP_PHOTO_FILE_NAME "photoTmp.jpg"
+
+using namespace concurrency;
+using namespace Windows::Devices::Enumeration;
+
+namespace SDKSample
+{
+    namespace MediaCapture
+    {
+        /// <summary>
+        /// An empty page that can be used on its own or navigated to within a Frame.
+        /// </summary>
+        [Windows::Foundation::Metadata::WebHostHidden]
+        public ref class AdvancedCapture sealed
+        {
+        public:
+            AdvancedCapture();
+
+        protected:
+            virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
+            virtual void OnNavigatedFrom(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
+
+        private:
+            MainPage^ rootPage;
+            void ScenarioInit();
+            void ScenarioReset();
+
+            void Failed(Windows::Media::Capture::MediaCapture ^ mediaCapture, Windows::Media::Capture::MediaCaptureFailedEventArgs ^ args);
+
+            void btnStartDevice_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+
+            void btnStartPreview_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+
+            void lstEnumedDevices_SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e);
+            void EnumerateWebcamsAsync();
+
+            void AddEffectToImageStream();
+
+            void ShowStatusMessage(Platform::String^ text);
+            void ShowExceptionMessage(Platform::Exception^ ex);
+
+            void EnableButton(bool enabled, Platform::String ^name);
+
+            task<Windows::Storage::StorageFile^> ReencodePhotoAsync(
+                Windows::Storage::StorageFile ^tempStorageFile,
+                Windows::Storage::FileProperties::PhotoOrientation photoRotation);
+            Windows::Storage::FileProperties::PhotoOrientation GetCurrentPhotoRotation();
+            void PrepareForVideoRecording();
+            void DisplayProperties_OrientationChanged(Platform::Object^ sender);
+            Windows::Storage::FileProperties::PhotoOrientation PhotoRotationLookup(
+                Windows::Graphics::Display::DisplayOrientations displayOrientation, bool counterclockwise);
+            Windows::Media::Capture::VideoRotation VideoRotationLookup(
+                Windows::Graphics::Display::DisplayOrientations displayOrientation, bool counterclockwise);
+
+            Platform::Agile<Windows::Media::Capture::MediaCapture> m_mediaCaptureMgr;
+            Windows::Storage::StorageFile^ m_recordStorageFile;
+            bool m_bRecording;
+            bool m_bEffectAdded;
+            bool m_bEffectAddedToRecord;
+            bool m_bEffectAddedToPhoto;
+            bool m_bSuspended;
+            bool m_bPreviewing;
+            DeviceInformationCollection^ m_devInfoCollection;
+            Windows::Foundation::EventRegistrationToken m_eventRegistrationToken;
+            bool m_bRotateVideoOnOrientationChange;
+            bool m_bReversePreviewRotation;
+            Windows::Foundation::EventRegistrationToken m_orientationChangedEventToken;
+            void Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+        };
+    }
+}
diff --git a/samples/winrt/ImageManipulations/App.xaml b/samples/winrt/ImageManipulations/App.xaml
new file mode 100644 (file)
index 0000000..2edfd77
--- /dev/null
@@ -0,0 +1,30 @@
+<!--
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+-->
+
+<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
+    x:Class="SDKSample.App"
+    RequestedTheme="Light">
+    <Application.Resources>
+
+        <ResourceDictionary>
+            <ResourceDictionary.MergedDictionaries>
+                <!-- 
+                    Styles that define common aspects of the platform look and feel
+                    Required by Visual Studio project and item templates
+                 -->
+                <ResourceDictionary Source="Common/StandardStyles.xaml"/>
+                <ResourceDictionary Source="Sample-Utils/SampleTemplateStyles.xaml"/>
+            </ResourceDictionary.MergedDictionaries>
+        </ResourceDictionary>
+    </Application.Resources>
+</Application>
diff --git a/samples/winrt/ImageManipulations/App.xaml.cpp b/samples/winrt/ImageManipulations/App.xaml.cpp
new file mode 100644 (file)
index 0000000..a24a4f9
--- /dev/null
@@ -0,0 +1,116 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+//
+// App.xaml.cpp
+// Implementation of the App.xaml class.
+//
+
+#include "pch.h"
+#include "MainPage.xaml.h"
+#include "AdvancedCapture.xaml.h"
+#include "Common\SuspensionManager.h"
+
+using namespace SDKSample;
+using namespace SDKSample::Common;
+using namespace SDKSample::MediaCapture;
+
+using namespace Concurrency;
+using namespace Platform;
+using namespace Windows::ApplicationModel;
+using namespace Windows::ApplicationModel::Activation;
+using namespace Windows::Foundation;
+using namespace Windows::Foundation::Collections;
+using namespace Windows::UI::Core;
+using namespace Windows::UI::Xaml;
+using namespace Windows::UI::Xaml::Controls;
+using namespace Windows::UI::Xaml::Controls::Primitives;
+using namespace Windows::UI::Xaml::Data;
+using namespace Windows::UI::Xaml::Input;
+using namespace Windows::UI::Xaml::Interop;
+using namespace Windows::UI::Xaml::Media;
+using namespace Windows::UI::Xaml::Navigation;
+
+/// <summary>
+/// Initializes the singleton application object.  This is the first line of authored code
+/// executed, and as such is the logical equivalent of main() or WinMain().
+/// </summary>
+App::App()
+{
+    InitializeComponent();
+    this->Suspending += ref new SuspendingEventHandler(this, &SDKSample::App::OnSuspending);
+}
+
+/// <summary>
+/// Invoked when the application is launched normally by the end user.  Other entry points will
+/// be used when the application is launched to open a specific file, to display search results,
+/// and so forth.
+/// </summary>
+/// <param name="pArgs">Details about the launch request and process.</param>
+void App::OnLaunched(LaunchActivatedEventArgs^ pArgs)
+{
+    this->LaunchArgs = pArgs;
+
+    // Do not repeat app initialization when already running, just ensure that
+    // the window is active
+    if (pArgs->PreviousExecutionState == ApplicationExecutionState::Running)
+    {
+        Window::Current->Activate();
+        return;
+    }
+
+    // Create a Frame to act as the navigation context and associate it with
+    // a SuspensionManager key
+    auto rootFrame = ref new Frame();
+    SuspensionManager::RegisterFrame(rootFrame, "AppFrame");
+
+    auto prerequisite = task<void>([](){});
+    if (pArgs->PreviousExecutionState == ApplicationExecutionState::Terminated)
+    {
+        // Restore the saved session state only when appropriate, scheduling the
+        // final launch steps after the restore is complete
+        prerequisite = SuspensionManager::RestoreAsync();
+    }
+    prerequisite.then([=]()
+    {
+        // When the navigation stack isn't restored navigate to the first page,
+        // configuring the new page by passing required information as a navigation
+        // parameter
+        if (rootFrame->Content == nullptr)
+        {
+            if (!rootFrame->Navigate(TypeName(MainPage::typeid)))
+            {
+                throw ref new FailureException("Failed to create initial page");
+            }
+        }
+
+        // Place the frame in the current Window and ensure that it is active
+        Window::Current->Content = rootFrame;
+        Window::Current->Activate();
+    }, task_continuation_context::use_current());
+}
+
+/// <summary>
+/// Invoked when application execution is being suspended.  Application state is saved
+/// without knowing whether the application will be terminated or resumed with the contents
+/// of memory still intact.
+/// </summary>
+/// <param name="sender">The source of the suspend request.</param>
+/// <param name="e">Details about the suspend request.</param>
+void App::OnSuspending(Object^ sender, SuspendingEventArgs^ e)
+{
+    (void) sender;     // Unused parameter
+
+    auto deferral = e->SuspendingOperation->GetDeferral();
+    SuspensionManager::SaveAsync().then([=]()
+    {
+        deferral->Complete();
+    });
+}
diff --git a/samples/winrt/ImageManipulations/App.xaml.h b/samples/winrt/ImageManipulations/App.xaml.h
new file mode 100644 (file)
index 0000000..a8b6064
--- /dev/null
@@ -0,0 +1,35 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+//
+// App.xaml.h
+// Declaration of the App.xaml class.
+//
+
+#pragma once
+
+#include "pch.h"
+#include "App.g.h"
+#include "MainPage.g.h"
+
+namespace SDKSample
+{
+    ref class App
+    {
+    internal:
+        App();
+        virtual void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ pArgs);
+        Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ LaunchArgs;
+    protected:
+        virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ pArgs) override;
+    private:
+        Windows::UI::Xaml::Controls::Frame^ rootFrame;
+    };
+}
diff --git a/samples/winrt/ImageManipulations/Constants.cpp b/samples/winrt/ImageManipulations/Constants.cpp
new file mode 100644 (file)
index 0000000..a266342
--- /dev/null
@@ -0,0 +1,22 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+#include "pch.h"
+#include "MainPage.xaml.h"
+#include "Constants.h"
+
+using namespace SDKSample;
+
+Platform::Array<Scenario>^ MainPage::scenariosInner = ref new Platform::Array<Scenario>
+{
+    // The format here is the following:
+    //     { "Description for the sample", "Fully quaified name for the class that implements the scenario" }
+    { "Enumerate cameras and add a video effect", "SDKSample.MediaCapture.AdvancedCapture" },
+};
diff --git a/samples/winrt/ImageManipulations/Constants.h b/samples/winrt/ImageManipulations/Constants.h
new file mode 100644 (file)
index 0000000..143f069
--- /dev/null
@@ -0,0 +1,45 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+#pragma once
+
+#include <collection.h>
+namespace SDKSample
+{
+    public value struct Scenario
+    {
+        Platform::String^ Title;
+        Platform::String^ ClassName;
+    };
+
+    partial ref class MainPage
+    {
+    public:
+        static property Platform::String^ FEATURE_NAME
+        {
+            Platform::String^ get()
+            {
+                return ref new Platform::String(L"OpenCV Image Manipulations sample");
+            }
+        }
+
+        static property Platform::Array<Scenario>^ scenarios
+        {
+            Platform::Array<Scenario>^ get()
+            {
+                return scenariosInner;
+            }
+        }
+    private:
+        static Platform::Array<Scenario>^ scenariosInner;
+    };
+
+
+}
diff --git a/samples/winrt/ImageManipulations/MainPage.xaml b/samples/winrt/ImageManipulations/MainPage.xaml
new file mode 100644 (file)
index 0000000..e0ed0d7
--- /dev/null
@@ -0,0 +1,156 @@
+<!--
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+-->
+
+<common:LayoutAwarePage 
+    x:Class="SDKSample.MainPage"
+    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+    xmlns:common="using:SDKSample.Common"
+    mc:Ignorable="d"
+    x:Name="RootPage">
+
+    <common:LayoutAwarePage.Resources>
+        <Style x:Key="BaseStatusStyle" TargetType="TextBlock">
+            <Setter Property="FontFamily" Value="Segoe UI Semilight"/>
+            <Setter Property="FontSize" Value="14.667"/>
+            <Setter Property="Margin" Value="0,0,0,5"/>
+        </Style>
+        <Style x:Key="StatusStyle" BasedOn="{StaticResource BaseStatusStyle}" TargetType="TextBlock">
+            <Setter Property="Foreground" Value="Green"/>
+        </Style>
+        <Style x:Key="ErrorStyle" BasedOn="{StaticResource BaseStatusStyle}" TargetType="TextBlock">
+            <Setter Property="Foreground" Value="Blue"/>
+        </Style>
+    </common:LayoutAwarePage.Resources>
+
+
+    <Grid x:Name="LayoutRoot" Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
+
+        <Grid x:Name="ContentRoot" Background="{StaticResource ApplicationPageBackgroundThemeBrush}" Margin="100,20,100,20">
+            <Grid.RowDefinitions>
+                <RowDefinition Height="Auto"/>
+                <RowDefinition Height="*"/>
+                <RowDefinition Height="Auto"/>
+            </Grid.RowDefinitions>
+
+            <!-- Header -->
+            <StackPanel Orientation="Horizontal" Grid.Row="0">
+                <Image x:Name="WindowsLogo" Stretch="None" Source="Assets/windows-sdk.png" AutomationProperties.Name="Windows Logo" HorizontalAlignment="Left" Grid.Column="0"/>
+                <TextBlock VerticalAlignment="Bottom" Style="{StaticResource TitleTextStyle}" TextWrapping="Wrap" Grid.Column="1" Text="OpenCV for Windows RT"/>
+            </StackPanel>
+            <ScrollViewer x:Name="MainScrollViewer" Grid.Row="1" ZoomMode="Disabled" IsTabStop="False" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Padding="0,0,0,20" >
+                <Grid>
+                    <Grid.RowDefinitions>
+                        <RowDefinition Height="Auto"/>
+                        <RowDefinition Height="*"/>
+                    </Grid.RowDefinitions>
+                    <TextBlock x:Name="FeatureName" Grid.Row="0"  Text="Add Sample Title Here" Style="{StaticResource HeaderTextStyle}" TextWrapping="Wrap"/>
+
+                    <!-- Content -->
+                    <Grid Grid.Row="1">
+
+                        <!-- All XAML in this section is purely for design time so you can see sample content in the designer. -->
+                        <!-- This will be repaced at runtime by live content.                                                  -->
+                        <Grid>
+                            <Grid.RowDefinitions>
+                                <RowDefinition Height="Auto"/>
+                                <RowDefinition Height="Auto"/>
+                                <RowDefinition Height="Auto"/>
+                                <RowDefinition Height="Auto"/>
+                                <RowDefinition Height="Auto"/>
+                                <RowDefinition Height="Auto"/>
+                                <RowDefinition Height="Auto"/>
+                                <RowDefinition Height="*"/>
+                            </Grid.RowDefinitions>
+                            <Grid.ColumnDefinitions>
+                                <ColumnDefinition Width="Auto"/>
+                                <ColumnDefinition Width="*"/>
+                            </Grid.ColumnDefinitions>
+                            <TextBlock Grid.Row="0" Text="Input" Style="{StaticResource H2Style}"/>
+
+                            <TextBlock x:Name="ScenarioListLabel" Text="Select Scenario:" Grid.Row="1"  Style="{StaticResource SubheaderTextStyle}" Margin="0,5,0,0" />
+                            <ListBox x:Name="Scenarios" Margin="0,0,20,0" Grid.Row="2" AutomationProperties.Name="Scenarios" HorizontalAlignment="Left" 
+                                         VerticalAlignment="Top" ScrollViewer.HorizontalScrollBarVisibility="Auto"
+                                         AutomationProperties.LabeledBy="{Binding ElementName=ScenarioListLabel}" MaxHeight="125">
+                                <ListBox.ItemTemplate>
+                                    <DataTemplate>
+                                        <TextBlock Text="{Binding Name}"/>
+                                    </DataTemplate>
+                                </ListBox.ItemTemplate>
+                            </ListBox>
+                            <TextBlock x:Name="DescriptionText" Margin="0,5,0,0" Text="Description:" Style="{StaticResource SubheaderTextStyle}" Grid.Row="1" Grid.Column="1"/>
+                            <!-- Input Scenarios -->
+                            <UserControl x:Name="InputSection" Margin="0,5,0,0" IsTabStop="False" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top"/>
+
+                            <!-- Output section -->
+                            <TextBlock Text="Output" Grid.Row="5"  Margin="0,25,0,20" Style="{StaticResource H2Style}" Grid.ColumnSpan="2"/>
+                            <TextBlock x:Name="StatusBlock" Grid.Row="6" Margin="0,0,0,5" Grid.ColumnSpan="2"/>
+
+                            <!-- Output Scenarios -->
+                            <UserControl x:Name="OutputSection" Grid.Row="7" Grid.ColumnSpan="2" BorderThickness="0"/>
+                        </Grid>
+                    </Grid>
+                </Grid>
+            </ScrollViewer>
+
+            <!-- Footer -->
+            <Grid x:Name="Footer"  Grid.Row="3" Margin="0,10,0,10" VerticalAlignment="Bottom" >
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="Auto"/>
+                    <RowDefinition Height="Auto"/>
+                    <RowDefinition Height="Auto"/>
+                </Grid.RowDefinitions>
+
+                <Grid.ColumnDefinitions>
+                    <ColumnDefinition Width="Auto"/>
+                    <ColumnDefinition Width="*"/>
+                </Grid.ColumnDefinitions>
+                <StackPanel x:Name="FooterPanel" Orientation="Horizontal" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right"/>
+            </Grid>
+
+
+        </Grid>
+
+        <VisualStateManager.VisualStateGroups>
+            <!-- Visual states reflect the application's view state -->
+            <VisualStateGroup>
+                <VisualState x:Name="FullScreenLandscape">
+                    <Storyboard>
+                    </Storyboard>
+                </VisualState>
+                <VisualState x:Name="Filled">
+                    <Storyboard>
+                    </Storyboard>
+                </VisualState>
+
+                <VisualState x:Name="FullScreenPortrait">
+                    <Storyboard>
+                    </Storyboard>
+                </VisualState>
+
+                <VisualState x:Name="Snapped">
+                    <Storyboard>
+                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="ContentRoot">
+                            <DiscreteObjectKeyFrame KeyTime="0">
+                                <DiscreteObjectKeyFrame.Value>
+                                    <Thickness>20,20,20,20</Thickness>
+                                </DiscreteObjectKeyFrame.Value>
+                            </DiscreteObjectKeyFrame>
+                        </ObjectAnimationUsingKeyFrames>
+                    </Storyboard>
+                </VisualState>
+            </VisualStateGroup>
+        </VisualStateManager.VisualStateGroups>
+    </Grid>
+</common:LayoutAwarePage>
diff --git a/samples/winrt/ImageManipulations/MainPage.xaml.cpp b/samples/winrt/ImageManipulations/MainPage.xaml.cpp
new file mode 100644 (file)
index 0000000..bd897fc
--- /dev/null
@@ -0,0 +1,315 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+//
+// MainPage.xaml.cpp
+// Implementation of the MainPage.xaml class.
+//
+
+#include "pch.h"
+#include "MainPage.xaml.h"
+#include "App.xaml.h"
+
+#include <collection.h>
+
+using namespace Windows::UI::Xaml;
+using namespace Windows::UI::Xaml::Controls;
+using namespace Windows::Foundation;
+using namespace Windows::Foundation::Collections;
+using namespace Platform;
+using namespace SDKSample;
+using namespace Windows::UI::Xaml::Navigation;
+using namespace Windows::UI::Xaml::Interop;
+using namespace Windows::Graphics::Display;
+using namespace Windows::UI::ViewManagement;
+
+MainPage^ MainPage::Current = nullptr;
+
+MainPage::MainPage()
+{
+    InitializeComponent();
+
+    // This frame is hidden, meaning it is never shown.  It is simply used to load
+    // each scenario page and then pluck out the input and output sections and
+    // place them into the UserControls on the main page.
+    HiddenFrame = ref new Windows::UI::Xaml::Controls::Frame();
+    HiddenFrame->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+    ContentRoot->Children->Append(HiddenFrame);
+
+    FeatureName->Text = FEATURE_NAME;
+
+    this->SizeChanged += ref new SizeChangedEventHandler(this, &MainPage::MainPage_SizeChanged);
+    Scenarios->SelectionChanged += ref new SelectionChangedEventHandler(this, &MainPage::Scenarios_SelectionChanged);
+
+    MainPage::Current = this;
+    autoSizeInputSectionWhenSnapped = true;
+}
+
+/// <summary>
+/// We need to handle SizeChanged so that we can make the sample layout property
+/// in the various layouts.
+/// </summary>
+/// <param name="sender"></param>
+/// <param name="e"></param>
+void MainPage::MainPage_SizeChanged(Object^ sender, SizeChangedEventArgs^ e)
+{
+    InvalidateSize();
+    MainPageSizeChangedEventArgs^ args = ref new MainPageSizeChangedEventArgs();
+    args->ViewState = ApplicationView::Value;
+    MainPageResized(this, args);
+
+}
+
+void MainPage::InvalidateSize()
+{
+    // Get the window width
+    double windowWidth = this->ActualWidth;
+
+    if (windowWidth != 0.0)
+    {
+        // Get the width of the ListBox.
+        double listBoxWidth = Scenarios->ActualWidth;
+
+        // Is the ListBox using any margins that we need to consider?
+        double listBoxMarginLeft = Scenarios->Margin.Left;
+        double listBoxMarginRight = Scenarios->Margin.Right;
+
+        // Figure out how much room is left after considering the list box width
+        double availableWidth = windowWidth - listBoxWidth;
+
+        // Is the top most child using margins?
+        double layoutRootMarginLeft = ContentRoot->Margin.Left;
+        double layoutRootMarginRight = ContentRoot->Margin.Right;
+
+        // We have different widths to use depending on the view state
+        if (ApplicationView::Value != ApplicationViewState::Snapped)
+        {
+            // Make us as big as the the left over space, factoring in the ListBox width, the ListBox margins.
+            // and the LayoutRoot's margins
+            InputSection->Width = ((availableWidth) -
+                (layoutRootMarginLeft + layoutRootMarginRight + listBoxMarginLeft + listBoxMarginRight));
+        }
+        else
+        {
+            // Make us as big as the left over space, factoring in just the LayoutRoot's margins.
+            if (autoSizeInputSectionWhenSnapped)
+            {
+                InputSection->Width = (windowWidth - (layoutRootMarginLeft + layoutRootMarginRight));
+            }
+        }
+    }
+    InvalidateViewState();
+}
+
+void MainPage::InvalidateViewState()
+{
+    // Are we going to snapped mode?
+    if (ApplicationView::Value == ApplicationViewState::Snapped)
+    {
+        Grid::SetRow(DescriptionText, 3);
+        Grid::SetColumn(DescriptionText, 0);
+
+        Grid::SetRow(InputSection, 4);
+        Grid::SetColumn(InputSection, 0);
+
+        Grid::SetRow(FooterPanel, 2);
+        Grid::SetColumn(FooterPanel, 0);
+    }
+    else
+    {
+        Grid::SetRow(DescriptionText, 1);
+        Grid::SetColumn(DescriptionText, 1);
+
+        Grid::SetRow(InputSection, 2);
+        Grid::SetColumn(InputSection, 1);
+
+        Grid::SetRow(FooterPanel, 1);
+        Grid::SetColumn(FooterPanel, 1);
+    }
+
+    //  Since we don't load the scenario page in the traditional manner (we just pluck out the
+    // input and output sections from the page) we need to ensure that any VSM code used
+    // by the scenario's input and output sections is fired.
+    VisualStateManager::GoToState(InputSection, "Input" + LayoutAwarePage::DetermineVisualState(ApplicationView::Value), false);
+    VisualStateManager::GoToState(OutputSection, "Output" + LayoutAwarePage::DetermineVisualState(ApplicationView::Value), false);
+}
+
+void MainPage::PopulateScenarios()
+{
+    ScenarioList = ref new Platform::Collections::Vector<Object^>();
+
+    // Populate the ListBox with the list of scenarios as defined in Constants.cpp.
+    for (unsigned int i = 0; i < scenarios->Length; ++i)
+    {
+        Scenario s = scenarios[i];
+        ListBoxItem^ item = ref new ListBoxItem();
+        item->Name = s.ClassName;
+        item->Content = (i + 1).ToString() + ") " + s.Title;
+        ScenarioList->Append(item);
+    }
+
+    // Bind the ListBox to the scenario list.
+    Scenarios->ItemsSource = ScenarioList;
+    Scenarios->ScrollIntoView(Scenarios->SelectedItem);
+}
+
+/// <summary>
+/// This method is responsible for loading the individual input and output sections for each scenario.  This
+/// is based on navigating a hidden Frame to the ScenarioX.xaml page and then extracting out the input
+/// and output sections into the respective UserControl on the main page.
+/// </summary>
+/// <param name="scenarioName"></param>
+void MainPage::LoadScenario(String^ scenarioName)
+{
+    autoSizeInputSectionWhenSnapped = true;
+
+    // Load the ScenarioX.xaml file into the Frame.
+    TypeName scenarioType = {scenarioName, TypeKind::Custom};
+    HiddenFrame->Navigate(scenarioType, this);
+
+    // Get the top element, the Page, so we can look up the elements
+    // that represent the input and output sections of the ScenarioX file.
+    Page^ hiddenPage = safe_cast<Page^>(HiddenFrame->Content);
+
+    // Get each element.
+    UIElement^ input = safe_cast<UIElement^>(hiddenPage->FindName("Input"));
+    UIElement^ output = safe_cast<UIElement^>(hiddenPage->FindName("Output"));
+
+    if (input == nullptr)
+    {
+        // Malformed input section.
+        NotifyUser("Cannot load scenario input section for " + scenarioName +
+            "  Make sure root of input section markup has x:Name of 'Input'", NotifyType::ErrorMessage);
+        return;
+    }
+
+    if (output == nullptr)
+    {
+        // Malformed output section.
+        NotifyUser("Cannot load scenario output section for " + scenarioName +
+            "  Make sure root of output section markup has x:Name of 'Output'", NotifyType::ErrorMessage);
+        return;
+    }
+
+    // Find the LayoutRoot which parents the input and output sections in the main page.
+    Panel^ panel = safe_cast<Panel^>(hiddenPage->FindName("LayoutRoot"));
+
+    if (panel != nullptr)
+    {
+        unsigned int index = 0;
+        UIElementCollection^ collection = panel->Children;
+
+        // Get rid of the content that is currently in the intput and output sections.
+        collection->IndexOf(input, &index);
+        collection->RemoveAt(index);
+
+        collection->IndexOf(output, &index);
+        collection->RemoveAt(index);
+
+        // Populate the input and output sections with the newly loaded content.
+        InputSection->Content = input;
+        OutputSection->Content = output;
+
+        ScenarioLoaded(this, nullptr);
+    }
+    else
+    {
+        // Malformed Scenario file.
+        NotifyUser("Cannot load scenario: " + scenarioName + ".  Make sure root tag in the '" +
+            scenarioName + "' file has an x:Name of 'LayoutRoot'", NotifyType::ErrorMessage);
+    }
+}
+
+void MainPage::Scenarios_SelectionChanged(Object^ sender, SelectionChangedEventArgs^ e)
+{
+    if (Scenarios->SelectedItem != nullptr)
+    {
+        NotifyUser("", NotifyType::StatusMessage);
+
+        LoadScenario((safe_cast<ListBoxItem^>(Scenarios->SelectedItem))->Name);
+        InvalidateSize();
+    }
+}
+
+void MainPage::NotifyUser(String^ strMessage, NotifyType type)
+{
+    switch (type)
+    {
+    case NotifyType::StatusMessage:
+        // Use the status message style.
+        StatusBlock->Style = safe_cast<Windows::UI::Xaml::Style^>(this->Resources->Lookup("StatusStyle"));
+        break;
+    case NotifyType::ErrorMessage:
+        // Use the error message style.
+        StatusBlock->Style = safe_cast<Windows::UI::Xaml::Style^>(this->Resources->Lookup("ErrorStyle"));
+        break;
+    default:
+        break;
+    }
+    StatusBlock->Text = strMessage;
+
+    // Collapsed the StatusBlock if it has no text to conserve real estate.
+    if (StatusBlock->Text != "")
+    {
+        StatusBlock->Visibility = Windows::UI::Xaml::Visibility::Visible;
+    }
+    else
+    {
+        StatusBlock->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+    }
+}
+
+void MainPage::Footer_Click(Object^ sender, RoutedEventArgs^ e)
+{
+    auto uri = ref new Uri((String^)((HyperlinkButton^)sender)->Tag);
+    Windows::System::Launcher::LaunchUriAsync(uri);
+}
+
+
+/// <summary>
+/// Populates the page with content passed during navigation.  Any saved state is also
+/// provided when recreating a page from a prior session.
+/// </summary>
+/// <param name="navigationParameter">The parameter value passed to
+/// <see cref="Frame::Navigate(Type, Object)"/> when this page was initially requested.
+/// </param>
+/// <param name="pageState">A map of state preserved by this page during an earlier
+/// session.  This will be null the first time a page is visited.</param>
+void MainPage::LoadState(Object^ navigationParameter, IMap<String^, Object^>^ pageState)
+{
+    (void) navigationParameter;    // Unused parameter
+
+    PopulateScenarios();
+
+    // Starting scenario is the first or based upon a previous state.
+    ListBoxItem^ startingScenario = nullptr;
+    int startingScenarioIndex = -1;
+
+    if (pageState != nullptr && pageState->HasKey("SelectedScenarioIndex"))
+    {
+        startingScenarioIndex = safe_cast<int>(pageState->Lookup("SelectedScenarioIndex"));
+    }
+
+    Scenarios->SelectedIndex = startingScenarioIndex != -1 ? startingScenarioIndex : 0;
+
+    InvalidateViewState();
+}
+
+/// <summary>
+/// Preserves state associated with this page in case the application is suspended or the
+/// page is discarded from the navigation cache.  Values must conform to the serialization
+/// requirements of <see cref="SuspensionManager::SessionState"/>.
+/// </summary>
+/// <param name="pageState">An empty map to be populated with serializable state.</param>
+void MainPage::SaveState(IMap<String^, Object^>^ pageState)
+{
+    int selectedListBoxItemIndex = Scenarios->SelectedIndex;
+    pageState->Insert("SelectedScenarioIndex", selectedListBoxItemIndex);
+}
diff --git a/samples/winrt/ImageManipulations/MainPage.xaml.h b/samples/winrt/ImageManipulations/MainPage.xaml.h
new file mode 100644 (file)
index 0000000..36fb779
--- /dev/null
@@ -0,0 +1,105 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+//
+// MainPage.xaml.h
+// Declaration of the MainPage.xaml class.
+//
+
+#pragma once
+
+#include "pch.h"
+#include "MainPage.g.h"
+#include "Common\LayoutAwarePage.h" // Required by generated header
+#include "Constants.h"
+
+namespace SDKSample
+{
+    public enum class NotifyType
+    {
+        StatusMessage,
+        ErrorMessage
+    };
+
+    public ref class MainPageSizeChangedEventArgs sealed
+    {
+    public:
+        property Windows::UI::ViewManagement::ApplicationViewState ViewState
+        {
+            Windows::UI::ViewManagement::ApplicationViewState get()
+            {
+                return viewState;
+            }
+
+            void set(Windows::UI::ViewManagement::ApplicationViewState value)
+            {
+                viewState = value;
+            }
+        }
+
+    private:
+        Windows::UI::ViewManagement::ApplicationViewState viewState;
+    };
+
+    public ref class MainPage sealed
+    {
+    public:
+        MainPage();
+
+    protected:
+        virtual void LoadState(Platform::Object^ navigationParameter,
+            Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ pageState) override;
+        virtual void SaveState(Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ pageState) override;
+
+    internal:
+        property bool AutoSizeInputSectionWhenSnapped
+        {
+            bool get()
+            {
+                return autoSizeInputSectionWhenSnapped;
+            }
+
+            void set(bool value)
+            {
+                autoSizeInputSectionWhenSnapped = value;
+            }
+        }
+
+        property Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ LaunchArgs
+       {
+            Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ get()
+            {
+                return safe_cast<App^>(App::Current)->LaunchArgs;
+            }
+        }
+
+        void NotifyUser(Platform::String^ strMessage, NotifyType type);
+        void LoadScenario(Platform::String^ scenarioName);
+        event Windows::Foundation::EventHandler<Platform::Object^>^ ScenarioLoaded;
+        event Windows::Foundation::EventHandler<MainPageSizeChangedEventArgs^>^ MainPageResized;
+
+    private:
+        void PopulateScenarios();
+        void InvalidateSize();
+        void InvalidateViewState();
+
+        Platform::Collections::Vector<Object^>^ ScenarioList;
+        Windows::UI::Xaml::Controls::Frame^ HiddenFrame;
+        void Footer_Click(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+        bool autoSizeInputSectionWhenSnapped;
+
+        void MainPage_SizeChanged(Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e);
+        void Scenarios_SelectionChanged(Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e);
+
+    internal:
+        static MainPage^ Current;
+
+    };
+}
diff --git a/samples/winrt/ImageManipulations/MediaCapture.sln b/samples/winrt/ImageManipulations/MediaCapture.sln
new file mode 100644 (file)
index 0000000..e1f9aa3
--- /dev/null
@@ -0,0 +1,52 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 11 Express for Windows 8
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MediaCapture", "MediaCapture.vcxproj", "{C5B886A7-8300-46FF-B533-9613DE2AF637}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GrayscaleTransform", "MediaExtensions\OcvTransform\OcvTransform.vcxproj", "{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|ARM = Debug|ARM
+               Debug|Win32 = Debug|Win32
+               Debug|x64 = Debug|x64
+               Release|ARM = Release|ARM
+               Release|Win32 = Release|Win32
+               Release|x64 = Release|x64
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Debug|ARM.ActiveCfg = Debug|ARM
+               {BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Debug|ARM.Build.0 = Debug|ARM
+               {BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Debug|Win32.ActiveCfg = Debug|Win32
+               {BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Debug|Win32.Build.0 = Debug|Win32
+               {BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Debug|x64.ActiveCfg = Debug|x64
+               {BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Debug|x64.Build.0 = Debug|x64
+               {BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Release|ARM.ActiveCfg = Release|ARM
+               {BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Release|ARM.Build.0 = Release|ARM
+               {BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Release|Win32.ActiveCfg = Release|Win32
+               {BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Release|Win32.Build.0 = Release|Win32
+               {BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Release|x64.ActiveCfg = Release|x64
+               {BA69218F-DA5C-4D14-A78D-21A9E4DEC669}.Release|x64.Build.0 = Release|x64
+               {C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|ARM.ActiveCfg = Debug|ARM
+               {C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|ARM.Build.0 = Debug|ARM
+               {C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|ARM.Deploy.0 = Debug|ARM
+               {C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|Win32.ActiveCfg = Debug|Win32
+               {C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|Win32.Build.0 = Debug|Win32
+               {C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|Win32.Deploy.0 = Debug|Win32
+               {C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|x64.ActiveCfg = Debug|x64
+               {C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|x64.Build.0 = Debug|x64
+               {C5B886A7-8300-46FF-B533-9613DE2AF637}.Debug|x64.Deploy.0 = Debug|x64
+               {C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|ARM.ActiveCfg = Release|ARM
+               {C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|ARM.Build.0 = Release|ARM
+               {C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|ARM.Deploy.0 = Release|ARM
+               {C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|Win32.ActiveCfg = Release|Win32
+               {C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|Win32.Build.0 = Release|Win32
+               {C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|Win32.Deploy.0 = Release|Win32
+               {C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|x64.ActiveCfg = Release|x64
+               {C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|x64.Build.0 = Release|x64
+               {C5B886A7-8300-46FF-B533-9613DE2AF637}.Release|x64.Deploy.0 = Release|x64
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+EndGlobal
diff --git a/samples/winrt/ImageManipulations/MediaCapture.vcxproj b/samples/winrt/ImageManipulations/MediaCapture.vcxproj
new file mode 100644 (file)
index 0000000..b8b8990
--- /dev/null
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|ARM">
+      <Configuration>Debug</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|ARM">
+      <Configuration>Release</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{C5B886A7-8300-46FF-B533-9613DE2AF637}</ProjectGuid>
+    <RootNamespace>SDKSample</RootNamespace>
+    <DefaultLanguage>en-US</DefaultLanguage>
+    <VCTargetsPath Condition="'$(VCTargetsPath11)' != '' and '$(VSVersion)' == '' and '$(VisualStudioVersion)' == ''">$(VCTargetsPath11)</VCTargetsPath>
+    <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+    <AppContainerApplication>true</AppContainerApplication>
+    <ProjectName>MediaCapture</ProjectName>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="AdvancedCapture.xaml.h">
+      <DependentUpon>AdvancedCapture.xaml</DependentUpon>
+      <SubType>Code</SubType>
+    </ClInclude>
+    <ClInclude Include="Constants.h" />
+    <ClInclude Include="MainPage.xaml.h">
+      <DependentUpon>MainPage.xaml</DependentUpon>
+    </ClInclude>
+    <ClInclude Include="pch.h" />
+    <ClInclude Include="Common\LayoutAwarePage.h" />
+    <ClInclude Include="Common\SuspensionManager.h" />
+    <ClInclude Include="App.xaml.h">
+      <DependentUpon>App.xaml</DependentUpon>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ApplicationDefinition Include="App.xaml">
+      <SubType>Designer</SubType>
+    </ApplicationDefinition>
+    <Page Include="AdvancedCapture.xaml">
+      <SubType>Designer</SubType>
+    </Page>
+    <Page Include="Common\StandardStyles.xaml">
+      <SubType>Designer</SubType>
+    </Page>
+    <Page Include="MainPage.xaml" />
+    <Page Include="Sample-Utils\SampleTemplateStyles.xaml">
+      <SubType>Designer</SubType>
+    </Page>
+  </ItemGroup>
+  <ItemGroup>
+    <AppxManifest Include="Package.appxmanifest">
+      <SubType>Designer</SubType>
+    </AppxManifest>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="AdvancedCapture.xaml.cpp">
+      <DependentUpon>AdvancedCapture.xaml</DependentUpon>
+      <SubType>Code</SubType>
+    </ClCompile>
+    <ClCompile Include="App.xaml.cpp">
+      <DependentUpon>App.xaml</DependentUpon>
+    </ClCompile>
+    <ClCompile Include="Common\LayoutAwarePage.cpp" />
+    <ClCompile Include="Constants.cpp" />
+    <ClCompile Include="Common\SuspensionManager.cpp" />
+    <ClCompile Include="MainPage.xaml.cpp">
+      <DependentUpon>MainPage.xaml</DependentUpon>
+    </ClCompile>
+    <ClCompile Include="pch.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <Image Include="assets\opencv-logo-150.png" />
+    <Image Include="assets\opencv-logo-30.png" />
+    <Image Include="Assets\splash-sdk.png" />
+    <Image Include="Assets\windows-sdk.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="MediaExtensions\OcvTransform\OcvTransform.vcxproj">
+      <Project>{ba69218f-da5c-4d14-a78d-21a9e4dec669}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="$(OPENCV_DIR)\bin\opencv_calib3d245.dll">
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
+    </None>
+    <None Include="$(OPENCV_DIR)\bin\opencv_contrib245.dll">
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
+    </None>
+    <None Include="$(OPENCV_DIR)\bin\opencv_core245.dll">
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
+    </None>
+    <None Include="$(OPENCV_DIR)\bin\opencv_features2d245.dll">
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
+    </None>
+    <None Include="$(OPENCV_DIR)\bin\opencv_flann245.dll">
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
+    </None>
+    <None Include="$(OPENCV_DIR)\bin\opencv_highgui245.dll">
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
+    </None>
+    <None Include="$(OPENCV_DIR)\bin\opencv_imgproc245.dll">
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
+    </None>
+    <None Include="$(OPENCV_DIR)\bin\opencv_legacy245.dll">
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
+    </None>
+    <None Include="$(OPENCV_DIR)\bin\opencv_ml245.dll">
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
+    </None>
+    <None Include="$(OPENCV_DIR)\bin\opencv_nonfree245.dll">
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
+    </None>
+    <None Include="$(OPENCV_DIR)\bin\opencv_objdetect245.dll">
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
+    </None>
+    <None Include="$(OPENCV_DIR)\bin\opencv_photo245.dll">
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
+    </None>
+    <None Include="$(OPENCV_DIR)\bin\opencv_stitching245.dll">
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
+    </None>
+    <None Include="$(OPENCV_DIR)\bin\opencv_superres245.dll">
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
+    </None>
+    <None Include="$(OPENCV_DIR)\bin\opencv_ts245.dll">
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
+    </None>
+    <None Include="$(OPENCV_DIR)\bin\opencv_video245.dll">
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
+    </None>
+    <None Include="$(OPENCV_DIR)\bin\opencv_videostab245.dll">
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
+      <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
+    </None>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/samples/winrt/ImageManipulations/MediaExtensions/Common/AsyncCB.h b/samples/winrt/ImageManipulations/MediaExtensions/Common/AsyncCB.h
new file mode 100644 (file)
index 0000000..04ff69e
--- /dev/null
@@ -0,0 +1,81 @@
+#pragma once
+
+//////////////////////////////////////////////////////////////////////////
+//  AsyncCallback [template]
+//
+//  Description: 
+//  Helper class that routes IMFAsyncCallback::Invoke calls to a class
+//  method on the parent class.
+//
+//  Usage:
+//  Add this class as a member variable. In the parent class constructor,
+//  initialize the AsyncCallback class like this:
+//     m_cb(this, &CYourClass::OnInvoke)
+//  where
+//      m_cb       = AsyncCallback object
+//      CYourClass = parent class
+//      OnInvoke   = Method in the parent class to receive Invoke calls.
+//
+//  The parent's OnInvoke method (you can name it anything you like) must
+//  have a signature that matches the InvokeFn typedef below.
+//////////////////////////////////////////////////////////////////////////
+
+// T: Type of the parent object
+template<class T>
+class AsyncCallback : public IMFAsyncCallback
+{
+public: 
+    typedef HRESULT (T::*InvokeFn)(IMFAsyncResult *pAsyncResult);
+
+    AsyncCallback(T *pParent, InvokeFn fn) : m_pParent(pParent), m_pInvokeFn(fn)
+    {
+    }
+
+    // IUnknown
+    STDMETHODIMP_(ULONG) AddRef() { 
+        // Delegate to parent class.
+        return m_pParent->AddRef(); 
+    }
+    STDMETHODIMP_(ULONG) Release() { 
+        // Delegate to parent class.
+        return m_pParent->Release(); 
+    }
+    STDMETHODIMP QueryInterface(REFIID iid, void** ppv)
+    {
+        if (!ppv)
+        {
+            return E_POINTER;
+        }
+        if (iid == __uuidof(IUnknown))
+        {
+            *ppv = static_cast<IUnknown*>(static_cast<IMFAsyncCallback*>(this));
+        }
+        else if (iid == __uuidof(IMFAsyncCallback))
+        {
+            *ppv = static_cast<IMFAsyncCallback*>(this);
+        }
+        else
+        {
+            *ppv = NULL;
+            return E_NOINTERFACE;
+        }
+        AddRef();
+        return S_OK;
+    }
+
+
+    // IMFAsyncCallback methods
+    STDMETHODIMP GetParameters(DWORD*, DWORD*)
+    {
+        // Implementation of this method is optional.
+        return E_NOTIMPL;
+    }
+
+    STDMETHODIMP Invoke(IMFAsyncResult* pAsyncResult)
+    {
+        return (m_pParent->*m_pInvokeFn)(pAsyncResult);
+    }
+
+    T *m_pParent;
+    InvokeFn m_pInvokeFn;
+};
diff --git a/samples/winrt/ImageManipulations/MediaExtensions/Common/BufferLock.h b/samples/winrt/ImageManipulations/MediaExtensions/Common/BufferLock.h
new file mode 100644 (file)
index 0000000..92de15e
--- /dev/null
@@ -0,0 +1,102 @@
+// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
+// PARTICULAR PURPOSE.
+//
+// Copyright (c) Microsoft Corporation. All rights reserved
+
+
+#pragma once
+
+
+//////////////////////////////////////////////////////////////////////////
+//  VideoBufferLock
+//
+//  Description:
+//  Locks a video buffer that might or might not support IMF2DBuffer.
+//
+//////////////////////////////////////////////////////////////////////////
+
+class VideoBufferLock
+{
+public:
+    VideoBufferLock(IMFMediaBuffer *pBuffer) : m_p2DBuffer(NULL)
+    {
+        m_pBuffer = pBuffer;
+        m_pBuffer->AddRef();
+
+        // Query for the 2-D buffer interface. OK if this fails.
+        m_pBuffer->QueryInterface(IID_PPV_ARGS(&m_p2DBuffer));
+    }
+
+    ~VideoBufferLock()
+    {
+        UnlockBuffer();
+        SafeRelease(&m_pBuffer);
+        SafeRelease(&m_p2DBuffer);
+    }
+
+    // LockBuffer:
+    // Locks the buffer. Returns a pointer to scan line 0 and returns the stride.
+
+    // The caller must provide the default stride as an input parameter, in case
+    // the buffer does not expose IMF2DBuffer. You can calculate the default stride
+    // from the media type.
+
+    HRESULT LockBuffer(
+        LONG  lDefaultStride,    // Minimum stride (with no padding).
+        DWORD dwHeightInPixels,  // Height of the image, in pixels.
+        BYTE  **ppbScanLine0,    // Receives a pointer to the start of scan line 0.
+        LONG  *plStride          // Receives the actual stride.
+        )
+    {
+        HRESULT hr = S_OK;
+
+        // Use the 2-D version if available.
+        if (m_p2DBuffer)
+        {
+            hr = m_p2DBuffer->Lock2D(ppbScanLine0, plStride);
+        }
+        else
+        {
+            // Use non-2D version.
+            BYTE *pData = NULL;
+
+            hr = m_pBuffer->Lock(&pData, NULL, NULL);
+            if (SUCCEEDED(hr))
+            {
+                *plStride = lDefaultStride;
+                if (lDefaultStride < 0)
+                {
+                    // Bottom-up orientation. Return a pointer to the start of the
+                    // last row *in memory* which is the top row of the image.
+                    *ppbScanLine0 = pData + abs(lDefaultStride) * (dwHeightInPixels - 1);
+                }
+                else
+                {
+                    // Top-down orientation. Return a pointer to the start of the
+                    // buffer.
+                    *ppbScanLine0 = pData;
+                }
+            }
+        }
+        return hr;
+    }
+
+    HRESULT UnlockBuffer()
+    {
+        if (m_p2DBuffer)
+        {
+            return m_p2DBuffer->Unlock2D();
+        }
+        else
+        {
+            return m_pBuffer->Unlock();
+        }
+    }
+
+private:
+    IMFMediaBuffer  *m_pBuffer;
+    IMF2DBuffer     *m_p2DBuffer;
+};
+
diff --git a/samples/winrt/ImageManipulations/MediaExtensions/Common/CritSec.h b/samples/winrt/ImageManipulations/MediaExtensions/Common/CritSec.h
new file mode 100644 (file)
index 0000000..d5ea05b
--- /dev/null
@@ -0,0 +1,62 @@
+#pragma once
+
+//////////////////////////////////////////////////////////////////////////
+//  CritSec
+//  Description: Wraps a critical section.
+//////////////////////////////////////////////////////////////////////////
+
+class CritSec
+{
+public:
+    CRITICAL_SECTION m_criticalSection;
+public:
+    CritSec()
+    {
+        InitializeCriticalSectionEx(&m_criticalSection, 100, 0);
+    }
+
+    ~CritSec()
+    {
+        DeleteCriticalSection(&m_criticalSection);
+    }
+
+       _Acquires_lock_(m_criticalSection)
+    void Lock()
+    {
+        EnterCriticalSection(&m_criticalSection);
+    }
+
+       _Releases_lock_(m_criticalSection)
+    void Unlock()
+    {
+        LeaveCriticalSection(&m_criticalSection);
+    }
+};
+
+
+//////////////////////////////////////////////////////////////////////////
+//  AutoLock
+//  Description: Provides automatic locking and unlocking of a 
+//               of a critical section.
+//
+//  Note: The AutoLock object must go out of scope before the CritSec.
+//////////////////////////////////////////////////////////////////////////
+
+class AutoLock
+{
+private:
+    CritSec *m_pCriticalSection;
+public:
+       _Acquires_lock_(m_pCriticalSection)
+    AutoLock(CritSec& crit)
+    {
+        m_pCriticalSection = &crit;
+        m_pCriticalSection->Lock();
+    }
+
+       _Releases_lock_(m_pCriticalSection)
+    ~AutoLock()
+    {
+           m_pCriticalSection->Unlock();
+    }
+};
diff --git a/samples/winrt/ImageManipulations/MediaExtensions/Common/LinkList.h b/samples/winrt/ImageManipulations/MediaExtensions/Common/LinkList.h
new file mode 100644 (file)
index 0000000..c67c0f2
--- /dev/null
@@ -0,0 +1,516 @@
+//-----------------------------------------------------------------------------
+// File: Linklist.h
+// Desc: Linked list class.
+//
+// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
+// PARTICULAR PURPOSE.
+//
+//  Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+
+#pragma once
+
+// Notes:
+// 
+// The List class template implements a simple double-linked list. 
+// It uses STL's copy semantics. 
+
+// There are two versions of the Clear() method:
+//  Clear(void) clears the list w/out cleaning up the object.
+//  Clear(FN fn) takes a functor object that releases the objects, if they need cleanup.
+
+// The List class supports enumeration. Example of usage:
+//
+// List<T>::POSIITON pos = list.GetFrontPosition();
+// while (pos != list.GetEndPosition())
+// {
+//     T item;
+//     hr = list.GetItemPos(&item);
+//     pos = list.Next(pos);
+// }
+
+// The ComPtrList class template derives from List<> and implements a list of COM pointers.
+
+template <class T>
+struct NoOp
+{
+    void operator()(T& t)
+    {
+    }
+};
+
+template <class T>
+class List
+{
+protected:
+
+    // Nodes in the linked list
+    struct Node
+    {
+        Node *prev;
+        Node *next;
+        T    item;
+
+        Node() : prev(nullptr), next(nullptr)
+        {
+        }
+
+        Node(T item) : prev(nullptr), next(nullptr)
+        {
+            this->item = item;
+        }
+
+        T Item() const { return item; }
+    };
+
+public:
+
+    // Object for enumerating the list.
+    class POSITION
+    {
+        friend class List<T>;
+
+    public:
+        POSITION() : pNode(nullptr)
+        {
+        }
+
+        bool operator==(const POSITION &p) const
+        {
+            return pNode == p.pNode;
+        }
+
+        bool operator!=(const POSITION &p) const
+        {
+            return pNode != p.pNode;
+        }
+
+    private:
+        const Node *pNode;
+
+        POSITION(Node *p) : pNode(p) 
+        {
+        }
+    };
+
+protected:
+    Node    m_anchor;  // Anchor node for the linked list.
+    DWORD   m_count;   // Number of items in the list.
+
+    Node* Front() const
+    {
+        return m_anchor.next;
+    }
+
+    Node* Back() const
+    {
+        return m_anchor.prev;
+    }
+
+    virtual HRESULT InsertAfter(T item, Node *pBefore)
+    {
+        if (pBefore == nullptr)
+        {
+            return E_POINTER;
+        }
+
+        Node *pNode = new Node(item);
+        if (pNode == nullptr)
+        {
+            return E_OUTOFMEMORY;
+        }
+
+        Node *pAfter = pBefore->next;
+            
+        pBefore->next = pNode;
+        pAfter->prev = pNode;
+
+        pNode->prev = pBefore;
+        pNode->next = pAfter;
+
+        m_count++;
+
+        return S_OK;
+    }
+
+    virtual HRESULT GetItem(const Node *pNode, T* ppItem)
+    {
+        if (pNode == nullptr || ppItem == nullptr)
+        {
+            return E_POINTER;
+        }
+
+        *ppItem = pNode->item;
+        return S_OK;
+    }
+
+    // RemoveItem:
+    // Removes a node and optionally returns the item.
+    // ppItem can be nullptr.
+    virtual HRESULT RemoveItem(Node *pNode, T *ppItem)
+    {
+        if (pNode == nullptr)
+        {
+            return E_POINTER;
+        }
+
+        assert(pNode != &m_anchor); // We should never try to remove the anchor node.
+        if (pNode == &m_anchor)
+        {
+            return E_INVALIDARG;
+        }
+
+
+        T item;
+
+        // The next node's previous is this node's previous.
+        pNode->next->prev = pNode->prev;
+
+        // The previous node's next is this node's next.
+        pNode->prev->next = pNode->next;
+
+        item = pNode->item;
+        delete pNode;
+
+        m_count--;
+
+        if (ppItem)
+        {
+            *ppItem = item;
+        }
+
+        return S_OK;
+    }
+
+public:
+
+    List()
+    {
+        m_anchor.next = &m_anchor;
+        m_anchor.prev = &m_anchor;
+
+        m_count = 0;
+    }
+
+    virtual ~List()
+    {
+        Clear();
+    }
+
+    // Insertion functions
+    HRESULT InsertBack(T item)
+    {
+        return InsertAfter(item, m_anchor.prev);
+    }
+
+
+    HRESULT InsertFront(T item)
+    {
+        return InsertAfter(item, &m_anchor);
+    }
+
+    HRESULT InsertPos(POSITION pos, T item)
+    {
+        if (pos.pNode == nullptr)
+        {
+            return InsertBack(item);
+        }
+
+        return InsertAfter(item, pos.pNode->prev);
+    }
+
+    // RemoveBack: Removes the tail of the list and returns the value.
+    // ppItem can be nullptr if you don't want the item back. (But the method does not release the item.)
+    HRESULT RemoveBack(T *ppItem)
+    {
+        if (IsEmpty())
+        {
+            return E_FAIL;
+        }
+        else
+        {
+            return RemoveItem(Back(), ppItem);
+        }
+    }
+
+    // RemoveFront: Removes the head of the list and returns the value.
+    // ppItem can be nullptr if you don't want the item back. (But the method does not release the item.)
+    HRESULT RemoveFront(T *ppItem)
+    {
+        if (IsEmpty())
+        {
+            return E_FAIL;
+        }
+        else
+        {
+            return RemoveItem(Front(), ppItem);
+        }
+    }
+
+    // GetBack: Gets the tail item.
+    HRESULT GetBack(T *ppItem)
+    {
+        if (IsEmpty())
+        {
+            return E_FAIL;
+        }
+        else
+        {
+            return GetItem(Back(), ppItem);
+        }
+    }
+
+    // GetFront: Gets the front item.
+    HRESULT GetFront(T *ppItem)
+    {
+        if (IsEmpty())
+        {
+            return E_FAIL;
+        }
+        else
+        {
+            return GetItem(Front(), ppItem);
+        }
+    }
+
+
+    // GetCount: Returns the number of items in the list.
+    DWORD GetCount() const { return m_count; }
+
+    bool IsEmpty() const
+    {
+        return (GetCount() == 0);
+    }
+
+    // Clear: Takes a functor object whose operator()
+    // frees the object on the list.
+    template <class FN>
+    void Clear(FN& clear_fn)
+    {
+        Node *n = m_anchor.next;
+
+        // Delete the nodes
+        while (n != &m_anchor)
+        {
+            clear_fn(n->item);
+
+            Node *tmp = n->next;
+            delete n;
+            n = tmp;
+        }
+
+        // Reset the anchor to point at itself
+        m_anchor.next = &m_anchor;
+        m_anchor.prev = &m_anchor;
+
+        m_count = 0;
+    }
+
+    // Clear: Clears the list. (Does not delete or release the list items.)
+    virtual void Clear()
+    {
+        NoOp<T> clearOp;
+        Clear<>(clearOp);
+    }
+
+
+    // Enumerator functions
+
+    POSITION FrontPosition()
+    {
+        if (IsEmpty())
+        {
+            return POSITION(nullptr);
+        }
+        else
+        {
+            return POSITION(Front());
+        }
+    }
+
+    POSITION EndPosition() const
+    {
+        return POSITION();
+    }
+
+    HRESULT GetItemPos(POSITION pos, T *ppItem)
+    {   
+        if (pos.pNode)
+        {
+            return GetItem(pos.pNode, ppItem);
+        }
+        else 
+        {
+            return E_FAIL;
+        }
+    }
+
+    POSITION Next(const POSITION pos)
+    {
+        if (pos.pNode && (pos.pNode->next != &m_anchor))
+        {
+            return POSITION(pos.pNode->next);
+        }
+        else
+        {
+            return POSITION(nullptr);
+        }
+    }
+
+    // Remove an item at a position. 
+    // The item is returns in ppItem, unless ppItem is nullptr.
+    // NOTE: This method invalidates the POSITION object.
+    HRESULT Remove(POSITION& pos, T *ppItem)
+    {
+        if (pos.pNode)
+        {
+            // Remove const-ness temporarily...
+            Node *pNode = const_cast<Node*>(pos.pNode);
+
+            pos = POSITION();
+
+            return RemoveItem(pNode, ppItem);
+        }
+        else
+        {
+            return E_INVALIDARG;
+        }
+    }
+
+};
+
+
+
+// Typical functors for Clear method.
+
+// ComAutoRelease: Releases COM pointers.
+// MemDelete: Deletes pointers to new'd memory.
+
+class ComAutoRelease
+{
+public: 
+    void operator()(IUnknown *p)
+    {
+        if (p)
+        {
+            p->Release();
+        }
+    }
+};
+        
+class MemDelete
+{
+public: 
+    void operator()(void *p)
+    {
+        if (p)
+        {
+            delete p;
+        }
+    }
+};
+
+
+// ComPtrList class
+// Derived class that makes it safer to store COM pointers in the List<> class.
+// It automatically AddRef's the pointers that are inserted onto the list
+// (unless the insertion method fails). 
+//
+// T must be a COM interface type. 
+// example: ComPtrList<IUnknown>
+//
+// NULLABLE: If true, client can insert nullptr pointers. This means GetItem can
+// succeed but return a nullptr pointer. By default, the list does not allow nullptr
+// pointers.
+
+template <class T, bool NULLABLE = FALSE>
+class ComPtrList : public List<T*>
+{
+public:
+
+    typedef T* Ptr;
+
+    void Clear()
+    {
+        ComAutoRelease car;
+        List<Ptr>::Clear(car);
+    }
+
+    ~ComPtrList()
+    {
+        Clear();
+    }
+
+protected:
+    HRESULT InsertAfter(Ptr item, Node *pBefore)
+    {
+        // Do not allow nullptr item pointers unless NULLABLE is true.
+        if (item == nullptr && !NULLABLE)
+        {
+            return E_POINTER;
+        }
+
+        if (item)
+        {
+            item->AddRef();
+        }
+
+        HRESULT hr = List<Ptr>::InsertAfter(item, pBefore);
+        if (FAILED(hr) && item != nullptr)
+        {
+            item->Release();
+        }
+        return hr;
+    }
+
+    HRESULT GetItem(const Node *pNode, Ptr* ppItem)
+    {
+        Ptr pItem = nullptr;
+
+        // The base class gives us the pointer without AddRef'ing it.
+        // If we return the pointer to the caller, we must AddRef().
+        HRESULT hr = List<Ptr>::GetItem(pNode, &pItem);
+        if (SUCCEEDED(hr))
+        {
+            assert(pItem || NULLABLE);
+            if (pItem)
+            {
+                *ppItem = pItem;
+                (*ppItem)->AddRef();
+            }
+        }
+        return hr;
+    }
+
+    HRESULT RemoveItem(Node *pNode, Ptr *ppItem)
+    {
+        // ppItem can be nullptr, but we need to get the
+        // item so that we can release it. 
+
+        // If ppItem is not nullptr, we will AddRef it on the way out.
+
+        Ptr pItem = nullptr;
+
+        HRESULT hr = List<Ptr>::RemoveItem(pNode, &pItem);
+
+        if (SUCCEEDED(hr))
+        {
+            assert(pItem || NULLABLE);
+            if (ppItem && pItem)
+            {
+                *ppItem = pItem;
+                (*ppItem)->AddRef();
+            }
+
+            if (pItem)
+            {
+                pItem->Release();
+                pItem = nullptr;
+            }
+        }
+
+        return hr;
+    }
+};
diff --git a/samples/winrt/ImageManipulations/MediaExtensions/Common/OpQueue.h b/samples/winrt/ImageManipulations/MediaExtensions/Common/OpQueue.h
new file mode 100644 (file)
index 0000000..dd0813b
--- /dev/null
@@ -0,0 +1,222 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// OpQueue.h
+// Async operation queue.
+//
+// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
+// PARTICULAR PURPOSE.
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+#pragma warning( push )
+#pragma warning( disable : 4355 )  // 'this' used in base member initializer list
+
+/*
+    This header file defines an object to help queue and serialize
+    asynchronous operations.
+
+    Background:
+
+    To perform an operation asynchronously in Media Foundation, an object
+    does one of the following:
+
+        1. Calls MFPutWorkItem(Ex), using either a standard work queue
+           identifier or a caller-allocated work queue. The work-queue
+           thread invokes the object's callback.
+
+        2. Creates an async result object (IMFAsyncResult) and calls
+           MFInvokeCallback to invoke the object's callback.
+
+    Ultimately, either of these cause the object's callback to be invoked
+    from a work-queue thread. The object can then complete the operation
+    inside the callback.
+
+    However, the Media Foundation platform may dispatch async callbacks in
+    parallel on several threads. Putting an item on a work queue does NOT
+    guarantee that one operation will complete before the next one starts,
+    or even that work items will be dispatched in the same order they were
+    called.
+
+    To serialize async operations that should not overlap, an object should
+    use a queue. While one operation is pending, subsequent operations are
+    put on the queue, and only dispatched after the previous operation is
+    complete.
+
+    The granularity of a single "operation" depends on the requirements of
+    that particular object. A single operation might involve several
+    asynchronous calls before the object dispatches the next operation on
+    the queue.
+
+
+*/
+
+
+
+//-------------------------------------------------------------------
+// OpQueue class template
+//
+// Base class for an async operation queue.
+//
+// TOperation: The class used to describe operations. This class must
+//          implement IUnknown.
+//
+// The OpQueue class is an abstract class. The derived class must
+// implement the following pure-virtual methods:
+//
+// - IUnknown methods (AddRef, Release, QI)
+//
+// - DispatchOperation:
+//
+//      Performs the asynchronous operation specified by pOp.
+//
+//      At the end of each operation, the derived class must call
+//      ProcessQueue to process the next operation in the queue.
+//
+//      NOTE: An operation is not required to complete inside the
+//      DispatchOperation method. A single operation might consist
+//      of several asynchronous method calls.
+//
+// - ValidateOperation:
+//
+//      Checks whether the object can perform the operation specified
+//      by pOp at this time.
+//
+//      If the object cannot perform the operation now (e.g., because
+//      another operation is still in progress) the method should
+//      return MF_E_NOTACCEPTING.
+//
+//-------------------------------------------------------------------
+#include "linklist.h"
+#include "AsyncCB.h"
+
+template <class T, class TOperation>
+class OpQueue //: public IUnknown
+{
+public:
+
+    typedef ComPtrList<TOperation>   OpList;
+
+    HRESULT QueueOperation(TOperation *pOp);
+
+protected:
+
+    HRESULT ProcessQueue();
+    HRESULT ProcessQueueAsync(IMFAsyncResult *pResult);
+
+    virtual HRESULT DispatchOperation(TOperation *pOp) = 0;
+    virtual HRESULT ValidateOperation(TOperation *pOp) = 0;
+
+    OpQueue(CRITICAL_SECTION& critsec)
+        : m_OnProcessQueue(static_cast<T *>(this), &OpQueue::ProcessQueueAsync),
+          m_critsec(critsec)
+    {
+    }
+
+    virtual ~OpQueue()
+    {
+    }
+
+protected:
+    OpList                  m_OpQueue;         // Queue of operations.
+    CRITICAL_SECTION&       m_critsec;         // Protects the queue state.
+    AsyncCallback<T>  m_OnProcessQueue;  // ProcessQueueAsync callback.
+};
+
+
+
+//-------------------------------------------------------------------
+// Place an operation on the queue.
+// Public method.
+//-------------------------------------------------------------------
+
+template <class T, class TOperation>
+HRESULT OpQueue<T, TOperation>::QueueOperation(TOperation *pOp)
+{
+    HRESULT hr = S_OK;
+
+    EnterCriticalSection(&m_critsec);
+
+    hr = m_OpQueue.InsertBack(pOp);
+    if (SUCCEEDED(hr))
+    {
+        hr = ProcessQueue();
+    }
+
+    LeaveCriticalSection(&m_critsec);
+    return hr;
+}
+
+
+//-------------------------------------------------------------------
+// Process the next operation on the queue.
+// Protected method.
+//
+// Note: This method dispatches the operation to a work queue.
+//-------------------------------------------------------------------
+
+template <class T, class TOperation>
+HRESULT OpQueue<T, TOperation>::ProcessQueue()
+{
+    HRESULT hr = S_OK;
+    if (m_OpQueue.GetCount() > 0)
+    {
+        hr = MFPutWorkItem2(
+            MFASYNC_CALLBACK_QUEUE_STANDARD,    // Use the standard work queue.
+            0,                                  // Default priority
+            &m_OnProcessQueue,                  // Callback method.
+            nullptr                             // State object.
+            );
+    }
+    return hr;
+}
+
+
+//-------------------------------------------------------------------
+// Process the next operation on the queue.
+// Protected method.
+//
+// Note: This method is called from a work-queue thread.
+//-------------------------------------------------------------------
+
+template <class T, class TOperation>
+HRESULT OpQueue<T, TOperation>::ProcessQueueAsync(IMFAsyncResult *pResult)
+{
+    HRESULT hr = S_OK;
+    TOperation *pOp = nullptr;
+
+    EnterCriticalSection(&m_critsec);
+
+    if (m_OpQueue.GetCount() > 0)
+    {
+        hr = m_OpQueue.GetFront(&pOp);
+
+        if (SUCCEEDED(hr))
+        {
+            hr = ValidateOperation(pOp);
+        }
+        if (SUCCEEDED(hr))
+        {
+            hr = m_OpQueue.RemoveFront(nullptr);
+        }
+        if (SUCCEEDED(hr))
+        {
+            (void)DispatchOperation(pOp);
+        }
+    }
+
+    if (pOp != nullptr)
+    {
+        pOp->Release();
+    }
+
+    LeaveCriticalSection(&m_critsec);
+    return hr;
+}
+
+#pragma warning( pop )
\ No newline at end of file
diff --git a/samples/winrt/ImageManipulations/MediaExtensions/OcvTransform/OcvImageManipulations.idl b/samples/winrt/ImageManipulations/MediaExtensions/OcvTransform/OcvImageManipulations.idl
new file mode 100644 (file)
index 0000000..120ef7d
--- /dev/null
@@ -0,0 +1,11 @@
+import "Windows.Media.idl";
+
+#include <sdkddkver.h>
+
+namespace OcvTransform
+{
+       [version(NTDDI_WIN8)]
+       runtimeclass OcvImageManipulations 
+    {
+       }
+}
\ No newline at end of file
diff --git a/samples/winrt/ImageManipulations/MediaExtensions/OcvTransform/OcvTransform.cpp b/samples/winrt/ImageManipulations/MediaExtensions/OcvTransform/OcvTransform.cpp
new file mode 100644 (file)
index 0000000..bf98128
--- /dev/null
@@ -0,0 +1,1486 @@
+// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
+// PARTICULAR PURPOSE.
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+
+#include "OcvTransform.h"
+#include "bufferlock.h"
+
+#include "opencv2\core\core.hpp"
+#include "opencv2\imgproc\imgproc.hpp"
+
+using namespace Microsoft::WRL;
+
+/*
+
+This sample implements a video effect as a Media Foundation transform (MFT).
+
+NOTES ON THE MFT IMPLEMENTATION
+
+1. The MFT has fixed streams: One input stream and one output stream.
+
+2. The MFT supports NV12 format only.
+
+3. If the MFT is holding an input sample, SetInputType and SetOutputType both fail.
+
+4. The input and output types must be identical.
+
+5. If both types are set, no type can be set until the current type is cleared.
+
+6. Preferred input types:
+
+     (a) If the output type is set, that's the preferred type.
+     (b) Otherwise, the preferred types are partial types, constructed from the
+         list of supported subtypes.
+
+7. Preferred output types: As above.
+
+8. Streaming:
+
+    The private BeingStreaming() method is called in response to the
+    MFT_MESSAGE_NOTIFY_BEGIN_STREAMING message.
+
+    If the client does not send MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, the MFT calls
+    BeginStreaming inside the first call to ProcessInput or ProcessOutput.
+
+    This is a good approach for allocating resources that your MFT requires for
+    streaming.
+
+9. The configuration attributes are applied in the BeginStreaming method. If the
+   client changes the attributes during streaming, the change is ignored until
+   streaming is stopped (either by changing the media types or by sending the
+   MFT_MESSAGE_NOTIFY_END_STREAMING message) and then restarted.
+
+*/
+
+
+// Static array of media types (preferred and accepted).
+const GUID g_MediaSubtypes[] =
+{
+    MFVideoFormat_NV12
+};
+
+HRESULT GetDefaultStride(IMFMediaType *pType, LONG *plStride);
+
+template <typename T>
+inline T clamp(const T& val, const T& minVal, const T& maxVal)
+{
+    return (val < minVal ? minVal : (val > maxVal ? maxVal : val));
+}
+
+OcvImageManipulations::OcvImageManipulations() :
+    m_pSample(NULL), m_pInputType(NULL), m_pOutputType(NULL),
+    m_imageWidthInPixels(0), m_imageHeightInPixels(0), m_cbImageSize(0),
+    m_TransformType(Preview), m_bStreamingInitialized(false),
+    m_pAttributes(NULL)
+{
+    InitializeCriticalSectionEx(&m_critSec, 3000, 0);
+}
+
+OcvImageManipulations::~OcvImageManipulations()
+{
+    SafeRelease(&m_pInputType);
+    SafeRelease(&m_pOutputType);
+    SafeRelease(&m_pSample);
+    SafeRelease(&m_pAttributes);
+    DeleteCriticalSection(&m_critSec);
+}
+
+// Initialize the instance.
+STDMETHODIMP OcvImageManipulations::RuntimeClassInitialize()
+{
+    // Create the attribute store.
+    return MFCreateAttributes(&m_pAttributes, 3);
+}
+
+// IMediaExtension methods
+
+//-------------------------------------------------------------------
+// SetProperties
+// Sets the configuration of the effect
+//-------------------------------------------------------------------
+HRESULT OcvImageManipulations::SetProperties(ABI::Windows::Foundation::Collections::IPropertySet *pConfiguration)
+{
+    HRESULT hr = S_OK;
+
+    if (!pConfiguration)
+        return hr;
+
+    HSTRING key;
+    WindowsCreateString(L"{698649BE-8EAE-4551-A4CB-3EC98FBD3D86}", 38, &key);
+    Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable *>> spSetting;
+    pConfiguration->QueryInterface(IID_PPV_ARGS(&spSetting));
+    boolean found;
+    spSetting->HasKey(key, &found);
+
+    if (found)
+    {
+        IInspectable* value;
+        spSetting->Lookup(key, &value);
+
+        Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IReference<int>> ref;
+        hr = value->QueryInterface(IID_PPV_ARGS(&ref));
+        int effect = InvalidEffect;
+        hr = ref->get_Value(&effect);
+        if ((effect >= 0) && (effect < InvalidEffect))
+        {
+            m_TransformType = (ProcessingType)effect;
+        }
+    }
+
+       return hr;
+}
+
+// IMFTransform methods. Refer to the Media Foundation SDK documentation for details.
+
+//-------------------------------------------------------------------
+// GetStreamLimits
+// Returns the minimum and maximum number of streams.
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::GetStreamLimits(
+    DWORD   *pdwInputMinimum,
+    DWORD   *pdwInputMaximum,
+    DWORD   *pdwOutputMinimum,
+    DWORD   *pdwOutputMaximum
+)
+{
+    if ((pdwInputMinimum == NULL) ||
+        (pdwInputMaximum == NULL) ||
+        (pdwOutputMinimum == NULL) ||
+        (pdwOutputMaximum == NULL))
+    {
+        return E_POINTER;
+    }
+
+    // This MFT has a fixed number of streams.
+    *pdwInputMinimum = 1;
+    *pdwInputMaximum = 1;
+    *pdwOutputMinimum = 1;
+    *pdwOutputMaximum = 1;
+    return S_OK;
+}
+
+
+//-------------------------------------------------------------------
+// GetStreamCount
+// Returns the actual number of streams.
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::GetStreamCount(
+    DWORD   *pcInputStreams,
+    DWORD   *pcOutputStreams
+)
+{
+    if ((pcInputStreams == NULL) || (pcOutputStreams == NULL))
+
+    {
+        return E_POINTER;
+    }
+
+    // This MFT has a fixed number of streams.
+    *pcInputStreams = 1;
+    *pcOutputStreams = 1;
+    return S_OK;
+}
+
+
+
+//-------------------------------------------------------------------
+// GetStreamIDs
+// Returns stream IDs for the input and output streams.
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::GetStreamIDs(
+    DWORD   dwInputIDArraySize,
+    DWORD   *pdwInputIDs,
+    DWORD   dwOutputIDArraySize,
+    DWORD   *pdwOutputIDs
+)
+{
+    // It is not required to implement this method if the MFT has a fixed number of
+    // streams AND the stream IDs are numbered sequentially from zero (that is, the
+    // stream IDs match the stream indexes).
+
+    // In that case, it is OK to return E_NOTIMPL.
+    return E_NOTIMPL;
+}
+
+
+//-------------------------------------------------------------------
+// GetInputStreamInfo
+// Returns information about an input stream.
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::GetInputStreamInfo(
+    DWORD                     dwInputStreamID,
+    MFT_INPUT_STREAM_INFO *   pStreamInfo
+)
+{
+    if (pStreamInfo == NULL)
+    {
+        return E_POINTER;
+    }
+
+    EnterCriticalSection(&m_critSec);
+
+    if (!IsValidInputStream(dwInputStreamID))
+    {
+        LeaveCriticalSection(&m_critSec);
+        return MF_E_INVALIDSTREAMNUMBER;
+    }
+
+    // NOTE: This method should succeed even when there is no media type on the
+    //       stream. If there is no media type, we only need to fill in the dwFlags
+    //       member of MFT_INPUT_STREAM_INFO. The other members depend on having a
+    //       a valid media type.
+
+    pStreamInfo->hnsMaxLatency = 0;
+    pStreamInfo->dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER;
+
+    if (m_pInputType == NULL)
+    {
+        pStreamInfo->cbSize = 0;
+    }
+    else
+    {
+        pStreamInfo->cbSize = m_cbImageSize;
+    }
+
+    pStreamInfo->cbMaxLookahead = 0;
+    pStreamInfo->cbAlignment = 0;
+
+    LeaveCriticalSection(&m_critSec);
+    return S_OK;
+}
+
+//-------------------------------------------------------------------
+// GetOutputStreamInfo
+// Returns information about an output stream.
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::GetOutputStreamInfo(
+    DWORD                     dwOutputStreamID,
+    MFT_OUTPUT_STREAM_INFO *  pStreamInfo
+)
+{
+    if (pStreamInfo == NULL)
+    {
+        return E_POINTER;
+    }
+
+    EnterCriticalSection(&m_critSec);
+
+    if (!IsValidOutputStream(dwOutputStreamID))
+    {
+        LeaveCriticalSection(&m_critSec);
+        return MF_E_INVALIDSTREAMNUMBER;
+    }
+
+    // NOTE: This method should succeed even when there is no media type on the
+    //       stream. If there is no media type, we only need to fill in the dwFlags
+    //       member of MFT_OUTPUT_STREAM_INFO. The other members depend on having a
+    //       a valid media type.
+
+    pStreamInfo->dwFlags =
+        MFT_OUTPUT_STREAM_WHOLE_SAMPLES |
+        MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER |
+        MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE ;
+
+    if (m_pOutputType == NULL)
+    {
+        pStreamInfo->cbSize = 0;
+    }
+    else
+    {
+        pStreamInfo->cbSize = m_cbImageSize;
+    }
+
+    pStreamInfo->cbAlignment = 0;
+
+    LeaveCriticalSection(&m_critSec);
+    return S_OK;
+}
+
+
+//-------------------------------------------------------------------
+// GetAttributes
+// Returns the attributes for the MFT.
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::GetAttributes(IMFAttributes** ppAttributes)
+{
+    if (ppAttributes == NULL)
+    {
+        return E_POINTER;
+    }
+
+    EnterCriticalSection(&m_critSec);
+
+    *ppAttributes = m_pAttributes;
+    (*ppAttributes)->AddRef();
+
+    LeaveCriticalSection(&m_critSec);
+    return S_OK;
+}
+
+
+//-------------------------------------------------------------------
+// GetInputStreamAttributes
+// Returns stream-level attributes for an input stream.
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::GetInputStreamAttributes(
+    DWORD           dwInputStreamID,
+    IMFAttributes   **ppAttributes
+)
+{
+    // This MFT does not support any stream-level attributes, so the method is not implemented.
+    return E_NOTIMPL;
+}
+
+
+//-------------------------------------------------------------------
+// GetOutputStreamAttributes
+// Returns stream-level attributes for an output stream.
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::GetOutputStreamAttributes(
+    DWORD           dwOutputStreamID,
+    IMFAttributes   **ppAttributes
+)
+{
+    // This MFT does not support any stream-level attributes, so the method is not implemented.
+    return E_NOTIMPL;
+}
+
+
+//-------------------------------------------------------------------
+// DeleteInputStream
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::DeleteInputStream(DWORD dwStreamID)
+{
+    // This MFT has a fixed number of input streams, so the method is not supported.
+    return E_NOTIMPL;
+}
+
+
+//-------------------------------------------------------------------
+// AddInputStreams
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::AddInputStreams(
+    DWORD   cStreams,
+    DWORD   *adwStreamIDs
+)
+{
+    // This MFT has a fixed number of output streams, so the method is not supported.
+    return E_NOTIMPL;
+}
+
+
+//-------------------------------------------------------------------
+// GetInputAvailableType
+// Returns a preferred input type.
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::GetInputAvailableType(
+    DWORD           dwInputStreamID,
+    DWORD           dwTypeIndex, // 0-based
+    IMFMediaType    **ppType
+)
+{
+    if (ppType == NULL)
+    {
+        return E_INVALIDARG;
+    }
+
+    EnterCriticalSection(&m_critSec);
+
+    if (!IsValidInputStream(dwInputStreamID))
+    {
+        LeaveCriticalSection(&m_critSec);
+        return MF_E_INVALIDSTREAMNUMBER;
+    }
+
+    HRESULT hr = S_OK;
+
+    // If the output type is set, return that type as our preferred input type.
+    if (m_pOutputType == NULL)
+    {
+        // The output type is not set. Create a partial media type.
+        hr = OnGetPartialType(dwTypeIndex, ppType);
+    }
+    else if (dwTypeIndex > 0)
+    {
+        hr = MF_E_NO_MORE_TYPES;
+    }
+    else
+    {
+        *ppType = m_pOutputType;
+        (*ppType)->AddRef();
+    }
+
+    LeaveCriticalSection(&m_critSec);
+    return hr;
+}
+
+
+
+//-------------------------------------------------------------------
+// GetOutputAvailableType
+// Returns a preferred output type.
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::GetOutputAvailableType(
+    DWORD           dwOutputStreamID,
+    DWORD           dwTypeIndex, // 0-based
+    IMFMediaType    **ppType
+)
+{
+    if (ppType == NULL)
+    {
+        return E_INVALIDARG;
+    }
+
+    EnterCriticalSection(&m_critSec);
+
+    if (!IsValidOutputStream(dwOutputStreamID))
+    {
+        LeaveCriticalSection(&m_critSec);
+        return MF_E_INVALIDSTREAMNUMBER;
+    }
+
+    HRESULT hr = S_OK;
+
+    if (m_pInputType == NULL)
+    {
+        // The input type is not set. Create a partial media type.
+        hr = OnGetPartialType(dwTypeIndex, ppType);
+    }
+    else if (dwTypeIndex > 0)
+    {
+        hr = MF_E_NO_MORE_TYPES;
+    }
+    else
+    {
+        *ppType = m_pInputType;
+        (*ppType)->AddRef();
+    }
+
+    LeaveCriticalSection(&m_critSec);
+    return hr;
+}
+
+
+//-------------------------------------------------------------------
+// SetInputType
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::SetInputType(
+    DWORD           dwInputStreamID,
+    IMFMediaType    *pType, // Can be NULL to clear the input type.
+    DWORD           dwFlags
+)
+{
+    // Validate flags.
+    if (dwFlags & ~MFT_SET_TYPE_TEST_ONLY)
+    {
+        return E_INVALIDARG;
+    }
+
+    EnterCriticalSection(&m_critSec);
+
+    if (!IsValidInputStream(dwInputStreamID))
+    {
+        LeaveCriticalSection(&m_critSec);
+        return MF_E_INVALIDSTREAMNUMBER;
+    }
+
+    HRESULT hr = S_OK;
+
+    // Does the caller want us to set the type, or just test it?
+    BOOL bReallySet = ((dwFlags & MFT_SET_TYPE_TEST_ONLY) == 0);
+
+    // If we have an input sample, the client cannot change the type now.
+    if (HasPendingOutput())
+    {
+        hr = MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING;
+        goto done;
+    }
+
+    // Validate the type, if non-NULL.
+    if (pType)
+    {
+        hr = OnCheckInputType(pType);
+        if (FAILED(hr))
+        {
+            goto done;
+        }
+    }
+
+    // The type is OK. Set the type, unless the caller was just testing.
+    if (bReallySet)
+    {
+        OnSetInputType(pType);
+
+        // When the type changes, end streaming.
+        hr = EndStreaming();
+    }
+
+done:
+    LeaveCriticalSection(&m_critSec);
+    return hr;
+}
+
+
+
+//-------------------------------------------------------------------
+// SetOutputType
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::SetOutputType(
+    DWORD           dwOutputStreamID,
+    IMFMediaType    *pType, // Can be NULL to clear the output type.
+    DWORD           dwFlags
+)
+{
+    // Validate flags.
+    if (dwFlags & ~MFT_SET_TYPE_TEST_ONLY)
+    {
+        return E_INVALIDARG;
+    }
+
+    EnterCriticalSection(&m_critSec);
+
+    if (!IsValidOutputStream(dwOutputStreamID))
+    {
+        LeaveCriticalSection(&m_critSec);
+        return MF_E_INVALIDSTREAMNUMBER;
+    }
+
+    HRESULT hr = S_OK;
+
+    // Does the caller want us to set the type, or just test it?
+    BOOL bReallySet = ((dwFlags & MFT_SET_TYPE_TEST_ONLY) == 0);
+
+    // If we have an input sample, the client cannot change the type now.
+    if (HasPendingOutput())
+    {
+        hr = MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING;
+        goto done;
+    }
+
+    // Validate the type, if non-NULL.
+    if (pType)
+    {
+        hr = OnCheckOutputType(pType);
+        if (FAILED(hr))
+        {
+            goto done;
+        }
+    }
+
+    // The type is OK. Set the type, unless the caller was just testing.
+    if (bReallySet)
+    {
+        OnSetOutputType(pType);
+
+        // When the type changes, end streaming.
+        hr = EndStreaming();
+    }
+
+done:
+    LeaveCriticalSection(&m_critSec);
+    return hr;
+}
+
+
+//-------------------------------------------------------------------
+// GetInputCurrentType
+// Returns the current input type.
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::GetInputCurrentType(
+    DWORD           dwInputStreamID,
+    IMFMediaType    **ppType
+)
+{
+    if (ppType == NULL)
+    {
+        return E_POINTER;
+    }
+
+    HRESULT hr = S_OK;
+
+    EnterCriticalSection(&m_critSec);
+
+    if (!IsValidInputStream(dwInputStreamID))
+    {
+        hr = MF_E_INVALIDSTREAMNUMBER;
+    }
+    else if (!m_pInputType)
+    {
+        hr = MF_E_TRANSFORM_TYPE_NOT_SET;
+    }
+    else
+    {
+        *ppType = m_pInputType;
+        (*ppType)->AddRef();
+    }
+    LeaveCriticalSection(&m_critSec);
+    return hr;
+}
+
+
+//-------------------------------------------------------------------
+// GetOutputCurrentType
+// Returns the current output type.
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::GetOutputCurrentType(
+    DWORD           dwOutputStreamID,
+    IMFMediaType    **ppType
+)
+{
+    if (ppType == NULL)
+    {
+        return E_POINTER;
+    }
+
+    HRESULT hr = S_OK;
+
+    EnterCriticalSection(&m_critSec);
+
+    if (!IsValidOutputStream(dwOutputStreamID))
+    {
+        hr = MF_E_INVALIDSTREAMNUMBER;
+    }
+    else if (!m_pOutputType)
+    {
+        hr = MF_E_TRANSFORM_TYPE_NOT_SET;
+    }
+    else
+    {
+        *ppType = m_pOutputType;
+        (*ppType)->AddRef();
+    }
+
+    LeaveCriticalSection(&m_critSec);
+    return hr;
+}
+
+
+//-------------------------------------------------------------------
+// GetInputStatus
+// Query if the MFT is accepting more input.
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::GetInputStatus(
+    DWORD           dwInputStreamID,
+    DWORD           *pdwFlags
+)
+{
+    if (pdwFlags == NULL)
+    {
+        return E_POINTER;
+    }
+
+    EnterCriticalSection(&m_critSec);
+
+    if (!IsValidInputStream(dwInputStreamID))
+    {
+        LeaveCriticalSection(&m_critSec);
+        return MF_E_INVALIDSTREAMNUMBER;
+    }
+
+    // If an input sample is already queued, do not accept another sample until the
+    // client calls ProcessOutput or Flush.
+
+    // NOTE: It is possible for an MFT to accept more than one input sample. For
+    // example, this might be required in a video decoder if the frames do not
+    // arrive in temporal order. In the case, the decoder must hold a queue of
+    // samples. For the video effect, each sample is transformed independently, so
+    // there is no reason to queue multiple input samples.
+
+    if (m_pSample == NULL)
+    {
+        *pdwFlags = MFT_INPUT_STATUS_ACCEPT_DATA;
+    }
+    else
+    {
+        *pdwFlags = 0;
+    }
+
+    LeaveCriticalSection(&m_critSec);
+    return S_OK;
+}
+
+
+
+//-------------------------------------------------------------------
+// GetOutputStatus
+// Query if the MFT can produce output.
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::GetOutputStatus(DWORD *pdwFlags)
+{
+    if (pdwFlags == NULL)
+    {
+        return E_POINTER;
+    }
+
+    EnterCriticalSection(&m_critSec);
+
+    // The MFT can produce an output sample if (and only if) there an input sample.
+    if (m_pSample != NULL)
+    {
+        *pdwFlags = MFT_OUTPUT_STATUS_SAMPLE_READY;
+    }
+    else
+    {
+        *pdwFlags = 0;
+    }
+
+    LeaveCriticalSection(&m_critSec);
+    return S_OK;
+}
+
+
+//-------------------------------------------------------------------
+// SetOutputBounds
+// Sets the range of time stamps that the MFT will output.
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::SetOutputBounds(
+    LONGLONG        hnsLowerBound,
+    LONGLONG        hnsUpperBound
+)
+{
+    // Implementation of this method is optional.
+    return E_NOTIMPL;
+}
+
+
+//-------------------------------------------------------------------
+// ProcessEvent
+// Sends an event to an input stream.
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::ProcessEvent(
+    DWORD              dwInputStreamID,
+    IMFMediaEvent      *pEvent
+)
+{
+    // This MFT does not handle any stream events, so the method can
+    // return E_NOTIMPL. This tells the pipeline that it can stop
+    // sending any more events to this MFT.
+    return E_NOTIMPL;
+}
+
+
+//-------------------------------------------------------------------
+// ProcessMessage
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::ProcessMessage(
+    MFT_MESSAGE_TYPE    eMessage,
+    ULONG_PTR           ulParam
+)
+{
+    EnterCriticalSection(&m_critSec);
+
+    HRESULT hr = S_OK;
+
+    switch (eMessage)
+    {
+    case MFT_MESSAGE_COMMAND_FLUSH:
+        // Flush the MFT.
+        hr = OnFlush();
+        break;
+
+    case MFT_MESSAGE_COMMAND_DRAIN:
+        // Drain: Tells the MFT to reject further input until all pending samples are
+        // processed. That is our default behavior already, so there is nothing to do.
+        //
+        // For a decoder that accepts a queue of samples, the MFT might need to drain
+        // the queue in response to this command.
+    break;
+
+    case MFT_MESSAGE_SET_D3D_MANAGER:
+        // Sets a pointer to the IDirect3DDeviceManager9 interface.
+
+        // The pipeline should never send this message unless the MFT sets the MF_SA_D3D_AWARE
+        // attribute set to TRUE. Because this MFT does not set MF_SA_D3D_AWARE, it is an error
+        // to send the MFT_MESSAGE_SET_D3D_MANAGER message to the MFT. Return an error code in
+        // this case.
+
+        // NOTE: If this MFT were D3D-enabled, it would cache the IDirect3DDeviceManager9
+        // pointer for use during streaming.
+
+        hr = E_NOTIMPL;
+        break;
+
+    case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING:
+        hr = BeginStreaming();
+        break;
+
+    case MFT_MESSAGE_NOTIFY_END_STREAMING:
+        hr = EndStreaming();
+        break;
+
+    // The next two messages do not require any action from this MFT.
+
+    case MFT_MESSAGE_NOTIFY_END_OF_STREAM:
+        break;
+
+    case MFT_MESSAGE_NOTIFY_START_OF_STREAM:
+        break;
+    }
+
+    LeaveCriticalSection(&m_critSec);
+    return hr;
+}
+
+
+//-------------------------------------------------------------------
+// ProcessInput
+// Process an input sample.
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::ProcessInput(
+    DWORD               dwInputStreamID,
+    IMFSample           *pSample,
+    DWORD               dwFlags
+)
+{
+    // Check input parameters.
+    if (pSample == NULL)
+    {
+        return E_POINTER;
+    }
+
+    if (dwFlags != 0)
+    {
+        return E_INVALIDARG; // dwFlags is reserved and must be zero.
+    }
+
+    HRESULT hr = S_OK;
+
+    EnterCriticalSection(&m_critSec);
+
+    // Validate the input stream number.
+    if (!IsValidInputStream(dwInputStreamID))
+    {
+        hr = MF_E_INVALIDSTREAMNUMBER;
+        goto done;
+    }
+
+    // Check for valid media types.
+    // The client must set input and output types before calling ProcessInput.
+    if (!m_pInputType || !m_pOutputType)
+    {
+        hr = MF_E_NOTACCEPTING;
+        goto done;
+    }
+
+    // Check if an input sample is already queued.
+    if (m_pSample != NULL)
+    {
+        hr = MF_E_NOTACCEPTING;   // We already have an input sample.
+        goto done;
+    }
+
+    // Initialize streaming.
+    hr = BeginStreaming();
+    if (FAILED(hr))
+    {
+        goto done;
+    }
+
+    // Cache the sample. We do the actual work in ProcessOutput.
+    m_pSample = pSample;
+    pSample->AddRef();  // Hold a reference count on the sample.
+
+done:
+    LeaveCriticalSection(&m_critSec);
+    return hr;
+}
+
+
+//-------------------------------------------------------------------
+// ProcessOutput
+// Process an output sample.
+//-------------------------------------------------------------------
+
+HRESULT OcvImageManipulations::ProcessOutput(
+    DWORD                   dwFlags,
+    DWORD                   cOutputBufferCount,
+    MFT_OUTPUT_DATA_BUFFER  *pOutputSamples, // one per stream
+    DWORD                   *pdwStatus
+)
+{
+    // Check input parameters...
+
+    // This MFT does not accept any flags for the dwFlags parameter.
+
+    // The only defined flag is MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER. This flag
+    // applies only when the MFT marks an output stream as lazy or optional. But this
+    // MFT has no lazy or optional streams, so the flag is not valid.
+
+    if (dwFlags != 0)
+    {
+        return E_INVALIDARG;
+    }
+
+    if (pOutputSamples == NULL || pdwStatus == NULL)
+    {
+        return E_POINTER;
+    }
+
+    // There must be exactly one output buffer.
+    if (cOutputBufferCount != 1)
+    {
+        return E_INVALIDARG;
+    }
+
+    // It must contain a sample.
+    if (pOutputSamples[0].pSample == NULL)
+    {
+        return E_INVALIDARG;
+    }
+
+    HRESULT hr = S_OK;
+
+    IMFMediaBuffer *pInput = NULL;
+    IMFMediaBuffer *pOutput = NULL;
+
+    EnterCriticalSection(&m_critSec);
+
+    // There must be an input sample available for processing.
+    if (m_pSample == NULL)
+    {
+        hr = MF_E_TRANSFORM_NEED_MORE_INPUT;
+        goto done;
+    }
+
+    // Initialize streaming.
+
+    hr = BeginStreaming();
+    if (FAILED(hr))
+    {
+        goto done;
+    }
+
+    // Get the input buffer.
+    hr = m_pSample->ConvertToContiguousBuffer(&pInput);
+    if (FAILED(hr))
+    {
+        goto done;
+    }
+
+    // Get the output buffer.
+    hr = pOutputSamples[0].pSample->ConvertToContiguousBuffer(&pOutput);
+    if (FAILED(hr))
+    {
+        goto done;
+    }
+
+    hr = OnProcessOutput(pInput, pOutput);
+    if (FAILED(hr))
+    {
+        goto done;
+    }
+
+    // Set status flags.
+    pOutputSamples[0].dwStatus = 0;
+    *pdwStatus = 0;
+
+
+    // Copy the duration and time stamp from the input sample, if present.
+
+    LONGLONG hnsDuration = 0;
+    LONGLONG hnsTime = 0;
+
+    if (SUCCEEDED(m_pSample->GetSampleDuration(&hnsDuration)))
+    {
+        hr = pOutputSamples[0].pSample->SetSampleDuration(hnsDuration);
+        if (FAILED(hr))
+        {
+            goto done;
+        }
+    }
+
+    if (SUCCEEDED(m_pSample->GetSampleTime(&hnsTime)))
+    {
+        hr = pOutputSamples[0].pSample->SetSampleTime(hnsTime);
+    }
+
+done:
+    SafeRelease(&m_pSample);   // Release our input sample.
+    SafeRelease(&pInput);
+    SafeRelease(&pOutput);
+    LeaveCriticalSection(&m_critSec);
+    return hr;
+}
+
+// PRIVATE METHODS
+
+// All methods that follow are private to this MFT and are not part of the IMFTransform interface.
+
+// Create a partial media type from our list.
+//
+// dwTypeIndex: Index into the list of peferred media types.
+// ppmt:        Receives a pointer to the media type.
+
+HRESULT OcvImageManipulations::OnGetPartialType(DWORD dwTypeIndex, IMFMediaType **ppmt)
+{
+    if (dwTypeIndex >= ARRAYSIZE(g_MediaSubtypes))
+    {
+        return MF_E_NO_MORE_TYPES;
+    }
+
+    IMFMediaType *pmt = NULL;
+
+    HRESULT hr = MFCreateMediaType(&pmt);
+    if (FAILED(hr))
+    {
+        goto done;
+    }
+
+    hr = pmt->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
+    if (FAILED(hr))
+    {
+        goto done;
+    }
+
+    hr = pmt->SetGUID(MF_MT_SUBTYPE, g_MediaSubtypes[dwTypeIndex]);
+    if (FAILED(hr))
+    {
+        goto done;
+    }
+
+    *ppmt = pmt;
+    (*ppmt)->AddRef();
+
+done:
+    SafeRelease(&pmt);
+    return hr;
+}
+
+
+// Validate an input media type.
+
+HRESULT OcvImageManipulations::OnCheckInputType(IMFMediaType *pmt)
+{
+    assert(pmt != NULL);
+
+    HRESULT hr = S_OK;
+
+    // If the output type is set, see if they match.
+    if (m_pOutputType != NULL)
+    {
+        DWORD flags = 0;
+        hr = pmt->IsEqual(m_pOutputType, &flags);
+
+        // IsEqual can return S_FALSE. Treat this as failure.
+        if (hr != S_OK)
+        {
+            hr = MF_E_INVALIDMEDIATYPE;
+        }
+    }
+    else
+    {
+        // Output type is not set. Just check this type.
+        hr = OnCheckMediaType(pmt);
+    }
+    return hr;
+}
+
+
+// Validate an output media type.
+
+HRESULT OcvImageManipulations::OnCheckOutputType(IMFMediaType *pmt)
+{
+    assert(pmt != NULL);
+
+    HRESULT hr = S_OK;
+
+    // If the input type is set, see if they match.
+    if (m_pInputType != NULL)
+    {
+        DWORD flags = 0;
+        hr = pmt->IsEqual(m_pInputType, &flags);
+
+        // IsEqual can return S_FALSE. Treat this as failure.
+        if (hr != S_OK)
+        {
+            hr = MF_E_INVALIDMEDIATYPE;
+        }
+
+    }
+    else
+    {
+        // Input type is not set. Just check this type.
+        hr = OnCheckMediaType(pmt);
+    }
+    return hr;
+}
+
+
+// Validate a media type (input or output)
+
+HRESULT OcvImageManipulations::OnCheckMediaType(IMFMediaType *pmt)
+{
+    BOOL bFoundMatchingSubtype = FALSE;
+
+    // Major type must be video.
+    GUID major_type;
+    HRESULT hr = pmt->GetGUID(MF_MT_MAJOR_TYPE, &major_type);
+    if (FAILED(hr))
+    {
+        goto done;
+    }
+
+    if (major_type != MFMediaType_Video)
+    {
+        hr = MF_E_INVALIDMEDIATYPE;
+        goto done;
+    }
+
+    // Subtype must be one of the subtypes in our global list.
+
+    // Get the subtype GUID.
+    GUID subtype;
+    hr = pmt->GetGUID(MF_MT_SUBTYPE, &subtype);
+    if (FAILED(hr))
+    {
+        goto done;
+    }
+
+    // Look for the subtype in our list of accepted types.
+    for (DWORD i = 0; i < ARRAYSIZE(g_MediaSubtypes); i++)
+    {
+        if (subtype == g_MediaSubtypes[i])
+        {
+            bFoundMatchingSubtype = TRUE;
+            break;
+        }
+    }
+
+    if (!bFoundMatchingSubtype)
+    {
+        hr = MF_E_INVALIDMEDIATYPE; // The MFT does not support this subtype.
+        goto done;
+    }
+
+    // Reject single-field media types.
+    UINT32 interlace = MFGetAttributeUINT32(pmt, MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
+    if (interlace == MFVideoInterlace_FieldSingleUpper  || interlace == MFVideoInterlace_FieldSingleLower)
+    {
+        hr = MF_E_INVALIDMEDIATYPE;
+    }
+
+done:
+    return hr;
+}
+
+
+// Set or clear the input media type.
+//
+// Prerequisite: The input type was already validated.
+
+void OcvImageManipulations::OnSetInputType(IMFMediaType *pmt)
+{
+    // if pmt is NULL, clear the type.
+    // if pmt is non-NULL, set the type.
+
+    SafeRelease(&m_pInputType);
+    m_pInputType = pmt;
+    if (m_pInputType)
+    {
+        m_pInputType->AddRef();
+    }
+
+    // Update the format information.
+    UpdateFormatInfo();
+}
+
+
+// Set or clears the output media type.
+//
+// Prerequisite: The output type was already validated.
+
+void OcvImageManipulations::OnSetOutputType(IMFMediaType *pmt)
+{
+    // If pmt is NULL, clear the type. Otherwise, set the type.
+
+    SafeRelease(&m_pOutputType);
+    m_pOutputType = pmt;
+    if (m_pOutputType)
+    {
+        m_pOutputType->AddRef();
+    }
+}
+
+
+// Initialize streaming parameters.
+//
+// This method is called if the client sends the MFT_MESSAGE_NOTIFY_BEGIN_STREAMING
+// message, or when the client processes a sample, whichever happens first.
+
+HRESULT OcvImageManipulations::BeginStreaming()
+{
+    HRESULT hr = S_OK;
+
+    if (!m_bStreamingInitialized)
+    {
+        m_bStreamingInitialized = true;
+        hr = S_OK;
+    }
+
+    return hr;
+}
+
+
+// End streaming.
+
+// This method is called if the client sends an MFT_MESSAGE_NOTIFY_END_STREAMING
+// message, or when the media type changes. In general, it should be called whenever
+// the streaming parameters need to be reset.
+
+HRESULT OcvImageManipulations::EndStreaming()
+{
+    m_bStreamingInitialized = false;
+    return S_OK;
+}
+
+
+
+// Generate output data.
+
+HRESULT OcvImageManipulations::OnProcessOutput(IMFMediaBuffer *pIn, IMFMediaBuffer *pOut)
+{
+    BYTE *pDest = NULL;         // Destination buffer.
+    LONG lDestStride = 0;       // Destination stride.
+
+    BYTE *pSrc = NULL;          // Source buffer.
+    LONG lSrcStride = 0;        // Source stride.
+
+    // Helper objects to lock the buffers.
+    VideoBufferLock inputLock(pIn);
+    VideoBufferLock outputLock(pOut);
+
+    // Stride if the buffer does not support IMF2DBuffer
+    LONG lDefaultStride = 0;
+
+    HRESULT hr = GetDefaultStride(m_pInputType, &lDefaultStride);
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+
+    // Lock the input buffer.
+    hr = inputLock.LockBuffer(lDefaultStride, m_imageHeightInPixels, &pSrc, &lSrcStride);
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+
+    // Lock the output buffer.
+    hr = outputLock.LockBuffer(lDefaultStride, m_imageHeightInPixels, &pDest, &lDestStride);
+    if (FAILED(hr))
+    {
+        return hr;
+    }
+
+    cv::Mat InputFrame(m_imageHeightInPixels + m_imageHeightInPixels/2, m_imageWidthInPixels, CV_8UC1, pSrc, lSrcStride);
+    cv::Mat InputGreyScale(InputFrame, cv::Range(0, m_imageHeightInPixels), cv::Range(0, m_imageWidthInPixels));
+    cv::Mat OutputFrame(m_imageHeightInPixels + m_imageHeightInPixels/2, m_imageWidthInPixels, CV_8UC1, pDest, lDestStride);
+
+    switch (m_TransformType)
+    {
+    case Preview:
+        {
+            InputFrame.copyTo(OutputFrame);
+        } break;
+    case GrayScale:
+        {
+            OutputFrame.setTo(cv::Scalar(128));
+            cv::Mat OutputGreyScale(OutputFrame, cv::Range(0, m_imageHeightInPixels), cv::Range(0, m_imageWidthInPixels));
+            InputGreyScale.copyTo(OutputGreyScale);
+        } break;
+    case Canny:
+        {
+            OutputFrame.setTo(cv::Scalar(128));
+            cv::Mat OutputGreyScale(OutputFrame, cv::Range(0, m_imageHeightInPixels), cv::Range(0, m_imageWidthInPixels));
+            cv::Canny(InputGreyScale, OutputGreyScale, 80, 90);
+
+        } break;
+    case Sobel:
+        {
+            OutputFrame.setTo(cv::Scalar(128));
+            cv::Mat OutputGreyScale(OutputFrame, cv::Range(0, m_imageHeightInPixels), cv::Range(0, m_imageWidthInPixels));
+            cv::Sobel(InputGreyScale, OutputGreyScale, CV_8U, 1, 1);
+        } break;
+    case Histogram:
+        {
+            const int mHistSizeNum = 25;
+            const int channels[3][1] = {{0}, {1}, {2}};
+            const int mHistSize[] = {25};
+            const float baseRabge[] = {0.f,256.f};
+            const float* ranges[] = {baseRabge};
+            
+                       const cv::Scalar mColorsY[] = { cv::Scalar(76), cv::Scalar(149), cv::Scalar(29) };
+                       const cv::Scalar mColorsUV[] = { cv::Scalar(84, 255), cv::Scalar(43, 21), cv::Scalar(255, 107) };
+
+                       cv::Mat OutputY(m_imageHeightInPixels, m_imageWidthInPixels, CV_8UC1, pDest, lDestStride);
+                       cv::Mat OutputUV(m_imageHeightInPixels/2, m_imageWidthInPixels/2,
+                                                        CV_8UC2, pDest+m_imageHeightInPixels*lDestStride, lDestStride);
+            cv::Mat BgrFrame;
+
+                       InputFrame.copyTo(OutputFrame);
+
+            cv::cvtColor(InputFrame, BgrFrame, cv::COLOR_YUV420sp2BGR);
+            int thikness = (int) (BgrFrame.cols / (mHistSizeNum + 10) / 5);
+            if(thikness > 5) thikness = 5;
+            int offset = (int) ((BgrFrame.cols - (5*mHistSizeNum + 4*10)*thikness)/2);
+
+            // RGB
+            for (int c=0; c<3; c++)
+            {
+                cv::Mat hist;
+                cv::calcHist(&BgrFrame, 1, channels[c], cv::Mat(), hist, 1, mHistSize, ranges);
+                cv::normalize(hist, hist, BgrFrame.rows/2, 0, cv::NORM_INF);
+                for(int h=0; h<mHistSizeNum; h++) {
+                    cv::Point mP1, mP2;
+                                       // Draw on Y plane
+                                       mP1.x = mP2.x = offset + (c * (mHistSizeNum + 10) + h) * thikness;
+                    mP1.y = BgrFrame.rows-1;
+                    mP2.y = mP1.y - 2 - (int)hist.at<float>(h);
+                                       cv::line(OutputY, mP1, mP2, mColorsY[c], thikness);
+
+                                       // Draw on UV planes
+                    mP1.x /= 2;
+                    mP1.y /= 2;
+                                       mP2.x /= 2;
+                    mP2.y /= 2;
+                                       cv::line(OutputUV, mP1, mP2, mColorsUV[c], thikness/2);
+                }
+            }            
+        } break;
+    default:
+        break;
+    }
+
+    // Set the data size on the output buffer.
+    hr = pOut->SetCurrentLength(m_cbImageSize);
+
+    return hr;
+}
+
+
+// Flush the MFT.
+
+HRESULT OcvImageManipulations::OnFlush()
+{
+    // For this MFT, flushing just means releasing the input sample.
+    SafeRelease(&m_pSample);
+    return S_OK;
+}
+
+
+// Update the format information. This method is called whenever the
+// input type is set.
+
+HRESULT OcvImageManipulations::UpdateFormatInfo()
+{
+    HRESULT hr = S_OK;
+
+    GUID subtype = GUID_NULL;
+
+    m_imageWidthInPixels = 0;
+    m_imageHeightInPixels = 0;
+    m_cbImageSize = 0;
+
+    if (m_pInputType != NULL)
+    {
+        hr = m_pInputType->GetGUID(MF_MT_SUBTYPE, &subtype);
+        if (FAILED(hr))
+        {
+            goto done;
+        }
+        if (subtype != MFVideoFormat_NV12)
+        {
+            hr = E_UNEXPECTED;
+            goto done;
+        }
+
+        hr = MFGetAttributeSize(m_pInputType, MF_MT_FRAME_SIZE, &m_imageWidthInPixels, &m_imageHeightInPixels);
+        if (FAILED(hr))
+        {
+            goto done;
+        }
+
+        // Calculate the image size for YUV NV12 image(not including padding)
+               m_cbImageSize = (m_imageHeightInPixels + m_imageHeightInPixels/2)*m_imageWidthInPixels;
+    }
+
+done:
+    return hr;
+}
+
+
+// Get the default stride for a video format.
+HRESULT GetDefaultStride(IMFMediaType *pType, LONG *plStride)
+{
+    LONG lStride = 0;
+
+    // Try to get the default stride from the media type.
+    HRESULT hr = pType->GetUINT32(MF_MT_DEFAULT_STRIDE, (UINT32*)&lStride);
+    if (FAILED(hr))
+    {
+        // Attribute not set. Try to calculate the default stride.
+        GUID subtype = GUID_NULL;
+
+        UINT32 width = 0;
+        UINT32 height = 0;
+
+        // Get the subtype and the image size.
+        hr = pType->GetGUID(MF_MT_SUBTYPE, &subtype);
+        if (SUCCEEDED(hr))
+        {
+            hr = MFGetAttributeSize(pType, MF_MT_FRAME_SIZE, &width, &height);
+        }
+        if (SUCCEEDED(hr))
+        {
+            if (subtype == MFVideoFormat_NV12)
+            {
+                lStride = width;
+            }
+            else if (subtype == MFVideoFormat_YUY2 || subtype == MFVideoFormat_UYVY)
+            {
+                lStride = ((width * 2) + 3) & ~3;
+            }
+            else
+            {
+                hr = E_INVALIDARG;
+            }
+        }
+
+        // Set the attribute for later reference.
+        if (SUCCEEDED(hr))
+        {
+            (void)pType->SetUINT32(MF_MT_DEFAULT_STRIDE, UINT32(lStride));
+        }
+    }
+    if (SUCCEEDED(hr))
+    {
+        *plStride = lStride;
+    }
+    return hr;
+}
+
diff --git a/samples/winrt/ImageManipulations/MediaExtensions/OcvTransform/OcvTransform.def b/samples/winrt/ImageManipulations/MediaExtensions/OcvTransform/OcvTransform.def
new file mode 100644 (file)
index 0000000..0b80190
--- /dev/null
@@ -0,0 +1,4 @@
+EXPORTS
+    DllCanUnloadNow                     PRIVATE
+    DllGetActivationFactory             PRIVATE
+    DllGetClassObject                   PRIVATE
\ No newline at end of file
diff --git a/samples/winrt/ImageManipulations/MediaExtensions/OcvTransform/OcvTransform.h b/samples/winrt/ImageManipulations/MediaExtensions/OcvTransform/OcvTransform.h
new file mode 100644 (file)
index 0000000..118f6e4
--- /dev/null
@@ -0,0 +1,247 @@
+// Defines the transform class.
+//
+// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
+// PARTICULAR PURPOSE.
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+
+#ifndef GRAYSCALE_H
+#define GRAYSCALE_H
+
+#include <new>
+#include <mfapi.h>
+#include <mftransform.h>
+#include <mfidl.h>
+#include <mferror.h>
+#include <strsafe.h>
+#include <assert.h>
+
+#include <wrl\implements.h>
+#include <wrl\module.h>
+#include <windows.media.h>
+
+#include "OcvImageManipulations.h"
+
+// CLSID of the MFT.
+DEFINE_GUID(CLSID_GrayscaleMFT,
+0x2f3dbc05, 0xc011, 0x4a8f, 0xb2, 0x64, 0xe4, 0x2e, 0x35, 0xc6, 0x7b, 0xf4);
+
+//
+// * IMPORTANT: If you implement your own MFT, create a new GUID for the CLSID. *
+//
+
+
+// Configuration attributes
+// {698649BE-8EAE-4551-A4CB-3EC98FBD3D86}
+DEFINE_GUID(OCV_IMAGE_EFFECT,
+0x698649be, 0x8eae, 0x4551, 0xa4, 0xcb, 0x3e, 0xc9, 0x8f, 0xbd, 0x3d, 0x86);
+
+
+enum ProcessingType
+{
+    Preview,
+    GrayScale,
+    Canny,
+    Sobel,
+    Histogram,
+    InvalidEffect
+};
+
+template <class T> void SafeRelease(T **ppT)
+{
+    if (*ppT)
+    {
+        (*ppT)->Release();
+        *ppT = NULL;
+    }
+}
+
+// OcvImageManipulations class:
+// Implements a grayscale video effect.
+
+class OcvImageManipulations
+    : public Microsoft::WRL::RuntimeClass<
+           Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::RuntimeClassType::WinRtClassicComMix >,
+           ABI::Windows::Media::IMediaExtension,
+           IMFTransform >
+{
+    InspectableClass(RuntimeClass_OcvTransform_OcvImageManipulations, BaseTrust)
+
+public:
+    OcvImageManipulations();
+
+    ~OcvImageManipulations();
+
+    STDMETHOD(RuntimeClassInitialize)();
+
+    // IMediaExtension
+    STDMETHODIMP SetProperties(ABI::Windows::Foundation::Collections::IPropertySet *pConfiguration);
+
+    // IMFTransform
+    STDMETHODIMP GetStreamLimits(
+        DWORD   *pdwInputMinimum,
+        DWORD   *pdwInputMaximum,
+        DWORD   *pdwOutputMinimum,
+        DWORD   *pdwOutputMaximum
+    );
+
+    STDMETHODIMP GetStreamCount(
+        DWORD   *pcInputStreams,
+        DWORD   *pcOutputStreams
+    );
+
+    STDMETHODIMP GetStreamIDs(
+        DWORD   dwInputIDArraySize,
+        DWORD   *pdwInputIDs,
+        DWORD   dwOutputIDArraySize,
+        DWORD   *pdwOutputIDs
+    );
+
+    STDMETHODIMP GetInputStreamInfo(
+        DWORD                     dwInputStreamID,
+        MFT_INPUT_STREAM_INFO *   pStreamInfo
+    );
+
+    STDMETHODIMP GetOutputStreamInfo(
+        DWORD                     dwOutputStreamID,
+        MFT_OUTPUT_STREAM_INFO *  pStreamInfo
+    );
+
+    STDMETHODIMP GetAttributes(IMFAttributes** pAttributes);
+
+    STDMETHODIMP GetInputStreamAttributes(
+        DWORD           dwInputStreamID,
+        IMFAttributes   **ppAttributes
+    );
+
+    STDMETHODIMP GetOutputStreamAttributes(
+        DWORD           dwOutputStreamID,
+        IMFAttributes   **ppAttributes
+    );
+
+    STDMETHODIMP DeleteInputStream(DWORD dwStreamID);
+
+    STDMETHODIMP AddInputStreams(
+        DWORD   cStreams,
+        DWORD   *adwStreamIDs
+    );
+
+    STDMETHODIMP GetInputAvailableType(
+        DWORD           dwInputStreamID,
+        DWORD           dwTypeIndex, // 0-based
+        IMFMediaType    **ppType
+    );
+
+    STDMETHODIMP GetOutputAvailableType(
+        DWORD           dwOutputStreamID,
+        DWORD           dwTypeIndex, // 0-based
+        IMFMediaType    **ppType
+    );
+
+    STDMETHODIMP SetInputType(
+        DWORD           dwInputStreamID,
+        IMFMediaType    *pType,
+        DWORD           dwFlags
+    );
+
+    STDMETHODIMP SetOutputType(
+        DWORD           dwOutputStreamID,
+        IMFMediaType    *pType,
+        DWORD           dwFlags
+    );
+
+    STDMETHODIMP GetInputCurrentType(
+        DWORD           dwInputStreamID,
+        IMFMediaType    **ppType
+    );
+
+    STDMETHODIMP GetOutputCurrentType(
+        DWORD           dwOutputStreamID,
+        IMFMediaType    **ppType
+    );
+
+    STDMETHODIMP GetInputStatus(
+        DWORD           dwInputStreamID,
+        DWORD           *pdwFlags
+    );
+
+    STDMETHODIMP GetOutputStatus(DWORD *pdwFlags);
+
+    STDMETHODIMP SetOutputBounds(
+        LONGLONG        hnsLowerBound,
+        LONGLONG        hnsUpperBound
+    );
+
+    STDMETHODIMP ProcessEvent(
+        DWORD              dwInputStreamID,
+        IMFMediaEvent      *pEvent
+    );
+
+    STDMETHODIMP ProcessMessage(
+        MFT_MESSAGE_TYPE    eMessage,
+        ULONG_PTR           ulParam
+    );
+
+    STDMETHODIMP ProcessInput(
+        DWORD               dwInputStreamID,
+        IMFSample           *pSample,
+        DWORD               dwFlags
+    );
+
+    STDMETHODIMP ProcessOutput(
+        DWORD                   dwFlags,
+        DWORD                   cOutputBufferCount,
+        MFT_OUTPUT_DATA_BUFFER  *pOutputSamples, // one per stream
+        DWORD                   *pdwStatus
+    );
+
+
+private:
+    // HasPendingOutput: Returns TRUE if the MFT is holding an input sample.
+    BOOL HasPendingOutput() const { return m_pSample != NULL; }
+
+    // IsValidInputStream: Returns TRUE if dwInputStreamID is a valid input stream identifier.
+    BOOL IsValidInputStream(DWORD dwInputStreamID) const
+    {
+        return dwInputStreamID == 0;
+    }
+
+    // IsValidOutputStream: Returns TRUE if dwOutputStreamID is a valid output stream identifier.
+    BOOL IsValidOutputStream(DWORD dwOutputStreamID) const
+    {
+        return dwOutputStreamID == 0;
+    }
+
+    HRESULT OnGetPartialType(DWORD dwTypeIndex, IMFMediaType **ppmt);
+    HRESULT OnCheckInputType(IMFMediaType *pmt);
+    HRESULT OnCheckOutputType(IMFMediaType *pmt);
+    HRESULT OnCheckMediaType(IMFMediaType *pmt);
+    void    OnSetInputType(IMFMediaType *pmt);
+    void    OnSetOutputType(IMFMediaType *pmt);
+    HRESULT BeginStreaming();
+    HRESULT EndStreaming();
+    HRESULT OnProcessOutput(IMFMediaBuffer *pIn, IMFMediaBuffer *pOut);
+    HRESULT OnFlush();
+    HRESULT UpdateFormatInfo();
+
+    CRITICAL_SECTION            m_critSec;
+
+    // Transformation parameters
+    ProcessingType              m_TransformType;
+
+    // Streaming
+    bool                        m_bStreamingInitialized;
+    IMFSample                   *m_pSample;                 // Input sample.
+    IMFMediaType                *m_pInputType;              // Input media type.
+    IMFMediaType                *m_pOutputType;             // Output media type.
+
+    // Fomat information
+    UINT32                      m_imageWidthInPixels;
+    UINT32                      m_imageHeightInPixels;
+    DWORD                       m_cbImageSize;              // Image size, in bytes.
+
+    IMFAttributes               *m_pAttributes;
+};
+#endif
\ No newline at end of file
diff --git a/samples/winrt/ImageManipulations/MediaExtensions/OcvTransform/OcvTransform.vcxproj b/samples/winrt/ImageManipulations/MediaExtensions/OcvTransform/OcvTransform.vcxproj
new file mode 100644 (file)
index 0000000..fbe768c
--- /dev/null
@@ -0,0 +1,319 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|ARM">
+      <Configuration>Debug</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|ARM">
+      <Configuration>Release</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCTargetsPath Condition="'$(VCTargetsPath11)' != '' and '$(VSVersion)' == '' and '$(VisualStudioVersion)' == ''">$(VCTargetsPath11)</VCTargetsPath>
+    <ProjectGuid>{BA69218F-DA5C-4D14-A78D-21A9E4DEC669}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>OcvTransform</RootNamespace>
+    <ProjectName>OcvTransform</ProjectName>
+    <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+    <AppContainerApplication>true</AppContainerApplication>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <PropertyGroup>
+    <DefaultLanguage>en-US</DefaultLanguage>
+  </PropertyGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <GenerateManifest>false</GenerateManifest>
+    <OutDir>$(Configuration)\$(MSBuildProjectName)\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+    <GenerateManifest>false</GenerateManifest>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <GenerateManifest>false</GenerateManifest>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <GenerateManifest>false</GenerateManifest>
+    <OutDir>$(Configuration)\$(MSBuildProjectName)\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+    <GenerateManifest>false</GenerateManifest>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <GenerateManifest>false</GenerateManifest>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PreprocessorDefinitions>_WINRT_DLL;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile>
+      </PrecompiledHeaderFile>
+      <PrecompiledHeaderOutputFile>
+      </PrecompiledHeaderOutputFile>
+      <AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+      <CompileAsWinRT>false</CompileAsWinRT>
+      <AdditionalIncludeDirectories>$(OPENCV_DIR)\include;$(ProjectDir);$(IntermediateOutputPath);%(AdditionalIncludeDirectories);$(ProjectDir)\..\Common</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <AdditionalDependencies>runtimeobject.lib;%(AdditionalDependencies);mf.lib;mfuuid.lib;mfplat.lib;opencv_core245.lib;opencv_imgproc245.lib</AdditionalDependencies>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <ModuleDefinitionFile>OcvTransform.def</ModuleDefinitionFile>
+      <AdditionalLibraryDirectories>$(OPENCV_DIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
+    <CustomBuildStep>
+      <Command>mdmerge -metadata_dir "$(WindowsSDK_MetadataPath)" -o "$(ProjectDir)$(Configuration)\$(MSBuildProjectName)" -i "$(MSBuildProjectDirectory)" -v -partial</Command>
+      <Outputs>$(ProjectDir)$(Configuration)\$(MSBuildProjectName)\$(ProjectName).winmd</Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PreprocessorDefinitions>_WINRT_DLL;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile>
+      </PrecompiledHeaderFile>
+      <PrecompiledHeaderOutputFile>
+      </PrecompiledHeaderOutputFile>
+      <AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+      <CompileAsWinRT>false</CompileAsWinRT>
+      <AdditionalIncludeDirectories>$(OPENCV_DIR)\include;$(ProjectDir);$(IntermediateOutputPath);%(AdditionalIncludeDirectories);$(ProjectDir)\..\Common</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <AdditionalDependencies>runtimeobject.lib;%(AdditionalDependencies);mf.lib;mfuuid.lib;mfplat.lib</AdditionalDependencies>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <ModuleDefinitionFile>OcvTransform.def</ModuleDefinitionFile>
+      <AdditionalLibraryDirectories>$(OPENCV_DIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
+    <CustomBuildStep>
+      <Command>mdmerge -metadata_dir "$(WindowsSDK_MetadataPath)" -o "$(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)" -i "$(MSBuildProjectDirectory)" -v -partial</Command>
+      <Outputs>$(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)\$(ProjectName).winmd</Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PreprocessorDefinitions>_WINRT_DLL;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile>
+      </PrecompiledHeaderFile>
+      <PrecompiledHeaderOutputFile>
+      </PrecompiledHeaderOutputFile>
+      <AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+      <CompileAsWinRT>false</CompileAsWinRT>
+      <AdditionalIncludeDirectories>$(OPENCV_DIR)\include;$(ProjectDir);$(IntermediateOutputPath);%(AdditionalIncludeDirectories);$(ProjectDir)\..\Common</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <AdditionalDependencies>runtimeobject.lib;%(AdditionalDependencies);mf.lib;mfuuid.lib;mfplat.lib</AdditionalDependencies>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <ModuleDefinitionFile>OcvTransform.def</ModuleDefinitionFile>
+      <AdditionalLibraryDirectories>$(OPENCV_DIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
+    <CustomBuildStep>
+      <Command>mdmerge -metadata_dir "$(WindowsSDK_MetadataPath)" -o "$(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)" -i "$(MSBuildProjectDirectory)" -v -partial</Command>
+      <Outputs>$(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)\$(ProjectName).winmd</Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PreprocessorDefinitions>_WINRT_DLL;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile>
+      </PrecompiledHeaderFile>
+      <PrecompiledHeaderOutputFile>
+      </PrecompiledHeaderOutputFile>
+      <AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+      <CompileAsWinRT>false</CompileAsWinRT>
+      <AdditionalIncludeDirectories>$(OPENCV_DIR)\include;$(ProjectDir);$(IntermediateOutputPath);%(AdditionalIncludeDirectories);$(ProjectDir)\..\Common</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <AdditionalDependencies>runtimeobject.lib;%(AdditionalDependencies);mf.lib;mfuuid.lib;mfplat.lib</AdditionalDependencies>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <ModuleDefinitionFile>OcvTransform.def</ModuleDefinitionFile>
+      <AdditionalLibraryDirectories>$(OPENCV_DIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
+    <CustomBuildStep>
+      <Command>mdmerge -metadata_dir "$(WindowsSDK_MetadataPath)" -o "$(ProjectDir)$(Configuration)\$(MSBuildProjectName)" -i "$(MSBuildProjectDirectory)" -v -partial</Command>
+      <Outputs>$(ProjectDir)$(Configuration)\$(MSBuildProjectName)\$(ProjectName).winmd</Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PreprocessorDefinitions>_WINRT_DLL;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile>
+      </PrecompiledHeaderFile>
+      <PrecompiledHeaderOutputFile>
+      </PrecompiledHeaderOutputFile>
+      <AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+      <CompileAsWinRT>false</CompileAsWinRT>
+      <AdditionalIncludeDirectories>$(OPENCV_DIR)\include;$(ProjectDir);$(IntermediateOutputPath);%(AdditionalIncludeDirectories);$(ProjectDir)\..\Common</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <AdditionalDependencies>runtimeobject.lib;%(AdditionalDependencies);mf.lib;mfuuid.lib;mfplat.lib</AdditionalDependencies>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <ModuleDefinitionFile>OcvTransform.def</ModuleDefinitionFile>
+      <AdditionalLibraryDirectories>$(OPENCV_DIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
+    <CustomBuildStep>
+      <Command>mdmerge -metadata_dir "$(WindowsSDK_MetadataPath)" -o "$(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)" -i "$(MSBuildProjectDirectory)" -v -partial</Command>
+      <Outputs>$(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)\$(ProjectName).winmd</Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PreprocessorDefinitions>_WINRT_DLL;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile>
+      </PrecompiledHeaderFile>
+      <PrecompiledHeaderOutputFile>
+      </PrecompiledHeaderOutputFile>
+      <AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+      <CompileAsWinRT>false</CompileAsWinRT>
+      <AdditionalIncludeDirectories>$(OPENCV_DIR)\include;$(ProjectDir);$(IntermediateOutputPath);%(AdditionalIncludeDirectories);$(ProjectDir)\..\Common</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <AdditionalDependencies>runtimeobject.lib;%(AdditionalDependencies);mf.lib;mfuuid.lib;mfplat.lib</AdditionalDependencies>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <ModuleDefinitionFile>OcvTransform.def</ModuleDefinitionFile>
+      <AdditionalLibraryDirectories>$(OPENCV_DIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
+    <CustomBuildStep>
+      <Command>mdmerge -metadata_dir "$(WindowsSDK_MetadataPath)" -o "$(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)" -i "$(MSBuildProjectDirectory)" -v -partial</Command>
+      <Outputs>$(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)\$(ProjectName).winmd</Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="OcvTransform.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="dllmain.cpp" />
+    <ClCompile Include="OcvTransform.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="OcvTransform.def" />
+  </ItemGroup>
+  <ItemGroup>
+    <Midl Include="OcvImageManipulations.idl">
+      <MetadataFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+      </MetadataFileName>
+      <MetadataFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+      </MetadataFileName>
+      <MetadataFileName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+      </MetadataFileName>
+      <MetadataFileName Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+      </MetadataFileName>
+      <MetadataFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+      </MetadataFileName>
+      <MetadataFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+      </MetadataFileName>
+      <AdditionalMetadataDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(WindowsSDK_MetadataPath)</AdditionalMetadataDirectories>
+      <AdditionalMetadataDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(WindowsSDK_MetadataPath)</AdditionalMetadataDirectories>
+      <AdditionalMetadataDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">$(WindowsSDK_MetadataPath)</AdditionalMetadataDirectories>
+      <AdditionalMetadataDirectories Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">$(WindowsSDK_MetadataPath)</AdditionalMetadataDirectories>
+      <AdditionalMetadataDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(WindowsSDK_MetadataPath)</AdditionalMetadataDirectories>
+      <AdditionalMetadataDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(WindowsSDK_MetadataPath)</AdditionalMetadataDirectories>
+      <EnableWindowsRuntime Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</EnableWindowsRuntime>
+      <EnableWindowsRuntime Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</EnableWindowsRuntime>
+      <EnableWindowsRuntime Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</EnableWindowsRuntime>
+      <EnableWindowsRuntime Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</EnableWindowsRuntime>
+      <EnableWindowsRuntime Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</EnableWindowsRuntime>
+      <EnableWindowsRuntime Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</EnableWindowsRuntime>
+      <HeaderFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(Filename).h</HeaderFileName>
+      <HeaderFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(Filename).h</HeaderFileName>
+      <HeaderFileName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">%(Filename).h</HeaderFileName>
+      <HeaderFileName Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">%(Filename).h</HeaderFileName>
+      <HeaderFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(Filename).h</HeaderFileName>
+      <HeaderFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(Filename).h</HeaderFileName>
+    </Midl>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ItemGroup>
+    <_MdMergeOutput Condition="'$(Platform)' == 'Win32'" Include="$(ProjectDir)$(Configuration)\$(MSBuildProjectName)\$(ProjectName).winmd" />
+    <_MdMergeOutput Condition="'$(Platform)' != 'Win32'" Include="$(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)\$(ProjectName).winmd" />
+  </ItemGroup>
+  <Target Name="CopyWinmdArtifactsOutputGroup" Returns="@(CopyWinmdArtifactsOutputGroupOutputs)">
+    <ItemGroup>
+      <CopyWinmdArtifactsOutputGroupOutputs Include="@(_MdMergeOutput)">
+        <TargetPath>$(ProjectName).winmd</TargetPath>
+        <Implementation>$(TargetName)$(TargetExt)</Implementation>
+      </CopyWinmdArtifactsOutputGroupOutputs>
+    </ItemGroup>
+  </Target>
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/samples/winrt/ImageManipulations/MediaExtensions/OcvTransform/dllmain.cpp b/samples/winrt/ImageManipulations/MediaExtensions/OcvTransform/dllmain.cpp
new file mode 100644 (file)
index 0000000..d11bcea
--- /dev/null
@@ -0,0 +1,58 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// dllmain.cpp
+//
+// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
+// PARTICULAR PURPOSE.
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include <initguid.h>
+#include "OcvTransform.h"
+
+using namespace Microsoft::WRL;
+
+namespace Microsoft { namespace Samples {
+       ActivatableClass(OcvImageManipulations);
+}}
+
+BOOL WINAPI DllMain( _In_ HINSTANCE hInstance, _In_ DWORD dwReason, _In_opt_ LPVOID lpReserved )
+{
+    if( DLL_PROCESS_ATTACH == dwReason )
+    {
+        //
+        //  Don't need per-thread callbacks
+        //
+        DisableThreadLibraryCalls( hInstance );
+
+        Module<InProc>::GetModule().Create();
+    }
+    else if( DLL_PROCESS_DETACH == dwReason )
+    {
+        Module<InProc>::GetModule().Terminate();
+    }
+
+    return TRUE;
+}
+
+HRESULT WINAPI DllGetActivationFactory( _In_ HSTRING activatibleClassId, _Outptr_ IActivationFactory** factory )
+{
+    auto &module = Microsoft::WRL::Module< Microsoft::WRL::InProc >::GetModule();
+    return module.GetActivationFactory( activatibleClassId, factory );
+}
+
+HRESULT WINAPI DllCanUnloadNow()
+{
+    auto &module = Microsoft::WRL::Module<Microsoft::WRL::InProc>::GetModule();    
+    return (module.Terminate()) ? S_OK : S_FALSE;
+}
+
+STDAPI DllGetClassObject( _In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID FAR* ppv )
+{
+    auto &module = Microsoft::WRL::Module<Microsoft::WRL::InProc>::GetModule();
+    return module.GetClassObject( rclsid, riid, ppv );
+}
diff --git a/samples/winrt/ImageManipulations/Package.appxmanifest b/samples/winrt/ImageManipulations/Package.appxmanifest
new file mode 100644 (file)
index 0000000..9d63dea
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">
+  <Identity Name="Microsoft.SDKSamples.MediaCapture.CPP" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" Version="1.0.0.0" />
+  <Properties>
+    <DisplayName>MediaCapture CPP sample</DisplayName>
+    <PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
+    <Logo>Assets\storeLogo-sdk.png</Logo>
+  </Properties>
+  <Prerequisites>
+    <OSMinVersion>6.2.1</OSMinVersion>
+    <OSMaxVersionTested>6.2.1</OSMaxVersionTested>
+  </Prerequisites>
+  <Resources>
+    <Resource Language="x-generate" />
+  </Resources>
+  <Applications>
+    <Application Id="MediaCapture.App" Executable="$targetnametoken$.exe" EntryPoint="MediaCapture.App">
+      <VisualElements DisplayName="OCV Image Manipulations" Logo="assets\opencv-logo-150.png" SmallLogo="assets\opencv-logo-30.png" Description="OpenCV Image Manipulations sample" ForegroundText="light" BackgroundColor="#00b2f0">
+        <DefaultTile ShortName="Ocv ImageManipulations" ShowName="allLogos" />
+        <SplashScreen Image="Assets\splash-sdk.png" BackgroundColor="#00b2f0" />
+      </VisualElements>
+    </Application>
+  </Applications>
+  <Capabilities>
+    <DeviceCapability Name="webcam" />
+    <DeviceCapability Name="microphone" />
+  </Capabilities>
+  <Extensions>
+    <Extension Category="windows.activatableClass.inProcessServer">
+      <InProcessServer>
+        <Path>OcvTransform.dll</Path>
+        <ActivatableClass ActivatableClassId="OcvTransform.OcvImageManipulations" ThreadingModel="both" />
+      </InProcessServer>
+    </Extension>
+  </Extensions>
+</Package>
\ No newline at end of file
diff --git a/samples/winrt/ImageManipulations/assets/opencv-logo-150.png b/samples/winrt/ImageManipulations/assets/opencv-logo-150.png
new file mode 100644 (file)
index 0000000..ea685d6
Binary files /dev/null and b/samples/winrt/ImageManipulations/assets/opencv-logo-150.png differ
diff --git a/samples/winrt/ImageManipulations/assets/opencv-logo-30.png b/samples/winrt/ImageManipulations/assets/opencv-logo-30.png
new file mode 100644 (file)
index 0000000..efaf546
Binary files /dev/null and b/samples/winrt/ImageManipulations/assets/opencv-logo-30.png differ
diff --git a/samples/winrt/ImageManipulations/assets/splash-sdk.png b/samples/winrt/ImageManipulations/assets/splash-sdk.png
new file mode 100644 (file)
index 0000000..901c3b0
Binary files /dev/null and b/samples/winrt/ImageManipulations/assets/splash-sdk.png differ
diff --git a/samples/winrt/ImageManipulations/assets/windows-sdk.png b/samples/winrt/ImageManipulations/assets/windows-sdk.png
new file mode 100644 (file)
index 0000000..6726802
Binary files /dev/null and b/samples/winrt/ImageManipulations/assets/windows-sdk.png differ
diff --git a/samples/winrt/ImageManipulations/common/LayoutAwarePage.cpp b/samples/winrt/ImageManipulations/common/LayoutAwarePage.cpp
new file mode 100644 (file)
index 0000000..9449fbe
--- /dev/null
@@ -0,0 +1,452 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+#include "pch.h"
+#include "LayoutAwarePage.h"
+#include "SuspensionManager.h"
+
+using namespace SDKSample::Common;
+
+using namespace Platform;
+using namespace Platform::Collections;
+using namespace Windows::Foundation;
+using namespace Windows::Foundation::Collections;
+using namespace Windows::System;
+using namespace Windows::UI::Core;
+using namespace Windows::UI::ViewManagement;
+using namespace Windows::UI::Xaml;
+using namespace Windows::UI::Xaml::Controls;
+using namespace Windows::UI::Xaml::Interop;
+using namespace Windows::UI::Xaml::Navigation;
+
+/// <summary>
+/// Initializes a new instance of the <see cref="LayoutAwarePage"/> class.
+/// </summary>
+LayoutAwarePage::LayoutAwarePage()
+{
+    if (Windows::ApplicationModel::DesignMode::DesignModeEnabled)
+    {
+        return;
+    }
+
+    // Create an empty default view model
+    DefaultViewModel = ref new Map<String^, Object^>(std::less<String^>());
+
+    // When this page is part of the visual tree make two changes:
+    // 1) Map application view state to visual state for the page
+    // 2) Handle keyboard and mouse navigation requests
+    Loaded += ref new RoutedEventHandler(this, &LayoutAwarePage::OnLoaded);
+
+    // Undo the same changes when the page is no longer visible
+    Unloaded += ref new RoutedEventHandler(this, &LayoutAwarePage::OnUnloaded);
+}
+
+static DependencyProperty^ _defaultViewModelProperty =
+    DependencyProperty::Register("DefaultViewModel",
+    TypeName(IObservableMap<String^, Object^>::typeid), TypeName(LayoutAwarePage::typeid), nullptr);
+
+/// <summary>
+/// Identifies the <see cref="DefaultViewModel"/> dependency property.
+/// </summary>
+DependencyProperty^ LayoutAwarePage::DefaultViewModelProperty::get()
+{
+    return _defaultViewModelProperty;
+}
+
+/// <summary>
+/// Gets an implementation of <see cref="IObservableMap&lt;String, Object&gt;"/> designed to be
+/// used as a trivial view model.
+/// </summary>
+IObservableMap<String^, Object^>^ LayoutAwarePage::DefaultViewModel::get()
+{
+    return safe_cast<IObservableMap<String^, Object^>^>(GetValue(DefaultViewModelProperty));
+}
+
+/// <summary>
+/// Sets an implementation of <see cref="IObservableMap&lt;String, Object&gt;"/> designed to be
+/// used as a trivial view model.
+/// </summary>
+void LayoutAwarePage::DefaultViewModel::set(IObservableMap<String^, Object^>^ value)
+{
+    SetValue(DefaultViewModelProperty, value);
+}
+
+/// <summary>
+/// Invoked when the page is part of the visual tree
+/// </summary>
+/// <param name="sender">Instance that triggered the event.</param>
+/// <param name="e">Event data describing the conditions that led to the event.</param>
+void LayoutAwarePage::OnLoaded(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+       this->StartLayoutUpdates(sender, e);
+
+       // Keyboard and mouse navigation only apply when occupying the entire window
+       if (this->ActualHeight == Window::Current->Bounds.Height &&
+               this->ActualWidth == Window::Current->Bounds.Width)
+       {
+               // Listen to the window directly so focus isn't required
+               _acceleratorKeyEventToken = Window::Current->CoreWindow->Dispatcher->AcceleratorKeyActivated +=
+                       ref new TypedEventHandler<CoreDispatcher^, AcceleratorKeyEventArgs^>(this,
+                       &LayoutAwarePage::CoreDispatcher_AcceleratorKeyActivated);
+               _pointerPressedEventToken = Window::Current->CoreWindow->PointerPressed +=
+                       ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this,
+                       &LayoutAwarePage::CoreWindow_PointerPressed);
+               _navigationShortcutsRegistered = true;
+       }
+}
+
+/// <summary>
+/// Invoked when the page is removed from visual tree
+/// </summary>
+/// <param name="sender">Instance that triggered the event.</param>
+/// <param name="e">Event data describing the conditions that led to the event.</param>
+void LayoutAwarePage::OnUnloaded(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+       if (_navigationShortcutsRegistered)
+       {
+               Window::Current->CoreWindow->Dispatcher->AcceleratorKeyActivated -= _acceleratorKeyEventToken;
+               Window::Current->CoreWindow->PointerPressed -= _pointerPressedEventToken;
+               _navigationShortcutsRegistered = false;
+       }
+       StopLayoutUpdates(sender, e);
+}
+
+#pragma region Navigation support
+
+/// <summary>
+/// Invoked as an event handler to navigate backward in the page's associated <see cref="Frame"/>
+/// until it reaches the top of the navigation stack.
+/// </summary>
+/// <param name="sender">Instance that triggered the event.</param>
+/// <param name="e">Event data describing the conditions that led to the event.</param>
+void LayoutAwarePage::GoHome(Object^ sender, RoutedEventArgs^ e)
+{
+    (void) sender;     // Unused parameter
+    (void) e;  // Unused parameter
+
+    // Use the navigation frame to return to the topmost page
+    if (Frame != nullptr)
+    {
+        while (Frame->CanGoBack)
+        {
+            Frame->GoBack();
+        }
+    }
+}
+
+/// <summary>
+/// Invoked as an event handler to navigate backward in the navigation stack
+/// associated with this page's <see cref="Frame"/>.
+/// </summary>
+/// <param name="sender">Instance that triggered the event.</param>
+/// <param name="e">Event data describing the conditions that led to the event.</param>
+void LayoutAwarePage::GoBack(Object^ sender, RoutedEventArgs^ e)
+{
+    (void) sender;     // Unused parameter
+    (void) e;  // Unused parameter
+
+    // Use the navigation frame to return to the previous page
+    if (Frame != nullptr && Frame->CanGoBack)
+    {
+        Frame->GoBack();
+    }
+}
+
+/// <summary>
+/// Invoked as an event handler to navigate forward in the navigation stack
+/// associated with this page's <see cref="Frame"/>.
+/// </summary>
+/// <param name="sender">Instance that triggered the event.</param>
+/// <param name="e">Event data describing the conditions that led to the event.</param>
+void LayoutAwarePage::GoForward(Object^ sender, RoutedEventArgs^ e)
+{
+    (void) sender;     // Unused parameter
+    (void) e;  // Unused parameter
+
+    // Use the navigation frame to advance to the next page
+    if (Frame != nullptr && Frame->CanGoForward)
+    {
+        Frame->GoForward();
+    }
+}
+
+/// <summary>
+/// Invoked on every keystroke, including system keys such as Alt key combinations, when
+/// this page is active and occupies the entire window.  Used to detect keyboard navigation
+/// between pages even when the page itself doesn't have focus.
+/// </summary>
+/// <param name="sender">Instance that triggered the event.</param>
+/// <param name="args">Event data describing the conditions that led to the event.</param>
+void LayoutAwarePage::CoreDispatcher_AcceleratorKeyActivated(CoreDispatcher^ sender, AcceleratorKeyEventArgs^ args)
+{
+    auto virtualKey = args->VirtualKey;
+
+    // Only investigate further when Left, Right, or the dedicated Previous or Next keys
+    // are pressed
+    if ((args->EventType == CoreAcceleratorKeyEventType::SystemKeyDown ||
+        args->EventType == CoreAcceleratorKeyEventType::KeyDown) &&
+        (virtualKey == VirtualKey::Left || virtualKey == VirtualKey::Right ||
+        (int)virtualKey == 166 || (int)virtualKey == 167))
+    {
+        auto coreWindow = Window::Current->CoreWindow;
+        auto downState = Windows::UI::Core::CoreVirtualKeyStates::Down;
+        bool menuKey = (coreWindow->GetKeyState(VirtualKey::Menu) & downState) == downState;
+        bool controlKey = (coreWindow->GetKeyState(VirtualKey::Control) & downState) == downState;
+        bool shiftKey = (coreWindow->GetKeyState(VirtualKey::Shift) & downState) == downState;
+        bool noModifiers = !menuKey && !controlKey && !shiftKey;
+        bool onlyAlt = menuKey && !controlKey && !shiftKey;
+
+        if (((int)virtualKey == 166 && noModifiers) ||
+            (virtualKey == VirtualKey::Left && onlyAlt))
+        {
+            // When the previous key or Alt+Left are pressed navigate back
+            args->Handled = true;
+            GoBack(this, ref new RoutedEventArgs());
+        }
+        else if (((int)virtualKey == 167 && noModifiers) ||
+            (virtualKey == VirtualKey::Right && onlyAlt))
+        {
+            // When the next key or Alt+Right are pressed navigate forward
+            args->Handled = true;
+            GoForward(this, ref new RoutedEventArgs());
+        }
+    }
+}
+
+/// <summary>
+/// Invoked on every mouse click, touch screen tap, or equivalent interaction when this
+/// page is active and occupies the entire window.  Used to detect browser-style next and
+/// previous mouse button clicks to navigate between pages.
+/// </summary>
+/// <param name="sender">Instance that triggered the event.</param>
+/// <param name="args">Event data describing the conditions that led to the event.</param>
+void LayoutAwarePage::CoreWindow_PointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
+{
+    auto properties = args->CurrentPoint->Properties;
+
+    // Ignore button chords with the left, right, and middle buttons
+    if (properties->IsLeftButtonPressed || properties->IsRightButtonPressed ||
+        properties->IsMiddleButtonPressed) return;
+
+    // If back or foward are pressed (but not both) navigate appropriately
+    bool backPressed = properties->IsXButton1Pressed;
+    bool forwardPressed = properties->IsXButton2Pressed;
+    if (backPressed ^ forwardPressed)
+    {
+        args->Handled = true;
+        if (backPressed) GoBack(this, ref new RoutedEventArgs());
+        if (forwardPressed) GoForward(this, ref new RoutedEventArgs());
+    }
+}
+
+#pragma endregion
+
+#pragma region Visual state switching
+
+/// <summary>
+/// Invoked as an event handler, typically on the <see cref="Loaded"/> event of a
+/// <see cref="Control"/> within the page, to indicate that the sender should start receiving
+/// visual state management changes that correspond to application view state changes.
+/// </summary>
+/// <param name="sender">Instance of <see cref="Control"/> that supports visual state management
+/// corresponding to view states.</param>
+/// <param name="e">Event data that describes how the request was made.</param>
+/// <remarks>The current view state will immediately be used to set the corresponding visual state
+/// when layout updates are requested.  A corresponding <see cref="Unloaded"/> event handler
+/// connected to <see cref="StopLayoutUpdates"/> is strongly encouraged.  Instances of
+/// <see cref="LayoutAwarePage"/> automatically invoke these handlers in their Loaded and Unloaded
+/// events.</remarks>
+/// <seealso cref="DetermineVisualState"/>
+/// <seealso cref="InvalidateVisualState"/>
+void LayoutAwarePage::StartLayoutUpdates(Object^ sender, RoutedEventArgs^ e)
+{
+    (void) e;  // Unused parameter
+
+    auto control = safe_cast<Control^>(sender);
+    if (_layoutAwareControls == nullptr)
+    {
+        // Start listening to view state changes when there are controls interested in updates
+        _layoutAwareControls = ref new Vector<Control^>();
+        _windowSizeEventToken = Window::Current->SizeChanged += ref new WindowSizeChangedEventHandler(this, &LayoutAwarePage::WindowSizeChanged);
+
+        // Page receives notifications for children. Protect the page until we stopped layout updates for all controls.
+        _this = this;
+    }
+    _layoutAwareControls->Append(control);
+
+    // Set the initial visual state of the control
+    VisualStateManager::GoToState(control, DetermineVisualState(ApplicationView::Value), false);
+}
+
+void LayoutAwarePage::WindowSizeChanged(Object^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ e)
+{
+    (void) sender;     // Unused parameter
+    (void) e;  // Unused parameter
+
+    InvalidateVisualState();
+}
+
+/// <summary>
+/// Invoked as an event handler, typically on the <see cref="Unloaded"/> event of a
+/// <see cref="Control"/>, to indicate that the sender should start receiving visual state
+/// management changes that correspond to application view state changes.
+/// </summary>
+/// <param name="sender">Instance of <see cref="Control"/> that supports visual state management
+/// corresponding to view states.</param>
+/// <param name="e">Event data that describes how the request was made.</param>
+/// <remarks>The current view state will immediately be used to set the corresponding visual state
+/// when layout updates are requested.</remarks>
+/// <seealso cref="StartLayoutUpdates"/>
+void LayoutAwarePage::StopLayoutUpdates(Object^ sender, RoutedEventArgs^ e)
+{
+    (void) e;  // Unused parameter
+
+    auto control = safe_cast<Control^>(sender);
+    unsigned int index;
+    if (_layoutAwareControls != nullptr && _layoutAwareControls->IndexOf(control, &index))
+    {
+        _layoutAwareControls->RemoveAt(index);
+        if (_layoutAwareControls->Size == 0)
+        {
+            // Stop listening to view state changes when no controls are interested in updates
+            Window::Current->SizeChanged -= _windowSizeEventToken;
+            _layoutAwareControls = nullptr;
+            // Last control has received the Unload notification.
+            _this = nullptr;
+        }
+    }
+}
+
+/// <summary>
+/// Translates <see cref="ApplicationViewState"/> values into strings for visual state management
+/// within the page.  The default implementation uses the names of enum values.  Subclasses may
+/// override this method to control the mapping scheme used.
+/// </summary>
+/// <param name="viewState">View state for which a visual state is desired.</param>
+/// <returns>Visual state name used to drive the <see cref="VisualStateManager"/></returns>
+/// <seealso cref="InvalidateVisualState"/>
+String^ LayoutAwarePage::DetermineVisualState(ApplicationViewState viewState)
+{
+    switch (viewState)
+    {
+    case ApplicationViewState::Filled:
+        return "Filled";
+    case ApplicationViewState::Snapped:
+        return "Snapped";
+    case ApplicationViewState::FullScreenPortrait:
+        return "FullScreenPortrait";
+    case ApplicationViewState::FullScreenLandscape:
+    default:
+        return "FullScreenLandscape";
+    }
+}
+
+/// <summary>
+/// Updates all controls that are listening for visual state changes with the correct visual
+/// state.
+/// </summary>
+/// <remarks>
+/// Typically used in conjunction with overriding <see cref="DetermineVisualState"/> to
+/// signal that a different value may be returned even though the view state has not changed.
+/// </remarks>
+void LayoutAwarePage::InvalidateVisualState()
+{
+    if (_layoutAwareControls != nullptr)
+    {
+        String^ visualState = DetermineVisualState(ApplicationView::Value);
+        auto controlIterator = _layoutAwareControls->First();
+        while (controlIterator->HasCurrent)
+        {
+            auto control = controlIterator->Current;
+            VisualStateManager::GoToState(control, visualState, false);
+            controlIterator->MoveNext();
+        }
+    }
+}
+
+#pragma endregion
+
+#pragma region Process lifetime management
+
+/// <summary>
+/// Invoked when this page is about to be displayed in a Frame.
+/// </summary>
+/// <param name="e">Event data that describes how this page was reached.  The Parameter
+/// property provides the group to be displayed.</param>
+void LayoutAwarePage::OnNavigatedTo(NavigationEventArgs^ e)
+{
+    // Returning to a cached page through navigation shouldn't trigger state loading
+    if (_pageKey != nullptr) return;
+
+    auto frameState = SuspensionManager::SessionStateForFrame(Frame);
+    _pageKey = "Page-" + Frame->BackStackDepth;
+
+    if (e->NavigationMode == NavigationMode::New)
+    {
+        // Clear existing state for forward navigation when adding a new page to the
+        // navigation stack
+        auto nextPageKey = _pageKey;
+        int nextPageIndex = Frame->BackStackDepth;
+        while (frameState->HasKey(nextPageKey))
+        {
+            frameState->Remove(nextPageKey);
+            nextPageIndex++;
+            nextPageKey = "Page-" + nextPageIndex;
+        }
+
+        // Pass the navigation parameter to the new page
+        LoadState(e->Parameter, nullptr);
+    }
+    else
+    {
+        // Pass the navigation parameter and preserved page state to the page, using
+        // the same strategy for loading suspended state and recreating pages discarded
+        // from cache
+        LoadState(e->Parameter, safe_cast<IMap<String^, Object^>^>(frameState->Lookup(_pageKey)));
+    }
+}
+
+/// <summary>
+/// Invoked when this page will no longer be displayed in a Frame.
+/// </summary>
+/// <param name="e">Event data that describes how this page was reached.  The Parameter
+/// property provides the group to be displayed.</param>
+void LayoutAwarePage::OnNavigatedFrom(NavigationEventArgs^ e)
+{
+    auto frameState = SuspensionManager::SessionStateForFrame(Frame);
+    auto pageState = ref new Map<String^, Object^>();
+    SaveState(pageState);
+    frameState->Insert(_pageKey, pageState);
+}
+
+/// <summary>
+/// Populates the page with content passed during navigation.  Any saved state is also
+/// provided when recreating a page from a prior session.
+/// </summary>
+/// <param name="navigationParameter">The parameter value passed to
+/// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested.
+/// </param>
+/// <param name="pageState">A map of state preserved by this page during an earlier
+/// session.  This will be null the first time a page is visited.</param>
+void LayoutAwarePage::LoadState(Object^ navigationParameter, IMap<String^, Object^>^ pageState)
+{
+}
+
+/// <summary>
+/// Preserves state associated with this page in case the application is suspended or the
+/// page is discarded from the navigation cache.  Values must conform to the serialization
+/// requirements of <see cref="SuspensionManager.SessionState"/>.
+/// </summary>
+/// <param name="pageState">An empty map to be populated with serializable state.</param>
+void LayoutAwarePage::SaveState(IMap<String^, Object^>^ pageState)
+{
+}
+
+#pragma endregion
diff --git a/samples/winrt/ImageManipulations/common/LayoutAwarePage.h b/samples/winrt/ImageManipulations/common/LayoutAwarePage.h
new file mode 100644 (file)
index 0000000..bd71062
--- /dev/null
@@ -0,0 +1,88 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+#pragma once
+
+#include <collection.h>
+
+namespace SDKSample
+{
+    namespace Common
+    {
+        /// <summary>
+        /// Typical implementation of Page that provides several important conveniences:
+        /// <list type="bullet">
+        /// <item>
+        /// <description>Application view state to visual state mapping</description>
+        /// </item>
+        /// <item>
+        /// <description>GoBack, GoForward, and GoHome event handlers</description>
+        /// </item>
+        /// <item>
+        /// <description>Mouse and keyboard shortcuts for navigation</description>
+        /// </item>
+        /// <item>
+        /// <description>State management for navigation and process lifetime management</description>
+        /// </item>
+        /// <item>
+        /// <description>A default view model</description>
+        /// </item>
+        /// </list>
+        /// </summary>
+        [Windows::Foundation::Metadata::WebHostHidden]
+        public ref class LayoutAwarePage : Windows::UI::Xaml::Controls::Page
+        {
+        internal:
+            LayoutAwarePage();
+
+        public:
+            void StartLayoutUpdates(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+            void StopLayoutUpdates(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+            void InvalidateVisualState();
+            static property Windows::UI::Xaml::DependencyProperty^ DefaultViewModelProperty
+            {
+                Windows::UI::Xaml::DependencyProperty^ get();
+            };
+            property Windows::Foundation::Collections::IObservableMap<Platform::String^, Platform::Object^>^ DefaultViewModel
+            {
+                Windows::Foundation::Collections::IObservableMap<Platform::String^, Platform::Object^>^ get();
+                void set(Windows::Foundation::Collections::IObservableMap<Platform::String^, Platform::Object^>^ value);
+            }
+
+        protected:
+            virtual void GoHome(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+            virtual void GoBack(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+            virtual void GoForward(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+            virtual Platform::String^ DetermineVisualState(Windows::UI::ViewManagement::ApplicationViewState viewState);
+            virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
+            virtual void OnNavigatedFrom(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
+            virtual void LoadState(Platform::Object^ navigationParameter,
+                Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ pageState);
+            virtual void SaveState(Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ pageState);
+
+        private:
+            Platform::String^ _pageKey;
+            bool _navigationShortcutsRegistered;
+            Platform::Collections::Map<Platform::String^, Platform::Object^>^ _defaultViewModel;
+            Windows::Foundation::EventRegistrationToken _windowSizeEventToken,
+                _acceleratorKeyEventToken, _pointerPressedEventToken;
+            Platform::Collections::Vector<Windows::UI::Xaml::Controls::Control^>^ _layoutAwareControls;
+            void WindowSizeChanged(Platform::Object^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ e);
+            void OnLoaded(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+            void OnUnloaded(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+
+            void CoreDispatcher_AcceleratorKeyActivated(Windows::UI::Core::CoreDispatcher^ sender,
+                Windows::UI::Core::AcceleratorKeyEventArgs^ args);
+            void CoreWindow_PointerPressed(Windows::UI::Core::CoreWindow^ sender,
+                Windows::UI::Core::PointerEventArgs^ args);
+            LayoutAwarePage^ _this; // Strong reference to self, cleaned up in OnUnload
+        };
+    }
+}
diff --git a/samples/winrt/ImageManipulations/common/StandardStyles.xaml b/samples/winrt/ImageManipulations/common/StandardStyles.xaml
new file mode 100644 (file)
index 0000000..7c3d238
--- /dev/null
@@ -0,0 +1,978 @@
+<!--
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+-->
+
+<ResourceDictionary
+    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+
+    <!-- Non-brush values that vary across themes -->
+    
+    <ResourceDictionary.ThemeDictionaries>
+        <ResourceDictionary x:Key="Default">
+            <x:String x:Key="BackButtonGlyph">&#xE071;</x:String>
+            <x:String x:Key="BackButtonSnappedGlyph">&#xE0BA;</x:String>
+        </ResourceDictionary>
+
+        <ResourceDictionary x:Key="HighContrast">
+            <x:String x:Key="BackButtonGlyph">&#xE0A6;</x:String>
+            <x:String x:Key="BackButtonSnappedGlyph">&#xE0C4;</x:String>
+        </ResourceDictionary>
+    </ResourceDictionary.ThemeDictionaries>
+
+    <!-- RichTextBlock styles -->
+
+    <Style x:Key="BasicRichTextStyle" TargetType="RichTextBlock">
+        <Setter Property="Foreground" Value="{StaticResource ApplicationForegroundThemeBrush}"/>
+        <Setter Property="FontSize" Value="{StaticResource ControlContentThemeFontSize}"/>
+        <Setter Property="FontFamily" Value="{StaticResource ContentControlThemeFontFamily}"/>
+        <Setter Property="TextTrimming" Value="WordEllipsis"/>
+        <Setter Property="TextWrapping" Value="Wrap"/>
+        <Setter Property="Typography.StylisticSet20" Value="True"/>
+        <Setter Property="Typography.DiscretionaryLigatures" Value="True"/>
+    </Style>
+
+    <Style x:Key="BaselineRichTextStyle" TargetType="RichTextBlock" BasedOn="{StaticResource BasicRichTextStyle}">
+        <Setter Property="LineHeight" Value="20"/>
+        <Setter Property="LineStackingStrategy" Value="BlockLineHeight"/>
+        <!-- Properly align text along its baseline -->
+        <Setter Property="RenderTransform">
+            <Setter.Value>
+                <TranslateTransform X="-1" Y="4"/>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+    <Style x:Key="ItemRichTextStyle" TargetType="RichTextBlock" BasedOn="{StaticResource BaselineRichTextStyle}"/>
+
+    <Style x:Key="BodyRichTextStyle" TargetType="RichTextBlock" BasedOn="{StaticResource BaselineRichTextStyle}">
+        <Setter Property="FontWeight" Value="SemiLight"/>
+    </Style>
+
+    <!-- TextBlock styles -->
+
+    <Style x:Key="BasicTextStyle" TargetType="TextBlock">
+        <Setter Property="Foreground" Value="{StaticResource ApplicationForegroundThemeBrush}"/>
+        <Setter Property="FontSize" Value="{StaticResource ControlContentThemeFontSize}"/>
+        <Setter Property="FontFamily" Value="{StaticResource ContentControlThemeFontFamily}"/>
+        <Setter Property="TextTrimming" Value="WordEllipsis"/>
+        <Setter Property="TextWrapping" Value="Wrap"/>
+        <Setter Property="Typography.StylisticSet20" Value="True"/>
+        <Setter Property="Typography.DiscretionaryLigatures" Value="True"/>
+    </Style>
+
+    <Style x:Key="BaselineTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BasicTextStyle}">
+        <Setter Property="LineHeight" Value="20"/>
+        <Setter Property="LineStackingStrategy" Value="BlockLineHeight"/>
+        <!-- Properly align text along its baseline -->
+        <Setter Property="RenderTransform">
+            <Setter.Value>
+                <TranslateTransform X="-1" Y="4"/>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+    <Style x:Key="HeaderTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaselineTextStyle}">
+        <Setter Property="FontSize" Value="56"/>
+        <Setter Property="FontWeight" Value="Light"/>
+        <Setter Property="LineHeight" Value="40"/>
+        <Setter Property="RenderTransform">
+            <Setter.Value>
+                <TranslateTransform X="-2" Y="8"/>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+    <Style x:Key="SubheaderTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaselineTextStyle}">
+        <Setter Property="FontSize" Value="26.667"/>
+        <Setter Property="FontWeight" Value="Light"/>
+        <Setter Property="LineHeight" Value="30"/>
+        <Setter Property="RenderTransform">
+            <Setter.Value>
+                <TranslateTransform X="-1" Y="6"/>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+    <Style x:Key="TitleTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaselineTextStyle}">
+        <Setter Property="FontWeight" Value="SemiBold"/>
+    </Style>
+
+    <Style x:Key="ItemTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaselineTextStyle}"/>
+
+    <Style x:Key="BodyTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaselineTextStyle}">
+        <Setter Property="FontWeight" Value="SemiLight"/>
+    </Style>
+
+    <Style x:Key="CaptionTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaselineTextStyle}">
+        <Setter Property="FontSize" Value="12"/>
+        <Setter Property="Foreground" Value="{StaticResource ApplicationSecondaryForegroundThemeBrush}"/>
+    </Style>
+
+    <!-- Button styles -->
+
+    <!--
+        TextButtonStyle is used to style a Button using subheader-styled text with no other adornment.  This
+        style is used in the GroupedItemsPage as a group header and in the FileOpenPickerPage for triggering
+        commands.
+    -->
+    <Style x:Key="TextButtonStyle" TargetType="Button">
+        <Setter Property="MinWidth" Value="0"/>
+        <Setter Property="MinHeight" Value="0"/>
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="Button">
+                    <Grid Background="Transparent">
+                        <TextBlock
+                            x:Name="Text"
+                            Text="{TemplateBinding Content}"
+                            Margin="3,-7,3,10"
+                            TextWrapping="NoWrap"
+                            Style="{StaticResource SubheaderTextStyle}"/>
+                        <Rectangle
+                            x:Name="FocusVisualWhite"
+                            IsHitTestVisible="False"
+                            Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}"
+                            StrokeEndLineCap="Square"
+                            StrokeDashArray="1,1"
+                            Opacity="0"
+                            StrokeDashOffset="1.5"/>
+                        <Rectangle
+                            x:Name="FocusVisualBlack"
+                            IsHitTestVisible="False"
+                            Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}"
+                            StrokeEndLineCap="Square"
+                            StrokeDashArray="1,1"
+                            Opacity="0"
+                            StrokeDashOffset="0.5"/>
+
+                        <VisualStateManager.VisualStateGroups>
+                            <VisualStateGroup x:Name="CommonStates">
+                                <VisualState x:Name="Normal"/>
+                                <VisualState x:Name="PointerOver">
+                                    <Storyboard>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPointerOverForegroundThemeBrush}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Pressed">
+                                    <Storyboard>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPressedForegroundThemeBrush}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Disabled">
+                                    <Storyboard>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ButtonDisabledForegroundThemeBrush}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                            </VisualStateGroup>
+                            <VisualStateGroup x:Name="FocusStates">
+                                <VisualState x:Name="Focused">
+                                    <Storyboard>
+                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetName="FocusVisualWhite" Storyboard.TargetProperty="Opacity"/>
+                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetName="FocusVisualBlack" Storyboard.TargetProperty="Opacity"/>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Unfocused"/>
+                            </VisualStateGroup>
+                        </VisualStateManager.VisualStateGroups>
+                    </Grid>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+    <!--
+        TextRadioButtonStyle is used to style a RadioButton using subheader-styled text with no other adornment.
+        This style is used in the SearchResultsPage to allow selection among filters.
+    -->
+    <Style x:Key="TextRadioButtonStyle" TargetType="RadioButton">
+        <Setter Property="MinWidth" Value="0"/>
+        <Setter Property="MinHeight" Value="0"/>
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="RadioButton">
+                    <Grid Background="Transparent">
+                        <TextBlock
+                            x:Name="Text"
+                            Text="{TemplateBinding Content}"
+                            Margin="3,-7,3,10"
+                            TextWrapping="NoWrap"
+                            Style="{StaticResource SubheaderTextStyle}"/>
+                        <Rectangle
+                            x:Name="FocusVisualWhite"
+                            IsHitTestVisible="False"
+                            Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}"
+                            StrokeEndLineCap="Square"
+                            StrokeDashArray="1,1"
+                            Opacity="0"
+                            StrokeDashOffset="1.5"/>
+                        <Rectangle
+                            x:Name="FocusVisualBlack"
+                            IsHitTestVisible="False"
+                            Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}"
+                            StrokeEndLineCap="Square"
+                            StrokeDashArray="1,1"
+                            Opacity="0"
+                            StrokeDashOffset="0.5"/>
+
+                        <VisualStateManager.VisualStateGroups>
+                            <VisualStateGroup x:Name="CommonStates">
+                                <VisualState x:Name="Normal"/>
+                                <VisualState x:Name="PointerOver">
+                                    <Storyboard>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPointerOverForegroundThemeBrush}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Pressed">
+                                    <Storyboard>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPressedForegroundThemeBrush}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Disabled">
+                                    <Storyboard>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ButtonDisabledForegroundThemeBrush}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                            </VisualStateGroup>
+                            <VisualStateGroup x:Name="FocusStates">
+                                <VisualState x:Name="Focused">
+                                    <Storyboard>
+                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetName="FocusVisualWhite" Storyboard.TargetProperty="Opacity"/>
+                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetName="FocusVisualBlack" Storyboard.TargetProperty="Opacity"/>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Unfocused"/>
+                            </VisualStateGroup>
+                            <VisualStateGroup x:Name="CheckStates">
+                                <VisualState x:Name="Checked"/>
+                                <VisualState x:Name="Unchecked">
+                                    <Storyboard>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationSecondaryForegroundThemeBrush}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Indeterminate"/>
+                            </VisualStateGroup>
+                        </VisualStateManager.VisualStateGroups>
+                    </Grid>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+    <!--
+        AppBarButtonStyle is used to style a Button for use in an App Bar.  Content will be centered and should fit within
+        the 40-pixel radius glyph provided.  16-point Segoe UI Symbol is used for content text to simplify the use of glyphs
+        from that font.  AutomationProperties.Name is used for the text below the glyph.
+    -->
+    <Style x:Key="AppBarButtonStyle" TargetType="Button">
+        <Setter Property="Foreground" Value="{StaticResource AppBarItemForegroundThemeBrush}"/>
+        <Setter Property="VerticalAlignment" Value="Stretch"/>
+        <Setter Property="FontFamily" Value="Segoe UI Symbol"/>
+        <Setter Property="FontWeight" Value="Normal"/>
+        <Setter Property="FontSize" Value="20"/>
+        <Setter Property="AutomationProperties.ItemType" Value="App Bar Button"/>
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="Button">
+                    <Grid Width="100" Background="Transparent">
+                        <StackPanel VerticalAlignment="Top" Margin="0,14,0,13">
+                            <Grid Width="40" Height="40" Margin="0,0,0,5" HorizontalAlignment="Center">
+                                <TextBlock x:Name="BackgroundGlyph" Text="&#xE0A8;" FontFamily="Segoe UI Symbol" FontSize="53.333" Margin="-4,-19,0,0" Foreground="{StaticResource AppBarItemBackgroundThemeBrush}"/>
+                                <TextBlock x:Name="OutlineGlyph" Text="&#xE0A7;" FontFamily="Segoe UI Symbol" FontSize="53.333" Margin="-4,-19,0,0"/>
+                                <ContentPresenter x:Name="Content" HorizontalAlignment="Center" Margin="-1,-1,0,0" VerticalAlignment="Center"/>
+                            </Grid>
+                            <TextBlock
+                                x:Name="TextLabel"
+                                Text="{TemplateBinding AutomationProperties.Name}"
+                                Margin="0,0,2,0"
+                                FontSize="12"
+                                TextAlignment="Center"
+                                Width="88"
+                                MaxHeight="32"
+                                TextTrimming="WordEllipsis"
+                                Style="{StaticResource BasicTextStyle}"/>
+                        </StackPanel>
+                        <Rectangle
+                                x:Name="FocusVisualWhite"
+                                IsHitTestVisible="False"
+                                Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}"
+                                StrokeEndLineCap="Square"
+                                StrokeDashArray="1,1"
+                                Opacity="0"
+                                StrokeDashOffset="1.5"/>
+                        <Rectangle
+                                x:Name="FocusVisualBlack"
+                                IsHitTestVisible="False"
+                                Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}"
+                                StrokeEndLineCap="Square"
+                                StrokeDashArray="1,1"
+                                Opacity="0"
+                                StrokeDashOffset="0.5"/>
+
+                        <VisualStateManager.VisualStateGroups>
+                            <VisualStateGroup x:Name="CommonStates">
+                                <VisualState x:Name="Normal"/>
+                                <VisualState x:Name="PointerOver">
+                                    <Storyboard>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPointerOverBackgroundThemeBrush}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPointerOverForegroundThemeBrush}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Pressed">
+                                    <Storyboard>
+                                        <DoubleAnimation
+                                            Storyboard.TargetName="OutlineGlyph"
+                                            Storyboard.TargetProperty="Opacity"
+                                            To="0"
+                                            Duration="0"/>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemForegroundThemeBrush}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPressedForegroundThemeBrush}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Disabled">
+                                    <Storyboard>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="OutlineGlyph" Storyboard.TargetProperty="Foreground">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemDisabledForegroundThemeBrush}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemDisabledForegroundThemeBrush}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextLabel" Storyboard.TargetProperty="Foreground">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemDisabledForegroundThemeBrush}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                            </VisualStateGroup>
+                            <VisualStateGroup x:Name="FocusStates">
+                                <VisualState x:Name="Focused">
+                                    <Storyboard>
+                                        <DoubleAnimation
+                                                Storyboard.TargetName="FocusVisualWhite"
+                                                Storyboard.TargetProperty="Opacity"
+                                                To="1"
+                                                Duration="0"/>
+                                        <DoubleAnimation
+                                                Storyboard.TargetName="FocusVisualBlack"
+                                                Storyboard.TargetProperty="Opacity"
+                                                To="1"
+                                                Duration="0"/>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Unfocused" />
+                                <VisualState x:Name="PointerFocused" />
+                            </VisualStateGroup>
+                        </VisualStateManager.VisualStateGroups>
+                    </Grid>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+    <!-- Standard App Bar buttons -->
+  
+    <Style x:Key="SkipBackAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="SkipBackAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Skip Back"/>
+        <Setter Property="Content" Value="&#xE100;"/>
+    </Style>
+    <Style x:Key="SkipAheadAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="SkipAheadAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Skip Ahead"/>
+        <Setter Property="Content" Value="&#xE101;"/>
+    </Style>
+    <Style x:Key="PlayAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="PlayAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Play"/>
+        <Setter Property="Content" Value="&#xE102;"/>
+    </Style>
+    <Style x:Key="PauseAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="PauseAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Pause"/>
+        <Setter Property="Content" Value="&#xE103;"/>
+    </Style>
+    <Style x:Key="EditAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="EditAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Edit"/>
+        <Setter Property="Content" Value="&#xE104;"/>
+    </Style>
+    <Style x:Key="SaveAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="SaveAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Save"/>
+        <Setter Property="Content" Value="&#xE105;"/>
+    </Style>
+    <Style x:Key="DeleteAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="DeleteAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Delete"/>
+        <Setter Property="Content" Value="&#xE106;"/>
+    </Style>
+    <Style x:Key="DiscardAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="DiscardAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Discard"/>
+        <Setter Property="Content" Value="&#xE107;"/>
+    </Style>
+    <Style x:Key="RemoveAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="RemoveAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Remove"/>
+        <Setter Property="Content" Value="&#xE108;"/>
+    </Style>
+    <Style x:Key="AddAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="AddAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Add"/>
+        <Setter Property="Content" Value="&#xE109;"/>
+    </Style>
+    <Style x:Key="NoAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="NoAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="No"/>
+        <Setter Property="Content" Value="&#xE10A;"/>
+    </Style>
+    <Style x:Key="YesAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="YesAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Yes"/>
+        <Setter Property="Content" Value="&#xE10B;"/>
+    </Style>
+    <Style x:Key="MoreAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="MoreAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="More"/>
+        <Setter Property="Content" Value="&#xE10C;"/>
+    </Style>
+    <Style x:Key="RedoAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="RedoAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Redo"/>
+        <Setter Property="Content" Value="&#xE10D;"/>
+    </Style>
+    <Style x:Key="UndoAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="UndoAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Undo"/>
+        <Setter Property="Content" Value="&#xE10E;"/>
+    </Style>
+    <Style x:Key="HomeAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="HomeAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Home"/>
+        <Setter Property="Content" Value="&#xE10F;"/>
+    </Style>
+    <Style x:Key="OutAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="OutAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Out"/>
+        <Setter Property="Content" Value="&#xE110;"/>
+    </Style>
+    <Style x:Key="NextAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="NextAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Next"/>
+        <Setter Property="Content" Value="&#xE111;"/>
+    </Style>
+    <Style x:Key="PreviousAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="PreviousAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Previous"/>
+        <Setter Property="Content" Value="&#xE112;"/>
+    </Style>
+    <Style x:Key="FavoriteAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="FavoriteAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Favorite"/>
+        <Setter Property="Content" Value="&#xE113;"/>
+    </Style>
+    <Style x:Key="PhotoAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="PhotoAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Photo"/>
+        <Setter Property="Content" Value="&#xE114;"/>
+    </Style>
+    <Style x:Key="SettingsAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="SettingsAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Settings"/>
+        <Setter Property="Content" Value="&#xE115;"/>
+    </Style>
+    <Style x:Key="VideoAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="VideoAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Video"/>
+        <Setter Property="Content" Value="&#xE116;"/>
+    </Style>
+    <Style x:Key="RefreshAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="RefreshAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Refresh"/>
+        <Setter Property="Content" Value="&#xE117;"/>
+    </Style>
+    <Style x:Key="DownloadAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="DownloadAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Download"/>
+        <Setter Property="Content" Value="&#xE118;"/>
+    </Style>
+    <Style x:Key="MailAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="MailAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Mail"/>
+        <Setter Property="Content" Value="&#xE119;"/>
+    </Style>
+    <Style x:Key="SearchAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="SearchAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Search"/>
+        <Setter Property="Content" Value="&#xE11A;"/>
+    </Style>
+    <Style x:Key="HelpAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="HelpAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Help"/>
+        <Setter Property="Content" Value="&#xE11B;"/>
+    </Style>
+    <Style x:Key="UploadAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="UploadAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Upload"/>
+        <Setter Property="Content" Value="&#xE11C;"/>
+    </Style>
+    <Style x:Key="PinAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="PinAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Pin"/>
+        <Setter Property="Content" Value="&#xE141;"/>
+    </Style>
+    <Style x:Key="UnpinAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
+        <Setter Property="AutomationProperties.AutomationId" Value="UnpinAppBarButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Unpin"/>
+        <Setter Property="Content" Value="&#xE196;"/>
+    </Style>
+
+    <!-- Title area styles -->
+
+    <Style x:Key="PageHeaderTextStyle" TargetType="TextBlock" BasedOn="{StaticResource HeaderTextStyle}">
+        <Setter Property="TextWrapping" Value="NoWrap"/>
+        <Setter Property="VerticalAlignment" Value="Bottom"/>
+        <Setter Property="Margin" Value="0,0,40,40"/>
+    </Style>
+
+    <Style x:Key="PageSubheaderTextStyle" TargetType="TextBlock" BasedOn="{StaticResource SubheaderTextStyle}">
+        <Setter Property="TextWrapping" Value="NoWrap"/>
+        <Setter Property="VerticalAlignment" Value="Bottom"/>
+        <Setter Property="Margin" Value="0,0,0,40"/>
+    </Style>
+
+    <Style x:Key="SnappedPageHeaderTextStyle" TargetType="TextBlock" BasedOn="{StaticResource PageSubheaderTextStyle}">
+        <Setter Property="Margin" Value="0,0,18,40"/>
+    </Style>
+
+    <!--
+        BackButtonStyle is used to style a Button for use in the title area of a page.  Margins appropriate for
+        the conventional page layout are included as part of the style.
+    -->
+    <Style x:Key="BackButtonStyle" TargetType="Button">
+        <Setter Property="MinWidth" Value="0"/>
+        <Setter Property="Width" Value="48"/>
+        <Setter Property="Height" Value="48"/>
+        <Setter Property="Margin" Value="36,0,36,36"/>
+        <Setter Property="VerticalAlignment" Value="Bottom"/>
+        <Setter Property="FontFamily" Value="Segoe UI Symbol"/>
+        <Setter Property="FontWeight" Value="Normal"/>
+        <Setter Property="FontSize" Value="56"/>
+        <Setter Property="AutomationProperties.AutomationId" Value="BackButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Back"/>
+        <Setter Property="AutomationProperties.ItemType" Value="Navigation Button"/>
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="Button">
+                    <Grid x:Name="RootGrid">
+                        <Grid Margin="-1,-16,0,0">
+                            <TextBlock x:Name="BackgroundGlyph" Text="&#xE0A8;" Foreground="{StaticResource BackButtonBackgroundThemeBrush}"/>
+                            <TextBlock x:Name="NormalGlyph" Text="{StaticResource BackButtonGlyph}" Foreground="{StaticResource BackButtonForegroundThemeBrush}"/>
+                            <TextBlock x:Name="ArrowGlyph" Text="&#xE0A6;" Foreground="{StaticResource BackButtonPressedForegroundThemeBrush}" Opacity="0"/>
+                        </Grid>
+                        <Rectangle
+                            x:Name="FocusVisualWhite"
+                            IsHitTestVisible="False"
+                            Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}"
+                            StrokeEndLineCap="Square"
+                            StrokeDashArray="1,1"
+                            Opacity="0"
+                            StrokeDashOffset="1.5"/>
+                        <Rectangle
+                            x:Name="FocusVisualBlack"
+                            IsHitTestVisible="False"
+                            Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}"
+                            StrokeEndLineCap="Square"
+                            StrokeDashArray="1,1"
+                            Opacity="0"
+                            StrokeDashOffset="0.5"/>
+
+                        <VisualStateManager.VisualStateGroups>
+                            <VisualStateGroup x:Name="CommonStates">
+                                <VisualState x:Name="Normal" />
+                                <VisualState x:Name="PointerOver">
+                                    <Storyboard>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BackButtonPointerOverBackgroundThemeBrush}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="NormalGlyph" Storyboard.TargetProperty="Foreground">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BackButtonPointerOverForegroundThemeBrush}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Pressed">
+                                    <Storyboard>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BackButtonForegroundThemeBrush}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                        <DoubleAnimation
+                                            Storyboard.TargetName="ArrowGlyph"
+                                            Storyboard.TargetProperty="Opacity"
+                                            To="1"
+                                            Duration="0"/>
+                                        <DoubleAnimation
+                                            Storyboard.TargetName="NormalGlyph"
+                                            Storyboard.TargetProperty="Opacity"
+                                            To="0"
+                                            Duration="0"/>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Disabled">
+                                    <Storyboard>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Visibility">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                            </VisualStateGroup>
+                            <VisualStateGroup x:Name="FocusStates">
+                                <VisualState x:Name="Focused">
+                                    <Storyboard>
+                                        <DoubleAnimation
+                                            Storyboard.TargetName="FocusVisualWhite"
+                                            Storyboard.TargetProperty="Opacity"
+                                            To="1"
+                                            Duration="0"/>
+                                        <DoubleAnimation
+                                            Storyboard.TargetName="FocusVisualBlack"
+                                            Storyboard.TargetProperty="Opacity"
+                                            To="1"
+                                            Duration="0"/>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Unfocused" />
+                                <VisualState x:Name="PointerFocused" />
+                            </VisualStateGroup>
+                        </VisualStateManager.VisualStateGroups>
+                    </Grid>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+    <!--
+        PortraitBackButtonStyle is used to style a Button for use in the title area of a portrait page.  Margins appropriate
+        for the conventional page layout are included as part of the style.
+    -->
+    <Style x:Key="PortraitBackButtonStyle" TargetType="Button" BasedOn="{StaticResource BackButtonStyle}">
+        <Setter Property="Margin" Value="26,0,26,36"/>
+    </Style>
+
+    <!--
+        SnappedBackButtonStyle is used to style a Button for use in the title area of a snapped page.  Margins appropriate
+        for the conventional page layout are included as part of the style.
+        
+        The obvious duplication here is necessary as the glyphs used in snapped are not merely smaller versions of the same
+        glyph but are actually distinct.
+    -->
+    <Style x:Key="SnappedBackButtonStyle" TargetType="Button">
+        <Setter Property="MinWidth" Value="0"/>
+        <Setter Property="Margin" Value="20,0,0,0"/>
+        <Setter Property="VerticalAlignment" Value="Bottom"/>
+        <Setter Property="FontFamily" Value="Segoe UI Symbol"/>
+        <Setter Property="FontWeight" Value="Normal"/>
+        <Setter Property="FontSize" Value="26.66667"/>
+        <Setter Property="AutomationProperties.AutomationId" Value="BackButton"/>
+        <Setter Property="AutomationProperties.Name" Value="Back"/>
+        <Setter Property="AutomationProperties.ItemType" Value="Navigation Button"/>
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="Button">
+                    <Grid x:Name="RootGrid" Width="36" Height="36" Margin="-3,0,7,33">
+                        <Grid Margin="-1,-1,0,0">
+                            <TextBlock x:Name="BackgroundGlyph" Text="&#xE0D4;" Foreground="{StaticResource BackButtonBackgroundThemeBrush}"/>
+                            <TextBlock x:Name="NormalGlyph" Text="{StaticResource BackButtonSnappedGlyph}" Foreground="{StaticResource BackButtonForegroundThemeBrush}"/>
+                            <TextBlock x:Name="ArrowGlyph" Text="&#xE0C4;" Foreground="{StaticResource BackButtonPressedForegroundThemeBrush}" Opacity="0"/>
+                        </Grid>
+                        <Rectangle
+                            x:Name="FocusVisualWhite"
+                            IsHitTestVisible="False"
+                            Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}"
+                            StrokeEndLineCap="Square"
+                            StrokeDashArray="1,1"
+                            Opacity="0"
+                            StrokeDashOffset="1.5"/>
+                        <Rectangle
+                            x:Name="FocusVisualBlack"
+                            IsHitTestVisible="False"
+                            Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}"
+                            StrokeEndLineCap="Square"
+                            StrokeDashArray="1,1"
+                            Opacity="0"
+                            StrokeDashOffset="0.5"/>
+
+                        <VisualStateManager.VisualStateGroups>
+                            <VisualStateGroup x:Name="CommonStates">
+                                <VisualState x:Name="Normal" />
+                                <VisualState x:Name="PointerOver">
+                                    <Storyboard>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BackButtonPointerOverBackgroundThemeBrush}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="NormalGlyph" Storyboard.TargetProperty="Foreground">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BackButtonPointerOverForegroundThemeBrush}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Pressed">
+                                    <Storyboard>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BackButtonForegroundThemeBrush}"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                        <DoubleAnimation
+                                            Storyboard.TargetName="ArrowGlyph"
+                                            Storyboard.TargetProperty="Opacity"
+                                            To="1"
+                                            Duration="0"/>
+                                        <DoubleAnimation
+                                            Storyboard.TargetName="NormalGlyph"
+                                            Storyboard.TargetProperty="Opacity"
+                                            To="0"
+                                            Duration="0"/>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Disabled">
+                                    <Storyboard>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Visibility">
+                                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                            </VisualStateGroup>
+                            <VisualStateGroup x:Name="FocusStates">
+                                <VisualState x:Name="Focused">
+                                    <Storyboard>
+                                        <DoubleAnimation
+                                            Storyboard.TargetName="FocusVisualWhite"
+                                            Storyboard.TargetProperty="Opacity"
+                                            To="1"
+                                            Duration="0"/>
+                                        <DoubleAnimation
+                                            Storyboard.TargetName="FocusVisualBlack"
+                                            Storyboard.TargetProperty="Opacity"
+                                            To="1"
+                                            Duration="0"/>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Unfocused" />
+                                <VisualState x:Name="PointerFocused" />
+                            </VisualStateGroup>
+                        </VisualStateManager.VisualStateGroups>
+                    </Grid>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+    <!-- Item templates -->
+
+    <!-- Grid-appropriate 250 pixel square item template as seen in the GroupedItemsPage and ItemsPage -->
+    <DataTemplate x:Key="Standard250x250ItemTemplate">
+        <Grid HorizontalAlignment="Left" Width="250" Height="250">
+            <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
+                <Image Source="{Binding Image}" Stretch="UniformToFill"/>
+            </Border>
+            <StackPanel VerticalAlignment="Bottom" Background="{StaticResource ListViewItemOverlayBackgroundThemeBrush}">
+                <TextBlock Text="{Binding Title}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Height="60" Margin="15,0,15,0"/>
+                <TextBlock Text="{Binding Subtitle}" Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
+            </StackPanel>
+        </Grid>
+    </DataTemplate>
+
+    <!-- Grid-appropriate 500 by 130 pixel item template as seen in the GroupDetailPage -->
+    <DataTemplate x:Key="Standard500x130ItemTemplate">
+        <Grid Height="110" Width="480" Margin="10">
+            <Grid.ColumnDefinitions>
+                <ColumnDefinition Width="Auto"/>
+                <ColumnDefinition Width="*"/>
+            </Grid.ColumnDefinitions>
+            <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Width="110" Height="110">
+                <Image Source="{Binding Image}" Stretch="UniformToFill"/>
+            </Border>
+            <StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="10,0,0,0">
+                <TextBlock Text="{Binding Title}" Style="{StaticResource TitleTextStyle}" TextWrapping="NoWrap"/>
+                <TextBlock Text="{Binding Subtitle}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap"/>
+                <TextBlock Text="{Binding Description}" Style="{StaticResource BodyTextStyle}" MaxHeight="60"/>
+            </StackPanel>
+        </Grid>
+    </DataTemplate>
+
+    <!-- List-appropriate 130 pixel high item template as seen in the SplitPage -->
+    <DataTemplate x:Key="Standard130ItemTemplate">
+        <Grid Height="110" Margin="6">
+            <Grid.ColumnDefinitions>
+                <ColumnDefinition Width="Auto"/>
+                <ColumnDefinition Width="*"/>
+            </Grid.ColumnDefinitions>
+            <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Width="110" Height="110">
+                <Image Source="{Binding Image}" Stretch="UniformToFill"/>
+            </Border>
+            <StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="10,0,0,0">
+                <TextBlock Text="{Binding Title}" Style="{StaticResource TitleTextStyle}" TextWrapping="NoWrap"/>
+                <TextBlock Text="{Binding Subtitle}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap"/>
+                <TextBlock Text="{Binding Description}" Style="{StaticResource BodyTextStyle}" MaxHeight="60"/>
+            </StackPanel>
+        </Grid>
+    </DataTemplate>
+
+    <!--
+        List-appropriate 80 pixel high item template as seen in the SplitPage when Filled, and
+        the following pages when snapped: GroupedItemsPage, GroupDetailPage, and ItemsPage
+    -->
+    <DataTemplate x:Key="Standard80ItemTemplate">
+        <Grid Margin="6">
+            <Grid.ColumnDefinitions>
+                <ColumnDefinition Width="Auto"/>
+                <ColumnDefinition Width="*"/>
+            </Grid.ColumnDefinitions>
+            <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Width="60" Height="60">
+                <Image Source="{Binding Image}" Stretch="UniformToFill"/>
+            </Border>
+            <StackPanel Grid.Column="1" Margin="10,0,0,0">
+                <TextBlock Text="{Binding Title}" Style="{StaticResource ItemTextStyle}" MaxHeight="40"/>
+                <TextBlock Text="{Binding Subtitle}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap"/>
+            </StackPanel>
+        </Grid>
+    </DataTemplate>
+
+    <!-- Grid-appropriate 300 by 70 pixel item template as seen in the SearchResultsPage -->
+    <DataTemplate x:Key="StandardSmallIcon300x70ItemTemplate">
+        <Grid Width="300">
+            <Grid.ColumnDefinitions>
+                <ColumnDefinition Width="Auto"/>
+                <ColumnDefinition Width="*"/>
+            </Grid.ColumnDefinitions>
+            <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Margin="10,10,0,20" Width="40" Height="40">
+                <Image Source="{Binding Image}" Stretch="UniformToFill"/>
+            </Border>
+            <StackPanel Grid.Column="1" Margin="10,0,10,10">
+                <TextBlock Text="{Binding Title}" Style="{StaticResource BodyTextStyle}" TextWrapping="NoWrap"/>
+                <TextBlock Text="{Binding Subtitle}" Style="{StaticResource BodyTextStyle}" Foreground="{StaticResource ApplicationSecondaryForegroundThemeBrush}" Height="40"/>
+            </StackPanel>
+        </Grid>
+    </DataTemplate>
+
+    <!-- List-appropriate 70 pixel high item template as seen in the SearchResultsPage when Snapped -->
+    <DataTemplate x:Key="StandardSmallIcon70ItemTemplate">
+        <Grid Margin="6">
+            <Grid.ColumnDefinitions>
+                <ColumnDefinition Width="Auto"/>
+                <ColumnDefinition Width="*"/>
+            </Grid.ColumnDefinitions>
+            <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Margin="0,0,0,10" Width="40" Height="40">
+                <Image Source="{Binding Image}" Stretch="UniformToFill"/>
+            </Border>
+            <StackPanel Grid.Column="1" Margin="10,-10,0,0">
+                <TextBlock Text="{Binding Title}" Style="{StaticResource BodyTextStyle}" TextWrapping="NoWrap"/>
+                <TextBlock Text="{Binding Subtitle}" Style="{StaticResource BodyTextStyle}" Foreground="{StaticResource ApplicationSecondaryForegroundThemeBrush}" Height="40"/>
+            </StackPanel>
+        </Grid>
+    </DataTemplate>
+
+  <!--
+      190x130 pixel item template for displaying file previews as seen in the FileOpenPickerPage
+      Includes an elaborate tooltip to display title and description text
+  -->
+  <DataTemplate x:Key="StandardFileWithTooltip190x130ItemTemplate">
+        <Grid>
+            <Grid Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
+                <Image
+                    Source="{Binding Image}"
+                    Width="190"
+                    Height="130"
+                    HorizontalAlignment="Center"
+                    VerticalAlignment="Center"
+                    Stretch="Uniform"/>
+            </Grid>
+            <ToolTipService.Placement>Mouse</ToolTipService.Placement>
+            <ToolTipService.ToolTip>
+                <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
+                    <Grid.ColumnDefinitions>
+                        <ColumnDefinition Width="Auto"/>
+                        <ColumnDefinition Width="*"/>
+                    </Grid.ColumnDefinitions>
+
+                    <Grid Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Margin="20">
+                        <Image
+                            Source="{Binding Image}"
+                            Width="160"
+                            Height="160"
+                            HorizontalAlignment="Center"
+                            VerticalAlignment="Center"
+                            Stretch="Uniform"/>
+                    </Grid>
+                    <StackPanel Width="200" Grid.Column="1" Margin="0,20,20,20">
+                        <TextBlock Text="{Binding Title}" TextWrapping="NoWrap" Style="{StaticResource BodyTextStyle}"/>
+                        <TextBlock Text="{Binding Description}" MaxHeight="140" Foreground="{StaticResource ApplicationSecondaryForegroundThemeBrush}" Style="{StaticResource BodyTextStyle}"/>
+                    </StackPanel>
+                </Grid>                    
+            </ToolTipService.ToolTip>
+        </Grid>
+    </DataTemplate>
+
+    <!-- Default to 10-pixel spacing between grid items (after accounting for 4-pixel insets for focus) -->
+
+    <Style TargetType="GridViewItem">
+        <Setter Property="Margin" Value="0,0,2,2" />
+    </Style>
+
+    <!-- ScrollViewer styles -->
+
+    <Style x:Key="HorizontalScrollViewerStyle" TargetType="ScrollViewer">
+        <Setter Property="HorizontalScrollBarVisibility" Value="Auto"/>
+        <Setter Property="VerticalScrollBarVisibility" Value="Disabled"/>
+        <Setter Property="ScrollViewer.HorizontalScrollMode" Value="Enabled" />
+        <Setter Property="ScrollViewer.VerticalScrollMode" Value="Disabled" />
+        <Setter Property="ScrollViewer.ZoomMode" Value="Disabled" />
+    </Style>
+
+    <Style x:Key="VerticalScrollViewerStyle" TargetType="ScrollViewer">
+        <Setter Property="HorizontalScrollBarVisibility" Value="Disabled"/>
+        <Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
+        <Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled" />
+        <Setter Property="ScrollViewer.VerticalScrollMode" Value="Enabled" />
+        <Setter Property="ScrollViewer.ZoomMode" Value="Disabled" />
+    </Style>
+
+    <!-- Page layout roots typically use entrance animations and a theme-appropriate background color -->
+
+    <Style x:Key="LayoutRootStyle" TargetType="Panel">
+        <Setter Property="Background" Value="{StaticResource ApplicationPageBackgroundThemeBrush}"/>
+        <Setter Property="ChildrenTransitions">
+            <Setter.Value>
+                <TransitionCollection>
+                    <EntranceThemeTransition/>
+                </TransitionCollection>
+            </Setter.Value>
+        </Setter>
+    </Style>
+</ResourceDictionary>
diff --git a/samples/winrt/ImageManipulations/common/suspensionmanager.cpp b/samples/winrt/ImageManipulations/common/suspensionmanager.cpp
new file mode 100644 (file)
index 0000000..c1ecf11
--- /dev/null
@@ -0,0 +1,481 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+//
+// SuspensionManager.cpp
+// Implementation of the SuspensionManager class
+//
+
+#include "pch.h"
+#include "SuspensionManager.h"
+
+#include <collection.h>
+#include <algorithm>
+
+using namespace SDKSample::Common;
+
+using namespace Concurrency;
+using namespace Platform;
+using namespace Platform::Collections;
+using namespace Windows::Foundation;
+using namespace Windows::Foundation::Collections;
+using namespace Windows::Storage;
+using namespace Windows::Storage::FileProperties;
+using namespace Windows::Storage::Streams;
+using namespace Windows::UI::Xaml;
+using namespace Windows::UI::Xaml::Controls;
+using namespace Windows::UI::Xaml::Interop;
+
+namespace
+{
+    Map<String^, Object^>^ _sessionState = ref new Map<String^, Object^>();
+    String^ sessionStateFilename = "_sessionState.dat";
+
+    // Forward declarations for object object read / write support
+    void WriteObject(Windows::Storage::Streams::DataWriter^ writer, Platform::Object^ object);
+    Platform::Object^ ReadObject(Windows::Storage::Streams::DataReader^ reader);
+}
+
+/// <summary>
+/// Provides access to global session state for the current session.  This state is serialized by
+/// <see cref="SaveAsync"/> and restored by <see cref="RestoreAsync"/> which require values to be
+/// one of the following: boxed values including integers, floating-point singles and doubles,
+/// wide characters, boolean, Strings and Guids, or Map<String^, Object^> where map values are
+/// subject to the same constraints.  Session state should be as compact as possible.
+/// </summary>
+IMap<String^, Object^>^ SuspensionManager::SessionState::get(void)
+{
+    return _sessionState;
+}
+
+/// <summary>
+/// Wrap a WeakReference as a reference object for use in a collection.
+/// </summary>
+private ref class WeakFrame sealed
+{
+private:
+    WeakReference _frameReference;
+
+internal:
+    WeakFrame(Frame^ frame) { _frameReference = frame; }
+    property Frame^ ResolvedFrame
+    {
+        Frame^ get(void) { return _frameReference.Resolve<Frame>(); }
+    };
+};
+
+namespace
+{
+    std::vector<WeakFrame^> _registeredFrames;
+    DependencyProperty^ FrameSessionStateKeyProperty =
+        DependencyProperty::RegisterAttached("_FrameSessionStateKeyProperty",
+        TypeName(String::typeid), TypeName(SuspensionManager::typeid), nullptr);
+    DependencyProperty^ FrameSessionStateProperty =
+        DependencyProperty::RegisterAttached("_FrameSessionStateProperty",
+        TypeName(IMap<String^, Object^>::typeid), TypeName(SuspensionManager::typeid), nullptr);
+}
+
+/// <summary>
+/// Registers a <see cref="Frame"/> instance to allow its navigation history to be saved to
+/// and restored from <see cref="SessionState"/>.  Frames should be registered once
+/// immediately after creation if they will participate in session state management.  Upon
+/// registration if state has already been restored for the specified key
+/// the navigation history will immediately be restored.  Subsequent invocations of
+/// <see cref="RestoreAsync(String)"/> will also restore navigation history.
+/// </summary>
+/// <param name="frame">An instance whose navigation history should be managed by
+/// <see cref="SuspensionManager"/></param>
+/// <param name="sessionStateKey">A unique key into <see cref="SessionState"/> used to
+/// store navigation-related information.</param>
+void SuspensionManager::RegisterFrame(Frame^ frame, String^ sessionStateKey)
+{
+    if (frame->GetValue(FrameSessionStateKeyProperty) != nullptr)
+    {
+        throw ref new FailureException("Frames can only be registered to one session state key");
+    }
+
+    if (frame->GetValue(FrameSessionStateProperty) != nullptr)
+    {
+        throw ref new FailureException("Frames must be either be registered before accessing frame session state, or not registered at all");
+    }
+
+    // Use a dependency property to associate the session key with a frame, and keep a list of frames whose
+    // navigation state should be managed
+    frame->SetValue(FrameSessionStateKeyProperty, sessionStateKey);
+    _registeredFrames.insert(_registeredFrames.begin(), ref new WeakFrame(frame));
+
+    // Check to see if navigation state can be restored
+    RestoreFrameNavigationState(frame);
+}
+
+/// <summary>
+/// Disassociates a <see cref="Frame"/> previously registered by <see cref="RegisterFrame"/>
+/// from <see cref="SessionState"/>.  Any navigation state previously captured will be
+/// removed.
+/// </summary>
+/// <param name="frame">An instance whose navigation history should no longer be
+/// managed.</param>
+void SuspensionManager::UnregisterFrame(Frame^ frame)
+{
+    // Remove session state and remove the frame from the list of frames whose navigation
+    // state will be saved (along with any weak references that are no longer reachable)
+    auto key = safe_cast<String^>(frame->GetValue(FrameSessionStateKeyProperty));
+    if (SessionState->HasKey(key)) SessionState->Remove(key);
+    _registeredFrames.erase(
+        std::remove_if(_registeredFrames.begin(), _registeredFrames.end(), [=](WeakFrame^& e)
+        {
+            auto testFrame = e->ResolvedFrame;
+            return testFrame == nullptr || testFrame == frame;
+        }),
+        _registeredFrames.end()
+    );
+}
+
+/// <summary>
+/// Provides storage for session state associated with the specified <see cref="Frame"/>.
+/// Frames that have been previously registered with <see cref="RegisterFrame"/> have
+/// their session state saved and restored automatically as a part of the global
+/// <see cref="SessionState"/>.  Frames that are not registered have transient state
+/// that can still be useful when restoring pages that have been discarded from the
+/// navigation cache.
+/// </summary>
+/// <remarks>Apps may choose to rely on <see cref="LayoutAwarePage"/> to manage
+/// page-specific state instead of working with frame session state directly.</remarks>
+/// <param name="frame">The instance for which session state is desired.</param>
+/// <returns>A collection of state subject to the same serialization mechanism as
+/// <see cref="SessionState"/>.</returns>
+IMap<String^, Object^>^ SuspensionManager::SessionStateForFrame(Frame^ frame)
+{
+    auto frameState = safe_cast<IMap<String^, Object^>^>(frame->GetValue(FrameSessionStateProperty));
+
+    if (frameState == nullptr)
+    {
+        auto frameSessionKey = safe_cast<String^>(frame->GetValue(FrameSessionStateKeyProperty));
+        if (frameSessionKey != nullptr)
+        {
+            // Registered frames reflect the corresponding session state
+            if (!_sessionState->HasKey(frameSessionKey))
+            {
+                _sessionState->Insert(frameSessionKey, ref new Map<String^, Object^>());
+            }
+            frameState = safe_cast<IMap<String^, Object^>^>(_sessionState->Lookup(frameSessionKey));
+        }
+        else
+        {
+            // Frames that aren't registered have transient state
+            frameState = ref new Map<String^, Object^>();
+        }
+        frame->SetValue(FrameSessionStateProperty, frameState);
+    }
+    return frameState;
+}
+
+void SuspensionManager::RestoreFrameNavigationState(Frame^ frame)
+{
+    auto frameState = SessionStateForFrame(frame);
+    if (frameState->HasKey("Navigation"))
+    {
+        frame->SetNavigationState(safe_cast<String^>(frameState->Lookup("Navigation")));
+    }
+}
+
+void SuspensionManager::SaveFrameNavigationState(Frame^ frame)
+{
+    auto frameState = SessionStateForFrame(frame);
+    frameState->Insert("Navigation", frame->GetNavigationState());
+}
+
+/// <summary>
+/// Save the current <see cref="SessionState"/>.  Any <see cref="Frame"/> instances
+/// registered with <see cref="RegisterFrame"/> will also preserve their current
+/// navigation stack, which in turn gives their active <see cref="Page"/> an opportunity
+/// to save its state.
+/// </summary>
+/// <returns>An asynchronous task that reflects when session state has been saved.</returns>
+task<void> SuspensionManager::SaveAsync(void)
+{
+    // Save the navigation state for all registered frames
+    for (auto&& weakFrame : _registeredFrames)
+    {
+        auto frame = weakFrame->ResolvedFrame;
+        if (frame != nullptr) SaveFrameNavigationState(frame);
+    }
+
+    // Serialize the session state synchronously to avoid asynchronous access to shared
+    // state
+    auto sessionData = ref new InMemoryRandomAccessStream();
+    auto sessionDataWriter = ref new DataWriter(sessionData->GetOutputStreamAt(0));
+    WriteObject(sessionDataWriter, _sessionState);
+
+    // Once session state has been captured synchronously, begin the asynchronous process
+    // of writing the result to disk
+    return task<unsigned int>(sessionDataWriter->StoreAsync()).then([=](unsigned int)
+    {
+        return sessionDataWriter->FlushAsync();
+    }).then([=](bool flushSucceeded)
+    {
+        (void)flushSucceeded; // Unused parameter
+        return ApplicationData::Current->LocalFolder->CreateFileAsync(sessionStateFilename,
+            CreationCollisionOption::ReplaceExisting);
+    }).then([=](StorageFile^ createdFile)
+    {
+        return createdFile->OpenAsync(FileAccessMode::ReadWrite);
+    }).then([=](IRandomAccessStream^ newStream)
+    {
+        return RandomAccessStream::CopyAndCloseAsync(
+            sessionData->GetInputStreamAt(0), newStream->GetOutputStreamAt(0));
+    }).then([=](UINT64 copiedBytes)
+    {
+        (void)copiedBytes; // Unused parameter
+        return;
+    });
+}
+
+/// <summary>
+/// Restores previously saved <see cref="SessionState"/>.  Any <see cref="Frame"/> instances
+/// registered with <see cref="RegisterFrame"/> will also restore their prior navigation
+/// state, which in turn gives their active <see cref="Page"/> an opportunity restore its
+/// state.
+/// </summary>
+/// <param name="version">A version identifer compared to the session state to prevent
+/// incompatible versions of session state from reaching app code.  Saved state with a
+/// different version will be ignored, resulting in an empty <see cref="SessionState"/>
+/// dictionary.</param>
+/// <returns>An asynchronous task that reflects when session state has been read.  The
+/// content of <see cref="SessionState"/> should not be relied upon until this task
+/// completes.</returns>
+task<void> SuspensionManager::RestoreAsync(void)
+{
+    _sessionState->Clear();
+
+    task<StorageFile^> getFileTask(ApplicationData::Current->LocalFolder->GetFileAsync(sessionStateFilename));
+    return getFileTask.then([=](StorageFile^ stateFile)
+    {
+        task<BasicProperties^> getBasicPropertiesTask(stateFile->GetBasicPropertiesAsync());
+        return getBasicPropertiesTask.then([=](BasicProperties^ stateFileProperties)
+        {
+            auto size = unsigned int(stateFileProperties->Size);
+            if (size != stateFileProperties->Size) throw ref new FailureException("Session state larger than 4GB");
+            task<IRandomAccessStreamWithContentType^> openReadTask(stateFile->OpenReadAsync());
+            return openReadTask.then([=](IRandomAccessStreamWithContentType^ stateFileStream)
+            {
+                auto stateReader = ref new DataReader(stateFileStream);
+                return task<unsigned int>(stateReader->LoadAsync(size)).then([=](unsigned int bytesRead)
+                {
+                    (void)bytesRead; // Unused parameter
+                    // Deserialize the Session State
+                    Object^ content = ReadObject(stateReader);
+                    _sessionState = (Map<String^, Object^>^)content;
+
+                    // Restore any registered frames to their saved state
+                    for (auto&& weakFrame : _registeredFrames)
+                    {
+                        auto frame = weakFrame->ResolvedFrame;
+                        if (frame != nullptr)
+                        {
+                            frame->ClearValue(FrameSessionStateProperty);
+                            RestoreFrameNavigationState(frame);
+                        }
+                    }
+                }, task_continuation_context::use_current());
+            });
+        });
+    });
+}
+
+#pragma region Object serialization for a known set of types
+
+namespace
+{
+    // Codes used for identifying serialized types
+    enum StreamTypes {
+        NullPtrType = 0,
+
+        // Supported IPropertyValue types
+        UInt8Type, UInt16Type, UInt32Type, UInt64Type, Int16Type, Int32Type, Int64Type,
+        SingleType, DoubleType, BooleanType, Char16Type, GuidType, StringType,
+
+        // Additional supported types
+        StringToObjectMapType,
+
+        // Marker values used to ensure stream integrity
+        MapEndMarker
+    };
+
+    void WriteString(DataWriter^ writer, String^ string)
+    {
+        writer->WriteByte(StringType);
+        writer->WriteUInt32(writer->MeasureString(string));
+        writer->WriteString(string);
+    }
+
+    void WriteProperty(DataWriter^ writer, IPropertyValue^ propertyValue)
+    {
+        switch (propertyValue->Type)
+        {
+        case PropertyType::UInt8:
+            writer->WriteByte(UInt8Type);
+            writer->WriteByte(propertyValue->GetUInt8());
+            return;
+        case PropertyType::UInt16:
+            writer->WriteByte(UInt16Type);
+            writer->WriteUInt16(propertyValue->GetUInt16());
+            return;
+        case PropertyType::UInt32:
+            writer->WriteByte(UInt32Type);
+            writer->WriteUInt32(propertyValue->GetUInt32());
+            return;
+        case PropertyType::UInt64:
+            writer->WriteByte(UInt64Type);
+            writer->WriteUInt64(propertyValue->GetUInt64());
+            return;
+        case PropertyType::Int16:
+            writer->WriteByte(Int16Type);
+            writer->WriteUInt16(propertyValue->GetInt16());
+            return;
+        case PropertyType::Int32:
+            writer->WriteByte(Int32Type);
+            writer->WriteUInt32(propertyValue->GetInt32());
+            return;
+        case PropertyType::Int64:
+            writer->WriteByte(Int64Type);
+            writer->WriteUInt64(propertyValue->GetInt64());
+            return;
+        case PropertyType::Single:
+            writer->WriteByte(SingleType);
+            writer->WriteSingle(propertyValue->GetSingle());
+            return;
+        case PropertyType::Double:
+            writer->WriteByte(DoubleType);
+            writer->WriteDouble(propertyValue->GetDouble());
+            return;
+        case PropertyType::Boolean:
+            writer->WriteByte(BooleanType);
+            writer->WriteBoolean(propertyValue->GetBoolean());
+            return;
+        case PropertyType::Char16:
+            writer->WriteByte(Char16Type);
+            writer->WriteUInt16(propertyValue->GetChar16());
+            return;
+        case PropertyType::Guid:
+            writer->WriteByte(GuidType);
+            writer->WriteGuid(propertyValue->GetGuid());
+            return;
+        case PropertyType::String:
+            WriteString(writer, propertyValue->GetString());
+            return;
+        default:
+            throw ref new InvalidArgumentException("Unsupported property type");
+        }
+    }
+
+    void WriteStringToObjectMap(DataWriter^ writer, IMap<String^, Object^>^ map)
+    {
+        writer->WriteByte(StringToObjectMapType);
+        writer->WriteUInt32(map->Size);
+        for (auto&& pair : map)
+        {
+            WriteObject(writer, pair->Key);
+            WriteObject(writer, pair->Value);
+        }
+        writer->WriteByte(MapEndMarker);
+    }
+
+    void WriteObject(DataWriter^ writer, Object^ object)
+    {
+        if (object == nullptr)
+        {
+            writer->WriteByte(NullPtrType);
+            return;
+        }
+
+        auto propertyObject = dynamic_cast<IPropertyValue^>(object);
+        if (propertyObject != nullptr)
+        {
+            WriteProperty(writer, propertyObject);
+            return;
+        }
+
+        auto mapObject = dynamic_cast<IMap<String^, Object^>^>(object);
+        if (mapObject != nullptr)
+        {
+            WriteStringToObjectMap(writer, mapObject);
+            return;
+        }
+
+        throw ref new InvalidArgumentException("Unsupported data type");
+    }
+
+    String^ ReadString(DataReader^ reader)
+    {
+        int length = reader->ReadUInt32();
+        String^ string = reader->ReadString(length);
+        return string;
+    }
+
+    IMap<String^, Object^>^ ReadStringToObjectMap(DataReader^ reader)
+    {
+        auto map = ref new Map<String^, Object^>();
+        auto size = reader->ReadUInt32();
+        for (unsigned int index = 0; index < size; index++)
+        {
+            auto key = safe_cast<String^>(ReadObject(reader));
+            auto value = ReadObject(reader);
+            map->Insert(key, value);
+        }
+        if (reader->ReadByte() != MapEndMarker)
+        {
+            throw ref new InvalidArgumentException("Invalid stream");
+        }
+        return map;
+    }
+
+    Object^ ReadObject(DataReader^ reader)
+    {
+        auto type = reader->ReadByte();
+        switch (type)
+        {
+        case NullPtrType:
+            return nullptr;
+        case UInt8Type:
+            return reader->ReadByte();
+        case UInt16Type:
+            return reader->ReadUInt16();
+        case UInt32Type:
+            return reader->ReadUInt32();
+        case UInt64Type:
+            return reader->ReadUInt64();
+        case Int16Type:
+            return reader->ReadInt16();
+        case Int32Type:
+            return reader->ReadInt32();
+        case Int64Type:
+            return reader->ReadInt64();
+        case SingleType:
+            return reader->ReadSingle();
+        case DoubleType:
+            return reader->ReadDouble();
+        case BooleanType:
+            return reader->ReadBoolean();
+        case Char16Type:
+            return (char16_t)reader->ReadUInt16();
+        case GuidType:
+            return reader->ReadGuid();
+        case StringType:
+            return ReadString(reader);
+        case StringToObjectMapType:
+            return ReadStringToObjectMap(reader);
+        default:
+            throw ref new InvalidArgumentException("Unsupported property type");
+        }
+    }
+}
+
+#pragma endregion
diff --git a/samples/winrt/ImageManipulations/common/suspensionmanager.h b/samples/winrt/ImageManipulations/common/suspensionmanager.h
new file mode 100644 (file)
index 0000000..65e1180
--- /dev/null
@@ -0,0 +1,50 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+//
+// SuspensionManager.h
+// Declaration of the SuspensionManager class
+//
+
+#pragma once
+
+#include <ppltasks.h>
+
+namespace SDKSample
+{
+    namespace Common
+    {
+        /// <summary>
+        /// SuspensionManager captures global session state to simplify process lifetime management
+        /// for an application.  Note that session state will be automatically cleared under a variety
+        /// of conditions and should only be used to store information that would be convenient to
+        /// carry across sessions, but that should be disacarded when an application crashes or is
+        /// upgraded.
+        /// </summary>
+        ref class SuspensionManager sealed
+        {
+        internal:
+            static void RegisterFrame(Windows::UI::Xaml::Controls::Frame^ frame, Platform::String^ sessionStateKey);
+            static void UnregisterFrame(Windows::UI::Xaml::Controls::Frame^ frame);
+            static Concurrency::task<void> SaveAsync(void);
+            static Concurrency::task<void> RestoreAsync(void);
+            static property Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ SessionState
+            {
+                Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ get(void);
+            };
+            static Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ SessionStateForFrame(
+                Windows::UI::Xaml::Controls::Frame^ frame);
+
+        private:
+            static void RestoreFrameNavigationState(Windows::UI::Xaml::Controls::Frame^ frame);
+            static void SaveFrameNavigationState(Windows::UI::Xaml::Controls::Frame^ frame);
+        };
+    }
+}
diff --git a/samples/winrt/ImageManipulations/pch.cpp b/samples/winrt/ImageManipulations/pch.cpp
new file mode 100644 (file)
index 0000000..97389d9
--- /dev/null
@@ -0,0 +1,16 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+//
+// pch.cpp
+// Include the standard header and generate the precompiled header.
+//
+
+#include "pch.h"
diff --git a/samples/winrt/ImageManipulations/pch.h b/samples/winrt/ImageManipulations/pch.h
new file mode 100644 (file)
index 0000000..13f9bc3
--- /dev/null
@@ -0,0 +1,23 @@
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+
+//
+// pch.h
+// Header for standard system include files.
+//
+
+#pragma once
+
+#include <collection.h>
+#include <ppltasks.h>
+#include <agile.h>
+#include "Common\LayoutAwarePage.h"
+#include "Common\SuspensionManager.h"
+#include "App.xaml.h"
diff --git a/samples/winrt/ImageManipulations/sample-utils/SampleTemplateStyles.xaml b/samples/winrt/ImageManipulations/sample-utils/SampleTemplateStyles.xaml
new file mode 100644 (file)
index 0000000..ec2c1a7
--- /dev/null
@@ -0,0 +1,51 @@
+<!--
+//*********************************************************
+//
+// Copyright (c) Microsoft. All rights reserved.
+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
+//
+//*********************************************************
+-->
+<ResourceDictionary
+    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+
+    <Style x:Key="TitleTextStyle" TargetType="TextBlock">
+        <Setter Property="FontFamily" Value="Segoe UI Light" />
+        <Setter Property="FontSize" Value="16" />
+    </Style>
+    <Style x:Key="HeaderTextStyle" TargetType="TextBlock">
+        <Setter Property="FontFamily" Value="Segoe UI Semilight" />
+        <Setter Property="FontSize" Value="26.667" />
+        <Setter Property="Margin" Value="0,0,0,25" />
+    </Style>
+    <Style x:Key="H2Style" TargetType="TextBlock">
+        <Setter Property="FontFamily" Value="Segoe UI" />
+        <Setter Property="FontSize" Value="14.667" />
+        <Setter Property="Margin" Value="0,0,0,0" />
+    </Style>
+    <Style x:Key="SubheaderTextStyle" TargetType="TextBlock">
+        <Setter Property="FontFamily" Value="Segoe UI Semilight" />
+        <Setter Property="FontSize" Value="14.667" />
+        <Setter Property="Margin" Value="0,0,0,5" />
+    </Style>
+    <Style x:Key="BasicTextStyle" TargetType="TextBlock">
+        <Setter Property="FontFamily" Value="Segoe UI Light" />
+        <Setter Property="FontSize" Value="16" />
+    </Style>
+    <Style x:Key="SeparatorStyle" TargetType="TextBlock">
+        <Setter Property="FontFamily" Value="Segoe UI" />
+        <Setter Property="FontSize" Value="9" />
+    </Style>
+    <Style x:Key="FooterStyle" TargetType="TextBlock">
+        <Setter Property="FontFamily" Value="Segoe UI" />
+        <Setter Property="FontSize" Value="12" />
+        <Setter Property="Margin" Value="0,8,0,0" />
+    </Style>
+    <Style x:Key="HyperlinkStyle" TargetType="HyperlinkButton">
+        <Setter Property="Padding" Value="5"/>
+    </Style>
+</ResourceDictionary>