merged ocl module from ocl branch (it's not quite usable yet; at least on Mac)
authorVadim Pisarevsky <no@email>
Mon, 16 Jul 2012 17:08:14 +0000 (17:08 +0000)
committerVadim Pisarevsky <no@email>
Mon, 16 Jul 2012 17:08:14 +0000 (17:08 +0000)
120 files changed:
CMakeLists.txt
cmake/OpenCVDetectOpenCL.cmake [new file with mode: 0644]
cmake/templates/cvconfig.h.cmake
modules/ocl/CMakeLists.txt [new file with mode: 0644]
modules/ocl/cl2cpp.py [new file with mode: 0644]
modules/ocl/doc/introduction.rst [new file with mode: 0644]
modules/ocl/doc/ocl.rst [new file with mode: 0644]
modules/ocl/doc/structures_and_functions.rst [new file with mode: 0644]
modules/ocl/include/opencv2/ocl/matrix_operations.hpp [new file with mode: 0644]
modules/ocl/include/opencv2/ocl/ocl.hpp [new file with mode: 0644]
modules/ocl/src/arithm.cpp [new file with mode: 0644]
modules/ocl/src/binarycaching.hpp [new file with mode: 0644]
modules/ocl/src/color.cpp [new file with mode: 0644]
modules/ocl/src/error.cpp [new file with mode: 0644]
modules/ocl/src/filtering.cpp [new file with mode: 0644]
modules/ocl/src/haar.cpp [new file with mode: 0644]
modules/ocl/src/imgproc.cpp [new file with mode: 0644]
modules/ocl/src/initialization.cpp [new file with mode: 0644]
modules/ocl/src/kernels/arithm_2_mat.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_LUT.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_absdiff.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_add.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_addWeighted.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_add_scalar.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_add_scalar_mask.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_bitwise_and.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_bitwise_and_mask.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_bitwise_and_scalar.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_bitwise_and_scalar_mask.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_bitwise_not.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_bitwise_or.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_bitwise_or_mask.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_bitwise_or_scalar.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_bitwise_or_scalar_mask.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_bitwise_xor.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_bitwise_xor_mask.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_bitwise_xor_scalar.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_bitwise_xor_scalar_mask.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_cartToPolar.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_compare_eq.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_compare_ne.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_div.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_exp.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_flip.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_flip_rc.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_log.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_magnitude.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_magnitudeSqr.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_minMax.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_minMaxLoc.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_minMaxLoc_mask.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_minMax_mask.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_mul.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_nonzero.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_phase.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_polarToCart.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_pow.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_sub.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_sub_scalar.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_sub_scalar_mask.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_sum.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_sum_3.cl [new file with mode: 0644]
modules/ocl/src/kernels/arithm_transpose.cl [new file with mode: 0644]
modules/ocl/src/kernels/convertC3C4.cl [new file with mode: 0644]
modules/ocl/src/kernels/cvt_color.cl [new file with mode: 0644]
modules/ocl/src/kernels/filter_sep_col.cl [new file with mode: 0644]
modules/ocl/src/kernels/filter_sep_row.cl [new file with mode: 0644]
modules/ocl/src/kernels/filtering_boxFilter.cl [new file with mode: 0644]
modules/ocl/src/kernels/filtering_dilateFilter.cl [new file with mode: 0644]
modules/ocl/src/kernels/filtering_erodeFilter.cl [new file with mode: 0644]
modules/ocl/src/kernels/filtering_laplacian.cl [new file with mode: 0644]
modules/ocl/src/kernels/haarobjectdetect.cl [new file with mode: 0644]
modules/ocl/src/kernels/haarobjectdetect_scaled2.cl [new file with mode: 0644]
modules/ocl/src/kernels/img_proc.cl [new file with mode: 0644]
modules/ocl/src/kernels/imgproc_bilateral.cl [new file with mode: 0644]
modules/ocl/src/kernels/imgproc_calcHarris.cl [new file with mode: 0644]
modules/ocl/src/kernels/imgproc_calcMinEigenVal.cl [new file with mode: 0644]
modules/ocl/src/kernels/imgproc_copymakeboder.cl [new file with mode: 0644]
modules/ocl/src/kernels/imgproc_histogram.cl [new file with mode: 0644]
modules/ocl/src/kernels/imgproc_integral.cl [new file with mode: 0644]
modules/ocl/src/kernels/imgproc_integral_sum.cl [new file with mode: 0644]
modules/ocl/src/kernels/imgproc_median.cl [new file with mode: 0644]
modules/ocl/src/kernels/imgproc_remap.cl [new file with mode: 0644]
modules/ocl/src/kernels/imgproc_resize.cl [new file with mode: 0644]
modules/ocl/src/kernels/imgproc_threshold.cl [new file with mode: 0644]
modules/ocl/src/kernels/imgproc_warpAffine.cl [new file with mode: 0644]
modules/ocl/src/kernels/imgproc_warpPerspective.cl [new file with mode: 0644]
modules/ocl/src/kernels/meanShift.cl [new file with mode: 0644]
modules/ocl/src/kernels/merge_mat.cl [new file with mode: 0644]
modules/ocl/src/kernels/operator_convertTo.cl [new file with mode: 0644]
modules/ocl/src/kernels/operator_copyToM.cl [new file with mode: 0644]
modules/ocl/src/kernels/operator_setTo.cl [new file with mode: 0644]
modules/ocl/src/kernels/operator_setToM.cl [new file with mode: 0644]
modules/ocl/src/kernels/split_mat.cl [new file with mode: 0644]
modules/ocl/src/kernels/stereobm.cl [new file with mode: 0644]
modules/ocl/src/kernels/stereobp.cl [new file with mode: 0644]
modules/ocl/src/kernels/stereocsbp.cl [new file with mode: 0644]
modules/ocl/src/matrix_operations.cpp [new file with mode: 0644]
modules/ocl/src/mssegmentation.cpp [new file with mode: 0644]
modules/ocl/src/precomp.cpp [new file with mode: 0644]
modules/ocl/src/precomp.hpp [new file with mode: 0644]
modules/ocl/src/safe_call.hpp [new file with mode: 0644]
modules/ocl/src/split_merge.cpp [new file with mode: 0644]
modules/ocl/src/stereo_csbp.cpp [new file with mode: 0644]
modules/ocl/src/stereobm.cpp [new file with mode: 0644]
modules/ocl/src/stereobp.cpp [new file with mode: 0644]
modules/ocl/src/threadsafe.cpp [new file with mode: 0644]
modules/ocl/src/threadsafe.h [new file with mode: 0644]
modules/ocl/test/interpolation.hpp [new file with mode: 0644]
modules/ocl/test/main.cpp [new file with mode: 0644]
modules/ocl/test/precomp.cpp [new file with mode: 0644]
modules/ocl/test/precomp.hpp [new file with mode: 0644]
modules/ocl/test/test_arithm.cpp [new file with mode: 0644]
modules/ocl/test/test_filters.cpp [new file with mode: 0644]
modules/ocl/test/test_haar.cpp [new file with mode: 0644]
modules/ocl/test/test_imgproc.cpp [new file with mode: 0644]
modules/ocl/test/test_matrix_operation.cpp [new file with mode: 0644]
modules/ocl/test/test_split_merge.cpp [new file with mode: 0644]
modules/ocl/test/utility.cpp [new file with mode: 0644]
modules/ocl/test/utility.hpp [new file with mode: 0644]

index 01222f9..62709b8 100644 (file)
@@ -139,6 +139,7 @@ OCV_OPTION(WITH_VIDEOINPUT     "Build HighGUI with DirectShow support"       ON
 OCV_OPTION(WITH_XIMEA          "Include XIMEA cameras support"               OFF  IF (NOT ANDROID AND NOT APPLE) )
 OCV_OPTION(WITH_XINE           "Include Xine support (GPL)"                  OFF  IF (UNIX AND NOT APPLE AND NOT ANDROID) )
 OCV_OPTION(WITH_CLP            "Include Clp support (EPL)"                   OFF)
+OCV_OPTION(WITH_OPENCL         "Include OpenCL Runtime support"              OFF  IF (NOT ANDROID AND NOT IOS) )
 
 # OpenCV build components
 # ===================================================
@@ -389,6 +390,13 @@ else()
   SET(CAN_BUILD_ANDROID_PROJECTS FALSE)
 endif()
 
+# --- OpenCL ---
+if(WITH_OPENCL)
+  include(cmake/OpenCVDetectOpenCL.cmake REQUIRED)
+  if(OPENCL_FOUND)
+    set(HAVE_OPENCL 1)
+  endif()
+endif()
 
 # ----------------------------------------------------------------------------
 # Solution folders:
@@ -715,6 +723,8 @@ if(DEFINED WITH_CUDA)
   status("    Use Cuda:"  HAVE_CUDA  THEN "YES (ver ${CUDA_VERSION_STRING})" ELSE NO)
 endif(DEFINED WITH_CUDA)
 
+status("    Use OpenCL:"  HAVE_OPENCL  THEN YES ELSE NO)
+
 status("    Use Eigen:" HAVE_EIGEN THEN "YES (ver ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION})" ELSE NO)
 status("    Use Clp:"   HAVE_CLP   THEN YES ELSE NO)
 
diff --git a/cmake/OpenCVDetectOpenCL.cmake b/cmake/OpenCVDetectOpenCL.cmake
new file mode 100644 (file)
index 0000000..d000926
--- /dev/null
@@ -0,0 +1,64 @@
+if(APPLE)
+    set(OPENCL_FOUND YES)
+    set(OPENCL_LIBRARIES "-framework OpenCL")
+else()
+    find_package(OpenCL)
+
+    # Try AMD/ATI Stream SDK
+    if (NOT OPENCL_FOUND)
+        set(ENV_AMDSTREAMSDKROOT $ENV{AMDAPPSDKROOT})
+        set(ENV_OPENCLROOT $ENV{OPENCLROOT})
+        set(ENV_CUDA_PATH $ENV{CUDA_PATH})
+        if(ENV_AMDSTREAMSDKROOT)
+            set(OPENCL_INCLUDE_SEARCH_PATH ${ENV_AMDSTREAMSDKROOT}/include)
+            if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+                set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} ${ENV_AMDSTREAMSDKROOT}/lib/x86)
+            else()
+                set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} ${ENV_AMDSTREAMSDKROOT}/lib/x86_64)
+            endif()
+        elif(ENV_CUDAPATH AND WIN32)
+            set(OPENCL_INCLUDE_SEARCH_PATH ${ENV_CUDA_PATH}/include)
+            if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+                set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} ${ENV_CUDA_PATH}/lib/Win32)
+            else()
+                set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} ${ENV_CUDA_PATH}/lib/x64)
+            endif()
+        elif(ENV_OPENCLROOT AND UNIX)
+            set(OPENCL_INCLUDE_SEARCH_PATH ${ENV_OPENCLROOT}/inc)
+            if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+                set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} /usr/lib)
+            else()
+                set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} /usr/lib64)
+            endif()
+        endif()
+    
+        if(OPENCL_INCLUDE_SEARCH_PATH)
+            find_path(OPENCL_INCLUDE_DIR
+                NAMES CL/cl.h OpenCL/cl.h
+                PATHS ${OPENCL_INCLUDE_SEARCH_PATH}
+                NO_DEFAULT_PATH)
+        else()
+            find_path(OPENCL_INCLUDE_DIR
+                NAMES CL/cl.h OpenCL/cl.h)
+        endif()
+    
+        if(OPENCL_LIB_SEARCH_PATH)
+            find_library(OPENCL_LIBRARY NAMES OpenCL PATHS ${OPENCL_LIB_SEARCH_PATH} NO_DEFAULT_PATH)
+        else()
+            find_library(OPENCL_LIBRARY NAMES OpenCL PATHS ${OPENCL_LIB_SEARCH_PATH} NO_DEFAULT_PATH)
+        endif()
+
+        include(FindPackageHandleStandardArgs)
+        find_package_handle_standard_args(
+          OPENCL
+          DEFAULT_MSG
+          OPENCL_LIBRARY OPENCL_INCLUDE_DIR
+          )
+
+        if(OPENCL_FOUND)
+            set(OPENCL_LIBRARIES ${OPENCL_LIBRARY})
+        else()
+            set(OPENCL_LIBRARIES)
+        endif()
+    endif()
+endif()
index 417f6eb..1012008 100644 (file)
 /* NVidia Cuda Runtime API*/
 #cmakedefine HAVE_CUDA
 
+/* OpenCL Support */
+#cmakedefine HAVE_OPENCL
+
 /* NVidia Cuda Fast Fourier Transform (FFT) API*/
 #cmakedefine HAVE_CUFFT
 
diff --git a/modules/ocl/CMakeLists.txt b/modules/ocl/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b331e9f
--- /dev/null
@@ -0,0 +1,63 @@
+# Will be modified later 
+if(NOT HAVE_OPENCL)
+  ocv_module_disable(ocl)
+endif()
+
+set(the_description "OpenCL-accelerated Computer Vision")
+ocv_add_module(ocl opencv_core opencv_imgproc opencv_calib3d opencv_objdetect opencv_video opencv_nonfree)
+
+ocv_module_include_directories()
+
+file(GLOB CL_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/kernels/*.cl")
+set(kernels_cpp "${CMAKE_CURRENT_BINARY_DIR}/kernels.cpp")
+set(cl2cpp_script "${CMAKE_CURRENT_SOURCE_DIR}/cl2cpp.py")
+
+add_custom_command(
+   OUTPUT ${kernels_cpp}
+   COMMAND ${PYTHON_EXECUTABLE} ${cl2cpp_script} "${CMAKE_CURRENT_SOURCE_DIR}/src/kernels" ${kernels_cpp}
+   DEPENDS ${CL_FILES} ${cl2cpp_script})
+
+file(GLOB lib_hdrs     "include/opencv2/${name}/*.hpp" "include/opencv2/${name}/*.h")
+file(GLOB lib_srcs     "src/*.cpp")
+file(GLOB lib_int_hdrs "src/*.h*")
+
+source_group("Include"   FILES ${lib_hdrs})
+source_group("Src\\Host" FILES ${lib_srcs} ${lib_int_hdrs} ${kernels_cpp})
+
+if (HAVE_OPENCL)
+  set(ocl_link_libs ${OPENCL_LIBRARIES})
+  if(OPENCL_INCLUDE_DIR)
+      ocv_include_directories(${OPENCL_INCLUDE_DIR})
+  endif()
+endif()
+
+ocv_set_module_sources(
+    HEADERS ${lib_hdrs}
+    SOURCES ${lib_int_hdrs} ${lib_srcs}
+    )
+    
+set(OPENCV_MODULE_opencv_ocl_SOURCES ${OPENCV_MODULE_opencv_ocl_SOURCES} ${kernels_cpp})
+ocv_create_module(${ocl_link_libs})
+
+install(FILES ${lib_hdrs}
+    DESTINATION include/opencv2/${name}
+    COMPONENT main)
+
+ocv_add_precompiled_headers(${the_module})
+
+################################################################################################################
+################################      OpenCL Module Tests     ##################################################
+################################################################################################################
+file(GLOB test_srcs "test/*.cpp")
+file(GLOB test_hdrs "test/*.hpp" "test/*.h")
+
+ocv_add_accuracy_tests(FILES "Include" ${test_hdrs}
+                       FILES "Src" ${test_srcs})
+################################################################################################################
+################################   OpenCL Module Performance  ##################################################
+################################################################################################################
+#file(GLOB perf_srcs "perf/*.cpp")
+#file(GLOB perf_hdrs "perf/*.hpp" "perf/*.h")
+
+#ocv_add_perf_tests(FILES "Include" ${perf_hdrs}
+#                       FILES "Src" ${perf_srcs})
diff --git a/modules/ocl/cl2cpp.py b/modules/ocl/cl2cpp.py
new file mode 100644 (file)
index 0000000..b6b5fa6
--- /dev/null
@@ -0,0 +1,55 @@
+import os, os.path, sys, glob
+
+indir = sys.argv[1]
+outname = sys.argv[2]
+#indir = "/Users/vp/work/ocv/opencv/modules/ocl/src/kernels"
+#outname = "/Users/vp/work/ocv.build/xcode/modules/ocl/kernels.cpp"
+
+try:
+    os.mkdir(os.path.dirname(outname))
+except OSError:
+    pass
+
+cl_list = glob.glob(os.path.join(indir, "*.cl"))
+kfile = open(outname, "wt")
+
+kfile.write("""// This file is auto-generated. Do not edit!
+#include "precomp.hpp"
+namespace cv
+{
+namespace ocl
+{
+""")
+
+for cl in cl_list:
+    cl_file = open(cl, "rt")
+    cl_filename = os.path.basename(cl)
+    cl_filename = cl_filename[:cl_filename.rfind(".")]
+    kfile.write("const char* %s=" % cl_filename)
+    state = 0
+    
+    for cl_line in cl_file.readlines():
+        l = cl_line.strip()
+        # skip the leading comments
+        if l.startswith("//") and l.find("*/") < 0:
+            if state == 0:
+                state = 1
+        else:
+            if state == 1 or l.find("*/") >= 0:
+                state = 2
+        
+        if state == 1:
+            continue
+        
+        l = l.replace("\\", "\\\\")
+        l = l.replace("\r", "")
+        l = l.replace("\"", "\\\"")
+        l = l.replace("\t", "  ")
+        kfile.write("\"%s\\n\"\n" % l)
+    kfile.write(";\n")
+    cl_file.close()
+
+kfile.write("""}
+}
+""")
+kfile.close()
diff --git a/modules/ocl/doc/introduction.rst b/modules/ocl/doc/introduction.rst
new file mode 100644 (file)
index 0000000..ef6d4c3
--- /dev/null
@@ -0,0 +1,19 @@
+OpenCL Module Introduction
+==========================
+
+.. highlight:: cpp
+
+General Information
+-------------------
+
+The OpenCV OCL module is a set of classes and functions to utilize OpenCL compatible device. It should support any device compatible with OpenCL 1.1. The module includes utility functions, low-level vision primitives, and a few high-level algorithms ready to be used in the end-user applications.
+
+The OpenCV OCL module is designed as a host-level API plus device-level kernels. The device-level kernels are converted to text string and are compiled at runtime, so it need OpenCL runtime support. To correctly run the OpenCV OCL module, make sure you have OpenCL runtime provided by your device vendor, which is device driver normally.
+
+The OpenCV OCL module is designed for ease of use and does not require any knowledge of OpenCL. Though, such a knowledge will certainly be useful to handle non-trivial cases or achieve the highest performance. It is helpful to understand the cost of various operations, what the module does, what the preferred data formats are, and so on. Since there is data transfer between OpenCL host and OpenCL device, for better performance it's recommended to copy data once to the OpenCL host memory (i.e. copy ``cv::Mat`` to ``cv::ocl::OclMat``), then call several ``cv::ocl`` functions and then copy the result back to CPU memory, rather than do forward and backward transfer for each OCL function.
+
+To enable OCL support, configure OpenCV using CMake with the option ``WITH\_OPENCL=ON``. If the option is passed and if OpenCL SDK is installed (e.g. on MacOSX it's always the case), the full-featured OpenCV OCL module will be built. Otherwise, the module will not be built.
+
+Right now, the user should define the ``cv::ocl::Info`` class in the application and call ``cv::ocl::getDevice`` before any ``cv::ocl::<func>``. This operation initialize OpenCL runtime and set the first found device as computing device. If there is more than one device and you want to use non-default device, you should call ``cv::ocl::setDevice``.
+
+In the current version, all the threads share the same context and device so the multi-devices are not supported. This is to be fixed in future releases.
diff --git a/modules/ocl/doc/ocl.rst b/modules/ocl/doc/ocl.rst
new file mode 100644 (file)
index 0000000..3792673
--- /dev/null
@@ -0,0 +1,19 @@
+************************************
+ocl. OpenCL-accelerated Computer Vision
+************************************
+
+.. toctree::
+    :maxdepth: 1
+
+    introduction
+    initalization_and_information
+    data_structures
+    operations_on_matrices
+    per_element_operations
+    image_processing
+    matrix_reductions
+    object_detection
+    feature_detection_and_description
+    image_filtering
+    camera_calibration_and_3d_reconstruction
+    video
diff --git a/modules/ocl/doc/structures_and_functions.rst b/modules/ocl/doc/structures_and_functions.rst
new file mode 100644 (file)
index 0000000..aba4b70
--- /dev/null
@@ -0,0 +1,23 @@
+Data Structures and Functions
+=============================
+
+.. highlight:: cpp
+
+ocl::Info
+---------
+.. ocv:class:: ocl::Info
+
+this class should be maintained by the user and be passed to getDevice
+
+ocl::getDevice
+------------------
+Returns the list of devices
+
+.. ocv:function:: int ocl::getDevice(std::vector<Info>& oclinfo, int devicetype = CVCL_DEVICE_TYPE_GPU)
+
+    :param oclinfo: Output vector of ``ocl::Info`` structures
+    
+    :param devicetype: One of ``CVCL_DEVICE_TYPE_GPU``, ``CVCL_DEVICE_TYPE_CPU`` or ``CVCL_DEVICE_TYPE_DEFAULT``.
+    
+the function must be called before any other ``cv::ocl`` functions; it initializes ocl runtime.
+
diff --git a/modules/ocl/include/opencv2/ocl/matrix_operations.hpp b/modules/ocl/include/opencv2/ocl/matrix_operations.hpp
new file mode 100644 (file)
index 0000000..e90da2b
--- /dev/null
@@ -0,0 +1,456 @@
+/*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.
+// 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 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 __OPENCV_GPU_MATRIX_OPERATIONS_HPP__
+#define __OPENCV_GPU_MATRIX_OPERATIONS_HPP__
+
+namespace cv
+{
+
+    namespace ocl
+    {
+        ////////////////////////////////////OpenCL kernel strings//////////////////////////
+        extern const char *convertC3C4;
+
+        ////////////////////////////////////////////////////////////////////////
+        //////////////////////////////// oclMat ////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////
+
+        inline oclMat::oclMat() : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), offset(0), wholerows(0), wholecols(0) {}
+
+        inline oclMat::oclMat(int _rows, int _cols, int _type) : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), offset(0), wholerows(0), wholecols(0)
+        {
+            if( _rows > 0 && _cols > 0 )
+                create( _rows, _cols, _type );
+        }
+
+        inline oclMat::oclMat(Size _size, int _type) : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), offset(0), wholerows(0), wholecols(0)
+        {
+            if( _size.height > 0 && _size.width > 0 )
+                create( _size.height, _size.width, _type );
+        }
+
+        inline oclMat::oclMat(int _rows, int _cols, int _type, const Scalar &_s)
+            : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), offset(0), wholerows(0), wholecols(0)
+        {
+            if(_rows > 0 && _cols > 0)
+            {
+                create(_rows, _cols, _type);
+                *this = _s;
+            }
+        }
+
+        inline oclMat::oclMat(Size _size, int _type, const Scalar &_s)
+            : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), offset(0), wholerows(0), wholecols(0)
+        {
+            if( _size.height > 0 && _size.width > 0 )
+            {
+                create( _size.height, _size.width, _type );
+                *this = _s;
+            }
+        }
+
+        inline oclMat::oclMat(const oclMat &m)
+            : flags(m.flags), rows(m.rows), cols(m.cols), step(m.step), data(m.data),
+              refcount(m.refcount), datastart(m.datastart), dataend(m.dataend), clCxt(m.clCxt), offset(m.offset), wholerows(m.wholerows), wholecols(m.wholecols)
+        {
+            if( refcount )
+                CV_XADD(refcount, 1);
+        }
+        //Fixme, the data is not correct if _data point to the CPU memory
+        inline oclMat::oclMat(int _rows, int _cols, int _type, void *_data, size_t _step)
+            : flags(Mat::MAGIC_VAL + (_type &TYPE_MASK)), rows(_rows), cols(_cols), step(_step), data((uchar *)_data), refcount(0),
+              datastart((uchar *)_data), dataend((uchar *)_data), offset(0), wholerows(_rows), wholecols(_cols)
+        {
+            size_t minstep = cols * elemSize();
+            if( step == Mat::AUTO_STEP )
+            {
+                step = minstep;
+                flags |= Mat::CONTINUOUS_FLAG;
+            }
+            else
+            {
+                if( rows == 1 ) step = minstep;
+                CV_DbgAssert( step >= minstep );
+                flags |= step == minstep ? Mat::CONTINUOUS_FLAG : 0;
+            }
+            dataend += step * (rows - 1) + minstep;
+        }
+        //Fixme, the data is not correct if _data point to the CPU memory
+        inline oclMat::oclMat(Size _size, int _type, void *_data, size_t _step)
+            : flags(Mat::MAGIC_VAL + (_type &TYPE_MASK)), rows(_size.height), cols(_size.width),
+              step(_step), data((uchar *)_data), refcount(0),
+              datastart((uchar *)_data), dataend((uchar *)_data), offset(0), wholerows(_size.height), wholecols(_size.width)
+        {
+            size_t minstep = cols * elemSize();
+            if( step == Mat::AUTO_STEP )
+            {
+                step = minstep;
+                flags |= Mat::CONTINUOUS_FLAG;
+            }
+            else
+            {
+                if( rows == 1 ) step = minstep;
+                CV_DbgAssert( step >= minstep );
+                flags |= step == minstep ? Mat::CONTINUOUS_FLAG : 0;
+            }
+            dataend += step * (rows - 1) + minstep;
+        }
+
+
+        inline oclMat::oclMat(const oclMat &m, const Range &rowRange, const Range &colRange)
+        {
+            flags = m.flags;
+            step = m.step;
+            refcount = m.refcount;
+            data = m.data;
+            datastart = m.datastart;
+            dataend = m.dataend;
+            wholerows = m.wholerows;
+            wholecols = m.wholecols;
+            offset = m.offset;
+            if( rowRange == Range::all() )
+                rows = m.rows;
+            else
+            {
+                CV_Assert( 0 <= rowRange.start && rowRange.start <= rowRange.end && rowRange.end <= m.rows );
+                rows = rowRange.size();
+                offset += step * rowRange.start;
+            }
+
+            if( colRange == Range::all() )
+                cols = m.cols;
+            else
+            {
+                CV_Assert( 0 <= colRange.start && colRange.start <= colRange.end && colRange.end <= m.cols );
+                cols = colRange.size();
+                offset += colRange.start * elemSize();
+                flags &= cols < m.cols ? ~Mat::CONTINUOUS_FLAG : -1;
+            }
+
+            if( rows == 1 )
+                flags |= Mat::CONTINUOUS_FLAG;
+
+            if( refcount )
+                CV_XADD(refcount, 1);
+            if( rows <= 0 || cols <= 0 )
+                rows = cols = 0;
+        }
+
+        inline oclMat::oclMat(const oclMat &m, const Rect &roi)
+            : flags(m.flags), rows(roi.height), cols(roi.width),
+              step(m.step), data(m.data), refcount(m.refcount),
+              datastart(m.datastart), dataend(m.dataend), clCxt(m.clCxt), offset(m.offset), wholerows(m.wholerows), wholecols(m.wholecols)
+        {
+            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 );
+            if( refcount )
+                CV_XADD(refcount, 1);
+            if( rows <= 0 || cols <= 0 )
+                rows = cols = 0;
+        }
+
+        inline oclMat::oclMat(const Mat &m)
+            : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0) , offset(0), wholerows(0), wholecols(0)
+        {
+            //clCxt = Context::getContext();
+            upload(m);
+        }
+
+        inline oclMat::~oclMat()
+        {
+            release();
+        }
+
+        inline oclMat &oclMat::operator = (const oclMat &m)
+        {
+            if( this != &m )
+            {
+                if( m.refcount )
+                    CV_XADD(m.refcount, 1);
+                release();
+                clCxt = m.clCxt;
+                flags = m.flags;
+                rows = m.rows;
+                cols = m.cols;
+                step = m.step;
+                data = m.data;
+                datastart = m.datastart;
+                dataend = m.dataend;
+                offset = m.offset;
+                wholerows = m.wholerows;
+                wholecols = m.wholecols;
+                refcount = m.refcount;
+            }
+            return *this;
+        }
+
+        inline oclMat &oclMat::operator = (const Mat &m)
+        {
+            //clCxt = Context::getContext();
+            upload(m);
+            return *this;
+        }
+
+        /* Fixme! To be supported in OpenCL later. */
+#if 0
+        template <class T> inline oclMat::operator DevMem2D_<T>() const
+        {
+            return DevMem2D_<T>(rows, cols, (T *)data, step);
+        }
+        template <class T> inline oclMat::operator PtrStep_<T>() const
+        {
+            return PtrStep_<T>(static_cast< DevMem2D_<T> >(*this));
+        }
+#endif
+
+        //CPP: void oclMat::upload(const Mat& m);
+
+        inline oclMat::operator Mat() const
+        {
+            Mat m;
+            download(m);
+            return m;
+        }
+
+        //CPP void oclMat::download(cv::Mat& m) const;
+
+        inline oclMat oclMat::row(int y) const
+        {
+            return oclMat(*this, Range(y, y + 1), Range::all());
+        }
+        inline oclMat oclMat::col(int x) const
+        {
+            return oclMat(*this, Range::all(), Range(x, x + 1));
+        }
+        inline oclMat oclMat::rowRange(int startrow, int endrow) const
+        {
+            return oclMat(*this, Range(startrow, endrow), Range::all());
+        }
+        inline oclMat oclMat::rowRange(const Range &r) const
+        {
+            return oclMat(*this, r, Range::all());
+        }
+        inline oclMat oclMat::colRange(int startcol, int endcol) const
+        {
+            return oclMat(*this, Range::all(), Range(startcol, endcol));
+        }
+        inline oclMat oclMat::colRange(const Range &r) const
+        {
+            return oclMat(*this, Range::all(), r);
+        }
+
+        inline oclMat oclMat::clone() const
+        {
+            oclMat m;
+            copyTo(m);
+            return m;
+        }
+
+        //CPP void oclMat::copyTo( oclMat& m ) const;
+        //CPP void oclMat::copyTo( oclMat& m, const oclMat& mask  ) const;
+        //CPP void oclMat::convertTo( oclMat& m, int rtype, double alpha=1, double beta=0 ) const;
+
+        inline void oclMat::assignTo( oclMat &m, int type ) const
+        {
+            if( type < 0 )
+                m = *this;
+            else
+                convertTo(m, type);
+        }
+
+        //CPP oclMat& oclMat::operator = (const Scalar& s);
+        //CPP oclMat& oclMat::setTo(const Scalar& s, const oclMat& mask=oclMat());
+        //CPP oclMat oclMat::reshape(int _cn, int _rows=0) const;
+        inline void oclMat::create(Size _size, int _type)
+        {
+            create(_size.height, _size.width, _type);
+        }
+        //CPP void oclMat::create(int _rows, int _cols, int _type);
+        //CPP void oclMat::release();
+
+        inline void oclMat::swap(oclMat &b)
+        {
+            std::swap( flags, b.flags );
+            std::swap( rows, b.rows );
+            std::swap( cols, b.cols );
+            std::swap( step, b.step );
+            std::swap( data, b.data );
+            std::swap( datastart, b.datastart );
+            std::swap( dataend, b.dataend );
+            std::swap( refcount, b.refcount );
+            std::swap( offset, b.offset );
+            std::swap( wholerows, b.wholerows );
+            std::swap( wholecols, b.wholecols );
+        }
+
+        inline void oclMat::locateROI( Size &wholeSize, Point &ofs ) const
+        {
+            size_t esz = elemSize();//, minstep;
+            //ptrdiff_t delta1 = offset;//, delta2 = dataend - datastart;
+            CV_DbgAssert( step > 0 );
+            if( offset == 0 )
+                ofs.x = ofs.y = 0;
+            else
+            {
+                ofs.y = (int)(offset / step);
+                ofs.x = (int)((offset - step * ofs.y) / esz);
+                //CV_DbgAssert( data == datastart + ofs.y*step + ofs.x*esz );
+            }
+            //minstep = (ofs.x + cols)*esz;
+            //wholeSize.height = (int)((delta2 - minstep)/step + 1);
+            //wholeSize.height = std::max(wholeSize.height, ofs.y + rows);
+            //wholeSize.width = (int)((delta2 - step*(wholeSize.height-1))/esz);
+            //wholeSize.width = std::max(wholeSize.width, ofs.x + cols);
+            wholeSize.height = wholerows;
+            wholeSize.width = wholecols;
+        }
+
+        inline oclMat &oclMat::adjustROI( int dtop, int dbottom, int dleft, int dright )
+        {
+            Size wholeSize;
+            Point ofs;
+            size_t esz = elemSize();
+            locateROI( wholeSize, ofs );
+            int row1 = std::max(ofs.y - dtop, 0), row2 = std::min(ofs.y + rows + dbottom, wholeSize.height);
+            int col1 = std::max(ofs.x - dleft, 0), col2 = std::min(ofs.x + cols + dright, wholeSize.width);
+            offset += (row1 - ofs.y) * step + (col1 - ofs.x) * esz;
+            rows = row2 - row1;
+            cols = col2 - col1;
+            if( esz *cols == step || rows == 1 )
+                flags |= Mat::CONTINUOUS_FLAG;
+            else
+                flags &= ~Mat::CONTINUOUS_FLAG;
+            return *this;
+        }
+
+        inline oclMat oclMat::operator()( Range rowRange, Range colRange ) const
+        {
+            return oclMat(*this, rowRange, colRange);
+        }
+        inline oclMat oclMat::operator()( const Rect &roi ) const
+        {
+            return oclMat(*this, roi);
+        }
+
+        inline bool oclMat::isContinuous() const
+        {
+            return (flags & Mat::CONTINUOUS_FLAG) != 0;
+        }
+        inline size_t oclMat::elemSize() const
+        {
+            return CV_ELEM_SIZE(flags);
+        }
+        inline size_t oclMat::elemSize1() const
+        {
+            return CV_ELEM_SIZE1(flags);
+        }
+        inline int oclMat::type() const
+        {
+            return CV_MAT_TYPE(flags);
+        }
+        inline int oclMat::depth() const
+        {
+            return CV_MAT_DEPTH(flags);
+        }
+        inline int oclMat::channels() const
+        {
+            return CV_MAT_CN(flags);
+        }
+        inline size_t oclMat::step1() const
+        {
+            return step / elemSize1();
+        }
+        inline Size oclMat::size() const
+        {
+            return Size(cols, rows);
+        }
+        inline bool oclMat::empty() const
+        {
+            return data == 0;
+        }
+
+
+        //fixme, the ROI operation is not correct.
+        inline uchar *oclMat::ptr(int y)
+        {
+            CV_DbgAssert( (unsigned)y < (unsigned)rows );
+            return data + step * y;
+        }
+
+        inline const uchar *oclMat::ptr(int y) const
+        {
+            CV_DbgAssert( (unsigned)y < (unsigned)rows );
+            return data + step * y;
+        }
+
+        template<typename _Tp> inline _Tp *oclMat::ptr(int y)
+        {
+            CV_DbgAssert( (unsigned)y < (unsigned)rows );
+            return (_Tp *)(data + step * y);
+        }
+
+        template<typename _Tp> inline const _Tp *oclMat::ptr(int y) const
+        {
+            CV_DbgAssert( (unsigned)y < (unsigned)rows );
+            return (const _Tp *)(data + step * y);
+        }
+
+        inline oclMat oclMat::t() const
+        {
+            oclMat tmp;
+            transpose(*this, tmp);
+            return tmp;
+        }
+
+        static inline void swap( oclMat &a, oclMat &b )
+        {
+            a.swap(b);
+        }
+
+    } /* end of namespace ocl */
+
+} /* end of namespace cv */
+
+#endif /* __OPENCV_GPU_MATRIX_OPERATIONS_HPP__ */
diff --git a/modules/ocl/include/opencv2/ocl/ocl.hpp b/modules/ocl/include/opencv2/ocl/ocl.hpp
new file mode 100644 (file)
index 0000000..752b554
--- /dev/null
@@ -0,0 +1,864 @@
+/*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.
+// 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 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 __OPENCV_GPU_HPP__
+#define __OPENCV_GPU_HPP__
+
+#include <memory>
+#include <vector>
+
+#include "opencv2/core/core.hpp"
+#include "opencv2/imgproc/imgproc.hpp"
+#include "opencv2/objdetect/objdetect.hpp"
+
+namespace cv
+{
+    namespace ocl
+    {
+        using std::auto_ptr;
+        
+#define CVCL_DEVICE_TYPE_DEFAULT                      (1 << 0)
+#define CVCL_DEVICE_TYPE_CPU                          (1 << 1)
+#define CVCL_DEVICE_TYPE_GPU                          (1 << 2)
+#define CVCL_DEVICE_TYPE_ACCELERATOR                  (1 << 3)
+        //#define CVCL_DEVICE_TYPE_CUSTOM                       (1 << 4)
+#define CVCL_DEVICE_TYPE_ALL                          0xFFFFFFFF
+        //this class contains ocl runtime information
+        class CV_EXPORTS Info
+        {
+        public:
+            struct Impl;
+            Impl *impl;
+
+            Info();
+            Info(const Info &m);
+            ~Info();
+            void release();
+            Info &operator = (const Info &m);
+        };
+        //////////////////////////////// Initialization & Info ////////////////////////
+        //this function may be obsoleted
+        //CV_EXPORTS cl_device_id getDevice();
+        //the function must be called before any other cv::ocl::functions, it initialize ocl runtime
+        CV_EXPORTS int getDevice(std::vector<Info>& oclinfo, int devicetype = CVCL_DEVICE_TYPE_GPU);
+        //set device you want to use, optional function after getDevice be called
+        CV_EXPORTS void setDevice(Info &oclinfo, int devnum = 0);
+        //this function is not ready yet
+        //CV_EXPORTS void getComputeCapability(cl_device_id device, int &major, int &minor);
+        //optional function, if you want save opencl binary kernel to the file, set its path
+        CV_EXPORTS  void setBinpath(const char *path);
+
+        //////////////////////////////// Error handling ////////////////////////
+        CV_EXPORTS void error(const char *error_string, const char *file, const int line, const char *func);
+
+        //////////////////////////////// OpenCL context ////////////////////////
+        //This is a global singleton class used to represent a OpenCL context.
+        class Context
+        {
+        protected:
+            Context();
+            friend class auto_ptr<Context>;
+            static auto_ptr<Context> clCxt;
+
+        public:
+            ~Context();
+            static int val;
+            static Context *getContext();
+            static void setContext(Info &oclinfo);
+            struct Impl;
+            Impl *impl;
+        };
+
+        //////////////////////////////// oclMat ////////////////////////////////
+        class CV_EXPORTS oclMat
+        {
+            public:
+            //! default constructor
+            oclMat();
+            //! constructs oclMatrix of the specified size and type (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.)
+            oclMat(int rows, int cols, int type);
+            oclMat(Size size, int type);
+            //! constucts oclMatrix and fills it with the specified value _s.
+            oclMat(int rows, int cols, int type, const Scalar &s);
+            oclMat(Size size, int type, const Scalar &s);
+            //! copy constructor
+            oclMat(const oclMat &m);
+
+            //! constructor for oclMatrix headers pointing to user-allocated data
+            oclMat(int rows, int cols, int type, void *data, size_t step = Mat::AUTO_STEP);
+            oclMat(Size size, int type, void *data, size_t step = Mat::AUTO_STEP);
+
+            //! creates a matrix header for a part of the bigger matrix
+            oclMat(const oclMat &m, const Range &rowRange, const Range &colRange);
+            oclMat(const oclMat &m, const Rect &roi);
+
+            //! builds oclMat from Mat. Perfom blocking upload to device.
+            explicit oclMat (const Mat &m);
+
+            //! destructor - calls release()
+            ~oclMat();
+
+            //! assignment operators
+            oclMat &operator = (const oclMat &m);
+            //! assignment operator. Perfom blocking upload to device.
+            oclMat &operator = (const Mat &m);
+
+            /* Fixme! To be supported in OpenCL later. */
+#if 0
+            //! returns lightweight DevMem2D_ structure for passing to nvcc-compiled code.
+            // Contains just image size, data ptr and step.
+            template <class T> operator DevMem2D_<T>() const;
+            template <class T> operator PtrStep_<T>() const;
+#endif
+
+            //! pefroms blocking upload data to oclMat.
+            void upload(const cv::Mat &m);
+
+            /* Fixme! To be supported in OpenCL later. */
+#if 0
+            //! upload async
+            void upload(const CudaMem &m, Stream &stream);
+#endif
+
+            //! downloads data from device to host memory. Blocking calls.
+            operator Mat() const;
+            void download(cv::Mat &m) const;
+
+            /* Fixme! To be supported in OpenCL later. */
+#if 0
+            //! download async
+            void download(CudaMem &m, Stream &stream) const;
+#endif
+
+            //! returns a new oclMatrix header for the specified row
+            oclMat row(int y) const;
+            //! returns a new oclMatrix header for the specified column
+            oclMat col(int x) const;
+            //! ... for the specified row span
+            oclMat rowRange(int startrow, int endrow) const;
+            oclMat rowRange(const Range &r) const;
+            //! ... for the specified column span
+            oclMat colRange(int startcol, int endcol) const;
+            oclMat colRange(const Range &r) const;
+
+            //! returns deep copy of the oclMatrix, i.e. the data is copied
+            oclMat clone() const;
+            //! copies the oclMatrix content to "m".
+            // It calls m.create(this->size(), this->type()).
+            // It supports any data type
+            void copyTo( oclMat &m ) const;
+            //! copies those oclMatrix elements to "m" that are marked with non-zero mask elements.
+            //It supports 8UC1 8UC4 32SC1 32SC4 32FC1 32FC4
+            void copyTo( oclMat &m, const oclMat &mask ) const;
+            //! converts oclMatrix to another datatype with optional scalng. See cvConvertScale.
+            //It supports 8UC1 8UC4 32SC1 32SC4 32FC1 32FC4
+            void convertTo( oclMat &m, int rtype, double alpha = 1, double beta = 0 ) const;
+
+            void assignTo( oclMat &m, int type = -1 ) const;
+
+            //! sets every oclMatrix element to s
+            //It supports 8UC1 8UC4 32SC1 32SC4 32FC1 32FC4
+            oclMat &operator = (const Scalar &s);
+            //! sets some of the oclMatrix elements to s, according to the mask
+            //It supports 8UC1 8UC4 32SC1 32SC4 32FC1 32FC4
+            oclMat &setTo(const Scalar &s, const oclMat &mask = oclMat());
+            //! creates alternative oclMatrix header for the same data, with different
+            // number of channels and/or different number of rows. see cvReshape.
+            oclMat reshape(int cn, int rows = 0) const;
+
+            //! allocates new oclMatrix data unless the oclMatrix already has specified size and type.
+            // previous data is unreferenced if needed.
+            void create(int rows, int cols, int type);
+            void create(Size size, int type);
+            //! decreases reference counter;
+            // deallocate the data when reference counter reaches 0.
+            void release();
+
+            //! swaps with other smart pointer
+            void swap(oclMat &mat);
+
+            //! locates oclMatrix header within a parent oclMatrix. See below
+            void locateROI( Size &wholeSize, Point &ofs ) const;
+            //! moves/resizes the current oclMatrix ROI inside the parent oclMatrix.
+            oclMat &adjustROI( int dtop, int dbottom, int dleft, int dright );
+            //! extracts a rectangular sub-oclMatrix
+            // (this is a generalized form of row, rowRange etc.)
+            oclMat operator()( Range rowRange, Range colRange ) const;
+            oclMat operator()( const Rect &roi ) const;
+
+            //! returns true if the oclMatrix data is continuous
+            // (i.e. when there are no gaps between successive rows).
+            // similar to CV_IS_oclMat_CONT(cvoclMat->type)
+            bool isContinuous() const;
+            //! returns element size in bytes,
+            // similar to CV_ELEM_SIZE(cvMat->type)
+            size_t elemSize() const;
+            //! returns the size of element channel in bytes.
+            size_t elemSize1() const;
+            //! returns element type, similar to CV_MAT_TYPE(cvMat->type)
+            int type() const;
+            //! returns element type, similar to CV_MAT_DEPTH(cvMat->type)
+            int depth() const;
+            //! returns element type, similar to CV_MAT_CN(cvMat->type)
+            int channels() const;
+            //! returns step/elemSize1()
+            size_t step1() const;
+            //! returns oclMatrix size:
+            // width == number of columns, height == number of rows
+            Size size() const;
+            //! returns true if oclMatrix data is NULL
+            bool empty() const;
+
+            //! returns pointer to y-th row
+            uchar *ptr(int y = 0);
+            const uchar *ptr(int y = 0) const;
+
+            //! template version of the above method
+            template<typename _Tp> _Tp *ptr(int y = 0);
+            template<typename _Tp> const _Tp *ptr(int y = 0) const;
+
+            //! matrix transposition
+            oclMat t() const;
+
+            /*! includes several bit-fields:
+              - the magic signature
+              - continuity flag
+              - depth
+              - number of channels
+              */
+            int flags;
+            //! the number of rows and columns
+            int rows, cols;
+            //! a distance between successive rows in bytes; includes the gap if any
+            size_t step;
+            //! pointer to the data(OCL memory object)
+            uchar *data;
+
+            //! pointer to the reference counter;
+            // when oclMatrix points to user-allocated data, the pointer is NULL
+            int *refcount;
+
+            //! helper fields used in locateROI and adjustROI
+            //datastart and dataend are not used in current version
+            uchar *datastart;
+            uchar *dataend;
+
+            //! OpenCL context associated with the oclMat object.
+            Context *clCxt;
+            //add offset for handle ROI, calculated in byte
+            int offset;
+            //add wholerows and wholecols for the whole matrix, datastart and dataend are no longer used
+            int wholerows;
+            int wholecols;
+            //add download_channels for 3 channels to 4 channels
+            int download_channels;
+        };
+
+        ///////////////////// mat split and merge /////////////////////////////////
+        //! Compose a multi-channel array from several single-channel arrays
+        // Support all types
+        CV_EXPORTS void merge(const oclMat *src, size_t n, oclMat &dst);
+        CV_EXPORTS void merge(const vector<oclMat> &src, oclMat &dst);
+
+        //! Divides multi-channel array into several single-channel arrays
+        // Support all types
+        CV_EXPORTS void split(const oclMat &src, oclMat *dst);
+        CV_EXPORTS void split(const oclMat &src, vector<oclMat> &dst);
+
+        ////////////////////////////// Arithmetics ///////////////////////////////////
+        //#if defined DOUBLE_SUPPORT
+        //typedef double F;
+        //#else
+        //typedef float F;
+        //#endif
+        //  CV_EXPORTS void addWeighted(const oclMat& a,F  alpha, const oclMat& b,F beta,F gama, oclMat& c);
+        CV_EXPORTS void addWeighted(const oclMat &a, double  alpha, const oclMat &b, double beta, double gama, oclMat &c);
+        //! adds one matrix to another (c = a + b)
+        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+        CV_EXPORTS void add(const oclMat &a, const oclMat &b, oclMat &c);
+        //! adds one matrix to another (c = a + b)
+        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+        CV_EXPORTS void add(const oclMat &a, const oclMat &b, oclMat &c, const oclMat &mask);
+        //! adds scalar to a matrix (c = a + s)
+        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+        CV_EXPORTS void add(const oclMat &a, const Scalar &sc, oclMat &c, const oclMat &mask = oclMat());
+        //! subtracts one matrix from another (c = a - b)
+        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+        CV_EXPORTS void subtract(const oclMat &a, const oclMat &b, oclMat &c);
+        //! subtracts one matrix from another (c = a - b)
+        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+        CV_EXPORTS void subtract(const oclMat &a, const oclMat &b, oclMat &c, const oclMat &mask);
+        //! subtracts scalar from a matrix (c = a - s)
+        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+        CV_EXPORTS void subtract(const oclMat &a, const Scalar &sc, oclMat &c, const oclMat &mask = oclMat());
+        //! subtracts scalar from a matrix (c = a - s)
+        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+        CV_EXPORTS void subtract(const Scalar &sc, const oclMat &a, oclMat &c, const oclMat &mask = oclMat());
+        //! computes element-wise product of the two arrays (c = a * b)
+        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+        CV_EXPORTS void multiply(const oclMat &a, const oclMat &b, oclMat &c, double scale = 1);
+        //! computes element-wise quotient of the two arrays (c = a / b)
+        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+        CV_EXPORTS void divide(const oclMat &a, const oclMat &b, oclMat &c, double scale = 1);
+        //! computes element-wise quotient of the two arrays (c = a / b)
+        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+        CV_EXPORTS void divide(double scale, const oclMat &b, oclMat &c);
+
+        //! compares elements of two arrays (c = a <cmpop> b)
+        // supports except CV_8SC1,CV_8SC2,CV8SC3,CV_8SC4 types
+        CV_EXPORTS void compare(const oclMat &a, const oclMat &b, oclMat &c, int cmpop);
+
+        //! transposes the matrix
+        // supports  CV_8UC1, 8UC4, 8SC4, 16UC2, 16SC2, 32SC1 and 32FC1.(the same as cuda)
+        CV_EXPORTS void transpose(const oclMat &src1, oclMat &dst);
+
+        //! computes element-wise absolute difference of two arrays (c = abs(a - b))
+        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+        CV_EXPORTS void absdiff(const oclMat &a, const oclMat &b, oclMat &c);
+        //! computes element-wise absolute difference of array and scalar (c = abs(a - s))
+        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+        CV_EXPORTS void absdiff(const oclMat &a, const Scalar &s, oclMat &c);
+
+        //! computes mean value and standard deviation of all or selected array elements
+        // supports except CV_32F,CV_64F
+        CV_EXPORTS void meanStdDev(const oclMat &mtx, Scalar &mean, Scalar &stddev);
+
+        //! computes norm of array
+        // supports NORM_INF, NORM_L1, NORM_L2
+        // supports only CV_8UC1 type
+        CV_EXPORTS double norm(const oclMat &src1, int normType = NORM_L2);
+
+        //! computes norm of the difference between two arrays
+        // supports NORM_INF, NORM_L1, NORM_L2
+        // supports only CV_8UC1 type
+        CV_EXPORTS double norm(const oclMat &src1, const oclMat &src2, int normType = NORM_L2);
+
+        //! reverses the order of the rows, columns or both in a matrix
+        // supports all types
+        CV_EXPORTS void flip(const oclMat &a, oclMat &b, int flipCode);
+
+        //! computes sum of array elements
+        // disabled until fix crash
+        // support all types
+        CV_EXPORTS Scalar sum(const oclMat &m);
+
+        //! finds global minimum and maximum array elements and returns their values
+        // support all types
+        CV_EXPORTS void minMax(const oclMat &src, double *minVal, double *maxVal = 0, const oclMat &mask = oclMat());
+
+        //! finds global minimum and maximum array elements and returns their values with locations
+        // support all types
+        CV_EXPORTS void minMaxLoc(const oclMat &src, double *minVal, double *maxVal = 0, Point *minLoc = 0, Point *maxLoc = 0,
+                const oclMat &mask = oclMat());
+
+        //! counts non-zero array elements
+        // support all types
+        CV_EXPORTS int countNonZero(const oclMat &src);
+
+        //! transforms 8-bit unsigned integers using lookup table: dst(i)=lut(src(i))
+        // destination array will have the depth type as lut and the same channels number as source
+        //It supports 8UC1 8UC4 only
+        CV_EXPORTS void LUT(const oclMat &src, const oclMat &lut, oclMat &dst);
+
+        //! only 8UC1 and 256 bins is supported now
+        CV_EXPORTS void calcHist(const oclMat &mat_src, oclMat &mat_hist);
+        //! only 8UC1 and 256 bins is supported now
+        CV_EXPORTS void equalizeHist(const oclMat &mat_src, oclMat &mat_dst);
+        //! bilateralFilter
+        // supports 8UC1 8UC4
+        CV_EXPORTS void bilateralFilter(const oclMat &, oclMat &, int , double, double, int);
+        //! computes exponent of each matrix element (b = e**a)
+        // supports only CV_32FC1 type
+        CV_EXPORTS void exp(const oclMat &a, oclMat &b);
+
+        //! computes natural logarithm of absolute value of each matrix element: b = log(abs(a))
+        // supports only CV_32FC1 type
+        CV_EXPORTS void log(const oclMat &a, oclMat &b);
+
+        //! computes magnitude of each (x(i), y(i)) vector
+        // supports only CV_32F CV_64F type
+        CV_EXPORTS void magnitude(const oclMat &x, const oclMat &y, oclMat &magnitude);
+        CV_EXPORTS void magnitudeSqr(const oclMat &x, const oclMat &y, oclMat &magnitude);
+
+        CV_EXPORTS void magnitudeSqr(const oclMat &x, oclMat &magnitude);
+
+        //! computes angle (angle(i)) of each (x(i), y(i)) vector
+        // supports only CV_32F CV_64F type
+        CV_EXPORTS void phase(const oclMat &x, const oclMat &y, oclMat &angle, bool angleInDegrees = false);
+
+        //! the function raises every element of tne input array to p
+        //! support only CV_32F CV_64F type
+        CV_EXPORTS void pow(const oclMat &x, double p, oclMat &y);
+
+        //! converts Cartesian coordinates to polar
+        // supports only CV_32F CV_64F type
+        CV_EXPORTS void cartToPolar(const oclMat &x, const oclMat &y, oclMat &magnitude, oclMat &angle, bool angleInDegrees = false);
+
+        //! converts polar coordinates to Cartesian
+        // supports only CV_32F CV_64F type
+        CV_EXPORTS void polarToCart(const oclMat &magnitude, const oclMat &angle, oclMat &x, oclMat &y, bool angleInDegrees = false);
+
+        //! perfroms per-elements bit-wise inversion
+        // supports all types
+        CV_EXPORTS void bitwise_not(const oclMat &src, oclMat &dst);
+        //! calculates per-element bit-wise disjunction of two arrays
+        // supports all types
+        CV_EXPORTS void bitwise_or(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask = oclMat());
+        CV_EXPORTS void bitwise_or(const oclMat &src1, const Scalar &s, oclMat &dst, const oclMat &mask = oclMat());
+        //! calculates per-element bit-wise conjunction of two arrays
+        // supports all types
+        CV_EXPORTS void bitwise_and(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask = oclMat());
+        CV_EXPORTS void bitwise_and(const oclMat &src1, const Scalar &s, oclMat &dst, const oclMat &mask = oclMat());
+        //! calculates per-element bit-wise "exclusive or" operation
+        // supports all types
+        CV_EXPORTS void bitwise_xor(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask = oclMat());
+        CV_EXPORTS void bitwise_xor(const oclMat &src1, const Scalar &s, oclMat &dst, const oclMat &mask = oclMat());
+
+        //! Logical operators
+        CV_EXPORTS oclMat operator ~ (const oclMat &src);
+        CV_EXPORTS oclMat operator | (const oclMat &src1, const oclMat &src2);
+        CV_EXPORTS oclMat operator & (const oclMat &src1, const oclMat &src2);
+        CV_EXPORTS oclMat operator ^ (const oclMat &src1, const oclMat &src2);
+        CV_EXPORTS void cvtColor(const oclMat &src, oclMat &dst, int code , int dcn = 0);
+
+        //////////////////////////////// Filter Engine ////////////////////////////////
+
+        /*!
+          The Base Class for 1D or Row-wise Filters
+
+          This is the base class for linear or non-linear filters that process 1D data.
+          In particular, such filters are used for the "horizontal" filtering parts in separable filters.
+          */
+        class CV_EXPORTS BaseRowFilter_GPU
+        {
+            public:
+                BaseRowFilter_GPU(int ksize_, int anchor_, int bordertype_) : ksize(ksize_), anchor(anchor_), bordertype(bordertype_) {}
+                virtual ~BaseRowFilter_GPU() {}
+                virtual void operator()(const oclMat &src, oclMat &dst) = 0;
+                int ksize, anchor, bordertype;
+        };
+
+        /*!
+          The Base Class for Column-wise Filters
+
+          This is the base class for linear or non-linear filters that process columns of 2D arrays.
+          Such filters are used for the "vertical" filtering parts in separable filters.
+          */
+        class CV_EXPORTS BaseColumnFilter_GPU
+        {
+            public:
+                BaseColumnFilter_GPU(int ksize_, int anchor_, int bordertype_) : ksize(ksize_), anchor(anchor_), bordertype(bordertype_) {}
+                virtual ~BaseColumnFilter_GPU() {}
+                virtual void operator()(const oclMat &src, oclMat &dst) = 0;
+                int ksize, anchor, bordertype;
+        };
+
+        /*!
+          The Base Class for Non-Separable 2D Filters.
+
+          This is the base class for linear or non-linear 2D filters.
+          */
+        class CV_EXPORTS BaseFilter_GPU
+        {
+            public:
+                BaseFilter_GPU(const Size &ksize_, const Point &anchor_, const int &borderType_)
+                    : ksize(ksize_), anchor(anchor_), borderType(borderType_) {}
+                virtual ~BaseFilter_GPU() {}
+                virtual void operator()(const oclMat &src, oclMat &dst) = 0;
+                Size ksize;
+                Point anchor;
+                int borderType;
+        };
+
+        /*!
+          The Base Class for Filter Engine.
+
+          The class can be used to apply an arbitrary filtering operation to an image.
+          It contains all the necessary intermediate buffers.
+          */
+        class CV_EXPORTS FilterEngine_GPU
+        {
+            public:
+                virtual ~FilterEngine_GPU() {}
+
+                virtual void apply(const oclMat &src, oclMat &dst, Rect roi = Rect(0, 0, -1, -1)) = 0;
+        };
+
+        //! returns the non-separable filter engine with the specified filter
+        CV_EXPORTS Ptr<FilterEngine_GPU> createFilter2D_GPU(const Ptr<BaseFilter_GPU> filter2D);
+
+        //! returns the primitive row filter with the specified kernel
+        CV_EXPORTS Ptr<BaseRowFilter_GPU> getLinearRowFilter_GPU(int srcType, int bufType, const Mat &rowKernel,
+                int anchor = -1, int bordertype = BORDER_DEFAULT);
+
+        //! returns the primitive column filter with the specified kernel
+        CV_EXPORTS Ptr<BaseColumnFilter_GPU> getLinearColumnFilter_GPU(int bufType, int dstType, const Mat &columnKernel,
+                int anchor = -1, int bordertype = BORDER_DEFAULT, double delta = 0.0);
+
+        //! returns the separable linear filter engine
+        CV_EXPORTS Ptr<FilterEngine_GPU> createSeparableLinearFilter_GPU(int srcType, int dstType, const Mat &rowKernel,
+                const Mat &columnKernel, const Point &anchor = Point(-1, -1), double delta = 0.0, int bordertype = BORDER_DEFAULT);
+
+        //! returns the separable filter engine with the specified filters
+        CV_EXPORTS Ptr<FilterEngine_GPU> createSeparableFilter_GPU(const Ptr<BaseRowFilter_GPU>& rowFilter,
+                const Ptr<BaseColumnFilter_GPU>& columnFilter);
+
+        //! returns the Gaussian filter engine
+        CV_EXPORTS Ptr<FilterEngine_GPU> createGaussianFilter_GPU(int type, Size ksize, double sigma1, double sigma2 = 0, int bordertype = BORDER_DEFAULT);
+
+        //! returns filter engine for the generalized Sobel operator
+        CV_EXPORTS Ptr<FilterEngine_GPU> createDerivFilter_GPU( int srcType, int dstType, int dx, int dy, int ksize, int borderType=BORDER_DEFAULT );
+
+        //! applies Laplacian operator to the image
+        // supports only ksize = 1 and ksize = 3 8UC1 8UC4 32FC1 32FC4 data type
+        CV_EXPORTS void Laplacian(const oclMat &src, oclMat &dst, int ddepth, int ksize = 1, double scale = 1);
+
+        //! returns 2D box filter
+        // supports CV_8UC1 and CV_8UC4 source type, dst type must be the same as source type
+        CV_EXPORTS Ptr<BaseFilter_GPU> getBoxFilter_GPU(int srcType, int dstType,
+                const Size &ksize, Point anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
+
+        //! returns box filter engine
+        CV_EXPORTS Ptr<FilterEngine_GPU> createBoxFilter_GPU(int srcType, int dstType, const Size &ksize,
+                const Point &anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
+
+        //! returns 2D filter with the specified kernel
+        // supports CV_8UC1 and CV_8UC4 types
+        CV_EXPORTS Ptr<BaseFilter_GPU> getLinearFilter_GPU(int srcType, int dstType, const Mat &kernel, const Size &ksize,
+                Point anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
+
+        //! returns the non-separable linear filter engine
+        CV_EXPORTS Ptr<FilterEngine_GPU> createLinearFilter_GPU(int srcType, int dstType, const Mat &kernel,
+                const Point &anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
+
+        //! smooths the image using the normalized box filter
+        // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4
+        // supports border type: BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT,BORDER_REFLECT_101,BORDER_WRAP
+        CV_EXPORTS void boxFilter(const oclMat &src, oclMat &dst, int ddepth, Size ksize,
+                Point anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
+
+        //! returns 2D morphological filter
+        //! only MORPH_ERODE and MORPH_DILATE are supported
+        // supports CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 types
+        // kernel must have CV_8UC1 type, one rows and cols == ksize.width * ksize.height
+        CV_EXPORTS Ptr<BaseFilter_GPU> getMorphologyFilter_GPU(int op, int type, const Mat &kernel, const Size &ksize,
+                Point anchor = Point(-1, -1));
+
+        //! returns morphological filter engine. Only MORPH_ERODE and MORPH_DILATE are supported.
+        CV_EXPORTS Ptr<FilterEngine_GPU> createMorphologyFilter_GPU(int op, int type, const Mat &kernel,
+                const Point &anchor = Point(-1, -1), int iterations = 1);
+
+        //! a synonym for normalized box filter
+        // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4
+        // supports border type: BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT,BORDER_REFLECT_101
+        static inline void blur(const oclMat &src, oclMat &dst, Size ksize, Point anchor = Point(-1, -1),
+                int borderType = BORDER_CONSTANT)
+        {
+            boxFilter(src, dst, -1, ksize, anchor, borderType);
+        }
+
+        //! applies non-separable 2D linear filter to the image
+        CV_EXPORTS void filter2D(const oclMat &src, oclMat &dst, int ddepth, const Mat &kernel,
+                Point anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
+
+        //! applies separable 2D linear filter to the image
+        CV_EXPORTS void sepFilter2D(const oclMat &src, oclMat &dst, int ddepth, const Mat &kernelX, const Mat &kernelY,
+                Point anchor = Point(-1, -1), double delta = 0.0, int bordertype = BORDER_DEFAULT);
+
+        //! applies generalized Sobel operator to the image
+        // dst.type must equalize src.type
+        // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4
+        // supports border type: BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT,BORDER_REFLECT_101
+        CV_EXPORTS void Sobel(const oclMat &src, oclMat &dst, int ddepth, int dx, int dy, int ksize = 3, double scale = 1, double delta = 0.0, int bordertype = BORDER_DEFAULT);
+
+        //! applies the vertical or horizontal Scharr operator to the image
+        // dst.type must equalize src.type
+        // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4
+        // supports border type: BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT,BORDER_REFLECT_101
+        CV_EXPORTS void Scharr(const oclMat &src, oclMat &dst, int ddepth, int dx, int dy, double scale = 1, double delta = 0.0, int bordertype = BORDER_DEFAULT);
+
+        //! smooths the image using Gaussian filter.
+        // dst.type must equalize src.type
+        // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4
+        // supports border type: BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT,BORDER_REFLECT_101
+        CV_EXPORTS void GaussianBlur(const oclMat &src, oclMat &dst, Size ksize, double sigma1, double sigma2 = 0, int bordertype = BORDER_DEFAULT);
+
+        //! erodes the image (applies the local minimum operator)
+        // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4
+        CV_EXPORTS void erode( const oclMat &src, oclMat &dst, const Mat &kernel, Point anchor = Point(-1, -1), int iterations = 1);
+
+        //! dilates the image (applies the local maximum operator)
+        // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4
+        CV_EXPORTS void dilate( const oclMat &src, oclMat &dst, const Mat &kernel, Point anchor = Point(-1, -1), int iterations = 1);
+
+        //! applies an advanced morphological operation to the image
+        CV_EXPORTS void morphologyEx( const oclMat &src, oclMat &dst, int op, const Mat &kernel, Point anchor = Point(-1, -1), int iterations = 1);
+
+        ////////////////////////////// Image processing //////////////////////////////
+        //! Does mean shift filtering on GPU.
+        CV_EXPORTS void meanShiftFiltering(const oclMat &src, oclMat &dst, int sp, int sr,
+                TermCriteria criteria = TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 5, 1));
+
+        //! Does mean shift procedure on GPU.
+        CV_EXPORTS void meanShiftProc(const oclMat &src, oclMat &dstr, oclMat &dstsp, int sp, int sr,
+                TermCriteria criteria = TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 5, 1));
+
+        //! Does mean shift segmentation with elimiation of small regions.
+        CV_EXPORTS void meanShiftSegmentation(const oclMat &src, Mat &dst, int sp, int sr, int minsize,
+                TermCriteria criteria = TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 5, 1));
+
+        //! applies fixed threshold to the image.
+        // supports CV_8UC1 and CV_32FC1 data type
+        // supports threshold type: THRESH_BINARY, THRESH_BINARY_INV, THRESH_TRUNC, THRESH_TOZERO, THRESH_TOZERO_INV
+        CV_EXPORTS double threshold(const oclMat &src, oclMat &dst, double thresh, double maxVal, int type = THRESH_TRUNC);
+
+        //! resizes the image
+        // Supports INTER_NEAREST, INTER_LINEAR
+        // supports CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 types
+        CV_EXPORTS void resize(const oclMat &src, oclMat &dst, Size dsize, double fx = 0, double fy = 0, int interpolation = INTER_LINEAR);
+
+        //! Applies a generic geometrical transformation to an image.
+            // Supports INTER_NEAREST, INTER_LINEAR.
+            // Map1 supports CV_16SC2, CV_32FC2  types.
+        // Src supports CV_8UC1, CV_8UC2, CV_8UC4.
+        CV_EXPORTS void remap(const oclMat& src, oclMat& dst, oclMat& map1, oclMat& map2, int interpolation, int bordertype, const Scalar& value = Scalar());
+        //! copies 2D array to a larger destination array and pads borders with user-specifiable constant
+        // supports CV_8UC1, CV_8UC4, CV_32SC1 types
+        CV_EXPORTS void copyMakeBorder(const oclMat &src, oclMat &dst, int top, int bottom, int left, int right, int boardtype, const Scalar &value = Scalar());
+
+        //! Smoothes image using median filter
+        // The source 1- or 4-channel image. When m is 3 or 5, the image depth should be CV 8U or CV 32F.
+        CV_EXPORTS void medianFilter(const oclMat &src, oclMat &dst, int m);
+
+        //! warps the image using affine transformation
+        // Supports INTER_NEAREST, INTER_LINEAR, INTER_CUBIC
+        // supports CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 types
+        CV_EXPORTS void warpAffine(const oclMat &src, oclMat &dst, const Mat &M, Size dsize, int flags = INTER_LINEAR);
+
+        //! warps the image using perspective transformation
+        // Supports INTER_NEAREST, INTER_LINEAR, INTER_CUBIC
+        // supports CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 types
+        CV_EXPORTS void warpPerspective(const oclMat &src, oclMat &dst, const Mat &M, Size dsize, int flags = INTER_LINEAR);
+
+        //! computes the integral image and integral for the squared image
+        // sum will have CV_32S type, sqsum - CV32F type
+        // supports only CV_8UC1 source type
+        CV_EXPORTS void integral(const oclMat &src, oclMat &sum, oclMat &sqsum);
+        CV_EXPORTS void integral(const oclMat &src, oclMat &sum);
+        CV_EXPORTS void cornerHarris(const oclMat &src, oclMat &dst, int blockSize, int ksize, double k, int bordertype = cv::BORDER_DEFAULT);
+        CV_EXPORTS void cornerMinEigenVal(const oclMat &src, oclMat &dst, int blockSize, int ksize, int bordertype = cv::BORDER_DEFAULT);
+
+
+        //////////////////////////////// StereoBM_GPU ////////////////////////////////
+        class CV_EXPORTS StereoBM_GPU
+        {
+        public:
+            enum { BASIC_PRESET = 0, PREFILTER_XSOBEL = 1 };
+
+            enum { DEFAULT_NDISP = 64, DEFAULT_WINSZ = 19 };
+
+            //! the default constructor
+            StereoBM_GPU();
+            //! the full constructor taking the camera-specific preset, number of disparities and the SAD window size. ndisparities must be multiple of 8.
+            StereoBM_GPU(int preset, int ndisparities = DEFAULT_NDISP, int winSize = DEFAULT_WINSZ);
+
+            //! the stereo correspondence operator. Finds the disparity for the specified rectified stereo pair
+            //! Output disparity has CV_8U type.
+            void operator() ( const oclMat &left, const oclMat &right, oclMat &disparity);
+
+            //! Some heuristics that tries to estmate
+            // if current GPU will be faster then CPU in this algorithm.
+            // It queries current active device.
+            static bool checkIfGpuCallReasonable();
+
+            int preset;
+            int ndisp;
+            int winSize;
+
+            // If avergeTexThreshold  == 0 => post procesing is disabled
+            // If avergeTexThreshold != 0 then disparity is set 0 in each point (x,y) where for left image
+            // SumOfHorizontalGradiensInWindow(x, y, winSize) < (winSize * winSize) * avergeTexThreshold
+            // i.e. input left image is low textured.
+            float avergeTexThreshold;
+        private:
+            oclMat minSSD, leBuf, riBuf;
+        };
+
+        ////////////////////////// StereoBeliefPropagation ///////////////////////////
+        // "Efficient Belief Propagation for Early Vision"
+        // P.Felzenszwalb
+
+        class CV_EXPORTS StereoBeliefPropagation
+        {
+        public:
+            enum { DEFAULT_NDISP  = 64 };
+            enum { DEFAULT_ITERS  = 5  };
+            enum { DEFAULT_LEVELS = 5  };
+
+            static void estimateRecommendedParams(int width, int height, int &ndisp, int &iters, int &levels);
+
+            //! the default constructor
+            explicit StereoBeliefPropagation(int ndisp  = DEFAULT_NDISP,
+                    int iters  = DEFAULT_ITERS,
+                    int levels = DEFAULT_LEVELS,
+                    int msg_type = CV_16S);
+
+            //! the full constructor taking the number of disparities, number of BP iterations on each level,
+            //! number of levels, truncation of data cost, data weight,
+            //! truncation of discontinuity cost and discontinuity single jump
+            //! DataTerm = data_weight * min(fabs(I2-I1), max_data_term)
+            //! DiscTerm = min(disc_single_jump * fabs(f1-f2), max_disc_term)
+            //! please see paper for more details
+            StereoBeliefPropagation(int ndisp, int iters, int levels,
+                    float max_data_term, float data_weight,
+                    float max_disc_term, float disc_single_jump,
+                    int msg_type = CV_32F);
+
+            //! the stereo correspondence operator. Finds the disparity for the specified rectified stereo pair,
+            //! if disparity is empty output type will be CV_16S else output type will be disparity.type().
+            void operator()(const oclMat &left, const oclMat &right, oclMat &disparity);
+
+            //! version for user specified data term
+            void operator()(const oclMat &data, oclMat &disparity);
+
+            int ndisp;
+
+            int iters;
+            int levels;
+
+            float max_data_term;
+            float data_weight;
+            float max_disc_term;
+            float disc_single_jump;
+
+            int msg_type;
+        private:
+            oclMat u, d, l, r, u2, d2, l2, r2;
+            std::vector<oclMat> datas;
+            oclMat out;
+        };
+
+        /////////////////////////// StereoConstantSpaceBP ///////////////////////////
+        // "A Constant-Space Belief Propagation Algorithm for Stereo Matching"
+        // Qingxiong Yang, Liang Wangï¿? Narendra Ahuja
+        // http://vision.ai.uiuc.edu/~qyang6/
+
+        class CV_EXPORTS StereoConstantSpaceBP
+        {
+        public:
+            enum { DEFAULT_NDISP    = 128 };
+            enum { DEFAULT_ITERS    = 8   };
+            enum { DEFAULT_LEVELS   = 4   };
+            enum { DEFAULT_NR_PLANE = 4   };
+
+            static void estimateRecommendedParams(int width, int height, int &ndisp, int &iters, int &levels, int &nr_plane);
+
+            //! the default constructor
+            explicit StereoConstantSpaceBP(int ndisp    = DEFAULT_NDISP,
+                    int iters    = DEFAULT_ITERS,
+                    int levels   = DEFAULT_LEVELS,
+                    int nr_plane = DEFAULT_NR_PLANE,
+                    int msg_type = CV_32F);
+
+            //! the full constructor taking the number of disparities, number of BP iterations on each level,
+            //! number of levels, number of active disparity on the first level, truncation of data cost, data weight,
+            //! truncation of discontinuity cost, discontinuity single jump and minimum disparity threshold
+            StereoConstantSpaceBP(int ndisp, int iters, int levels, int nr_plane,
+                    float max_data_term, float data_weight, float max_disc_term, float disc_single_jump,
+                    int min_disp_th = 0,
+                    int msg_type = CV_32F);
+
+            //! the stereo correspondence operator. Finds the disparity for the specified rectified stereo pair,
+            //! if disparity is empty output type will be CV_16S else output type will be disparity.type().
+            void operator()(const oclMat &left, const oclMat &right, oclMat &disparity);
+
+            int ndisp;
+
+            int iters;
+            int levels;
+
+            int nr_plane;
+
+            float max_data_term;
+            float data_weight;
+            float max_disc_term;
+            float disc_single_jump;
+
+            int min_disp_th;
+
+            int msg_type;
+
+            bool use_local_init_data_cost;
+        private:
+            oclMat u[2], d[2], l[2], r[2];
+            oclMat disp_selected_pyr[2];
+
+            oclMat data_cost;
+            oclMat data_cost_selected;
+
+            oclMat temp;
+
+            oclMat out;
+        };
+        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+        ///////////////////////////////////////////CascadeClassifier//////////////////////////////////////////////////////////////////
+        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+        class CV_EXPORTS_W OclCascadeClassifier : public  cv::CascadeClassifier
+        {
+        public:
+            OclCascadeClassifier() {};
+            ~OclCascadeClassifier() {};
+
+            CvSeq *oclHaarDetectObjects(oclMat &gimg, CvMemStorage *storage, double scaleFactor,
+                    int minNeighbors, int flags, CvSize minSize = cvSize(0, 0), CvSize maxSize = cvSize(0, 0));
+        };
+
+        ///////////////////////////////////////////////////////jhp_benchmark////////////////////////////////////////////////////
+        void benchmark_copy_vectorize(const oclMat &src, oclMat &dst);
+        void benchmark_copy_offset_stride(const oclMat &src, oclMat &dst);
+        void benchmark_ILP();
+        
+    }
+}
+#include "opencv2/ocl/matrix_operations.hpp"
+#endif /* __OPENCV_GPU_HPP__ */
diff --git a/modules/ocl/src/arithm.cpp b/modules/ocl/src/arithm.cpp
new file mode 100644 (file)
index 0000000..dba7778
--- /dev/null
@@ -0,0 +1,2384 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Niko Li, newlife20080214@gmail.com
+//    Jia Haipeng, jiahaipeng95@gmail.com
+//    Shengen Yan, yanshengen@gmail.com
+//    Jiang Liyuan, jlyuan001.good@163.com
+//    Rock Li, Rock.Li@amd.com
+//    Zailong Wu, bullet@yeah.net
+//
+// 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 <iomanip>
+
+
+using namespace cv;
+using namespace cv::ocl;
+using namespace std;
+
+#if !defined (HAVE_OPENCL)
+
+/* arithmetics */
+void cv::ocl::add(const oclMat &, const oclMat &, oclMat &)
+{
+    throw_nogpu();
+}
+void cv::ocl::add(const oclMat &, const oclMat &, oclMat &, const oclMat &)
+{
+    throw_nogpu();
+}
+void cv::ocl::add(const oclMat &, const Scalar &, oclMat &, const oclMat &)
+{
+    throw_nogpu();
+}
+void cv::ocl::subtract(const oclMat &, const oclMat &, oclMat &)
+{
+    throw_nogpu();
+}
+void cv::ocl::subtract(const oclMat &, const oclMat &, oclMat &, const oclMat &)
+{
+    throw_nogpu();
+}
+void cv::ocl::subtract(const oclMat &, const Scalar &, oclMat &, const oclMat & )
+{
+    throw_nogpu();
+}
+void cv::ocl::subtract(const Scalar &, const oclMat &,  oclMat &, const oclMat & )
+{
+    throw_nogpu();
+}
+void cv::ocl::multiply(const oclMat &, const oclMat &, oclMat &, double)
+{
+    throw_nogpu();
+}
+void cv::ocl::divide(const oclMat &, const oclMat &, oclMat &, double)
+{
+    throw_nogpu();
+}
+void cv::ocl::divide(double, const oclMat &, oclMat &)
+{
+    throw_nogpu();
+}
+void cv::ocl::absdiff(const oclMat &, const oclMat &, oclMat &)
+{
+    throw_nogpu();
+}
+void cv::ocl::absdiff(const oclMat &, const Scalar &, oclMat &)
+{
+    throw_nogpu();
+}
+void cv::ocl::compare(const oclMat &, const oclMat &, oclMat & , int)
+{
+    throw_nogpu();
+}
+void cv::ocl::meanStdDev(const oclMat &, Scalar &, Scalar &)
+{
+    throw_nogpu();
+}
+double cv::ocl::norm(const oclMat &, int)
+{
+    throw_nogpu();
+    return 0.0;
+}
+double cv::ocl::norm(const oclMat &, const oclMat &, int)
+{
+    throw_nogpu();
+    return 0.0;
+}
+void cv::ocl::flip(const oclMat &, oclMat &, int)
+{
+    throw_nogpu();
+}
+Scalar cv::ocl::sum(const oclMat &)
+{
+    throw_nogpu();
+    return Scalar();
+}
+void cv::ocl::minMax(const oclMat &, double *, double *, const oclMat &)
+{
+    throw_nogpu();
+}
+void cv::ocl::minMaxLoc(const oclMat &, double *, double *, Point *, Point *, const oclMat &)
+{
+    throw_nogpu();
+}
+void cv::ocl::LUT(const oclMat &, const Mat &, oclMat &)
+{
+    throw_nogpu();
+}
+void cv::ocl::exp(const oclMat &, oclMat &)
+{
+    throw_nogpu();
+}
+void cv::ocl::log(const oclMat &, oclMat &)
+{
+    throw_nogpu();
+}
+void cv::ocl::magnitude(const oclMat &, oclMat &)
+{
+    throw_nogpu();
+}
+void cv::ocl::phase(const oclMat &, const oclMat &, oclMat &, bool)
+{
+    throw_nogpu();
+}
+void cv::ocl::cartToPolar(const oclMat &, const oclMat &, oclMat &, oclMat &, bool)
+{
+    throw_nogpu();
+}
+void cv::ocl::polarToCart(const oclMat &, const oclMat &, oclMat &, oclMat &, bool)
+{
+    throw_nogpu();
+}
+void cv::ocl::transpose(const oclMat &, oclMat &)
+{
+    throw_nogpu();
+}
+void cv::ocl::pow(const oclMat &, double, oclMat &)
+{
+    throw_nogpu();
+}
+void cv::ocl::addWeighted(const oclMat &src1, double alpha, const oclMat &src2, double beta, double gama, oclMat &dst)
+{
+    throw_nogpu();
+}
+void cv::ocl::magnitudeSqr(const oclMat &src1, const oclMat &src2, oclMat &dst)
+{
+    throw_nogpu();
+}
+
+/* bit wise operations */
+void cv::ocl::bitwise_not(const oclMat &, oclMat &)
+{
+    throw_nogpu();
+}
+void cv::ocl::bitwise_or(const oclMat &, const oclMat &, oclMat &, const oclMat &)
+{
+    throw_nogpu();
+}
+void cv::ocl::bitwise_and(const oclMat &, const oclMat &, oclMat &, const oclMat &)
+{
+    throw_nogpu();
+}
+void cv::ocl::bitwise_and(const oclMat &, const Scalar &, oclMat &, const oclMat &)
+{
+    throw_nogpu();
+}
+void cv::ocl::bitwise_xor(const oclMat &, const oclMat &, oclMat &, const oclMat &)
+{
+    throw_nogpu();
+}
+cv::ocl::oclMat cv::ocl::operator ~ (const oclMat &)
+{
+    throw_nogpu();
+    return oclMat();
+}
+cv::ocl::oclMat cv::ocl::operator | (const oclMat &, const oclMat &)
+{
+    throw_nogpu();
+    return oclMat();
+}
+cv::ocl::oclMat cv::ocl::operator & (const oclMat &, const oclMat &)
+{
+    throw_nogpu();
+    return oclMat();
+}
+cv::ocl::oclMat cv::ocl::operator ^ (const oclMat &, const oclMat &)
+{
+    throw_nogpu();
+    return oclMat();
+}
+
+#else /* !defined (HAVE_OPENCL) */
+namespace cv
+{
+    namespace ocl
+    {
+        ////////////////////////////////OpenCL kernel strings/////////////////////
+        extern const char *bitwise;
+        extern const char *bitwiseM;
+        extern const char *transpose_kernel;
+        extern const char *arithm_nonzero;
+        extern const char *arithm_sum;
+        extern const char *arithm_2_mat;
+        extern const char *arithm_sum_3;
+        extern const char *arithm_minMax;
+        extern const char *arithm_minMax_mask;
+        extern const char *arithm_minMaxLoc;
+        extern const char *arithm_minMaxLoc_mask;
+        extern const char *arithm_LUT;
+        extern const char *arithm_add;
+        extern const char *arithm_add_scalar;
+        extern const char *arithm_add_scalar_mask;
+        extern const char *arithm_bitwise_not;
+        extern const char *arithm_bitwise_and;
+        extern const char *arithm_bitwise_and_mask;
+        extern const char *arithm_bitwise_and_scalar;
+        extern const char *arithm_bitwise_and_scalar_mask;
+        extern const char *arithm_bitwise_or;
+        extern const char *arithm_bitwise_or_mask;
+        extern const char *arithm_bitwise_or_scalar;
+        extern const char *arithm_bitwise_or_scalar_mask;
+        extern const char *arithm_bitwise_xor;
+        extern const char *arithm_bitwise_xor_mask;
+        extern const char *arithm_bitwise_xor_scalar;
+        extern const char *arithm_bitwise_xor_scalar_mask;
+        extern const char *arithm_compare_eq;
+        extern const char *arithm_compare_ne;
+        extern const char *arithm_sub;
+        extern const char *arithm_sub_scalar;
+        extern const char *arithm_sub_scalar_mask;
+        extern const char *arithm_mul;
+        extern const char *arithm_div;
+        extern const char *arithm_absdiff;
+        extern const char *arithm_transpose;
+        extern const char *arithm_flip;
+        extern const char *arithm_flip_rc;
+        extern const char *arithm_magnitude;
+        extern const char *arithm_cartToPolar;
+        extern const char *arithm_polarToCart;
+        extern const char *arithm_exp;
+        extern const char *arithm_log;
+        extern const char *arithm_addWeighted;
+        extern const char *arithm_phase;
+        extern const char *arithm_pow;
+        extern const char *arithm_magnitudeSqr;
+        //extern const char * jhp_transpose_kernel;
+        int64 kernelrealtotal = 0;
+        int64 kernelalltotal = 0;
+        int64 reducetotal = 0;
+        int64 downloadtotal = 0;
+        int64 alltotal = 0;
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////common/////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////
+inline int divUp(int total, int grain)
+{
+    return (total + grain - 1) / grain;
+}
+//////////////////////////////////////////////////////////////////////////////
+/////////////////////// add subtract multiply divide /////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+template<typename T>
+void arithmetic_run(const oclMat &src1, const oclMat &src2, oclMat &dst, string kernelName, const char **kernelString, void *_scalar)
+{
+    if(src1.clCxt -> impl -> double_support ==0 && src1.type() == CV_64F)
+    {
+        CV_Error(-217,"Selected device don't support double\r\n");
+        return;
+    }
+
+    dst.create(src1.size(), src1.type());
+    CV_Assert(src1.cols == src2.cols && src2.cols == dst.cols &&
+              src1.rows == src2.rows && src2.rows == dst.rows);
+
+    CV_Assert(src1.type() == src2.type() && src1.type() == dst.type());
+    CV_Assert(src1.depth() != CV_8S);
+
+    Context  *clCxt = src1.clCxt;
+    int channels = dst.channels();
+    int depth = dst.depth();
+
+    int vector_lengths[4][7] = {{4, 0, 4, 4, 1, 1, 1},
+        {4, 0, 4, 4, 1, 1, 1},
+        {4, 0, 4, 4, 1, 1, 1},
+        {4, 0, 4, 4, 1, 1, 1}
+    };
+
+    size_t vector_length = vector_lengths[channels-1][depth];
+    int offset_cols = (dst.offset / dst.elemSize1()) & (vector_length - 1);
+    int cols = divUp(dst.cols * channels + offset_cols, vector_length);
+
+    size_t localThreads[3]  = { 64, 4, 1 };
+    size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                divUp(dst.rows, localThreads[1]) * localThreads[1],
+                                1
+                              };
+
+    int dst_step1 = dst.cols * dst.elemSize();
+    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_int), (void *)&src1.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src1.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&src2.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src2.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src2.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.offset ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src1.rows ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&cols ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst_step1 ));
+
+    if(_scalar != NULL)
+    {
+        double scalar1 = *((double *)_scalar);
+        T scalar = (T)scalar1;
+        args.push_back( make_pair( sizeof(T), (void *)&scalar ));
+    }
+
+    openCLExecuteKernel(clCxt, kernelString, kernelName, globalThreads, localThreads, args, -1, depth);
+}
+void arithmetic_run(const oclMat &src1, const oclMat &src2, oclMat &dst, string kernelName, const char **kernelString)
+{
+    arithmetic_run<char>(src1, src2, dst, kernelName, kernelString, (void *)NULL);
+}
+void arithmetic_run(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask, string kernelName, const char **kernelString)
+{
+    if(src1.clCxt -> impl -> double_support ==0 && src1.type() == CV_64F)
+    {
+        CV_Error(-217,"Selected device don't support double\r\n");
+        return;
+    }
+
+    dst.create(src1.size(), src1.type());
+    CV_Assert(src1.cols == src2.cols && src2.cols == dst.cols &&
+              src1.rows == src2.rows && src2.rows == dst.rows &&
+              src1.rows == mask.rows && src1.cols == mask.cols);
+
+    CV_Assert(src1.type() == src2.type() && src1.type() == dst.type());
+    CV_Assert(src1.depth() != CV_8S);
+    CV_Assert(mask.type() == CV_8U);
+
+    Context  *clCxt = src1.clCxt;
+    int channels = dst.channels();
+    int depth = dst.depth();
+
+    int vector_lengths[4][7] = {{4, 4, 2, 2, 1, 1, 1},
+        {2, 2, 1, 1, 1, 1, 1},
+        {4, 4, 2, 2 , 1, 1, 1},
+        {1, 1, 1, 1, 1, 1, 1}
+    };
+
+    size_t vector_length = vector_lengths[channels-1][depth];
+    int offset_cols = ((dst.offset % dst.step) / dst.elemSize()) & (vector_length - 1);
+    int cols = divUp(dst.cols + offset_cols, vector_length);
+
+    size_t localThreads[3]  = { 64, 4, 1 };
+    size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                divUp(dst.rows, localThreads[1]) * localThreads[1],
+                                1
+                              };
+
+    int dst_step1 = dst.cols * dst.elemSize();
+    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_int), (void *)&src1.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src1.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&src2.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src2.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src2.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&mask.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&mask.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&mask.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.offset ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src1.rows ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&cols ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst_step1 ));
+
+    openCLExecuteKernel(clCxt, kernelString, kernelName, globalThreads, localThreads, args, channels, depth);
+}
+void cv::ocl::add(const oclMat &src1, const oclMat &src2, oclMat &dst)
+{
+    arithmetic_run(src1, src2, dst, "arithm_add", &arithm_add);
+}
+void cv::ocl::add(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask)
+{
+    arithmetic_run(src1, src2, dst, mask, "arithm_add_with_mask", &arithm_add);
+}
+
+void cv::ocl::subtract(const oclMat &src1, const oclMat &src2, oclMat &dst)
+{
+    arithmetic_run(src1, src2, dst, "arithm_sub", &arithm_sub);
+}
+void cv::ocl::subtract(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask)
+{
+    arithmetic_run(src1, src2, dst, mask, "arithm_sub_with_mask", &arithm_sub);
+}
+typedef void (*MulDivFunc)(const oclMat &src1, const oclMat &src2, oclMat &dst, string kernelName,
+                           const char **kernelString, void *scalar);
+
+void cv::ocl::multiply(const oclMat &src1, const oclMat &src2, oclMat &dst, double scalar)
+{
+    static MulDivFunc tab[] =
+    {
+        arithmetic_run<float>, 0, arithmetic_run<float>, arithmetic_run<float>,
+        arithmetic_run<float>, arithmetic_run<float>, arithmetic_run<double>,
+    };
+
+    tab[src1.depth()](src1, src2, dst, "arithm_mul", &arithm_mul, (void *)(&scalar));
+}
+void cv::ocl::divide(const oclMat &src1, const oclMat &src2, oclMat &dst, double scalar)
+{
+    if(src1.clCxt -> impl -> double_support ==0)
+    {
+        CV_Error(-217,"Selected device don't support double\r\n");
+        return;
+    }
+
+    arithmetic_run<double>(src1, src2, dst, "arithm_div", &arithm_div, (void *)(&scalar));
+}
+    template <typename WT ,typename CL_WT>
+void arithmetic_scalar_run(const oclMat &src1, const Scalar &src2, oclMat &dst, const oclMat &mask, string kernelName, const char **kernelString, int isMatSubScalar)
+{
+    if(src1.clCxt -> impl -> double_support ==0 && src1.type() == CV_64F)
+    {
+        CV_Error(-217,"Selected device don't support double\r\n");
+        return;
+    }
+
+    dst.create(src1.size(), src1.type());
+
+    CV_Assert(src1.cols == dst.cols && src1.rows == dst.rows &&
+            src1.type() == dst.type());
+
+    //CV_Assert(src1.depth() != CV_8S);
+
+    if(mask.data)
+        CV_Assert(mask.type() == CV_8U && src1.rows == mask.rows && src1.cols == mask.cols);
+
+    Context  *clCxt = src1.clCxt;
+    int channels = dst.channels();
+    int depth = dst.depth();
+
+    WT s[4] = { saturate_cast<WT>(src2.val[0]), saturate_cast<WT>(src2.val[1]),
+        saturate_cast<WT>(src2.val[2]), saturate_cast<WT>(src2.val[3])
+    };
+
+    int vector_lengths[4][7] = {{4, 0, 2, 2, 1, 1, 1},
+        {2, 0, 1, 1, 1, 1, 1},
+        {4, 0, 2, 2 , 1, 1, 1},
+        {1, 0, 1, 1, 1, 1, 1}
+    };
+
+    size_t vector_length = vector_lengths[channels-1][depth];
+    int offset_cols = ((dst.offset % dst.step) / dst.elemSize()) & (vector_length - 1);
+    int cols = divUp(dst.cols + offset_cols, vector_length);
+
+    size_t localThreads[3]  = { 64, 4, 1 };
+    size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+        divUp(dst.rows, localThreads[1]) * localThreads[1],
+        1
+    };
+
+    int dst_step1 = dst.cols * dst.elemSize();
+    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_int) , (void *)&src1.step ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&src1.offset));
+    args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst.data ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.step ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.offset));
+
+    if(mask.data)
+    {
+        args.push_back( make_pair( sizeof(cl_mem) , (void *)&mask.data ));
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&mask.step ));
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&mask.offset));
+    }
+    args.push_back( make_pair( sizeof(CL_WT) ,  (void *)&s ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&src1.rows ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&cols ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_step1 ));
+    if(isMatSubScalar != 0)
+    {
+        isMatSubScalar = isMatSubScalar > 0 ? 1 : 0;
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&isMatSubScalar));
+    }
+
+    openCLExecuteKernel(clCxt, kernelString, kernelName, globalThreads, localThreads, args, channels, depth);
+}
+
+void arithmetic_scalar_run(const oclMat &src, oclMat &dst, string kernelName, const char **kernelString, double scalar)
+{
+    if(src.clCxt -> impl -> double_support ==0 && src.type() == CV_64F)
+    {
+        CV_Error(-217,"Selected device don't support double\r\n");
+        return;
+    }
+
+    dst.create(src.size(), src.type());
+    CV_Assert(src.cols == dst.cols && src.rows == dst.rows);
+
+    CV_Assert(src.type() == dst.type());
+    CV_Assert(src.depth() != CV_8S);
+
+    Context  *clCxt = src.clCxt;
+    int channels = dst.channels();
+    int depth = dst.depth();
+
+    int vector_lengths[4][7] = {{4, 0, 4, 4, 1, 1, 1},
+        {4, 0, 4, 4, 1, 1, 1},
+        {4, 0, 4, 4 , 1, 1, 1},
+        {4, 0, 4, 4, 1, 1, 1}
+    };
+
+    size_t vector_length = vector_lengths[channels-1][depth];
+    int offset_cols = (dst.offset / dst.elemSize1()) & (vector_length - 1);
+    int cols = divUp(dst.cols * channels + offset_cols, vector_length);
+
+    size_t localThreads[3]  = { 64, 4, 1 };
+    size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+        divUp(dst.rows, localThreads[1]) * localThreads[1],
+        1
+    };
+
+    int dst_step1 = dst.cols * dst.elemSize();
+    vector<pair<size_t , const void *> > args;
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&src.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.offset ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src.rows ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&cols ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst_step1 ));
+    args.push_back( make_pair( sizeof(cl_double), (void *)&scalar ));
+
+    openCLExecuteKernel(clCxt, kernelString, kernelName, globalThreads, localThreads, args, -1, depth);
+}
+
+typedef void (*ArithmeticFuncS)(const oclMat &src1, const Scalar &src2, oclMat &dst, const oclMat &mask, string kernelName, const char **kernelString, int isMatSubScalar);
+
+
+void arithmetic_scalar(const oclMat &src1, const Scalar &src2, oclMat &dst, const oclMat &mask, string kernelName, const char **kernelString, int isMatSubScalar)
+{
+    static ArithmeticFuncS tab[8] =
+    {
+        arithmetic_scalar_run<int, cl_int4>,
+        arithmetic_scalar_run<int, cl_int4>,
+        arithmetic_scalar_run<int, cl_int4>,
+        arithmetic_scalar_run<int, cl_int4>,
+        arithmetic_scalar_run<int, cl_int4>,
+        arithmetic_scalar_run<float, cl_float4>,
+        arithmetic_scalar_run<double, cl_double4>,
+        0
+    };
+    ArithmeticFuncS func = tab[src1.depth()];
+    if(func == 0)
+        cv::ocl::error("Unsupported arithmetic operation", __FILE__, __LINE__);
+    func(src1, src2, dst, mask, kernelName, kernelString, isMatSubScalar);
+}
+void arithmetic_scalar(const oclMat &src1, const Scalar &src2, oclMat &dst, const oclMat &mask, string kernelName, const char **kernelString)
+{
+    arithmetic_scalar(src1, src2, dst, mask, kernelName, kernelString, 0);
+}
+
+void cv::ocl::add(const oclMat &src1, const Scalar &src2, oclMat &dst, const oclMat &mask)
+{
+    string kernelName = mask.data ? "arithm_s_add_with_mask" : "arithm_s_add";
+    const char **kernelString = mask.data ? &arithm_add_scalar_mask : &arithm_add_scalar;
+
+    arithmetic_scalar( src1, src2, dst, mask, kernelName, kernelString);
+}
+
+void cv::ocl::subtract(const oclMat &src1, const Scalar &src2, oclMat &dst, const oclMat &mask)
+{
+    string kernelName = mask.data ? "arithm_s_sub_with_mask" : "arithm_s_sub";
+    const char **kernelString = mask.data ? &arithm_sub_scalar_mask : &arithm_sub_scalar;
+    arithmetic_scalar( src1, src2, dst, mask, kernelName, kernelString, 1);
+}
+void cv::ocl::subtract(const Scalar &src2, const oclMat &src1, oclMat &dst, const oclMat &mask)
+{
+    string kernelName = mask.data ? "arithm_s_sub_with_mask" : "arithm_s_sub";
+    const char **kernelString = mask.data ? &arithm_sub_scalar_mask : &arithm_sub_scalar;
+    arithmetic_scalar( src1, src2, dst, mask, kernelName, kernelString, -1);
+}
+void cv::ocl::divide(double scalar, const oclMat &src,  oclMat &dst)
+{
+    if(src.clCxt -> impl -> double_support ==0)
+    {
+        CV_Error(-217,"Selected device don't support double\r\n");
+        return;
+    }
+
+    string kernelName =  "arithm_s_div";
+    arithmetic_scalar_run(src, dst, kernelName, &arithm_div, scalar);
+}
+//////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////  Absdiff ///////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+void cv::ocl::absdiff(const oclMat &src1, const oclMat &src2, oclMat &dst)
+{
+    arithmetic_run(src1, src2, dst, "arithm_absdiff", &arithm_absdiff);
+}
+void cv::ocl::absdiff(const oclMat &src1, const Scalar &src2, oclMat &dst)
+{
+    string kernelName = "arithm_s_absdiff";
+    oclMat mask;
+    arithmetic_scalar( src1, src2, dst, mask, kernelName, &arithm_absdiff);
+}
+//////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////  compare ///////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+void compare_run(const oclMat &src1, const oclMat &src2, oclMat &dst, string kernelName, const char **kernelString)
+{
+    dst.create(src1.size(), CV_8UC1);
+    CV_Assert(src1.channels() == 1);
+    CV_Assert(src1.type() == src2.type());
+    Context  *clCxt = src1.clCxt;
+    int depth = src1.depth();
+    int vector_lengths[7] = {4, 0, 4, 4, 4, 4, 4};
+    size_t vector_length = vector_lengths[depth];
+    int offset_cols = (dst.offset / dst.elemSize1()) & (vector_length - 1);
+    int cols = divUp(dst.cols  + offset_cols, vector_length);
+    size_t localThreads[3]  = { 64, 4, 1 };
+    size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                divUp(dst.rows, localThreads[1]) * localThreads[1],
+                                1
+                              };
+    int dst_step1 = dst.cols * dst.elemSize();
+    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_int), (void *)&src1.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src1.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&src2.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src2.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src2.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.offset ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src1.rows ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&cols ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst_step1 ));
+    openCLExecuteKernel(clCxt, kernelString, kernelName, globalThreads, localThreads, args, -1, depth);
+}
+
+void cv::ocl::compare(const oclMat &src1, const oclMat &src2, oclMat &dst , int cmpOp)
+{
+    if(src1.clCxt -> impl -> double_support ==0)
+    {
+        cout << "Selected device do not support double" << endl;
+        return;
+    }
+    string kernelName;
+    const char **kernelString = NULL;
+    switch( cmpOp )
+    {
+    case CMP_EQ:
+        kernelName = "arithm_compare_eq";
+        kernelString = &arithm_compare_eq;
+        break;
+    case CMP_GT:
+        kernelName = "arithm_compare_gt";
+        kernelString = &arithm_compare_eq;
+        break;
+    case CMP_GE:
+        kernelName = "arithm_compare_ge";
+        kernelString = &arithm_compare_eq;
+        break;
+    case CMP_NE:
+        kernelName = "arithm_compare_ne";
+        kernelString = &arithm_compare_ne;
+        break;
+    case CMP_LT:
+        kernelName = "arithm_compare_lt";
+        kernelString = &arithm_compare_ne;
+        break;
+    case CMP_LE:
+        kernelName = "arithm_compare_le";
+        kernelString = &arithm_compare_ne;
+        break;
+    default:
+        CV_Error(CV_StsBadArg, "Unknown comparison method");
+    }
+    compare_run(src1, src2, dst, kernelName, kernelString);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+////////////////////////////////// sum  //////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+//type = 0 sum,type = 1 absSum,type = 2 sqrSum
+void arithmetic_sum_buffer_run(const oclMat &src, cl_mem &dst, int vlen , int groupnum, int type = 0)
+{
+    vector<pair<size_t , const void *> > args;
+    int all_cols = src.step / (vlen * src.elemSize1());
+    int pre_cols = (src.offset % src.step) / (vlen * src.elemSize1());
+    int sec_cols = all_cols - (src.offset % src.step + src.cols * src.elemSize() - 1) / (vlen * src.elemSize1()) - 1;
+    int invalid_cols = pre_cols + sec_cols;
+    int cols = all_cols - invalid_cols , elemnum = cols * src.rows;;
+    int offset = src.offset / (vlen * src.elemSize1());
+    int repeat_s = src.offset / src.elemSize1() - offset * vlen;
+    int repeat_e = (offset + cols) * vlen - src.offset / src.elemSize1() - src.cols * src.channels();
+    char build_options[512];
+    CV_Assert(type == 0 || type == 1 || type == 2);
+    sprintf(build_options, "-D DEPTH_%d -D REPEAT_S%d -D REPEAT_E%d -D FUNC_TYPE_%d", src.depth(), repeat_s, repeat_e, type);
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&cols ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&invalid_cols ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&offset));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&elemnum));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&groupnum));
+    args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data));
+    args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst ));
+    size_t gt[3] = {groupnum * 256, 1, 1}, lt[3] = {256, 1, 1};
+    if(src.channels() != 3)
+        openCLExecuteKernel(src.clCxt, &arithm_sum, "arithm_op_sum", gt, lt, args, -1, -1, build_options);
+    else
+        openCLExecuteKernel(src.clCxt, &arithm_sum_3, "arithm_op_sum_3", gt, lt, args, -1, -1, build_options);
+}
+
+template <typename T>
+Scalar arithmetic_sum(const oclMat &src)
+{
+    size_t groupnum = src.clCxt->impl->maxComputeUnits;
+    CV_Assert(groupnum != 0);
+    int vlen = src.channels() == 3 ? 12 : 8, dbsize = groupnum * vlen, status;
+    Context *clCxt = src.clCxt;
+    T *p = new T[dbsize];
+    cl_mem dstBuffer = openCLCreateBuffer(clCxt,CL_MEM_WRITE_ONLY,dbsize*sizeof(T));
+    Scalar s;
+    s.val[0] = 0.0;
+    s.val[1] = 0.0;
+    s.val[2] = 0.0;
+    s.val[3] = 0.0;
+    arithmetic_sum_buffer_run(src, dstBuffer, vlen, groupnum);
+
+    memset(p, 0, dbsize * sizeof(T));
+    openCLReadBuffer(clCxt,dstBuffer,(void *)p,dbsize*sizeof(T));
+    for(int i = 0; i < dbsize;)
+    {
+        for(int j = 0; j < src.channels(); j++, i++)
+            s.val[j] += p[i];
+    }
+    delete[] p;
+    openCLFree(dstBuffer);
+    return s;
+}
+
+typedef Scalar (*sumFunc)(const oclMat &src);
+Scalar cv::ocl::sum(const oclMat &src)
+{
+    if(src.clCxt->impl->double_support==0 && src.depth()==CV_64F)
+    {
+        CV_Error(-217,"select device don't support double");
+    }
+    static sumFunc functab[2] =
+    {
+        arithmetic_sum<float>,
+        arithmetic_sum<double>
+    };
+
+    sumFunc func;
+    func = functab[src.clCxt->impl->double_support];
+    return func(src);
+}
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////// meanStdDev //////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+void cv::ocl::meanStdDev(const oclMat &src, Scalar &mean, Scalar &stddev)
+{
+    CV_Assert(src.depth() <= CV_32S);
+    cv::Size sz(1, 1);
+    int channels = src.channels();
+    Mat m1(sz, CV_MAKETYPE(CV_32S, channels), cv::Scalar::all(0)),
+        m2(sz, CV_MAKETYPE(CV_32S, channels), cv::Scalar::all(0));
+    oclMat dst1(m1), dst2(m2);
+    //arithmetic_sum_run(src, dst1,"arithm_op_sum");
+    //arithmetic_sum_run(src, dst2,"arithm_op_squares_sum");
+    m1 = (Mat)dst1;
+    m2 = (Mat)dst2;
+    int i = 0, *p = (int *)m1.data, *q = (int *)m2.data;
+    for(; i < channels; i++)
+    {
+        mean.val[i] = (double)p[i] / (src.cols * src.rows);
+        stddev.val[i] = std::sqrt(std::max((double) q[i] / (src.cols * src.rows) - mean.val[i] * mean.val[i] , 0.));
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////// minMax  /////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+void arithmetic_minMax_run(const oclMat &src, const oclMat &mask, cl_mem &dst, int vlen , int groupnum, string kernelName)
+{
+    vector<pair<size_t , const void *> > args;
+    int all_cols = src.step / (vlen * src.elemSize1());
+    int pre_cols = (src.offset % src.step) / (vlen * src.elemSize1());
+    int sec_cols = all_cols - (src.offset % src.step + src.cols * src.elemSize() - 1) / (vlen * src.elemSize1()) - 1;
+    int invalid_cols = pre_cols + sec_cols;
+    int cols = all_cols - invalid_cols , elemnum = cols * src.rows;;
+    int offset = src.offset / (vlen * src.elemSize1());
+    int repeat_s = src.offset / src.elemSize1() - offset * vlen;
+    int repeat_e = (offset + cols) * vlen - src.offset / src.elemSize1() - src.cols * src.channels();
+    char build_options[50];
+    sprintf(build_options, "-D DEPTH_%d -D REPEAT_S%d -D REPEAT_E%d", src.depth(), repeat_s, repeat_e);
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&cols ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&invalid_cols ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&offset));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&elemnum));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&groupnum));
+    args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data));
+    if(!mask.empty())
+    {
+        int mall_cols = mask.step / (vlen * mask.elemSize1());
+        int mpre_cols = (mask.offset % mask.step) / (vlen * mask.elemSize1());
+        int msec_cols = mall_cols - (mask.offset % mask.step + mask.cols * mask.elemSize() - 1) / (vlen * mask.elemSize1()) - 1;
+        int minvalid_cols = mpre_cols + msec_cols;
+        int moffset = mask.offset / (vlen * mask.elemSize1());
+
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&minvalid_cols ));
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&moffset ));
+        args.push_back( make_pair( sizeof(cl_mem) , (void *)&mask.data ));
+    }
+    args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst ));
+    size_t gt[3] = {groupnum * 256, 1, 1}, lt[3] = {256, 1, 1};
+    openCLExecuteKernel(src.clCxt, &arithm_minMax, kernelName, gt, lt, args, -1, -1, build_options);
+}
+
+
+void arithmetic_minMax_mask_run(const oclMat &src, const oclMat &mask, cl_mem &dst, int vlen, int groupnum, string kernelName)
+{
+    vector<pair<size_t , const void *> > args;
+    size_t gt[3] = {groupnum * 256, 1, 1}, lt[3] = {256, 1, 1};
+    char build_options[50];
+    if(src.channels() == 1)
+    {
+        int cols = (src.cols - 1) / vlen + 1;
+        int invalid_cols = src.step / (vlen * src.elemSize1()) - cols;
+        int offset = src.offset / src.elemSize1();
+        int repeat_me = vlen - (mask.cols % vlen == 0 ? vlen : mask.cols % vlen);
+        int minvalid_cols = mask.step / (vlen * mask.elemSize1()) - cols;
+        int moffset = mask.offset / mask.elemSize1();
+        int elemnum = cols * src.rows;
+        sprintf(build_options, "-D DEPTH_%d -D REPEAT_E%d", src.depth(), repeat_me);
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&cols ));
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&invalid_cols ));
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&offset));
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&elemnum));
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&groupnum));
+        args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data));
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&minvalid_cols ));
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&moffset ));
+        args.push_back( make_pair( sizeof(cl_mem) , (void *)&mask.data ));
+        args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst ));
+        //        printf("elemnum:%d,cols:%d,invalid_cols:%d,offset:%d,minvalid_cols:%d,moffset:%d,repeat_e:%d\r\n",
+        //               elemnum,cols,invalid_cols,offset,minvalid_cols,moffset,repeat_me);
+        openCLExecuteKernel(src.clCxt, &arithm_minMax_mask, kernelName, gt, lt, args, -1, -1, build_options);
+    }
+}
+
+template <typename T> void arithmetic_minMax(const oclMat &src, double *minVal, double *maxVal, const oclMat &mask)
+{
+    size_t groupnum = src.clCxt->impl->maxComputeUnits;
+    CV_Assert(groupnum != 0);
+    groupnum = groupnum * 2;
+    int vlen = 8;
+    int dbsize = groupnum * 2 * vlen * sizeof(T) , status;
+    Context *clCxt = src.clCxt;
+    cl_mem dstBuffer = openCLCreateBuffer(clCxt,CL_MEM_WRITE_ONLY,dbsize);
+    *minVal = std::numeric_limits<double>::max() , *maxVal = -std::numeric_limits<double>::max();
+    if (mask.empty())
+    {
+        arithmetic_minMax_run(src, mask, dstBuffer, vlen, groupnum, "arithm_op_minMax");
+    }
+    else
+    {
+        arithmetic_minMax_mask_run(src, mask, dstBuffer, vlen, groupnum, "arithm_op_minMax_mask");
+    }
+    T *p = new T[groupnum * vlen * 2];
+    memset(p, 0, dbsize);
+    openCLReadBuffer(clCxt,dstBuffer,(void *)p,dbsize);
+    for(int i = 0; i < vlen * groupnum; i++)
+    {
+        *minVal = *minVal < p[i] ? *minVal : p[i];
+    }
+    for(int i = vlen * groupnum; i < 2 * vlen * groupnum; i++)
+    {
+        *maxVal = *maxVal > p[i] ? *maxVal : p[i];
+    }
+    delete[] p;
+    openCLFree(dstBuffer);
+}
+
+typedef void (*minMaxFunc)(const oclMat &src, double *minVal, double *maxVal, const oclMat &mask);
+void cv::ocl::minMax(const oclMat &src, double *minVal, double *maxVal, const oclMat &mask)
+{
+    CV_Assert(src.channels() == 1);
+    if(src.clCxt->impl->double_support==0 && src.depth()==CV_64F)
+    {
+        CV_Error(-217,"select device don't support double");
+    }
+    static minMaxFunc functab[8] =
+    {
+        arithmetic_minMax<uchar>,
+        arithmetic_minMax<char>,
+        arithmetic_minMax<ushort>,
+        arithmetic_minMax<short>,
+        arithmetic_minMax<int>,
+        arithmetic_minMax<float>,
+        arithmetic_minMax<double>,
+        0
+    };
+    minMaxFunc func;
+    func = functab[src.depth()];
+    func(src, minVal, maxVal, mask);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////// norm /////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+double cv::ocl::norm(const oclMat &src1, int normType)
+{
+    return norm(src1, oclMat(src1.size(), src1.type(), Scalar::all(0)), normType);
+}
+
+double cv::ocl::norm(const oclMat &src1, const oclMat &src2, int normType)
+{
+    bool isRelative = (normType & NORM_RELATIVE) != 0;
+    normType &= 7;
+    CV_Assert(src1.depth() <= CV_32S && src1.type() == src2.type() && ( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2));
+    int channels = src1.channels(), i = 0, *p;
+    double r = 0;
+    oclMat gm1(src1.size(), src1.type());
+    int min_int = (normType == NORM_INF ? CL_INT_MIN : 0);
+    Mat m(1, 1, CV_MAKETYPE(CV_32S, channels), cv::Scalar::all(min_int));
+    oclMat gm2(m), emptyMat;
+    switch(normType)
+    {
+    case NORM_INF:
+        //  arithmetic_run(src1, src2, gm1, "arithm_op_absdiff");
+        //arithmetic_minMax_run(gm1,emptyMat, gm2,"arithm_op_max");
+        m = (gm2);
+        p = (int *)m.data;
+        r = -std::numeric_limits<double>::max();
+        for(i = 0; i < channels; i++)
+        {
+            r = std::max(r, (double)p[i]);
+        }
+        break;
+    case NORM_L1:
+        //arithmetic_run(src1, src2, gm1, "arithm_op_absdiff");
+        //arithmetic_sum_run(gm1, gm2,"arithm_op_sum");
+        m = (gm2);
+        p = (int *)m.data;
+        for(i = 0; i < channels; i++)
+        {
+            r = r + (double)p[i];
+        }
+        break;
+    case NORM_L2:
+        //arithmetic_run(src1, src2, gm1, "arithm_op_absdiff");
+        //arithmetic_sum_run(gm1, gm2,"arithm_op_squares_sum");
+        m = (gm2);
+        p = (int *)m.data;
+        for(i = 0; i < channels; i++)
+        {
+            r = r + (double)p[i];
+        }
+        r = std::sqrt(r);
+        break;
+    }
+    if(isRelative)
+        r = r / norm(src2, normType);
+    return r;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+////////////////////////////////// flip //////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+void arithmetic_flip_rows_run(const oclMat &src, oclMat &dst, string kernelName)
+{
+    if(src.clCxt -> impl -> double_support ==0 && src.type() == CV_64F)
+    {
+        CV_Error(-217,"Selected device don't support double\r\n");
+        return;
+    }
+
+    CV_Assert(src.cols == dst.cols && src.rows == dst.rows);
+
+    CV_Assert(src.type() == dst.type());
+
+    Context  *clCxt = src.clCxt;
+    int channels = dst.channels();
+    int depth = dst.depth();
+
+    int vector_lengths[4][7] = {{4, 4, 4, 4, 1, 1, 1},
+        {4, 4, 4, 4, 1, 1, 1},
+        {4, 4, 4, 4, 1, 1, 1},
+        {4, 4, 4, 4, 1, 1, 1}
+    };
+
+    size_t vector_length = vector_lengths[channels-1][depth];
+    int offset_cols = ((dst.offset % dst.step) / dst.elemSize1()) & (vector_length - 1);
+
+    int cols = divUp(dst.cols * channels + offset_cols, vector_length);
+    int rows = divUp(dst.rows, 2);
+
+    size_t localThreads[3]  = { 64, 4, 1 };
+    size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                divUp(rows, localThreads[1]) * localThreads[1],
+                                1
+                              };
+
+    int dst_step1 = dst.cols * dst.elemSize();
+    vector<pair<size_t , const void *> > args;
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&src.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.offset ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.rows ));
+    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 *)&dst_step1 ));
+
+    openCLExecuteKernel(clCxt, &arithm_flip, kernelName, globalThreads, localThreads, args, -1, depth);
+}
+void arithmetic_flip_cols_run(const oclMat &src, oclMat &dst, string kernelName, bool isVertical)
+{
+    if(src.clCxt -> impl -> double_support ==0 && src.type() == CV_64F)
+    {
+        CV_Error(-217,"Selected device don't support double\r\n");
+        return;
+    }
+
+    CV_Assert(src.cols == dst.cols && src.rows == dst.rows);
+    CV_Assert(src.type() == dst.type());
+
+    Context  *clCxt = src.clCxt;
+    int channels = dst.channels();
+    int depth = dst.depth();
+
+    int vector_lengths[4][7] = {{1, 1, 1, 1, 1, 1, 1},
+        {1, 1, 1, 1, 1, 1, 1},
+        {1, 1, 1, 1, 1, 1, 1},
+        {1, 1, 1, 1, 1, 1, 1}
+    };
+
+    size_t vector_length = vector_lengths[channels-1][depth];
+    int offset_cols = ((dst.offset % dst.step) / dst.elemSize()) & (vector_length - 1);
+    int cols = divUp(dst.cols + offset_cols, vector_length);
+    cols = isVertical ? cols : divUp(cols, 2);
+    int rows = isVertical ?  divUp(dst.rows, 2) : dst.rows;
+
+    size_t localThreads[3]  = { 64, 4, 1 };
+    size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                divUp(rows, localThreads[1]) * localThreads[1],
+                                1
+                              };
+
+    int dst_step1 = dst.cols * dst.elemSize();
+    vector<pair<size_t , const void *> > args;
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&src.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.offset ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.rows ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.cols ));
+
+    if(isVertical)
+        args.push_back( make_pair( sizeof(cl_int), (void *)&rows ));
+    else
+        args.push_back( make_pair( sizeof(cl_int), (void *)&cols ));
+
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst_step1 ));
+
+    const char **kernelString = isVertical ? &arithm_flip_rc : &arithm_flip;
+
+    openCLExecuteKernel(clCxt, kernelString, kernelName, globalThreads, localThreads, args, src.channels(), depth);
+}
+void cv::ocl::flip(const oclMat &src, oclMat &dst, int flipCode)
+{
+    dst.create(src.size(), src.type());
+    if(flipCode == 0)
+    {
+        arithmetic_flip_rows_run(src, dst, "arithm_flip_rows");
+    }
+    else if(flipCode > 0)
+        arithmetic_flip_cols_run(src, dst, "arithm_flip_cols", false);
+    else
+        arithmetic_flip_cols_run(src, dst, "arithm_flip_rc", true);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+////////////////////////////////// LUT  //////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+void arithmetic_lut_run(const oclMat &src1, const oclMat &src2, oclMat &dst, string kernelName)
+{
+    Context *clCxt = src1.clCxt;
+    int channels = src1.channels();
+    int rows = src1.rows;
+    int cols = src1.cols;
+    //int step = src1.step;
+    int src_step = src1.step;
+    int dst_step = dst.step;
+    int whole_rows = src1.wholerows;
+    int whole_cols = src1.wholecols;
+    int src_offset = src1.offset;
+    int dst_offset = dst.offset;
+    int lut_offset = src2.offset;
+    int left_col = 0, right_col = 0;
+    size_t localSize[] = {16, 16, 1};
+    //cl_kernel kernel = openCLGetKernelFromSource(clCxt,&arithm_LUT,kernelName);
+    size_t globalSize[] = {(cols + localSize[0] - 1) / localSize[0]*localSize[0], (rows + localSize[1] - 1) / localSize[1]*localSize[1], 1};
+    if(channels == 1 && cols > 6)
+    {
+        left_col = 4 - (dst_offset & 3);
+        left_col &= 3;
+        dst_offset += left_col;
+        src_offset += left_col;
+        cols -= left_col;
+        right_col = cols & 3;
+        cols -= right_col;
+        globalSize[0] = (cols / 4 + localSize[0] - 1) / localSize[0] * localSize[0];
+    }
+    else if(channels == 1)
+    {
+        left_col = cols;
+        right_col = 0;
+        cols = 0;
+        globalSize[0] = 0;
+    }
+    CV_Assert(clCxt == dst.clCxt);
+    CV_Assert(src1.cols == dst.cols);
+    CV_Assert(src1.rows == dst.rows);
+    CV_Assert(src1.channels() == dst.channels());
+    //  CV_Assert(src1.step == dst.step);
+    vector<pair<size_t , const void *> > args;
+
+    if(globalSize[0] != 0)
+    {
+        args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data ));
+        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_int), (void *)&rows ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&cols ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&channels ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&whole_rows ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&whole_cols ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&src_offset ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&dst_offset ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&lut_offset ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&src_step ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&dst_step ));
+        openCLExecuteKernel(clCxt, &arithm_LUT, kernelName, globalSize, localSize, args, src1.channels(), src1.depth());
+    }
+    if(channels == 1 && (left_col != 0 || right_col != 0))
+    {
+        src_offset = src1.offset;
+        dst_offset = dst.offset;
+        localSize[0] = 1;
+        localSize[1] = 256;
+        globalSize[0] = left_col + right_col;
+        globalSize[1] = (rows + localSize[1] - 1) / localSize[1] * localSize[1];
+        //kernel = openCLGetKernelFromSource(clCxt,&arithm_LUT,"LUT2");
+        args.clear();
+        args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data ));
+        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_int), (void *)&rows ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&left_col ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&channels ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&whole_rows ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&cols ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&src_offset ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&dst_offset ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&lut_offset ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&src_step ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&dst_step ));
+        openCLExecuteKernel(clCxt, &arithm_LUT, "LUT2", globalSize, localSize, args, src1.channels(), src1.depth());
+    }
+}
+
+void cv::ocl::LUT(const oclMat &src, const oclMat &lut, oclMat &dst)
+{
+    int cn = src.channels();
+    CV_Assert(src.depth() == CV_8U);
+    CV_Assert((lut.channels() == 1 || lut.channels() == cn) && lut.rows == 1 && lut.cols == 256);
+    dst.create(src.size(), CV_MAKETYPE(lut.depth(), cn));
+    //oclMat _lut(lut);
+    string kernelName = "LUT";
+    arithmetic_lut_run(src, lut, dst, kernelName);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////// exp log /////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+void arithmetic_exp_log_run(const oclMat &src, oclMat &dst, string kernelName, const char **kernelString)
+{
+    dst.create(src.size(), src.type());
+    CV_Assert(src.cols == dst.cols &&
+              src.rows == dst.rows );
+
+    CV_Assert(src.type() == dst.type());
+    CV_Assert( src.type() == CV_32F || src.type() == CV_64F);
+
+    Context  *clCxt = src.clCxt;
+
+    //int channels = dst.channels();
+    int depth = dst.depth();
+
+    size_t localThreads[3]  = { 64, 4, 1 };
+    size_t globalThreads[3] = { divUp(dst.cols, localThreads[0]) * localThreads[0],
+                                divUp(dst.rows, localThreads[1]) * localThreads[1],
+                                1
+                              };
+
+    vector<pair<size_t , const void *> > args;
+    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 *)&dst.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src.offset ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&src.data ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data ));
+
+    openCLExecuteKernel(clCxt, kernelString, kernelName, globalThreads, localThreads, args, -1, depth);
+}
+void cv::ocl::exp(const oclMat &src, oclMat &dst)
+{
+    arithmetic_exp_log_run(src, dst, "arithm_exp", &arithm_exp);
+}
+
+void cv::ocl::log(const oclMat &src, oclMat &dst)
+{
+    arithmetic_exp_log_run(src, dst, "arithm_log", &arithm_log);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+////////////////////////////// magnitude phase ///////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+void arithmetic_magnitude_phase_run(const oclMat &src1, const oclMat &src2, oclMat &dst, string kernelName)
+{
+    if(src1.clCxt -> impl -> double_support ==0 && src1.type() == CV_64F)
+    {
+        CV_Error(-217,"Selected device don't support double\r\n");
+        return;
+    }
+
+    Context  *clCxt = src1.clCxt;
+    int channels = dst.channels();
+    int depth = dst.depth();
+
+    size_t vector_length = 1;
+    int offset_cols = ((dst.offset % dst.step) / dst.elemSize1()) & (vector_length - 1);
+    int cols = divUp(dst.cols * channels + offset_cols, vector_length);
+    int rows = dst.rows;
+
+    size_t localThreads[3]  = { 64, 4, 1 };
+    size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                divUp(rows, localThreads[1]) * localThreads[1],
+                                1
+                              };
+
+    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_int), (void *)&src1.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src1.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&src2.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src2.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src2.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.offset ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.rows ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&cols ));
+
+    openCLExecuteKernel(clCxt, &arithm_magnitude, kernelName, globalThreads, localThreads, args, -1, depth);
+}
+
+void cv::ocl::magnitude(const oclMat &src1, const oclMat &src2, oclMat &dst)
+{
+    CV_Assert(src1.type() == src2.type() && src1.size() == src2.size() &&
+              (src1.depth() == CV_32F || src1.depth() == CV_64F));
+
+    dst.create(src1.size(), src1.type());
+    arithmetic_magnitude_phase_run(src1, src2, dst, "arithm_magnitude");
+}
+
+void arithmetic_phase_run(const oclMat &src1, const oclMat &src2, oclMat &dst, string kernelName, const char **kernelString)
+{
+    if(src1.clCxt -> impl -> double_support ==0 && src1.type() == CV_64F)
+    {
+        CV_Error(-217,"Selected device don't support double\r\n");
+        return;
+    }
+
+    CV_Assert(src1.cols == src2.cols && src2.cols == dst.cols && src1.rows == src2.rows && src2.rows == dst.rows);
+    CV_Assert(src1.type() == src2.type() && src1.type() == dst.type());
+
+    Context  *clCxt = src1.clCxt;
+    int channels = dst.channels();
+    int depth = dst.depth();
+
+    size_t vector_length = 1;
+    int offset_cols = ((dst.offset % dst.step) / dst.elemSize1()) & (vector_length - 1);
+    int cols = divUp(dst.cols * channels + offset_cols, vector_length);
+    int rows = dst.rows;
+
+    size_t localThreads[3]  = { 64, 4, 1 };
+    size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                divUp(rows, localThreads[1]) * localThreads[1],
+                                1
+                              };
+
+    int dst_step1 = dst.cols * dst.elemSize();
+    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_int), (void *)&src1.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src1.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&src2.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src2.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src2.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.offset ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.rows ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&cols ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst_step1 ));
+
+    openCLExecuteKernel(clCxt, kernelString, kernelName, globalThreads, localThreads, args, -1, depth);
+}
+void cv::ocl::phase(const oclMat &x, const oclMat &y, oclMat &Angle , bool angleInDegrees)
+{
+    CV_Assert(x.type() == y.type() && x.size() == y.size() && (x.depth() == CV_32F || x.depth() == CV_64F));
+    Angle.create(x.size(), x.type());
+    string kernelName = angleInDegrees ? "arithm_phase_indegrees" : "arithm_phase_inradians";
+    if(angleInDegrees)
+    {
+        arithmetic_phase_run(x, y, Angle, kernelName, &arithm_phase);
+        //cout<<"1"<<endl;
+    }
+    else
+    {
+        arithmetic_phase_run(x, y, Angle, kernelName, &arithm_phase);
+        //cout<<"2"<<endl;
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+////////////////////////////////// cartToPolar ///////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+void arithmetic_cartToPolar_run(const oclMat &src1, const oclMat &src2, oclMat &dst_mag, oclMat &dst_cart,
+                                string kernelName, bool angleInDegrees)
+{
+    if(src1.clCxt -> impl -> double_support ==0 && src1.type() == CV_64F)
+    {
+        CV_Error(-217,"Selected device don't support double\r\n");
+        return;
+    }
+
+    Context  *clCxt = src1.clCxt;
+    int channels = src1.channels();
+    int depth = src1.depth();
+
+    int cols = src1.cols * channels;
+    int rows = src1.rows;
+
+    size_t localThreads[3]  = { 64, 4, 1 };
+    size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                divUp(rows, localThreads[1]) * localThreads[1],
+                                1
+                              };
+
+    int tmp = angleInDegrees ? 1 : 0;
+    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_int), (void *)&src1.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src1.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&src2.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src2.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src2.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst_mag.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst_mag.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst_mag.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst_cart.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst_cart.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst_cart.offset ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&rows ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&cols ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&tmp ));
+
+    openCLExecuteKernel(clCxt, &arithm_cartToPolar, kernelName, globalThreads, localThreads, args, -1, depth);
+}
+void cv::ocl::cartToPolar(const oclMat &x, const oclMat &y, oclMat &mag, oclMat &angle, bool angleInDegrees)
+{
+    CV_Assert(x.type() == y.type() && x.size() == y.size() && (x.depth() == CV_32F || x.depth() == CV_64F));
+
+    mag.create(x.size(), x.type());
+    angle.create(x.size(), x.type());
+
+    arithmetic_cartToPolar_run(x, y, mag, angle, "arithm_cartToPolar", angleInDegrees);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+////////////////////////////////// polarToCart ///////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+void arithmetic_ptc_run(const oclMat &src1, const oclMat &src2, oclMat &dst1, oclMat &dst2, bool angleInDegrees,
+                        string kernelName)
+{
+    if(src1.clCxt -> impl -> double_support ==0 && src1.type() == CV_64F)
+    {
+        CV_Error(-217,"Selected device don't support double\r\n");
+        return;
+    }
+
+    Context  *clCxt = src2.clCxt;
+    int channels = src2.channels();
+    int depth = src2.depth();
+
+    int cols = src2.cols * channels;
+    int rows = src2.rows;
+
+    size_t localThreads[3]  = { 64, 4, 1 };
+    size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                divUp(rows, localThreads[1]) * localThreads[1],
+                                1
+                              };
+
+    int tmp = angleInDegrees ? 1 : 0;
+    vector<pair<size_t , const void *> > args;
+    if(src1.data)
+    {
+        args.push_back( make_pair( sizeof(cl_mem), (void *)&src1.data ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&src1.step ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&src1.offset ));
+    }
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&src2.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src2.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src2.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst1.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst1.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst1.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst2.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst2.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst2.offset ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&rows ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&cols ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&tmp ));
+
+    openCLExecuteKernel(clCxt, &arithm_polarToCart, kernelName, globalThreads, localThreads, args, -1, depth);
+}
+
+void cv::ocl::polarToCart(const oclMat &magnitude, const oclMat &angle, oclMat &x, oclMat &y, bool angleInDegrees)
+{
+    CV_Assert(angle.depth() == CV_32F || angle.depth() == CV_64F);
+
+    x.create(angle.size(), angle.type());
+    y.create(angle.size(), angle.type());
+
+    if( magnitude.data )
+    {
+        CV_Assert( magnitude.size() == angle.size() && magnitude.type() == angle.type() );
+        arithmetic_ptc_run(magnitude, angle, x, y, angleInDegrees, "arithm_polarToCart_mag");
+    }
+    else
+        arithmetic_ptc_run(magnitude, angle, x, y, angleInDegrees, "arithm_polarToCart");
+}
+
+//////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////// minMaxLoc ////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+void arithmetic_minMaxLoc_run(const oclMat &src, cl_mem &dst, int vlen , int groupnum)
+{
+    vector<pair<size_t , const void *> > args;
+    int all_cols = src.step / (vlen * src.elemSize1());
+    int pre_cols = (src.offset % src.step) / (vlen * src.elemSize1());
+    int sec_cols = all_cols - (src.offset % src.step + src.cols * src.elemSize1() - 1) / (vlen * src.elemSize1()) - 1;
+    int invalid_cols = pre_cols + sec_cols;
+    int cols = all_cols - invalid_cols , elemnum = cols * src.rows;;
+    int offset = src.offset / (vlen * src.elemSize1());
+    int repeat_s = src.offset / src.elemSize1() - offset * vlen;
+    int repeat_e = (offset + cols) * vlen - src.offset / src.elemSize1() - src.cols;
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&cols ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&invalid_cols ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&offset));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&elemnum));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&groupnum));
+    args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data));
+    args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst ));
+    char build_options[50];
+    sprintf(build_options, "-D DEPTH_%d -D REPEAT_S%d -D REPEAT_E%d", src.depth(), repeat_s, repeat_e);
+    size_t gt[3] = {groupnum * 256, 1, 1}, lt[3] = {256, 1, 1};
+    openCLExecuteKernel(src.clCxt, &arithm_minMaxLoc, "arithm_op_minMaxLoc", gt, lt, args, -1, -1, build_options);
+}
+
+void arithmetic_minMaxLoc_mask_run(const oclMat &src, const oclMat &mask, cl_mem &dst, int vlen, int groupnum)
+{
+    vector<pair<size_t , const void *> > args;
+    size_t gt[3] = {groupnum * 256, 1, 1}, lt[3] = {256, 1, 1};
+    char build_options[50];
+    if(src.channels() == 1)
+    {
+        int cols = (src.cols - 1) / vlen + 1;
+        int invalid_cols = src.step / (vlen * src.elemSize1()) - cols;
+        int offset = src.offset / src.elemSize1();
+        int repeat_me = vlen - (mask.cols % vlen == 0 ? vlen : mask.cols % vlen);
+        int minvalid_cols = mask.step / (vlen * mask.elemSize1()) - cols;
+        int moffset = mask.offset / mask.elemSize1();
+        int elemnum = cols * src.rows;
+        sprintf(build_options, "-D DEPTH_%d -D REPEAT_E%d", src.depth(), repeat_me);
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&cols ));
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&invalid_cols ));
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&offset));
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&elemnum));
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&groupnum));
+        args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data));
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&minvalid_cols ));
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&moffset ));
+        args.push_back( make_pair( sizeof(cl_mem) , (void *)&mask.data ));
+        args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst ));
+        //    printf("elemnum:%d,cols:%d,invalid_cols:%d,offset:%d,minvalid_cols:%d,moffset:%d,repeat_e:%d\r\n",
+        //           elemnum,cols,invalid_cols,offset,minvalid_cols,moffset,repeat_me);
+        openCLExecuteKernel(src.clCxt, &arithm_minMaxLoc_mask, "arithm_op_minMaxLoc_mask", gt, lt, args, -1, -1, build_options);
+    }
+}
+template<typename T>
+void arithmetic_minMaxLoc(const oclMat &src, double *minVal, double *maxVal,
+                        Point *minLoc, Point *maxLoc, const oclMat &mask)
+{
+    CV_Assert(src.channels() == 1);
+       size_t groupnum = src.clCxt->impl->maxComputeUnits;
+    CV_Assert(groupnum != 0);
+    int minloc = -1 , maxloc = -1;
+    int vlen = 8, dbsize = groupnum * vlen * 4 * sizeof(T) , status;
+    Context *clCxt = src.clCxt;
+    cl_mem dstBuffer = openCLCreateBuffer(clCxt,CL_MEM_WRITE_ONLY,dbsize);
+    *minVal = std::numeric_limits<double>::max() , *maxVal = -std::numeric_limits<double>::max();
+    if (mask.empty())
+    {
+        arithmetic_minMaxLoc_run(src, dstBuffer, vlen, groupnum);
+    }
+    else
+    {
+        arithmetic_minMaxLoc_mask_run(src, mask, dstBuffer, vlen, groupnum);
+    }
+    T *p = new T[groupnum * vlen * 4];
+    memset(p, 0, dbsize);
+    openCLReadBuffer(clCxt,dstBuffer,(void *)p,dbsize);
+    for(int i = 0; i < vlen * groupnum; i++)
+    {
+        *minVal = (*minVal < p[i] || p[i + 2 * vlen *groupnum] == -1) ? *minVal : p[i];
+        minloc = (*minVal < p[i] || p[i + 2 * vlen *groupnum] == -1) ? minloc : p[i + 2 * vlen * groupnum];
+    }
+    for(int i = vlen * groupnum; i < 2 * vlen * groupnum; i++)
+    {
+        *maxVal = (*maxVal > p[i] || p[i + 2 * vlen *groupnum] == -1) ? *maxVal : p[i];
+        maxloc = (*maxVal > p[i] || p[i + 2 * vlen *groupnum] == -1) ? maxloc : p[i + 2 * vlen * groupnum];
+    }
+
+    int pre_rows = src.offset / src.step;
+    int pre_cols = (src.offset % src.step) / src.elemSize1();
+    int wholecols = src.step / src.elemSize1();
+    if( minLoc )
+    {
+        if( minloc >= 0 )
+        {
+            minLoc->y = minloc / wholecols - pre_rows;
+            minLoc->x = minloc % wholecols - pre_cols;
+        }
+        else
+            minLoc->x = minLoc->y = -1;
+    }
+    if( maxLoc )
+    {
+        if( maxloc >= 0 )
+        {
+            maxLoc->y = maxloc / wholecols - pre_rows;
+            maxLoc->x = maxloc % wholecols - pre_cols;
+        }
+        else
+            maxLoc->x = maxLoc->y = -1;
+    }
+    delete[] p;
+    openCLSafeCall(clReleaseMemObject(dstBuffer));
+}
+
+typedef void (*minMaxLocFunc)(const oclMat &src, double *minVal, double *maxVal,
+                        Point *minLoc, Point *maxLoc, const oclMat &mask);
+void cv::ocl::minMaxLoc(const oclMat &src, double *minVal, double *maxVal,
+                        Point *minLoc, Point *maxLoc, const oclMat &mask)
+{
+    if(src.clCxt->impl->double_support==0 && src.depth()==CV_64F)
+    {
+        CV_Error(-217,"select device don't support double");
+    }
+    static minMaxLocFunc functab[2] =
+    {
+        arithmetic_minMaxLoc<float>,
+        arithmetic_minMaxLoc<double>
+    };
+
+    minMaxLocFunc func;
+    func = functab[src.clCxt->impl->double_support];
+    func(src,minVal,maxVal,minLoc,maxLoc,mask);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+///////////////////////////// countNonZero ///////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+void arithmetic_countNonZero_run(const oclMat &src, cl_mem &dst, int vlen , int groupnum, string kernelName)
+{
+    vector<pair<size_t , const void *> > args;
+    int all_cols = src.step / (vlen * src.elemSize1());
+    int pre_cols = (src.offset % src.step) / (vlen * src.elemSize1());
+    int sec_cols = all_cols - (src.offset % src.step + src.cols * src.elemSize() - 1) / (vlen * src.elemSize1()) - 1;
+    int invalid_cols = pre_cols + sec_cols;
+    int cols = all_cols - invalid_cols , elemnum = cols * src.rows;;
+    int offset = src.offset / (vlen * src.elemSize1());
+    int repeat_s = src.offset / src.elemSize1() - offset * vlen;
+    int repeat_e = (offset + cols) * vlen - src.offset / src.elemSize1() - src.cols * src.channels();
+
+    char build_options[50];
+    sprintf(build_options, "-D DEPTH_%d -D REPEAT_S%d -D REPEAT_E%d", src.depth(), repeat_s, repeat_e);
+
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&cols ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&invalid_cols ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&offset));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&elemnum));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&groupnum));
+    args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data));
+    args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst ));
+    size_t gt[3] = {groupnum * 256, 1, 1}, lt[3] = {256, 1, 1};
+    openCLExecuteKernel(src.clCxt, &arithm_nonzero, kernelName, gt, lt, args, -1, -1, build_options);
+}
+
+int cv::ocl::countNonZero(const oclMat &src)
+{
+    size_t groupnum = src.clCxt->impl->maxComputeUnits;
+    if(src.clCxt->impl->double_support == 0 && src.depth()==CV_64F)
+    {
+        CV_Error(-217,"select device don't support double");
+    }
+    CV_Assert(groupnum != 0);
+    groupnum = groupnum * 2;
+    int vlen = 8 , dbsize = groupnum * vlen, status;
+    //cl_ulong start, end;
+    Context *clCxt = src.clCxt;
+    string kernelName = "arithm_op_nonzero";
+    int *p = new int[dbsize], nonzero = 0;
+    cl_mem dstBuffer = openCLCreateBuffer(clCxt,CL_MEM_WRITE_ONLY,dbsize*sizeof(int));
+    arithmetic_countNonZero_run(src, dstBuffer, vlen, groupnum, kernelName);
+
+    memset(p, 0, dbsize * sizeof(int));
+    openCLReadBuffer(clCxt,dstBuffer,(void *)p,dbsize*sizeof(int));
+    for(int i = 0; i < dbsize; i++)
+    {
+        nonzero += p[i];
+    }
+    delete[] p;
+    openCLSafeCall(clReleaseMemObject(dstBuffer));
+    return nonzero;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+////////////////////////////////bitwise_op////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+void bitwise_run(const oclMat &src1, oclMat &dst, string kernelName, const char **kernelString)
+{
+    dst.create(src1.size(), src1.type());
+
+
+    Context  *clCxt = src1.clCxt;
+    int channels = dst.channels();
+    int depth = dst.depth();
+
+    int vector_lengths[4][7] = {{4, 4, 4, 4, 1, 1, 1},
+        {4, 4, 4, 4, 1, 1, 1},
+        {4, 4, 4, 4, 1, 1, 1},
+        {4, 4, 4, 4, 1, 1, 1}
+    };
+
+    size_t vector_length = vector_lengths[channels-1][depth];
+    int offset_cols = (dst.offset / dst.elemSize1()) & (vector_length - 1);
+    int cols = divUp(dst.cols * channels + offset_cols, vector_length);
+
+    size_t localThreads[3]  = { 64, 4, 1 };
+    size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                divUp(dst.rows, localThreads[1]) * localThreads[1],
+                                1
+                              };
+
+    int dst_step1 = dst.cols * dst.elemSize();
+    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_int), (void *)&src1.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src1.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.offset ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src1.rows ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&cols ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst_step1 ));
+
+    openCLExecuteKernel(clCxt, kernelString, kernelName, globalThreads, localThreads, args, -1, depth);
+}
+
+
+template<typename T>
+void bitwise_run(const oclMat &src1, const oclMat &src2, oclMat &dst, string kernelName, const char **kernelString, void *_scalar)
+{
+    dst.create(src1.size(), src1.type());
+    CV_Assert(src1.cols == src2.cols && src2.cols == dst.cols &&
+              src1.rows == src2.rows && src2.rows == dst.rows);
+
+    CV_Assert(src1.type() == src2.type() && src1.type() == dst.type());
+
+    Context  *clCxt = src1.clCxt;
+    int channels = dst.channels();
+    int depth = dst.depth();
+
+    int vector_lengths[4][7] = {{4, 4, 4, 4, 1, 1, 1},
+        {4, 4, 4, 4, 1, 1, 1},
+        {4, 4, 4, 4, 1, 1, 1},
+        {4, 4, 4, 4, 1, 1, 1}
+    };
+
+    size_t vector_length = vector_lengths[channels-1][depth];
+    int offset_cols = (dst.offset / dst.elemSize1()) & (vector_length - 1);
+    int cols = divUp(dst.cols * channels + offset_cols, vector_length);
+
+    size_t localThreads[3]  = { 64, 4, 1 };
+    size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                divUp(dst.rows, localThreads[1]) * localThreads[1],
+                                1
+                              };
+
+    int dst_step1 = dst.cols * dst.elemSize();
+    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_int), (void *)&src1.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src1.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&src2.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src2.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src2.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.offset ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src1.rows ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&cols ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst_step1 ));
+
+    if(_scalar != NULL)
+    {
+        double scalar1 = *((double *)_scalar);
+        T scalar = (T)scalar1;
+        args.push_back( make_pair( sizeof(T), (void *)&scalar ));
+    }
+
+    openCLExecuteKernel(clCxt, kernelString, kernelName, globalThreads, localThreads, args, -1, depth);
+}
+void bitwise_run(const oclMat &src1, const oclMat &src2, oclMat &dst, string kernelName, const char **kernelString)
+{
+    bitwise_run<char>(src1, src2, dst, kernelName, kernelString, (void *)NULL);
+}
+void bitwise_run(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask, string kernelName, const char **kernelString)
+{
+    dst.create(src1.size(), src1.type());
+    CV_Assert(src1.cols == src2.cols && src2.cols == dst.cols &&
+              src1.rows == src2.rows && src2.rows == dst.rows &&
+              src1.rows == mask.rows && src1.cols == mask.cols);
+
+    CV_Assert(src1.type() == src2.type() && src1.type() == dst.type());
+    CV_Assert(mask.type() == CV_8U);
+
+    Context  *clCxt = src1.clCxt;
+    int channels = dst.channels();
+    int depth = dst.depth();
+
+    int vector_lengths[4][7] = {{4, 4, 2, 2, 1, 1, 1},
+        {2, 2, 1, 1, 1, 1, 1},
+        {4, 4, 2, 2 , 1, 1, 1},
+        {1, 1, 1, 1, 1, 1, 1}
+    };
+
+    size_t vector_length = vector_lengths[channels-1][depth];
+    int offset_cols = ((dst.offset % dst.step) / dst.elemSize()) & (vector_length - 1);
+    int cols = divUp(dst.cols + offset_cols, vector_length);
+
+    size_t localThreads[3]  = { 64, 4, 1 };
+    size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                divUp(dst.rows, localThreads[1]) * localThreads[1],
+                                1
+                              };
+
+    int dst_step1 = dst.cols * dst.elemSize();
+    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_int), (void *)&src1.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src1.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&src2.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src2.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src2.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&mask.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&mask.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&mask.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.offset ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src1.rows ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&cols ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst_step1 ));
+
+    openCLExecuteKernel(clCxt, kernelString, kernelName, globalThreads, localThreads, args, channels, depth);
+}
+
+
+template <typename WT ,typename CL_WT>
+void bitwise_scalar_run(const oclMat &src1, const Scalar &src2, oclMat &dst, const oclMat &mask, string kernelName, const char **kernelString, int isMatSubScalar)
+{
+    dst.create(src1.size(), src1.type());
+
+    CV_Assert(src1.cols == dst.cols && src1.rows == dst.rows &&
+              src1.type() == dst.type());
+
+
+    if(mask.data)
+        CV_Assert(mask.type() == CV_8U && src1.rows == mask.rows && src1.cols == mask.cols);
+
+    Context  *clCxt = src1.clCxt;
+    int channels = dst.channels();
+    int depth = dst.depth();
+
+    WT s[4] = { saturate_cast<WT>(src2.val[0]), saturate_cast<WT>(src2.val[1]),
+                saturate_cast<WT>(src2.val[2]), saturate_cast<WT>(src2.val[3])
+              };
+
+    int vector_lengths[4][7] = {{4, 4, 2, 2, 1, 1, 1},
+        {2, 2, 1, 1, 1, 1, 1},
+        {4, 4, 2, 2 , 1, 1, 1},
+        {1, 1, 1, 1, 1, 1, 1}
+    };
+
+    size_t vector_length = vector_lengths[channels-1][depth];
+    int offset_cols = ((dst.offset % dst.step) / dst.elemSize()) & (vector_length - 1);
+    int cols = divUp(dst.cols + offset_cols, vector_length);
+
+    size_t localThreads[3]  = { 64, 4, 1 };
+    size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                divUp(dst.rows, localThreads[1]) * localThreads[1],
+                                1
+                              };
+
+    int dst_step1 = dst.cols * dst.elemSize();
+    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_int) , (void *)&src1.step ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&src1.offset));
+    args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst.data ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.step ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.offset));
+
+    if(mask.data)
+    {
+        args.push_back( make_pair( sizeof(cl_mem) , (void *)&mask.data ));
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&mask.step ));
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&mask.offset));
+    }
+    args.push_back( make_pair( sizeof(CL_WT) , (void *)&s ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&src1.rows ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&cols ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_step1 ));
+    if(isMatSubScalar != 0)
+    {
+        isMatSubScalar = isMatSubScalar > 0 ? 1 : 0;
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&isMatSubScalar));
+    }
+
+    openCLExecuteKernel(clCxt, kernelString, kernelName, globalThreads, localThreads, args, channels, depth);
+}
+
+
+typedef void (*BitwiseFuncS)(const oclMat &src1, const Scalar &src2, oclMat &dst, const oclMat &mask, string kernelName, const char **kernelString, int isMatSubScalar);
+
+
+void bitwise_scalar(const oclMat &src1, const Scalar &src2, oclMat &dst, const oclMat &mask, string kernelName, const char **kernelString, int isMatSubScalar)
+{
+    static BitwiseFuncS tab[8] =
+    {
+#if 0
+        bitwise_scalar_run<unsigned char>,
+        bitwise_scalar_run<char>,
+        bitwise_scalar_run<unsigned short>,
+        bitwise_scalar_run<short>,
+        bitwise_scalar_run<int>,
+        bitwise_scalar_run<float>,
+        bitwise_scalar_run<double>,
+        0
+#else
+
+        bitwise_scalar_run<unsigned char,cl_uchar4>,
+        bitwise_scalar_run<char,cl_char4>,
+        bitwise_scalar_run<unsigned short,cl_ushort4>,
+        bitwise_scalar_run<short,cl_short4>,
+        bitwise_scalar_run<int,cl_int4>,
+        bitwise_scalar_run<float,cl_float4>,
+        bitwise_scalar_run<double,cl_double4>,
+        0
+#endif
+    };
+    BitwiseFuncS func = tab[src1.depth()];
+    if(func == 0)
+        cv::ocl::error("Unsupported arithmetic operation", __FILE__, __LINE__);
+    func(src1, src2, dst, mask, kernelName, kernelString, isMatSubScalar);
+}
+void bitwise_scalar(const oclMat &src1, const Scalar &src2, oclMat &dst, const oclMat &mask, string kernelName, const char **kernelString)
+{
+    bitwise_scalar(src1, src2, dst, mask, kernelName, kernelString, 0);
+}
+
+void cv::ocl::bitwise_not(const oclMat &src, oclMat &dst)
+{
+    if(src.clCxt -> impl -> double_support ==0)
+    {
+        cout << "Selected device do not support double" << endl;
+        return;
+    }
+    dst.create(src.size(), src.type());
+    string kernelName =  "arithm_bitwise_not";
+    bitwise_run(src, dst, kernelName, &arithm_bitwise_not);
+}
+
+void cv::ocl::bitwise_or(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask)
+{
+    // dst.create(src1.size(),src1.type());
+    if(src1.clCxt -> impl -> double_support ==0)
+    {
+        cout << "Selected device do not support double" << endl;
+        return;
+    }
+    oclMat emptyMat;
+    string kernelName = mask.empty() ? "arithm_bitwise_or" : "arithm_bitwise_or_with_mask";
+    if (mask.empty())
+        bitwise_run(src1, src2, dst, kernelName, &arithm_bitwise_or);
+    else
+        bitwise_run(src1, src2, dst, mask, kernelName, &arithm_bitwise_or_mask);
+}
+
+
+void cv::ocl::bitwise_or(const oclMat &src1, const Scalar &src2, oclMat &dst, const oclMat &mask)
+{
+    if(src1.clCxt -> impl -> double_support ==0)
+    {
+        cout << "Selected device do not support double" << endl;
+        return;
+    }
+    string kernelName = mask.data ? "arithm_s_bitwise_or_with_mask" : "arithm_s_bitwise_or";
+    if (mask.data)
+        bitwise_scalar( src1, src2, dst, mask, kernelName, &arithm_bitwise_or_scalar_mask);
+    else
+        bitwise_scalar( src1, src2, dst, mask, kernelName, &arithm_bitwise_or_scalar);
+}
+
+void cv::ocl::bitwise_and(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask)
+{
+    //    dst.create(src1.size(),src1.type());
+    if(src1.clCxt -> impl -> double_support ==0)
+    {
+        cout << "Selected device do not support double" << endl;
+        return;
+    }
+    oclMat emptyMat;
+
+    string kernelName = mask.empty() ? "arithm_bitwise_and" : "arithm_bitwise_and_with_mask";
+
+    if (mask.empty())
+        bitwise_run(src1, src2, dst, kernelName, &arithm_bitwise_and);
+    else
+        bitwise_run(src1, src2, dst, mask, kernelName, &arithm_bitwise_and_mask);
+}
+
+void cv::ocl::bitwise_and(const oclMat &src1, const Scalar &src2, oclMat &dst, const oclMat &mask)
+{
+    if(src1.clCxt -> impl -> double_support ==0)
+    {
+        cout << "Selected device do not support double" << endl;
+        return;
+    }
+    string kernelName = mask.data ? "arithm_s_bitwise_and_with_mask" : "arithm_s_bitwise_and";
+    if (mask.data)
+        bitwise_scalar(src1, src2, dst, mask, kernelName, &arithm_bitwise_and_scalar_mask);
+    else
+        bitwise_scalar(src1, src2, dst, mask, kernelName, &arithm_bitwise_and_scalar);
+}
+
+void cv::ocl::bitwise_xor(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask)
+{
+    if(src1.clCxt -> impl -> double_support ==0)
+    {
+        cout << "Selected device do not support double" << endl;
+        return;
+    }
+    oclMat emptyMat;
+    string kernelName = mask.empty() ? "arithm_bitwise_xor" : "arithm_bitwise_xor_with_mask";
+
+
+    if (mask.empty())
+        bitwise_run(src1, src2, dst, kernelName, &arithm_bitwise_xor);
+    else
+        bitwise_run(src1, src2, dst, mask, kernelName, &arithm_bitwise_xor_mask);
+}
+
+
+void cv::ocl::bitwise_xor(const oclMat &src1, const Scalar &src2, oclMat &dst, const oclMat &mask)
+{
+
+    if(src1.clCxt -> impl -> double_support ==0)
+    {
+        cout << "Selected device do not support double" << endl;
+        return;
+    }
+    string kernelName = mask.data ? "arithm_s_bitwise_xor_with_mask" : "arithm_s_bitwise_xor";
+    if (mask.data)
+        bitwise_scalar( src1, src2, dst, mask, kernelName, &arithm_bitwise_xor_scalar_mask);
+    else
+        bitwise_scalar( src1, src2, dst, mask, kernelName, &arithm_bitwise_xor_scalar);
+}
+
+cv::ocl::oclMat cv::ocl::operator ~ (const oclMat &src)
+{
+    oclMat dst;
+    bitwise_not(src, dst);
+    return dst;
+}
+
+cv::ocl::oclMat cv::ocl::operator | (const oclMat &src1, const oclMat &src2)
+{
+    oclMat dst;
+    bitwise_or(src1, src2, dst);
+    return dst;
+}
+
+cv::ocl::oclMat cv::ocl::operator & (const oclMat &src1, const oclMat &src2)
+{
+    oclMat dst;
+    bitwise_and(src1, src2, dst);
+    return dst;
+}
+
+cv::ocl::oclMat cv::ocl::operator ^ (const oclMat &src1, const oclMat &src2)
+{
+    oclMat dst;
+    bitwise_xor(src1, src2, dst);
+    return dst;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+/////////////////////////////// transpose ////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+#define TILE_DIM      (32)
+#define BLOCK_ROWS    (256/TILE_DIM)
+void transpose_run(const oclMat &src, oclMat &dst, string kernelName)
+{
+    if(src.clCxt -> impl -> double_support ==0 && src.type() == CV_64F)
+    {
+        CV_Error(-217,"Selected device don't support double\r\n");
+        return;
+    }
+
+    CV_Assert(src.cols == dst.rows && src.rows == dst.cols);
+
+    Context  *clCxt = src.clCxt;
+    int channels = src.channels();
+    int depth = src.depth();
+
+    int vector_lengths[4][7] = {{1, 0, 0, 0, 1, 1, 0},
+        {0, 0, 1, 1, 0, 0, 0},
+        {0, 0, 0, 0 , 0, 0, 0},
+        {1, 1, 0, 0, 0, 0, 0}
+    };
+
+    size_t vector_length = vector_lengths[channels-1][depth];
+    int offset_cols = ((dst.offset % dst.step) / dst.elemSize()) & (vector_length - 1);
+    int cols = divUp(src.cols + offset_cols, vector_length);
+
+    size_t localThreads[3]  = { TILE_DIM, BLOCK_ROWS, 1 };
+    size_t globalThreads[3] = { divUp(cols, TILE_DIM) * localThreads[0],
+                                divUp(src.rows, TILE_DIM) * localThreads[1],
+                                1
+                              };
+
+    vector<pair<size_t , const void *> > args;
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&src.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.offset ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src.rows ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&cols ));
+
+    openCLExecuteKernel(clCxt, &arithm_transpose, kernelName, globalThreads, localThreads, args, channels, depth);
+}
+
+void cv::ocl::transpose(const oclMat &src, oclMat &dst)
+{
+    CV_Assert(src.type() == CV_8UC1  || src.type() == CV_8UC4  || src.type() == CV_8SC4  ||
+              src.type() == CV_16UC2 || src.type() == CV_16SC2 || src.type() == CV_32SC1 || src.type() == CV_32FC1);
+
+    stringstream idxstr;
+    oclMat emptyMat;
+
+    if( src.data == dst.data && dst.cols == dst.rows )
+        transpose_run( src, emptyMat, "transposeI_");
+    else
+    {
+        dst.create(src.cols, src.rows, src.type());
+        transpose_run( src, dst, "transpose");
+    }
+}
+
+void cv::ocl::addWeighted(const oclMat &src1, double alpha, const oclMat &src2, double beta, double gama, oclMat &dst)
+{
+    dst.create(src1.size(), src1.type());
+    CV_Assert(src1.cols ==  src2.cols && src2.cols == dst.cols &&
+              src1.rows ==  src2.rows && src2.rows == dst.rows);
+    CV_Assert(src1.type() == src2.type() && src1.type() == dst.type());
+
+    Context *clCxt = src1.clCxt;
+    int channels = dst.channels();
+    int depth = dst.depth();
+
+
+    int vector_lengths[4][7] = {{4, 0, 4, 4, 4, 4, 4},
+        {4, 0, 4, 4, 4, 4, 4},
+        {4, 0, 4, 4, 4, 4, 4},
+        {4, 0, 4, 4, 4, 4, 4}
+    };
+
+
+    size_t vector_length = vector_lengths[channels-1][depth];
+    int offset_cols = (dst.offset / dst.elemSize1()) & (vector_length - 1);
+    int cols = divUp(dst.cols * channels + offset_cols, vector_length);
+
+    size_t localThreads[3]  = { 256, 1, 1 };
+    size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                divUp(dst.rows, localThreads[1]) * localThreads[1],
+                                1
+                              };
+
+    int dst_step1 = dst.cols * dst.elemSize();
+    vector<pair<size_t , const void *> > args;
+    if(sizeof(double) == 8)
+    {
+        args.push_back( make_pair( sizeof(cl_mem), (void *)&src1.data ));
+        args.push_back( make_pair( sizeof(cl_double), (void *)&alpha ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&src1.step ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&src1.offset));
+        args.push_back( make_pair( sizeof(cl_mem), (void *)&src2.data ));
+        args.push_back( make_pair( sizeof(cl_double), (void *)&beta ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&src2.step ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&src2.offset));
+        args.push_back( make_pair( sizeof(cl_double), (void *)&gama ));
+        args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&dst.step ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&dst.offset));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&src1.rows ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&cols ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&dst_step1 ));
+    }
+    else
+    {
+
+        args.push_back( make_pair( sizeof(cl_mem), (void *)&src1.data ));
+        args.push_back( make_pair( sizeof(cl_float), (void *)&alpha ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&src1.step ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&src1.offset));
+        args.push_back( make_pair( sizeof(cl_mem), (void *)&src2.data ));
+        args.push_back( make_pair( sizeof(cl_float), (void *)&beta ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&src2.step ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&src2.offset));
+        args.push_back( make_pair( sizeof(cl_float), (void *)&gama ));
+        args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&dst.step ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&dst.offset));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&src1.rows ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&cols ));
+        args.push_back( make_pair( sizeof(cl_int), (void *)&dst_step1 ));
+    }
+    openCLExecuteKernel(clCxt, &arithm_addWeighted, "addWeighted", globalThreads, localThreads, args, -1, depth);
+}
+
+void cv::ocl::magnitudeSqr(const oclMat &src1, const oclMat &src2, oclMat &dst)
+{
+    CV_Assert(src1.type() == src2.type() && src1.size() == src2.size() &&
+              (src1.depth() == CV_32F ));
+
+    dst.create(src1.size(), src1.type());
+
+
+    Context *clCxt = src1.clCxt;
+    int channels = dst.channels();
+    int depth = dst.depth();
+
+
+    int vector_lengths[4][7] = {{4, 0, 4, 4, 4, 4, 4},
+        {4, 0, 4, 4, 4, 4, 4},
+        {4, 0, 4, 4, 4, 4, 4},
+        {4, 0, 4, 4, 4, 4, 4}
+    };
+
+
+    size_t vector_length = vector_lengths[channels-1][depth];
+    int offset_cols = (dst.offset / dst.elemSize1()) & (vector_length - 1);
+    int cols = divUp(dst.cols * channels + offset_cols, vector_length);
+
+    size_t localThreads[3]  = { 256, 1, 1 };
+    size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                divUp(dst.rows, localThreads[1]) * localThreads[1],
+                                1
+                              };
+
+    int dst_step1 = dst.cols * dst.elemSize();
+    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_int), (void *)&src1.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src1.offset));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&src2.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src2.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src2.offset));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.offset));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src1.rows ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&cols ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst_step1 ));
+
+    openCLExecuteKernel(clCxt, &arithm_magnitudeSqr, "magnitudeSqr", globalThreads, localThreads, args, 1, depth);
+}
+
+void cv::ocl::magnitudeSqr(const oclMat &src1, oclMat &dst)
+{
+    CV_Assert (src1.depth() == CV_32F );
+    CV_Assert(src1.size() == dst.size());
+
+    dst.create(src1.size(), CV_32FC1);
+
+
+    Context *clCxt = src1.clCxt;
+    int channels = dst.channels();
+    int depth = dst.depth();
+
+
+    int vector_lengths[4][7] = {{4, 0, 4, 4, 4, 4, 4},
+        {4, 0, 4, 4, 4, 4, 4},
+        {4, 0, 4, 4, 4, 4, 4},
+        {4, 0, 4, 4, 4, 4, 4}
+    };
+
+
+    size_t vector_length = vector_lengths[channels-1][depth];
+    int offset_cols = (dst.offset / dst.elemSize1()) & (vector_length - 1);
+    int cols = divUp(dst.cols * channels + offset_cols, vector_length);
+
+    size_t localThreads[3]  = { 256, 1, 1 };
+    size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                divUp(dst.rows, localThreads[1]) * localThreads[1],
+                                1
+                              };
+
+    int dst_step1 = dst.cols * dst.elemSize();
+    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_int), (void *)&src1.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src1.offset));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.offset));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src1.rows ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&cols ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst_step1 ));
+
+    openCLExecuteKernel(clCxt, &arithm_magnitudeSqr, "magnitudeSqr", globalThreads, localThreads, args, 2, depth);
+}
+
+void arithmetic_pow_run(const oclMat &src1, double p, oclMat &dst, string kernelName, const char **kernelString)
+{
+    CV_Assert(src1.cols == dst.cols && src1.rows == dst.rows);
+    CV_Assert(src1.type() == dst.type());
+
+    Context  *clCxt = src1.clCxt;
+    int channels = dst.channels();
+    int depth = dst.depth();
+
+    size_t vector_length = 1;
+    int offset_cols = ((dst.offset % dst.step) / dst.elemSize1()) & (vector_length - 1);
+    int cols = divUp(dst.cols * channels + offset_cols, vector_length);
+    int rows = dst.rows;
+
+    size_t localThreads[3]  = { 64, 4, 1 };
+    size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                divUp(rows, localThreads[1]) * localThreads[1],
+                                1
+                              };
+
+    int dst_step1 = dst.cols * dst.elemSize();
+    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_int), (void *)&src1.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src1.offset ));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.step ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.offset ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.rows ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&cols ));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst_step1 ));
+    args.push_back( make_pair( sizeof(cl_double), (void *)&p ));
+
+    openCLExecuteKernel(clCxt, kernelString, kernelName, globalThreads, localThreads, args, -1, depth);
+}
+void cv::ocl::pow(const oclMat &x, double p, oclMat &y)
+{
+    if(x.clCxt -> impl -> double_support ==0)
+    {
+        cout << "Selected device do not support double" << endl;
+        return;
+    }
+
+    CV_Assert(x.type() == y.type() && x.size() == y.size() && x.depth() == CV_32F || x.depth() == CV_64F);
+    y.create(x.size(), x.type());
+    string kernelName = "arithm_pow";
+
+    arithmetic_pow_run(x, p, y, kernelName, &arithm_pow);
+}
+#endif /* !defined (HAVE_OPENCL) */
diff --git a/modules/ocl/src/binarycaching.hpp b/modules/ocl/src/binarycaching.hpp
new file mode 100644 (file)
index 0000000..4794878
--- /dev/null
@@ -0,0 +1,102 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//
+// 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"
+
+using namespace cv;
+using namespace cv::ocl;
+using namespace std;
+using std::cout;
+using std::endl;
+
+#if !defined (HAVE_OPENCL)
+namespace cv
+{
+    namespace ocl
+    {
+        //nothing
+    }//namespace ocl
+}//namespace cv
+
+#else /* !defined (HAVE_OPENCL) */
+
+namespace cv
+{
+    namespace ocl
+    {
+        class ProgramCache
+        {
+        protected:
+            ProgramCache();
+            friend class auto_ptr<ProgramCache>;
+            static auto_ptr<ProgramCache> programCache;
+
+        public:
+            ~ProgramCache();
+            static ProgramCache *getProgramCache()
+            {
+                if( NULL == programCache.get())
+                    programCache.reset(new ProgramCache());
+                return programCache.get();
+            }
+
+            //lookup the binary given the file name
+            cl_program progLookup(string srcsign);
+
+            //add program to the cache
+            void addProgram(string srcsign, cl_program program);
+            void releaseProgram();
+
+            map <string, cl_program> codeCache;
+            unsigned int cacheSize;
+            //The presumed watermark for the cache volume (256MB). Is it enough?
+            //We may need more delicate algorithms when necessary later.
+            //Right now, let's just leave it along.
+            static const unsigned MAX_PROG_CACHE_SIZE = 1024;
+        };
+
+    }//namespace ocl
+
+}//namespace cv
+#endif
diff --git a/modules/ocl/src/color.cpp b/modules/ocl/src/color.cpp
new file mode 100644 (file)
index 0000000..bee370f
--- /dev/null
@@ -0,0 +1,153 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Wang Weiyan, wangweiyanster@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 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"
+
+using namespace cv;
+using namespace cv::ocl;
+
+#if !defined (HAVE_OPENCL)
+
+void cv::ocl::cvtColor(const oclMat &, oclMat &, int, int)
+{
+    throw_nogpu();
+}
+void cv::ocl::cvtColor(const oclMat &, oclMat &, int, int, const Stream &)
+{
+    throw_nogpu();
+}
+
+#else /* !defined (HAVE_OPENCL) */
+#ifndef CV_DESCALE
+#define CV_DESCALE(x, n) (((x) + (1 << ((n)-1))) >> (n))
+#endif
+
+#ifndef FLT_EPSILON
+#define FLT_EPSILON     1.192092896e-07F
+#endif
+
+namespace cv
+{
+    namespace ocl
+    {
+        extern const char *cvt_color;
+    }
+}
+
+namespace
+{
+    void RGB2Gray_caller(const oclMat &src, oclMat &dst, int bidx)
+    {
+        vector<pair<size_t , const void *> > args;
+        int channels = src.channels();
+        char build_options[50];
+        //printf("depth:%d,channels:%d,bidx:%d\n",src.depth(),src.channels(),bidx);
+        sprintf(build_options, "-D DEPTH_%d", src.depth());
+        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 *)&src.step));
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.step));
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&channels));
+        args.push_back( make_pair( sizeof(cl_int) , (void *)&bidx));
+        args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data));
+        args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst.data));
+        size_t gt[3] = {src.cols, src.rows, 1}, lt[3] = {16, 16, 1};
+        openCLExecuteKernel(src.clCxt, &cvt_color, "RGB2Gray", gt, lt, args, -1, -1, build_options);
+    }
+    void cvtColor_caller(const oclMat &src, oclMat &dst, int code, int dcn)
+    {
+        Size sz = src.size();
+        int scn = src.channels(), depth = src.depth(), bidx;
+
+        CV_Assert(depth == CV_8U || depth == CV_16U);
+
+        switch (code)
+        {
+            /*
+            case CV_BGR2BGRA: case CV_RGB2BGRA: case CV_BGRA2BGR:
+            case CV_RGBA2BGR: case CV_RGB2BGR: case CV_BGRA2RGBA:
+            case CV_BGR2BGR565: case CV_BGR2BGR555: case CV_RGB2BGR565: case CV_RGB2BGR555:
+            case CV_BGRA2BGR565: case CV_BGRA2BGR555: case CV_RGBA2BGR565: case CV_RGBA2BGR555:
+            case CV_BGR5652BGR: case CV_BGR5552BGR: case CV_BGR5652RGB: case CV_BGR5552RGB:
+            case CV_BGR5652BGRA: case CV_BGR5552BGRA: case CV_BGR5652RGBA: case CV_BGR5552RGBA:
+            */
+        case CV_BGR2GRAY:
+        case CV_BGRA2GRAY:
+        case CV_RGB2GRAY:
+        case CV_RGBA2GRAY:
+        {
+            CV_Assert(scn == 3 || scn == 4);
+            bidx = code == CV_BGR2GRAY || code == CV_BGRA2GRAY ? 0 : 2;
+            dst.create(sz, CV_MAKETYPE(depth, 1));
+            RGB2Gray_caller(src, dst, bidx);
+            break;
+        }
+        /*
+        case CV_BGR5652GRAY: case CV_BGR5552GRAY:
+        case CV_GRAY2BGR: case CV_GRAY2BGRA:
+        case CV_GRAY2BGR565: case CV_GRAY2BGR555:
+        case CV_BGR2YCrCb: case CV_RGB2YCrCb:
+        case CV_BGR2YUV: case CV_RGB2YUV:
+        case CV_YCrCb2BGR: case CV_YCrCb2RGB:
+        case CV_YUV2BGR: case CV_YUV2RGB:
+        case CV_BGR2XYZ: case CV_RGB2XYZ:
+        case CV_XYZ2BGR: case CV_XYZ2RGB:
+        case CV_BGR2HSV: case CV_RGB2HSV: case CV_BGR2HSV_FULL: case CV_RGB2HSV_FULL:
+        case CV_BGR2HLS: case CV_RGB2HLS: case CV_BGR2HLS_FULL: case CV_RGB2HLS_FULL:
+        case CV_HSV2BGR: case CV_HSV2RGB: case CV_HSV2BGR_FULL: case CV_HSV2RGB_FULL:
+        case CV_HLS2BGR: case CV_HLS2RGB: case CV_HLS2BGR_FULL: case CV_HLS2RGB_FULL:
+        */
+        default:
+            CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" );
+        }
+    }
+}
+
+void cv::ocl::cvtColor(const oclMat &src, oclMat &dst, int code, int dcn)
+{
+    cvtColor_caller(src, dst, code, dcn);
+}
+
+#endif /* !defined (HAVE_OPENCL) */
diff --git a/modules/ocl/src/error.cpp b/modules/ocl/src/error.cpp
new file mode 100644 (file)
index 0000000..007c013
--- /dev/null
@@ -0,0 +1,198 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//
+// 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"
+
+using namespace cv;
+using namespace cv::ocl;
+
+#if !defined (HAVE_OPENCL)
+
+// do nothing
+
+#else /* !defined (HAVE_OPENCL) */
+
+namespace cv
+{
+    namespace ocl
+    {
+
+        const char *getOpenCLErrorString( int err )
+        {
+            switch(err)
+            {
+            case CL_DEVICE_NOT_FOUND:
+                return "CL_DEVICE_NOT_FOUND";
+            case CL_DEVICE_NOT_AVAILABLE:
+                return "CL_DEVICE_NOT_AVAILABLE";
+            case CL_COMPILER_NOT_AVAILABLE:
+                return "CL_COMPILER_NOT_AVAILABLE";
+            case CL_MEM_OBJECT_ALLOCATION_FAILURE:
+                return "CL_MEM_OBJECT_ALLOCATION_FAILURE";
+            case CL_OUT_OF_RESOURCES:
+                return "CL_OUT_OF_RESOURCES";
+            case CL_OUT_OF_HOST_MEMORY:
+                return "CL_OUT_OF_HOST_MEMORY";
+            case CL_PROFILING_INFO_NOT_AVAILABLE:
+                return "CL_PROFILING_INFO_NOT_AVAILABLE";
+            case CL_MEM_COPY_OVERLAP:
+                return "CL_MEM_COPY_OVERLAP";
+            case CL_IMAGE_FORMAT_MISMATCH:
+                return "CL_IMAGE_FORMAT_MISMATCH";
+            case CL_IMAGE_FORMAT_NOT_SUPPORTED:
+                return "CL_IMAGE_FORMAT_NOT_SUPPORTED";
+            case CL_BUILD_PROGRAM_FAILURE:
+                return "CL_BUILD_PROGRAM_FAILURE";
+            case CL_MAP_FAILURE:
+                return "CL_MAP_FAILURE";
+            case CL_MISALIGNED_SUB_BUFFER_OFFSET:
+                return "CL_MISALIGNED_SUB_BUFFER_OFFSET";
+            case CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST:
+                return "CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST";
+            case CL_INVALID_VALUE:
+                return "CL_INVALID_VALUE";
+            case CL_INVALID_DEVICE_TYPE:
+                return "CL_INVALID_DEVICE_TYPE";
+            case CL_INVALID_PLATFORM:
+                return "CL_INVALID_PLATFORM";
+            case CL_INVALID_DEVICE:
+                return "CL_INVALID_DEVICE";
+            case CL_INVALID_CONTEXT:
+                return "CL_INVALID_CONTEXT";
+            case CL_INVALID_QUEUE_PROPERTIES:
+                return "CL_INVALID_QUEUE_PROPERTIES";
+            case CL_INVALID_COMMAND_QUEUE:
+                return "CL_INVALID_COMMAND_QUEUE";
+            case CL_INVALID_HOST_PTR:
+                return "CL_INVALID_HOST_PTR";
+            case CL_INVALID_MEM_OBJECT:
+                return "CL_INVALID_MEM_OBJECT";
+            case CL_INVALID_IMAGE_FORMAT_DESCRIPTOR:
+                return "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR";
+            case CL_INVALID_IMAGE_SIZE:
+                return "CL_INVALID_IMAGE_SIZE";
+            case CL_INVALID_SAMPLER:
+                return "CL_INVALID_SAMPLER";
+            case CL_INVALID_BINARY:
+                return "CL_INVALID_BINARY";
+            case CL_INVALID_BUILD_OPTIONS:
+                return "CL_INVALID_BUILD_OPTIONS";
+            case CL_INVALID_PROGRAM:
+                return "CL_INVALID_PROGRAM";
+            case CL_INVALID_PROGRAM_EXECUTABLE:
+                return "CL_INVALID_PROGRAM_EXECUTABLE";
+            case CL_INVALID_KERNEL_NAME:
+                return "CL_INVALID_KERNEL_NAME";
+            case CL_INVALID_KERNEL_DEFINITION:
+                return "CL_INVALID_KERNEL_DEFINITION";
+            case CL_INVALID_KERNEL:
+                return "CL_INVALID_KERNEL";
+            case CL_INVALID_ARG_INDEX:
+                return "CL_INVALID_ARG_INDEX";
+            case CL_INVALID_ARG_VALUE:
+                return "CL_INVALID_ARG_VALUE";
+            case CL_INVALID_ARG_SIZE:
+                return "CL_INVALID_ARG_SIZE";
+            case CL_INVALID_KERNEL_ARGS:
+                return "CL_INVALID_KERNEL_ARGS";
+            case CL_INVALID_WORK_DIMENSION:
+                return "CL_INVALID_WORK_DIMENSION";
+            case CL_INVALID_WORK_GROUP_SIZE:
+                return "CL_INVALID_WORK_GROUP_SIZE";
+            case CL_INVALID_WORK_ITEM_SIZE:
+                return "CL_INVALID_WORK_ITEM_SIZE";
+            case CL_INVALID_GLOBAL_OFFSET:
+                return "CL_INVALID_GLOBAL_OFFSET";
+            case CL_INVALID_EVENT_WAIT_LIST:
+                return "CL_INVALID_EVENT_WAIT_LIST";
+            case CL_INVALID_EVENT:
+                return "CL_INVALID_EVENT";
+            case CL_INVALID_OPERATION:
+                return "CL_INVALID_OPERATION";
+            case CL_INVALID_GL_OBJECT:
+                return "CL_INVALID_GL_OBJECT";
+            case CL_INVALID_BUFFER_SIZE:
+                return "CL_INVALID_BUFFER_SIZE";
+            case CL_INVALID_MIP_LEVEL:
+                return "CL_INVALID_MIP_LEVEL";
+            case CL_INVALID_GLOBAL_WORK_SIZE:
+                return "CL_INVALID_GLOBAL_WORK_SIZE";
+                //case CL_INVALID_PROPERTY:
+                //     return "CL_INVALID_PROPERTY";
+                //case CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR:
+                //     return "CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR";
+                //case CL_PLATFORM_NOT_FOUND_KHR:
+                //     return "CL_PLATFORM_NOT_FOUND_KHR";
+                //     //case CL_INVALID_PROPERTY_EXT:
+                //     //    return "CL_INVALID_PROPERTY_EXT";
+                //case CL_DEVICE_PARTITION_FAILED_EXT:
+                //     return "CL_DEVICE_PARTITION_FAILED_EXT";
+                //case CL_INVALID_PARTITION_COUNT_EXT:
+                //     return "CL_INVALID_PARTITION_COUNT_EXT";
+                //default:
+                //     return "unknown error code";
+            }
+            static char buf[256];
+            sprintf(buf, "%d", err);
+            return buf;
+        }
+
+        void error(const char *error_string, const char *file, const int line, const char *func)
+        {
+            int code = CV_GpuApiCallError;
+
+            if (std::uncaught_exception())
+            {
+                const char *errorStr = cvErrorStr(code);
+                const char *function = func ? func : "unknown function";
+
+                std::cerr << "OpenCV Error: " << errorStr << "(" << error_string << ") in " << function << ", file " << file << ", line " << line;
+                std::cerr.flush();
+            }
+            else
+                cv::error( cv::Exception(code, error_string, func, file, line) );
+        }
+    }
+}
+
+#endif
diff --git a/modules/ocl/src/filtering.cpp b/modules/ocl/src/filtering.cpp
new file mode 100644 (file)
index 0000000..ea7f312
--- /dev/null
@@ -0,0 +1,1514 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Niko Li, newlife20080214@gmail.com
+//    Jia Haipeng, jiahaipeng95@gmail.com
+//    Zero Lin, Zero.Lin@amd.com
+//    Zhang Ying, zhangying913@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 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 <iostream>
+using namespace std;
+using namespace cv;
+using namespace cv::ocl;
+
+#if !defined (HAVE_OPENCL)
+
+Ptr<BaseFilter_GPU> cv::ocl::getBoxFilter_GPU(int, int, const Size &, Point, int)
+{
+    throw_nogpu();
+    return Ptr<BaseFilter_GPU>(0);
+}
+
+Ptr<FilterEngine_GPU> cv::ocl::createBoxFilter_GPU(int, int, const Size &, const Point &, int)
+{
+    throw_nogpu();
+    return Ptr<FilterEngine_GPU>(0);
+}
+
+Ptr<FilterEngine_GPU> cv::ocl::createFilter2D_GPU(const Ptr<BaseFilter_GPU>)
+{
+    throw_nogpu();
+    return Ptr<FilterEngine_GPU>(0);
+}
+
+Ptr<FilterEngine_GPU> cv::ocl::createSeparableLinearFilter_GPU(int, int, const Mat &, const Mat &, const Point &)
+{
+    throw_nogpu();
+    return Ptr<FilterEngine_GPU>(0);
+}
+
+Ptr<BaseRowFilter_GPU> cv::ocl::getLinearRowFilter_GPU(int, int, const Mat &, int)
+{
+    throw_nogpu();
+    return Ptr<BaseRowFilter_GPU>(0);
+}
+
+Ptr<BaseColumnFilter_GPU> cv::ocl::getLinearColumnFilter_GPU(int, int, const Mat &, int)
+{
+    throw_nogpu();
+    return Ptr<BaseColumnFilter_GPU>(0);
+}
+
+Ptr<FilterEngine_GPU> cv::ocl::createGaussianFilter_GPU(int, Size, double, double)
+{
+    throw_nogpu();
+    return Ptr<FilterEngine_GPU>(0);
+}
+
+
+Ptr<BaseFilter_GPU> cv::ocl::getLinearFilter_GPU(int, int, const Mat &, const Size &, Point)
+{
+    throw_nogpu();
+    return Ptr<BaseFilter_GPU>(0);
+}
+
+Ptr<FilterEngine_GPU> cv::ocl::createLinearFilter_GPU(int, int, const Mat &, const Point &)
+{
+    throw_nogpu();
+    return Ptr<FilterEngine_GPU>(0);
+}
+
+Ptr<FilterEngine_GPU> cv::ocl::createDerivFilter_GPU( int srcType, int dstType, int dx, int dy, int ksize, int borderType )
+{ 
+       throw_nogpu(); 
+       return Ptr<FilterEngine_GPU>(0);
+}
+
+void cv::ocl::boxFilter(const oclMat &, oclMat &, int, Size, Point, int)
+{
+    throw_nogpu();
+}
+
+void cv::ocl::sepFilter2D(const oclMat &, oclMat &, int, const Mat &, const Mat &, Point)
+{
+    throw_nogpu();
+}
+
+void cv::ocl::Sobel(const oclMat &, oclMat &, int, int, int, int, double)
+{
+    throw_nogpu();
+}
+
+void cv::ocl::Scharr(const oclMat &, oclMat &, int, int, int, double)
+{
+    throw_nogpu();
+}
+
+void cv::ocl::GaussianBlur(const oclMat &, oclMat &, Size, double, double)
+{
+    throw_nogpu();
+}
+
+void cv::ocl::filter2D(const oclMat &, oclMat &, int, const Mat &, Point)
+{
+    throw_nogpu();
+}
+
+void cv::ocl::Laplacian(const oclMat &, oclMat &, int, int, double)
+{
+    throw_nogpu();
+}
+
+void cv::ocl::erode( const oclMat &, oclMat &, const Mat &, Point, int)
+{
+    throw_nogpu();
+}
+
+void cv::ocl::dilate( const oclMat &, oclMat &, const Mat &, Point, int)
+{
+    throw_nogpu();
+}
+
+void cv::ocl::morphologyEx( const oclMat &, oclMat &, int, const Mat &, Point, int)
+{
+    throw_nogpu();
+}
+
+#else /* !defined (HAVE_OPENCL) */
+
+//helper routines
+namespace cv
+{
+    namespace ocl
+    {
+        ///////////////////////////OpenCL kernel strings///////////////////////////
+        extern const char *filtering_boxFilter;
+        extern const char *filter_sep_row;
+        extern const char *filter_sep_col;
+        extern const char *filtering_laplacian;
+        extern const char *filtering_erodeFilter;
+        extern const char *filtering_dilateFilter;
+
+    }
+}
+
+namespace
+{
+    inline int divUp(int total, int grain)
+    {
+        return (total + grain - 1) / grain;
+    }
+}
+
+namespace
+{
+    inline void normalizeAnchor(int &anchor, int ksize)
+    {
+        if (anchor < 0)
+            anchor = ksize >> 1;
+
+        CV_Assert(0 <= anchor && anchor < ksize);
+    }
+
+    inline void normalizeAnchor(Point &anchor, const Size &ksize)
+    {
+        normalizeAnchor(anchor.x, ksize.width);
+        normalizeAnchor(anchor.y, ksize.height);
+    }
+
+    inline void normalizeROI(Rect &roi, const Size &ksize, const Point &anchor, const Size &src_size)
+    {
+        if (roi == Rect(0, 0, -1, -1))
+            roi = Rect(0, 0, src_size.width, src_size.height);
+        CV_Assert(ksize.height > 0 && ksize.width > 0 && ((ksize.height & 1) == 1) && ((ksize.width & 1) == 1));
+        CV_Assert((anchor.x == -1 && anchor.y == -1) || (anchor.x == ksize.width >> 1 && anchor.y == ksize.height >> 1));
+        CV_Assert(roi.x >= 0 && roi.y >= 0 && roi.width <= src_size.width && roi.height <= src_size.height);
+    }
+
+
+    inline void normalizeKernel(const Mat &kernel, oclMat &gpu_krnl, int type = CV_8U, int *nDivisor = 0, bool reverse = false)
+    {
+        int scale = nDivisor && (kernel.depth() == CV_32F || kernel.depth() == CV_64F) ? 256 : 1;
+        if (nDivisor) *nDivisor = scale;
+
+        Mat temp(kernel.size(), type);
+        kernel.convertTo(temp, type, scale);
+        Mat cont_krnl = temp.reshape(1, 1);
+
+        if (reverse)
+        {
+            int count = cont_krnl.cols >> 1;
+            for (int i = 0; i < count; ++i)
+            {
+                std::swap(cont_krnl.at<int>(0, i), cont_krnl.at<int>(0, cont_krnl.cols - 1 - i));
+            }
+        }
+
+        gpu_krnl.upload(cont_krnl);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Filter2D
+namespace
+{
+    class Filter2DEngine_GPU : public FilterEngine_GPU
+    {
+    public:
+        Filter2DEngine_GPU(const Ptr<BaseFilter_GPU>& filter2D_) : filter2D(filter2D_) {}
+
+        virtual void apply(const oclMat &src, oclMat &dst, Rect roi = Rect(0, 0, -1, -1))
+        {
+            Size src_size = src.size();
+
+            // Delete those two clause below which exist before, However, the result is alos correct
+            // dst.create(src_size, src.type());
+            // dst = Scalar(0.0);
+
+            normalizeROI(roi, filter2D->ksize, filter2D->anchor, src_size);
+
+            oclMat srcROI = src(roi);
+            oclMat dstROI = dst(roi);
+
+            (*filter2D)(srcROI, dstROI);
+        }
+
+        Ptr<BaseFilter_GPU> filter2D;
+    };
+}
+
+Ptr<FilterEngine_GPU> cv::ocl::createFilter2D_GPU(const Ptr<BaseFilter_GPU> filter2D)
+{
+    return Ptr<FilterEngine_GPU>(new Filter2DEngine_GPU(filter2D));
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Box Filter
+namespace
+{
+    typedef void (*FilterBox_t)(const oclMat & , oclMat & , Size &, const Point, const int);
+
+    class GPUBoxFilter : public BaseFilter_GPU
+    {
+    public:
+        GPUBoxFilter(const Size &ksize_, const Point &anchor_, const int borderType_, FilterBox_t func_) :
+            BaseFilter_GPU(ksize_, anchor_, borderType_), func(func_) {}
+
+        virtual void operator()(const oclMat &src, oclMat &dst)
+        {
+            func(src, dst, ksize, anchor, borderType);
+        }
+
+        FilterBox_t func;
+
+    };
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Morphology Filter
+
+namespace
+{
+    typedef void (*GPUMorfFilter_t)(const oclMat & , oclMat & , oclMat & , Size &, const Point);
+
+    class MorphFilter_GPU : public BaseFilter_GPU
+    {
+    public:
+        MorphFilter_GPU(const Size &ksize_, const Point &anchor_, const oclMat &kernel_, GPUMorfFilter_t func_) :
+            BaseFilter_GPU(ksize_, anchor_, BORDER_CONSTANT), kernel(kernel_), func(func_) {}
+
+        virtual void operator()(const oclMat &src, oclMat &dst)
+        {
+            func(src, dst, kernel, ksize, anchor) ;
+        }
+
+        oclMat kernel;
+        GPUMorfFilter_t func;
+    };
+}
+
+/*
+**We should be able to support any data types here.
+**Extend this if necessary later.
+**Note that the kernel need to be further refined.
+*/
+void GPUErode(const oclMat &src, oclMat &dst, oclMat &mat_kernel, Size &ksize, const Point anchor)
+{
+    //Normalize the result by default
+    //float alpha = ksize.height * ksize.width;
+    CV_Assert(src.clCxt == dst.clCxt);
+    CV_Assert( (src.cols == dst.cols) &&
+               (src.rows == dst.rows) );
+    CV_Assert( (src.channels() == dst.channels()) );
+
+    int srcStep = src.step1() / src.channels();
+    int dstStep = dst.step1() / dst.channels();
+    int srcOffset = src.offset / src.channels() / src.elemSize1();
+    int dstOffset = dst.offset / dst.channels() / dst.elemSize1();
+    int minclos = -(srcOffset % srcStep);
+    int maxclos = src.wholecols + minclos - 1;
+    int minrows = -(srcOffset / srcStep);
+    int maxrows = src.wholerows + minrows - 1;
+
+    //int D=src.depth();
+
+    Context *clCxt = src.clCxt;
+
+    string kernelName = "erode";
+
+    vector< pair<size_t, const void *> > args;
+    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 *)&srcOffset));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dstOffset));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&minclos));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&maxclos));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&minrows));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&maxrows));
+    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 *)&srcStep));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dstStep));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_kernel.data));
+       args.push_back( make_pair( sizeof(cl_int),(void*)&src.wholecols));
+       args.push_back( make_pair( sizeof(cl_int),(void*)&src.wholerows));
+    //args.push_back( make_pair( sizeof(cl_int),(void*)&ksize.width));
+    //args.push_back( make_pair( sizeof(cl_int),(void*)&ksize.height));
+
+    size_t globalThreads[3] = {(src.cols + 15) / 16 * 16, (src.rows + 15) / 16 * 16, 1};
+    if(src.channels() == 1)
+        globalThreads[0] = ((src.cols + 9) / 4 + 15) / 16 * 16;
+    size_t localThreads[3] = {16, 16, 1};
+
+    char compile_option[128];
+    sprintf(compile_option, "-D anX=%d -D anY=%d -D ksX=%d -D ksY=%d", anchor.x, anchor.y, ksize.width, ksize.height);
+
+    openCLExecuteKernel(clCxt, &filtering_erodeFilter, kernelName, globalThreads, localThreads, args, src.channels(), src.depth(), compile_option);
+}
+
+
+//! data type supported: CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4
+void GPUDilate(const oclMat &src, oclMat &dst, oclMat &mat_kernel, Size &ksize, const Point anchor)
+{
+    //Normalize the result by default
+    //float alpha = ksize.height * ksize.width;
+    CV_Assert(src.clCxt == dst.clCxt);
+    CV_Assert( (src.cols == dst.cols) &&
+               (src.rows == dst.rows) );
+    CV_Assert( (src.channels() == dst.channels()) );
+
+    int srcStep = src.step1() / src.channels();
+    int dstStep = dst.step1() / dst.channels();
+    int srcOffset = src.offset / src.channels() / src.elemSize1();
+    int dstOffset = dst.offset / dst.channels() / dst.elemSize1();
+    int minclos = -(srcOffset % srcStep);
+    int maxclos = src.wholecols + minclos - 1;
+    int minrows = -(srcOffset / srcStep);
+    int maxrows = src.wholerows + minrows - 1;
+
+
+    Context *clCxt = src.clCxt;
+
+    string kernelName = "dilate";
+    vector< pair<size_t, const void *> > args;
+    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 *)&srcOffset));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dstOffset));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&minclos));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&maxclos));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&minrows));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&maxrows));
+    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 *)&srcStep));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dstStep));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_kernel.data));
+       args.push_back( make_pair( sizeof(cl_int),(void*)&src.wholecols));
+       args.push_back( make_pair( sizeof(cl_int),(void*)&src.wholerows));
+
+    size_t globalThreads[3] = {(src.cols + 15) / 16 * 16, (src.rows + 15) / 16 * 16, 1};
+    if(src.channels() == 1)
+        globalThreads[0] = ((src.cols + 9) / 4 + 15) / 16 * 16;
+    size_t localThreads[3] = {16, 16, 1};
+    char compile_option[128];
+    sprintf(compile_option, "-D anX=%d -D anY=%d -D ksX=%d -D ksY=%d", anchor.x, anchor.y, ksize.width, ksize.height);
+
+    openCLExecuteKernel(clCxt, &filtering_dilateFilter, kernelName, globalThreads, localThreads, args, src.channels(), src.depth(), compile_option);
+}
+
+Ptr<BaseFilter_GPU> cv::ocl::getMorphologyFilter_GPU(int op, int type, const Mat &kernel, const Size &ksize, Point anchor)
+{
+    static const GPUMorfFilter_t GPUMorfFilter_callers[2][5] =
+    {
+        {0, GPUErode, 0, 0, GPUErode },
+        {0, GPUDilate, 0, 0, GPUDilate}
+    };
+
+    CV_Assert(op == MORPH_ERODE || op == MORPH_DILATE);
+    CV_Assert(type == CV_8UC1 || type == CV_8UC4 || type == CV_32FC1 || type == CV_32FC4);
+
+    oclMat gpu_krnl;
+    normalizeKernel(kernel, gpu_krnl);
+    normalizeAnchor(anchor, ksize);
+
+    return Ptr<BaseFilter_GPU>(new MorphFilter_GPU(ksize, anchor, gpu_krnl, GPUMorfFilter_callers[op][CV_MAT_CN(type)]));
+}
+
+namespace
+{
+    class MorphologyFilterEngine_GPU : public Filter2DEngine_GPU
+    {
+    public:
+        MorphologyFilterEngine_GPU(const Ptr<BaseFilter_GPU>& filter2D_, int iters_) :
+            Filter2DEngine_GPU(filter2D_), iters(iters_) {}
+
+        virtual void apply(const oclMat &src, oclMat &dst, Rect roi = Rect(0, 0, -1, -1))
+        {
+            Filter2DEngine_GPU::apply(src, dst);
+            //if (iters > 1)
+            //{
+            // Size wholesize;
+            // Point ofs;
+            // dst.locateROI(wholesize,ofs);
+            // int rows = dst.rows, cols = dst.cols;
+            // dst.adjustROI(ofs.y,-ofs.y-rows+dst.wholerows,ofs.x,-ofs.x-cols+dst.wholecols);
+            // dst.copyTo(morfBuf);
+            // dst.adjustROI(-ofs.y,ofs.y+rows-dst.wholerows,-ofs.x,ofs.x+cols-dst.wholecols);
+            // morfBuf.adjustROI(-ofs.y,ofs.y+rows-dst.wholerows,-ofs.x,ofs.x+cols-dst.wholecols);
+            // //morfBuf.create(src.size(),src.type());
+            // //Filter2DEngine_GPU::apply(dst, morfBuf);
+            // //morfBuf.copyTo(dst);
+            //}
+            for(int i = 1; i < iters; ++i)
+            {
+                //dst.swap(morfBuf);
+                Size wholesize;
+                Point ofs;
+                dst.locateROI(wholesize, ofs);
+                int rows = dst.rows, cols = dst.cols;
+                dst.adjustROI(ofs.y, -ofs.y - rows + dst.wholerows, ofs.x, -ofs.x - cols + dst.wholecols);
+                dst.copyTo(morfBuf);
+                dst.adjustROI(-ofs.y, ofs.y + rows - dst.wholerows, -ofs.x, ofs.x + cols - dst.wholecols);
+                morfBuf.adjustROI(-ofs.y, ofs.y + rows - dst.wholerows, -ofs.x, ofs.x + cols - dst.wholecols);
+                Filter2DEngine_GPU::apply(morfBuf, dst);
+            }
+        }
+
+        int iters;
+        oclMat morfBuf;
+    };
+}
+
+Ptr<FilterEngine_GPU> cv::ocl::createMorphologyFilter_GPU(int op, int type, const Mat &kernel, const Point &anchor, int iterations)
+{
+    CV_Assert(iterations > 0);
+
+    Size ksize = kernel.size();
+
+    Ptr<BaseFilter_GPU> filter2D = getMorphologyFilter_GPU(op, type, kernel, ksize, anchor);
+
+    return Ptr<FilterEngine_GPU>(new MorphologyFilterEngine_GPU(filter2D, iterations));
+}
+
+namespace
+{
+    void morphOp(int op, const oclMat &src, oclMat &dst, const Mat &_kernel, Point anchor, int iterations)
+    {
+        Mat kernel;
+        Size ksize = _kernel.data ? _kernel.size() : Size(3, 3);
+
+        normalizeAnchor(anchor, ksize);
+
+        if (iterations == 0 || _kernel.rows *_kernel.cols == 1)
+        {
+            src.copyTo(dst);
+            return;
+        }
+
+        dst.create(src.size(), src.type());
+
+        if (!_kernel.data)
+        {
+            kernel = getStructuringElement(MORPH_RECT, Size(1 + iterations * 2, 1 + iterations * 2));
+            anchor = Point(iterations, iterations);
+            iterations = 1;
+        }
+        else if (iterations > 1 && countNonZero(_kernel) == _kernel.rows * _kernel.cols)
+        {
+            anchor = Point(anchor.x * iterations, anchor.y * iterations);
+            kernel = getStructuringElement(MORPH_RECT, Size(ksize.width + iterations * (ksize.width - 1),
+                                           ksize.height + iterations * (ksize.height - 1)), anchor);
+            iterations = 1;
+        }
+        else
+            kernel = _kernel;
+
+        Ptr<FilterEngine_GPU> f = createMorphologyFilter_GPU(op, src.type(), kernel, anchor, iterations);
+
+        f->apply(src, dst);
+    }
+}
+
+void cv::ocl::erode( const oclMat &src, oclMat &dst, const Mat &kernel, Point anchor, int iterations)
+{
+    bool allZero = true;
+    for(int i = 0; i < kernel.rows * kernel.cols; ++i)
+        if(kernel.data[i] != 0)
+            allZero = false;
+    if(allZero)
+    {
+        kernel.data[0] = 1;
+    }
+    morphOp(MORPH_ERODE, src, dst, kernel, anchor, iterations);
+}
+
+void cv::ocl::dilate( const oclMat &src, oclMat &dst, const Mat &kernel, Point anchor, int iterations)
+{
+    morphOp(MORPH_DILATE, src, dst, kernel, anchor, iterations);
+}
+
+void cv::ocl::morphologyEx( const oclMat &src, oclMat &dst, int op, const Mat &kernel, Point anchor, int iterations)
+{
+    oclMat temp;
+    switch( op )
+    {
+    case MORPH_ERODE:
+        erode( src, dst, kernel, anchor, iterations);
+        break;
+    case MORPH_DILATE:
+        dilate( src, dst, kernel, anchor, iterations);
+        break;
+    case MORPH_OPEN:
+        erode( src, temp, kernel, anchor, iterations);
+        dilate( temp, dst, kernel, anchor, iterations);
+        break;
+    case CV_MOP_CLOSE:
+        dilate( src, temp, kernel, anchor, iterations);
+        erode( temp, dst, kernel, anchor, iterations);
+        break;
+    case CV_MOP_GRADIENT:
+        erode( src, temp, kernel, anchor, iterations);
+        dilate( src, dst, kernel, anchor, iterations);
+        subtract(dst, temp, dst);
+        break;
+    case CV_MOP_TOPHAT:
+        erode( src, dst, kernel, anchor, iterations);
+        dilate( dst, temp, kernel, anchor, iterations);
+        subtract(src, temp, dst);
+        break;
+    case CV_MOP_BLACKHAT:
+        dilate( src, dst, kernel, anchor, iterations);
+        erode( dst, temp, kernel, anchor, iterations);
+        subtract(temp, src, dst);
+        break;
+    default:
+        CV_Error( CV_StsBadArg, "unknown morphological operation" );
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Linear Filter
+
+namespace
+{
+    typedef void (*GPUFilter2D_t)(const oclMat & , oclMat & , oclMat & , Size &, const Point, const int);
+
+    class LinearFilter_GPU : public BaseFilter_GPU
+    {
+    public:
+        LinearFilter_GPU(const Size &ksize_, const Point &anchor_, const oclMat &kernel_, GPUFilter2D_t func_,
+                         int borderType_) :
+            BaseFilter_GPU(ksize_, anchor_, borderType_), kernel(kernel_), func(func_) {}
+
+        virtual void operator()(const oclMat &src, oclMat &dst)
+        {
+            func(src, dst, kernel, ksize, anchor, borderType) ;
+        }
+
+        oclMat kernel;
+        GPUFilter2D_t func;
+    };
+}
+
+void GPUFilter2D(const oclMat &src, oclMat &dst, oclMat &mat_kernel,
+                 Size &ksize, const Point anchor, const int borderType)
+{
+    CV_Assert(src.clCxt == dst.clCxt);
+    CV_Assert( (src.cols == dst.cols) &&
+               (src.rows == dst.rows) );
+    CV_Assert( (src.channels() == dst.channels()) );
+    CV_Assert( (borderType != 0) );
+    CV_Assert(ksize.height > 0 && ksize.width > 0 && ((ksize.height & 1) == 1) && ((ksize.width & 1) == 1));
+    CV_Assert((anchor.x == -1 && anchor.y == -1) || (anchor.x == ksize.width >> 1 && anchor.y == ksize.height >> 1));
+    Context *clCxt = src.clCxt;
+    int cn =  src.channels();
+    int depth = src.depth();
+
+    string kernelName = "filter2D";
+
+    size_t src_offset_x = (src.offset % src.step) / src.elemSize();
+    size_t src_offset_y = src.offset / src.step;
+
+    size_t dst_offset_x = (dst.offset % dst.step) / dst.elemSize();
+    size_t dst_offset_y = dst.offset / dst.step;
+
+    int vector_lengths[4][7] = {{4, 4, 4, 4, 4, 4, 4},
+        {4, 4, 1, 1, 1, 1, 1},
+        {1, 1, 1, 1, 1, 1, 1},
+        {4, 4, 4, 4, 1, 1, 4}
+    };
+
+    int vector_length = vector_lengths[cn-1][depth];
+    int offset_cols = (dst_offset_x) & (vector_length - 1);
+    int cols = dst.cols + offset_cols;
+    int rows = divUp(dst.rows, vector_length);
+
+    size_t localThreads[3] = {256, 1, 1};
+    size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                divUp(rows, localThreads[1]) * localThreads[1], 1
+                              };
+
+    vector< pair<size_t, const void *> > args;
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&src.data));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src.step));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src_offset_x));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src_offset_y));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.step));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst_offset_x));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst_offset_y));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_kernel.data));
+    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 *)&cols));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src.wholecols));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src.wholerows));
+
+    openCLExecuteKernel(clCxt, &filtering_laplacian, kernelName, globalThreads, localThreads, args, cn, depth);
+}
+Ptr<BaseFilter_GPU> cv::ocl::getLinearFilter_GPU(int srcType, int dstType, const Mat &kernel, const Size &ksize,
+        Point anchor, int borderType)
+{
+    static const GPUFilter2D_t GPUFilter2D_callers[] = {0, GPUFilter2D, 0, 0, GPUFilter2D};
+
+    CV_Assert((srcType == CV_8UC1 || srcType == CV_8UC4 || srcType == CV_32FC1 || srcType == CV_32FC4) && dstType == srcType);
+
+    oclMat gpu_krnl;
+    int nDivisor;
+    normalizeKernel(kernel, gpu_krnl, CV_32S, &nDivisor, true);
+    normalizeAnchor(anchor, ksize);
+
+    return Ptr<BaseFilter_GPU>(new LinearFilter_GPU(ksize, anchor, gpu_krnl, GPUFilter2D_callers[CV_MAT_CN(srcType)],
+                               borderType));
+}
+
+Ptr<FilterEngine_GPU> cv::ocl::createLinearFilter_GPU(int srcType, int dstType, const Mat &kernel, const Point &anchor,
+        int borderType)
+{
+
+    Size ksize = kernel.size();
+
+    Ptr<BaseFilter_GPU> linearFilter = getLinearFilter_GPU(srcType, dstType, kernel, ksize, anchor, borderType);
+
+    return createFilter2D_GPU(linearFilter);
+}
+
+void cv::ocl::filter2D(const oclMat &src, oclMat &dst, int ddepth, const Mat &kernel, Point anchor, int borderType)
+{
+
+    if( ddepth < 0 )
+        ddepth = src.depth();
+
+    dst.create(src.size(), CV_MAKETYPE(ddepth, src.channels()));
+
+    Ptr<FilterEngine_GPU> f = createLinearFilter_GPU(src.type(), dst.type(), kernel, anchor, borderType);
+    f->apply(src, dst);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// SeparableFilter
+
+namespace
+{
+    class SeparableFilterEngine_GPU : public FilterEngine_GPU
+    {
+    public:
+        SeparableFilterEngine_GPU(const Ptr<BaseRowFilter_GPU>& rowFilter_,
+                                  const Ptr<BaseColumnFilter_GPU>& columnFilter_) :
+            rowFilter(rowFilter_), columnFilter(columnFilter_)
+        {
+            ksize = Size(rowFilter->ksize, columnFilter->ksize);
+            anchor = Point(rowFilter->anchor, columnFilter->anchor);
+        }
+
+        virtual void apply(const oclMat &src, oclMat &dst, Rect roi = Rect(0, 0, -1, -1))
+        {
+            Size src_size = src.size();
+            int src_type = src.type();
+
+            int cn = src.channels();
+            dst.create(src_size, src_type);
+            dst = Scalar(0.0);
+            //dstBuf.create(src_size, src_type);
+            dstBuf.create(src_size.height + ksize.height - 1, src_size.width, CV_MAKETYPE(CV_32F, cn));
+            dstBuf = Scalar(0.0);
+
+            normalizeROI(roi, ksize, anchor, src_size);
+
+            srcROI = src(roi);
+            dstROI = dst(roi);
+            //dstBufROI = dstBuf(roi);
+
+            (*rowFilter)(srcROI, dstBuf);
+            //Mat rm(dstBufROI);
+            //std::cout << "rm " << rm << endl;
+            (*columnFilter)(dstBuf, dstROI);
+        }
+
+        Ptr<BaseRowFilter_GPU> rowFilter;
+        Ptr<BaseColumnFilter_GPU> columnFilter;
+        Size ksize;
+        Point anchor;
+        oclMat dstBuf;
+        oclMat srcROI;
+        oclMat dstROI;
+        oclMat dstBufROI;
+    };
+}
+
+Ptr<FilterEngine_GPU> cv::ocl::createSeparableFilter_GPU(const Ptr<BaseRowFilter_GPU>& rowFilter,
+        const Ptr<BaseColumnFilter_GPU>& columnFilter)
+{
+    return Ptr<FilterEngine_GPU>(new SeparableFilterEngine_GPU(rowFilter, columnFilter));
+}
+
+/*
+**data type supported: CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4
+**support four border types: BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT, BORDER_REFLECT_101
+*/
+
+void GPUFilterBox_8u_C1R(const oclMat &src, oclMat &dst,
+                         Size &ksize, const Point anchor, const int borderType)
+{
+    //Normalize the result by default
+    float alpha = ksize.height * ksize.width;
+
+    CV_Assert(src.clCxt == dst.clCxt);
+    CV_Assert((src.cols == dst.cols) &&
+              (src.rows == dst.rows) );
+    Context *clCxt = src.clCxt;
+
+    string kernelName = "boxFilter_C1_D0";
+
+    char btype[30];
+    switch(borderType)
+    {
+    case 0:
+        sprintf(btype, "BORDER_CONSTANT");
+        break;
+    case 1:
+        sprintf(btype, "BORDER_REPLICATE");
+        break;
+    case 2:
+        sprintf(btype, "BORDER_REFLECT");
+        break;
+    case 3:
+        CV_Error(CV_StsUnsupportedFormat, "BORDER_WRAP is not supported!");
+        return;
+    case 4:
+        sprintf(btype, "BORDER_REFLECT_101");
+        break;
+    }
+
+    char build_options[150];
+    sprintf(build_options, "-D anX=%d -D anY=%d -D ksX=%d -D ksY=%d -D %s", anchor.x, anchor.y, ksize.width, ksize.height, btype);
+
+    size_t blockSizeX = 256, blockSizeY = 1;
+    size_t gSize = blockSizeX - (ksize.width - 1);
+    size_t threads = (dst.offset % dst.step % 4 + dst.cols + 3) / 4;
+    size_t globalSizeX = threads % gSize == 0 ? threads / gSize * blockSizeX : (threads / gSize + 1) * blockSizeX;
+    size_t globalSizeY = ((dst.rows + 1) / 2) % blockSizeY == 0 ? ((dst.rows + 1) / 2) : (((dst.rows + 1) / 2) / blockSizeY + 1) * blockSizeY;
+
+    size_t globalThreads[3] = { globalSizeX, globalSizeY, 1 };
+    size_t localThreads[3]  = { blockSizeX, blockSizeY, 1 };
+
+    vector<pair<size_t , const void *> > args;
+    args.push_back(make_pair(sizeof(cl_mem), &src.data));
+    args.push_back(make_pair(sizeof(cl_mem), &dst.data));
+    args.push_back(make_pair(sizeof(cl_float), (void *)&alpha));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src.offset));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src.wholerows));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src.wholecols));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src.step));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst.offset));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst.rows));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst.cols));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst.step));
+
+    openCLExecuteKernel(clCxt, &filtering_boxFilter, kernelName, globalThreads, localThreads, args, -1, -1, build_options);
+}
+
+void GPUFilterBox_8u_C4R(const oclMat &src, oclMat &dst,
+                         Size &ksize, const Point anchor, const int borderType)
+{
+    //Normalize the result by default
+    float alpha = ksize.height * ksize.width;
+
+    CV_Assert(src.clCxt == dst.clCxt);
+    CV_Assert((src.cols == dst.cols) &&
+              (src.rows == dst.rows) );
+    Context *clCxt = src.clCxt;
+
+    string kernelName = "boxFilter_C4_D0";
+
+    char btype[30];
+    switch(borderType)
+    {
+    case 0:
+        sprintf(btype, "BORDER_CONSTANT");
+        break;
+    case 1:
+        sprintf(btype, "BORDER_REPLICATE");
+        break;
+    case 2:
+        sprintf(btype, "BORDER_REFLECT");
+        break;
+    case 3:
+        CV_Error(CV_StsUnsupportedFormat, "BORDER_WRAP is not supported!");
+        return;
+    case 4:
+        sprintf(btype, "BORDER_REFLECT_101");
+        break;
+    }
+
+    char build_options[150];
+    sprintf(build_options, "-D anX=%d -D anY=%d -D ksX=%d -D ksY=%d -D %s", anchor.x, anchor.y, ksize.width, ksize.height, btype);
+
+    size_t blockSizeX = 256, blockSizeY = 1;
+    size_t gSize = blockSizeX - ksize.width / 2 * 2;
+    size_t globalSizeX = (src.cols) % gSize == 0 ? src.cols / gSize * blockSizeX : (src.cols / gSize + 1) * blockSizeX;
+    size_t rows_per_thread = 2;
+    size_t globalSizeY = ((src.rows + rows_per_thread - 1) / rows_per_thread) % blockSizeY == 0 ? ((src.rows + rows_per_thread - 1) / rows_per_thread) : (((src.rows + rows_per_thread - 1) / rows_per_thread) / blockSizeY + 1) * blockSizeY;
+
+    size_t globalThreads[3] = { globalSizeX, globalSizeY, 1};
+    size_t localThreads[3]  = { blockSizeX, blockSizeY, 1};
+
+    vector<pair<size_t , const void *> > args;
+    args.push_back(make_pair(sizeof(cl_mem), &src.data));
+    args.push_back(make_pair(sizeof(cl_mem), &dst.data));
+    args.push_back(make_pair(sizeof(cl_float), (void *)&alpha));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src.offset));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src.wholerows));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src.wholecols));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src.step));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst.offset));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst.rows));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst.cols));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst.step));
+
+    openCLExecuteKernel(clCxt, &filtering_boxFilter, kernelName, globalThreads, localThreads, args, -1, -1, build_options);
+}
+
+void GPUFilterBox_32F_C1R(const oclMat &src, oclMat &dst,
+                          Size &ksize, const Point anchor, const int borderType)
+{
+    //Normalize the result by default
+    float alpha = ksize.height * ksize.width;
+
+    CV_Assert(src.clCxt == dst.clCxt);
+    CV_Assert((src.cols == dst.cols) &&
+              (src.rows == dst.rows) );
+    Context *clCxt = src.clCxt;
+
+    string kernelName = "boxFilter_C1_D5";
+
+    char btype[30];
+    switch(borderType)
+    {
+    case 0:
+        sprintf(btype, "BORDER_CONSTANT");
+        break;
+    case 1:
+        sprintf(btype, "BORDER_REPLICATE");
+        break;
+    case 2:
+        sprintf(btype, "BORDER_REFLECT");
+        break;
+    case 3:
+        CV_Error(CV_StsUnsupportedFormat, "BORDER_WRAP is not supported!");
+        return;
+    case 4:
+        sprintf(btype, "BORDER_REFLECT_101");
+        break;
+    }
+
+    char build_options[150];
+    sprintf(build_options, "-D anX=%d -D anY=%d -D ksX=%d -D ksY=%d -D %s", anchor.x, anchor.y, ksize.width, ksize.height, btype);
+
+    size_t blockSizeX = 256, blockSizeY = 1;
+    size_t gSize = blockSizeX - ksize.width / 2 * 2;
+    size_t globalSizeX = (src.cols) % gSize == 0 ? src.cols / gSize * blockSizeX : (src.cols / gSize + 1) * blockSizeX;
+    size_t rows_per_thread = 2;
+    size_t globalSizeY = ((src.rows + rows_per_thread - 1) / rows_per_thread) % blockSizeY == 0 ? ((src.rows + rows_per_thread - 1) / rows_per_thread) : (((src.rows + rows_per_thread - 1) / rows_per_thread) / blockSizeY + 1) * blockSizeY;
+
+
+    size_t globalThreads[3] = { globalSizeX, globalSizeY, 1};
+    size_t localThreads[3]  = { blockSizeX, blockSizeY, 1};
+
+    vector<pair<size_t , const void *> > args;
+    args.push_back(make_pair(sizeof(cl_mem), &src.data));
+    args.push_back(make_pair(sizeof(cl_mem), &dst.data));
+    args.push_back(make_pair(sizeof(cl_float), (void *)&alpha));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src.offset));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src.wholerows));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src.wholecols));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src.step));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst.offset));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst.rows));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst.cols));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst.step));
+
+    openCLExecuteKernel(clCxt, &filtering_boxFilter, kernelName, globalThreads, localThreads, args, -1, -1, build_options);
+}
+
+void GPUFilterBox_32F_C4R(const oclMat &src, oclMat &dst,
+                          Size &ksize, const Point anchor, const int borderType)
+{
+    //Normalize the result by default
+    float alpha = ksize.height * ksize.width;
+
+    CV_Assert(src.clCxt == dst.clCxt);
+    CV_Assert((src.cols == dst.cols) &&
+              (src.rows == dst.rows) );
+    Context *clCxt = src.clCxt;
+
+    string kernelName = "boxFilter_C4_D5";
+
+    char btype[30];
+    switch(borderType)
+    {
+    case 0:
+        sprintf(btype, "BORDER_CONSTANT");
+        break;
+    case 1:
+        sprintf(btype, "BORDER_REPLICATE");
+        break;
+    case 2:
+        sprintf(btype, "BORDER_REFLECT");
+        break;
+    case 3:
+        CV_Error(CV_StsUnsupportedFormat, "BORDER_WRAP is not supported!");
+        return;
+    case 4:
+        sprintf(btype, "BORDER_REFLECT_101");
+        break;
+    }
+
+    char build_options[150];
+    sprintf(build_options, "-D anX=%d -D anY=%d -D ksX=%d -D ksY=%d -D %s", anchor.x, anchor.y, ksize.width, ksize.height, btype);
+
+    size_t blockSizeX = 256, blockSizeY = 1;
+    size_t gSize = blockSizeX - ksize.width / 2 * 2;
+    size_t globalSizeX = (src.cols) % gSize == 0 ? src.cols / gSize * blockSizeX : (src.cols / gSize + 1) * blockSizeX;
+    size_t rows_per_thread = 2;
+    size_t globalSizeY = ((src.rows + rows_per_thread - 1) / rows_per_thread) % blockSizeY == 0 ? ((src.rows + rows_per_thread - 1) / rows_per_thread) : (((src.rows + rows_per_thread - 1) / rows_per_thread) / blockSizeY + 1) * blockSizeY;
+
+
+    size_t globalThreads[3] = { globalSizeX, globalSizeY, 1};
+    size_t localThreads[3]  = { blockSizeX, blockSizeY, 1};
+
+    vector<pair<size_t , const void *> > args;
+    args.push_back(make_pair(sizeof(cl_mem), &src.data));
+    args.push_back(make_pair(sizeof(cl_mem), &dst.data));
+    args.push_back(make_pair(sizeof(cl_float), (void *)&alpha));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src.offset));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src.wholerows));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src.wholecols));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src.step));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst.offset));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst.rows));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst.cols));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst.step));
+
+    openCLExecuteKernel(clCxt, &filtering_boxFilter, kernelName, globalThreads, localThreads, args, -1, -1, build_options);
+}
+
+
+Ptr<BaseFilter_GPU> cv::ocl::getBoxFilter_GPU(int srcType, int dstType,
+        const Size &ksize, Point anchor, int borderType)
+{
+    static const FilterBox_t FilterBox_callers[2][5] = {{0, GPUFilterBox_8u_C1R, 0, 0, GPUFilterBox_8u_C4R},
+        {0, GPUFilterBox_32F_C1R, 0, 0, GPUFilterBox_32F_C4R}
+    };
+    //Remove this check if more data types need to be supported.
+    CV_Assert((srcType == CV_8UC1 || srcType == CV_8UC4 || srcType == CV_32FC1 || srcType == CV_32FC4)
+              && dstType == srcType);
+
+    normalizeAnchor(anchor, ksize);
+
+    return Ptr<BaseFilter_GPU>(new GPUBoxFilter(ksize, anchor,
+                               borderType, FilterBox_callers[(CV_MAT_DEPTH(srcType) == CV_32F)][CV_MAT_CN(srcType)]));
+}
+
+Ptr<FilterEngine_GPU> cv::ocl::createBoxFilter_GPU(int srcType, int dstType,
+        const Size &ksize, const Point &anchor, int borderType)
+{
+    Ptr<BaseFilter_GPU> boxFilter = getBoxFilter_GPU(srcType, dstType, ksize, anchor, borderType);
+    return createFilter2D_GPU(boxFilter);
+}
+
+void cv::ocl::boxFilter(const oclMat &src, oclMat &dst, int ddepth, Size ksize,
+                        Point anchor, int borderType)
+{
+    int sdepth = src.depth(), cn = src.channels();
+    if( ddepth < 0 )
+        ddepth = sdepth;
+
+    dst.create(src.size(), CV_MAKETYPE(ddepth, cn));
+
+    Ptr<FilterEngine_GPU> f = createBoxFilter_GPU(src.type(),
+                              dst.type(), ksize, anchor, borderType);
+    f->apply(src, dst);
+}
+
+namespace
+{
+    typedef void (*gpuFilter1D_t)(const oclMat &src, const oclMat &dst, oclMat kernel, int ksize, int anchor, int bordertype);
+
+    class GpuLinearRowFilter : public BaseRowFilter_GPU
+    {
+    public:
+        GpuLinearRowFilter(int ksize_, int anchor_, const oclMat &kernel_, gpuFilter1D_t func_, int bordertype_) :
+            BaseRowFilter_GPU(ksize_, anchor_, bordertype_), kernel(kernel_), func(func_) {}
+
+        virtual void operator()(const oclMat &src, oclMat &dst)
+        {
+            func(src, dst, kernel, ksize, anchor, bordertype);
+        }
+
+        oclMat kernel;
+        gpuFilter1D_t func;
+    };
+}
+
+template <typename T> struct index_and_sizeof;
+template <> struct index_and_sizeof<uchar>
+{
+    enum { index = 1 };
+};
+template <> struct index_and_sizeof<char>
+{
+    enum { index = 2 };
+};
+template <> struct index_and_sizeof<ushort>
+{
+    enum { index = 3 };
+};
+template <> struct index_and_sizeof<short>
+{
+    enum { index = 4 };
+};
+template <> struct index_and_sizeof<int>
+{
+    enum { index = 5 };
+};
+template <> struct index_and_sizeof<float>
+{
+    enum { index = 6 };
+};
+
+template <typename T>
+void linearRowFilter_gpu(const oclMat &src, const oclMat &dst, oclMat mat_kernel, int ksize, int anchor, int bordertype)
+{
+    Context *clCxt = src.clCxt;
+    int channels = src.channels();
+
+    size_t localThreads[3] = {16, 16, 1};
+    string kernelName = "row_filter";
+
+    char btype[30];
+    switch(bordertype)
+    {
+    case 0:
+        sprintf(btype, "BORDER_CONSTANT");
+        break;
+    case 1:
+        sprintf(btype, "BORDER_REPLICATE");
+        break;
+    case 2:
+        sprintf(btype, "BORDER_REFLECT");
+        break;
+    case 3:
+        sprintf(btype, "BORDER_WRAP");
+        break;
+    case 4:
+        sprintf(btype, "BORDER_REFLECT_101");
+        break;
+    }
+    char compile_option[128];
+    sprintf(compile_option, "-D RADIUSX=%d -D LSIZE0=%d -D LSIZE1=%d -D CN=%d -D %s", anchor, localThreads[0], localThreads[1], channels, btype);
+
+    size_t globalThreads[3];
+    globalThreads[1] = (dst.rows + localThreads[1] - 1) / localThreads[1] * localThreads[1];
+    globalThreads[2] = (1 + localThreads[2] - 1) / localThreads[2] * localThreads[2];
+    if(src.depth() == CV_8U)
+    {
+        switch(channels)
+        {
+        case 1:
+        case 3:
+            globalThreads[0] = ((dst.cols + 4) / 4 + localThreads[0] - 1) / localThreads[0] * localThreads[0];
+            break;
+        case 2:
+            globalThreads[0] = ((dst.cols + 1) / 2 + localThreads[0] - 1) / localThreads[0] * localThreads[0];
+            break;
+        case 4:
+            globalThreads[0] = (dst.cols + localThreads[0] - 1) / localThreads[0] * localThreads[0];
+            break;
+        }
+    }
+    else
+    {
+        globalThreads[0] = (dst.cols + localThreads[0] - 1) / localThreads[0] * localThreads[0];
+    }
+    //sanity checks
+    CV_Assert(clCxt == dst.clCxt);
+    CV_Assert(src.cols == dst.cols);
+    CV_Assert(src.channels() == dst.channels());
+    CV_Assert(ksize == (anchor << 1) + 1);
+    int src_pix_per_row, dst_pix_per_row;
+    int src_offset_x, src_offset_y, dst_offset_in_pixel;
+    src_pix_per_row = src.step / src.elemSize();
+    src_offset_x = (src.offset % src.step) / src.elemSize();
+    src_offset_y = src.offset / src.step;
+    dst_pix_per_row = dst.step / dst.elemSize();
+    dst_offset_in_pixel = dst.offset / dst.elemSize();
+    int ridusy = (dst.rows - src.rows) >> 1;
+    vector<pair<size_t , const void *> > args;
+    args.push_back(make_pair(sizeof(cl_mem), &src.data));
+    args.push_back(make_pair(sizeof(cl_mem), &dst.data));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst.cols));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst.rows));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src.wholecols));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src.wholerows));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src_pix_per_row));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src_offset_x));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src_offset_y));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst_pix_per_row));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&ridusy));
+    args.push_back(make_pair(sizeof(cl_mem), (void *)&mat_kernel.data));
+
+    openCLExecuteKernel(clCxt, &filter_sep_row, kernelName, globalThreads, localThreads, args, channels, src.depth(), compile_option);
+}
+
+Ptr<BaseRowFilter_GPU> cv::ocl::getLinearRowFilter_GPU(int srcType, int bufType, const Mat &rowKernel, int anchor, int bordertype)
+{
+    static const gpuFilter1D_t gpuFilter1D_callers[6] =
+    {
+        linearRowFilter_gpu<uchar>,
+        linearRowFilter_gpu<char>,
+        linearRowFilter_gpu<ushort>,
+        linearRowFilter_gpu<short>,
+        linearRowFilter_gpu<int>,
+        linearRowFilter_gpu<float>
+    };
+
+    Mat temp = rowKernel.reshape(1, 1);
+    oclMat mat_kernel(temp);
+
+
+    int ksize = temp.cols;
+
+    //CV_Assert(ksize < 16);
+
+    normalizeAnchor(anchor, ksize);
+
+    return Ptr<BaseRowFilter_GPU>(new GpuLinearRowFilter(ksize, anchor, mat_kernel,
+                                  gpuFilter1D_callers[CV_MAT_DEPTH(srcType)], bordertype));
+}
+
+namespace
+{
+    class GpuLinearColumnFilter : public BaseColumnFilter_GPU
+    {
+    public:
+        GpuLinearColumnFilter(int ksize_, int anchor_, const oclMat &kernel_, gpuFilter1D_t func_, int bordertype_) :
+            BaseColumnFilter_GPU(ksize_, anchor_, bordertype_), kernel(kernel_), func(func_) {}
+
+        virtual void operator()(const oclMat &src, oclMat &dst)
+        {
+            func(src, dst, kernel, ksize, anchor, bordertype);
+        }
+
+        oclMat kernel;
+        gpuFilter1D_t func;
+    };
+}
+
+template <typename T>
+void linearColumnFilter_gpu(const oclMat &src, const oclMat &dst, oclMat mat_kernel, int ksize, int anchor, int bordertype)
+{
+    Context *clCxt = src.clCxt;
+    int channels = src.channels();
+
+    size_t localThreads[3] = {16, 16, 1};
+    string kernelName = "col_filter";
+
+    char btype[30];
+    switch(bordertype)
+    {
+    case 0:
+        sprintf(btype, "BORDER_CONSTANT");
+        break;
+    case 1:
+        sprintf(btype, "BORDER_REPLICATE");
+        break;
+    case 2:
+        sprintf(btype, "BORDER_REFLECT");
+        break;
+    case 3:
+        sprintf(btype, "BORDER_WRAP");
+        break;
+    case 4:
+        sprintf(btype, "BORDER_REFLECT_101");
+        break;
+    }
+    char compile_option[128];
+    sprintf(compile_option, "-D RADIUSY=%d -D LSIZE0=%d -D LSIZE1=%d -D CN=%d -D %s", anchor, localThreads[0], localThreads[1], channels, btype);
+
+    size_t globalThreads[3];
+    globalThreads[1] = (dst.rows + localThreads[1] - 1) / localThreads[1] * localThreads[1];
+    globalThreads[2] = (1 + localThreads[2] - 1) / localThreads[2] * localThreads[2];
+    if(dst.depth() == CV_8U)
+    {
+        switch(channels)
+        {
+        case 1:
+            globalThreads[0] = (dst.cols + localThreads[0] - 1) / localThreads[0] * localThreads[0];
+            break;
+        case 2:
+            globalThreads[0] = ((dst.cols + 1) / 2 + localThreads[0] - 1) / localThreads[0] * localThreads[0];
+            break;
+        case 3:
+            globalThreads[0] = ((dst.cols * 3 + 3) / 4 + localThreads[0] - 1) / localThreads[0] * localThreads[0];
+            break;
+        case 4:
+            globalThreads[0] = (dst.cols + localThreads[0] - 1) / localThreads[0] * localThreads[0];
+            break;
+        }
+    }
+    else
+    {
+        globalThreads[0] = (dst.cols + localThreads[0] - 1) / localThreads[0] * localThreads[0];
+    }
+
+    //sanity checks
+    CV_Assert(clCxt == dst.clCxt);
+    CV_Assert(src.cols == dst.cols);
+    CV_Assert(src.channels() == dst.channels());
+    CV_Assert(ksize == (anchor << 1) + 1);
+    int src_pix_per_row, dst_pix_per_row;
+    int src_offset_x, src_offset_y, dst_offset_in_pixel;
+    src_pix_per_row = src.step / src.elemSize();
+    src_offset_x = (src.offset % src.step) / src.elemSize();
+    src_offset_y = src.offset / src.step;
+    dst_pix_per_row = dst.step / dst.elemSize();
+    dst_offset_in_pixel = dst.offset / dst.elemSize();
+
+    vector<pair<size_t , const void *> > args;
+    args.push_back(make_pair(sizeof(cl_mem), &src.data));
+    args.push_back(make_pair(sizeof(cl_mem), &dst.data));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst.cols));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst.rows));
+    args.push_back(make_pair(sizeof(cl_int),(void*)&src.wholecols));
+    args.push_back(make_pair(sizeof(cl_int),(void*)&src.wholerows));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&src_pix_per_row));
+    //args.push_back(make_pair(sizeof(cl_int),(void*)&src_offset_x));
+    //args.push_back(make_pair(sizeof(cl_int),(void*)&src_offset_y));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst_pix_per_row));
+    args.push_back(make_pair(sizeof(cl_int), (void *)&dst_offset_in_pixel));
+    args.push_back(make_pair(sizeof(cl_mem), (void *)&mat_kernel.data));
+
+    openCLExecuteKernel(clCxt, &filter_sep_col, kernelName, globalThreads, localThreads, args, channels, dst.depth(), compile_option);
+}
+
+Ptr<BaseColumnFilter_GPU> cv::ocl::getLinearColumnFilter_GPU(int bufType, int dstType, const Mat &columnKernel, int anchor, int bordertype, double delta)
+{
+    static const gpuFilter1D_t gpuFilter1D_callers[6] =
+    {
+        linearColumnFilter_gpu<uchar>,
+        linearColumnFilter_gpu<char>,
+        linearColumnFilter_gpu<ushort>,
+        linearColumnFilter_gpu<short>,
+        linearColumnFilter_gpu<int>,
+        linearColumnFilter_gpu<float>
+    };
+    /*
+    CV_Assert(dstType == CV_8UC4 || dstType == CV_8SC4 || dstType == CV_16UC2 ||
+    dstType == CV_16SC2 || dstType == CV_32SC1 || dstType == CV_32FC1);
+    CV_Assert(bufType == CV_8UC4 || bufType == CV_8SC4 || bufType == CV_16UC2 ||
+    bufType == CV_16SC2 || bufType == CV_32SC1 || bufType == CV_32FC1);
+
+    Mat temp(columnKernel.size(), CV_32SC1);
+    columnKernel.convertTo(temp, CV_32SC1);
+    Mat cont_krnl = temp.reshape(1, 1);
+    */
+    Mat temp = columnKernel.reshape(1, 1);
+    oclMat mat_kernel(temp);
+
+    int ksize = temp.cols;
+
+    //CV_Assert(ksize < 16);
+
+    normalizeAnchor(anchor, ksize);
+
+    return Ptr<BaseColumnFilter_GPU>(new GpuLinearColumnFilter(ksize, anchor, mat_kernel,
+                                     gpuFilter1D_callers[CV_MAT_DEPTH(dstType)], bordertype));
+}
+
+Ptr<FilterEngine_GPU> cv::ocl::createSeparableLinearFilter_GPU(int srcType, int dstType,
+        const Mat &rowKernel, const Mat &columnKernel, const Point &anchor, double delta, int bordertype)
+{
+    int sdepth = CV_MAT_DEPTH(srcType), ddepth = CV_MAT_DEPTH(dstType);
+    int cn = CV_MAT_CN(srcType);
+    int bdepth = std::max(std::max(sdepth, ddepth), CV_32F);
+    int bufType = CV_MAKETYPE(bdepth, cn);
+
+    Ptr<BaseRowFilter_GPU> rowFilter = getLinearRowFilter_GPU(srcType, bufType, rowKernel, anchor.x, bordertype);
+    Ptr<BaseColumnFilter_GPU> columnFilter = getLinearColumnFilter_GPU(bufType, dstType, columnKernel, anchor.y, bordertype, delta);
+
+    return createSeparableFilter_GPU(rowFilter, columnFilter);
+}
+
+void cv::ocl::sepFilter2D(const oclMat &src, oclMat &dst, int ddepth, const Mat &kernelX, const Mat &kernelY, Point anchor, double delta, int bordertype)
+{
+    if( ddepth < 0 )
+        ddepth = src.depth();
+    CV_Assert(ddepth == src.depth());
+    dst.create(src.size(), CV_MAKETYPE(ddepth, src.channels()));
+
+    Ptr<FilterEngine_GPU> f = createSeparableLinearFilter_GPU(src.type(), dst.type(), kernelX, kernelY, anchor, delta, bordertype);
+    f->apply(src, dst);
+}
+
+Ptr<FilterEngine_GPU> cv::ocl::createDerivFilter_GPU( int srcType, int dstType, int dx, int dy, int ksize, int borderType )
+{
+       CV_Assert(dstType == srcType);
+       Mat kx, ky;
+       getDerivKernels( kx, ky, dx, dy, ksize, false, CV_32F );
+       return createSeparableLinearFilter_GPU(srcType, dstType,
+               kx, ky, Point(-1,-1), 0, borderType );
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Deriv Filter
+void cv::ocl::Sobel(const oclMat &src, oclMat &dst, int ddepth, int dx, int dy, int ksize, double scale, double delta, int borderType)
+{
+    Mat kx, ky;
+    getDerivKernels(kx, ky, dx, dy, ksize, false, CV_32F);
+
+    if (scale != 1)
+    {
+        // usually the smoothing part is the slowest to compute,
+        // so try to scale it instead of the faster differenciating part
+        if (dx == 0)
+            kx *= scale;
+        else
+            ky *= scale;
+    }
+    // Mat kx_, ky_;
+    //ky.convertTo(ky_,CV_32S,1<<8);
+    //kx.convertTo(kx_,CV_32S,1<<8);
+
+    sepFilter2D(src, dst, ddepth, kx, ky, Point(-1, -1), delta, borderType );
+}
+
+void cv::ocl::Scharr(const oclMat &src, oclMat &dst, int ddepth, int dx, int dy, double scale, double delta , int bordertype)
+{
+    Mat kx, ky;
+    getDerivKernels(kx, ky, dx, dy, -1, false, CV_32F);
+
+    if( scale != 1 )
+    {
+        // usually the smoothing part is the slowest to compute,
+        // so try to scale it instead of the faster differenciating part
+        if( dx == 0 )
+            kx *= scale;
+        else
+            ky *= scale;
+    }
+
+    // Mat kx_, ky_;
+    //ky.convertTo(ky_,CV_32S,1<<8);
+    //kx.convertTo(kx_,CV_32S,1<<8);
+
+    sepFilter2D(src, dst, ddepth, kx, ky, Point(-1, -1), delta, bordertype);
+}
+
+void cv::ocl::Laplacian(const oclMat &src, oclMat &dst, int ddepth, int ksize, double scale)
+{
+    if(src.clCxt -> impl -> double_support ==0 && src.type() == CV_64F)
+    {
+        CV_Error(-217,"Selected device don't support double\r\n");
+        return;
+    }
+
+    CV_Assert(ksize == 1 || ksize == 3);
+
+    static const int K[2][9] =
+    {
+        {0, 1, 0, 1, -4, 1, 0, 1, 0},
+        {2, 0, 2, 0, -8, 0, 2, 0, 2}
+    };
+    Mat kernel(3, 3, CV_32S, (void *)K[ksize == 3]);
+    if (scale != 1)
+        kernel *= scale;
+    filter2D(src, dst, ddepth, kernel, Point(-1, -1));
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Gaussian Filter
+
+Ptr<FilterEngine_GPU> cv::ocl::createGaussianFilter_GPU(int type, Size ksize, double sigma1, double sigma2, int bordertype)
+{
+    int depth = CV_MAT_DEPTH(type);
+
+    if (sigma2 <= 0)
+        sigma2 = sigma1;
+
+    // automatic detection of kernel size from sigma
+    if (ksize.width <= 0 && sigma1 > 0)
+        ksize.width = cvRound(sigma1 * (depth == CV_8U ? 3 : 4) * 2 + 1) | 1;
+    if (ksize.height <= 0 && sigma2 > 0)
+        ksize.height = cvRound(sigma2 * (depth == CV_8U ? 3 : 4) * 2 + 1) | 1;
+
+    CV_Assert( ksize.width > 0 && ksize.width % 2 == 1 && ksize.height > 0 && ksize.height % 2 == 1 );
+
+    sigma1 = std::max(sigma1, 0.0);
+    sigma2 = std::max(sigma2, 0.0);
+
+    Mat kx = getGaussianKernel( ksize.width, sigma1, std::max(depth, CV_32F) );
+    Mat ky;
+    if( ksize.height == ksize.width && std::abs(sigma1 - sigma2) < DBL_EPSILON )
+        ky = kx;
+    else
+        ky = getGaussianKernel( ksize.height, sigma2, std::max(depth, CV_32F) );
+    //Mat kx_, ky_;
+    //kx.convertTo(kx_,CV_32S,1<<8);
+    //ky.convertTo(ky_,CV_32S,1<<8);
+    return createSeparableLinearFilter_GPU(type, type, kx, ky, Point(-1, -1), 0.0, bordertype);
+}
+
+void cv::ocl::GaussianBlur(const oclMat &src, oclMat &dst, Size ksize, double sigma1, double sigma2, int bordertype)
+{
+    if (ksize.width == 1 && ksize.height == 1)
+    {
+        src.copyTo(dst);
+        return;
+    }
+
+    dst.create(src.size(), src.type());
+    if( bordertype != BORDER_CONSTANT )
+    {
+        if( src.rows == 1 )
+            ksize.height = 1;
+        if( src.cols == 1 )
+            ksize.width = 1;
+    }
+    Ptr<FilterEngine_GPU> f = createGaussianFilter_GPU(src.type(), ksize, sigma1, sigma2, bordertype);
+    f->apply(src, dst);
+}
+
+#endif /* !defined (HAVE_OPENCL) */
diff --git a/modules/ocl/src/haar.cpp b/modules/ocl/src/haar.cpp
new file mode 100644 (file)
index 0000000..644463e
--- /dev/null
@@ -0,0 +1,2715 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Niko Li, newlife20080214@gmail.com
+//    Wang Weiyan, wangweiyanster@gmail.com
+//    Jia Haipeng, jiahaipeng95@gmail.com
+//    Wu Xinglong, wxl370@126.com
+//    Wang Yao, 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 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*/
+
+/* Haar features calculation */
+//#define EMU
+
+#include "precomp.hpp"
+#include <stdio.h>
+#ifdef EMU
+#include "runCL.h"
+#endif
+using namespace cv;
+using namespace cv::ocl;
+using namespace std;
+
+
+namespace cv
+{
+    namespace ocl
+    {
+        ///////////////////////////OpenCL kernel strings///////////////////////////
+        extern const char *haarobjectdetect;
+        extern const char *haarobjectdetectbackup;
+        extern const char *haarobjectdetect_scaled2;
+    }
+}
+
+/* these settings affect the quality of detection: change with care */
+#define CV_ADJUST_FEATURES 1
+#define CV_ADJUST_WEIGHTS  0
+
+typedef int sumtype;
+typedef double sqsumtype;
+
+typedef struct CvHidHaarFeature
+{
+    struct
+    {
+        sumtype *p0, *p1, *p2, *p3;
+        float weight;
+    }
+    rect[CV_HAAR_FEATURE_MAX];
+}
+CvHidHaarFeature;
+
+
+typedef struct CvHidHaarTreeNode
+{
+    CvHidHaarFeature feature;
+    float threshold;
+    int left;
+    int right;
+}
+CvHidHaarTreeNode;
+
+
+typedef struct CvHidHaarClassifier
+{
+    int count;
+    //CvHaarFeature* orig_feature;
+    CvHidHaarTreeNode *node;
+    float *alpha;
+}
+CvHidHaarClassifier;
+
+
+typedef struct CvHidHaarStageClassifier
+{
+    int  count;
+    float threshold;
+    CvHidHaarClassifier *classifier;
+    int two_rects;
+
+    struct CvHidHaarStageClassifier *next;
+    struct CvHidHaarStageClassifier *child;
+    struct CvHidHaarStageClassifier *parent;
+}
+CvHidHaarStageClassifier;
+
+
+struct CvHidHaarClassifierCascade
+{
+    int  count;
+    int  is_stump_based;
+    int  has_tilted_features;
+    int  is_tree;
+    double inv_window_area;
+    CvMat sum, sqsum, tilted;
+    CvHidHaarStageClassifier *stage_classifier;
+    sqsumtype *pq0, *pq1, *pq2, *pq3;
+    sumtype *p0, *p1, *p2, *p3;
+
+    void **ipp_stages;
+};
+typedef struct
+{
+    //int rows;
+    //int ystep;
+    int width_height;
+    //int height;
+    int grpnumperline_totalgrp;
+    //int totalgrp;
+    int imgoff;
+    float factor;
+} detect_piramid_info;
+#if WIN32
+#define _ALIGNED_ON(_ALIGNMENT) __declspec(align(_ALIGNMENT))
+typedef _ALIGNED_ON(128) struct  GpuHidHaarFeature
+{
+    _ALIGNED_ON(32) struct
+    {
+        _ALIGNED_ON(4)  int    p0 ;
+        _ALIGNED_ON(4)  int    p1 ;
+        _ALIGNED_ON(4)  int    p2 ;
+        _ALIGNED_ON(4)  int    p3 ;
+        _ALIGNED_ON(4)  float weight  ;
+    }
+    _ALIGNED_ON(32) rect[CV_HAAR_FEATURE_MAX] ;
+}
+GpuHidHaarFeature;
+
+
+typedef _ALIGNED_ON(128) struct  GpuHidHaarTreeNode
+{
+    _ALIGNED_ON(64) int p[CV_HAAR_FEATURE_MAX][4];
+    //_ALIGNED_ON(16) int p1[CV_HAAR_FEATURE_MAX] ;
+    //_ALIGNED_ON(16) int p2[CV_HAAR_FEATURE_MAX] ;
+    //_ALIGNED_ON(16) int p3[CV_HAAR_FEATURE_MAX] ;
+    /*_ALIGNED_ON(16)*/
+    float weight[CV_HAAR_FEATURE_MAX] ;
+    /*_ALIGNED_ON(4)*/
+    float threshold ;
+    _ALIGNED_ON(8) float alpha[2] ;
+    _ALIGNED_ON(4) int left ;
+    _ALIGNED_ON(4) int right ;
+    // GpuHidHaarFeature feature __attribute__((aligned (128)));
+}
+GpuHidHaarTreeNode;
+
+
+typedef  _ALIGNED_ON(32) struct  GpuHidHaarClassifier
+{
+    _ALIGNED_ON(4) int count;
+    //CvHaarFeature* orig_feature;
+    _ALIGNED_ON(8) GpuHidHaarTreeNode *node ;
+    _ALIGNED_ON(8) float *alpha ;
+}
+GpuHidHaarClassifier;
+
+
+typedef _ALIGNED_ON(64) struct   GpuHidHaarStageClassifier
+{
+    _ALIGNED_ON(4) int  count ;
+    _ALIGNED_ON(4) float threshold ;
+    _ALIGNED_ON(4) int two_rects ;
+    _ALIGNED_ON(8) GpuHidHaarClassifier *classifier ;
+    _ALIGNED_ON(8) struct GpuHidHaarStageClassifier *next;
+    _ALIGNED_ON(8) struct GpuHidHaarStageClassifier *child ;
+    _ALIGNED_ON(8) struct GpuHidHaarStageClassifier *parent ;
+}
+GpuHidHaarStageClassifier;
+
+
+typedef _ALIGNED_ON(64) struct  GpuHidHaarClassifierCascade
+{
+    _ALIGNED_ON(4) int  count ;
+    _ALIGNED_ON(4) int  is_stump_based ;
+    _ALIGNED_ON(4) int  has_tilted_features ;
+    _ALIGNED_ON(4) int  is_tree ;
+    _ALIGNED_ON(4) int pq0 ;
+    _ALIGNED_ON(4) int pq1 ;
+    _ALIGNED_ON(4) int pq2 ;
+    _ALIGNED_ON(4) int pq3 ;
+    _ALIGNED_ON(4) int p0 ;
+    _ALIGNED_ON(4) int p1 ;
+    _ALIGNED_ON(4) int p2 ;
+    _ALIGNED_ON(4) int p3 ;
+    _ALIGNED_ON(4) float inv_window_area ;
+    // GpuHidHaarStageClassifier* stage_classifier __attribute__((aligned (8)));
+} GpuHidHaarClassifierCascade;
+#else
+#define _ALIGNED_ON(_ALIGNMENT) __attribute__((aligned(_ALIGNMENT) ))
+
+typedef struct _ALIGNED_ON(128) GpuHidHaarFeature
+{
+    struct _ALIGNED_ON(32)
+{
+    int    p0 _ALIGNED_ON(4);
+    int    p1 _ALIGNED_ON(4);
+    int    p2 _ALIGNED_ON(4);
+    int    p3 _ALIGNED_ON(4);
+    float weight  _ALIGNED_ON(4);
+}
+rect[CV_HAAR_FEATURE_MAX] _ALIGNED_ON(32);
+}
+GpuHidHaarFeature;
+
+
+typedef struct _ALIGNED_ON(128) GpuHidHaarTreeNode
+{
+    int p[CV_HAAR_FEATURE_MAX][4] _ALIGNED_ON(64);
+    float weight[CV_HAAR_FEATURE_MAX];// _ALIGNED_ON(16);
+    float threshold;// _ALIGNED_ON(4);
+    float alpha[2] _ALIGNED_ON(8);
+    int left _ALIGNED_ON(4);
+    int right _ALIGNED_ON(4);
+}
+GpuHidHaarTreeNode;
+
+typedef struct _ALIGNED_ON(32) GpuHidHaarClassifier
+{
+    int count _ALIGNED_ON(4);
+    GpuHidHaarTreeNode *node _ALIGNED_ON(8);
+    float *alpha _ALIGNED_ON(8);
+}
+GpuHidHaarClassifier;
+
+
+typedef struct _ALIGNED_ON(64) GpuHidHaarStageClassifier
+{
+    int  count _ALIGNED_ON(4);
+    float threshold _ALIGNED_ON(4);
+    int two_rects _ALIGNED_ON(4);
+    GpuHidHaarClassifier *classifier _ALIGNED_ON(8);
+    struct GpuHidHaarStageClassifier *next _ALIGNED_ON(8);
+    struct GpuHidHaarStageClassifier *child _ALIGNED_ON(8);
+    struct GpuHidHaarStageClassifier *parent _ALIGNED_ON(8);
+}
+GpuHidHaarStageClassifier;
+
+
+typedef struct _ALIGNED_ON(64) GpuHidHaarClassifierCascade
+{
+    int  count _ALIGNED_ON(4);
+    int  is_stump_based _ALIGNED_ON(4);
+    int  has_tilted_features _ALIGNED_ON(4);
+    int  is_tree _ALIGNED_ON(4);
+    int pq0 _ALIGNED_ON(4);
+    int pq1 _ALIGNED_ON(4);
+    int pq2 _ALIGNED_ON(4);
+    int pq3 _ALIGNED_ON(4);
+    int p0 _ALIGNED_ON(4);
+    int p1 _ALIGNED_ON(4);
+    int p2 _ALIGNED_ON(4);
+    int p3 _ALIGNED_ON(4);
+    float inv_window_area _ALIGNED_ON(4);
+    // GpuHidHaarStageClassifier* stage_classifier __attribute__((aligned (8)));
+} GpuHidHaarClassifierCascade;
+#endif
+
+const int icv_object_win_border = 1;
+const float icv_stage_threshold_bias = 0.0001f;
+double globaltime = 0;
+
+
+CvHaarClassifierCascade*
+gpuCreateHaarClassifierCascade( int stage_count )
+{
+    CvHaarClassifierCascade *cascade = 0;
+
+    int block_size = sizeof(*cascade) + stage_count * sizeof(*cascade->stage_classifier);
+
+    if( stage_count <= 0 )
+        CV_Error( CV_StsOutOfRange, "Number of stages should be positive" );
+
+    cascade = (CvHaarClassifierCascade *)cvAlloc( block_size );
+    memset( cascade, 0, block_size );
+
+    cascade->stage_classifier = (CvHaarStageClassifier *)(cascade + 1);
+    cascade->flags = CV_HAAR_MAGIC_VAL;
+    cascade->count = stage_count;
+
+    return cascade;
+}
+
+//static int globalcounter = 0;
+
+void
+gpuReleaseHidHaarClassifierCascade( GpuHidHaarClassifierCascade **_cascade )
+{
+    if( _cascade && *_cascade )
+    {
+        cvFree( _cascade );
+    }
+}
+
+/* create more efficient internal representation of haar classifier cascade */
+GpuHidHaarClassifierCascade*
+gpuCreateHidHaarClassifierCascade( CvHaarClassifierCascade *cascade, int *size, int *totalclassifier)
+{
+    GpuHidHaarClassifierCascade *out = 0;
+
+    int i, j, k, l;
+    int datasize;
+    int total_classifiers = 0;
+    int total_nodes = 0;
+    char errorstr[100];
+
+    GpuHidHaarStageClassifier *stage_classifier_ptr;
+    GpuHidHaarClassifier *haar_classifier_ptr;
+    GpuHidHaarTreeNode *haar_node_ptr;
+
+    CvSize orig_window_size;
+    int has_tilted_features = 0;
+
+    if( !CV_IS_HAAR_CLASSIFIER(cascade) )
+        CV_Error( !cascade ? CV_StsNullPtr : CV_StsBadArg, "Invalid classifier pointer" );
+
+    if( cascade->hid_cascade )
+        CV_Error( CV_StsError, "hid_cascade has been already created" );
+
+    if( !cascade->stage_classifier )
+        CV_Error( CV_StsNullPtr, "" );
+
+    if( cascade->count <= 0 )
+        CV_Error( CV_StsOutOfRange, "Negative number of cascade stages" );
+
+    orig_window_size = cascade->orig_window_size;
+
+    /* check input structure correctness and calculate total memory size needed for
+    internal representation of the classifier cascade */
+    for( i = 0; i < cascade->count; i++ )
+    {
+        CvHaarStageClassifier *stage_classifier = cascade->stage_classifier + i;
+
+        if( !stage_classifier->classifier ||
+                stage_classifier->count <= 0 )
+        {
+            sprintf( errorstr, "header of the stage classifier #%d is invalid "
+                     "(has null pointers or non-positive classfier count)", i );
+            CV_Error( CV_StsError, errorstr );
+        }
+
+        total_classifiers += stage_classifier->count;
+
+        for( j = 0; j < stage_classifier->count; j++ )
+        {
+            CvHaarClassifier *classifier = stage_classifier->classifier + j;
+
+            total_nodes += classifier->count;
+            for( l = 0; l < classifier->count; l++ )
+            {
+                for( k = 0; k < CV_HAAR_FEATURE_MAX; k++ )
+                {
+                    if( classifier->haar_feature[l].rect[k].r.width )
+                    {
+                        CvRect r = classifier->haar_feature[l].rect[k].r;
+                        int tilted = classifier->haar_feature[l].tilted;
+                        has_tilted_features |= tilted != 0;
+                        if( r.width < 0 || r.height < 0 || r.y < 0 ||
+                                r.x + r.width > orig_window_size.width
+                                ||
+                                (!tilted &&
+                                 (r.x < 0 || r.y + r.height > orig_window_size.height))
+                                ||
+                                (tilted && (r.x - r.height < 0 ||
+                                            r.y + r.width + r.height > orig_window_size.height)))
+                        {
+                            sprintf( errorstr, "rectangle #%d of the classifier #%d of "
+                                     "the stage classifier #%d is not inside "
+                                     "the reference (original) cascade window", k, j, i );
+                            CV_Error( CV_StsNullPtr, errorstr );
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    // this is an upper boundary for the whole hidden cascade size
+    datasize = sizeof(GpuHidHaarClassifierCascade)                   +
+               sizeof(GpuHidHaarStageClassifier) * cascade->count    +
+               sizeof(GpuHidHaarClassifier)      * total_classifiers +
+               sizeof(GpuHidHaarTreeNode)        * total_nodes;
+
+    *totalclassifier = total_classifiers;
+    *size = datasize;
+    out = (GpuHidHaarClassifierCascade *)cvAlloc( datasize );
+    memset( out, 0, sizeof(*out) );
+
+    /* init header */
+    out->count = cascade->count;
+    stage_classifier_ptr = (GpuHidHaarStageClassifier *)(out + 1);
+    haar_classifier_ptr = (GpuHidHaarClassifier *)(stage_classifier_ptr + cascade->count);
+    haar_node_ptr = (GpuHidHaarTreeNode *)(haar_classifier_ptr + total_classifiers);
+
+    out->is_stump_based = 1;
+    out->has_tilted_features = has_tilted_features;
+    out->is_tree = 0;
+
+    /* initialize internal representation */
+    for( i = 0; i < cascade->count; i++ )
+    {
+        CvHaarStageClassifier *stage_classifier = cascade->stage_classifier + i;
+        GpuHidHaarStageClassifier *hid_stage_classifier = stage_classifier_ptr + i;
+
+        hid_stage_classifier->count = stage_classifier->count;
+        hid_stage_classifier->threshold = stage_classifier->threshold - icv_stage_threshold_bias;
+        hid_stage_classifier->classifier = haar_classifier_ptr;
+        hid_stage_classifier->two_rects = 1;
+        haar_classifier_ptr += stage_classifier->count;
+
+        /*
+        hid_stage_classifier->parent = (stage_classifier->parent == -1)
+        ? NULL : stage_classifier_ptr + stage_classifier->parent;
+        hid_stage_classifier->next = (stage_classifier->next == -1)
+        ? NULL : stage_classifier_ptr + stage_classifier->next;
+        hid_stage_classifier->child = (stage_classifier->child == -1)
+        ? NULL : stage_classifier_ptr + stage_classifier->child;
+
+        out->is_tree |= hid_stage_classifier->next != NULL;
+        */
+
+        for( j = 0; j < stage_classifier->count; j++ )
+        {
+            CvHaarClassifier *classifier         = stage_classifier->classifier + j;
+            GpuHidHaarClassifier *hid_classifier = hid_stage_classifier->classifier + j;
+            int node_count = classifier->count;
+
+            //   float* alpha_ptr = (float*)(haar_node_ptr + node_count);
+            float *alpha_ptr = &haar_node_ptr->alpha[0];
+
+            hid_classifier->count = node_count;
+            hid_classifier->node = haar_node_ptr;
+            hid_classifier->alpha = alpha_ptr;
+
+            for( l = 0; l < node_count; l++ )
+            {
+                GpuHidHaarTreeNode *node     = hid_classifier->node + l;
+                CvHaarFeature      *feature = classifier->haar_feature + l;
+
+                memset( node, -1, sizeof(*node) );
+                node->threshold = classifier->threshold[l];
+                node->left      = classifier->left[l];
+                node->right     = classifier->right[l];
+
+                if( fabs(feature->rect[2].weight) < DBL_EPSILON ||
+                        feature->rect[2].r.width == 0 ||
+                        feature->rect[2].r.height == 0 )
+                {
+                    node->p[2][0] = 0;
+                    node->p[2][1] = 0;
+                    node->p[2][2] = 0;
+                    node->p[2][3] = 0;
+                    node->weight[2] = 0;
+                }
+                //   memset( &(node->feature.rect[2]), 0, sizeof(node->feature.rect[2]) );
+                else
+                    hid_stage_classifier->two_rects = 0;
+            }
+
+            memcpy( alpha_ptr, classifier->alpha, (node_count + 1)*sizeof(alpha_ptr[0]));
+            haar_node_ptr = haar_node_ptr + 1;
+            // (GpuHidHaarTreeNode*)cvAlignPtr(alpha_ptr+node_count+1, sizeof(void*));
+            //   (GpuHidHaarTreeNode*)(alpha_ptr+node_count+1);
+
+            out->is_stump_based &= node_count == 1;
+        }
+    }
+
+    cascade->hid_cascade = (CvHidHaarClassifierCascade *)out;
+    assert( (char *)haar_node_ptr - (char *)out <= datasize );
+
+    return out;
+}
+
+
+#define sum_elem_ptr(sum,row,col)  \
+       ((sumtype*)CV_MAT_ELEM_PTR_FAST((sum),(row),(col),sizeof(sumtype)))
+
+#define sqsum_elem_ptr(sqsum,row,col)  \
+       ((sqsumtype*)CV_MAT_ELEM_PTR_FAST((sqsum),(row),(col),sizeof(sqsumtype)))
+
+#define calc_sum(rect,offset) \
+       ((rect).p0[offset] - (rect).p1[offset] - (rect).p2[offset] + (rect).p3[offset])
+
+
+CV_IMPL void
+gpuSetImagesForHaarClassifierCascade( CvHaarClassifierCascade *_cascade,
+                                      /*   const CvArr* _sum,
+                                      const CvArr* _sqsum,
+                                      const CvArr* _tilted_sum,*/
+                                      double scale,
+                                      int step)
+{
+    //   CvMat sum_stub, *sum = (CvMat*)_sum;
+    //   CvMat sqsum_stub, *sqsum = (CvMat*)_sqsum;
+    //   CvMat tilted_stub, *tilted = (CvMat*)_tilted_sum;
+    GpuHidHaarClassifierCascade *cascade;
+    int coi0 = 0, coi1 = 0;
+    int i;
+    int datasize;
+    int total;
+    CvRect equRect;
+    double weight_scale;
+    GpuHidHaarStageClassifier *stage_classifier;
+
+    if( !CV_IS_HAAR_CLASSIFIER(_cascade) )
+        CV_Error( !_cascade ? CV_StsNullPtr : CV_StsBadArg, "Invalid classifier pointer" );
+
+    if( scale <= 0 )
+        CV_Error( CV_StsOutOfRange, "Scale must be positive" );
+
+    //   sum = cvGetMat( sum, &sum_stub, &coi0 );
+    //   sqsum = cvGetMat( sqsum, &sqsum_stub, &coi1 );
+
+    if( coi0 || coi1 )
+        CV_Error( CV_BadCOI, "COI is not supported" );
+
+    //   if( !CV_ARE_SIZES_EQ( sum, sqsum ))
+    //       CV_Error( CV_StsUnmatchedSizes, "All integral images must have the same size" );
+
+    //   if( CV_MAT_TYPE(sqsum->type) != CV_64FC1 ||
+    //       CV_MAT_TYPE(sum->type) != CV_32SC1 )
+    //       CV_Error( CV_StsUnsupportedFormat,
+    //       "Only (32s, 64f, 32s) combination of (sum,sqsum,tilted_sum) formats is allowed" );
+
+    if( !_cascade->hid_cascade )
+        gpuCreateHidHaarClassifierCascade(_cascade, &datasize, &total);
+
+    cascade = (GpuHidHaarClassifierCascade *) _cascade->hid_cascade;
+    stage_classifier = (GpuHidHaarStageClassifier *) (cascade + 1);
+
+    if( cascade->has_tilted_features )
+    {
+        //    tilted = cvGetMat( tilted, &tilted_stub, &coi1 );
+
+        //    if( CV_MAT_TYPE(tilted->type) != CV_32SC1 )
+        //        CV_Error( CV_StsUnsupportedFormat,
+        //        "Only (32s, 64f, 32s) combination of (sum,sqsum,tilted_sum) formats is allowed" );
+
+        //    if( sum->step != tilted->step )
+        //        CV_Error( CV_StsUnmatchedSizes,
+        //        "Sum and tilted_sum must have the same stride (step, widthStep)" );
+
+        //    if( !CV_ARE_SIZES_EQ( sum, tilted ))
+        //        CV_Error( CV_StsUnmatchedSizes, "All integral images must have the same size" );
+        //  cascade->tilted = *tilted;
+    }
+
+    _cascade->scale = scale;
+    _cascade->real_window_size.width = cvRound( _cascade->orig_window_size.width * scale );
+    _cascade->real_window_size.height = cvRound( _cascade->orig_window_size.height * scale );
+
+    //cascade->sum = *sum;
+    //cascade->sqsum = *sqsum;
+
+    equRect.x = equRect.y = cvRound(scale);
+    equRect.width = cvRound((_cascade->orig_window_size.width - 2) * scale);
+    equRect.height = cvRound((_cascade->orig_window_size.height - 2) * scale);
+    weight_scale = 1. / (equRect.width * equRect.height);
+    cascade->inv_window_area = weight_scale;
+
+    // cascade->pq0 = equRect.y * step + equRect.x;
+    // cascade->pq1 = equRect.y * step + equRect.x + equRect.width ;
+    // cascade->pq2 = (equRect.y + equRect.height)*step + equRect.x;
+    // cascade->pq3 = (equRect.y + equRect.height)*step + equRect.x + equRect.width ;
+
+    cascade->pq0 = equRect.x;
+    cascade->pq1 = equRect.y;
+    cascade->pq2 = equRect.x + equRect.width;
+    cascade->pq3 = equRect.y + equRect.height;
+
+    cascade->p0 = equRect.x;
+    cascade->p1 = equRect.y;
+    cascade->p2 = equRect.x + equRect.width;
+    cascade->p3 = equRect.y + equRect.height;
+
+
+    /* init pointers in haar features according to real window size and
+    given image pointers */
+    for( i = 0; i < _cascade->count; i++ )
+    {
+        int j, k, l;
+        for( j = 0; j < stage_classifier[i].count; j++ )
+        {
+            for( l = 0; l < stage_classifier[i].classifier[j].count; l++ )
+            {
+                CvHaarFeature *feature =
+                    &_cascade->stage_classifier[i].classifier[j].haar_feature[l];
+                /*  GpuHidHaarClassifier* classifier =
+                cascade->stage_classifier[i].classifier + j; */
+                //GpuHidHaarFeature* hidfeature =
+                //    &cascade->stage_classifier[i].classifier[j].node[l].feature;
+                GpuHidHaarTreeNode *hidnode = &stage_classifier[i].classifier[j].node[l];
+                double sum0 = 0, area0 = 0;
+                CvRect r[3];
+
+                int base_w = -1, base_h = -1;
+                int new_base_w = 0, new_base_h = 0;
+                int kx, ky;
+                int flagx = 0, flagy = 0;
+                int x0 = 0, y0 = 0;
+                int nr;
+
+                /* align blocks */
+                for( k = 0; k < CV_HAAR_FEATURE_MAX; k++ )
+                {
+                    //if( !hidfeature->rect[k].p0 )
+                    //    break;
+                    if(!hidnode->p[k][0])
+                        break;
+                    r[k] = feature->rect[k].r;
+                    base_w = (int)CV_IMIN( (unsigned)base_w, (unsigned)(r[k].width - 1) );
+                    base_w = (int)CV_IMIN( (unsigned)base_w, (unsigned)(r[k].x - r[0].x - 1) );
+                    base_h = (int)CV_IMIN( (unsigned)base_h, (unsigned)(r[k].height - 1) );
+                    base_h = (int)CV_IMIN( (unsigned)base_h, (unsigned)(r[k].y - r[0].y - 1) );
+                }
+
+                nr = k;
+                base_w += 1;
+                base_h += 1;
+                if(base_w == 0)
+                    base_w = 1;
+                kx = r[0].width / base_w;
+                if(base_h == 0)
+                    base_h = 1;
+                ky = r[0].height / base_h;
+
+                if( kx <= 0 )
+                {
+                    flagx = 1;
+                    new_base_w = cvRound( r[0].width * scale ) / kx;
+                    x0 = cvRound( r[0].x * scale );
+                }
+
+                if( ky <= 0 )
+                {
+                    flagy = 1;
+                    new_base_h = cvRound( r[0].height * scale ) / ky;
+                    y0 = cvRound( r[0].y * scale );
+                }
+
+                for( k = 0; k < nr; k++ )
+                {
+                    CvRect tr;
+                    double correction_ratio;
+
+                    if( flagx )
+                    {
+                        tr.x = (r[k].x - r[0].x) * new_base_w / base_w + x0;
+                        tr.width = r[k].width * new_base_w / base_w;
+                    }
+                    else
+                    {
+                        tr.x = cvRound( r[k].x * scale );
+                        tr.width = cvRound( r[k].width * scale );
+                    }
+
+                    if( flagy )
+                    {
+                        tr.y = (r[k].y - r[0].y) * new_base_h / base_h + y0;
+                        tr.height = r[k].height * new_base_h / base_h;
+                    }
+                    else
+                    {
+                        tr.y = cvRound( r[k].y * scale );
+                        tr.height = cvRound( r[k].height * scale );
+                    }
+
+#if CV_ADJUST_WEIGHTS
+                    {
+                        // RAINER START
+                        const float orig_feature_size =  (float)(feature->rect[k].r.width) * feature->rect[k].r.height;
+                        const float orig_norm_size = (float)(_cascade->orig_window_size.width) * (_cascade->orig_window_size.height);
+                        const float feature_size = float(tr.width * tr.height);
+                        //const float normSize    = float(equRect.width*equRect.height);
+                        float target_ratio = orig_feature_size / orig_norm_size;
+                        //float isRatio = featureSize / normSize;
+                        //correctionRatio = targetRatio / isRatio / normSize;
+                        correction_ratio = target_ratio / feature_size;
+                        // RAINER END
+                    }
+#else
+                    correction_ratio = weight_scale * (!feature->tilted ? 1 : 0.5);
+#endif
+
+                    if( !feature->tilted )
+                    {
+                        /*     hidfeature->rect[k].p0 = tr.y * sum->cols + tr.x;
+                        hidfeature->rect[k].p1 = tr.y * sum->cols + tr.x + tr.width;
+                        hidfeature->rect[k].p2 = (tr.y + tr.height) * sum->cols + tr.x;
+                        hidfeature->rect[k].p3 = (tr.y + tr.height) * sum->cols + tr.x + tr.width;
+                        */
+                        /*hidnode->p0[k] = tr.y * step + tr.x;
+                        hidnode->p1[k] = tr.y * step + tr.x + tr.width;
+                        hidnode->p2[k] = (tr.y + tr.height) * step + tr.x;
+                        hidnode->p3[k] = (tr.y + tr.height) * step + tr.x + tr.width;*/
+                        hidnode->p[k][0] = tr.x;
+                        hidnode->p[k][1] = tr.y;
+                        hidnode->p[k][2] = tr.x + tr.width;
+                        hidnode->p[k][3] = tr.y + tr.height;
+                    }
+                    else
+                    {
+                        /*    hidfeature->rect[k].p2 = (tr.y + tr.width) * tilted->cols + tr.x + tr.width;
+                        hidfeature->rect[k].p3 = (tr.y + tr.width + tr.height) * tilted->cols + tr.x + tr.width - tr.height;
+                        hidfeature->rect[k].p0 = tr.y * tilted->cols + tr.x;
+                        hidfeature->rect[k].p1 = (tr.y + tr.height) * tilted->cols + tr.x - tr.height;
+                        */
+
+                        hidnode->p[k][2] = (tr.y + tr.width) * step + tr.x + tr.width;
+                        hidnode->p[k][3] = (tr.y + tr.width + tr.height) * step + tr.x + tr.width - tr.height;
+                        hidnode->p[k][0] = tr.y * step + tr.x;
+                        hidnode->p[k][1] = (tr.y + tr.height) * step + tr.x - tr.height;
+                    }
+
+                    //hidfeature->rect[k].weight = (float)(feature->rect[k].weight * correction_ratio);
+                    hidnode->weight[k] = (float)(feature->rect[k].weight * correction_ratio);
+                    if( k == 0 )
+                        area0 = tr.width * tr.height;
+                    else
+                        //sum0 += hidfeature->rect[k].weight * tr.width * tr.height;
+                        sum0 += hidnode->weight[k] * tr.width * tr.height;
+                }
+
+                // hidfeature->rect[0].weight = (float)(-sum0/area0);
+                hidnode->weight[0] = (float)(-sum0 / area0);
+            } /* l */
+        } /* j */
+    }
+}
+CV_IMPL void
+gpuSetHaarClassifierCascade( CvHaarClassifierCascade *_cascade
+                             /*double scale=0.0,*/
+                             /*int step*/)
+{
+    GpuHidHaarClassifierCascade *cascade;
+    int i;
+    int datasize;
+    int total;
+    CvRect equRect;
+    double weight_scale;
+    GpuHidHaarStageClassifier *stage_classifier;
+
+    if( !CV_IS_HAAR_CLASSIFIER(_cascade) )
+        CV_Error( !_cascade ? CV_StsNullPtr : CV_StsBadArg, "Invalid classifier pointer" );
+
+    if( !_cascade->hid_cascade )
+        gpuCreateHidHaarClassifierCascade(_cascade, &datasize, &total);
+
+    cascade = (GpuHidHaarClassifierCascade *) _cascade->hid_cascade;
+    stage_classifier = (GpuHidHaarStageClassifier *) cascade + 1;
+
+    _cascade->scale = 1.0;
+    _cascade->real_window_size.width =  _cascade->orig_window_size.width ;
+    _cascade->real_window_size.height = _cascade->orig_window_size.height;
+
+    equRect.x = equRect.y = 1;
+    equRect.width = _cascade->orig_window_size.width - 2;
+    equRect.height = _cascade->orig_window_size.height - 2;
+    weight_scale = 1;
+    cascade->inv_window_area = weight_scale;
+
+    cascade->p0 = equRect.x;
+    cascade->p1 = equRect.y;
+    cascade->p2 = equRect.height;
+    cascade->p3 = equRect.width ;
+    for( i = 0; i < _cascade->count; i++ )
+    {
+        int j, k, l;
+        for( j = 0; j < stage_classifier[i].count; j++ )
+        {
+            for( l = 0; l < stage_classifier[i].classifier[j].count; l++ )
+            {
+                CvHaarFeature *feature =
+                    &_cascade->stage_classifier[i].classifier[j].haar_feature[l];
+                GpuHidHaarTreeNode *hidnode = &stage_classifier[i].classifier[j].node[l];
+                double sum0 = 0, area0 = 0;
+                CvRect r[3];
+
+                int base_w = -1, base_h = -1;
+                int new_base_w = 0, new_base_h = 0;
+                int kx, ky;
+                int flagx = 0, flagy = 0;
+                int x0 = 0, y0 = 0;
+                int nr;
+
+                /* align blocks */
+                for( k = 0; k < CV_HAAR_FEATURE_MAX; k++ )
+                {
+                    if(!hidnode->p[k][0])
+                        break;
+                    r[k] = feature->rect[k].r;
+                    //                                         base_w = (int)CV_IMIN( (unsigned)base_w, (unsigned)(r[k].width-1) );
+                    //                                         base_w = (int)CV_IMIN( (unsigned)base_w, (unsigned)(r[k].x - r[0].x-1) );
+                    //                                         base_h = (int)CV_IMIN( (unsigned)base_h, (unsigned)(r[k].height-1) );
+                    //                                         base_h = (int)CV_IMIN( (unsigned)base_h, (unsigned)(r[k].y - r[0].y-1) );
+                }
+
+                nr = k;
+                for( k = 0; k < nr; k++ )
+                {
+                    CvRect tr;
+                    double correction_ratio;
+                    tr.x = r[k].x;
+                    tr.width = r[k].width;
+                    tr.y = r[k].y ;
+                    tr.height = r[k].height;
+                    correction_ratio = weight_scale * (!feature->tilted ? 1 : 0.5);
+                    hidnode->p[k][0] = tr.x;
+                    hidnode->p[k][1] = tr.y;
+                    hidnode->p[k][2] = tr.width;
+                    hidnode->p[k][3] = tr.height;
+                    hidnode->weight[k] = (float)(feature->rect[k].weight * correction_ratio);
+                }
+                //hidnode->weight[0]=(float)(-sum0/area0);
+            } /* l */
+        } /* j */
+    }
+}
+CvSeq *cv::ocl::OclCascadeClassifier::oclHaarDetectObjects( oclMat &gimg, CvMemStorage *storage, double scaleFactor,
+        int minNeighbors, int flags, CvSize minSize, CvSize maxSize)
+{
+    CvHaarClassifierCascade *cascade = oldCascade;
+
+    //double alltime = (double)cvGetTickCount();
+    //double t = (double)cvGetTickCount();
+    const double GROUP_EPS = 0.2;
+    oclMat gtemp, gsum1, gtilted1, gsqsum1, gnormImg, gsumcanny;
+    CvSeq *result_seq = 0;
+    cv::Ptr<CvMemStorage> temp_storage;
+
+    cv::ConcurrentRectVector allCandidates;
+    std::vector<cv::Rect> rectList;
+    std::vector<int> rweights;
+    double factor;
+    int coi;
+    int datasize;
+    int totalclassifier;
+
+    void *out;
+    GpuHidHaarClassifierCascade *gcascade;
+    GpuHidHaarStageClassifier    *stage;
+    GpuHidHaarClassifier         *classifier;
+    GpuHidHaarTreeNode           *node;
+
+    int *candidate;
+    cl_int status;
+
+    bool doCannyPruning = (flags & CV_HAAR_DO_CANNY_PRUNING) != 0;
+    bool findBiggestObject = (flags & CV_HAAR_FIND_BIGGEST_OBJECT) != 0;
+    bool roughSearch = (flags & CV_HAAR_DO_ROUGH_SEARCH) != 0;
+
+    //double t = 0;
+    if( maxSize.height == 0 || maxSize.width == 0 )
+    {
+        maxSize.height = gimg.rows;
+        maxSize.width = gimg.cols;
+    }
+
+    if( !CV_IS_HAAR_CLASSIFIER(cascade) )
+        CV_Error( !cascade ? CV_StsNullPtr : CV_StsBadArg, "Invalid classifier cascade" );
+
+    if( !storage )
+        CV_Error( CV_StsNullPtr, "Null storage pointer" );
+
+    if( CV_MAT_DEPTH(gimg.type()) != CV_8U )
+        CV_Error( CV_StsUnsupportedFormat, "Only 8-bit images are supported" );
+
+    if( scaleFactor <= 1 )
+        CV_Error( CV_StsOutOfRange, "scale factor must be > 1" );
+
+    if( findBiggestObject )
+        flags &= ~CV_HAAR_SCALE_IMAGE;
+
+    //gtemp = oclMat( gimg.rows, gimg.cols, CV_8UC1);
+    //gsum1 =  oclMat( gimg.rows + 1, gimg.cols + 1, CV_32SC1 );
+    //gsqsum1 = oclMat( gimg.rows + 1, gimg.cols + 1, CV_32FC1 );
+
+    if( !cascade->hid_cascade )
+        out = (void *)gpuCreateHidHaarClassifierCascade(cascade, &datasize, &totalclassifier);
+    if( cascade->hid_cascade->has_tilted_features )
+        gtilted1 = oclMat( gimg.rows + 1, gimg.cols + 1, CV_32SC1 );
+
+    result_seq = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvAvgComp), storage );
+
+    if( CV_MAT_CN(gimg.type()) > 1 )
+    {
+        cvtColor( gimg, gtemp, CV_BGR2GRAY );
+        gimg = gtemp;
+    }
+
+    if( findBiggestObject )
+        flags &= ~(CV_HAAR_SCALE_IMAGE | CV_HAAR_DO_CANNY_PRUNING);
+    //t = (double)cvGetTickCount() - t;
+    //printf( "before if time = %g ms\n", t/((double)cvGetTickFrequency()*1000.) );
+
+    if( gimg.cols < minSize.width || gimg.rows < minSize.height )
+        CV_Error(CV_StsError, "Image too small");
+
+    if( flags & CV_HAAR_SCALE_IMAGE )
+    {
+        CvSize winSize0 = cascade->orig_window_size;
+        //float scalefactor = 1.1f;
+        //float factor = 1.f;
+        int totalheight = 0;
+        int indexy = 0;
+        CvSize sz;
+        //t = (double)cvGetTickCount();
+        vector<CvSize> sizev;
+        vector<float> scalev;
+        for(factor = 1.f;; factor *= scaleFactor)
+        {
+            CvSize winSize = { cvRound(winSize0.width *factor), cvRound(winSize0.height *factor) };
+            sz.width     = cvRound( gimg.cols / factor ) + 1;
+            sz.height    = cvRound( gimg.rows / factor ) + 1;
+            CvSize sz1     = { sz.width - winSize0.width - 1,      sz.height - winSize0.height - 1 };
+
+            if( sz1.width <= 0 || sz1.height <= 0 )
+                break;
+            if( winSize.width > maxSize.width || winSize.height > maxSize.height )
+                break;
+            if( winSize.width < minSize.width || winSize.height < minSize.height )
+                continue;
+
+            totalheight += sz.height;
+            sizev.push_back(sz);
+            scalev.push_back(factor);
+        }
+        //int flag = 0;
+
+        oclMat gimg1(gimg.rows, gimg.cols, CV_8UC1);
+        oclMat gsum(totalheight, gimg.cols + 1, CV_32SC1);
+        oclMat gsqsum(totalheight, gimg.cols + 1, CV_32FC1);
+
+        //cl_mem cascadebuffer;
+        cl_mem stagebuffer;
+        //cl_mem classifierbuffer;
+        cl_mem nodebuffer;
+        cl_mem candidatebuffer;
+        cl_mem scaleinfobuffer;
+        cl_kernel kernel;
+        kernel = openCLGetKernelFromSource(gimg.clCxt, &haarobjectdetect, "gpuRunHaarClassifierCascade");
+        cv::Rect roi, roi2;
+        cv::Mat imgroi, imgroisq;
+        cv::ocl::oclMat resizeroi, gimgroi, gimgroisq;
+        int grp_per_CU = 12;
+
+        size_t blocksize = 8;
+        size_t localThreads[3] = { blocksize, blocksize , 1 };
+        size_t globalThreads[3] = { grp_per_CU * ((gsum.clCxt)->impl->maxComputeUnits) *localThreads[0],
+                                    localThreads[1], 1
+                                  };
+        int outputsz = 256 * globalThreads[0] / localThreads[0];
+        int loopcount = sizev.size();
+        detect_piramid_info *scaleinfo = (detect_piramid_info *)malloc(sizeof(detect_piramid_info) * loopcount);
+
+        //t = (double)cvGetTickCount() - t;
+        // printf( "pre time = %g ms\n", t/((double)cvGetTickFrequency()*1000.) );
+        //int *it =scaleinfo;
+        // t = (double)cvGetTickCount();
+
+        for( int i = 0; i < loopcount; i++ )
+        {
+            sz = sizev[i];
+            factor = scalev[i];
+            roi = Rect(0, indexy, sz.width, sz.height);
+            roi2 = Rect(0, 0, sz.width - 1, sz.height - 1);
+            resizeroi = gimg1(roi2);
+            gimgroi = gsum(roi);
+            gimgroisq = gsqsum(roi);
+            //scaleinfo[i].rows = gimgroi.rows;
+            int ystep = 1; // factor > 2 ? 1 : 2;
+            int width = gimgroi.cols - 1 - cascade->orig_window_size.width;
+            int height = gimgroi.rows - 1 - cascade->orig_window_size.height;
+            scaleinfo[i].width_height = (width << 16) | height;
+
+
+            int grpnumperline = (width + localThreads[0] - 1) / localThreads[0];
+            int totalgrp = ((height + localThreads[1] - 1) / localThreads[1]) * grpnumperline;
+            //outputsz +=width*height;
+
+            scaleinfo[i].grpnumperline_totalgrp = (grpnumperline << 16) | totalgrp;
+            scaleinfo[i].imgoff = gimgroi.offset >> 2;
+            scaleinfo[i].factor = factor;
+            //printf("rows = %d,ystep = %d,width = %d,height = %d,grpnumperline = %d,totalgrp = %d,imgoff = %d,factor = %f\n",
+            // scaleinfo[i].rows,scaleinfo[i].ystep,scaleinfo[i].width,scaleinfo[i].height,scaleinfo[i].grpnumperline,
+            // scaleinfo[i].totalgrp,scaleinfo[i].imgoff,scaleinfo[i].factor);
+            cv::ocl::resize(gimg, resizeroi, Size(sz.width - 1, sz.height - 1), 0, 0, INTER_LINEAR);
+            //cv::imwrite("D:\\1.jpg",gimg1);
+            cv::ocl::integral(resizeroi, gimgroi, gimgroisq);
+            //cv::ocl::oclMat chk(sz.height,sz.width,CV_32SC1),chksq(sz.height,sz.width,CV_32FC1);
+            //cv::ocl::integral(gimg1, chk, chksq);
+            //double r = cv::norm(chk,gimgroi,NORM_INF);
+            //if(r > std::numeric_limits<double>::epsilon())
+            //{
+            // printf("failed");
+            //}
+            indexy += sz.height;
+        }
+        //int ystep = factor > 2 ? 1 : 2;
+        // t = (double)cvGetTickCount() - t;
+        //printf( "resize integral time = %g ms\n", t/((double)cvGetTickFrequency()*1000.) );
+        //t = (double)cvGetTickCount();
+        gcascade   = (GpuHidHaarClassifierCascade *)cascade->hid_cascade;
+        stage      = (GpuHidHaarStageClassifier *)(gcascade + 1);
+        classifier = (GpuHidHaarClassifier *)(stage + gcascade->count);
+        node       = (GpuHidHaarTreeNode *)(classifier->node);
+
+        //int m,n;
+        //m = (gsum.cols - 1 - cascade->orig_window_size.width  + ystep - 1)/ystep;
+        //n = (gsum.rows - 1 - cascade->orig_window_size.height + ystep - 1)/ystep;
+        //int counter = m*n;
+
+        int nodenum = (datasize - sizeof(GpuHidHaarClassifierCascade) -
+                       sizeof(GpuHidHaarStageClassifier) * gcascade->count - sizeof(GpuHidHaarClassifier) * totalclassifier) / sizeof(GpuHidHaarTreeNode);
+        //if(flag == 0){
+        candidate = (int *)malloc(4 * sizeof(int) * outputsz);
+        //memset((char*)candidate,0,4*sizeof(int)*outputsz);
+        gpuSetImagesForHaarClassifierCascade( cascade,/* &sum1, &sqsum1, _tilted,*/ 1., gsum.step / 4 );
+
+        //cascadebuffer = clCreateBuffer(gsum.clCxt->clContext,CL_MEM_READ_ONLY,sizeof(GpuHidHaarClassifierCascade),NULL,&status);
+        //openCLVerifyCall(status);
+        //openCLSafeCall(clEnqueueWriteBuffer(gsum.clCxt->clCmdQueue,cascadebuffer,1,0,sizeof(GpuHidHaarClassifierCascade),gcascade,0,NULL,NULL));
+
+        stagebuffer = clCreateBuffer(gsum.clCxt->impl->clContext, CL_MEM_READ_ONLY, sizeof(GpuHidHaarStageClassifier) * gcascade->count, NULL, &status);
+        openCLVerifyCall(status);
+        openCLSafeCall(clEnqueueWriteBuffer(gsum.clCxt->impl->clCmdQueue, stagebuffer, 1, 0, sizeof(GpuHidHaarStageClassifier)*gcascade->count, stage, 0, NULL, NULL));
+
+        //classifierbuffer = clCreateBuffer(gsum.clCxt->clContext,CL_MEM_READ_ONLY,sizeof(GpuHidHaarClassifier)*totalclassifier,NULL,&status);
+        //status = clEnqueueWriteBuffer(gsum.clCxt->clCmdQueue,classifierbuffer,1,0,sizeof(GpuHidHaarClassifier)*totalclassifier,classifier,0,NULL,NULL);
+
+        nodebuffer = clCreateBuffer(gsum.clCxt->impl->clContext, CL_MEM_READ_ONLY,
+                                    nodenum * sizeof(GpuHidHaarTreeNode), NULL, &status);
+        openCLVerifyCall(status);
+        openCLSafeCall(clEnqueueWriteBuffer(gsum.clCxt->impl->clCmdQueue, nodebuffer, 1, 0,
+                                            nodenum * sizeof(GpuHidHaarTreeNode),
+                                            node, 0, NULL, NULL));
+        candidatebuffer = clCreateBuffer(gsum.clCxt->impl->clContext, CL_MEM_WRITE_ONLY, 4 * sizeof(int) * outputsz, NULL, &status);
+        openCLVerifyCall(status);
+        scaleinfobuffer = clCreateBuffer(gsum.clCxt->impl->clContext, CL_MEM_READ_ONLY, sizeof(detect_piramid_info) * loopcount, NULL, &status);
+        openCLVerifyCall(status);
+        openCLSafeCall(clEnqueueWriteBuffer(gsum.clCxt->impl->clCmdQueue, scaleinfobuffer, 1, 0, sizeof(detect_piramid_info)*loopcount, scaleinfo, 0, NULL, NULL));
+        //flag  = 1;
+        //}
+
+        //t = (double)cvGetTickCount() - t;
+        //printf( "update time = %g ms\n", t/((double)cvGetTickFrequency()*1000.) );
+
+        //size_t globalThreads[3] = { counter+blocksize*blocksize-counter%(blocksize*blocksize),1,1};
+        //t = (double)cvGetTickCount();
+        int startstage = 0;
+        int endstage = gcascade->count;
+        int startnode = 0;
+        int pixelstep = gsum.step / 4;
+        int splitstage = 3;
+        int splitnode = stage[0].count + stage[1].count + stage[2].count;
+        cl_int4 p, pq;
+        p.s[0] = gcascade->p0;
+        p.s[1] = gcascade->p1;
+        p.s[2] = gcascade->p2;
+        p.s[3] = gcascade->p3;
+        pq.s[0] = gcascade->pq0;
+        pq.s[1] = gcascade->pq1;
+        pq.s[2] = gcascade->pq2;
+        pq.s[3] = gcascade->pq3;
+        float correction = gcascade->inv_window_area;
+        int argcount = 0;
+        //int grpnumperline = ((m + localThreads[0] - 1) / localThreads[0]);
+        //int totalgrp = ((n + localThreads[1] - 1) / localThreads[1])*grpnumperline;
+        openCLVerifyKernel(gsum.clCxt, kernel, &blocksize, globalThreads, localThreads);
+        //openCLSafeCall(clSetKernelArg(kernel,argcount++,sizeof(cl_mem),(void*)&cascadebuffer));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_mem), (void *)&stagebuffer));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_mem), (void *)&scaleinfobuffer));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_mem), (void *)&nodebuffer));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_mem), (void *)&gsum.data));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_mem), (void *)&gsqsum.data));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_mem), (void *)&candidatebuffer));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_int), (void *)&pixelstep));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_int), (void *)&loopcount));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_int), (void *)&startstage));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_int), (void *)&splitstage));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_int), (void *)&endstage));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_int), (void *)&startnode));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_int), (void *)&splitnode));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_int4), (void *)&p));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_int4), (void *)&pq));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_float), (void *)&correction));
+        //openCLSafeCall(clSetKernelArg(kernel,argcount++,sizeof(cl_int),(void*)&n));
+        //openCLSafeCall(clSetKernelArg(kernel,argcount++,sizeof(cl_int),(void*)&grpnumperline));
+        //openCLSafeCall(clSetKernelArg(kernel,argcount++,sizeof(cl_int),(void*)&totalgrp));
+
+        openCLSafeCall(clEnqueueNDRangeKernel(gsum.clCxt->impl->clCmdQueue, kernel, 2, NULL, globalThreads, localThreads, 0, NULL, NULL));
+
+        openCLSafeCall(clFinish(gsum.clCxt->impl->clCmdQueue));
+        //t = (double)cvGetTickCount() - t;
+        //printf( "detection time = %g ms\n", t/((double)cvGetTickFrequency()*1000.) );
+        //t = (double)cvGetTickCount();
+        openCLSafeCall(clEnqueueReadBuffer(gsum.clCxt->impl->clCmdQueue, candidatebuffer, 1, 0, 4 * sizeof(int)*outputsz, candidate, 0, NULL, NULL));
+
+
+        for(int i = 0; i < outputsz; i++)
+            if(candidate[4*i+2] != 0)
+                allCandidates.push_back(Rect(candidate[4*i], candidate[4*i+1], candidate[4*i+2], candidate[4*i+3]));
+        // t = (double)cvGetTickCount() - t;
+        //printf( "post time = %g ms\n", t/((double)cvGetTickFrequency()*1000.) );
+        //t = (double)cvGetTickCount();
+        free(scaleinfo);
+        free(candidate);
+        //openCLSafeCall(clReleaseMemObject(cascadebuffer));
+        openCLSafeCall(clReleaseMemObject(stagebuffer));
+        openCLSafeCall(clReleaseMemObject(scaleinfobuffer));
+        openCLSafeCall(clReleaseMemObject(nodebuffer));
+        openCLSafeCall(clReleaseMemObject(candidatebuffer));
+        openCLSafeCall(clReleaseKernel(kernel));
+        //t = (double)cvGetTickCount() - t;
+        //printf( "release time = %g ms\n", t/((double)cvGetTickFrequency()*1000.) );
+    }
+    else
+    {
+        CvSize winsize0 = cascade->orig_window_size;
+        int n_factors = 0;
+        int flag = 0;
+        oclMat gsum;
+        oclMat gsqsum;
+        cv::ocl::integral(gimg, gsum, gsqsum);
+        CvSize sz;
+        vector<CvSize> sizev;
+        vector<float> scalev;
+        gpuSetHaarClassifierCascade(cascade);
+        gcascade   = (GpuHidHaarClassifierCascade *)cascade->hid_cascade;
+        stage      = (GpuHidHaarStageClassifier *)(gcascade + 1);
+        classifier = (GpuHidHaarClassifier *)(stage + gcascade->count);
+        node       = (GpuHidHaarTreeNode *)(classifier->node);
+        cl_mem stagebuffer;
+        //cl_mem classifierbuffer;
+        cl_mem nodebuffer;
+        cl_mem candidatebuffer;
+        cl_mem scaleinfobuffer;
+        cl_mem pbuffer;
+        cl_mem correctionbuffer;
+        for( n_factors = 0, factor = 1;
+                cvRound(factor * winsize0.width) < gimg.cols - 10 &&
+                cvRound(factor * winsize0.height) < gimg.rows - 10;
+                n_factors++, factor *= scaleFactor )
+        {
+            CvSize winSize = { cvRound( winsize0.width *factor ),
+                               cvRound( winsize0.height *factor )
+                             };
+            if( winSize.width < minSize.width || winSize.height < minSize.height )
+            {
+                continue;
+            }
+            sizev.push_back(winSize);
+            scalev.push_back(factor);
+        }
+        int loopcount = scalev.size();
+        if(loopcount == 0)
+        {
+            loopcount = 1;
+            n_factors = 1;
+            sizev.push_back(minSize);
+            scalev.push_back( min(cvRound(minSize.width / winsize0.width), cvRound(minSize.height / winsize0.height)) );
+
+        }
+        detect_piramid_info *scaleinfo = (detect_piramid_info *)malloc(sizeof(detect_piramid_info) * loopcount);
+        cl_int4 *p = (cl_int4 *)malloc(sizeof(cl_int4) * loopcount);
+        float *correction = (float *)malloc(sizeof(float) * loopcount);
+        int grp_per_CU = 12;
+        size_t blocksize = 8;
+        size_t localThreads[3] = { blocksize, blocksize , 1 };
+        size_t globalThreads[3] = { grp_per_CU *gsum.clCxt->impl->maxComputeUnits *localThreads[0],
+                                    localThreads[1], 1
+                                  };
+        int outputsz = 256 * globalThreads[0] / localThreads[0];
+        int nodenum = (datasize - sizeof(GpuHidHaarClassifierCascade) -
+                       sizeof(GpuHidHaarStageClassifier) * gcascade->count - sizeof(GpuHidHaarClassifier) * totalclassifier) / sizeof(GpuHidHaarTreeNode);
+        nodebuffer = clCreateBuffer(gsum.clCxt->impl->clContext, CL_MEM_READ_ONLY,
+                                    nodenum * sizeof(GpuHidHaarTreeNode), NULL, &status);
+        openCLVerifyCall(status);
+        openCLSafeCall(clEnqueueWriteBuffer(gsum.clCxt->impl->clCmdQueue, nodebuffer, 1, 0,
+                                            nodenum * sizeof(GpuHidHaarTreeNode),
+                                            node, 0, NULL, NULL));
+        cl_mem newnodebuffer = clCreateBuffer(gsum.clCxt->impl->clContext, CL_MEM_READ_WRITE,
+                                              loopcount * nodenum * sizeof(GpuHidHaarTreeNode), NULL, &status);
+        int startstage = 0;
+        int endstage = gcascade->count;
+        cl_kernel kernel;
+        kernel = openCLGetKernelFromSource(gsum.clCxt, &haarobjectdetect_scaled2, "gpuRunHaarClassifierCascade_scaled2");
+        cl_kernel kernel2 = openCLGetKernelFromSource(gimg.clCxt, &haarobjectdetect_scaled2, "gpuscaleclassifier");
+        for(int i = 0; i < loopcount; i++)
+        {
+            sz = sizev[i];
+            factor = scalev[i];
+            int ystep = cvRound(std::max(2., factor));
+            int equRect_x = (int)(factor * gcascade->p0 + 0.5);
+            int equRect_y = (int)(factor * gcascade->p1 + 0.5);
+            int equRect_w = (int)(factor * gcascade->p3 + 0.5);
+            int equRect_h = (int)(factor * gcascade->p2 + 0.5);
+            p[i].s[0] = equRect_x;
+            p[i].s[1] = equRect_y;
+            p[i].s[2] = equRect_x + equRect_w;
+            p[i].s[3] = equRect_y + equRect_h;
+            correction[i] = 1. / (equRect_w * equRect_h);
+            int width = (gsum.cols - 1 - sz.width  + ystep - 1) / ystep;
+            int height = (gsum.rows - 1 - sz.height + ystep - 1) / ystep;
+            int grpnumperline = (width + localThreads[0] - 1) / localThreads[0];
+            int totalgrp = ((height + localThreads[1] - 1) / localThreads[1]) * grpnumperline;
+            //outputsz +=width*height;
+            scaleinfo[i].width_height = (width << 16) | height;
+            scaleinfo[i].grpnumperline_totalgrp = (grpnumperline << 16) | totalgrp;
+            scaleinfo[i].imgoff = 0;
+            scaleinfo[i].factor = factor;
+            int startnodenum = nodenum * i;
+            int argcounts = 0;
+            float factor2 = (float)factor;
+            openCLSafeCall(clSetKernelArg(kernel2, argcounts++, sizeof(cl_mem), (void *)&nodebuffer));
+            openCLSafeCall(clSetKernelArg(kernel2, argcounts++, sizeof(cl_mem), (void *)&newnodebuffer));
+            openCLSafeCall(clSetKernelArg(kernel2, argcounts++, sizeof(cl_float), (void *)&factor2));
+            openCLSafeCall(clSetKernelArg(kernel2, argcounts++, sizeof(cl_float), (void *)&correction[i]));
+            openCLSafeCall(clSetKernelArg(kernel2, argcounts++, sizeof(cl_int), (void *)&startnodenum));
+            size_t globalThreads2[1] = {nodenum};
+            clEnqueueNDRangeKernel(gsum.clCxt->impl->clCmdQueue, kernel2, 1, NULL, globalThreads2, 0, 0, NULL, NULL);
+            clFinish(gsum.clCxt->impl->clCmdQueue);
+        }
+        clReleaseKernel(kernel2);
+        int step = gsum.step / 4;
+        int startnode = 0;
+        int splitstage = 3;
+        int splitnode = stage[0].count + stage[1].count + stage[2].count;
+        stagebuffer = clCreateBuffer(gsum.clCxt->impl->clContext, CL_MEM_READ_ONLY, sizeof(GpuHidHaarStageClassifier) * gcascade->count, NULL, &status);
+        openCLVerifyCall(status);
+        openCLSafeCall(clEnqueueWriteBuffer(gsum.clCxt->impl->clCmdQueue, stagebuffer, 1, 0, sizeof(GpuHidHaarStageClassifier)*gcascade->count, stage, 0, NULL, NULL));
+        candidatebuffer = clCreateBuffer(gsum.clCxt->impl->clContext, CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR, 4 * sizeof(int) * outputsz, NULL, &status);
+        openCLVerifyCall(status);
+        scaleinfobuffer = clCreateBuffer(gsum.clCxt->impl->clContext, CL_MEM_READ_ONLY, sizeof(detect_piramid_info) * loopcount, NULL, &status);
+        openCLVerifyCall(status);
+        openCLSafeCall(clEnqueueWriteBuffer(gsum.clCxt->impl->clCmdQueue, scaleinfobuffer, 1, 0, sizeof(detect_piramid_info)*loopcount, scaleinfo, 0, NULL, NULL));
+        pbuffer = clCreateBuffer(gsum.clCxt->impl->clContext, CL_MEM_READ_ONLY, sizeof(cl_int4) * loopcount, NULL, &status);
+        openCLSafeCall(clEnqueueWriteBuffer(gsum.clCxt->impl->clCmdQueue, pbuffer, 1, 0, sizeof(cl_int4)*loopcount, p, 0, NULL, NULL));
+        correctionbuffer = clCreateBuffer(gsum.clCxt->impl->clContext, CL_MEM_READ_ONLY, sizeof(cl_float) * loopcount, NULL, &status);
+        openCLSafeCall(clEnqueueWriteBuffer(gsum.clCxt->impl->clCmdQueue, correctionbuffer, 1, 0, sizeof(cl_float)*loopcount, correction, 0, NULL, NULL));
+        int argcount = 0;
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_mem), (void *)&stagebuffer));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_mem), (void *)&scaleinfobuffer));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_mem), (void *)&newnodebuffer));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_mem), (void *)&gsum.data));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_mem), (void *)&gsqsum.data));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_mem), (void *)&candidatebuffer));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_int), (void *)&step));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_int), (void *)&loopcount));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_int), (void *)&startstage));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_int), (void *)&splitstage));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_int), (void *)&endstage));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_int), (void *)&startnode));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_int), (void *)&splitnode));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_mem), (void *)&pbuffer));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_mem), (void *)&correctionbuffer));
+        openCLSafeCall(clSetKernelArg(kernel, argcount++, sizeof(cl_int), (void *)&nodenum));
+        openCLSafeCall(clEnqueueNDRangeKernel(gsum.clCxt->impl->clCmdQueue, kernel, 2, NULL, globalThreads, localThreads, 0, NULL, NULL));
+
+        openCLSafeCall(clFinish(gsum.clCxt->impl->clCmdQueue));
+
+        //openCLSafeCall(clEnqueueReadBuffer(gsum.clCxt->clCmdQueue,candidatebuffer,1,0,4*sizeof(int)*outputsz,candidate,0,NULL,NULL));
+        candidate = (int *)clEnqueueMapBuffer(gsum.clCxt->impl->clCmdQueue, candidatebuffer, 1, CL_MAP_READ, 0, 4 * sizeof(int), 0, 0, 0, &status);
+
+        for(int i = 0; i < outputsz; i++)
+        {
+            if(candidate[4*i+2] != 0)
+                allCandidates.push_back(Rect(candidate[4*i], candidate[4*i+1], candidate[4*i+2], candidate[4*i+3]));
+        }
+
+        free(scaleinfo);
+        free(p);
+        free(correction);
+        clEnqueueUnmapMemObject(gsum.clCxt->impl->clCmdQueue, candidatebuffer, candidate, 0, 0, 0);
+        openCLSafeCall(clReleaseMemObject(stagebuffer));
+        openCLSafeCall(clReleaseMemObject(scaleinfobuffer));
+        openCLSafeCall(clReleaseMemObject(nodebuffer));
+        openCLSafeCall(clReleaseMemObject(newnodebuffer));
+        openCLSafeCall(clReleaseMemObject(candidatebuffer));
+        openCLSafeCall(clReleaseMemObject(pbuffer));
+        openCLSafeCall(clReleaseMemObject(correctionbuffer));
+    }
+    //t = (double)cvGetTickCount() ;
+    cvFree(&cascade->hid_cascade);
+    //    printf("%d\n",globalcounter);
+    rectList.resize(allCandidates.size());
+    if(!allCandidates.empty())
+        std::copy(allCandidates.begin(), allCandidates.end(), rectList.begin());
+
+    //cout << "count = " << rectList.size()<< endl;
+
+    if( minNeighbors != 0 || findBiggestObject )
+        groupRectangles(rectList, rweights, std::max(minNeighbors, 1), GROUP_EPS);
+    else
+        rweights.resize(rectList.size(), 0);
+
+
+    if( findBiggestObject && rectList.size() )
+    {
+        CvAvgComp result_comp = {{0, 0, 0, 0}, 0};
+
+        for( size_t i = 0; i < rectList.size(); i++ )
+        {
+            cv::Rect r = rectList[i];
+            if( r.area() > cv::Rect(result_comp.rect).area() )
+            {
+                result_comp.rect = r;
+                result_comp.neighbors = rweights[i];
+            }
+        }
+        cvSeqPush( result_seq, &result_comp );
+    }
+    else
+    {
+        for( size_t i = 0; i < rectList.size(); i++ )
+        {
+            CvAvgComp c;
+            c.rect = rectList[i];
+            c.neighbors = rweights[i];
+            cvSeqPush( result_seq, &c );
+        }
+    }
+    //t = (double)cvGetTickCount() - t;
+    //printf( "get face time = %g ms\n", t/((double)cvGetTickFrequency()*1000.) );
+    //alltime = (double)cvGetTickCount() - alltime;
+    //printf( "all time = %g ms\n", alltime/((double)cvGetTickFrequency()*1000.) );
+    return result_seq;
+}
+
+
+CvHaarClassifierCascade*
+gpuLoadCascadeCART( const char **input_cascade, int n, CvSize orig_window_size )
+{
+    int i;
+    CvHaarClassifierCascade *cascade = gpuCreateHaarClassifierCascade(n);
+    cascade->orig_window_size = orig_window_size;
+
+    for( i = 0; i < n; i++ )
+    {
+        int j, count, l;
+        float threshold = 0;
+        const char *stage = input_cascade[i];
+        int dl = 0;
+
+        /* tree links */
+        int parent = -1;
+        int next = -1;
+
+        sscanf( stage, "%d%n", &count, &dl );
+        stage += dl;
+
+        assert( count > 0 );
+        cascade->stage_classifier[i].count = count;
+        cascade->stage_classifier[i].classifier =
+        (CvHaarClassifier *)cvAlloc( count * sizeof(cascade->stage_classifier[i].classifier[0]));
+
+        for( j = 0; j < count; j++ )
+        {
+            CvHaarClassifier *classifier = cascade->stage_classifier[i].classifier + j;
+            int k, rects = 0;
+            char str[100];
+
+            sscanf( stage, "%d%n", &classifier->count, &dl );
+            stage += dl;
+
+            classifier->haar_feature = (CvHaarFeature *) cvAlloc(
+                classifier->count * ( sizeof( *classifier->haar_feature ) +
+            sizeof( *classifier->threshold ) +
+            sizeof( *classifier->left ) +
+            sizeof( *classifier->right ) ) +
+                (classifier->count + 1) * sizeof( *classifier->alpha ) );
+            classifier->threshold = (float *) (classifier->haar_feature + classifier->count);
+            classifier->left = (int *) (classifier->threshold + classifier->count);
+            classifier->right = (int *) (classifier->left + classifier->count);
+            classifier->alpha = (float *) (classifier->right + classifier->count);
+
+            for( l = 0; l < classifier->count; l++ )
+            {
+                sscanf( stage, "%d%n", &rects, &dl );
+                stage += dl;
+
+                assert( rects >= 2 && rects <= CV_HAAR_FEATURE_MAX );
+
+                for( k = 0; k < rects; k++ )
+                {
+                    CvRect r;
+                    int band = 0;
+                    sscanf( stage, "%d%d%d%d%d%f%n",
+                    &r.x, &r.y, &r.width, &r.height, &band,
+                    &(classifier->haar_feature[l].rect[k].weight), &dl );
+                    stage += dl;
+                    classifier->haar_feature[l].rect[k].r = r;
+                }
+                sscanf( stage, "%s%n", str, &dl );
+                stage += dl;
+
+                classifier->haar_feature[l].tilted = strncmp( str, "tilted", 6 ) == 0;
+
+                for( k = rects; k < CV_HAAR_FEATURE_MAX; k++ )
+                {
+                    memset( classifier->haar_feature[l].rect + k, 0,
+                    sizeof(classifier->haar_feature[l].rect[k]) );
+                }
+
+                sscanf( stage, "%f%d%d%n", &(classifier->threshold[l]),
+                &(classifier->left[l]),
+                &(classifier->right[l]), &dl );
+                stage += dl;
+            }
+            for( l = 0; l <= classifier->count; l++ )
+            {
+                sscanf( stage, "%f%n", &(classifier->alpha[l]), &dl );
+                stage += dl;
+            }
+        }
+
+        sscanf( stage, "%f%n", &threshold, &dl );
+        stage += dl;
+
+        cascade->stage_classifier[i].threshold = threshold;
+
+        /* load tree links */
+        if( sscanf( stage, "%d%d%n", &parent, &next, &dl ) != 2 )
+        {
+            parent = i - 1;
+            next = -1;
+        }
+        stage += dl;
+
+        cascade->stage_classifier[i].parent = parent;
+        cascade->stage_classifier[i].next = next;
+        cascade->stage_classifier[i].child = -1;
+
+        if( parent != -1 && cascade->stage_classifier[parent].child == -1 )
+        {
+            cascade->stage_classifier[parent].child = i;
+        }
+    }
+
+    return cascade;
+}
+
+#ifndef _MAX_PATH
+#define _MAX_PATH 1024
+#endif
+
+CV_IMPL CvHaarClassifierCascade*
+gpuLoadHaarClassifierCascade( const char *directory, CvSize orig_window_size )
+{
+    const char **input_cascade = 0;
+    CvHaarClassifierCascade *cascade = 0;
+
+    int i, n;
+    const char *slash;
+    char name[_MAX_PATH];
+    int size = 0;
+    char *ptr = 0;
+
+    if( !directory )
+        CV_Error( CV_StsNullPtr, "Null path is passed" );
+
+    n = (int)strlen(directory) - 1;
+    slash = directory[n] == '\\' || directory[n] == '/' ? "" : "/";
+
+    /* try to read the classifier from directory */
+    for( n = 0; ; n++ )
+    {
+        sprintf( name, "%s%s%d/AdaBoostCARTHaarClassifier.txt", directory, slash, n );
+        FILE *f = fopen( name, "rb" );
+        if( !f )
+            break;
+        fseek( f, 0, SEEK_END );
+        size += ftell( f ) + 1;
+        fclose(f);
+    }
+
+    if( n == 0 && slash[0] )
+        return (CvHaarClassifierCascade *)cvLoad( directory );
+
+    if( n == 0 )
+        CV_Error( CV_StsBadArg, "Invalid path" );
+
+    size += (n + 1) * sizeof(char *);
+    input_cascade = (const char **)cvAlloc( size );
+    ptr = (char *)(input_cascade + n + 1);
+
+    for( i = 0; i < n; i++ )
+    {
+        sprintf( name, "%s/%d/AdaBoostCARTHaarClassifier.txt", directory, i );
+        FILE *f = fopen( name, "rb" );
+        if( !f )
+            CV_Error( CV_StsError, "" );
+        fseek( f, 0, SEEK_END );
+        size = ftell( f );
+        fseek( f, 0, SEEK_SET );
+        fread( ptr, 1, size, f );
+        fclose(f);
+        input_cascade[i] = ptr;
+        ptr += size;
+        *ptr++ = '\0';
+    }
+
+    input_cascade[n] = 0;
+    cascade = gpuLoadCascadeCART( input_cascade, n, orig_window_size );
+
+    if( input_cascade )
+        cvFree( &input_cascade );
+
+    return cascade;
+}
+
+
+CV_IMPL void
+gpuReleaseHaarClassifierCascade( CvHaarClassifierCascade **_cascade )
+{
+    if( _cascade && *_cascade )
+    {
+        int i, j;
+        CvHaarClassifierCascade *cascade = *_cascade;
+
+        for( i = 0; i < cascade->count; i++ )
+        {
+            for( j = 0; j < cascade->stage_classifier[i].count; j++ )
+                cvFree( &cascade->stage_classifier[i].classifier[j].haar_feature );
+            cvFree( &cascade->stage_classifier[i].classifier );
+        }
+        gpuReleaseHidHaarClassifierCascade( (GpuHidHaarClassifierCascade **)&cascade->hid_cascade );
+        cvFree( _cascade );
+    }
+}
+
+
+/****************************************************************************************\
+*                                  Persistence functions                                 *
+\****************************************************************************************/
+
+/* field names */
+
+#define ICV_HAAR_SIZE_NAME            "size"
+#define ICV_HAAR_STAGES_NAME          "stages"
+#define ICV_HAAR_TREES_NAME             "trees"
+#define ICV_HAAR_FEATURE_NAME             "feature"
+#define ICV_HAAR_RECTS_NAME                 "rects"
+#define ICV_HAAR_TILTED_NAME                "tilted"
+#define ICV_HAAR_THRESHOLD_NAME           "threshold"
+#define ICV_HAAR_LEFT_NODE_NAME           "left_node"
+#define ICV_HAAR_LEFT_VAL_NAME            "left_val"
+#define ICV_HAAR_RIGHT_NODE_NAME          "right_node"
+#define ICV_HAAR_RIGHT_VAL_NAME           "right_val"
+#define ICV_HAAR_STAGE_THRESHOLD_NAME   "stage_threshold"
+#define ICV_HAAR_PARENT_NAME            "parent"
+#define ICV_HAAR_NEXT_NAME              "next"
+
+int
+gpuIsHaarClassifier( const void *struct_ptr )
+{
+    return CV_IS_HAAR_CLASSIFIER( struct_ptr );
+}
+
+void*
+gpuReadHaarClassifier( CvFileStorage *fs, CvFileNode *node )
+{
+    CvHaarClassifierCascade *cascade = NULL;
+
+    char buf[256];
+    CvFileNode *seq_fn = NULL; /* sequence */
+    CvFileNode *fn = NULL;
+    CvFileNode *stages_fn = NULL;
+    CvSeqReader stages_reader;
+    int n;
+    int i, j, k, l;
+    int parent, next;
+
+    stages_fn = cvGetFileNodeByName( fs, node, ICV_HAAR_STAGES_NAME );
+    if( !stages_fn || !CV_NODE_IS_SEQ( stages_fn->tag) )
+        CV_Error( CV_StsError, "Invalid stages node" );
+
+    n = stages_fn->data.seq->total;
+    cascade = gpuCreateHaarClassifierCascade(n);
+
+    /* read size */
+    seq_fn = cvGetFileNodeByName( fs, node, ICV_HAAR_SIZE_NAME );
+    if( !seq_fn || !CV_NODE_IS_SEQ( seq_fn->tag ) || seq_fn->data.seq->total != 2 )
+        CV_Error( CV_StsError, "size node is not a valid sequence." );
+    fn = (CvFileNode *) cvGetSeqElem( seq_fn->data.seq, 0 );
+    if( !CV_NODE_IS_INT( fn->tag ) || fn->data.i <= 0 )
+        CV_Error( CV_StsError, "Invalid size node: width must be positive integer" );
+    cascade->orig_window_size.width = fn->data.i;
+    fn = (CvFileNode *) cvGetSeqElem( seq_fn->data.seq, 1 );
+    if( !CV_NODE_IS_INT( fn->tag ) || fn->data.i <= 0 )
+        CV_Error( CV_StsError, "Invalid size node: height must be positive integer" );
+    cascade->orig_window_size.height = fn->data.i;
+
+    cvStartReadSeq( stages_fn->data.seq, &stages_reader );
+    for( i = 0; i < n; ++i )
+    {
+        CvFileNode *stage_fn;
+        CvFileNode *trees_fn;
+        CvSeqReader trees_reader;
+
+        stage_fn = (CvFileNode *) stages_reader.ptr;
+        if( !CV_NODE_IS_MAP( stage_fn->tag ) )
+        {
+            sprintf( buf, "Invalid stage %d", i );
+            CV_Error( CV_StsError, buf );
+        }
+
+        trees_fn = cvGetFileNodeByName( fs, stage_fn, ICV_HAAR_TREES_NAME );
+        if( !trees_fn || !CV_NODE_IS_SEQ( trees_fn->tag )
+        || trees_fn->data.seq->total <= 0 )
+        {
+            sprintf( buf, "Trees node is not a valid sequence. (stage %d)", i );
+            CV_Error( CV_StsError, buf );
+        }
+
+        cascade->stage_classifier[i].classifier =
+        (CvHaarClassifier *) cvAlloc( trees_fn->data.seq->total
+        * sizeof( cascade->stage_classifier[i].classifier[0] ) );
+        for( j = 0; j < trees_fn->data.seq->total; ++j )
+        {
+            cascade->stage_classifier[i].classifier[j].haar_feature = NULL;
+        }
+        cascade->stage_classifier[i].count = trees_fn->data.seq->total;
+
+        cvStartReadSeq( trees_fn->data.seq, &trees_reader );
+        for( j = 0; j < trees_fn->data.seq->total; ++j )
+        {
+            CvFileNode *tree_fn;
+            CvSeqReader tree_reader;
+            CvHaarClassifier *classifier;
+            int last_idx;
+
+            classifier = &cascade->stage_classifier[i].classifier[j];
+            tree_fn = (CvFileNode *) trees_reader.ptr;
+            if( !CV_NODE_IS_SEQ( tree_fn->tag ) || tree_fn->data.seq->total <= 0 )
+            {
+                sprintf( buf, "Tree node is not a valid sequence."
+                " (stage %d, tree %d)", i, j );
+                CV_Error( CV_StsError, buf );
+            }
+
+            classifier->count = tree_fn->data.seq->total;
+            classifier->haar_feature = (CvHaarFeature *) cvAlloc(
+                classifier->count * ( sizeof( *classifier->haar_feature ) +
+            sizeof( *classifier->threshold ) +
+            sizeof( *classifier->left ) +
+            sizeof( *classifier->right ) ) +
+                (classifier->count + 1) * sizeof( *classifier->alpha ) );
+            classifier->threshold = (float *) (classifier->haar_feature + classifier->count);
+            classifier->left = (int *) (classifier->threshold + classifier->count);
+            classifier->right = (int *) (classifier->left + classifier->count);
+            classifier->alpha = (float *) (classifier->right + classifier->count);
+
+            cvStartReadSeq( tree_fn->data.seq, &tree_reader );
+            for( k = 0, last_idx = 0; k < tree_fn->data.seq->total; ++k )
+            {
+                CvFileNode *node_fn;
+                CvFileNode *feature_fn;
+                CvFileNode *rects_fn;
+                CvSeqReader rects_reader;
+
+                node_fn = (CvFileNode *) tree_reader.ptr;
+                if( !CV_NODE_IS_MAP( node_fn->tag ) )
+                {
+                    sprintf( buf, "Tree node %d is not a valid map. (stage %d, tree %d)",
+                    k, i, j );
+                    CV_Error( CV_StsError, buf );
+                }
+                feature_fn = cvGetFileNodeByName( fs, node_fn, ICV_HAAR_FEATURE_NAME );
+                if( !feature_fn || !CV_NODE_IS_MAP( feature_fn->tag ) )
+                {
+                    sprintf( buf, "Feature node is not a valid map. "
+                    "(stage %d, tree %d, node %d)", i, j, k );
+                    CV_Error( CV_StsError, buf );
+                }
+                rects_fn = cvGetFileNodeByName( fs, feature_fn, ICV_HAAR_RECTS_NAME );
+                if( !rects_fn || !CV_NODE_IS_SEQ( rects_fn->tag )
+                || rects_fn->data.seq->total < 1
+                || rects_fn->data.seq->total > CV_HAAR_FEATURE_MAX )
+                {
+                    sprintf( buf, "Rects node is not a valid sequence. "
+                    "(stage %d, tree %d, node %d)", i, j, k );
+                    CV_Error( CV_StsError, buf );
+                }
+                cvStartReadSeq( rects_fn->data.seq, &rects_reader );
+                for( l = 0; l < rects_fn->data.seq->total; ++l )
+                {
+                    CvFileNode *rect_fn;
+                    CvRect r;
+
+                    rect_fn = (CvFileNode *) rects_reader.ptr;
+                    if( !CV_NODE_IS_SEQ( rect_fn->tag ) || rect_fn->data.seq->total != 5 )
+                    {
+                        sprintf( buf, "Rect %d is not a valid sequence. "
+                        "(stage %d, tree %d, node %d)", l, i, j, k );
+                        CV_Error( CV_StsError, buf );
+                    }
+
+                    fn = CV_SEQ_ELEM( rect_fn->data.seq, CvFileNode, 0 );
+                    if( !CV_NODE_IS_INT( fn->tag ) || fn->data.i < 0 )
+                    {
+                        sprintf( buf, "x coordinate must be non-negative integer. "
+                        "(stage %d, tree %d, node %d, rect %d)", i, j, k, l );
+                        CV_Error( CV_StsError, buf );
+                    }
+                    r.x = fn->data.i;
+                    fn = CV_SEQ_ELEM( rect_fn->data.seq, CvFileNode, 1 );
+                    if( !CV_NODE_IS_INT( fn->tag ) || fn->data.i < 0 )
+                    {
+                        sprintf( buf, "y coordinate must be non-negative integer. "
+                        "(stage %d, tree %d, node %d, rect %d)", i, j, k, l );
+                        CV_Error( CV_StsError, buf );
+                    }
+                    r.y = fn->data.i;
+                    fn = CV_SEQ_ELEM( rect_fn->data.seq, CvFileNode, 2 );
+                    if( !CV_NODE_IS_INT( fn->tag ) || fn->data.i <= 0
+                    || r.x + fn->data.i > cascade->orig_window_size.width )
+                    {
+                        sprintf( buf, "width must be positive integer and "
+                        "(x + width) must not exceed window width. "
+                        "(stage %d, tree %d, node %d, rect %d)", i, j, k, l );
+                        CV_Error( CV_StsError, buf );
+                    }
+                    r.width = fn->data.i;
+                    fn = CV_SEQ_ELEM( rect_fn->data.seq, CvFileNode, 3 );
+                    if( !CV_NODE_IS_INT( fn->tag ) || fn->data.i <= 0
+                    || r.y + fn->data.i > cascade->orig_window_size.height )
+                    {
+                        sprintf( buf, "height must be positive integer and "
+                        "(y + height) must not exceed window height. "
+                        "(stage %d, tree %d, node %d, rect %d)", i, j, k, l );
+                        CV_Error( CV_StsError, buf );
+                    }
+                    r.height = fn->data.i;
+                    fn = CV_SEQ_ELEM( rect_fn->data.seq, CvFileNode, 4 );
+                    if( !CV_NODE_IS_REAL( fn->tag ) )
+                    {
+                        sprintf( buf, "weight must be real number. "
+                        "(stage %d, tree %d, node %d, rect %d)", i, j, k, l );
+                        CV_Error( CV_StsError, buf );
+                    }
+
+                    classifier->haar_feature[k].rect[l].weight = (float) fn->data.f;
+                    classifier->haar_feature[k].rect[l].r = r;
+
+                    CV_NEXT_SEQ_ELEM( sizeof( *rect_fn ), rects_reader );
+                } /* for each rect */
+                for( l = rects_fn->data.seq->total; l < CV_HAAR_FEATURE_MAX; ++l )
+                {
+                    classifier->haar_feature[k].rect[l].weight = 0;
+                    classifier->haar_feature[k].rect[l].r = cvRect( 0, 0, 0, 0 );
+                }
+
+                fn = cvGetFileNodeByName( fs, feature_fn, ICV_HAAR_TILTED_NAME);
+                if( !fn || !CV_NODE_IS_INT( fn->tag ) )
+                {
+                    sprintf( buf, "tilted must be 0 or 1. "
+                    "(stage %d, tree %d, node %d)", i, j, k );
+                    CV_Error( CV_StsError, buf );
+                }
+                classifier->haar_feature[k].tilted = ( fn->data.i != 0 );
+                fn = cvGetFileNodeByName( fs, node_fn, ICV_HAAR_THRESHOLD_NAME);
+                if( !fn || !CV_NODE_IS_REAL( fn->tag ) )
+                {
+                    sprintf( buf, "threshold must be real number. "
+                    "(stage %d, tree %d, node %d)", i, j, k );
+                    CV_Error( CV_StsError, buf );
+                }
+                classifier->threshold[k] = (float) fn->data.f;
+                fn = cvGetFileNodeByName( fs, node_fn, ICV_HAAR_LEFT_NODE_NAME);
+                if( fn )
+                {
+                    if( !CV_NODE_IS_INT( fn->tag ) || fn->data.i <= k
+                    || fn->data.i >= tree_fn->data.seq->total )
+                    {
+                        sprintf( buf, "left node must be valid node number. "
+                        "(stage %d, tree %d, node %d)", i, j, k );
+                        CV_Error( CV_StsError, buf );
+                    }
+                    /* left node */
+                    classifier->left[k] = fn->data.i;
+                }
+                else
+                {
+                    fn = cvGetFileNodeByName( fs, node_fn, ICV_HAAR_LEFT_VAL_NAME );
+                    if( !fn )
+                    {
+                        sprintf( buf, "left node or left value must be specified. "
+                        "(stage %d, tree %d, node %d)", i, j, k );
+                        CV_Error( CV_StsError, buf );
+                    }
+                    if( !CV_NODE_IS_REAL( fn->tag ) )
+                    {
+                        sprintf( buf, "left value must be real number. "
+                        "(stage %d, tree %d, node %d)", i, j, k );
+                        CV_Error( CV_StsError, buf );
+                    }
+                    /* left value */
+                    if( last_idx >= classifier->count + 1 )
+                    {
+                        sprintf( buf, "Tree structure is broken: too many values. "
+                        "(stage %d, tree %d, node %d)", i, j, k );
+                        CV_Error( CV_StsError, buf );
+                    }
+                    classifier->left[k] = -last_idx;
+                    classifier->alpha[last_idx++] = (float) fn->data.f;
+                }
+                fn = cvGetFileNodeByName( fs, node_fn, ICV_HAAR_RIGHT_NODE_NAME);
+                if( fn )
+                {
+                    if( !CV_NODE_IS_INT( fn->tag ) || fn->data.i <= k
+                    || fn->data.i >= tree_fn->data.seq->total )
+                    {
+                        sprintf( buf, "right node must be valid node number. "
+                        "(stage %d, tree %d, node %d)", i, j, k );
+                        CV_Error( CV_StsError, buf );
+                    }
+                    /* right node */
+                    classifier->right[k] = fn->data.i;
+                }
+                else
+                {
+                    fn = cvGetFileNodeByName( fs, node_fn, ICV_HAAR_RIGHT_VAL_NAME );
+                    if( !fn )
+                    {
+                        sprintf( buf, "right node or right value must be specified. "
+                        "(stage %d, tree %d, node %d)", i, j, k );
+                        CV_Error( CV_StsError, buf );
+                    }
+                    if( !CV_NODE_IS_REAL( fn->tag ) )
+                    {
+                        sprintf( buf, "right value must be real number. "
+                        "(stage %d, tree %d, node %d)", i, j, k );
+                        CV_Error( CV_StsError, buf );
+                    }
+                    /* right value */
+                    if( last_idx >= classifier->count + 1 )
+                    {
+                        sprintf( buf, "Tree structure is broken: too many values. "
+                        "(stage %d, tree %d, node %d)", i, j, k );
+                        CV_Error( CV_StsError, buf );
+                    }
+                    classifier->right[k] = -last_idx;
+                    classifier->alpha[last_idx++] = (float) fn->data.f;
+                }
+
+                CV_NEXT_SEQ_ELEM( sizeof( *node_fn ), tree_reader );
+            } /* for each node */
+            if( last_idx != classifier->count + 1 )
+            {
+                sprintf( buf, "Tree structure is broken: too few values. "
+                "(stage %d, tree %d)", i, j );
+                CV_Error( CV_StsError, buf );
+            }
+
+            CV_NEXT_SEQ_ELEM( sizeof( *tree_fn ), trees_reader );
+        } /* for each tree */
+
+        fn = cvGetFileNodeByName( fs, stage_fn, ICV_HAAR_STAGE_THRESHOLD_NAME);
+        if( !fn || !CV_NODE_IS_REAL( fn->tag ) )
+        {
+            sprintf( buf, "stage threshold must be real number. (stage %d)", i );
+            CV_Error( CV_StsError, buf );
+        }
+        cascade->stage_classifier[i].threshold = (float) fn->data.f;
+
+        parent = i - 1;
+        next = -1;
+
+        fn = cvGetFileNodeByName( fs, stage_fn, ICV_HAAR_PARENT_NAME );
+        if( !fn || !CV_NODE_IS_INT( fn->tag )
+        || fn->data.i < -1 || fn->data.i >= cascade->count )
+        {
+            sprintf( buf, "parent must be integer number. (stage %d)", i );
+            CV_Error( CV_StsError, buf );
+        }
+        parent = fn->data.i;
+        fn = cvGetFileNodeByName( fs, stage_fn, ICV_HAAR_NEXT_NAME );
+        if( !fn || !CV_NODE_IS_INT( fn->tag )
+        || fn->data.i < -1 || fn->data.i >= cascade->count )
+        {
+            sprintf( buf, "next must be integer number. (stage %d)", i );
+            CV_Error( CV_StsError, buf );
+        }
+        next = fn->data.i;
+
+        cascade->stage_classifier[i].parent = parent;
+        cascade->stage_classifier[i].next = next;
+        cascade->stage_classifier[i].child = -1;
+
+        if( parent != -1 && cascade->stage_classifier[parent].child == -1 )
+        {
+            cascade->stage_classifier[parent].child = i;
+        }
+
+        CV_NEXT_SEQ_ELEM( sizeof( *stage_fn ), stages_reader );
+    } /* for each stage */
+
+    return cascade;
+}
+
+void
+gpuWriteHaarClassifier( CvFileStorage *fs, const char *name, const void *struct_ptr,
+CvAttrList attributes )
+{
+    int i, j, k, l;
+    char buf[256];
+    const CvHaarClassifierCascade *cascade = (const CvHaarClassifierCascade *) struct_ptr;
+
+    /* TODO: parameters check */
+
+    cvStartWriteStruct( fs, name, CV_NODE_MAP, CV_TYPE_NAME_HAAR, attributes );
+
+    cvStartWriteStruct( fs, ICV_HAAR_SIZE_NAME, CV_NODE_SEQ | CV_NODE_FLOW );
+    cvWriteInt( fs, NULL, cascade->orig_window_size.width );
+    cvWriteInt( fs, NULL, cascade->orig_window_size.height );
+    cvEndWriteStruct( fs ); /* size */
+
+    cvStartWriteStruct( fs, ICV_HAAR_STAGES_NAME, CV_NODE_SEQ );
+    for( i = 0; i < cascade->count; ++i )
+    {
+        cvStartWriteStruct( fs, NULL, CV_NODE_MAP );
+        sprintf( buf, "stage %d", i );
+        cvWriteComment( fs, buf, 1 );
+
+        cvStartWriteStruct( fs, ICV_HAAR_TREES_NAME, CV_NODE_SEQ );
+
+        for( j = 0; j < cascade->stage_classifier[i].count; ++j )
+        {
+            CvHaarClassifier *tree = &cascade->stage_classifier[i].classifier[j];
+
+            cvStartWriteStruct( fs, NULL, CV_NODE_SEQ );
+            sprintf( buf, "tree %d", j );
+            cvWriteComment( fs, buf, 1 );
+
+            for( k = 0; k < tree->count; ++k )
+            {
+                CvHaarFeature *feature = &tree->haar_feature[k];
+
+                cvStartWriteStruct( fs, NULL, CV_NODE_MAP );
+                if( k )
+                {
+                    sprintf( buf, "node %d", k );
+                }
+                else
+                {
+                    sprintf( buf, "root node" );
+                }
+                cvWriteComment( fs, buf, 1 );
+
+                cvStartWriteStruct( fs, ICV_HAAR_FEATURE_NAME, CV_NODE_MAP );
+
+                cvStartWriteStruct( fs, ICV_HAAR_RECTS_NAME, CV_NODE_SEQ );
+                for( l = 0; l < CV_HAAR_FEATURE_MAX && feature->rect[l].r.width != 0; ++l )
+                {
+                    cvStartWriteStruct( fs, NULL, CV_NODE_SEQ | CV_NODE_FLOW );
+                    cvWriteInt(  fs, NULL, feature->rect[l].r.x );
+                    cvWriteInt(  fs, NULL, feature->rect[l].r.y );
+                    cvWriteInt(  fs, NULL, feature->rect[l].r.width );
+                    cvWriteInt(  fs, NULL, feature->rect[l].r.height );
+                    cvWriteReal( fs, NULL, feature->rect[l].weight );
+                    cvEndWriteStruct( fs ); /* rect */
+                }
+                cvEndWriteStruct( fs ); /* rects */
+                cvWriteInt( fs, ICV_HAAR_TILTED_NAME, feature->tilted );
+                cvEndWriteStruct( fs ); /* feature */
+
+                cvWriteReal( fs, ICV_HAAR_THRESHOLD_NAME, tree->threshold[k]);
+
+                if( tree->left[k] > 0 )
+                {
+                    cvWriteInt( fs, ICV_HAAR_LEFT_NODE_NAME, tree->left[k] );
+                }
+                else
+                {
+                    cvWriteReal( fs, ICV_HAAR_LEFT_VAL_NAME,
+                    tree->alpha[-tree->left[k]] );
+                }
+
+                if( tree->right[k] > 0 )
+                {
+                    cvWriteInt( fs, ICV_HAAR_RIGHT_NODE_NAME, tree->right[k] );
+                }
+                else
+                {
+                    cvWriteReal( fs, ICV_HAAR_RIGHT_VAL_NAME,
+                    tree->alpha[-tree->right[k]] );
+                }
+
+                cvEndWriteStruct( fs ); /* split */
+            }
+
+            cvEndWriteStruct( fs ); /* tree */
+        }
+
+        cvEndWriteStruct( fs ); /* trees */
+
+        cvWriteReal( fs, ICV_HAAR_STAGE_THRESHOLD_NAME, cascade->stage_classifier[i].threshold);
+        cvWriteInt( fs, ICV_HAAR_PARENT_NAME, cascade->stage_classifier[i].parent );
+        cvWriteInt( fs, ICV_HAAR_NEXT_NAME, cascade->stage_classifier[i].next );
+
+        cvEndWriteStruct( fs ); /* stage */
+    } /* for each stage */
+
+    cvEndWriteStruct( fs ); /* stages */
+    cvEndWriteStruct( fs ); /* root */
+}
+
+void*
+gpuCloneHaarClassifier( const void *struct_ptr )
+{
+    CvHaarClassifierCascade *cascade = NULL;
+
+    int i, j, k, n;
+    const CvHaarClassifierCascade *cascade_src =
+    (const CvHaarClassifierCascade *) struct_ptr;
+
+    n = cascade_src->count;
+    cascade = gpuCreateHaarClassifierCascade(n);
+    cascade->orig_window_size = cascade_src->orig_window_size;
+
+    for( i = 0; i < n; ++i )
+    {
+        cascade->stage_classifier[i].parent = cascade_src->stage_classifier[i].parent;
+        cascade->stage_classifier[i].next = cascade_src->stage_classifier[i].next;
+        cascade->stage_classifier[i].child = cascade_src->stage_classifier[i].child;
+        cascade->stage_classifier[i].threshold = cascade_src->stage_classifier[i].threshold;
+
+        cascade->stage_classifier[i].count = 0;
+        cascade->stage_classifier[i].classifier =
+        (CvHaarClassifier *) cvAlloc( cascade_src->stage_classifier[i].count
+        * sizeof( cascade->stage_classifier[i].classifier[0] ) );
+
+        cascade->stage_classifier[i].count = cascade_src->stage_classifier[i].count;
+
+        for( j = 0; j < cascade->stage_classifier[i].count; ++j )
+            cascade->stage_classifier[i].classifier[j].haar_feature = NULL;
+
+        for( j = 0; j < cascade->stage_classifier[i].count; ++j )
+        {
+            const CvHaarClassifier *classifier_src =
+            &cascade_src->stage_classifier[i].classifier[j];
+            CvHaarClassifier *classifier =
+            &cascade->stage_classifier[i].classifier[j];
+
+            classifier->count = classifier_src->count;
+            classifier->haar_feature = (CvHaarFeature *) cvAlloc(
+                classifier->count * ( sizeof( *classifier->haar_feature ) +
+            sizeof( *classifier->threshold ) +
+            sizeof( *classifier->left ) +
+            sizeof( *classifier->right ) ) +
+                (classifier->count + 1) * sizeof( *classifier->alpha ) );
+            classifier->threshold = (float *) (classifier->haar_feature + classifier->count);
+            classifier->left = (int *) (classifier->threshold + classifier->count);
+            classifier->right = (int *) (classifier->left + classifier->count);
+            classifier->alpha = (float *) (classifier->right + classifier->count);
+            for( k = 0; k < classifier->count; ++k )
+            {
+                classifier->haar_feature[k] = classifier_src->haar_feature[k];
+                classifier->threshold[k] = classifier_src->threshold[k];
+                classifier->left[k] = classifier_src->left[k];
+                classifier->right[k] = classifier_src->right[k];
+                classifier->alpha[k] = classifier_src->alpha[k];
+            }
+            classifier->alpha[classifier->count] =
+            classifier_src->alpha[classifier->count];
+        }
+    }
+
+    return cascade;
+}
+
+#if 0
+CvType haar_type( CV_TYPE_NAME_HAAR, gpuIsHaarClassifier,
+(CvReleaseFunc)gpuReleaseHaarClassifierCascade,
+gpuReadHaarClassifier, gpuWriteHaarClassifier,
+gpuCloneHaarClassifier );
+
+
+namespace cv
+{
+
+    HaarClassifierCascade::HaarClassifierCascade() {}
+    HaarClassifierCascade::HaarClassifierCascade(const String &filename)
+    {
+        load(filename);
+    }
+
+    bool HaarClassifierCascade::load(const String &filename)
+    {
+        cascade = Ptr<CvHaarClassifierCascade>((CvHaarClassifierCascade *)cvLoad(filename.c_str(), 0, 0, 0));
+        return (CvHaarClassifierCascade *)cascade != 0;
+    }
+
+    void HaarClassifierCascade::detectMultiScale( const Mat &image,
+    Vector<Rect>& objects, double scaleFactor,
+    int minNeighbors, int flags,
+    Size minSize )
+    {
+        MemStorage storage(cvCreateMemStorage(0));
+        CvMat _image = image;
+        CvSeq *_objects = gpuHaarDetectObjects( &_image, cascade, storage, scaleFactor,
+        minNeighbors, flags, minSize );
+        Seq<Rect>(_objects).copyTo(objects);
+    }
+
+    int HaarClassifierCascade::runAt(Point pt, int startStage, int) const
+    {
+        return gpuRunHaarClassifierCascade(cascade, pt, startStage);
+    }
+
+    void HaarClassifierCascade::setImages( const Mat &sum, const Mat &sqsum,
+    const Mat &tilted, double scale )
+    {
+        CvMat _sum = sum, _sqsum = sqsum, _tilted = tilted;
+        gpuSetImagesForHaarClassifierCascade( cascade, &_sum, &_sqsum, &_tilted, scale );
+    }
+
+}
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////reserved functios//////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+/*#if CV_SSE2
+#   if CV_SSE4 || defined __SSE4__
+#       include <smmintrin.h>
+#   else
+#       define _mm_blendv_pd(a, b, m) _mm_xor_pd(a, _mm_and_pd(_mm_xor_pd(b, a), m))
+#       define _mm_blendv_ps(a, b, m) _mm_xor_ps(a, _mm_and_ps(_mm_xor_ps(b, a), m))
+#   endif
+#if defined CV_ICC
+#   define CV_HAAR_USE_SSE 1
+#endif
+#endif*/
+
+
+/*
+CV_IMPL void
+gpuSetImagesForHaarClassifierCascade( CvHaarClassifierCascade* _cascade,
+const CvArr* _sum,
+const CvArr* _sqsum,
+const CvArr* _tilted_sum,
+double scale )
+{
+CvMat sum_stub, *sum = (CvMat*)_sum;
+CvMat sqsum_stub, *sqsum = (CvMat*)_sqsum;
+CvMat tilted_stub, *tilted = (CvMat*)_tilted_sum;
+GpuHidHaarClassifierCascade* cascade;
+int coi0 = 0, coi1 = 0;
+int i;
+int datasize;
+int totalclassifier;
+CvRect equRect;
+double weight_scale;
+int rows,cols;
+
+if( !CV_IS_HAAR_CLASSIFIER(_cascade) )
+CV_Error( !_cascade ? CV_StsNullPtr : CV_StsBadArg, "Invalid classifier pointer" );
+
+if( scale <= 0 )
+CV_Error( CV_StsOutOfRange, "Scale must be positive" );
+
+sum = cvGetMat( sum, &sum_stub, &coi0 );
+sqsum = cvGetMat( sqsum, &sqsum_stub, &coi1 );
+
+if( coi0 || coi1 )
+CV_Error( CV_BadCOI, "COI is not supported" );
+
+if( !CV_ARE_SIZES_EQ( sum, sqsum ))
+CV_Error( CV_StsUnmatchedSizes, "All integral images must have the same size" );
+
+if( CV_MAT_TYPE(sqsum->type) != CV_64FC1 ||
+CV_MAT_TYPE(sum->type) != CV_32SC1 )
+CV_Error( CV_StsUnsupportedFormat,
+"Only (32s, 64f, 32s) combination of (sum,sqsum,tilted_sum) formats is allowed" );
+
+if( !_cascade->hid_cascade )
+gpuCreateHidHaarClassifierCascade(_cascade,&datasize,&totalclassifier);
+
+cascade =(GpuHidHaarClassifierCascade *)_cascade->hid_cascade;
+
+if( cascade->has_tilted_features )
+{
+tilted = cvGetMat( tilted, &tilted_stub, &coi1 );
+
+if( CV_MAT_TYPE(tilted->type) != CV_32SC1 )
+CV_Error( CV_StsUnsupportedFormat,
+"Only (32s, 64f, 32s) combination of (sum,sqsum,tilted_sum) formats is allowed" );
+
+if( sum->step != tilted->step )
+CV_Error( CV_StsUnmatchedSizes,
+"Sum and tilted_sum must have the same stride (step, widthStep)" );
+
+if( !CV_ARE_SIZES_EQ( sum, tilted ))
+CV_Error( CV_StsUnmatchedSizes, "All integral images must have the same size" );
+//cascade->tilted = *tilted;
+}
+
+_cascade->scale = scale;
+_cascade->real_window_size.width = cvRound( _cascade->orig_window_size.width * scale );
+_cascade->real_window_size.height = cvRound( _cascade->orig_window_size.height * scale );
+
+//cascade->sum = *sum;
+//cascade->sqsum = *sqsum;
+
+equRect.x = equRect.y = cvRound(scale);
+equRect.width = cvRound((_cascade->orig_window_size.width-2)*scale);
+equRect.height = cvRound((_cascade->orig_window_size.height-2)*scale);
+weight_scale = 1./(equRect.width*equRect.height);
+cascade->inv_window_area = weight_scale;
+
+cascade->p0 = sum_elem_ptr(*sum, equRect.y, equRect.x);
+cascade->p1 = sum_elem_ptr(*sum, equRect.y, equRect.x + equRect.width );
+cascade->p2 = sum_elem_ptr(*sum, equRect.y + equRect.height, equRect.x );
+cascade->p3 = sum_elem_ptr(*sum, equRect.y + equRect.height,
+equRect.x + equRect.width );
+*/
+/*    rows=sum->rows;
+cols=sum->cols;
+cascade->p0 = equRect.y*cols + equRect.x;
+cascade->p1 = equRect.y*cols + equRect.x + equRect.width;
+cascade->p2 = (equRect.y + equRect.height) * cols + equRect.x;
+cascade->p3 = (equRect.y + equRect.height) * cols + equRect.x + equRect.width ;
+*/
+/*
+cascade->pq0 = sqsum_elem_ptr(*sqsum, equRect.y, equRect.x);
+cascade->pq1 = sqsum_elem_ptr(*sqsum, equRect.y, equRect.x + equRect.width );
+cascade->pq2 = sqsum_elem_ptr(*sqsum, equRect.y + equRect.height, equRect.x );
+cascade->pq3 = sqsum_elem_ptr(*sqsum, equRect.y + equRect.height,
+equRect.x + equRect.width );
+*/
+/* init pointers in haar features according to real window size and
+given image pointers */
+/*    for( i = 0; i < _cascade->count; i++ )
+{
+int j, k, l;
+for( j = 0; j < cascade->stage_classifier[i].count; j++ )
+{
+for( l = 0; l < cascade->stage_classifier[i].classifier[j].count; l++ )
+{
+CvHaarFeature* feature =
+&_cascade->stage_classifier[i].classifier[j].haar_feature[l];
+*/                /* GpuHidHaarClassifier* classifier =
+cascade->stage_classifier[i].classifier + j; */
+//GpuHidHaarFeature* hidfeature =
+//  &cascade->stage_classifier[i].classifier[j].node[l].feature;
+/*                double sum0 = 0, area0 = 0;
+CvRect r[3];
+
+int base_w = -1, base_h = -1;
+int new_base_w = 0, new_base_h = 0;
+int kx, ky;
+int flagx = 0, flagy = 0;
+int x0 = 0, y0 = 0;
+int nr;
+*/
+/* align blocks */
+/*                for( k = 0; k < CV_HAAR_FEATURE_MAX; k++ )
+{
+//if( !hidfeature->rect[k].p0 )
+//    break;
+r[k] = feature->rect[k].r;
+base_w = (int)CV_IMIN( (unsigned)base_w, (unsigned)(r[k].width-1) );
+base_w = (int)CV_IMIN( (unsigned)base_w, (unsigned)(r[k].x - r[0].x-1) );
+base_h = (int)CV_IMIN( (unsigned)base_h, (unsigned)(r[k].height-1) );
+base_h = (int)CV_IMIN( (unsigned)base_h, (unsigned)(r[k].y - r[0].y-1) );
+}
+
+nr = k;
+
+base_w += 1;
+base_h += 1;
+kx = r[0].width / base_w;
+ky = r[0].height / base_h;
+
+if( kx <= 0 )
+{
+flagx = 1;
+new_base_w = cvRound( r[0].width * scale ) / kx;
+x0 = cvRound( r[0].x * scale );
+}
+
+if( ky <= 0 )
+{
+flagy = 1;
+new_base_h = cvRound( r[0].height * scale ) / ky;
+y0 = cvRound( r[0].y * scale );
+}
+
+for( k = 0; k < nr; k++ )
+{
+CvRect tr;
+double correction_ratio;
+
+if( flagx )
+{
+tr.x = (r[k].x - r[0].x) * new_base_w / base_w + x0;
+tr.width = r[k].width * new_base_w / base_w;
+}
+else
+{
+tr.x = cvRound( r[k].x * scale );
+tr.width = cvRound( r[k].width * scale );
+}
+
+if( flagy )
+{
+tr.y = (r[k].y - r[0].y) * new_base_h / base_h + y0;
+tr.height = r[k].height * new_base_h / base_h;
+}
+else
+{
+tr.y = cvRound( r[k].y * scale );
+tr.height = cvRound( r[k].height * scale );
+}
+
+#if CV_ADJUST_WEIGHTS
+{
+// RAINER START
+const float orig_feature_size =  (float)(feature->rect[k].r.width)*feature->rect[k].r.height;
+const float orig_norm_size = (float)(_cascade->orig_window_size.width)*(_cascade->orig_window_size.height);
+const float feature_size = float(tr.width*tr.height);
+//const float normSize    = float(equRect.width*equRect.height);
+float target_ratio = orig_feature_size / orig_norm_size;
+//float isRatio = featureSize / normSize;
+//correctionRatio = targetRatio / isRatio / normSize;
+correction_ratio = target_ratio / feature_size;
+// RAINER END
+}
+#else
+correction_ratio = weight_scale * (!feature->tilted ? 1 : 0.5);
+#endif
+
+if( !feature->tilted )
+{
+hidfeature->rect[k].p0 = tr.y * rows + tr.x;
+hidfeature->rect[k].p1 = tr.y * rows + tr.x + tr.width;
+hidfeature->rect[k].p2 = (tr.y + tr.height) * rows + tr.x;
+hidfeature->rect[k].p3 = (tr.y + tr.height) * rows + tr.x + tr.width;
+
+}
+else
+{
+hidfeature->rect[k].p2 = (tr.y + tr.width) * rows + tr.x + tr.width;
+hidfeature->rect[k].p3 = (tr.y + tr.width + tr.height) * rows + tr.x + tr.width - tr.height;
+hidfeature->rect[k].p0 = tr.y*rows + tr.x;
+hidfeature->rect[k].p1 = (tr.y + tr.height) * rows + tr.x - tr.height;
+
+}
+
+//hidfeature->rect[k].weight = (float)(feature->rect[k].weight * correction_ratio);
+
+if( k == 0 )
+area0 = tr.width * tr.height;
+else
+;//  sum0 += hidfeature->rect[k].weight * tr.width * tr.height;
+}
+
+//hidfeature->rect[0].weight = (float)(-sum0/area0);*/
+//            } /* l */
+//        } /* j */
+//    }
+//}
+
+CV_INLINE
+double gpuEvalHidHaarClassifier( GpuHidHaarClassifier *classifier,
+double variance_norm_factor,
+size_t p_offset )
+{
+    /*
+    int idx = 0;
+    do
+    {
+    GpuHidHaarTreeNode* node = classifier->node + idx;
+    double t = node->threshold * variance_norm_factor;
+
+    double sum = calc_sum(node->feature.rect[0],p_offset) * node->feature.rect[0].weight;
+    sum += calc_sum(node->feature.rect[1],p_offset) * node->feature.rect[1].weight;
+
+    if( node->feature.rect[2].p0 )
+    sum += calc_sum(node->feature.rect[2],p_offset) * node->feature.rect[2].weight;
+
+    idx = sum < t ? node->left : node->right;
+    }
+    while( idx > 0 );
+    return classifier->alpha[-idx];
+    */
+    return 0.;
+}
+
+
+CV_IMPL int
+gpuRunHaarClassifierCascade( const CvHaarClassifierCascade *_cascade,
+CvPoint pt, int start_stage )
+{
+    /*
+    int result = -1;
+
+    int p_offset, pq_offset;
+    int i, j;
+    double mean, variance_norm_factor;
+    GpuHidHaarClassifierCascade* cascade;
+
+    if( !CV_IS_HAAR_CLASSIFIER(_cascade) )
+    CV_Error( !_cascade ? CV_StsNullPtr : CV_StsBadArg, "Invalid cascade pointer" );
+
+    cascade = (GpuHidHaarClassifierCascade*) _cascade->hid_cascade;
+    if( !cascade )
+    CV_Error( CV_StsNullPtr, "Hidden cascade has not been created.\n"
+    "Use gpuSetImagesForHaarClassifierCascade" );
+
+    if( pt.x < 0 || pt.y < 0 ||
+    pt.x + _cascade->real_window_size.width >= cascade->sum.width-2 ||
+    pt.y + _cascade->real_window_size.height >= cascade->sum.height-2 )
+    return -1;
+
+    p_offset = pt.y * (cascade->sum.step/sizeof(sumtype)) + pt.x;
+    pq_offset = pt.y * (cascade->sqsum.step/sizeof(sqsumtype)) + pt.x;
+    mean = calc_sum(*cascade,p_offset)*cascade->inv_window_area;
+    variance_norm_factor = cascade->pq0[pq_offset] - cascade->pq1[pq_offset] -
+    cascade->pq2[pq_offset] + cascade->pq3[pq_offset];
+    variance_norm_factor = variance_norm_factor*cascade->inv_window_area - mean*mean;
+    if( variance_norm_factor >= 0. )
+    variance_norm_factor = sqrt(variance_norm_factor);
+    else
+    variance_norm_factor = 1.;
+
+
+    if( cascade->is_stump_based )
+    {
+    for( i = start_stage; i < cascade->count; i++ )
+    {
+    double stage_sum = 0;
+
+    if( cascade->stage_classifier[i].two_rects )
+    {
+    for( j = 0; j < cascade->stage_classifier[i].count; j++ )
+    {
+    GpuHidHaarClassifier* classifier = cascade->stage_classifier[i].classifier + j;
+    GpuHidHaarTreeNode* node = classifier->node;
+    double t = node->threshold*variance_norm_factor;
+    double sum = calc_sum(node->feature.rect[0],p_offset) * node->feature.rect[0].weight;
+    sum += calc_sum(node->feature.rect[1],p_offset) * node->feature.rect[1].weight;
+    stage_sum += classifier->alpha[sum >= t];
+    }
+    }
+    else
+    {
+    for( j = 0; j < cascade->stage_classifier[i].count; j++ )
+    {
+    GpuHidHaarClassifier* classifier = cascade->stage_classifier[i].classifier + j;
+    GpuHidHaarTreeNode* node = classifier->node;
+    double t = node->threshold*variance_norm_factor;
+    double sum = calc_sum(node->feature.rect[0],p_offset) * node->feature.rect[0].weight;
+    sum += calc_sum(node->feature.rect[1],p_offset) * node->feature.rect[1].weight;
+    if( node->feature.rect[2].p0 )
+    sum += calc_sum(node->feature.rect[2],p_offset) * node->feature.rect[2].weight;
+
+    stage_sum += classifier->alpha[sum >= t];
+    }
+    }
+
+    if( stage_sum < cascade->stage_classifier[i].threshold )
+    return -i;
+    }
+    }
+    */
+    return 1;
+}
+
+
+namespace cv
+{
+    namespace ocl
+    {
+
+        struct gpuHaarDetectObjects_ScaleImage_Invoker
+        {
+            gpuHaarDetectObjects_ScaleImage_Invoker( const CvHaarClassifierCascade *_cascade,
+            int _stripSize, double _factor,
+            const Mat &_sum1, const Mat &_sqsum1, Mat *_norm1,
+            Mat *_mask1, Rect _equRect, ConcurrentRectVector &_vec )
+            {
+                cascade = _cascade;
+                stripSize = _stripSize;
+                factor = _factor;
+                sum1 = _sum1;
+                sqsum1 = _sqsum1;
+                norm1 = _norm1;
+                mask1 = _mask1;
+                equRect = _equRect;
+                vec = &_vec;
+            }
+
+            void operator()( const BlockedRange &range ) const
+            {
+                Size winSize0 = cascade->orig_window_size;
+                Size winSize(cvRound(winSize0.width * factor), cvRound(winSize0.height * factor));
+                int y1 = range.begin() * stripSize, y2 = min(range.end() * stripSize, sum1.rows - 1 - winSize0.height);
+                Size ssz(sum1.cols - 1 - winSize0.width, y2 - y1);
+                int x, y, ystep = factor > 2 ? 1 : 2;
+
+                for( y = y1; y < y2; y += ystep )
+                    for( x = 0; x < ssz.width; x += ystep )
+                    {
+                        if( gpuRunHaarClassifierCascade( cascade, cvPoint(x, y), 0 ) > 0 )
+                            vec->push_back(Rect(cvRound(x * factor), cvRound(y * factor),
+                            winSize.width, winSize.height));
+                    }
+            }
+
+            const CvHaarClassifierCascade *cascade;
+            int stripSize;
+            double factor;
+            Mat sum1, sqsum1, *norm1, *mask1;
+            Rect equRect;
+            ConcurrentRectVector *vec;
+        };
+
+
+        struct gpuHaarDetectObjects_ScaleCascade_Invoker
+        {
+            gpuHaarDetectObjects_ScaleCascade_Invoker( const CvHaarClassifierCascade *_cascade,
+            Size _winsize, const Range &_xrange, double _ystep,
+            size_t _sumstep, const int **_p, const int **_pq,
+            ConcurrentRectVector &_vec )
+            {
+                cascade = _cascade;
+                winsize = _winsize;
+                xrange = _xrange;
+                ystep = _ystep;
+                sumstep = _sumstep;
+                p = _p;
+                pq = _pq;
+                vec = &_vec;
+            }
+
+            void operator()( const BlockedRange &range ) const
+            {
+                int iy, startY = range.begin(), endY = range.end();
+                const int *p0 = p[0], *p1 = p[1], *p2 = p[2], *p3 = p[3];
+                const int *pq0 = pq[0], *pq1 = pq[1], *pq2 = pq[2], *pq3 = pq[3];
+                bool doCannyPruning = p0 != 0;
+                int sstep = (int)(sumstep / sizeof(p0[0]));
+
+                for( iy = startY; iy < endY; iy++ )
+                {
+                    int ix, y = cvRound(iy * ystep), ixstep = 1;
+                    for( ix = xrange.start; ix < xrange.end; ix += ixstep )
+                    {
+                        int x = cvRound(ix * ystep); // it should really be ystep, not ixstep
+
+                        if( doCannyPruning )
+                        {
+                            int offset = y * sstep + x;
+                            int s = p0[offset] - p1[offset] - p2[offset] + p3[offset];
+                            int sq = pq0[offset] - pq1[offset] - pq2[offset] + pq3[offset];
+                            if( s < 100 || sq < 20 )
+                            {
+                                ixstep = 2;
+                                continue;
+                            }
+                        }
+
+                        int result = gpuRunHaarClassifierCascade( cascade, cvPoint(x, y), 0 );
+                        if( result > 0 )
+                            vec->push_back(Rect(x, y, winsize.width, winsize.height));
+                        ixstep = result != 0 ? 1 : 2;
+                    }
+                }
+            }
+
+            const CvHaarClassifierCascade *cascade;
+            double ystep;
+            size_t sumstep;
+            Size winsize;
+            Range xrange;
+            const int **p;
+            const int **pq;
+            ConcurrentRectVector *vec;
+        };
+
+    }
+}
+
+/*
+typedef struct _ALIGNED_ON(128) GpuHidHaarFeature
+{
+struct _ALIGNED_ON(32)
+{
+int    p0 _ALIGNED_ON(4);
+int    p1 _ALIGNED_ON(4);
+int    p2 _ALIGNED_ON(4);
+int    p3 _ALIGNED_ON(4);
+float weight  _ALIGNED_ON(4);
+}
+rect[CV_HAAR_FEATURE_MAX] _ALIGNED_ON(32);
+}
+GpuHidHaarFeature;
+
+
+typedef struct _ALIGNED_ON(128) GpuHidHaarTreeNode
+{
+int left _ALIGNED_ON(4);
+int right _ALIGNED_ON(4);
+float threshold _ALIGNED_ON(4);
+int p0[CV_HAAR_FEATURE_MAX] _ALIGNED_ON(16);
+int p1[CV_HAAR_FEATURE_MAX] _ALIGNED_ON(16);
+int p2[CV_HAAR_FEATURE_MAX] _ALIGNED_ON(16);
+int p3[CV_HAAR_FEATURE_MAX] _ALIGNED_ON(16);
+float weight[CV_HAAR_FEATURE_MAX] _ALIGNED_ON(16);
+float alpha[2] _ALIGNED_ON(8);
+// GpuHidHaarFeature feature __attribute__((aligned (128)));
+}
+GpuHidHaarTreeNode;
+
+
+typedef struct _ALIGNED_ON(32) GpuHidHaarClassifier
+{
+int count _ALIGNED_ON(4);
+//CvHaarFeature* orig_feature;
+GpuHidHaarTreeNode* node _ALIGNED_ON(8);
+float* alpha _ALIGNED_ON(8);
+}
+GpuHidHaarClassifier;
+
+
+typedef struct _ALIGNED_ON(64) __attribute__((aligned (64))) GpuHidHaarStageClassifier
+{
+int  count _ALIGNED_ON(4);
+float threshold _ALIGNED_ON(4);
+int two_rects _ALIGNED_ON(4);
+GpuHidHaarClassifier* classifier _ALIGNED_ON(8);
+struct GpuHidHaarStageClassifier* next _ALIGNED_ON(8);
+struct GpuHidHaarStageClassifier* child _ALIGNED_ON(8);
+struct GpuHidHaarStageClassifier* parent _ALIGNED_ON(8);
+}
+GpuHidHaarStageClassifier;
+
+
+typedef struct _ALIGNED_ON(64) GpuHidHaarClassifierCascade
+{
+int  count _ALIGNED_ON(4);
+int  is_stump_based _ALIGNED_ON(4);
+int  has_tilted_features _ALIGNED_ON(4);
+int  is_tree _ALIGNED_ON(4);
+int pq0 _ALIGNED_ON(4);
+int pq1 _ALIGNED_ON(4);
+int pq2 _ALIGNED_ON(4);
+int pq3 _ALIGNED_ON(4);
+int p0 _ALIGNED_ON(4);
+int p1 _ALIGNED_ON(4);
+int p2 _ALIGNED_ON(4);
+int p3 _ALIGNED_ON(4);
+float inv_window_area _ALIGNED_ON(4);
+// GpuHidHaarStageClassifier* stage_classifier __attribute__((aligned (8)));
+}GpuHidHaarClassifierCascade;
+*/
+/* End of file. */
diff --git a/modules/ocl/src/imgproc.cpp b/modules/ocl/src/imgproc.cpp
new file mode 100644 (file)
index 0000000..00fba08
--- /dev/null
@@ -0,0 +1,1353 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Niko Li, newlife20080214@gmail.com
+//    Jia Haipeng, jiahaipeng95@gmail.com
+//    Shengen Yan, yanshengen@gmail.com
+//    Rock Li, Rock.Li@amd.com
+//    Zero Lin, Zero.Lin@amd.com
+//    Zhang Ying, zhangying913@gmail.com
+//    Xu Pang, pangxu010@163.com
+//    Wu Zailong, bullet@yeah.net
+//
+// 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 <iomanip>
+
+using namespace cv;
+using namespace cv::ocl;
+using namespace std;
+
+#if !defined (HAVE_OPENCL)
+
+
+void cv::ocl::meanShiftFiltering(const oclMat &, oclMat &, int, int, TermCriteria)
+{
+    throw_nogpu();
+}
+void cv::ocl::meanShiftProc(const oclMat &, oclMat &, oclMat &, int, int, TermCriteria)
+{
+    throw_nogpu();
+}
+double cv::ocl::threshold(const oclMat &, oclMat &, double, int)
+{
+    throw_nogpu();
+    return 0.0;
+}
+void cv::ocl::resize(const oclMat &, oclMat &, Size, double, double, int)
+{
+    throw_nogpu();
+}
+void cv::ocl::remap(const oclMat&, oclMat&, oclMat&, oclMat&, int, int ,const Scalar&) { throw_nogpu(); }
+
+void cv::ocl::copyMakeBorder(const oclMat &, oclMat &, int, int, int, int, const Scalar &)
+{
+    throw_nogpu();
+}
+void cv::ocl::warpAffine(const oclMat &, oclMat &, const Mat &, Size, int)
+{
+    throw_nogpu();
+}
+void cv::ocl::warpPerspective(const oclMat &, oclMat &, const Mat &, Size, int)
+{
+    throw_nogpu();
+}
+void cv::ocl::integral(const oclMat &, oclMat &, oclMat &)
+{
+    throw_nogpu();
+}
+void cv::ocl::calcHist(const oclMat &, oclMat &hist)
+{
+    throw_nogpu();
+}
+void cv::ocl::bilateralFilter(const oclMat &, oclMat &, int, double, double, int)
+{
+    throw_nogpu();
+}
+#else /* !defined (HAVE_OPENCL) */
+
+namespace cv
+{
+    namespace ocl
+    {
+
+        ////////////////////////////////////OpenCL kernel strings//////////////////////////
+        extern const char *meanShift;
+        extern const char *img_proc;
+        extern const char *imgproc_copymakeboder;
+        extern const char *imgproc_median;
+        extern const char *imgproc_threshold;
+        extern const char *imgproc_resize;
+        extern const char *imgproc_remap;
+        extern const char *imgproc_warpAffine;
+        extern const char *imgproc_warpPerspective;
+        extern const char *imgproc_integral_sum;
+        extern const char *imgproc_integral;
+        extern const char *imgproc_histogram;
+        extern const char *imgproc_bilateral;
+        extern const char *imgproc_calcHarris;
+        extern const char *imgproc_calcMinEigenVal;
+        ////////////////////////////////////OpenCL call wrappers////////////////////////////
+
+        template <typename T> struct index_and_sizeof;
+        template <> struct index_and_sizeof<char>
+        {
+            enum { index = 1 };
+        };
+        template <> struct index_and_sizeof<unsigned char>
+        {
+            enum { index = 2 };
+        };
+        template <> struct index_and_sizeof<short>
+        {
+            enum { index = 3 };
+        };
+        template <> struct index_and_sizeof<unsigned short>
+        {
+            enum { index = 4 };
+        };
+        template <> struct index_and_sizeof<int>
+        {
+            enum { index = 5 };
+        };
+        template <> struct index_and_sizeof<float>
+        {
+            enum { index = 6 };
+        };
+        template <> struct index_and_sizeof<double>
+        {
+            enum { index = 7 };
+        };
+
+        /////////////////////////////////////////////////////////////////////////////////////
+        // threshold
+
+        typedef void (*gpuThresh_t)(const oclMat &src, oclMat &dst, double thresh, double maxVal, int type);
+
+        void threshold_8u(const oclMat &src, oclMat &dst, double thresh, double maxVal, int type)
+        {
+            CV_Assert( (src.cols == dst.cols) && (src.rows == dst.rows) );
+            Context *clCxt = src.clCxt;
+
+            uchar thresh_uchar = cvFloor(thresh);
+            uchar max_val = cvRound(maxVal);
+            string kernelName = "threshold";
+
+            size_t cols = (dst.cols + (dst.offset % 16) + 15) / 16;
+            size_t bSizeX = 16, bSizeY = 16;
+            size_t gSizeX = cols % bSizeX == 0 ? cols : (cols + bSizeX - 1) / bSizeX * bSizeX;
+            size_t gSizeY = dst.rows;
+            size_t globalThreads[3] = {gSizeX, gSizeY, 1};
+            size_t localThreads[3] = {bSizeX, bSizeY, 1};
+
+            vector< pair<size_t, const void *> > args;
+            args.push_back( make_pair(sizeof(cl_mem), &src.data));
+            args.push_back( make_pair(sizeof(cl_mem), &dst.data));
+            args.push_back( make_pair(sizeof(cl_int), (void *)&src.offset));
+            args.push_back( make_pair(sizeof(cl_int), (void *)&src.step));
+            args.push_back( make_pair(sizeof(cl_int), (void *)&dst.offset));
+            args.push_back( make_pair(sizeof(cl_int), (void *)&dst.rows));
+            args.push_back( make_pair(sizeof(cl_int), (void *)&dst.cols));
+            args.push_back( make_pair(sizeof(cl_int), (void *)&dst.step));
+            args.push_back( make_pair(sizeof(cl_uchar), (void *)&thresh_uchar));
+            args.push_back( make_pair(sizeof(cl_uchar), (void *)&max_val));
+            args.push_back( make_pair(sizeof(cl_int), (void *)&type));
+            openCLExecuteKernel(clCxt, &imgproc_threshold, kernelName, globalThreads, localThreads, args, src.channels(), src.depth());
+        }
+
+        void threshold_32f(const oclMat &src, oclMat &dst, double thresh, double maxVal, int type)
+        {
+            CV_Assert( (src.cols == dst.cols) && (src.rows == dst.rows) );
+            Context *clCxt = src.clCxt;
+
+            float thresh_f = thresh;
+            float max_val = maxVal;
+            int dst_offset = (dst.offset >> 2);
+            int dst_step = (dst.step >> 2);
+            int src_offset = (src.offset >> 2);
+            int src_step = (src.step >> 2);
+
+            string kernelName = "threshold";
+
+            size_t cols = (dst.cols + (dst_offset & 3) + 3) / 4;
+            //size_t cols = dst.cols;
+            size_t bSizeX = 16, bSizeY = 16;
+            size_t gSizeX = cols % bSizeX == 0 ? cols : (cols + bSizeX - 1) / bSizeX * bSizeX;
+            size_t gSizeY = dst.rows;
+            size_t globalThreads[3] = {gSizeX, gSizeY, 1};
+            size_t localThreads[3] = {bSizeX, bSizeY, 1};
+
+            vector< pair<size_t, const void *> > args;
+            args.push_back( make_pair(sizeof(cl_mem), &src.data));
+            args.push_back( make_pair(sizeof(cl_mem), &dst.data));
+            args.push_back( make_pair(sizeof(cl_int), (void *)&src_offset));
+            args.push_back( make_pair(sizeof(cl_int), (void *)&src_step));
+            args.push_back( make_pair(sizeof(cl_int), (void *)&dst_offset));
+            args.push_back( make_pair(sizeof(cl_int), (void *)&dst.rows));
+            args.push_back( make_pair(sizeof(cl_int), (void *)&dst.cols));
+            args.push_back( make_pair(sizeof(cl_int), (void *)&dst_step));
+            args.push_back( make_pair(sizeof(cl_float), (void *)&thresh_f));
+            args.push_back( make_pair(sizeof(cl_float), (void *)&max_val));
+            args.push_back( make_pair(sizeof(cl_int), (void *)&type));
+            openCLExecuteKernel(clCxt, &imgproc_threshold, kernelName, globalThreads, localThreads, args, src.channels(), src.depth());
+
+        }
+
+        //threshold: support 8UC1 and 32FC1 data type and five threshold type
+        double threshold(const oclMat &src, oclMat &dst, double thresh, double maxVal, int type)
+        {
+            //TODO: These limitations shall be removed later.
+            CV_Assert(src.type() == CV_8UC1 || src.type() == CV_32FC1);
+            CV_Assert(type == THRESH_BINARY || type == THRESH_BINARY_INV || type == THRESH_TRUNC
+                      || type == THRESH_TOZERO || type == THRESH_TOZERO_INV );
+
+            static const gpuThresh_t gpuThresh_callers[2] = {threshold_8u, threshold_32f};
+
+            dst.create( src.size(), src.type() );
+            gpuThresh_callers[(src.type() == CV_32FC1)](src, dst, thresh, maxVal, type);
+
+            return thresh;
+        }
+    ////////////////////////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////   remap   //////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////////////////////
+
+        void remap( const oclMat& src, oclMat& dst, oclMat& map1, oclMat& map2, int interpolation, int borderType, const Scalar& borderValue )
+        {
+            Context *clCxt = src.clCxt;
+            CV_Assert(interpolation == INTER_LINEAR || interpolation == INTER_NEAREST 
+                    || interpolation == INTER_CUBIC || interpolation== INTER_LANCZOS4);
+            CV_Assert((map1.type() == CV_16SC2)&&(!map2.data) || (map1.type()== CV_32FC2)&&!map2.data);//more
+            CV_Assert((!map2.data || map2.size()== map1.size()));
+
+            dst.create(map1.size(), src.type());
+            int depth = src.depth(), map_depth = map1.depth();
+
+            string kernelName;
+
+            if( map1.type() == CV_32FC2 && !map2.data )
+            {
+                if(interpolation == INTER_LINEAR && borderType == BORDER_CONSTANT)
+                    kernelName = "remapLNFConstant";
+                else if(interpolation == INTER_NEAREST && borderType == BORDER_CONSTANT)
+                    kernelName = "remapNNFConstant";
+            }
+            else if(map1.type() == CV_16SC2 && !map2.data)
+            {
+                if(interpolation == INTER_LINEAR && borderType == BORDER_CONSTANT)
+                    kernelName = "remapLNSConstant";
+                else if(interpolation == INTER_NEAREST && borderType == BORDER_CONSTANT)
+                    kernelName = "remapNNSConstant";
+
+            }
+            int type = src.type();
+            size_t blkSizeX = 16, blkSizeY = 16;
+            size_t glbSizeX;
+
+            if(src.type() == CV_8UC1 || src.type() == CV_8UC2 || src.type() == CV_8UC4) 
+            {
+                size_t cols = (dst.cols + dst.offset%4 + 3)/4;
+                glbSizeX = cols %blkSizeX==0 ? cols : (cols/blkSizeX+1)*blkSizeX;
+            }
+            else
+            {
+                glbSizeX = dst.cols%blkSizeX==0 ? dst.cols : (dst.cols/blkSizeX+1)*blkSizeX;
+            }
+            size_t glbSizeY = dst.rows%blkSizeY==0 ? dst.rows : (dst.rows/blkSizeY+1)*blkSizeY;
+            size_t globalThreads[3] = {glbSizeX,glbSizeY,1};
+            size_t localThreads[3] = {blkSizeX,blkSizeY,1};
+
+            vector< pair<size_t, const void *> > args;
+            if(map1.channels() == 2)
+            {
+                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_mem),(void*)&map1.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*)&map1.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*)&map1.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*)&dst.cols));
+                args.push_back( make_pair(sizeof(cl_int),(void*)&dst.rows));
+                args.push_back( make_pair(sizeof(cl_int),(void*)&map1.cols));
+                args.push_back( make_pair(sizeof(cl_int),(void*)&map1.rows));
+                args.push_back( make_pair(sizeof(cl_double4),(void*)&borderValue));
+            }
+            openCLExecuteKernel(clCxt,&imgproc_remap,kernelName,globalThreads,localThreads,args,src.channels(),src.depth());
+
+        
+
+    }  
+    
+        ////////////////////////////////////////////////////////////////////////////////////////////
+        // resize
+
+        void resize_gpu( const oclMat &src, oclMat &dst, double fx, double fy, int interpolation)
+        {
+            CV_Assert( (src.channels() == dst.channels()) );
+            Context *clCxt = src.clCxt;
+            float ifx = 1. / fx;
+            float ify = 1. / fy;
+            double ifx_d = 1. / fx;
+            double ify_d = 1. / fy;
+
+            string kernelName;
+            if(interpolation == INTER_LINEAR)
+                kernelName = "resizeLN";
+            else if(interpolation == INTER_NEAREST)
+                kernelName = "resizeNN";
+
+            //TODO: improve this kernel
+            size_t blkSizeX = 16, blkSizeY = 16;
+            size_t glbSizeX;
+            if(src.type() == CV_8UC1)
+            {
+                size_t cols = (dst.cols + dst.offset % 4 + 3) / 4;
+                glbSizeX = cols % blkSizeX == 0 ? cols : (cols / blkSizeX + 1) * blkSizeX;
+            }
+            else
+            {
+                glbSizeX = dst.cols % blkSizeX == 0 ? dst.cols : (dst.cols / blkSizeX + 1) * blkSizeX;
+            }
+            size_t glbSizeY = dst.rows % blkSizeY == 0 ? dst.rows : (dst.rows / blkSizeY + 1) * blkSizeY;
+            size_t globalThreads[3] = {glbSizeX, glbSizeY, 1};
+            size_t localThreads[3] = {blkSizeX, blkSizeY, 1};
+
+            vector< pair<size_t, const void *> > args;
+            if(interpolation == INTER_NEAREST)
+            {
+                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 *)&dst.cols));
+                args.push_back( make_pair(sizeof(cl_int), (void *)&dst.rows));
+                args.push_back( make_pair(sizeof(cl_double), (void *)&ifx_d));
+                args.push_back( make_pair(sizeof(cl_double), (void *)&ify_d));
+            }
+            else
+            {
+                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 *)&dst.cols));
+                args.push_back( make_pair(sizeof(cl_int), (void *)&dst.rows));
+                args.push_back( make_pair(sizeof(cl_float), (void *)&ifx));
+                args.push_back( make_pair(sizeof(cl_float), (void *)&ify));
+            }
+
+            openCLExecuteKernel(clCxt, &imgproc_resize, kernelName, globalThreads, localThreads, args, src.channels(), src.depth());
+        }
+
+
+        void resize(const oclMat &src, oclMat &dst, Size dsize,
+                    double fx, double fy, int interpolation)
+        {
+            CV_Assert(src.type() == CV_8UC1 || src.type() == CV_8UC4
+                      || src.type() == CV_32FC1 || src.type() == CV_32FC4);
+            CV_Assert(interpolation == INTER_LINEAR || interpolation == INTER_NEAREST);
+            CV_Assert( src.size().area() > 0 );
+            CV_Assert( !(dsize == Size()) || (fx > 0 && fy > 0) );
+
+            if(!(dsize == Size()) && (fx > 0 && fy > 0))
+            {
+                if(dsize.width != (int)(src.cols * fx) || dsize.height != (int)(src.rows * fy))
+                {
+                    std::cout << "invalid dsize and fx, fy!" << std::endl;
+                }
+            }
+            if( dsize == Size() )
+            {
+                dsize = Size(saturate_cast<int>(src.cols * fx), saturate_cast<int>(src.rows * fy));
+            }
+            else
+            {
+                fx = (double)dsize.width / src.cols;
+                fy = (double)dsize.height / src.rows;
+            }
+
+            dst.create(dsize, src.type());
+
+            if( interpolation == INTER_NEAREST || interpolation == INTER_LINEAR )
+            {
+                resize_gpu( src, dst, fx, fy, interpolation);
+                return;
+            }
+            CV_Error(CV_StsUnsupportedFormat, "Non-supported interpolation method");
+        }
+
+
+        ////////////////////////////////////////////////////////////////////////
+        // medianFilter
+        void medianFilter(const oclMat &src, oclMat &dst, int m)
+        {
+            CV_Assert( m % 2 == 1 && m > 1 );
+            CV_Assert( m <= 5 || src.depth() == CV_8U );
+            CV_Assert( src.cols <= dst.cols && src.rows <= dst.rows );
+
+            if(src.data == dst.data)
+            {
+                oclMat src1;
+                src.copyTo(src1);
+                return medianFilter(src1, dst, m);
+            }
+
+            int srcStep = src.step1() / src.channels();
+            int dstStep = dst.step1() / dst.channels();
+            int srcOffset = src.offset / src.channels() / src.elemSize1();
+            int dstOffset = dst.offset / dst.channels() / dst.elemSize1();
+
+            Context *clCxt = src.clCxt;
+            string kernelName = "medianFilter";
+
+
+            vector< pair<size_t, const void *> > args;
+            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 *)&srcOffset));
+            args.push_back( make_pair( sizeof(cl_int), (void *)&dstOffset));
+            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 *)&srcStep));
+            args.push_back( make_pair( sizeof(cl_int), (void *)&dstStep));
+
+            size_t globalThreads[3] = {(src.cols + 18) / 16 * 16, (src.rows + 15) / 16 * 16, 1};
+            size_t localThreads[3] = {16, 16, 1};
+
+            if(m == 3)
+            {
+                string kernelName = "medianFilter3";
+                openCLExecuteKernel(clCxt, &imgproc_median, kernelName, globalThreads, localThreads, args, src.channels(), src.depth());
+            }
+            else if(m == 5)
+            {
+                string kernelName = "medianFilter5";
+                openCLExecuteKernel(clCxt, &imgproc_median, kernelName, globalThreads, localThreads, args, src.channels(), src.depth());
+            }
+            else
+            {
+                CV_Error(CV_StsUnsupportedFormat, "Non-supported filter length");
+                //string kernelName = "medianFilter";
+                //args.push_back( make_pair( sizeof(cl_int),(void*)&m));
+
+                //openCLExecuteKernel(clCxt,&imgproc_median,kernelName,globalThreads,localThreads,args,src.channels(),-1);
+            }
+
+        }
+
+        ////////////////////////////////////////////////////////////////////////
+        // copyMakeBorder
+        void copyMakeBorder(const oclMat &src, oclMat &dst, int top, int left, int boardtype, void *nVal)
+        {
+            CV_Assert( (src.channels() == dst.channels()) );
+
+            int srcStep = src.step1() / src.channels();
+            int dstStep = dst.step1() / dst.channels();
+            int srcOffset = src.offset / src.channels() / src.elemSize1();
+            int dstOffset = dst.offset / dst.channels() / dst.elemSize1();
+
+            int D = src.depth();
+            int V32 = *(int *)nVal;
+            char V8 = *(char *)nVal;
+            if(src.channels() == 4)
+            {
+                unsigned int v = 0x01020408;
+                char *pv = (char *)(&v);
+                uchar *pnVal = (uchar *)(nVal);
+                if(((*pv) & 0x01) != 0)
+                    V32 = (pnVal[0] << 24) + (pnVal[1] << 16) + (pnVal[2] << 8) + (pnVal[3]);
+                else
+                    V32 = (pnVal[3] << 24) + (pnVal[2] << 16) + (pnVal[1] << 8) + (pnVal[0]);
+
+                srcStep = src.step / 4;
+                dstStep = dst.step / 4;
+
+                D = 4;
+            }
+
+            Context *clCxt = src.clCxt;
+            string kernelName = "copyConstBorder";
+            if(boardtype == BORDER_REPLICATE)
+                kernelName = "copyReplicateBorder";
+            else if(boardtype == BORDER_REFLECT_101)
+                kernelName = "copyReflectBorder";
+
+            vector< pair<size_t, const void *> > args;
+            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 *)&srcOffset));
+            args.push_back( make_pair( sizeof(cl_int), (void *)&dstOffset));
+            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 *)&dst.cols));
+            args.push_back( make_pair( sizeof(cl_int), (void *)&dst.rows));
+            args.push_back( make_pair( sizeof(cl_int), (void *)&top));
+            args.push_back( make_pair( sizeof(cl_int), (void *)&left));
+            if(D == 0)
+                args.push_back( make_pair( sizeof(uchar), (void *)&V8));
+            else
+                args.push_back( make_pair( sizeof(int), (void *)&V32));
+            args.push_back( make_pair( sizeof(cl_int), (void *)&srcStep));
+            args.push_back( make_pair( sizeof(cl_int), (void *)&dstStep));
+
+            size_t globalThreads[3] = {((dst.cols + 6) / 4 * dst.rows + 255) / 256 * 256, 1, 1};
+            size_t localThreads[3] = {256, 1, 1};
+
+            openCLExecuteKernel(clCxt, &imgproc_copymakeboder, kernelName, globalThreads, localThreads, args, 1, D);
+        }
+
+        void copyMakeBorder(const oclMat &src, oclMat &dst, int top, int bottom, int left, int right, int boardtype, const Scalar &value)
+        {
+            CV_Assert(src.type() == CV_8UC1 || src.type() == CV_8UC4 || src.type() == CV_32SC1);
+            CV_Assert(top >= 0 && bottom >= 0 && left >= 0 && right >= 0);
+
+            dst.create(src.rows + top + bottom, src.cols + left + right, src.type());
+
+            switch (src.type())
+            {
+            case CV_8UC1:
+            {
+                uchar nVal = cvRound(value[0]);
+                copyMakeBorder( src, dst, top, left, boardtype, &nVal);
+                break;
+            }
+            case CV_8UC4:
+            {
+                uchar nVal[] = {(uchar)value[0], (uchar)value[1], (uchar)value[2], (uchar)value[3]};
+                copyMakeBorder( src, dst, top, left, boardtype, nVal);
+                break;
+            }
+            case CV_32SC1:
+            {
+                int nVal = cvRound(value[0]);
+                copyMakeBorder( src, dst, top, left, boardtype, &nVal);
+                break;
+            }
+            default:
+                CV_Error(-217, "Unsupported source type");
+            }
+        }
+
+        ////////////////////////////////////////////////////////////////////////
+        // warp
+
+        namespace
+        {
+#define F double
+
+            void convert_coeffs(F *M)
+            {
+                double D = M[0] * M[4] - M[1] * M[3];
+                D = D != 0 ? 1. / D : 0;
+                double A11 = M[4] * D, A22 = M[0] * D;
+                M[0] = A11;
+                M[1] *= -D;
+                M[3] *= -D;
+                M[4] = A22;
+                double b1 = -M[0] * M[2] - M[1] * M[5];
+                double b2 = -M[3] * M[2] - M[4] * M[5];
+                M[2] = b1;
+                M[5] = b2;
+            }
+
+            double invert(double *M)
+            {
+#define Sd(y,x) (Sd[y*3+x])
+#define Dd(y,x) (Dd[y*3+x])
+#define det3(m)   (m(0,0)*(m(1,1)*m(2,2) - m(1,2)*m(2,1)) -  \
+        m(0,1)*(m(1,0)*m(2,2) - m(1,2)*m(2,0)) +  \
+        m(0,2)*(m(1,0)*m(2,1) - m(1,1)*m(2,0)))
+                double *Sd = M;
+                double *Dd = M;
+                double d = det3(Sd);
+                double result = 0;
+                if( d != 0)
+                {
+                    double t[9];
+                    result = d;
+                    d = 1. / d;
+
+                    t[0] = (Sd(1, 1) * Sd(2, 2) - Sd(1, 2) * Sd(2, 1)) * d;
+                    t[1] = (Sd(0, 2) * Sd(2, 1) - Sd(0, 1) * Sd(2, 2)) * d;
+                    t[2] = (Sd(0, 1) * Sd(1, 2) - Sd(0, 2) * Sd(1, 1)) * d;
+
+                    t[3] = (Sd(1, 2) * Sd(2, 0) - Sd(1, 0) * Sd(2, 2)) * d;
+                    t[4] = (Sd(0, 0) * Sd(2, 2) - Sd(0, 2) * Sd(2, 0)) * d;
+                    t[5] = (Sd(0, 2) * Sd(1, 0) - Sd(0, 0) * Sd(1, 2)) * d;
+
+                    t[6] = (Sd(1, 0) * Sd(2, 1) - Sd(1, 1) * Sd(2, 0)) * d;
+                    t[7] = (Sd(0, 1) * Sd(2, 0) - Sd(0, 0) * Sd(2, 1)) * d;
+                    t[8] = (Sd(0, 0) * Sd(1, 1) - Sd(0, 1) * Sd(1, 0)) * d;
+
+                    Dd(0, 0) = t[0];
+                    Dd(0, 1) = t[1];
+                    Dd(0, 2) = t[2];
+                    Dd(1, 0) = t[3];
+                    Dd(1, 1) = t[4];
+                    Dd(1, 2) = t[5];
+                    Dd(2, 0) = t[6];
+                    Dd(2, 1) = t[7];
+                    Dd(2, 2) = t[8];
+                }
+                return result;
+            }
+
+            void warpAffine_gpu(const oclMat &src, oclMat &dst, F coeffs[2][3], int interpolation)
+            {
+                CV_Assert( (src.channels() == dst.channels()) );
+                int srcStep = src.step1();
+                int dstStep = dst.step1();
+
+                Context *clCxt = src.clCxt;
+                string s[3] = {"NN", "Linear", "Cubic"};
+                string kernelName = "warpAffine" + s[interpolation];
+
+                cl_int st;
+                               cl_mem coeffs_cm = clCreateBuffer( clCxt->impl->clContext, CL_MEM_READ_WRITE, sizeof(F) * 2 * 3, NULL, &st );
+                openCLVerifyCall(st);
+                openCLSafeCall(clEnqueueWriteBuffer(clCxt->impl->clCmdQueue, (cl_mem)coeffs_cm, 1, 0, sizeof(F) * 2 * 3, coeffs, 0, 0, 0));
+
+                //TODO: improve this kernel
+                size_t blkSizeX = 16, blkSizeY = 16;
+                size_t glbSizeX;
+                //if(src.type() == CV_8UC1 && interpolation != 2)
+                if(src.type() == CV_8UC1 && interpolation != 2)
+                {
+                    size_t cols = (dst.cols + dst.offset % 4 + 3) / 4;
+                    glbSizeX = cols % blkSizeX == 0 ? cols : (cols / blkSizeX + 1) * blkSizeX;
+                }
+                else
+                {
+                    glbSizeX = dst.cols % blkSizeX == 0 ? dst.cols : (dst.cols / blkSizeX + 1) * blkSizeX;
+                }
+                size_t glbSizeY = dst.rows % blkSizeY == 0 ? dst.rows : (dst.rows / blkSizeY + 1) * blkSizeY;
+                size_t globalThreads[3] = {glbSizeX, glbSizeY, 1};
+                size_t localThreads[3] = {blkSizeX, blkSizeY, 1};
+
+                vector< pair<size_t, const void *> > args;
+
+                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.cols));
+                args.push_back(make_pair(sizeof(cl_int), (void *)&src.rows));
+                args.push_back(make_pair(sizeof(cl_int), (void *)&dst.cols));
+                args.push_back(make_pair(sizeof(cl_int), (void *)&dst.rows));
+                args.push_back(make_pair(sizeof(cl_int), (void *)&srcStep));
+                args.push_back(make_pair(sizeof(cl_int), (void *)&dstStep));
+                args.push_back(make_pair(sizeof(cl_int), (void *)&src.offset));
+                args.push_back(make_pair(sizeof(cl_int), (void *)&dst.offset));
+                args.push_back(make_pair(sizeof(cl_mem), (void *)&coeffs_cm));
+
+                openCLExecuteKernel(clCxt, &imgproc_warpAffine, kernelName, globalThreads, localThreads, args, src.channels(), src.depth());
+                openCLSafeCall(clReleaseMemObject(coeffs_cm));
+            }
+
+
+            void warpPerspective_gpu(const oclMat &src, oclMat &dst, double coeffs[3][3], int interpolation)
+            {
+                CV_Assert( (src.channels() == dst.channels()) );
+                int srcStep = src.step1();
+                int dstStep = dst.step1();
+
+                Context *clCxt = src.clCxt;
+                string s[3] = {"NN", "Linear", "Cubic"};
+                string kernelName = "warpPerspective" + s[interpolation];
+
+                cl_int st;
+                cl_mem coeffs_cm = clCreateBuffer( clCxt->impl->clContext, CL_MEM_READ_WRITE, sizeof(double) * 3 * 3, NULL, &st );
+                openCLVerifyCall(st);
+                openCLSafeCall(clEnqueueWriteBuffer(clCxt->impl->clCmdQueue, (cl_mem)coeffs_cm, 1, 0, sizeof(double) * 3 * 3, coeffs, 0, 0, 0));
+
+                //TODO: improve this kernel
+                size_t blkSizeX = 16, blkSizeY = 16;
+                size_t glbSizeX;
+                if(src.type() == CV_8UC1 && interpolation == 0)
+                {
+                    size_t cols = (dst.cols + dst.offset % 4 + 3) / 4;
+                    glbSizeX = cols % blkSizeX == 0 ? cols : (cols / blkSizeX + 1) * blkSizeX;
+                }
+                else
+                    /*
+                    */
+                {
+                    glbSizeX = dst.cols % blkSizeX == 0 ? dst.cols : (dst.cols / blkSizeX + 1) * blkSizeX;
+                }
+                size_t glbSizeY = dst.rows % blkSizeY == 0 ? dst.rows : (dst.rows / blkSizeY + 1) * blkSizeY;
+                size_t globalThreads[3] = {glbSizeX, glbSizeY, 1};
+                size_t localThreads[3] = {blkSizeX, blkSizeY, 1};
+
+                vector< pair<size_t, const void *> > args;
+
+                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.cols));
+                args.push_back(make_pair(sizeof(cl_int), (void *)&src.rows));
+                args.push_back(make_pair(sizeof(cl_int), (void *)&dst.cols));
+                args.push_back(make_pair(sizeof(cl_int), (void *)&dst.rows));
+                args.push_back(make_pair(sizeof(cl_int), (void *)&srcStep));
+                args.push_back(make_pair(sizeof(cl_int), (void *)&dstStep));
+                args.push_back(make_pair(sizeof(cl_int), (void *)&src.offset));
+                args.push_back(make_pair(sizeof(cl_int), (void *)&dst.offset));
+                args.push_back(make_pair(sizeof(cl_mem), (void *)&coeffs_cm));
+
+                openCLExecuteKernel(clCxt, &imgproc_warpPerspective, kernelName, globalThreads, localThreads, args, src.channels(), src.depth());
+                openCLSafeCall(clReleaseMemObject(coeffs_cm));
+            }
+        }
+
+        void warpAffine(const oclMat &src, oclMat &dst, const Mat &M, Size dsize, int flags)
+        {
+            int interpolation = flags & INTER_MAX;
+
+            CV_Assert((src.depth() == CV_8U  || src.depth() == CV_32F) && src.channels() != 2 && src.channels() != 3);
+            CV_Assert(interpolation == INTER_NEAREST || interpolation == INTER_LINEAR || interpolation == INTER_CUBIC);
+
+            dst.create(dsize, src.type());
+
+            CV_Assert(M.rows == 2 && M.cols == 3);
+
+            int warpInd = (flags & WARP_INVERSE_MAP) >> 4;
+            F coeffs[2][3];
+            Mat coeffsMat(2, 3, CV_64F, (void *)coeffs);
+            M.convertTo(coeffsMat, coeffsMat.type());
+            if(!warpInd)
+            {
+                convert_coeffs((F *)(&coeffs[0][0]));
+            }
+            warpAffine_gpu(src, dst, coeffs, interpolation);
+        }
+
+        void warpPerspective(const oclMat &src, oclMat &dst, const Mat &M, Size dsize, int flags)
+        {
+            int interpolation = flags & INTER_MAX;
+
+            CV_Assert((src.depth() == CV_8U  || src.depth() == CV_32F) && src.channels() != 2 && src.channels() != 3);
+            CV_Assert(interpolation == INTER_NEAREST || interpolation == INTER_LINEAR || interpolation == INTER_CUBIC);
+
+            dst.create(dsize, src.type());
+
+
+            CV_Assert(M.rows == 3 && M.cols == 3);
+
+            int warpInd = (flags & WARP_INVERSE_MAP) >> 4;
+            double coeffs[3][3];
+            Mat coeffsMat(3, 3, CV_64F, (void *)coeffs);
+            M.convertTo(coeffsMat, coeffsMat.type());
+            if(!warpInd)
+            {
+                invert((double *)(&coeffs[0][0]));
+            }
+
+            warpPerspective_gpu(src, dst, coeffs, interpolation);
+        }
+
+
+        ////////////////////////////////////////////////////////////////////////
+        // integral
+
+        void integral(const oclMat &src, oclMat &sum, oclMat &sqsum)
+        {
+            CV_Assert(src.type() == CV_8UC1);
+            if(src.clCxt->impl->double_support == 0 && src.depth() ==CV_64F)
+            {
+                CV_Error(-217,"select device don't support double");
+            }
+            int vlen = 4;
+            int offset = src.offset / vlen;
+            int pre_invalid = src.offset % vlen;
+            int vcols = (pre_invalid + src.cols + vlen - 1) / vlen;
+
+            oclMat t_sum , t_sqsum;
+            t_sum.create(src.cols, src.rows, CV_32SC1);
+            t_sqsum.create(src.cols, src.rows, CV_32FC1);
+
+            int w = src.cols + 1, h = src.rows + 1;
+            sum.create(h, w, CV_32SC1);
+            sqsum.create(h, w, CV_32FC1);
+            int sum_offset = sum.offset / vlen, sqsum_offset = sqsum.offset / vlen;
+
+            vector<pair<size_t , const void *> > args;
+            args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data ));
+            args.push_back( make_pair( sizeof(cl_mem) , (void *)&t_sum.data ));
+            args.push_back( make_pair( sizeof(cl_mem) , (void *)&t_sqsum.data ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&offset ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&pre_invalid ));
+            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 *)&t_sum.step));
+            size_t gt[3] = {((vcols + 1) / 2) * 256, 1, 1}, lt[3] = {256, 1, 1};
+            openCLExecuteKernel(src.clCxt, &imgproc_integral, "integral_cols", gt, lt, args, -1, -1);
+            args.clear();
+            args.push_back( make_pair( sizeof(cl_mem) , (void *)&t_sum.data ));
+            args.push_back( make_pair( sizeof(cl_mem) , (void *)&t_sqsum.data ));
+            args.push_back( make_pair( sizeof(cl_mem) , (void *)&sum.data ));
+            args.push_back( make_pair( sizeof(cl_mem) , (void *)&sqsum.data ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&t_sum.rows ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&t_sum.cols ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&t_sum.step ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&sum.step));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&sqsum.step));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&sum_offset));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&sqsum_offset));
+            size_t gt2[3] = {t_sum.cols  * 32, 1, 1}, lt2[3] = {256, 1, 1};
+            openCLExecuteKernel(src.clCxt, &imgproc_integral, "integral_rows", gt2, lt2, args, -1, -1);
+            //cout << "tested" << endl;
+        }
+        void integral(const oclMat &src, oclMat &sum)
+        {
+            CV_Assert(src.type() == CV_8UC1);
+            int vlen = 4;
+            int offset = src.offset / vlen;
+            int pre_invalid = src.offset % vlen;
+            int vcols = (pre_invalid + src.cols + vlen - 1) / vlen;
+
+            oclMat t_sum;
+            t_sum.create(src.cols, src.rows, CV_32SC1);
+
+            int w = src.cols + 1, h = src.rows + 1;
+            sum.create(h, w, CV_32SC1);
+            int sum_offset = sum.offset / vlen;
+
+            vector<pair<size_t , const void *> > args;
+            args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data ));
+            args.push_back( make_pair( sizeof(cl_mem) , (void *)&t_sum.data ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&offset ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&pre_invalid ));
+            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 *)&t_sum.step));
+            size_t gt[3] = {((vcols + 1) / 2) * 256, 1, 1}, lt[3] = {256, 1, 1};
+            openCLExecuteKernel(src.clCxt, &imgproc_integral_sum, "integral_cols", gt, lt, args, -1, -1);
+            args.clear();
+            args.push_back( make_pair( sizeof(cl_mem) , (void *)&t_sum.data ));
+            args.push_back( make_pair( sizeof(cl_mem) , (void *)&sum.data ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&t_sum.rows ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&t_sum.cols ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&t_sum.step ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&sum.step));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&sum_offset));
+            size_t gt2[3] = {t_sum.cols  * 32, 1, 1}, lt2[3] = {256, 1, 1};
+            openCLExecuteKernel(src.clCxt, &imgproc_integral_sum, "integral_rows", gt2, lt2, args, -1, -1);
+            //cout << "tested" << endl;
+        }
+
+        /////////////////////// corner //////////////////////////////
+        void extractCovData(const oclMat &src, oclMat &Dx, oclMat &Dy,
+                            int blockSize, int ksize, int borderType)
+        {
+            CV_Assert(src.type() == CV_8UC1 || src.type() == CV_32FC1);
+            double scale = static_cast<double>(1 << ((ksize > 0 ? ksize : 3) - 1)) * blockSize;
+            oclMat temp;
+            if (ksize < 0)
+                scale *= 2.;
+
+            if (src.depth() == CV_8U){
+                src.convertTo(temp, (int)CV_32FC1);
+                scale *= 255.;
+                scale = 1. / scale;
+                if (ksize > 0)
+                {
+                    Sobel(temp, Dx, CV_32F, 1, 0, ksize, scale, 0, borderType);
+                    Sobel(temp, Dy, CV_32F, 0, 1, ksize, scale, 0, borderType);
+                }
+                else
+                {
+                    Scharr(temp, Dx, CV_32F, 1, 0, scale, 0, borderType);
+                    Scharr(temp, Dy, CV_32F, 0, 1, scale, 0, borderType);
+                }
+            }else{
+                scale = 1. / scale;
+                if (ksize > 0)
+                {
+                    Sobel(src, Dx, CV_32F, 1, 0, ksize, scale, 0, borderType);
+                    Sobel(src, Dy, CV_32F, 0, 1, ksize, scale, 0, borderType);
+                }
+                else
+                {
+                    Scharr(src, Dx, CV_32F, 1, 0, scale, 0, borderType);
+                    Scharr(src, Dy, CV_32F, 0, 1, scale, 0, borderType);
+                }
+            }
+        }
+
+        void corner_ocl(const char *src_str, string kernelName, int block_size, float k, oclMat &Dx, oclMat &Dy,
+                        oclMat &dst, int border_type)
+        {
+            char borderType[30];
+            switch (border_type)
+            {
+            case cv::BORDER_CONSTANT:
+                sprintf(borderType, "BORDER_CONSTANT");
+                break;
+            case cv::BORDER_REFLECT101:
+                sprintf(borderType, "BORDER_REFLECT101");
+                break;
+            case cv::BORDER_REFLECT:
+                sprintf(borderType, "BORDER_REFLECT");
+                break;
+            case cv::BORDER_REPLICATE:
+                sprintf(borderType, "BORDER_REPLICATE");
+                break;
+            default:
+                cout << "BORDER type is not supported!" << endl;
+            }
+            char build_options[150];
+            sprintf(build_options, "-D anX=%d -D anY=%d -D ksX=%d -D ksY=%d -D %s",
+                    block_size / 2, block_size / 2, block_size, block_size, borderType);
+
+            size_t blockSizeX = 256, blockSizeY = 1;
+            size_t gSize = blockSizeX - block_size / 2 * 2;
+            size_t globalSizeX = (Dx.cols) % gSize == 0 ? Dx.cols / gSize * blockSizeX : (Dx.cols / gSize + 1) * blockSizeX;
+            size_t rows_per_thread = 2;
+            size_t globalSizeY = ((Dx.rows + rows_per_thread - 1) / rows_per_thread) % blockSizeY == 0 ?
+                                 ((Dx.rows + rows_per_thread - 1) / rows_per_thread) :
+                                 (((Dx.rows + rows_per_thread - 1) / rows_per_thread) / blockSizeY + 1) * blockSizeY;
+
+            size_t gt[3] = { globalSizeX, globalSizeY, 1 };
+            size_t lt[3]  = { blockSizeX, blockSizeY, 1 };
+            vector<pair<size_t , const void *> > args;
+            args.push_back( make_pair( sizeof(cl_mem) , (void *)&Dx.data ));
+            args.push_back( make_pair( sizeof(cl_mem) , (void *)&Dy.data));
+            args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst.data));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&Dx.offset ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&Dx.wholerows ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&Dx.wholecols ));
+            args.push_back( make_pair(sizeof(cl_int), (void *)&Dx.step));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&Dy.offset ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&Dy.wholerows ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&Dy.wholecols ));
+            args.push_back( make_pair(sizeof(cl_int), (void *)&Dy.step));
+            args.push_back( make_pair(sizeof(cl_int), (void *)&dst.offset));
+            args.push_back( make_pair(sizeof(cl_int), (void *)&dst.rows));
+            args.push_back( make_pair(sizeof(cl_int), (void *)&dst.cols));
+            args.push_back( make_pair(sizeof(cl_int), (void *)&dst.step));
+            args.push_back( make_pair( sizeof(cl_float) , (void *)&k));
+            openCLExecuteKernel(dst.clCxt, &src_str, kernelName, gt, lt, args, -1, -1, build_options);
+        }
+
+        void cornerHarris(const oclMat &src, oclMat &dst, int blockSize, int ksize,
+                          double k, int borderType)
+        {
+            if(src.clCxt->impl->double_support == 0 && src.depth() ==CV_64F)
+            {
+                CV_Error(-217,"select device don't support double");
+            }
+            oclMat Dx, Dy;
+            CV_Assert(borderType == cv::BORDER_REFLECT101 || borderType == cv::BORDER_REPLICATE || borderType == cv::BORDER_REFLECT);
+            extractCovData(src, Dx, Dy, blockSize, ksize, borderType);
+            dst.create(src.size(), CV_32F);
+            corner_ocl(imgproc_calcHarris, "calcHarris", blockSize, static_cast<float>(k), Dx, Dy, dst, borderType);
+        }
+
+        void cornerMinEigenVal(const oclMat &src, oclMat &dst, int blockSize, int ksize, int borderType)
+        {
+            if(src.clCxt->impl->double_support == 0 && src.depth() ==CV_64F)
+            {
+                CV_Error(-217,"select device don't support double");
+            }
+            oclMat Dx, Dy;
+            CV_Assert(borderType == cv::BORDER_REFLECT101 || borderType == cv::BORDER_REPLICATE || borderType == cv::BORDER_REFLECT);
+            extractCovData(src, Dx, Dy, blockSize, ksize, borderType);
+            dst.create(src.size(), CV_32F);
+            corner_ocl(imgproc_calcMinEigenVal, "calcMinEigenVal", blockSize, 0, Dx, Dy, dst, borderType);
+        }
+        /////////////////////////////////// MeanShiftfiltering ///////////////////////////////////////////////
+        void meanShiftFiltering_gpu(const oclMat &src, oclMat dst, int sp, int sr, int maxIter, float eps)
+        {
+            CV_Assert( (src.cols == dst.cols) && (src.rows == dst.rows) );
+            CV_Assert( !(dst.step & 0x3) );
+            Context *clCxt = src.clCxt;
+
+            //Arrange the NDRange
+            int col = src.cols, row = src.rows;
+            int ltx = 16, lty = 8;
+            if(src.cols % ltx != 0)
+                col = (col / ltx + 1) * ltx;
+            if(src.rows % lty != 0)
+                row = (row / lty + 1) * lty;
+
+            size_t globalThreads[3] = {col, row, 1};
+            size_t localThreads[3]  = {ltx, lty, 1};
+
+            //set args
+            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_int) , (void *)&dst.step ));
+            args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&src.step ));
+            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.cols ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.rows ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&sp ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&sr ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&maxIter ));
+            args.push_back( make_pair( sizeof(cl_float) , (void *)&eps ));
+            openCLExecuteKernel(clCxt, &meanShift, "meanshift_kernel", globalThreads, localThreads, args, -1, -1);
+        }
+
+        void meanShiftFiltering(const oclMat &src, oclMat &dst, int sp, int sr, TermCriteria criteria)
+        {
+            if( src.empty() )
+                CV_Error( CV_StsBadArg, "The input image is empty" );
+
+            if( src.depth() != CV_8U || src.channels() != 4 )
+                CV_Error( CV_StsUnsupportedFormat, "Only 8-bit, 4-channel images are supported" );
+
+            dst.create( src.size(), CV_8UC4 );
+
+            if( !(criteria.type & TermCriteria::MAX_ITER) )
+                criteria.maxCount = 5;
+
+            int maxIter = std::min(std::max(criteria.maxCount, 1), 100);
+
+            float eps;
+            if( !(criteria.type & TermCriteria::EPS) )
+                eps = 1.f;
+            eps = (float)std::max(criteria.epsilon, 0.0);
+
+            meanShiftFiltering_gpu(src, dst, sp, sr, maxIter, eps);
+
+        }
+
+        void meanShiftProc_gpu(const oclMat &src, oclMat dstr, oclMat dstsp, int sp, int sr, int maxIter, float eps)
+        {
+            //sanity checks
+            CV_Assert( (src.cols == dstr.cols) && (src.rows == dstr.rows) &&
+                       (src.rows == dstsp.rows) && (src.cols == dstsp.cols));
+            CV_Assert( !(dstsp.step & 0x3) );
+            Context *clCxt = src.clCxt;
+
+            //Arrange the NDRange
+            int col = src.cols, row = src.rows;
+            int ltx = 16, lty = 8;
+            if(src.cols % ltx != 0)
+                col = (col / ltx + 1) * ltx;
+            if(src.rows % lty != 0)
+                row = (row / lty + 1) * lty;
+
+            size_t globalThreads[3] = {col, row, 1};
+            size_t localThreads[3]  = {ltx, lty, 1};
+
+            //set args
+            vector<pair<size_t , const void *> > args;
+            args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data ));
+            args.push_back( make_pair( sizeof(cl_mem) , (void *)&dstr.data ));
+            args.push_back( make_pair( sizeof(cl_mem) , (void *)&dstsp.data ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&src.step ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&dstr.step ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&dstsp.step ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&src.offset ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&dstr.offset ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&dstsp.offset ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&dstr.cols ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&dstr.rows ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&sp ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&sr ));
+            args.push_back( make_pair( sizeof(cl_int) , (void *)&maxIter ));
+            args.push_back( make_pair( sizeof(cl_float) , (void *)&eps ));
+            openCLExecuteKernel(clCxt, &meanShift, "meanshiftproc_kernel", globalThreads, localThreads, args, -1, -1);
+        }
+
+        void meanShiftProc(const oclMat &src, oclMat &dstr, oclMat &dstsp, int sp, int sr, TermCriteria criteria)
+        {
+            if( src.empty() )
+                CV_Error( CV_StsBadArg, "The input image is empty" );
+
+            if( src.depth() != CV_8U || src.channels() != 4 )
+                CV_Error( CV_StsUnsupportedFormat, "Only 8-bit, 4-channel images are supported" );
+
+            dstr.create( src.size(), CV_8UC4 );
+            dstsp.create( src.size(), CV_16SC2 );
+
+            if( !(criteria.type & TermCriteria::MAX_ITER) )
+                criteria.maxCount = 5;
+
+            int maxIter = std::min(std::max(criteria.maxCount, 1), 100);
+
+            float eps;
+            if( !(criteria.type & TermCriteria::EPS) )
+                eps = 1.f;
+            eps = (float)std::max(criteria.epsilon, 0.0);
+
+            meanShiftProc_gpu(src, dstr, dstsp, sp, sr, maxIter, eps);
+        }
+
+        ///////////////////////////////////////////////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////hist///////////////////////////////////////////////
+        /////////////////////////////////////////////////////////////////////////////////////////////////////
+        namespace histograms
+        {
+            const int PARTIAL_HISTOGRAM256_COUNT = 256;
+            const int HISTOGRAM256_BIN_COUNT = 256;
+        }
+        ///////////////////////////////calcHist/////////////////////////////////////////////////////////////////
+        void calc_sub_hist(const oclMat &mat_src, const oclMat &mat_sub_hist)
+        {
+            using namespace histograms;
+
+            Context  *clCxt = mat_src.clCxt;
+            int depth = mat_src.depth();
+
+            string kernelName = "calc_sub_hist";
+
+            size_t localThreads[3]  = { 256, 1, 1 };
+            size_t globalThreads[3] = { PARTIAL_HISTOGRAM256_COUNT *localThreads[0], 1, 1};
+
+            int cols = mat_src.cols * mat_src.channels();
+            int src_offset = mat_src.offset;
+            int hist_step = mat_sub_hist.step >> 2;
+            int left_col = 0, right_col = 0;
+            if(cols > 6)
+            {
+                left_col = 4 - (src_offset & 3);
+                left_col &= 3;
+                //dst_offset +=left_col;
+                src_offset += left_col;
+                cols -= left_col;
+                right_col = cols & 3;
+                cols -= right_col;
+                //globalThreads[0] = (cols/4+globalThreads[0]-1)/localThreads[0]*localThreads[0];
+            }
+            else
+            {
+                left_col = cols;
+                right_col = 0;
+                cols = 0;
+                globalThreads[0] = 0;
+            }
+
+            vector<pair<size_t , const void *> > args;
+            if(globalThreads[0] != 0)
+            {
+                int tempcols = cols / 4;
+                int inc_x = globalThreads[0] % tempcols;
+                int inc_y = globalThreads[0] / tempcols;
+                src_offset /= 4;
+                int src_step = mat_src.step / 4;
+                int datacount = tempcols * mat_src.rows * mat_src.channels();
+                args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_src.data));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&src_step));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&src_offset));
+                args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_sub_hist.data));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&datacount));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&tempcols));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&inc_x));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&inc_y));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&hist_step));
+                openCLExecuteKernel(clCxt, &imgproc_histogram, kernelName, globalThreads, localThreads, args, -1, depth);
+            }
+            if(left_col != 0 || right_col != 0)
+            {
+                kernelName = "calc_sub_hist2";
+                src_offset = mat_src.offset;
+                //dst_offset = dst.offset;
+                localThreads[0] = 1;
+                localThreads[1] = 256;
+                globalThreads[0] = left_col + right_col;
+                globalThreads[1] = (mat_src.rows + localThreads[1] - 1) / localThreads[1] * localThreads[1];
+                //kernel = openCLGetKernelFromSource(clCxt,&arithm_LUT,"LUT2");
+                args.clear();
+                args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_src.data));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_src.step));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&src_offset));
+                args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_sub_hist.data));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&left_col));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&cols));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_src.rows));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&hist_step));
+                openCLExecuteKernel(clCxt, &imgproc_histogram, kernelName, globalThreads, localThreads, args, -1, depth);
+            }
+        }
+        void merge_sub_hist(const oclMat &sub_hist, oclMat &mat_hist)
+        {
+            using namespace histograms;
+
+            Context  *clCxt = sub_hist.clCxt;
+            string kernelName = "merge_hist";
+
+            size_t localThreads[3]  = { 256, 1, 1 };
+            size_t globalThreads[3] = { HISTOGRAM256_BIN_COUNT *localThreads[0], 1, 1};
+            int src_step = sub_hist.step >> 2;
+            vector<pair<size_t , const void *> > args;
+            args.push_back( make_pair( sizeof(cl_mem), (void *)&sub_hist.data));
+            args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_hist.data));
+            args.push_back( make_pair( sizeof(cl_int), (void *)&src_step));
+            openCLExecuteKernel(clCxt, &imgproc_histogram, kernelName, globalThreads, localThreads, args, -1, -1);
+        }
+        void calcHist(const oclMat &mat_src, oclMat &mat_hist)
+        {
+            using namespace histograms;
+            CV_Assert(mat_src.type() == CV_8UC1);
+            mat_hist.create(1, 256, CV_32SC1);
+
+            oclMat buf(PARTIAL_HISTOGRAM256_COUNT, HISTOGRAM256_BIN_COUNT, CV_32SC1);
+            //buf.setTo(0);
+            calc_sub_hist(mat_src, buf);
+            merge_sub_hist(buf, mat_hist);
+        }
+        ///////////////////////////////////equalizeHist/////////////////////////////////////////////////////
+        void equalizeHist(const oclMat &mat_src, oclMat &mat_dst)
+        {
+            mat_dst.create(mat_src.rows, mat_src.cols, CV_8UC1);
+
+            oclMat mat_hist(1, 256, CV_32SC1);
+            //mat_hist.setTo(0);
+            calcHist(mat_src, mat_hist);
+
+            Context *clCxt = mat_src.clCxt;
+            string kernelName = "calLUT";
+            size_t localThreads[3] = { 256, 1, 1};
+            size_t globalThreads[3] = { 256, 1, 1};
+            oclMat lut(1, 256, CV_8UC1);
+            vector<pair<size_t , const void *> > args;
+            float scale = 255.f / (mat_src.rows * mat_src.cols);
+            args.push_back( make_pair( sizeof(cl_mem), (void *)&lut.data));
+            args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_hist.data));
+            args.push_back( make_pair( sizeof(cl_float), (void *)&scale));
+            openCLExecuteKernel(clCxt, &imgproc_histogram, kernelName, globalThreads, localThreads, args, -1, -1);
+            LUT(mat_src, lut, mat_dst);
+        }
+        //////////////////////////////////bilateralFilter////////////////////////////////////////////////////
+        void bilateralFilter(const oclMat &src, oclMat &dst, int radius, double sigmaclr, double sigmaspc, int borderType)
+        {
+            double sigmacolor = -0.5 / (sigmaclr * sigmaclr);
+            double sigmaspace = -0.5 / (sigmaspc * sigmaspc);
+            dst.create(src.size(), src.type());
+            Context *clCxt = src.clCxt;
+            int r = radius;
+            int d = 2 * r + 1;
+
+            oclMat tmp;
+            Scalar valu(0, 0, 0, 0);
+            copyMakeBorder(src, tmp, r, r, r, r, borderType, valu);
+
+            tmp.offset = (src.offset / src.step + r) * tmp.step + (src.offset % src.step + r);
+            int src_offset = tmp.offset;
+            int channels = tmp.channels();
+            int rows = src.rows;//in pixel
+            int cols = src.cols;//in pixel
+            //int step = tmp.step;
+            int src_step = tmp.step;//in Byte
+            int dst_step = dst.step;//in Byte
+            int whole_rows = tmp.wholerows;//in pixel
+            int whole_cols = tmp.wholecols;//in pixel
+            int dst_offset = dst.offset;//in Byte
+
+            double rs;
+            size_t size_space = d * d * sizeof(float);
+            float *sigSpcH = (float *)malloc(size_space);
+            for(int i = -r; i <= r; i++)
+            {
+                for(int j = -r; j <= r; j++)
+                {
+                    rs = std::sqrt(double(i * i) + (double)j * j);
+
+                    sigSpcH[(i+r)*d+j+r] = rs > r ? 0 : (float)std::exp(rs * rs * sigmaspace);
+                }
+            }
+
+            size_t size_color = 256 * channels * sizeof(float);
+            float *sigClrH = (float *)malloc(size_color);
+            for(int i = 0; i < 256 * channels; i++)
+            {
+                sigClrH[i] = (float)std::exp(i * i * sigmacolor);
+            }
+            string kernelName;
+            if(1 == channels) kernelName = "bilateral";
+            if(4 == channels) kernelName = "bilateral4";
+
+            cl_int errcode_ret;
+            cl_kernel kernel = openCLGetKernelFromSource(clCxt, &imgproc_bilateral, kernelName);
+
+            CV_Assert(src.channels() == dst.channels());
+
+            cl_mem sigClr = clCreateBuffer(clCxt->impl->clContext, CL_MEM_USE_HOST_PTR, size_color, sigClrH, &errcode_ret);
+            cl_mem sigSpc = clCreateBuffer(clCxt->impl->clContext, CL_MEM_USE_HOST_PTR, size_space, sigSpcH, &errcode_ret);
+            if(errcode_ret != CL_SUCCESS) printf("create buffer error\n");
+            openCLSafeCall(clSetKernelArg(kernel, 0, sizeof(void *), (void *)&dst.data));
+            openCLSafeCall(clSetKernelArg(kernel, 1, sizeof(void *), (void *)&tmp.data));
+            openCLSafeCall(clSetKernelArg(kernel, 2, sizeof(rows), (void *)&rows));
+            openCLSafeCall(clSetKernelArg(kernel, 3, sizeof(cols), (void *)&cols));
+            openCLSafeCall(clSetKernelArg(kernel, 4, sizeof(channels), (void *)&channels));
+            openCLSafeCall(clSetKernelArg(kernel, 5, sizeof(radius), (void *)&radius));
+            openCLSafeCall(clSetKernelArg(kernel, 6, sizeof(whole_rows), (void *)&whole_rows));
+            openCLSafeCall(clSetKernelArg(kernel, 7, sizeof(whole_cols), (void *)&whole_cols));
+            openCLSafeCall(clSetKernelArg(kernel, 8, sizeof(src_step), (void *)&src_step));
+            openCLSafeCall(clSetKernelArg(kernel, 9, sizeof(dst_step), (void *)&dst_step));
+            openCLSafeCall(clSetKernelArg(kernel, 10, sizeof(src_offset), (void *)&src_offset));
+            openCLSafeCall(clSetKernelArg(kernel, 11, sizeof(dst_offset), (void *)&dst_offset));
+            openCLSafeCall(clSetKernelArg(kernel, 12, sizeof(cl_mem), (void *)&sigClr));
+            openCLSafeCall(clSetKernelArg(kernel, 13, sizeof(cl_mem), (void *)&sigSpc));
+
+            openCLSafeCall(clEnqueueWriteBuffer(clCxt->impl->clCmdQueue, sigClr, CL_TRUE, 0, size_color, sigClrH, 0, NULL, NULL));
+            openCLSafeCall(clEnqueueWriteBuffer(clCxt->impl->clCmdQueue, sigSpc, CL_TRUE, 0, size_space, sigSpcH, 0, NULL, NULL));
+
+            size_t localSize[] = {16, 16};
+            size_t globalSize[] = {(cols / 16 + 1) * 16, (rows / 16 + 1) * 16};
+            openCLSafeCall(clEnqueueNDRangeKernel(clCxt->impl->clCmdQueue, kernel, 2, NULL, globalSize, localSize, 0, NULL, NULL));
+
+            clFinish(clCxt->impl->clCmdQueue);
+            openCLSafeCall(clReleaseKernel(kernel));
+            free(sigClrH);
+            free(sigSpcH);
+
+        }
+
+    }
+}
+#endif /* !defined (HAVE_OPENCL) */
diff --git a/modules/ocl/src/initialization.cpp b/modules/ocl/src/initialization.cpp
new file mode 100644 (file)
index 0000000..feff1db
--- /dev/null
@@ -0,0 +1,885 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Guoping Long, longguoping@gmail.com
+//       Niko Li, newlife20080214@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 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 "threadsafe.h"
+#include <iomanip>
+#include "binarycaching.hpp"
+
+using namespace cv;
+using namespace cv::ocl;
+using namespace std;
+using std::cout;
+using std::endl;
+
+//#define PRINT_KERNEL_RUN_TIME
+#define RUN_TIMES 100
+
+//#define AMD_DOUBLE_DIFFER
+
+#if !defined (HAVE_OPENCL)
+
+namespace cv
+{
+    namespace ocl
+    {
+
+        cl_device_id getDevice()
+        {
+            throw_nogpu();
+            return 0;
+        }
+
+        void getComputeCapability(cl_device_id, int &major, int &minor)
+        {
+            throw_nogpu();
+        }
+
+        void openCLMallocPitch(Context * /*clCxt*/, void ** /*dev_ptr*/, size_t * /*pitch*/,
+                size_t /*widthInBytes*/, size_t /*height*/)
+        {
+            throw_nogpu();
+        }
+
+        void openCLMemcpy2D(Context * /*clCxt*/, void * /*dst*/, size_t /*dpitch*/,
+                const void * /*src*/, size_t /*spitch*/,
+                size_t /*width*/, size_t /*height*/, enum openCLMemcpyKind /*kind*/)
+        {
+            throw_nogpu();
+        }
+
+        void openCLCopyBuffer2D(Context * /*clCxt*/, void * /*dst*/, size_t /*dpitch*/,
+                const void * /*src*/, size_t /*spitch*/,
+                size_t /*width*/, size_t /*height*/, enum openCLMemcpyKind /*kind*/)
+        {
+            throw_nogpu();
+        }
+
+        cl_mem openCLCreateBuffer(Context *,size_t, size_t)
+        {
+            throw_nogpu();
+        }
+
+        void openCLReadBuffer(Context *, cl_mem, void*, size_t)
+        {
+            throw_nogpu();
+        }
+
+        void openCLFree(void * /*devPtr*/)
+        {
+            throw_nogpu();
+        }
+
+        cl_kernel openCLGetKernelFromSource(const Context * /*clCxt*/,
+                const char ** /*fileName*/, string /*kernelName*/)
+        {
+            throw_nogpu();
+        }
+
+        void openCLVerifyKernel(const Context * /*clCxt*/, cl_kernel /*kernel*/, size_t * /*blockSize*/,
+                size_t * /*globalThreads*/, size_t * /*localThreads*/)
+        {
+            throw_nogpu();
+        }
+
+        cl_mem load_constant(cl_context context, cl_command_queue command_queue, const void *value,
+                const size_t size)
+        {
+            throw_nogpu();
+        }
+
+    }//namespace ocl
+}//namespace cv
+
+#else /* !defined (HAVE_OPENCL) */
+
+namespace cv
+{
+    namespace ocl
+    {
+        /*
+         * The binary caching system to eliminate redundant program source compilation.
+         * Strictly, this is not a cache because we do not implement evictions right now.
+         * We shall add such features to trade-off memory consumption and performance when necessary.
+         */
+        auto_ptr<ProgramCache> ProgramCache::programCache;
+        ProgramCache *programCache = NULL;
+        ProgramCache::ProgramCache()
+        {
+            codeCache.clear();
+            cacheSize = 0;
+        }
+
+        ProgramCache::~ProgramCache()
+        {
+            releaseProgram();
+        }
+
+        cl_program ProgramCache::progLookup(string srcsign)
+        {
+            map<string, cl_program>::iterator iter;
+            iter = codeCache.find(srcsign);
+            if(iter != codeCache.end())
+                return iter->second;
+            else
+                return NULL;
+        }
+
+        void ProgramCache::addProgram(string srcsign , cl_program program)
+        {
+            if(!progLookup(srcsign))
+            {
+                codeCache.insert(map<string, cl_program>::value_type(srcsign, program));
+            }
+        }
+
+        void ProgramCache::releaseProgram()
+        {
+            map<string, cl_program>::iterator iter;
+            for(iter = codeCache.begin(); iter != codeCache.end(); iter++)
+            {
+                openCLSafeCall(clReleaseProgram(iter->second));
+            }
+            codeCache.clear();
+            cacheSize = 0;
+        }
+
+        ////////////////////////Common OpenCL specific calls///////////////
+        //Info::Info()
+        //{
+        //     oclplatform = 0;
+        //     oclcontext = 0;
+        //     devnum = 0;
+        //}
+        //Info::~Info()
+        //{
+        //     release();
+        //}
+        //void Info::release()
+        //{
+        //     if(oclplatform)
+        //     {
+        //             oclplatform = 0;
+        //     }
+        //     if(oclcontext)
+        //     {
+        //             openCLSafeCall(clReleaseContext(oclcontext));
+        //     }
+        //     devices.empty();
+        //     devName.empty();
+        //}
+        struct Info::Impl
+        {
+            cl_platform_id oclplatform;
+            std::vector<cl_device_id> devices;
+            std::vector<std::string> devName;
+
+            cl_context oclcontext;
+            cl_command_queue clCmdQueue;
+            int devnum;
+            cl_uint maxDimensions;
+            size_t maxWorkGroupSize;
+            size_t *maxWorkItemSizes;
+            cl_uint maxComputeUnits;
+            char extra_options[512];
+            int  double_support;
+            Impl()
+            {
+                memset(extra_options,0,512);
+            }
+        };
+
+        inline int divUp(int total, int grain)
+        {
+            return (total + grain - 1) / grain;
+        }
+
+        int getDevice(std::vector<Info> &oclinfo, int devicetype)
+        {
+            cl_device_type _devicetype;
+            switch(devicetype)
+            {
+                case CVCL_DEVICE_TYPE_DEFAULT:
+                    _devicetype = CL_DEVICE_TYPE_DEFAULT;
+                    break;
+                case CVCL_DEVICE_TYPE_CPU:
+                    _devicetype = CL_DEVICE_TYPE_CPU;
+                    break;
+                case CVCL_DEVICE_TYPE_GPU:
+                    _devicetype = CL_DEVICE_TYPE_GPU;
+                    break;
+                case CVCL_DEVICE_TYPE_ACCELERATOR:
+                    _devicetype = CL_DEVICE_TYPE_ACCELERATOR;
+                    break;
+                case CVCL_DEVICE_TYPE_ALL:
+                    _devicetype = CL_DEVICE_TYPE_ALL;
+                    break;
+                default:
+                    CV_Error(-217,"Unkown device type");
+            }
+            int devcienums = 0;
+            // Platform info
+            cl_int status = 0;
+            cl_uint numPlatforms;
+            Info ocltmpinfo;
+            openCLSafeCall(clGetPlatformIDs(0, NULL, &numPlatforms));
+            CV_Assert(numPlatforms > 0);
+            cl_platform_id *platforms = new cl_platform_id[numPlatforms];
+
+            openCLSafeCall(clGetPlatformIDs(numPlatforms, platforms, NULL));
+            char deviceName[256];
+            for (unsigned i = 0; i < numPlatforms; ++i)
+            {
+                cl_uint numsdev;
+                status = clGetDeviceIDs(platforms[i], devicetype, 0, NULL, &numsdev);
+                if(status != CL_DEVICE_NOT_FOUND)
+                {
+                    openCLVerifyCall(status);
+                }
+                if(numsdev > 0)
+                {
+                    devcienums += numsdev;
+                    cl_device_id *devices = new cl_device_id[numsdev];
+                    openCLSafeCall(clGetDeviceIDs(platforms[i], devicetype, numsdev, devices, NULL));
+                    ocltmpinfo.impl->oclplatform = platforms[i];
+                    for(unsigned j = 0; j < numsdev; j++)
+                    {
+                        ocltmpinfo.impl->devices.push_back(devices[j]);
+                        openCLSafeCall(clGetDeviceInfo(devices[j], CL_DEVICE_NAME, 256, deviceName, NULL));
+                        ocltmpinfo.impl->devName.push_back(std::string(deviceName));
+                    }
+                    delete[] devices;
+                    oclinfo.push_back(ocltmpinfo);
+                    ocltmpinfo.release();
+                }
+            }
+            delete[] platforms;
+            if(devcienums > 0)
+            {
+                setDevice(oclinfo[0]);
+            }
+            return devcienums;
+        }
+        void setDevice(Info &oclinfo, int devnum)
+        {
+            CV_Assert(devnum >= 0);
+            cl_int status = 0;
+            cl_context_properties cps[3] =
+            {
+                CL_CONTEXT_PLATFORM, (cl_context_properties)(oclinfo.impl->oclplatform), 0
+            };
+            oclinfo.impl->devnum = devnum;
+            oclinfo.impl->oclcontext = clCreateContext(cps, 1, &oclinfo.impl->devices[devnum], NULL, NULL, &status);
+            openCLVerifyCall(status);
+            //create the command queue using the first device of the list
+            oclinfo.impl->clCmdQueue = clCreateCommandQueue(oclinfo.impl->oclcontext, oclinfo.impl->devices[devnum],
+                    CL_QUEUE_PROFILING_ENABLE, &status);
+            openCLVerifyCall(status);
+
+            //get device information
+            openCLSafeCall(clGetDeviceInfo(oclinfo.impl->devices[devnum], CL_DEVICE_MAX_WORK_GROUP_SIZE,
+                        sizeof(size_t), (void *)&oclinfo.impl->maxWorkGroupSize, NULL));
+            openCLSafeCall(clGetDeviceInfo(oclinfo.impl->devices[devnum], CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS,
+                        sizeof(cl_uint), (void *)&oclinfo.impl->maxDimensions, NULL));
+            oclinfo.impl->maxWorkItemSizes = new size_t[oclinfo.impl->maxDimensions];
+            openCLSafeCall(clGetDeviceInfo(oclinfo.impl->devices[devnum], CL_DEVICE_MAX_WORK_ITEM_SIZES,
+                        sizeof(size_t)*oclinfo.impl->maxDimensions, (void *)oclinfo.impl->maxWorkItemSizes, NULL));
+            openCLSafeCall(clGetDeviceInfo(oclinfo.impl->devices[devnum], CL_DEVICE_MAX_COMPUTE_UNITS,
+                        sizeof(cl_uint), (void *)&oclinfo.impl->maxComputeUnits, NULL));
+            //initialize extra options for compilation. Currently only fp64 is included.
+            //Assume 4KB is enough to store all possible extensions.
+
+            const int EXT_LEN = 4096 + 1 ;
+            char extends_set[EXT_LEN];
+            size_t extends_size;
+            openCLSafeCall(clGetDeviceInfo(oclinfo.impl->devices[devnum], CL_DEVICE_EXTENSIONS,
+                        EXT_LEN, (void *)extends_set, &extends_size));
+            CV_Assert(extends_size < EXT_LEN);
+            extends_set[EXT_LEN-1] = 0;
+            //oclinfo.extra_options = NULL;
+            int fp64_khr = string(extends_set).find("cl_khr_fp64");
+
+            if(fp64_khr >= 0 && fp64_khr < EXT_LEN)
+            {
+                sprintf(oclinfo.impl->extra_options , "-D DOUBLE_SUPPORT");
+                oclinfo.impl -> double_support = 1;
+            }
+            Context::setContext(oclinfo);
+        }
+
+        void openCLReadBuffer(Context *clCxt, cl_mem dst_buffer, void *host_buffer, size_t size)
+        {
+            cl_int status;
+            status = clEnqueueReadBuffer(clCxt->impl->clCmdQueue, dst_buffer, CL_TRUE, 0,
+                                 size, host_buffer, 0, NULL, NULL);
+            openCLVerifyCall(status);
+        }
+
+        cl_mem openCLCreateBuffer(Context *clCxt, size_t flag , size_t size)
+        {
+            cl_int status;
+            cl_mem buffer = clCreateBuffer(clCxt->impl->clContext,(cl_mem_flags)flag, size, NULL, &status);
+            openCLVerifyCall(status);
+            return buffer;
+        }
+
+        void openCLMallocPitch(Context *clCxt, void **dev_ptr, size_t *pitch,
+                size_t widthInBytes, size_t height)
+        {
+            cl_int status;
+
+            *dev_ptr = clCreateBuffer(clCxt->impl->clContext, CL_MEM_READ_WRITE,
+                    widthInBytes * height, 0, &status);
+            openCLVerifyCall(status);
+            *pitch = widthInBytes;
+        }
+
+        void openCLMemcpy2D(Context *clCxt, void *dst, size_t dpitch,
+                const void *src, size_t spitch,
+                size_t width, size_t height, enum openCLMemcpyKind kind)
+        {
+            size_t buffer_origin[3] = {0, 0, 0};
+            size_t host_origin[3] = {0, 0, 0};
+            size_t region[3] = {width, height, 1};
+            if(kind == clMemcpyHostToDevice)
+            {
+                openCLSafeCall(clEnqueueWriteBufferRect(clCxt->impl->clCmdQueue, (cl_mem)dst, CL_TRUE,
+                            buffer_origin, host_origin, region, dpitch, 0, spitch, 0, src, 0, 0, 0));
+            }
+            else if(kind == clMemcpyDeviceToHost)
+            {
+                openCLSafeCall(clEnqueueReadBufferRect(clCxt->impl->clCmdQueue, (cl_mem)src, CL_TRUE,
+                            buffer_origin, host_origin, region, spitch, 0, dpitch, 0, dst, 0, 0, 0));
+            }
+        }
+
+        void openCLCopyBuffer2D(Context *clCxt, void *dst, size_t dpitch, int dst_offset,
+                const void *src, size_t spitch,
+                size_t width, size_t height, int src_offset, enum openCLMemcpyKind kind)
+        {
+            size_t src_origin[3] = {src_offset % spitch, src_offset / spitch, 0};
+            size_t dst_origin[3] = {dst_offset % dpitch, dst_offset / dpitch, 0};
+            size_t region[3] = {width, height, 1};
+
+            openCLSafeCall(clEnqueueCopyBufferRect(clCxt->impl->clCmdQueue, (cl_mem)src, (cl_mem)dst, src_origin, dst_origin,
+                        region, spitch, 0, dpitch, 0, 0, 0, 0));
+        }
+
+        void openCLFree(void *devPtr)
+        {
+            openCLSafeCall(clReleaseMemObject((cl_mem)devPtr));
+        }
+        cl_kernel openCLGetKernelFromSource(const Context *clCxt, const char **source, string kernelName)
+        {
+            return openCLGetKernelFromSource(clCxt, source, kernelName, NULL);
+        }
+
+        
+        void setBinpath(const char *path)
+        {
+                       Context *clcxt = Context::getContext();
+                       clcxt->impl->Binpath = path;
+        }
+        int savetofile(const Context *clcxt,  cl_program &program, const char *fileName)
+        {
+            cl_int status;
+            size_t numDevices = 1;
+            cl_device_id *devices = clcxt->impl->devices;
+            //figure out the sizes of each of the binaries.
+            size_t *binarySizes = (size_t *)malloc( sizeof(size_t) * numDevices );
+
+            openCLSafeCall(clGetProgramInfo(program,
+                    CL_PROGRAM_BINARY_SIZES,
+                    sizeof(size_t) * numDevices,
+                    binarySizes, NULL));
+
+            size_t i = 0;
+            //copy over all of the generated binaries.
+            char **binaries = (char **)malloc( sizeof(char *) * numDevices );
+            if(binaries == NULL)
+            {
+                CV_Error(-217,"Failed to allocate host memory.(binaries)\r\n");
+            }
+
+            for(i = 0; i < numDevices; i++)
+            {
+                if(binarySizes[i] != 0)
+                {
+                    binaries[i] = (char *)malloc( sizeof(char) * binarySizes[i]);
+                    if(binaries[i] == NULL)
+                    {
+                        CV_Error(-217,"Failed to allocate host memory.(binaries[i])\r\n");
+                    }
+                }
+                else
+                {
+                    binaries[i] = NULL;
+                }
+            }
+            openCLSafeCall(clGetProgramInfo(program,
+                    CL_PROGRAM_BINARIES,
+                    sizeof(char *) * numDevices,
+                    binaries,
+                    NULL));
+
+            //dump out each binary into its own separate file.
+            for(i = 0; i < numDevices; i++)
+            {
+                if(binarySizes[i] != 0)
+                {
+                    char deviceName[1024];
+                    openCLSafeCall(clGetDeviceInfo(devices[i],
+                            CL_DEVICE_NAME,
+                            sizeof(deviceName),
+                            deviceName,
+                            NULL));
+
+                    printf( "%s binary kernel: %s\n", deviceName, fileName);
+                    FILE *fp = fopen(fileName, "wb+");
+                    if(fp == NULL)
+                    {
+                        char *temp;
+                        sprintf(temp, "Failed to load kernel file : %s\r\n", fileName);
+                        CV_Error(-217, temp);
+                    }
+                    else
+                    {
+                        fwrite(binaries[i], binarySizes[i], 1, fp);
+                        free(binaries[i]);
+                        fclose(fp);
+                    }
+                }
+                else
+                {
+                    printf("Skipping %s since there is no binary data to write!\n",
+                            fileName);
+                }
+            }
+            free(binarySizes);
+            free(binaries);
+            return 1;
+        }
+
+
+        cl_kernel openCLGetKernelFromSource(const Context *clCxt, const char **source, string kernelName,
+                const char *build_options)
+        {
+            cl_kernel kernel;
+            cl_program program ;
+            cl_int status = 0;
+            stringstream src_sign;
+            string srcsign;
+                       string filename;
+            CV_Assert(programCache != NULL);
+
+            if(NULL != build_options)
+                       {
+                src_sign << (int64)source << clCxt->impl->clContext << "_" << build_options;
+                       }
+            else
+                       {
+                src_sign << (int64)source << clCxt->impl->clContext;                   
+                       }
+            srcsign = src_sign.str();
+
+            program = NULL;
+            program = programCache->progLookup(srcsign);
+
+            if(!program)
+            {
+                //config build programs
+                char all_build_options[1024];
+                memset(all_build_options, 0, 1024);
+                char zeromem[512]={0};
+                if(0!=memcmp(clCxt -> impl->extra_options, zeromem,512))
+                    strcat(all_build_options, clCxt -> impl->extra_options);
+                strcat(all_build_options, " ");
+                if(build_options != NULL)
+                    strcat(all_build_options, build_options);
+                               if(all_build_options != NULL)
+                               {
+                                       filename = clCxt->impl->Binpath + "\\" + kernelName + "_" + clCxt->impl->devName + all_build_options + ".clb";
+                               }
+                               else
+                               {
+                                       filename = clCxt->impl->Binpath + "\\" + kernelName + "_" + clCxt->impl->devName + ".clb";
+                               }
+
+                FILE *fp;
+                fp = fopen(filename.c_str(), "rb");
+                if(fp == NULL || clCxt->impl->Binpath.size() == 0)    //we should genetate a binary file for the first time.
+                {
+                    program = clCreateProgramWithSource(
+                            clCxt->impl->clContext, 1, source, NULL, &status);
+                    openCLVerifyCall(status);
+                    status = clBuildProgram(program, 1, &(clCxt->impl->devices[0]), all_build_options, NULL, NULL);
+                    if(status == CL_SUCCESS && clCxt->impl->Binpath.size()) 
+                                               savetofile(clCxt, program, filename.c_str());
+                }
+                else
+                {
+                    fseek(fp, 0, SEEK_END);
+                    size_t binarySize = ftell(fp);
+                    fseek(fp, 0, SEEK_SET);
+                    char *binary = new char[binarySize];
+                    fread(binary, binarySize, 1, fp);
+                    fclose(fp);
+                    cl_int status = 0;
+                    program = clCreateProgramWithBinary(clCxt->impl->clContext,
+                            1,
+                            &(clCxt->impl->devices[0]),
+                            (const size_t *)&binarySize,
+                            (const unsigned char **)&binary,
+                            NULL,
+                            &status);
+                    openCLVerifyCall(status);
+                    status = clBuildProgram(program, 1, &(clCxt->impl->devices[0]), all_build_options, NULL, NULL);
+                }
+
+                if(status != CL_SUCCESS)
+                {
+                    if(status == CL_BUILD_PROGRAM_FAILURE)
+                    {
+                        cl_int logStatus;
+                        char *buildLog = NULL;
+                        size_t buildLogSize = 0;
+                        logStatus = clGetProgramBuildInfo(program,
+                                clCxt->impl->devices[0], CL_PROGRAM_BUILD_LOG, buildLogSize,
+                                buildLog, &buildLogSize);
+                        if(logStatus != CL_SUCCESS)
+                            cout << "Failed to build the program and get the build info." << endl;
+                        buildLog = new char[buildLogSize];
+                        CV_DbgAssert(!!buildLog);
+                        memset(buildLog, 0, buildLogSize);
+                        openCLSafeCall(clGetProgramBuildInfo(program, clCxt->impl->devices[0],
+                                    CL_PROGRAM_BUILD_LOG, buildLogSize, buildLog, NULL));
+                        cout << "\n\t\t\tBUILD LOG\n";
+                        cout << buildLog << endl;
+                        delete buildLog;
+                    }
+                    openCLVerifyCall(status);
+                }
+                //Cache the binary for future use if build_options is null
+                if( (programCache->cacheSize += 1) < programCache->MAX_PROG_CACHE_SIZE)
+                    programCache->addProgram(srcsign, program);
+                else 
+                                       cout << "Warning: code cache has been full.\n";
+            }
+            kernel = clCreateKernel(program, kernelName.c_str(), &status);
+            openCLVerifyCall(status);
+            return kernel;
+        }
+
+        void openCLVerifyKernel(const Context *clCxt, cl_kernel kernel, size_t *blockSize,
+                size_t *globalThreads, size_t *localThreads)
+        {
+            size_t kernelWorkGroupSize;
+            openCLSafeCall(clGetKernelWorkGroupInfo(kernel, clCxt->impl->devices[0],
+                        CL_KERNEL_WORK_GROUP_SIZE, sizeof(size_t), &kernelWorkGroupSize, 0));
+            CV_DbgAssert( (localThreads[0] <= clCxt->impl->maxWorkItemSizes[0]) &&
+                    (localThreads[1] <= clCxt->impl->maxWorkItemSizes[1]) &&
+                    (localThreads[2] <= clCxt->impl->maxWorkItemSizes[2]) &&
+                    ((localThreads[0] * localThreads[1] * localThreads[2]) <= kernelWorkGroupSize) &&
+                    (localThreads[0] * localThreads[1] * localThreads[2]) <= clCxt->impl->maxWorkGroupSize);
+        }
+
+#ifdef PRINT_KERNEL_RUN_TIME
+        static double total_execute_time = 0;
+        static double total_kernel_time = 0;
+#endif
+        void openCLExecuteKernel_(Context *clCxt , const char **source, string kernelName, size_t globalThreads[3],
+                size_t localThreads[3],  vector< pair<size_t, const void *> > &args, int channels,
+                int depth, char *build_options)
+        {
+            //construct kernel name
+            //The rule is functionName_Cn_Dn, C represent Channels, D Represent DataType Depth, n represent an integer number
+            //for exmaple split_C2_D2, represent the split kernel with channels =2 and dataType Depth = 2(Data type is char)
+            stringstream idxStr;
+            if(channels != -1)
+                idxStr << "_C" << channels;
+            if(depth != -1)
+                idxStr << "_D" << depth;
+            kernelName += idxStr.str();
+
+            cl_kernel kernel;
+            kernel = openCLGetKernelFromSource(clCxt, source, kernelName, build_options);
+
+            globalThreads[0] = divUp(globalThreads[0], localThreads[0]) * localThreads[0];
+            globalThreads[1] = divUp(globalThreads[1], localThreads[1]) * localThreads[1];
+            globalThreads[2] = divUp(globalThreads[2], localThreads[2]) * localThreads[2];
+
+            size_t blockSize = localThreads[0] * localThreads[1] * localThreads[2];
+            cv::ocl::openCLVerifyKernel(clCxt, kernel, &blockSize, globalThreads, localThreads);
+
+            for(int i = 0; i < args.size(); i ++)
+                openCLSafeCall(clSetKernelArg(kernel, i, args[i].first, args[i].second));
+
+#ifndef PRINT_KERNEL_RUN_TIME
+            openCLSafeCall(clEnqueueNDRangeKernel(clCxt->impl->clCmdQueue, kernel, 3, NULL, globalThreads,
+                        localThreads, 0, NULL, NULL));
+#else
+            cl_event event = NULL;
+            openCLSafeCall(clEnqueueNDRangeKernel(clCxt->impl->clCmdQueue, kernel, 3, NULL, globalThreads,
+                        localThreads, 0, NULL, &event));
+
+            cl_ulong start_time, end_time, queue_time;
+            double execute_time = 0;
+            double total_time   = 0;
+
+            openCLSafeCall(clWaitForEvents(1, &event));
+            openCLSafeCall(clGetEventProfilingInfo(event, CL_PROFILING_COMMAND_START,
+                        sizeof(cl_ulong), &start_time, 0));
+
+            openCLSafeCall(clGetEventProfilingInfo(event, CL_PROFILING_COMMAND_END,
+                        sizeof(cl_ulong), &end_time, 0));
+
+            openCLSafeCall(clGetEventProfilingInfo(event, CL_PROFILING_COMMAND_QUEUED,
+                        sizeof(cl_ulong), &queue_time, 0));
+
+            execute_time = (double)(end_time - start_time) / (1000 * 1000);
+            total_time = (double)(end_time - queue_time) / (1000 * 1000);
+
+            // cout << setiosflags(ios::left) << setw(15) << execute_time;
+            // cout << setiosflags(ios::left) << setw(15) << total_time - execute_time;
+            // cout << setiosflags(ios::left) << setw(15) << total_time << endl;
+
+            total_execute_time += execute_time;
+            total_kernel_time += total_time;
+            clReleaseEvent(event);
+#endif
+
+            clFinish(clCxt->impl->clCmdQueue);
+            openCLSafeCall(clReleaseKernel(kernel));
+        }
+
+        void openCLExecuteKernel(Context *clCxt , const char **source, string kernelName,
+                size_t globalThreads[3], size_t localThreads[3],
+                vector< pair<size_t, const void *> > &args, int channels, int depth)
+        {
+            openCLExecuteKernel(clCxt, source, kernelName, globalThreads, localThreads, args,
+                    channels, depth, NULL);
+        }
+        void openCLExecuteKernel(Context *clCxt , const char **source, string kernelName,
+                size_t globalThreads[3], size_t localThreads[3],
+                vector< pair<size_t, const void *> > &args, int channels, int depth, char *build_options)
+
+        {
+#ifndef PRINT_KERNEL_RUN_TIME
+            openCLExecuteKernel_(clCxt, source, kernelName, globalThreads, localThreads, args, channels, depth,
+                    build_options);
+#else
+            string data_type[] = { "uchar", "char", "ushort", "short", "int", "float", "double"};
+            cout << endl;
+            cout << "Function Name: " << kernelName;
+            if(depth >= 0)
+                cout << " |data type: " << data_type[depth];
+            cout << " |channels: " << channels;
+            cout << " |Time Unit: " << "ms" << endl;
+
+            total_execute_time = 0;
+            total_kernel_time = 0;
+            cout << "-------------------------------------" << endl;
+
+            cout << setiosflags(ios::left) << setw(15) << "excute time";
+            cout << setiosflags(ios::left) << setw(15) << "lauch time";
+            cout << setiosflags(ios::left) << setw(15) << "kernel time" << endl;
+            int i = 0;
+            for(i = 0; i < RUN_TIMES; i++)
+                openCLExecuteKernel_(clCxt, source, kernelName, globalThreads, localThreads, args, channels, depth,
+                        build_options);
+
+            cout << "average kernel excute time: " << total_execute_time / RUN_TIMES << endl; // "ms" << endl;
+            cout << "average kernel total time:  " << total_kernel_time / RUN_TIMES << endl; // "ms" << endl;
+#endif
+        }
+
+        cl_mem load_constant(cl_context context, cl_command_queue command_queue, const void *value,
+                const size_t size)
+        {
+            int status;
+            cl_mem con_struct;
+
+            con_struct = clCreateBuffer(context, CL_MEM_READ_ONLY, size, NULL, &status);
+            openCLSafeCall(status);
+
+            openCLSafeCall(clEnqueueWriteBuffer(command_queue, con_struct, 1, 0, size,
+                        value, 0, 0, 0));
+
+            return con_struct;
+
+        }
+
+        /////////////////////////////OpenCL initialization/////////////////
+        auto_ptr<Context> Context::clCxt;
+        int Context::val = 0;
+        CriticalSection cs;
+        Context *Context::getContext()
+        {
+            if(val == 0)
+            {
+                AutoLock al(&cs);
+                if( NULL == clCxt.get())
+                    clCxt.reset(new Context);
+
+                val = 1;
+                return clCxt.get();
+            }
+            else
+            {
+                return clCxt.get();
+            }
+        }
+        void Context::setContext(Info &oclinfo)
+        {
+            Context *clcxt = getContext();
+            clcxt->impl->clContext = oclinfo.impl->oclcontext;
+            clcxt->impl->clCmdQueue = oclinfo.impl->clCmdQueue;
+            clcxt->impl->devices = &oclinfo.impl->devices[oclinfo.impl->devnum];
+                       clcxt->impl->devName = oclinfo.impl->devName[oclinfo.impl->devnum];
+            clcxt->impl->maxDimensions = oclinfo.impl->maxDimensions;
+            clcxt->impl->maxWorkGroupSize = oclinfo.impl->maxWorkGroupSize;
+            clcxt->impl->maxWorkItemSizes = oclinfo.impl->maxWorkItemSizes;
+            clcxt->impl->maxComputeUnits = oclinfo.impl->maxComputeUnits;
+            clcxt->impl->double_support = oclinfo.impl->double_support;
+            //extra options to recognize compiler options
+            clcxt->impl->extra_options = oclinfo.impl->extra_options;
+        }
+        Context::Context()
+        {
+            impl = new Impl;
+            //Information of the OpenCL context
+            impl->clContext = NULL;
+            impl->clCmdQueue = NULL;
+            impl->devices = NULL;
+            impl->maxDimensions = 0;
+            impl->maxWorkGroupSize = 0;
+            impl->maxWorkItemSizes = NULL;
+            impl->maxComputeUnits = 0;
+            impl->double_support = 0;
+            //extra options to recognize vendor specific fp64 extensions
+            impl->extra_options = NULL;
+            programCache = ProgramCache::getProgramCache();
+        }
+
+        Context::~Context()
+        {
+            delete impl;
+            programCache->releaseProgram();
+        }
+        Info::Info()
+        {
+            impl = new Impl;
+            impl->oclplatform = 0;
+            impl->oclcontext = 0;
+            impl->clCmdQueue = 0;
+            impl->devnum = 0;
+            impl->maxDimensions = 0;
+            impl->maxWorkGroupSize = 0;
+            impl->maxWorkItemSizes = 0;
+            impl->maxComputeUnits = 0;
+            impl->double_support = 0;
+            //extra_options = 0;
+        }
+        void Info::release()
+        {
+            if(impl->oclplatform)
+            {
+                impl->oclplatform = 0;
+            }
+            if(impl->clCmdQueue)
+            {
+                openCLSafeCall(clReleaseCommandQueue(impl->clCmdQueue));
+            }
+            ProgramCache::getProgramCache()->releaseProgram();
+            if(impl->oclcontext)
+            {
+                openCLSafeCall(clReleaseContext(impl->oclcontext));
+            }
+            if(impl->maxWorkItemSizes)
+            {
+                delete[] impl->maxWorkItemSizes;
+                impl->maxWorkItemSizes = 0;
+            }
+            //if(extra_options)
+            //{
+            // delete[] extra_options;
+            // extra_options = 0;
+            //}
+            impl->devices.clear();
+            impl->devName.clear();
+        }
+        Info::~Info()
+        {
+            release();
+            delete impl;
+        }
+        Info &Info::operator = (const Info &m)
+        {
+            impl->oclplatform = m.impl->oclplatform;
+            impl->oclcontext = m.impl->oclcontext;
+            impl->clCmdQueue = m.impl->clCmdQueue;
+            impl->devnum = m.impl->devnum;
+            impl->maxDimensions = m.impl->maxDimensions;
+            impl->maxWorkGroupSize = m.impl->maxWorkGroupSize;
+            impl->maxWorkItemSizes = m.impl->maxWorkItemSizes;
+            impl->maxComputeUnits = m.impl->maxComputeUnits;
+            impl->double_support = m.impl->double_support;
+            memcpy(impl->extra_options, m.impl->extra_options, 512);
+            for(int i = 0; i < m.impl->devices.size(); i++)
+            {
+                impl->devices.push_back(m.impl->devices[i]);
+                impl->devName.push_back(m.impl->devName[i]);
+            }
+            return *this;
+        }
+        Info::Info(const Info &m)
+        {
+            impl = new Impl;
+            *this = m;
+        }
+    }//namespace ocl
+
+}//namespace cv
+#endif
diff --git a/modules/ocl/src/kernels/arithm_2_mat.cl b/modules/ocl/src/kernels/arithm_2_mat.cl
new file mode 100644 (file)
index 0000000..63c1cca
--- /dev/null
@@ -0,0 +1,158 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Shengen Yan,yanshengen@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 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*/
+
+/**************************************PUBLICFUNC*************************************/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics:enable
+#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics:enable
+#define CV_PI   3.1415926535897932384626433832795
+
+char round_char(double v){
+    char v1=(char)v;
+    return convert_char_sat(v+(v>=0 ? 0.5 : -0.5));
+}
+unsigned char round_uchar(double v){
+    unsigned char v1=(unsigned char)v;
+    return convert_uchar_sat(v+(v>=0 ? 0.5 : -0.5));
+}
+short round_short(double v){
+    short v1=(short)v;
+    return convert_short_sat(v+(v>=0 ? 0.5 : -0.5));
+}
+unsigned short round_ushort(double v){
+    unsigned short v1=(unsigned short)v;
+    return convert_ushort_sat(v+(v>=0 ? 0.5 : -0.5));
+}
+int round_int(double v){
+    int v1=(int)v;
+    return convert_int_sat(v+(v>=0 ? 0.5 : -0.5));
+}
+
+char round2_char(double v){
+    char v1=(char)v;
+    if((v-v1)==0.5&&v1%2==0)
+        return v1;
+    else
+        return convert_char_sat(v+(v>=0 ? 0.5 : -0.5));
+}
+unsigned char round2_uchar(double v){
+    unsigned char v1=(unsigned char)v;
+    if((v-v1)==0.5&&v1%2==0)
+        return v1;
+    else
+        return convert_uchar_sat(v+(v>=0 ? 0.5 : -0.5));
+}
+short round2_short(double v){
+    short v1=(short)v;
+    if((v-v1)==0.5&&v1%2==0)
+        return v1;
+    else
+        return convert_short_sat(v+(v>=0 ? 0.5 : -0.5));
+}
+unsigned short round2_ushort(double v){
+    unsigned short v1=(unsigned short)v;
+    if((v-v1)==0.5&&v1%2==0)
+        return v1;
+    else
+        return convert_ushort_sat(v+(v>=0 ? 0.5 : -0.5));
+}
+int round2_int(double v){
+    int v1=(int)v;
+    if((v-v1)==0.5&&v1%2==0)
+        return v1;
+    else
+        return convert_int_sat(v+(v>=0 ? 0.5 : -0.5));
+}
+
+/*****************************************EXP***************************************/
+__kernel void arithm_op_exp_5 (int rows,int cols,int srcStep,__global float *src1Mat,
+                             __global float * dstMat,int channels)
+{
+    size_t x = get_global_id(0);
+    size_t y = get_global_id(1);
+    if (x < cols && y < rows)
+    {
+        size_t idx = y * ( srcStep >> 2 ) + x;
+        dstMat[idx] = (float)exp((float)src1Mat[idx]);
+    }
+}
+__kernel void arithm_op_exp_6 (int rows,int cols,int srcStep,__global double *src1Mat,
+                             __global double * dstMat,int channels)
+{
+    size_t x = get_global_id(0);
+    size_t y = get_global_id(1);
+    if (x < cols && y < rows)
+    {
+        size_t idx = y * ( srcStep >> 3 ) + x;
+        dstMat[idx] = exp(src1Mat[idx]);
+    }
+}
+
+/*****************************************LOG***************************************/
+__kernel void arithm_op_log_5 (int rows,int cols,int srcStep,__global float *src1Mat,
+                             __global float * dstMat,int channels)
+{
+    size_t x = get_global_id(0);
+    size_t y = get_global_id(1);
+    if (x < cols && y < rows)
+    {
+        size_t idx = y * ( srcStep >> 2 ) + x;
+        dstMat[idx] =(float) log((float)src1Mat[idx]);
+    }
+}
+__kernel void arithm_op_log_6 (int rows,int cols,int srcStep,__global double *src1Mat,
+                             __global double * dstMat,int channels)
+{
+    size_t x = get_global_id(0);
+    size_t y = get_global_id(1);
+    if (x < cols && y < rows)
+    {
+        size_t idx = y * ( srcStep >> 3 ) + x;
+        dstMat[idx] = log(src1Mat[idx]);
+    }
+}
diff --git a/modules/ocl/src/kernels/arithm_LUT.cl b/modules/ocl/src/kernels/arithm_LUT.cl
new file mode 100644 (file)
index 0000000..9400ac6
--- /dev/null
@@ -0,0 +1,162 @@
+//                           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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Niko Li, newlife20080214@gmail.com
+//    Rock Li, Rock.li@amd.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.
+//
+//
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+__kernel
+void LUT_C1_D0( __global uchar *dst,
+         __global const uchar *src,
+         __constant uchar *table,
+         int rows,
+         int cols,
+         int channels,
+         int whole_rows,
+         int whole_cols,
+         int src_offset,
+         int dst_offset,
+         int lut_offset,
+         int src_step,
+         int dst_step)
+{
+       int gidx = get_global_id(0)<<2;
+       int gidy = get_global_id(1);
+       int lidx = get_local_id(0);
+       int lidy = get_local_id(1);
+
+       __local uchar l[256];
+       l[(lidy<<4)+lidx] = table[(lidy<<4)+lidx+lut_offset];
+       //mem_fence(CLK_LOCAL_MEM_FENCE);
+
+
+       //clamp(gidx,mask,cols-1);
+       gidx = gidx >= cols-4?cols-4:gidx;
+       gidy = gidy >= rows?rows-1:gidy;
+
+       int src_index = src_offset + mad24(gidy,src_step,gidx); 
+       int dst_index = dst_offset + mad24(gidy,dst_step,gidx);
+       uchar4 p,q;
+       barrier(CLK_LOCAL_MEM_FENCE);
+       p.x = src[src_index];
+       p.y = src[src_index+1];
+       p.z = src[src_index+2];
+       p.w = src[src_index+3];
+
+       q.x = l[p.x];
+       q.y = l[p.y];
+       q.z = l[p.z];
+       q.w = l[p.w];
+       *(__global uchar4*)(dst + dst_index) = q;
+}
+
+__kernel
+void LUT2_C1_D0( __global uchar *dst,
+         __global const uchar *src,
+         __constant uchar *table,
+         int rows,
+         int precols,
+         int channels,
+         int whole_rows,
+         int cols,
+         int src_offset,
+         int dst_offset,
+         int lut_offset,
+         int src_step,
+         int dst_step)
+{
+       int gidx = get_global_id(0);
+       int gidy = get_global_id(1);
+       //int lidx = get_local_id(0);
+       int lidy = get_local_id(1);
+
+       __local uchar l[256];
+       l[lidy] = table[lidy+lut_offset];
+       //mem_fence(CLK_LOCAL_MEM_FENCE);
+
+
+       //clamp(gidx,mask,cols-1);
+       gidx = gidx >= precols ? cols+gidx : gidx;
+       gidy = gidy >= rows?rows-1:gidy;
+
+       int src_index = src_offset + mad24(gidy,src_step,gidx); 
+       int dst_index = dst_offset + mad24(gidy,dst_step,gidx);
+       //uchar4 p,q;
+       barrier(CLK_LOCAL_MEM_FENCE);
+       uchar p = src[src_index];
+       uchar q = l[p];
+       dst[dst_index] = q;
+}
+
+__kernel
+void LUT_C4_D0( __global uchar4 *dst,
+         __global uchar4 *src,
+         __constant uchar *table,
+         uint rows,
+         uint cols,
+         uint channels,
+         uint whole_rows,
+         uint whole_cols,
+         uint src_offset,
+         uint dst_offset,
+         uint lut_offset,
+         uint src_step,
+         uint dst_step)
+{
+       uint gidx = get_global_id(0);
+       uint gidy = get_global_id(1);
+       
+       uint lidx = get_local_id(0);
+       uint lidy = get_local_id(1);
+
+       __local uchar l[256];
+       l[lidy*16+lidx] = table[lidy*16+lidx+lut_offset];
+       mem_fence(CLK_LOCAL_MEM_FENCE);
+       barrier(CLK_LOCAL_MEM_FENCE);
+       
+       gidx = gidx >= cols?cols-1:gidx;
+       gidy = gidy >= rows?rows-1:gidy;
+
+       uint src_index = src_offset/4 + gidy * src_step/4 + gidx;
+       
+       uint dst_index = dst_offset/4 + gidy * dst_step/4 + gidx;
+
+       uchar4 p = src[src_index];
+       dst[dst_index].x = l[p.x];      
+       dst[dst_index].y = l[p.y];      
+       dst[dst_index].z = l[p.z];      
+       dst[dst_index].w = l[p.w];      
+}
diff --git a/modules/ocl/src/kernels/arithm_absdiff.cl b/modules/ocl/src/kernels/arithm_absdiff.cl
new file mode 100644 (file)
index 0000000..6e17d52
--- /dev/null
@@ -0,0 +1,917 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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*/
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////absdiff////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+/**************************************adddiff *************************************/
+__kernel void arithm_absdiff_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                 __global uchar *src2, int src2_step, int src2_offset,
+                                 __global uchar *dst,  int dst_step,  int dst_offset,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = abs_diff(src1_data, src2_data);
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+__kernel void arithm_absdiff_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                                 __global ushort *src2, int src2_step, int src2_offset,
+                                 __global ushort *dst,  int dst_step,  int dst_offset,
+                                 int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        ushort4 src1_data = vload4(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort4 src2_data = vload4(0, (__global ushort *)((__global char *)src2 + src2_index));
+
+        ushort4 dst_data = *((__global ushort4 *)((__global char *)dst + dst_index));
+        ushort4 tmp_data = abs_diff(src1_data, src2_data);
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+}
+__kernel void arithm_absdiff_D3 (__global short *src1, int src1_step, int src1_offset,
+                                 __global short *src2, int src2_step, int src2_offset,
+                                 __global short *dst,  int dst_step,  int dst_offset,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        short4 src1_data = vload4(0, (__global short *)((__global char *)src1 + src1_index));
+        short4 src2_data = vload4(0, (__global short *)((__global char *)src2 + src2_index));
+
+        short4  dst_data = *((__global short4 *)((__global char *)dst + dst_index));
+        ushort4 tmp = abs_diff(src1_data, src2_data);
+        short4  tmp_data = convert_short4_sat(tmp);
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+}
+
+__kernel void arithm_absdiff_D4 (__global int *src1, int src1_step, int src1_offset,
+                                 __global int *src2, int src2_step, int src2_offset,
+                                 __global int *dst,  int dst_step,  int dst_offset,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        int data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int data2 = *((__global int *)((__global char *)src2 + src2_index));
+        uint tmp = abs_diff(data1, data2);
+        int  tmp_data = convert_int_sat(tmp);
+
+        *((__global int *)((__global char *)dst + dst_index)) = tmp_data;
+    }
+}
+__kernel void arithm_absdiff_D5 (__global float *src1, int src1_step, int src1_offset,
+                                 __global float *src2, int src2_step, int src2_offset,
+                                 __global float *dst,  int dst_step,  int dst_offset,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        float data1 = *((__global float *)((__global char *)src1 + src1_index));
+        float data2 = *((__global float *)((__global char *)src2 + src2_index));
+        float tmp = fabs(data1 - data2);
+
+        *((__global float *)((__global char *)dst + dst_index)) = tmp;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_absdiff_D6 (__global double *src1, int src1_step, int src1_offset,
+                                 __global double *src2, int src2_step, int src2_offset,
+                                 __global double *dst,  int dst_step,  int dst_offset,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        double data1 = *((__global double *)((__global char *)src1 + src1_index));
+        double data2 = *((__global double *)((__global char *)src2 + src2_index));
+        double tmp = fabs(data1-data2);
+
+        *((__global double *)((__global char *)dst + dst_index)) = tmp;
+    }
+}
+#endif
+
+/**************************************absdiff with scalar**************************************/
+__kernel void arithm_s_absdiff_C1_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                      __global   uchar *dst,  int dst_step,  int dst_offset,
+                                      int4 src2, int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        int4 src2_data = (int4)(src2.x, src2.x, src2.x, src2.x);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = convert_uchar4_sat(abs_diff(convert_int4_sat(src1_data), src2_data));
+
+        data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_absdiff_C1_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                      __global   ushort *dst,  int dst_step,  int dst_offset,
+                                      int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        ushort2 src1_data = vload2(0, (__global ushort *)((__global char *)src1 + src1_index));
+        int2 src2_data = (int2)(src2.x, src2.x);
+
+        ushort2 data = *((__global ushort2 *)((__global uchar *)dst + dst_index));
+        ushort2 tmp_data = convert_ushort2_sat(abs_diff(convert_int2_sat(src1_data), src2_data));
+
+        data.x = (dst_index + 0 >= dst_start) ? tmp_data.x : data.x;
+        data.y = (dst_index + 2 <  dst_end  ) ? tmp_data.y : data.y;
+
+        *((__global ushort2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_absdiff_C1_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                      __global   short *dst,  int dst_step,  int dst_offset,
+                                      int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        short2 src1_data = vload2(0, (__global short *)((__global char *)src1 + src1_index));
+        int2 src2_data = (int2)(src2.x, src2.x);
+        short2 data = *((__global short2 *)((__global uchar *)dst + dst_index));
+
+        ushort2 tmp = convert_ushort2_sat(abs_diff(convert_int2_sat(src1_data), src2_data));
+        short2 tmp_data = convert_short2_sat(tmp);
+
+        data.x = (dst_index + 0 >= dst_start) ? tmp_data.x : data.x;
+        data.y = (dst_index + 2 <  dst_end  ) ? tmp_data.y : data.y;
+
+        *((__global short2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_absdiff_C1_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                      __global   int *dst,  int dst_step,  int dst_offset,
+                                      int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        int src_data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int src_data2 = src2.x;
+        int dst_data  = *((__global int *)((__global char *)dst  + dst_index));
+
+        uint tmp_data = abs_diff(src_data1, src_data2);
+        int  data = convert_int_sat(tmp_data);
+
+        *((__global int *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_absdiff_C1_D5 (__global   float *src1, int src1_step, int src1_offset,
+                                      __global   float *dst,  int dst_step,  int dst_offset,
+                                      float4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        float src_data1 = *((__global float *)((__global char *)src1 + src1_index));
+        float src_data2 = src2.x;
+        float dst_data  = *((__global float *)((__global char *)dst  + dst_index));
+
+        float data = fabs(src_data1 - src_data2);
+
+        *((__global float *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_absdiff_C1_D6 (__global   double *src1, int src1_step, int src1_offset,
+                                     __global   double *dst,  int dst_step,  int dst_offset,
+                                     double4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        double src_data1 = *((__global double *)((__global char *)src1 + src1_index));
+        double src2_data = src2.x;
+        double dst_data  = *((__global double *)((__global char *)dst  + dst_index));
+
+        double data = fabs(src_data1 - src2_data);
+
+        *((__global double *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+
+__kernel void arithm_s_absdiff_C2_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                      __global   uchar *dst,  int dst_step,  int dst_offset,
+                                      int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        int4 src2_data = (int4)(src2.x, src2.y, src2.x, src2.y);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = convert_uchar4_sat(abs_diff(convert_int4_sat(src1_data), src2_data));
+
+        data.xy = (dst_index + 0 >= dst_start) ? tmp_data.xy : data.xy;
+        data.zw = (dst_index + 2 <  dst_end  ) ? tmp_data.zw : data.zw;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_absdiff_C2_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                      __global   ushort *dst,  int dst_step,  int dst_offset,
+                                      int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        ushort2 src_data1 = *((__global ushort2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = (int2)(src2.x, src2.y);
+        ushort2 dst_data  = *((__global ushort2 *)((__global char *)dst  + dst_index));
+
+        ushort2 data = convert_ushort2_sat( abs_diff(convert_int2_sat(src_data1), src_data2));
+
+        *((__global ushort2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_absdiff_C2_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                      __global   short *dst,  int dst_step,  int dst_offset,
+                                     int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        short2 src_data1 = *((__global short2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = (int2)(src2.x, src2.y);
+        short2 dst_data  = *((__global short2 *)((__global char *)dst  + dst_index));
+
+        ushort2 tmp = convert_ushort2_sat(abs_diff(convert_int2_sat(src_data1), src_data2));
+        short2 data = convert_short2_sat(tmp);
+
+        *((__global short2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_absdiff_C2_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                      __global   int *dst,  int dst_step,  int dst_offset,
+                                      int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        int2 src_data1 = *((__global int2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = (int2)(src2.x, src2.y);
+        int2 dst_data  = *((__global int2 *)((__global char *)dst  + dst_index));
+
+        int2 data = convert_int2_sat(abs_diff(src_data1, src_data2));
+        *((__global int2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_absdiff_C2_D5 (__global   float *src1, int src1_step, int src1_offset,
+                                      __global   float *dst,  int dst_step,  int dst_offset,
+                                     float4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        float2 src_data1 = *((__global float2 *)((__global char *)src1 + src1_index));
+        float2 src_data2 = (float2)(src2.x, src2.y);
+        float2 dst_data  = *((__global float2 *)((__global char *)dst  + dst_index));
+
+        float2 data = fabs(src_data1 - src_data2);
+        *((__global float2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_absdiff_C2_D6 (__global   double *src1, int src1_step, int src1_offset,
+                                      __global   double *dst,  int dst_step,  int dst_offset,
+                                      double4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        double2 src_data1 = *((__global double2 *)((__global char *)src1 + src1_index));
+        double2 src_data2 = (double2)(src2.x, src2.y);
+        double2 dst_data  = *((__global double2 *)((__global char *)dst  + dst_index));
+
+        double2 data = fabs(src_data1 - src_data2);
+
+        *((__global double2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+__kernel void arithm_s_absdiff_C3_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                      __global   uchar *dst,  int dst_step,  int dst_offset,
+                                      int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        uchar4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        uchar4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        uchar4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        int4 src2_data_0 = (int4)(src2.x, src2.y, src2.z, src2.x); 
+        int4 src2_data_1 = (int4)(src2.y, src2.z, src2.x, src2.y);
+        int4 src2_data_2 = (int4)(src2.z, src2.x, src2.y, src2.z); 
+
+        uchar4 data_0 = *((__global uchar4 *)(dst + dst_index + 0));
+        uchar4 data_1 = *((__global uchar4 *)(dst + dst_index + 4));
+        uchar4 data_2 = *((__global uchar4 *)(dst + dst_index + 8));
+
+        uchar4 tmp_data_0 = convert_uchar4_sat(abs_diff(convert_int4_sat(src1_data_0), src2_data_0));
+        uchar4 tmp_data_1 = convert_uchar4_sat(abs_diff(convert_int4_sat(src1_data_1), src2_data_1));
+        uchar4 tmp_data_2 = convert_uchar4_sat(abs_diff(convert_int4_sat(src1_data_2), src2_data_2));
+
+        data_0.xyz = ((dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global uchar4 *)(dst + dst_index + 0)) = data_0;
+        *((__global uchar4 *)(dst + dst_index + 4)) = data_1;
+        *((__global uchar4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+__kernel void arithm_s_absdiff_C3_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                      __global   ushort *dst,  int dst_step,  int dst_offset,
+                                      int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        ushort2 src1_data_0 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 0));
+        ushort2 src1_data_1 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 4));
+        ushort2 src1_data_2 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 8));
+
+        int2 src2_data_0 = (int2)(src2.x, src2.y);
+        int2 src2_data_1 = (int2)(src2.z, src2.x);
+        int2 src2_data_2 = (int2)(src2.y, src2.z);
+
+        ushort2 data_0 = *((__global ushort2 *)((__global char *)dst + dst_index + 0));
+        ushort2 data_1 = *((__global ushort2 *)((__global char *)dst + dst_index + 4));
+        ushort2 data_2 = *((__global ushort2 *)((__global char *)dst + dst_index + 8));
+
+        ushort2 tmp_data_0 = convert_ushort2_sat(abs_diff(convert_int2_sat(src1_data_0), src2_data_0));
+        ushort2 tmp_data_1 = convert_ushort2_sat(abs_diff(convert_int2_sat(src1_data_1), src2_data_1));
+        ushort2 tmp_data_2 = convert_ushort2_sat(abs_diff(convert_int2_sat(src1_data_2), src2_data_2));
+
+        data_0.xy = ((dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global ushort2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_absdiff_C3_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                      __global   short *dst,  int dst_step,  int dst_offset,
+                                      int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        short2 src1_data_0 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 0));
+        short2 src1_data_1 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 4));
+        short2 src1_data_2 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 8));
+
+        int2 src2_data_0 = (int2)(src2.x, src2.y);
+        int2 src2_data_1 = (int2)(src2.z, src2.x);
+        int2 src2_data_2 = (int2)(src2.y, src2.z);
+
+        short2 data_0 = *((__global short2 *)((__global char *)dst + dst_index + 0));
+        short2 data_1 = *((__global short2 *)((__global char *)dst + dst_index + 4));
+        short2 data_2 = *((__global short2 *)((__global char *)dst + dst_index + 8));
+
+        short2 tmp_data_0 = convert_short2_sat(abs_diff(convert_int2_sat(src1_data_0), src2_data_0));
+        short2 tmp_data_1 = convert_short2_sat(abs_diff(convert_int2_sat(src1_data_1), src2_data_1));
+        short2 tmp_data_2 = convert_short2_sat(abs_diff(convert_int2_sat(src1_data_2), src2_data_2));
+
+        data_0.xy = ((dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global short2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global short2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global short2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_absdiff_C3_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                      __global   int *dst,  int dst_step,  int dst_offset,
+                                      int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        int src1_data_0 = *((__global int *)((__global char *)src1 + src1_index + 0));
+        int src1_data_1 = *((__global int *)((__global char *)src1 + src1_index + 4));
+        int src1_data_2 = *((__global int *)((__global char *)src1 + src1_index + 8));
+
+        int src2_data_0 = src2.x;
+        int src2_data_1 = src2.y;
+        int src2_data_2 = src2.z;
+
+        int data_0 = *((__global int *)((__global char *)dst + dst_index + 0));
+        int data_1 = *((__global int *)((__global char *)dst + dst_index + 4));
+        int data_2 = *((__global int *)((__global char *)dst + dst_index + 8));
+
+        int tmp_data_0 = convert_int_sat(abs_diff(src1_data_0, src2_data_0));
+        int tmp_data_1 = convert_int_sat(abs_diff(src1_data_1, src2_data_1));
+        int tmp_data_2 = convert_int_sat(abs_diff(src1_data_2, src2_data_2));
+
+       *((__global int *)((__global char *)dst + dst_index + 0))= tmp_data_0;
+       *((__global int *)((__global char *)dst + dst_index + 4))= tmp_data_1;
+       *((__global int *)((__global char *)dst + dst_index + 8))= tmp_data_2;
+    }
+}
+__kernel void arithm_s_absdiff_C3_D5 (__global   float *src1, int src1_step, int src1_offset,
+                                      __global   float *dst,  int dst_step,  int dst_offset,
+                                      float4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        float src1_data_0 = *((__global float *)((__global char *)src1 + src1_index + 0));
+        float src1_data_1 = *((__global float *)((__global char *)src1 + src1_index + 4));
+        float src1_data_2 = *((__global float *)((__global char *)src1 + src1_index + 8));
+                                             
+        float src2_data_0 = src2.x;
+        float src2_data_1 = src2.y;
+        float src2_data_2 = src2.z;
+
+        float data_0 = *((__global float *)((__global char *)dst + dst_index + 0));
+        float data_1 = *((__global float *)((__global char *)dst + dst_index + 4));
+        float data_2 = *((__global float *)((__global char *)dst + dst_index + 8));
+
+        float tmp_data_0 = fabs(src1_data_0 - src2_data_0);
+        float tmp_data_1 = fabs(src1_data_1 - src2_data_1);
+        float tmp_data_2 = fabs(src1_data_2 - src2_data_2);
+
+       *((__global float *)((__global char *)dst + dst_index + 0))= tmp_data_0;
+       *((__global float *)((__global char *)dst + dst_index + 4))= tmp_data_1;
+       *((__global float *)((__global char *)dst + dst_index + 8))= tmp_data_2;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_absdiff_C3_D6 (__global   double *src1, int src1_step, int src1_offset,
+                                      __global   double *dst,  int dst_step,  int dst_offset,
+                                      double4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 24) + src1_offset); 
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 24));
+
+        double src1_data_0 = *((__global double *)((__global char *)src1 + src1_index + 0 ));
+        double src1_data_1 = *((__global double *)((__global char *)src1 + src1_index + 8 ));
+        double src1_data_2 = *((__global double *)((__global char *)src1 + src1_index + 16));
+                                               
+        double src2_data_0 = src2.x;
+        double src2_data_1 = src2.y;
+        double src2_data_2 = src2.z;
+
+        double data_0 = *((__global double *)((__global char *)dst + dst_index + 0 ));
+        double data_1 = *((__global double *)((__global char *)dst + dst_index + 8 ));
+        double data_2 = *((__global double *)((__global char *)dst + dst_index + 16));
+
+        double tmp_data_0 = fabs(src1_data_0 - src2_data_0);
+        double tmp_data_1 = fabs(src1_data_1 - src2_data_1);
+        double tmp_data_2 = fabs(src1_data_2 - src2_data_2);
+
+       *((__global double *)((__global char *)dst + dst_index + 0 ))= tmp_data_0;
+       *((__global double *)((__global char *)dst + dst_index + 8 ))= tmp_data_1;
+       *((__global double *)((__global char *)dst + dst_index + 16))= tmp_data_2;
+    }
+}
+#endif
+__kernel void arithm_s_absdiff_C4_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                      __global   uchar *dst,  int dst_step,  int dst_offset,
+                                      int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar4 src_data1 = *((__global uchar4 *)(src1 + src1_index));
+
+        uchar4 data = convert_uchar4_sat(abs_diff(convert_int4_sat(src_data1), src2));
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_absdiff_C4_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                      __global   ushort *dst,  int dst_step,  int dst_offset,
+                                      int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        ushort4 src_data1 = *((__global ushort4 *)((__global char *)src1 + src1_index));
+
+        ushort4 data = convert_ushort4_sat(abs_diff(convert_int4_sat(src_data1), src2));
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_absdiff_C4_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                      __global   short *dst,  int dst_step,  int dst_offset,
+                                      int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        short4 src_data1 = *((__global short4 *)((__global char *)src1 + src1_index));
+
+        short4 data = convert_short4_sat(abs_diff(convert_int4_sat(src_data1), src2));
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_absdiff_C4_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                      __global   int *dst,  int dst_step,  int dst_offset,
+                                      int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        int4 src_data1 = *((__global int4 *)((__global char *)src1 + src1_index));
+
+        int4 data = convert_int4_sat(abs_diff(src_data1, src2));
+
+        *((__global int4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_absdiff_C4_D5 (__global   float *src1, int src1_step, int src1_offset,
+                                      __global   float *dst,  int dst_step,  int dst_offset,
+                                      float4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        float4 src_data1 = *((__global float4 *)((__global char *)src1 + src1_index));
+
+        float4 data = fabs(src_data1 - src2);
+
+        *((__global float4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_absdiff_C4_D6 (__global   double *src1, int src1_step, int src1_offset,
+                                      __global   double *dst,  int dst_step,  int dst_offset,
+                                      double4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 5) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 5) + dst_offset);
+
+        double4 src_data1 = *((__global double4 *)((__global char *)src1 + src1_index));
+
+        double4 data = fabs(src_data1 - src2);
+
+        *((__global double4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
diff --git a/modules/ocl/src/kernels/arithm_add.cl b/modules/ocl/src/kernels/arithm_add.cl
new file mode 100644 (file)
index 0000000..3d5b13f
--- /dev/null
@@ -0,0 +1,1104 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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*/
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////ADD////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+/**************************************add without mask**************************************/
+__kernel void arithm_add_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                             __global uchar *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        short4 tmp      = convert_short4_sat(src1_data) + convert_short4_sat(src2_data);
+        uchar4 tmp_data = convert_uchar4_sat(tmp);
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+__kernel void arithm_add_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                             __global ushort *src2, int src2_step, int src2_offset,
+                             __global ushort *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        ushort4 src1_data = vload4(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort4 src2_data = vload4(0, (__global ushort *)((__global char *)src2 + src2_index));
+
+        ushort4 dst_data = *((__global ushort4 *)((__global char *)dst + dst_index));
+        int4    tmp = convert_int4_sat(src1_data) + convert_int4_sat(src2_data);
+        ushort4 tmp_data = convert_ushort4_sat(tmp);
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+}
+__kernel void arithm_add_D3 (__global short *src1, int src1_step, int src1_offset,
+                             __global short *src2, int src2_step, int src2_offset,
+                             __global short *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        short4 src1_data = vload4(0, (__global short *)((__global char *)src1 + src1_index));
+        short4 src2_data = vload4(0, (__global short *)((__global char *)src2 + src2_index));
+
+        short4 dst_data = *((__global short4 *)((__global char *)dst + dst_index));
+        int4   tmp = convert_int4_sat(src1_data) + convert_int4_sat(src2_data);
+        short4 tmp_data = convert_short4_sat(tmp);
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+}
+
+__kernel void arithm_add_D4 (__global int *src1, int src1_step, int src1_offset,
+                             __global int *src2, int src2_step, int src2_offset,
+                             __global int *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        int data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int data2 = *((__global int *)((__global char *)src2 + src2_index));
+        long tmp  = (long)(data1) + (long)(data2);
+
+        *((__global int *)((__global char *)dst + dst_index)) = convert_int_sat(tmp);
+    }
+}
+__kernel void arithm_add_D5 (__global float *src1, int src1_step, int src1_offset,
+                             __global float *src2, int src2_step, int src2_offset,
+                             __global float *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        float data1 = *((__global float *)((__global char *)src1 + src1_index));
+        float data2 = *((__global float *)((__global char *)src2 + src2_index));
+        float tmp = data1 + data2;
+
+        *((__global float *)((__global char *)dst + dst_index)) = tmp;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_add_D6 (__global double *src1, int src1_step, int src1_offset,
+                             __global double *src2, int src2_step, int src2_offset,
+                             __global double *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        double data1 = *((__global double *)((__global char *)src1 + src1_index));
+        double data2 = *((__global double *)((__global char *)src2 + src2_index));
+
+        *((__global double *)((__global char *)dst + dst_index)) = data1 + data2;
+    }
+}
+#endif
+
+/**************************************add with mask**************************************/
+__kernel void arithm_add_with_mask_C1_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                          __global uchar *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global uchar *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        short4 tmp = convert_short4_sat(src1_data) + convert_short4_sat(src2_data);
+        uchar4 tmp_data = convert_uchar4_sat(tmp);
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((mask_data.z) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((mask_data.w) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_add_with_mask_C1_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                                          __global ushort *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global ushort *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        ushort2 src1_data = vload2(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort2 src2_data = vload2(0, (__global ushort *)((__global char *)src2 + src2_index));
+        uchar2  mask_data = vload2(0, mask + mask_index);
+
+        ushort2 data = *((__global ushort2 *)((__global uchar *)dst + dst_index));
+        int2    tmp = convert_int2_sat(src1_data) + convert_int2_sat(src2_data);
+        ushort2 tmp_data = convert_ushort2_sat(tmp);
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.y : data.y;
+
+        *((__global ushort2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_add_with_mask_C1_D3 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        short2 src1_data = vload2(0, (__global short *)((__global char *)src1 + src1_index));
+        short2 src2_data = vload2(0, (__global short *)((__global char *)src2 + src2_index));
+        uchar2  mask_data = vload2(0, mask + mask_index);
+
+        short2 data = *((__global short2 *)((__global uchar *)dst + dst_index));
+        int2    tmp = convert_int2_sat(src1_data) + convert_int2_sat(src2_data);
+        short2 tmp_data = convert_short2_sat(tmp);
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.y : data.y;
+
+        *((__global short2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_add_with_mask_C1_D4 (__global int   *src1, int src1_step, int src1_offset,
+                                          __global int   *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global int   *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int src_data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int src_data2 = *((__global int *)((__global char *)src2 + src2_index));
+        int dst_data  = *((__global int *)((__global char *)dst  + dst_index));
+
+        int data = convert_int_sat((long)src_data1 + (long)src_data2);
+        data = mask_data ? data : dst_data; 
+
+        *((__global int *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_add_with_mask_C1_D5 (__global float *src1, int src1_step, int src1_offset,
+                                          __global float *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global float *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        float src_data1 = *((__global float *)((__global char *)src1 + src1_index));
+        float src_data2 = *((__global float *)((__global char *)src2 + src2_index));
+        float dst_data  = *((__global float *)((__global char *)dst  + dst_index));
+
+        float data = src_data1 + src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global float *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_add_with_mask_C1_D6 (__global double *src1, int src1_step, int src1_offset,
+                                          __global double *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global double *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        double src_data1 = *((__global double *)((__global char *)src1 + src1_index));
+        double src_data2 = *((__global double *)((__global char *)src2 + src2_index));
+        double dst_data  = *((__global double *)((__global char *)dst  + dst_index));
+
+        double data = src_data1 + src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global double *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+
+__kernel void arithm_add_with_mask_C2_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                          __global uchar *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global uchar *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        short4   tmp = convert_short4_sat(src1_data) + convert_short4_sat(src2_data);
+        uchar4 tmp_data = convert_uchar4_sat(tmp);
+
+        data.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.xy : data.xy;
+        data.zw = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.zw : data.zw;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_add_with_mask_C2_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                                          __global ushort *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global ushort *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        ushort2 src_data1 = *((__global ushort2 *)((__global char *)src1 + src1_index));
+        ushort2 src_data2 = *((__global ushort2 *)((__global char *)src2 + src2_index));
+        ushort2 dst_data  = *((__global ushort2 *)((__global char *)dst  + dst_index));
+
+        int2    tmp = convert_int2_sat(src_data1) + convert_int2_sat(src_data2);
+        ushort2 data = convert_ushort2_sat(tmp);
+        data = mask_data ? data : dst_data; 
+
+        *((__global ushort2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_add_with_mask_C2_D3 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short2 src_data1 = *((__global short2 *)((__global char *)src1 + src1_index));
+        short2 src_data2 = *((__global short2 *)((__global char *)src2 + src2_index));
+        short2 dst_data  = *((__global short2 *)((__global char *)dst  + dst_index));
+
+        int2    tmp = convert_int2_sat(src_data1) + convert_int2_sat(src_data2);
+        short2 data = convert_short2_sat(tmp);
+        data = mask_data ? data : dst_data; 
+
+        *((__global short2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_add_with_mask_C2_D4 (__global int   *src1, int src1_step, int src1_offset,
+                                          __global int   *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global int    *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int2 src_data1 = *((__global int2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = *((__global int2 *)((__global char *)src2 + src2_index));
+        int2 dst_data  = *((__global int2 *)((__global char *)dst  + dst_index));
+
+        int2 data = convert_int2_sat(convert_long2_sat(src_data1) + convert_long2_sat(src_data2));
+        data = mask_data ? data : dst_data; 
+
+        *((__global int2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_add_with_mask_C2_D5 (__global float *src1, int src1_step, int src1_offset,
+                                          __global float *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global float *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        float2 src_data1 = *((__global float2 *)((__global char *)src1 + src1_index));
+        float2 src_data2 = *((__global float2 *)((__global char *)src2 + src2_index));
+        float2 dst_data  = *((__global float2 *)((__global char *)dst  + dst_index));
+
+        float2 data = src_data1 + src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global float2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_add_with_mask_C2_D6 (__global double *src1, int src1_step, int src1_offset,
+                                          __global double *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global double *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 4) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        double2 src_data1 = *((__global double2 *)((__global char *)src1 + src1_index));
+        double2 src_data2 = *((__global double2 *)((__global char *)src2 + src2_index));
+        double2 dst_data  = *((__global double2 *)((__global char *)dst  + dst_index));
+
+        double2 data = src_data1 + src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global double2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+__kernel void arithm_add_with_mask_C3_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                          __global uchar *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global uchar *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+        int src2_index = mad24(y, src2_step, (x * 3) + src2_offset - (dst_align * 3)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        uchar4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        uchar4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        uchar4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        uchar4 src2_data_0 = vload4(0, src2 + src2_index + 0);
+        uchar4 src2_data_1 = vload4(0, src2 + src2_index + 4);
+        uchar4 src2_data_2 = vload4(0, src2 + src2_index + 8);
+
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        uchar4 data_0 = *((__global uchar4 *)(dst + dst_index + 0));
+        uchar4 data_1 = *((__global uchar4 *)(dst + dst_index + 4));
+        uchar4 data_2 = *((__global uchar4 *)(dst + dst_index + 8));
+
+        uchar4 tmp_data_0 = convert_uchar4_sat(convert_short4_sat(src1_data_0) + convert_short4_sat(src2_data_0));
+        uchar4 tmp_data_1 = convert_uchar4_sat(convert_short4_sat(src1_data_1) + convert_short4_sat(src2_data_1));
+        uchar4 tmp_data_2 = convert_uchar4_sat(convert_short4_sat(src1_data_2) + convert_short4_sat(src2_data_2));
+
+        data_0.xyz = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((mask_data.w) && (dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global uchar4 *)(dst + dst_index + 0)) = data_0;
+        *((__global uchar4 *)(dst + dst_index + 4)) = data_1;
+        *((__global uchar4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+__kernel void arithm_add_with_mask_C3_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                                          __global ushort *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global ushort *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+        int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        ushort2 src1_data_0 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 0));
+        ushort2 src1_data_1 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 4));
+        ushort2 src1_data_2 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 8));
+
+        ushort2 src2_data_0 = vload2(0, (__global ushort *)((__global char *)src2 + src2_index + 0));
+        ushort2 src2_data_1 = vload2(0, (__global ushort *)((__global char *)src2 + src2_index + 4));
+        ushort2 src2_data_2 = vload2(0, (__global ushort *)((__global char *)src2 + src2_index + 8));
+
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        ushort2 data_0 = *((__global ushort2 *)((__global char *)dst + dst_index + 0));
+        ushort2 data_1 = *((__global ushort2 *)((__global char *)dst + dst_index + 4));
+        ushort2 data_2 = *((__global ushort2 *)((__global char *)dst + dst_index + 8));
+
+        ushort2 tmp_data_0 = convert_ushort2_sat(convert_int2_sat(src1_data_0) + convert_int2_sat(src2_data_0));
+        ushort2 tmp_data_1 = convert_ushort2_sat(convert_int2_sat(src1_data_1) + convert_int2_sat(src2_data_1));
+        ushort2 tmp_data_2 = convert_ushort2_sat(convert_int2_sat(src1_data_2) + convert_int2_sat(src2_data_2));
+
+        data_0.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global ushort2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_add_with_mask_C3_D3 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+        int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        short2 src1_data_0 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 0));
+        short2 src1_data_1 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 4));
+        short2 src1_data_2 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 8));
+
+        short2 src2_data_0 = vload2(0, (__global short *)((__global char *)src2 + src2_index + 0));
+        short2 src2_data_1 = vload2(0, (__global short *)((__global char *)src2 + src2_index + 4));
+        short2 src2_data_2 = vload2(0, (__global short *)((__global char *)src2 + src2_index + 8));
+
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        short2 data_0 = *((__global short2 *)((__global char *)dst + dst_index + 0));
+        short2 data_1 = *((__global short2 *)((__global char *)dst + dst_index + 4));
+        short2 data_2 = *((__global short2 *)((__global char *)dst + dst_index + 8));
+
+        short2 tmp_data_0 = convert_short2_sat(convert_int2_sat(src1_data_0) + convert_int2_sat(src2_data_0));
+        short2 tmp_data_1 = convert_short2_sat(convert_int2_sat(src1_data_1) + convert_int2_sat(src2_data_1));
+        short2 tmp_data_2 = convert_short2_sat(convert_int2_sat(src1_data_2) + convert_int2_sat(src2_data_2));
+
+        data_0.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global short2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global short2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global short2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_add_with_mask_C3_D4 (__global int   *src1, int src1_step, int src1_offset,
+                                          __global int   *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global int   *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int src2_index = mad24(y, src2_step, (x * 12) + src2_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        int src1_data_0 = *((__global int *)((__global char *)src1 + src1_index + 0));
+        int src1_data_1 = *((__global int *)((__global char *)src1 + src1_index + 4));
+        int src1_data_2 = *((__global int *)((__global char *)src1 + src1_index + 8));
+
+        int src2_data_0 = *((__global int *)((__global char *)src2 + src2_index + 0));
+        int src2_data_1 = *((__global int *)((__global char *)src2 + src2_index + 4));
+        int src2_data_2 = *((__global int *)((__global char *)src2 + src2_index + 8));
+
+        uchar mask_data = * (mask + mask_index);
+
+        int data_0 = *((__global int *)((__global char *)dst + dst_index + 0));
+        int data_1 = *((__global int *)((__global char *)dst + dst_index + 4));
+        int data_2 = *((__global int *)((__global char *)dst + dst_index + 8));
+
+        int tmp_data_0 = convert_int_sat((long)src1_data_0 + (long)src2_data_0);
+        int tmp_data_1 = convert_int_sat((long)src1_data_1 + (long)src2_data_1);
+        int tmp_data_2 = convert_int_sat((long)src1_data_2 + (long)src2_data_2);
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global int *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global int *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global int *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_add_with_mask_C3_D5 (__global float *src1, int src1_step, int src1_offset,
+                                          __global float *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global float *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int src2_index = mad24(y, src2_step, (x * 12) + src2_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        float src1_data_0 = *((__global float *)((__global char *)src1 + src1_index + 0));
+        float src1_data_1 = *((__global float *)((__global char *)src1 + src1_index + 4));
+        float src1_data_2 = *((__global float *)((__global char *)src1 + src1_index + 8));
+                                             
+        float src2_data_0 = *((__global float *)((__global char *)src2 + src2_index + 0));
+        float src2_data_1 = *((__global float *)((__global char *)src2 + src2_index + 4));
+        float src2_data_2 = *((__global float *)((__global char *)src2 + src2_index + 8));
+
+        uchar mask_data = * (mask + mask_index);
+
+        float data_0 = *((__global float *)((__global char *)dst + dst_index + 0));
+        float data_1 = *((__global float *)((__global char *)dst + dst_index + 4));
+        float data_2 = *((__global float *)((__global char *)dst + dst_index + 8));
+
+        float tmp_data_0 = src1_data_0 + src2_data_0;
+        float tmp_data_1 = src1_data_1 + src2_data_1;
+        float tmp_data_2 = src1_data_2 + src2_data_2;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global float *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global float *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global float *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_add_with_mask_C3_D6 (__global double *src1, int src1_step, int src1_offset,
+                                          __global double *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global double *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 24) + src1_offset); 
+        int src2_index = mad24(y, src2_step, (x * 24) + src2_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 24));
+
+        double src1_data_0 = *((__global double *)((__global char *)src1 + src1_index + 0 ));
+        double src1_data_1 = *((__global double *)((__global char *)src1 + src1_index + 8 ));
+        double src1_data_2 = *((__global double *)((__global char *)src1 + src1_index + 16));
+                                               
+        double src2_data_0 = *((__global double *)((__global char *)src2 + src2_index + 0 ));
+        double src2_data_1 = *((__global double *)((__global char *)src2 + src2_index + 8 ));
+        double src2_data_2 = *((__global double *)((__global char *)src2 + src2_index + 16));
+
+        uchar mask_data = * (mask + mask_index);
+
+        double data_0 = *((__global double *)((__global char *)dst + dst_index + 0 ));
+        double data_1 = *((__global double *)((__global char *)dst + dst_index + 8 ));
+        double data_2 = *((__global double *)((__global char *)dst + dst_index + 16));
+
+        double tmp_data_0 = src1_data_0 + src2_data_0;
+        double tmp_data_1 = src1_data_1 + src2_data_1;
+        double tmp_data_2 = src1_data_2 + src2_data_2;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global double *)((__global char *)dst + dst_index + 0 ))= data_0;
+       *((__global double *)((__global char *)dst + dst_index + 8 ))= data_1;
+       *((__global double *)((__global char *)dst + dst_index + 16))= data_2;
+    }
+}
+#endif
+__kernel void arithm_add_with_mask_C4_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                          __global uchar *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global uchar *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        uchar4 src_data1 = *((__global uchar4 *)(src1 + src1_index));
+        uchar4 src_data2 = *((__global uchar4 *)(src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+
+        uchar4 data = convert_uchar4_sat(convert_ushort4_sat(src_data1) + convert_ushort4_sat(src_data2));
+        data = mask_data ? data : dst_data; 
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_add_with_mask_C4_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                                          __global ushort *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global ushort *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        ushort4 src_data1 = *((__global ushort4 *)((__global char *)src1 + src1_index));
+        ushort4 src_data2 = *((__global ushort4 *)((__global char *)src2 + src2_index));
+        ushort4 dst_data  = *((__global ushort4 *)((__global char *)dst  + dst_index));
+
+        ushort4 data = convert_ushort4_sat(convert_int4_sat(src_data1) + convert_int4_sat(src_data2));
+        data = mask_data ? data : dst_data; 
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_add_with_mask_C4_D3 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short4 src_data1 = *((__global short4 *)((__global char *)src1 + src1_index));
+        short4 src_data2 = *((__global short4 *)((__global char *)src2 + src2_index));
+        short4 dst_data  = *((__global short4 *)((__global char *)dst  + dst_index));
+
+        short4 data = convert_short4_sat(convert_int4_sat(src_data1) + convert_int4_sat(src_data2));
+        data = mask_data ? data : dst_data; 
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_add_with_mask_C4_D4 (__global int   *src1, int src1_step, int src1_offset,
+                                          __global int   *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global int   *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 4) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int4 src_data1 = *((__global int4 *)((__global char *)src1 + src1_index));
+        int4 src_data2 = *((__global int4 *)((__global char *)src2 + src2_index));
+        int4 dst_data  = *((__global int4 *)((__global char *)dst  + dst_index));
+
+        int4 data = convert_int4_sat(convert_long4_sat(src_data1) + convert_long4_sat(src_data2));
+        data = mask_data ? data : dst_data; 
+
+        *((__global int4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_add_with_mask_C4_D5 (__global float *src1, int src1_step, int src1_offset,
+                                          __global float *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global float *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 4) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        float4 src_data1 = *((__global float4 *)((__global char *)src1 + src1_index));
+        float4 src_data2 = *((__global float4 *)((__global char *)src2 + src2_index));
+        float4 dst_data  = *((__global float4 *)((__global char *)dst  + dst_index));
+
+        float4 data = src_data1 + src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global float4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_add_with_mask_C4_D6 (__global double *src1, int src1_step, int src1_offset,
+                                          __global double *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global double *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 5) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 5) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 5) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        double4 src_data1 = *((__global double4 *)((__global char *)src1 + src1_index));
+        double4 src_data2 = *((__global double4 *)((__global char *)src2 + src2_index));
+        double4 dst_data  = *((__global double4 *)((__global char *)dst  + dst_index));
+
+        double4 data = src_data1 + src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global double4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
diff --git a/modules/ocl/src/kernels/arithm_addWeighted.cl b/modules/ocl/src/kernels/arithm_addWeighted.cl
new file mode 100644 (file)
index 0000000..a34fd8d
--- /dev/null
@@ -0,0 +1,332 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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*/
+#if defined DOUBLE_SUPPORT
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+typedef double F;
+#else
+typedef float F;
+#endif
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////addWeighted//////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void addWeighted_D0 (__global uchar *src1, F alpha,int src1_step,int src1_offset,
+                           __global uchar *src2, F  beta, int src2_step,int src2_offset,
+                           F gama,
+                           __global uchar *dst,  int dst_step,int dst_offset,
+                           int rows,  int cols,int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    
+    {
+
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+//        short4 tmp      = convert_short4_sat(src1_data) * alpha + convert_short4_sat(src2_data) * beta + gama;
+         short4 tmp;
+        tmp.x = src1_data.x * alpha + src2_data.x * beta + gama;
+        tmp.y = src1_data.y * alpha + src2_data.y * beta + gama;
+        tmp.z = src1_data.z * alpha + src2_data.z * beta + gama;
+        tmp.w = src1_data.w * alpha + src2_data.w * beta + gama;
+        uchar4 tmp_data = convert_uchar4_sat(tmp);
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+       // dst[x + y * dst_step] = src1[x + y * src1_step] * alpha + src2[x + y * src2_step] * beta + gama;
+    }
+
+}
+
+
+
+__kernel void addWeighted_D2 (__global ushort *src1, F alpha,int src1_step,int src1_offset,
+                           __global ushort *src2, F beta, int src2_step,int src2_offset,
+                           F gama,
+                           __global ushort *dst,  int dst_step,int dst_offset,
+                           int rows,  int cols,int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    
+    {
+
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset -( dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset -( dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset +( x<< 1) & (int)0xfffffff8);
+
+        ushort4 src1_data = vload4(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort4 src2_data = vload4(0, (__global ushort *)((__global char *)src2 + src2_index));
+
+        ushort4 dst_data = *((__global ushort4 *)((__global char *)dst + dst_index));
+       // int4 tmp      = convert_int4_sat(src1_data) * alpha + convert_int4_sat(src2_data) * beta + gama;
+         int4 tmp;
+        tmp.x = src1_data.x * alpha + src2_data.x * beta + gama;
+        tmp.y = src1_data.y * alpha + src2_data.y * beta + gama;
+        tmp.z = src1_data.z * alpha + src2_data.z * beta + gama;
+        tmp.w = src1_data.w * alpha + src2_data.w * beta + gama;
+        ushort4 tmp_data = convert_ushort4_sat(tmp);
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+
+
+}
+
+
+__kernel void addWeighted_D3 (__global short *src1, F alpha,int src1_step,int src1_offset,
+                              __global short *src2, F beta, int src2_step,int src2_offset,
+                              F gama,
+                              __global short *dst,  int dst_step,int dst_offset,
+                              int rows,  int cols,int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    
+    {
+
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset -( dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset -( dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset +( x<< 1) - (dst_align << 1 ));
+
+        short4 src1_data = vload4(0, (__global short *)((__global char *)src1 + src1_index));
+        short4 src2_data = vload4(0, (__global short *)((__global char *)src2 + src2_index));
+
+        short4 dst_data = *((__global short4 *)((__global char *)dst + dst_index));
+       // int4 tmp      = convert_int4_sat(src1_data) * alpha + convert_int4_sat(src2_data) * beta + gama;
+         int4 tmp;
+        tmp.x = src1_data.x * alpha + src2_data.x * beta + gama;
+        tmp.y = src1_data.y * alpha + src2_data.y * beta + gama;
+        tmp.z = src1_data.z * alpha + src2_data.z * beta + gama;
+        tmp.w = src1_data.w * alpha + src2_data.w * beta + gama;
+        short4 tmp_data = convert_short4_sat(tmp);
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+
+}
+
+
+__kernel void addWeighted_D4 (__global int *src1, F alpha,int src1_step,int src1_offset,
+                              __global int *src2, F beta, int src2_step,int src2_offset,
+                              F gama,
+                              __global int *dst,  int dst_step,int dst_offset,
+                              int rows,  int cols,int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    
+    {
+            
+        x = x << 2;
+
+        #define bitOfInt  (sizeof(int)== 4 ? 2: 3)
+
+        #define dst_align ((dst_offset >> bitOfInt) & 3)
+
+        int src1_index = mad24(y, src1_step, (x << bitOfInt) + src1_offset - (dst_align << bitOfInt)); 
+        int src2_index = mad24(y, src2_step, (x << bitOfInt) + src2_offset - (dst_align << bitOfInt)); 
+       
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << bitOfInt) -(dst_align << bitOfInt));
+
+        int4 src1_data = vload4(0, (__global int *)((__global char *)src1 + src1_index));
+        int4 src2_data = vload4(0, (__global int *)((__global char *)src2 + src2_index));
+        int4 dst_data = *((__global int4 *)((__global char *)dst + dst_index));
+       // double4   tmp = convert_double4(src1_data) * alpha + convert_double4(src2_data) * beta + gama ;
+         float4 tmp;
+        tmp.x = src1_data.x * alpha + src2_data.x * beta + gama;
+        tmp.y = src1_data.y * alpha + src2_data.y * beta + gama;
+        tmp.z = src1_data.z * alpha + src2_data.z * beta + gama;
+        tmp.w = src1_data.w * alpha + src2_data.w * beta + gama;
+        int4 tmp_data = convert_int4_sat(tmp);
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 8 >= dst_start) && (dst_index + 8 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 12 >= dst_start) && (dst_index + 12 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global int4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+
+}
+
+
+__kernel void addWeighted_D5 (__global float *src1, F alpha,int src1_step,int src1_offset,
+                              __global float *src2, F beta, int src2_step,int src2_offset,
+                              F gama,
+                              __global float *dst,  int dst_step,int dst_offset,
+                              int rows,  int cols,int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    
+    {
+            
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 2) & 3)
+
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset - (dst_align << 2)); 
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset - (dst_align << 2)); 
+       
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 2) -(dst_align << 2));
+
+        float4 src1_data = vload4(0, (__global float  *)((__global char *)src1 + src1_index));
+        float4 src2_data = vload4(0, (__global float *)((__global char *)src2 + src2_index));
+        float4 dst_data = *((__global float4 *)((__global char *)dst + dst_index));
+    //    double4   tmp = convert_double4(src1_data) * alpha + convert_double4(src2_data) * beta + gama ;
+
+       // float4   tmp_data =(src1_data) * alpha + (src2_data) * beta + gama ;
+         float4 tmp_data;
+        tmp_data.x = src1_data.x * alpha + src2_data.x * beta + gama;
+        tmp_data.y = src1_data.y * alpha + src2_data.y * beta + gama;
+        tmp_data.z = src1_data.z * alpha + src2_data.z * beta + gama;
+        tmp_data.w = src1_data.w * alpha + src2_data.w * beta + gama;
+       // float4 tmp_data = convert_float4(tmp);
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 8 >= dst_start) && (dst_index + 8 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 12 >= dst_start) && (dst_index + 12 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global float4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void addWeighted_D6 (__global double *src1, F alpha,int src1_step,int src1_offset,
+                              __global double *src2, F beta, int src2_step,int src2_offset,
+                              F gama,
+                              __global double *dst,  int dst_step,int dst_offset,
+                              int rows,  int cols,int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    
+    {
+            
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 3) & 3)
+
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset - (dst_align << 3)); 
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset - (dst_align << 3)); 
+       
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 3) -(dst_align << 3));
+
+        double4 src1_data = vload4(0, (__global double  *)((__global char *)src1 + src1_index));
+        double4 src2_data = vload4(0, (__global double  *)((__global char *)src2 + src2_index));
+        double4 dst_data = *((__global double4 *)((__global char *)dst + dst_index));
+      //  double4   tmp_data = (src1_data) * alpha + (src2_data) * beta + gama ;
+         double4 tmp_data;
+        tmp_data.x = src1_data.x * alpha + src2_data.x * beta + gama;
+        tmp_data.y = src1_data.y * alpha + src2_data.y * beta + gama;
+        tmp_data.z = src1_data.z * alpha + src2_data.z * beta + gama;
+        tmp_data.w = src1_data.w * alpha + src2_data.w * beta + gama;
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 8 >= dst_start) && (dst_index + 8 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 16 >= dst_start) && (dst_index + 16 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 24 >= dst_start) && (dst_index + 24 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global double4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+
+}
+#endif
diff --git a/modules/ocl/src/kernels/arithm_add_scalar.cl b/modules/ocl/src/kernels/arithm_add_scalar.cl
new file mode 100644 (file)
index 0000000..4fa5e68
--- /dev/null
@@ -0,0 +1,744 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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*/
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+/**************************************add with scalar without mask**************************************/
+__kernel void arithm_s_add_C1_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                  __global   uchar *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        int4 src2_data = (int4)(src2.x, src2.x, src2.x, src2.x);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        int4 tmp = convert_int4_sat(src1_data) + src2_data;
+        uchar4 tmp_data = convert_uchar4_sat(tmp);
+
+        data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_C1_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                  __global   ushort *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        ushort2 src1_data = vload2(0, (__global ushort *)((__global char *)src1 + src1_index));
+        int2 src2_data = (int2)(src2.x, src2.x);
+
+        ushort2 data = *((__global ushort2 *)((__global uchar *)dst + dst_index));
+        int2    tmp = convert_int2_sat(src1_data) + src2_data;
+        ushort2 tmp_data = convert_ushort2_sat(tmp);
+
+        data.x = (dst_index + 0 >= dst_start) ? tmp_data.x : data.x;
+        data.y = (dst_index + 2 <  dst_end  ) ? tmp_data.y : data.y;
+
+        *((__global ushort2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_C1_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                  __global   short *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        short2 src1_data = vload2(0, (__global short *)((__global char *)src1 + src1_index));
+        int2 src2_data = (int2)(src2.x, src2.x);
+        short2 data = *((__global short2 *)((__global uchar *)dst + dst_index));
+
+        int2    tmp = convert_int2_sat(src1_data) + src2_data;
+        short2 tmp_data = convert_short2_sat(tmp);
+
+        data.x = (dst_index + 0 >= dst_start) ? tmp_data.x : data.x;
+        data.y = (dst_index + 2 <  dst_end  ) ? tmp_data.y : data.y;
+
+        *((__global short2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_C1_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                  __global   int *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        int src_data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int src_data2 = src2.x;
+        int dst_data  = *((__global int *)((__global char *)dst  + dst_index));
+
+        int data = convert_int_sat((long)src_data1 + (long)src_data2);
+
+        *((__global int *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_C1_D5 (__global   float *src1, int src1_step, int src1_offset,
+                                  __global   float *dst,  int dst_step,  int dst_offset,
+                                  float4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        float src_data1 = *((__global float *)((__global char *)src1 + src1_index));
+        float src_data2 = src2.x;
+        float dst_data  = *((__global float *)((__global char *)dst  + dst_index));
+
+        float data = src_data1 + src_data2;
+
+        *((__global float *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_add_C1_D6 (__global   double *src1, int src1_step, int src1_offset,
+                                  __global   double *dst,  int dst_step,  int dst_offset,
+                                  double4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        double src_data1 = *((__global double *)((__global char *)src1 + src1_index));
+        double src2_data = src2.x;
+        double dst_data  = *((__global double *)((__global char *)dst  + dst_index));
+
+        double data = src_data1 + src2_data;
+
+        *((__global double *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+
+__kernel void arithm_s_add_C2_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                  __global   uchar *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        int4 src2_data = (int4)(src2.x, src2.y, src2.x, src2.y);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        int4 tmp = convert_int4_sat(src1_data) + src2_data;
+        uchar4 tmp_data = convert_uchar4_sat(tmp);
+
+        data.xy = (dst_index + 0 >= dst_start) ? tmp_data.xy : data.xy;
+        data.zw = (dst_index + 2 <  dst_end  ) ? tmp_data.zw : data.zw;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_C2_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                  __global   ushort *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        ushort2 src_data1 = *((__global ushort2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = (int2)(src2.x, src2.y);
+        ushort2 dst_data  = *((__global ushort2 *)((__global char *)dst  + dst_index));
+
+        int2    tmp = convert_int2_sat(src_data1) + src_data2;
+        ushort2 data = convert_ushort2_sat(tmp);
+
+        *((__global ushort2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_C2_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                  __global   short *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        short2 src_data1 = *((__global short2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = (int2)(src2.x, src2.y);
+        short2 dst_data  = *((__global short2 *)((__global char *)dst  + dst_index));
+
+        int2    tmp = convert_int2_sat(src_data1) + src_data2;
+        short2 data = convert_short2_sat(tmp);
+
+        *((__global short2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_C2_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                  __global   int *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        int2 src_data1 = *((__global int2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = (int2)(src2.x, src2.y);
+        int2 dst_data  = *((__global int2 *)((__global char *)dst  + dst_index));
+
+        int2 data = convert_int2_sat(convert_long2_sat(src_data1) + convert_long2_sat(src_data2));
+        *((__global int2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_C2_D5 (__global   float *src1, int src1_step, int src1_offset,
+                                  __global   float *dst,  int dst_step,  int dst_offset,
+                                  float4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        float2 src_data1 = *((__global float2 *)((__global char *)src1 + src1_index));
+        float2 src_data2 = (float2)(src2.x, src2.y);
+        float2 dst_data  = *((__global float2 *)((__global char *)dst  + dst_index));
+
+        float2 data = src_data1 + src_data2;
+        *((__global float2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_add_C2_D6 (__global   double *src1, int src1_step, int src1_offset,
+                                  __global   double *dst,  int dst_step,  int dst_offset,
+                                  double4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        double2 src_data1 = *((__global double2 *)((__global char *)src1 + src1_index));
+        double2 src_data2 = (double2)(src2.x, src2.y);
+        double2 dst_data  = *((__global double2 *)((__global char *)dst  + dst_index));
+
+        double2 data = src_data1 + src_data2;
+
+        *((__global double2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+__kernel void arithm_s_add_C3_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                  __global   uchar *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        uchar4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        uchar4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        uchar4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        int4 src2_data_0 = (int4)(src2.x, src2.y, src2.z, src2.x); 
+        int4 src2_data_1 = (int4)(src2.y, src2.z, src2.x, src2.y);
+        int4 src2_data_2 = (int4)(src2.z, src2.x, src2.y, src2.z); 
+
+        uchar4 data_0 = *((__global uchar4 *)(dst + dst_index + 0));
+        uchar4 data_1 = *((__global uchar4 *)(dst + dst_index + 4));
+        uchar4 data_2 = *((__global uchar4 *)(dst + dst_index + 8));
+
+        uchar4 tmp_data_0 = convert_uchar4_sat(convert_int4_sat(src1_data_0) + src2_data_0);
+        uchar4 tmp_data_1 = convert_uchar4_sat(convert_int4_sat(src1_data_1) + src2_data_1);
+        uchar4 tmp_data_2 = convert_uchar4_sat(convert_int4_sat(src1_data_2) + src2_data_2);
+
+        data_0.xyz = ((dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global uchar4 *)(dst + dst_index + 0)) = data_0;
+        *((__global uchar4 *)(dst + dst_index + 4)) = data_1;
+        *((__global uchar4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+__kernel void arithm_s_add_C3_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                  __global   ushort *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        ushort2 src1_data_0 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 0));
+        ushort2 src1_data_1 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 4));
+        ushort2 src1_data_2 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 8));
+
+        int2 src2_data_0 = (int2)(src2.x, src2.y);
+        int2 src2_data_1 = (int2)(src2.z, src2.x);
+        int2 src2_data_2 = (int2)(src2.y, src2.z);
+
+        ushort2 data_0 = *((__global ushort2 *)((__global char *)dst + dst_index + 0));
+        ushort2 data_1 = *((__global ushort2 *)((__global char *)dst + dst_index + 4));
+        ushort2 data_2 = *((__global ushort2 *)((__global char *)dst + dst_index + 8));
+
+        ushort2 tmp_data_0 = convert_ushort2_sat(convert_int2_sat(src1_data_0) + src2_data_0);
+        ushort2 tmp_data_1 = convert_ushort2_sat(convert_int2_sat(src1_data_1) + src2_data_1);
+        ushort2 tmp_data_2 = convert_ushort2_sat(convert_int2_sat(src1_data_2) + src2_data_2);
+
+        data_0.xy = ((dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global ushort2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_add_C3_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                  __global   short *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        short2 src1_data_0 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 0));
+        short2 src1_data_1 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 4));
+        short2 src1_data_2 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 8));
+
+        int2 src2_data_0 = (int2)(src2.x, src2.y);
+        int2 src2_data_1 = (int2)(src2.z, src2.x);
+        int2 src2_data_2 = (int2)(src2.y, src2.z);
+
+        short2 data_0 = *((__global short2 *)((__global char *)dst + dst_index + 0));
+        short2 data_1 = *((__global short2 *)((__global char *)dst + dst_index + 4));
+        short2 data_2 = *((__global short2 *)((__global char *)dst + dst_index + 8));
+
+        short2 tmp_data_0 = convert_short2_sat(convert_int2_sat(src1_data_0) + src2_data_0);
+        short2 tmp_data_1 = convert_short2_sat(convert_int2_sat(src1_data_1) + src2_data_1);
+        short2 tmp_data_2 = convert_short2_sat(convert_int2_sat(src1_data_2) + src2_data_2);
+
+        data_0.xy = ((dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global short2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global short2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global short2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_add_C3_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                  __global   int *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        int src1_data_0 = *((__global int *)((__global char *)src1 + src1_index + 0));
+        int src1_data_1 = *((__global int *)((__global char *)src1 + src1_index + 4));
+        int src1_data_2 = *((__global int *)((__global char *)src1 + src1_index + 8));
+
+        int src2_data_0 = src2.x;
+        int src2_data_1 = src2.y;
+        int src2_data_2 = src2.z;
+
+        int data_0 = *((__global int *)((__global char *)dst + dst_index + 0));
+        int data_1 = *((__global int *)((__global char *)dst + dst_index + 4));
+        int data_2 = *((__global int *)((__global char *)dst + dst_index + 8));
+
+        int tmp_data_0 = convert_int_sat((long)src1_data_0 + (long)src2_data_0);
+        int tmp_data_1 = convert_int_sat((long)src1_data_1 + (long)src2_data_1);
+        int tmp_data_2 = convert_int_sat((long)src1_data_2 + (long)src2_data_2);
+
+       *((__global int *)((__global char *)dst + dst_index + 0))= tmp_data_0;
+       *((__global int *)((__global char *)dst + dst_index + 4))= tmp_data_1;
+       *((__global int *)((__global char *)dst + dst_index + 8))= tmp_data_2;
+    }
+}
+__kernel void arithm_s_add_C3_D5 (__global   float *src1, int src1_step, int src1_offset,
+                                  __global   float *dst,  int dst_step,  int dst_offset,
+                                  float4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        float src1_data_0 = *((__global float *)((__global char *)src1 + src1_index + 0));
+        float src1_data_1 = *((__global float *)((__global char *)src1 + src1_index + 4));
+        float src1_data_2 = *((__global float *)((__global char *)src1 + src1_index + 8));
+                                             
+        float src2_data_0 = src2.x;
+        float src2_data_1 = src2.y;
+        float src2_data_2 = src2.z;
+
+        float data_0 = *((__global float *)((__global char *)dst + dst_index + 0));
+        float data_1 = *((__global float *)((__global char *)dst + dst_index + 4));
+        float data_2 = *((__global float *)((__global char *)dst + dst_index + 8));
+
+        float tmp_data_0 = src1_data_0 + src2_data_0;
+        float tmp_data_1 = src1_data_1 + src2_data_1;
+        float tmp_data_2 = src1_data_2 + src2_data_2;
+
+       *((__global float *)((__global char *)dst + dst_index + 0))= tmp_data_0;
+       *((__global float *)((__global char *)dst + dst_index + 4))= tmp_data_1;
+       *((__global float *)((__global char *)dst + dst_index + 8))= tmp_data_2;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_add_C3_D6 (__global   double *src1, int src1_step, int src1_offset,
+                                  __global   double *dst,  int dst_step,  int dst_offset,
+                                  double4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 24) + src1_offset); 
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 24));
+
+        double src1_data_0 = *((__global double *)((__global char *)src1 + src1_index + 0 ));
+        double src1_data_1 = *((__global double *)((__global char *)src1 + src1_index + 8 ));
+        double src1_data_2 = *((__global double *)((__global char *)src1 + src1_index + 16));
+                                               
+        double src2_data_0 = src2.x;
+        double src2_data_1 = src2.y;
+        double src2_data_2 = src2.z;
+
+        double data_0 = *((__global double *)((__global char *)dst + dst_index + 0 ));
+        double data_1 = *((__global double *)((__global char *)dst + dst_index + 8 ));
+        double data_2 = *((__global double *)((__global char *)dst + dst_index + 16));
+
+        double tmp_data_0 = src1_data_0 + src2_data_0;
+        double tmp_data_1 = src1_data_1 + src2_data_1;
+        double tmp_data_2 = src1_data_2 + src2_data_2;
+
+       *((__global double *)((__global char *)dst + dst_index + 0 ))= tmp_data_0;
+       *((__global double *)((__global char *)dst + dst_index + 8 ))= tmp_data_1;
+       *((__global double *)((__global char *)dst + dst_index + 16))= tmp_data_2;
+    }
+}
+#endif
+__kernel void arithm_s_add_C4_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                  __global   uchar *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar4 src_data1 = *((__global uchar4 *)(src1 + src1_index));
+
+        uchar4 data = convert_uchar4_sat(convert_int4_sat(src_data1) + src2);
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_C4_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                  __global   ushort *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        ushort4 src_data1 = *((__global ushort4 *)((__global char *)src1 + src1_index));
+
+        ushort4 data = convert_ushort4_sat(convert_int4_sat(src_data1) + src2);
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_C4_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                  __global   short *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        short4 src_data1 = *((__global short4 *)((__global char *)src1 + src1_index));
+
+        short4 data = convert_short4_sat(convert_int4_sat(src_data1) + src2);
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_C4_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                  __global   int *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        int4 src_data1 = *((__global int4 *)((__global char *)src1 + src1_index));
+
+        int4 data = convert_int4_sat(convert_long4_sat(src_data1) + convert_long4_sat(src2));
+
+        *((__global int4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_C4_D5 (__global   float *src1, int src1_step, int src1_offset,
+                                  __global   float *dst,  int dst_step,  int dst_offset,
+                                  float4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        float4 src_data1 = *((__global float4 *)((__global char *)src1 + src1_index));
+
+        float4 data = src_data1 + src2;
+
+        *((__global float4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_add_C4_D6 (__global   double *src1, int src1_step, int src1_offset,
+                                  __global   double *dst,  int dst_step,  int dst_offset,
+                                  double4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 5) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 5) + dst_offset);
+
+        double4 src_data1 = *((__global double4 *)((__global char *)src1 + src1_index));
+
+        double4 data = src_data1 + src2;
+
+        *((__global double4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
diff --git a/modules/ocl/src/kernels/arithm_add_scalar_mask.cl b/modules/ocl/src/kernels/arithm_add_scalar_mask.cl
new file mode 100644 (file)
index 0000000..9e41d2c
--- /dev/null
@@ -0,0 +1,874 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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*/
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+/**************************************add with scalar with mask**************************************/
+__kernel void arithm_s_add_with_mask_C1_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                            __global   uchar *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        int4 src2_data = (int4)(src2.x, src2.x, src2.x, src2.x);
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        int4 tmp = convert_int4_sat(src1_data) + src2_data;
+        uchar4 tmp_data = convert_uchar4_sat(tmp);
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((mask_data.z) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((mask_data.w) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_with_mask_C1_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                            __global   ushort *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar  *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        ushort2 src1_data = vload2(0, (__global ushort *)((__global char *)src1 + src1_index));
+        int2 src2_data = (int2)(src2.x, src2.x);
+        uchar2  mask_data = vload2(0, mask + mask_index);
+
+        ushort2 data = *((__global ushort2 *)((__global uchar *)dst + dst_index));
+        int2    tmp = convert_int2_sat(src1_data) + src2_data;
+        ushort2 tmp_data = convert_ushort2_sat(tmp);
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.y : data.y;
+
+        *((__global ushort2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_with_mask_C1_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                            __global   short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        short2 src1_data = vload2(0, (__global short *)((__global char *)src1 + src1_index));
+        int2 src2_data = (int2)(src2.x, src2.x);
+        uchar2  mask_data = vload2(0, mask + mask_index);
+
+        short2 data = *((__global short2 *)((__global uchar *)dst + dst_index));
+        int2    tmp = convert_int2_sat(src1_data) + src2_data;
+        short2 tmp_data = convert_short2_sat(tmp);
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.y : data.y;
+
+        *((__global short2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_with_mask_C1_D4 (__global   int   *src1, int src1_step, int src1_offset,
+                                            __global   int   *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int src_data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int src_data2 = src2.x;
+        int dst_data  = *((__global int *)((__global char *)dst  + dst_index));
+
+        int data = convert_int_sat((long)src_data1 + (long)src_data2);
+        data = mask_data ? data : dst_data; 
+
+        *((__global int *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_add_with_mask_C1_D5 (__global   float   *src1, int src1_step, int src1_offset,
+                                            __global   float   *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            float4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        float src_data1 = *((__global float *)((__global char *)src1 + src1_index));
+        float src_data2 = src2.x;
+        float dst_data  = *((__global float *)((__global char *)dst  + dst_index));
+
+        float data = src_data1 + src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global float *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_add_with_mask_C1_D6 (__global   double   *src1, int src1_step, int src1_offset,
+                                            __global   double   *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            double4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        double src_data1 = *((__global double *)((__global char *)src1 + src1_index));
+        double src_data2 = src2.x;
+        double dst_data  = *((__global double *)((__global char *)dst  + dst_index));
+
+        double data = src_data1 + src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global double *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+__kernel void arithm_s_add_with_mask_C2_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                            __global   uchar *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        int4   src2_data = (int4)(src2.x, src2.y, src2.x, src2.y);
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        int4  tmp = convert_int4_sat(src1_data) + src2_data;
+        uchar4 tmp_data = convert_uchar4_sat(tmp);
+
+        data.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.xy : data.xy;
+        data.zw = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.zw : data.zw;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_with_mask_C2_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                            __global   ushort *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        ushort2 src_data1 = *((__global ushort2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = (int2)(src2.x, src2.y); 
+        ushort2 dst_data  = *((__global ushort2 *)((__global char *)dst  + dst_index));
+
+        int2    tmp = convert_int2_sat(src_data1) + src_data2;
+        ushort2 data = convert_ushort2_sat(tmp);
+        data = mask_data ? data : dst_data; 
+
+        *((__global ushort2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_with_mask_C2_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                            __global   short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short2 src_data1 = *((__global short2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = (int2)(src2.x, src2.y); 
+        short2 dst_data  = *((__global short2 *)((__global char *)dst  + dst_index));
+
+        int2    tmp = convert_int2_sat(src_data1) + src_data2;
+        short2 data = convert_short2_sat(tmp);
+        data = mask_data ? data : dst_data; 
+
+        *((__global short2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_with_mask_C2_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                            __global   int *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int2 src_data1 = *((__global int2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = (int2)(src2.x, src2.y); 
+        int2 dst_data  = *((__global int2 *)((__global char *)dst  + dst_index));
+
+        int2 data = convert_int2_sat(convert_long2_sat(src_data1) + convert_long2_sat(src_data2));
+        data = mask_data ? data : dst_data; 
+
+        *((__global int2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_with_mask_C2_D5 (__global   float *src1, int src1_step, int src1_offset,
+                                            __global   float *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            float4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        float2 src_data1 = *((__global float2 *)((__global char *)src1 + src1_index));
+        float2 src_data2 = (float2)(src2.x, src2.y); 
+        float2 dst_data  = *((__global float2 *)((__global char *)dst  + dst_index));
+
+        float2 data = src_data1 + src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global float2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_add_with_mask_C2_D6 (__global   double *src1, int src1_step, int src1_offset,
+                                            __global   double *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            double4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        double2 src_data1 = *((__global double2 *)((__global char *)src1 + src1_index));
+        double2 src_data2 = (double2)(src2.x, src2.y); 
+        double2 dst_data  = *((__global double2 *)((__global char *)dst  + dst_index));
+
+        double2 data = src_data1 + src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global double2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+
+__kernel void arithm_s_add_with_mask_C3_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                            __global   uchar *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        uchar4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        uchar4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        uchar4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        int4 src2_data_0 = (int4)(src2.x, src2.y, src2.z, src2.x);
+        int4 src2_data_1 = (int4)(src2.y, src2.z, src2.x, src2.y);
+        int4 src2_data_2 = (int4)(src2.z, src2.x, src2.y, src2.z);
+
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        uchar4 data_0 = *((__global uchar4 *)(dst + dst_index + 0));
+        uchar4 data_1 = *((__global uchar4 *)(dst + dst_index + 4));
+        uchar4 data_2 = *((__global uchar4 *)(dst + dst_index + 8));
+
+        uchar4 tmp_data_0 = convert_uchar4_sat(convert_int4_sat(src1_data_0) + src2_data_0);
+        uchar4 tmp_data_1 = convert_uchar4_sat(convert_int4_sat(src1_data_1) + src2_data_1);
+        uchar4 tmp_data_2 = convert_uchar4_sat(convert_int4_sat(src1_data_2) + src2_data_2);
+
+        data_0.xyz = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((mask_data.w) && (dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global uchar4 *)(dst + dst_index + 0)) = data_0;
+        *((__global uchar4 *)(dst + dst_index + 4)) = data_1;
+        *((__global uchar4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+__kernel void arithm_s_add_with_mask_C3_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                            __global   ushort *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        ushort2 src1_data_0 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 0));
+        ushort2 src1_data_1 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 4));
+        ushort2 src1_data_2 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 8));
+
+        int2 src2_data_0 = (int2)(src2.x, src2.y); 
+        int2 src2_data_1 = (int2)(src2.z, src2.x); 
+        int2 src2_data_2 = (int2)(src2.y, src2.z); 
+
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        ushort2 data_0 = *((__global ushort2 *)((__global char *)dst + dst_index + 0));
+        ushort2 data_1 = *((__global ushort2 *)((__global char *)dst + dst_index + 4));
+        ushort2 data_2 = *((__global ushort2 *)((__global char *)dst + dst_index + 8));
+
+        ushort2 tmp_data_0 = convert_ushort2_sat(convert_int2_sat(src1_data_0) + src2_data_0);
+        ushort2 tmp_data_1 = convert_ushort2_sat(convert_int2_sat(src1_data_1) + src2_data_1);
+        ushort2 tmp_data_2 = convert_ushort2_sat(convert_int2_sat(src1_data_2) + src2_data_2);
+
+        data_0.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global ushort2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_add_with_mask_C3_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                            __global   short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        short2 src1_data_0 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 0));
+        short2 src1_data_1 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 4));
+        short2 src1_data_2 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 8));
+
+        int2 src2_data_0 = (int2)(src2.x, src2.y); 
+        int2 src2_data_1 = (int2)(src2.z, src2.x); 
+        int2 src2_data_2 = (int2)(src2.y, src2.z); 
+
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        short2 data_0 = *((__global short2 *)((__global char *)dst + dst_index + 0));
+        short2 data_1 = *((__global short2 *)((__global char *)dst + dst_index + 4));
+        short2 data_2 = *((__global short2 *)((__global char *)dst + dst_index + 8));
+
+        short2 tmp_data_0 = convert_short2_sat(convert_int2_sat(src1_data_0) + src2_data_0);
+        short2 tmp_data_1 = convert_short2_sat(convert_int2_sat(src1_data_1) + src2_data_1);
+        short2 tmp_data_2 = convert_short2_sat(convert_int2_sat(src1_data_2) + src2_data_2);
+
+        data_0.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global short2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global short2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global short2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_add_with_mask_C3_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                            __global   int *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        int src1_data_0 = *((__global int *)((__global char *)src1 + src1_index + 0));
+        int src1_data_1 = *((__global int *)((__global char *)src1 + src1_index + 4));
+        int src1_data_2 = *((__global int *)((__global char *)src1 + src1_index + 8));
+
+        int src2_data_0 = src2.x; 
+        int src2_data_1 = src2.y;
+        int src2_data_2 = src2.z; 
+
+        uchar mask_data = * (mask + mask_index);
+
+        int data_0 = *((__global int *)((__global char *)dst + dst_index + 0));
+        int data_1 = *((__global int *)((__global char *)dst + dst_index + 4));
+        int data_2 = *((__global int *)((__global char *)dst + dst_index + 8));
+
+        int tmp_data_0 = convert_int_sat((long)src1_data_0 + (long)src2_data_0);
+        int tmp_data_1 = convert_int_sat((long)src1_data_1 + (long)src2_data_1);
+        int tmp_data_2 = convert_int_sat((long)src1_data_2 + (long)src2_data_2);
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global int *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global int *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global int *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_add_with_mask_C3_D5 (__global   float *src1, int src1_step, int src1_offset,
+                                            __global   float *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            float4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        float src1_data_0 = *((__global float *)((__global char *)src1 + src1_index + 0));
+        float src1_data_1 = *((__global float *)((__global char *)src1 + src1_index + 4));
+        float src1_data_2 = *((__global float *)((__global char *)src1 + src1_index + 8));
+                                             
+        float src2_data_0 = src2.x; 
+        float src2_data_1 = src2.y;
+        float src2_data_2 = src2.z; 
+
+        uchar mask_data = * (mask + mask_index);
+
+        float data_0 = *((__global float *)((__global char *)dst + dst_index + 0));
+        float data_1 = *((__global float *)((__global char *)dst + dst_index + 4));
+        float data_2 = *((__global float *)((__global char *)dst + dst_index + 8));
+
+        float tmp_data_0 = src1_data_0 + src2_data_0;
+        float tmp_data_1 = src1_data_1 + src2_data_1;
+        float tmp_data_2 = src1_data_2 + src2_data_2;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global float *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global float *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global float *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_add_with_mask_C3_D6 (__global   double *src1, int src1_step, int src1_offset,
+                                            __global   double *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar  *mask, int mask_step, int mask_offset,
+                                            double4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 24) + src1_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 24));
+
+        double src1_data_0 = *((__global double *)((__global char *)src1 + src1_index + 0 ));
+        double src1_data_1 = *((__global double *)((__global char *)src1 + src1_index + 8 ));
+        double src1_data_2 = *((__global double *)((__global char *)src1 + src1_index + 16));
+                                               
+        double src2_data_0 = src2.x; 
+        double src2_data_1 = src2.y;
+        double src2_data_2 = src2.z; 
+
+        uchar mask_data = * (mask + mask_index);
+
+        double data_0 = *((__global double *)((__global char *)dst + dst_index + 0 ));
+        double data_1 = *((__global double *)((__global char *)dst + dst_index + 8 ));
+        double data_2 = *((__global double *)((__global char *)dst + dst_index + 16));
+
+        double tmp_data_0 = src1_data_0 + src2_data_0;
+        double tmp_data_1 = src1_data_1 + src2_data_1;
+        double tmp_data_2 = src1_data_2 + src2_data_2;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global double *)((__global char *)dst + dst_index + 0 ))= data_0;
+       *((__global double *)((__global char *)dst + dst_index + 8 ))= data_1;
+       *((__global double *)((__global char *)dst + dst_index + 16))= data_2;
+    }
+}
+#endif
+
+__kernel void arithm_s_add_with_mask_C4_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                            __global   uchar *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        uchar4 src_data1 = *((__global uchar4 *)(src1 + src1_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+
+        uchar4 data = convert_uchar4_sat(convert_int4_sat(src_data1) + src2);
+        data = mask_data ? data : dst_data; 
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_with_mask_C4_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                            __global   ushort *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        ushort4 src_data1 = *((__global ushort4 *)((__global char *)src1 + src1_index));
+        ushort4 dst_data  = *((__global ushort4 *)((__global char *)dst  + dst_index));
+
+        ushort4 data = convert_ushort4_sat(convert_int4_sat(src_data1) + src2);
+        data = mask_data ? data : dst_data; 
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_with_mask_C4_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                            __global   short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short4 src_data1 = *((__global short4 *)((__global char *)src1 + src1_index));
+        short4 dst_data  = *((__global short4 *)((__global char *)dst  + dst_index));
+
+        short4 data = convert_short4_sat(convert_int4_sat(src_data1) + src2);
+        data = mask_data ? data : dst_data; 
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_with_mask_C4_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                            __global   int *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int4 src_data1 = *((__global int4 *)((__global char *)src1 + src1_index));
+        int4 dst_data  = *((__global int4 *)((__global char *)dst  + dst_index));
+
+        int4 data = convert_int4_sat(convert_long4_sat(src_data1) + convert_long4_sat(src2));
+        data = mask_data ? data : dst_data; 
+
+        *((__global int4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_add_with_mask_C4_D5 (__global   float *src1, int src1_step, int src1_offset,
+                                            __global   float *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            float4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        float4 src_data1 = *((__global float4 *)((__global char *)src1 + src1_index));
+        float4 dst_data  = *((__global float4 *)((__global char *)dst  + dst_index));
+
+        float4 data = src_data1 + src2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global float4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_add_with_mask_C4_D6 (__global   double *src1, int src1_step, int src1_offset,
+                                            __global   double *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            double4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 5) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 5) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        double4 src_data1 = *((__global double4 *)((__global char *)src1 + src1_index));
+        double4 dst_data  = *((__global double4 *)((__global char *)dst  + dst_index));
+
+        double4 data = src_data1 + src2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global double4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
diff --git a/modules/ocl/src/kernels/arithm_bitwise_and.cl b/modules/ocl/src/kernels/arithm_bitwise_and.cl
new file mode 100644 (file)
index 0000000..49db2df
--- /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.
+//
+//
+//                           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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jiang Liyuan, jlyuan001.good@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*/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////BITWISE_AND////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+/**************************************bitwise_and without mask**************************************/
+__kernel void arithm_bitwise_and_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                             __global uchar *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = src1_data & src2_data;
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+
+__kernel void arithm_bitwise_and_D1 (__global char *src1, int src1_step, int src1_offset,
+                             __global char *src2, int src2_step, int src2_offset,
+                             __global char *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+        char4 src2_data = vload4(0, src2 + src2_index);
+
+        char4 dst_data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = src1_data & src2_data;
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global char4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+
+__kernel void arithm_bitwise_and_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                             __global ushort *src2, int src2_step, int src2_offset,
+                             __global ushort *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        ushort4 src1_data = vload4(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort4 src2_data = vload4(0, (__global ushort *)((__global char *)src2 + src2_index));
+
+        ushort4 dst_data = *((__global ushort4 *)((__global char *)dst + dst_index));
+        ushort4 tmp_data = src1_data & src2_data;
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_and_D3 (__global short *src1, int src1_step, int src1_offset,
+                             __global short *src2, int src2_step, int src2_offset,
+                             __global short *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        short4 src1_data = vload4(0, (__global short *)((__global char *)src1 + src1_index));
+        short4 src2_data = vload4(0, (__global short *)((__global char *)src2 + src2_index));
+
+        short4 dst_data = *((__global short4 *)((__global char *)dst + dst_index));
+        short4 tmp_data = src1_data & src2_data;
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_and_D4 (__global int *src1, int src1_step, int src1_offset,
+                             __global int *src2, int src2_step, int src2_offset,
+                             __global int *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        int data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int data2 = *((__global int *)((__global char *)src2 + src2_index));
+        int tmp  = data1 & data2;
+
+        *((__global int *)((__global char *)dst + dst_index)) = tmp;
+    }
+}
+
+__kernel void arithm_bitwise_and_D5 (__global char *src1, int src1_step, int src1_offset,
+                             __global char *src2, int src2_step, int src2_offset,
+                             __global char *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        char4 data1 = *((__global char4 *)((__global char *)src1 + src1_index));
+        char4 data2 = *((__global char4 *)((__global char *)src2 + src2_index));
+        char4 tmp = data1 & data2;
+
+        *((__global char4 *)((__global char *)dst + dst_index)) = tmp;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_bitwise_and_D6 (__global char *src1, int src1_step, int src1_offset,
+                             __global char *src2, int src2_step, int src2_offset,
+                             __global char *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        char8 data1 = *((__global char8 *)((__global char *)src1 + src1_index));
+        char8 data2 = *((__global char8 *)((__global char *)src2 + src2_index));
+
+        *((__global char8 *)((__global char *)dst + dst_index)) = data1 & data2;
+    }
+}
+#endif
+
diff --git a/modules/ocl/src/kernels/arithm_bitwise_and_mask.cl b/modules/ocl/src/kernels/arithm_bitwise_and_mask.cl
new file mode 100644 (file)
index 0000000..43986e3
--- /dev/null
@@ -0,0 +1,1138 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jiang Liyuan, jlyuan001.good@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*/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////BITWISE_AND////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+/**************************************bitwise_and with mask**************************************/
+__kernel void arithm_bitwise_and_with_mask_C1_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                          __global uchar *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global uchar *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = src1_data & src2_data;
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((mask_data.z) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((mask_data.w) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_and_with_mask_C1_D1 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+        char4 src2_data = vload4(0, src2 + src2_index);
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        char4 data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = src1_data & src2_data;
+
+        data.x = convert_char((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = convert_char((mask_data.y) && (dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = convert_char((mask_data.z) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = convert_char((mask_data.w) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_and_with_mask_C1_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                                          __global ushort *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global ushort *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        ushort2 src1_data = vload2(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort2 src2_data = vload2(0, (__global ushort *)((__global char *)src2 + src2_index));
+        uchar2  mask_data = vload2(0, mask + mask_index);
+
+        ushort2 data = *((__global ushort2 *)((__global uchar *)dst + dst_index));
+        ushort2 tmp_data = src1_data & src2_data;
+
+        data.x = convert_ushort((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = convert_ushort((mask_data.y) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : data.y;
+
+        *((__global ushort2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_and_with_mask_C1_D3 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        short2 src1_data = vload2(0, (__global short *)((__global char *)src1 + src1_index));
+        short2 src2_data = vload2(0, (__global short *)((__global char *)src2 + src2_index));
+        uchar2  mask_data = vload2(0, mask + mask_index);
+
+       short2 data = *((__global short2 *)((__global uchar *)dst + dst_index));
+       short2 tmp_data = src1_data & src2_data;
+
+        data.x = convert_short((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = convert_short((mask_data.y) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : data.y;
+
+        *((__global short2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_and_with_mask_C1_D4 (__global int   *src1, int src1_step, int src1_offset,
+                                          __global int   *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global int   *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int src_data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int src_data2 = *((__global int *)((__global char *)src2 + src2_index));
+        int dst_data  = *((__global int *)((__global char *)dst  + dst_index));
+
+        int data = src_data1 & src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global int *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_and_with_mask_C1_D5 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char4 src_data1 = *((__global char4 *)((__global char *)src1 + src1_index));
+        char4 src_data2 = *((__global char4 *)((__global char *)src2 + src2_index));
+        char4 dst_data  = *((__global char4 *)((__global char *)dst  + dst_index));
+
+        char4 data = src_data1 & src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_bitwise_and_with_mask_C1_D6 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char8 src_data1 = *((__global char8 *)((__global char *)src1 + src1_index));
+        char8 src_data2 = *((__global char8 *)((__global char *)src2 + src2_index));
+        char8 dst_data  = *((__global char8 *)((__global char *)dst  + dst_index));
+
+        char8 data = src_data1 & src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char8 *)((__global char *)dst + dst_index)) = data;
+    }
+
+}
+#endif
+
+
+
+__kernel void arithm_bitwise_and_with_mask_C2_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                          __global uchar *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global uchar *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = src1_data & src2_data;
+
+        data.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.xy : data.xy;
+        data.zw = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.zw : data.zw;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_bitwise_and_with_mask_C2_D1 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+        char4 src2_data = vload4(0, src2 + src2_index);
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        char4 data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = src1_data & src2_data;
+
+        data.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.xy : data.xy;
+        data.zw = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.zw : data.zw;
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_bitwise_and_with_mask_C2_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                                          __global ushort *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global ushort *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        ushort2 src_data1 = *((__global ushort2 *)((__global char *)src1 + src1_index));
+        ushort2 src_data2 = *((__global ushort2 *)((__global char *)src2 + src2_index));
+        ushort2 dst_data  = *((__global ushort2 *)((__global char *)dst  + dst_index));
+
+        ushort2 data = src_data1 & src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global ushort2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_bitwise_and_with_mask_C2_D3 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short2 src_data1 = *((__global short2 *)((__global char *)src1 + src1_index));
+        short2 src_data2 = *((__global short2 *)((__global char *)src2 + src2_index));
+        short2 dst_data  = *((__global short2 *)((__global char *)dst  + dst_index));
+
+        short2 data = src_data1 & src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global short2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_bitwise_and_with_mask_C2_D4 (__global int   *src1, int src1_step, int src1_offset,
+                                          __global int   *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global int    *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int2 src_data1 = *((__global int2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = *((__global int2 *)((__global char *)src2 + src2_index));
+        int2 dst_data  = *((__global int2 *)((__global char *)dst  + dst_index));
+
+        int2 data = src_data1 & src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global int2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_bitwise_and_with_mask_C2_D5 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char8 src_data1 = *((__global char8 *)((__global char *)src1 + src1_index));
+        char8 src_data2 = *((__global char8 *)((__global char *)src2 + src2_index));
+        char8 dst_data  = *((__global char8 *)((__global char *)dst  + dst_index));
+
+        char8 data = src_data1 & src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char8 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_bitwise_and_with_mask_C2_D6 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 4) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char16 src_data1 = *((__global char16 *)((__global char *)src1 + src1_index));
+        char16 src_data2 = *((__global char16 *)((__global char *)src2 + src2_index));
+        char16 dst_data  = *((__global char16 *)((__global char *)dst  + dst_index));
+
+        char16 data = src_data1 & src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char16 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+
+
+
+__kernel void arithm_bitwise_and_with_mask_C3_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                          __global uchar *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global uchar *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+        int src2_index = mad24(y, src2_step, (x * 3) + src2_offset - (dst_align * 3)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        uchar4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        uchar4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        uchar4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        uchar4 src2_data_0 = vload4(0, src2 + src2_index + 0);
+        uchar4 src2_data_1 = vload4(0, src2 + src2_index + 4);
+        uchar4 src2_data_2 = vload4(0, src2 + src2_index + 8);
+
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        uchar4 data_0 = *((__global uchar4 *)(dst + dst_index + 0));
+        uchar4 data_1 = *((__global uchar4 *)(dst + dst_index + 4));
+        uchar4 data_2 = *((__global uchar4 *)(dst + dst_index + 8));
+
+        uchar4 tmp_data_0 =  src1_data_0 & src2_data_0;
+        uchar4 tmp_data_1 =  src1_data_1 & src2_data_1;
+        uchar4 tmp_data_2 =  src1_data_2 & src2_data_2;
+
+        data_0.xyz = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((mask_data.w) && (dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global uchar4 *)(dst + dst_index + 0)) = data_0;
+        *((__global uchar4 *)(dst + dst_index + 4)) = data_1;
+        *((__global uchar4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+
+
+__kernel void arithm_bitwise_and_with_mask_C3_D1 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+        int src2_index = mad24(y, src2_step, (x * 3) + src2_offset - (dst_align * 3)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        char4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        char4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        char4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        char4 src2_data_0 = vload4(0, src2 + src2_index + 0);
+        char4 src2_data_1 = vload4(0, src2 + src2_index + 4);
+        char4 src2_data_2 = vload4(0, src2 + src2_index + 8);
+
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        char4 data_0 = *((__global char4 *)(dst + dst_index + 0));
+        char4 data_1 = *((__global char4 *)(dst + dst_index + 4));
+        char4 data_2 = *((__global char4 *)(dst + dst_index + 8));
+
+        char4 tmp_data_0 =  src1_data_0 & src2_data_0;
+        char4 tmp_data_1 =  src1_data_1 & src2_data_1;
+        char4 tmp_data_2 =  src1_data_2 & src2_data_2;
+
+        data_0.xyz = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((mask_data.w) && (dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global char4 *)(dst + dst_index + 0)) = data_0;
+        *((__global char4 *)(dst + dst_index + 4)) = data_1;
+        *((__global char4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+
+__kernel void arithm_bitwise_and_with_mask_C3_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                                          __global ushort *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global ushort *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+        int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        ushort2 src1_data_0 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 0));
+        ushort2 src1_data_1 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 4));
+        ushort2 src1_data_2 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 8));
+
+        ushort2 src2_data_0 = vload2(0, (__global ushort *)((__global char *)src2 + src2_index + 0));
+        ushort2 src2_data_1 = vload2(0, (__global ushort *)((__global char *)src2 + src2_index + 4));
+        ushort2 src2_data_2 = vload2(0, (__global ushort *)((__global char *)src2 + src2_index + 8));
+
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        ushort2 data_0 = *((__global ushort2 *)((__global char *)dst + dst_index + 0));
+        ushort2 data_1 = *((__global ushort2 *)((__global char *)dst + dst_index + 4));
+        ushort2 data_2 = *((__global ushort2 *)((__global char *)dst + dst_index + 8));
+
+        ushort2 tmp_data_0 =  src1_data_0 & src2_data_0 ;
+        ushort2 tmp_data_1 =  src1_data_1 & src2_data_1 ;
+        ushort2 tmp_data_2 =  src1_data_2 & src2_data_2 ;
+
+        data_0.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global ushort2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_bitwise_and_with_mask_C3_D3 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+        int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        short2 src1_data_0 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 0));
+        short2 src1_data_1 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 4));
+        short2 src1_data_2 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 8));
+
+        short2 src2_data_0 = vload2(0, (__global short *)((__global char *)src2 + src2_index + 0));
+        short2 src2_data_1 = vload2(0, (__global short *)((__global char *)src2 + src2_index + 4));
+        short2 src2_data_2 = vload2(0, (__global short *)((__global char *)src2 + src2_index + 8));
+
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        short2 data_0 = *((__global short2 *)((__global char *)dst + dst_index + 0));
+        short2 data_1 = *((__global short2 *)((__global char *)dst + dst_index + 4));
+        short2 data_2 = *((__global short2 *)((__global char *)dst + dst_index + 8));
+
+        short2 tmp_data_0 =  src1_data_0 & src2_data_0 ;
+        short2 tmp_data_1 =  src1_data_1 & src2_data_1 ;
+        short2 tmp_data_2 =  src1_data_2 & src2_data_2 ;
+
+        data_0.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global short2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global short2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global short2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_bitwise_and_with_mask_C3_D4 (__global int   *src1, int src1_step, int src1_offset,
+                                          __global int   *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global int   *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int src2_index = mad24(y, src2_step, (x * 12) + src2_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        int src1_data_0 = *((__global int *)((__global char *)src1 + src1_index + 0));
+        int src1_data_1 = *((__global int *)((__global char *)src1 + src1_index + 4));
+        int src1_data_2 = *((__global int *)((__global char *)src1 + src1_index + 8));
+
+        int src2_data_0 = *((__global int *)((__global char *)src2 + src2_index + 0));
+        int src2_data_1 = *((__global int *)((__global char *)src2 + src2_index + 4));
+        int src2_data_2 = *((__global int *)((__global char *)src2 + src2_index + 8));
+
+        uchar mask_data = * (mask + mask_index);
+
+        int data_0 = *((__global int *)((__global char *)dst + dst_index + 0));
+        int data_1 = *((__global int *)((__global char *)dst + dst_index + 4));
+        int data_2 = *((__global int *)((__global char *)dst + dst_index + 8));
+
+        int tmp_data_0 =  src1_data_0 &  src2_data_0 ;
+        int tmp_data_1 =  src1_data_1 &  src2_data_1 ;
+        int tmp_data_2 =  src1_data_2 &  src2_data_2 ;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global int *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global int *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global int *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_bitwise_and_with_mask_C3_D5 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int src2_index = mad24(y, src2_step, (x * 12) + src2_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        char4 src1_data_0 = *((__global char4 *)((__global char *)src1 + src1_index + 0));
+        char4 src1_data_1 = *((__global char4 *)((__global char *)src1 + src1_index + 4));
+        char4 src1_data_2 = *((__global char4 *)((__global char *)src1 + src1_index + 8));
+                                             
+        char4 src2_data_0 = *((__global char4 *)((__global char *)src2 + src2_index + 0));
+        char4 src2_data_1 = *((__global char4 *)((__global char *)src2 + src2_index + 4));
+        char4 src2_data_2 = *((__global char4 *)((__global char *)src2 + src2_index + 8));
+
+        uchar mask_data = * (mask + mask_index);
+
+        char4 data_0 = *((__global char4 *)((__global char *)dst + dst_index + 0));
+        char4 data_1 = *((__global char4 *)((__global char *)dst + dst_index + 4));
+        char4 data_2 = *((__global char4 *)((__global char *)dst + dst_index + 8));
+
+        char4 tmp_data_0 = src1_data_0 & src2_data_0;
+        char4 tmp_data_1 = src1_data_1 & src2_data_1;
+        char4 tmp_data_2 = src1_data_2 & src2_data_2;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global char4 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global char4 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global char4 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_bitwise_and_with_mask_C3_D6 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 24) + src1_offset); 
+        int src2_index = mad24(y, src2_step, (x * 24) + src2_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 24));
+
+        char8 src1_data_0 = *((__global char8 *)((__global char *)src1 + src1_index + 0 ));
+        char8 src1_data_1 = *((__global char8 *)((__global char *)src1 + src1_index + 8 ));
+        char8 src1_data_2 = *((__global char8 *)((__global char *)src1 + src1_index + 16));
+                                               
+        char8 src2_data_0 = *((__global char8 *)((__global char *)src2 + src2_index + 0 ));
+        char8 src2_data_1 = *((__global char8 *)((__global char *)src2 + src2_index + 8 ));
+        char8 src2_data_2 = *((__global char8 *)((__global char *)src2 + src2_index + 16));
+
+        uchar mask_data = * (mask + mask_index);
+
+        char8 data_0 = *((__global char8 *)((__global char *)dst + dst_index + 0 ));
+        char8 data_1 = *((__global char8 *)((__global char *)dst + dst_index + 8 ));
+        char8 data_2 = *((__global char8 *)((__global char *)dst + dst_index + 16));
+
+        char8 tmp_data_0 = src1_data_0 & src2_data_0;
+        char8 tmp_data_1 = src1_data_1 & src2_data_1;
+        char8 tmp_data_2 = src1_data_2 & src2_data_2;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global char8 *)((__global char *)dst + dst_index + 0 ))= data_0;
+       *((__global char8 *)((__global char *)dst + dst_index + 8 ))= data_1;
+       *((__global char8 *)((__global char *)dst + dst_index + 16))= data_2;
+    }
+}
+#endif
+
+
+
+__kernel void arithm_bitwise_and_with_mask_C4_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                          __global uchar *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global uchar *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        uchar4 src_data1 = *((__global uchar4 *)(src1 + src1_index));
+        uchar4 src_data2 = *((__global uchar4 *)(src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+
+        uchar4 data = src_data1 & src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_bitwise_and_with_mask_C4_D1 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char4 src_data1 = *((__global char4 *)(src1 + src1_index));
+        char4 src_data2 = *((__global char4 *)(src2 + src2_index));
+        char4 dst_data  = *((__global char4 *)(dst  + dst_index));
+
+        char4 data = src_data1 & src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_bitwise_and_with_mask_C4_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                                          __global ushort *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global ushort *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        ushort4 src_data1 = *((__global ushort4 *)((__global char *)src1 + src1_index));
+        ushort4 src_data2 = *((__global ushort4 *)((__global char *)src2 + src2_index));
+        ushort4 dst_data  = *((__global ushort4 *)((__global char *)dst  + dst_index));
+
+        ushort4 data = src_data1 & src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_bitwise_and_with_mask_C4_D3 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short4 src_data1 = *((__global short4 *)((__global char *)src1 + src1_index));
+        short4 src_data2 = *((__global short4 *)((__global char *)src2 + src2_index));
+        short4 dst_data  = *((__global short4 *)((__global char *)dst  + dst_index));
+
+        short4 data = src_data1 & src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_bitwise_and_with_mask_C4_D4 (__global int   *src1, int src1_step, int src1_offset,
+                                          __global int   *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global int   *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 4) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int4 src_data1 = *((__global int4 *)((__global char *)src1 + src1_index));
+        int4 src_data2 = *((__global int4 *)((__global char *)src2 + src2_index));
+        int4 dst_data  = *((__global int4 *)((__global char *)dst  + dst_index));
+
+        int4 data = src_data1 & src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global int4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_bitwise_and_with_mask_C4_D5 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 4) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char16 src_data1 = *((__global char16 *)((__global char *)src1 + src1_index));
+        char16 src_data2 = *((__global char16 *)((__global char *)src2 + src2_index));
+        char16 dst_data  = *((__global char16 *)((__global char *)dst  + dst_index));
+
+        char16 data = src_data1 & src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char16 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_bitwise_and_with_mask_C4_D6 (__global char *src1, int src1_step, int src1_offset,
+                                                  __global char *src2, int src2_step, int src2_offset,
+                                                  __global uchar  *mask, int mask_step, int mask_offset,
+                                                  __global char *dst,  int dst_step,  int dst_offset,
+                                                  int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 5) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 5) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 5) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char8 src_data1_0 = *((__global char8 *)((__global char *)src1 + src1_index + 0));
+        char8 src_data1_1 = *((__global char8 *)((__global char *)src1 + src1_index + 8));
+        char8 src_data1_2 = *((__global char8 *)((__global char *)src1 + src1_index + 16));
+        char8 src_data1_3 = *((__global char8 *)((__global char *)src1 + src1_index + 24));
+
+        char8 src_data2_0 = *((__global char8 *)((__global char *)src2 + src2_index + 0));
+        char8 src_data2_1 = *((__global char8 *)((__global char *)src2 + src2_index + 8));
+        char8 src_data2_2 = *((__global char8 *)((__global char *)src2 + src2_index + 16));
+        char8 src_data2_3 = *((__global char8 *)((__global char *)src2 + src2_index + 24));
+
+        char8 dst_data_0  = *((__global char8 *)((__global char *)dst  + dst_index + 0));
+        char8 dst_data_1  = *((__global char8 *)((__global char *)dst  + dst_index + 8));
+        char8 dst_data_2  = *((__global char8 *)((__global char *)dst  + dst_index + 16));
+        char8 dst_data_3  = *((__global char8 *)((__global char *)dst  + dst_index + 24));
+
+        char8 data_0 = src_data1_0 & src_data2_0;
+        char8 data_1 = src_data1_1 & src_data2_1;
+        char8 data_2 = src_data1_2 & src_data2_2;
+        char8 data_3 = src_data1_3 & src_data2_3;
+
+        data_0 = mask_data ? data_0 : dst_data_0; 
+        data_1 = mask_data ? data_1 : dst_data_1; 
+        data_2 = mask_data ? data_2 : dst_data_2; 
+        data_3 = mask_data ? data_3 : dst_data_3; 
+
+        *((__global char8 *)((__global char *)dst + dst_index + 0)) = data_0;
+        *((__global char8 *)((__global char *)dst + dst_index + 8)) = data_1;
+        *((__global char8 *)((__global char *)dst + dst_index + 16)) = data_2;
+        *((__global char8 *)((__global char *)dst + dst_index + 24)) = data_3;
+    }
+}
+#endif
+
diff --git a/modules/ocl/src/kernels/arithm_bitwise_and_scalar.cl b/modules/ocl/src/kernels/arithm_bitwise_and_scalar.cl
new file mode 100644 (file)
index 0000000..dc47003
--- /dev/null
@@ -0,0 +1,907 @@
+////////////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jiang Liyuan, jlyuan001.good@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.
+//
+//
+#if defined (__ATI__)
+#pragma OPENCL EXTENSION cl_amd_fp64:enable
+#elif defined (__NVIDIA__)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////BITWISE_AND////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+/**************************************and with scalar without mask**************************************/
+__kernel void arithm_s_bitwise_and_C1_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                  __global   uchar *dst,  int dst_step,  int dst_offset,
+                                  uchar4 src2, int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = (uchar4)(src2.x, src2.x, src2.x, src2.x);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = src1_data & src2_data;
+
+        data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_and_C1_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char4 src2, int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+        char4 src2_data = (char4)(src2.x, src2.x, src2.x, src2.x);
+
+        char4 data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = src1_data & src2_data;
+
+        data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_bitwise_and_C1_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                  __global   ushort *dst,  int dst_step,  int dst_offset,
+                                  ushort4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        ushort2 src1_data = vload2(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort2 src2_data = (ushort2)(src2.x, src2.x);
+
+        ushort2 data = *((__global ushort2 *)((__global uchar *)dst + dst_index));
+        ushort2 tmp_data = src1_data & src2_data;
+
+        data.x = (dst_index + 0 >= dst_start) ? tmp_data.x : data.x;
+        data.y = (dst_index + 2 <  dst_end  ) ? tmp_data.y : data.y;
+
+        *((__global ushort2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_and_C1_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                  __global   short *dst,  int dst_step,  int dst_offset,
+                                  short4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        short2 src1_data = vload2(0, (__global short *)((__global char *)src1 + src1_index));
+        short2 src2_data = (short2)(src2.x, src2.x);
+        short2 data = *((__global short2 *)((__global uchar *)dst + dst_index));
+
+        short2 tmp_data = src1_data & src2_data;
+
+        data.x = (dst_index + 0 >= dst_start) ? tmp_data.x : data.x;
+        data.y = (dst_index + 2 <  dst_end  ) ? tmp_data.y : data.y;
+
+        *((__global short2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_and_C1_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                  __global   int *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        int src_data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int src_data2 = src2.x;
+
+        int data = src_data1 & src_data2;
+
+        *((__global int *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_and_C1_D5 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        char4 src1_data = *((__global char4 *)((__global char *)src1 + src1_index));
+        char4 src2_data = (char4)(src2.s0, src2.s1, src2.s2, src2.s3);
+
+        char4 data  = *((__global char4 *)((__global char *)dst  + dst_index));
+        char4 tmp_data = src1_data & src2_data;
+
+        data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global char4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_and_C1_D6 (__global short *src1, int src1_step, int src1_offset,
+                                  __global short *dst,  int dst_step,  int dst_offset,
+                                  short16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        short4 src1_data = *((__global short4 *)((__global char *)src1 + src1_index));
+        short4 src2_data = (short4)(src2.s0, src2.s1, src2.s2, src2.s3);
+        
+        short4 tmp_data = src1_data & src2_data;
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = tmp_data;
+    }
+}
+#endif
+__kernel void arithm_s_bitwise_and_C2_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                  __global   uchar *dst,  int dst_step,  int dst_offset,
+                                  uchar4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = (uchar4)(src2.x, src2.y, src2.x, src2.y);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = src1_data & src2_data;
+        
+
+        data.xy = (dst_index + 0 >= dst_start) ? tmp_data.xy : data.xy;
+        data.zw = (dst_index + 2 <  dst_end  ) ? tmp_data.zw : data.zw;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_and_C2_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+        char4 src2_data = (char4)(src2.x, src2.y, src2.x, src2.y);
+        
+        char4 data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = src1_data & src2_data;
+        
+        data.xy = (dst_index + 0 >= dst_start) ? tmp_data.xy : data.xy;
+        data.zw = (dst_index + 2 <  dst_end  ) ? tmp_data.zw : data.zw;
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_bitwise_and_C2_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                  __global   ushort *dst,  int dst_step,  int dst_offset,
+                                  ushort4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        ushort2 src_data1 = *((__global ushort2 *)((__global char *)src1 + src1_index));
+        ushort2 src_data2 = (ushort2)(src2.x, src2.y);
+
+        ushort2 data = src_data1 & src_data2;
+        
+        *((__global ushort2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_and_C2_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                  __global   short *dst,  int dst_step,  int dst_offset,
+                                  short4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        short2 src_data1 = *((__global short2 *)((__global char *)src1 + src1_index));
+        short2 src_data2 = (short2)(src2.x, src2.y);
+
+        short2 data = src_data1 & src_data2;
+        
+        *((__global short2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_and_C2_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                  __global   int *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        int2 src_data1 = *((__global int2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = (int2)(src2.x, src2.y);
+
+        int2 data = src_data1 & src_data2;
+        *((__global int2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_and_C2_D5 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        char8 src1_data = *((__global char8 *)((__global char *)src1 + src1_index));
+        char8 src2_data = (char8)(src2.s0, src2.s1, src2.s2, src2.s3, src2.s4, src2.s5, src2.s6, src2.s7);
+
+        char8 tmp_data = src1_data & src2_data;
+        
+        *((__global char8 *)((__global char *)dst + dst_index)) = tmp_data;
+      }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_and_C2_D6 (__global short *src1, int src1_step, int src1_offset,
+                                  __global short *dst,  int dst_step,  int dst_offset,
+                                  short16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        short8 src1_data = *((__global short8 *)((__global char *)src1 + src1_index));
+        short8 src2_data = (short8)(src2.s0, src2.s1, src2.s2, src2.s3, src2.s4, src2.s5, src2.s6, src2.s7);
+
+        short8 tmp_data = src1_data & src2_data;
+        
+        *((__global short8 *)((__global char *)dst + dst_index)) = tmp_data;
+    }
+}
+#endif
+__kernel void arithm_s_bitwise_and_C3_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                  __global   uchar *dst,  int dst_step,  int dst_offset,
+                                  uchar4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        uchar4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        uchar4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        uchar4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        uchar4 src2_data_0 = (uchar4)(src2.x, src2.y, src2.z, src2.x); 
+        uchar4 src2_data_1 = (uchar4)(src2.y, src2.z, src2.x, src2.y);
+        uchar4 src2_data_2 = (uchar4)(src2.z, src2.x, src2.y, src2.z); 
+
+        uchar4 data_0 = *((__global uchar4 *)(dst + dst_index + 0));
+        uchar4 data_1 = *((__global uchar4 *)(dst + dst_index + 4));
+        uchar4 data_2 = *((__global uchar4 *)(dst + dst_index + 8));
+
+        uchar4 tmp_data_0 = src1_data_0 & src2_data_0;
+        uchar4 tmp_data_1 = src1_data_1 & src2_data_1;
+        uchar4 tmp_data_2 = src1_data_2 & src2_data_2;
+        
+        data_0.xyz = ((dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global uchar4 *)(dst + dst_index + 0)) = data_0;
+        *((__global uchar4 *)(dst + dst_index + 4)) = data_1;
+        *((__global uchar4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_and_C3_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        char4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        char4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        char4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        char4 src2_data_0 = (char4)(src2.x, src2.y, src2.z, src2.x); 
+        char4 src2_data_1 = (char4)(src2.y, src2.z, src2.x, src2.y);
+        char4 src2_data_2 = (char4)(src2.z, src2.x, src2.y, src2.z); 
+
+        char4 data_0 = *((__global char4 *)(dst + dst_index + 0));
+        char4 data_1 = *((__global char4 *)(dst + dst_index + 4));
+        char4 data_2 = *((__global char4 *)(dst + dst_index + 8));
+
+        char4 tmp_data_0 = convert_char4_sat(convert_uchar4_sat(src1_data_0) & convert_uchar4_sat(src2_data_0));
+        char4 tmp_data_1 = convert_char4_sat(convert_uchar4_sat(src1_data_1) & convert_uchar4_sat(src2_data_1));
+        char4 tmp_data_2 = convert_char4_sat(convert_uchar4_sat(src1_data_2) & convert_uchar4_sat(src2_data_2));
+
+        data_0.xyz = ((dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global char4 *)(dst + dst_index + 0)) = data_0;
+        *((__global char4 *)(dst + dst_index + 4)) = data_1;
+        *((__global char4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+
+__kernel void arithm_s_bitwise_and_C3_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                  __global   ushort *dst,  int dst_step,  int dst_offset,
+                                  ushort4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        ushort2 src1_data_0 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 0));
+        ushort2 src1_data_1 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 4));
+        ushort2 src1_data_2 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 8));
+
+        ushort2 src2_data_0 = (ushort2)(src2.x, src2.y);
+        ushort2 src2_data_1 = (ushort2)(src2.z, src2.x);
+        ushort2 src2_data_2 = (ushort2)(src2.y, src2.z);
+
+        ushort2 data_0 = *((__global ushort2 *)((__global char *)dst + dst_index + 0));
+        ushort2 data_1 = *((__global ushort2 *)((__global char *)dst + dst_index + 4));
+        ushort2 data_2 = *((__global ushort2 *)((__global char *)dst + dst_index + 8));
+
+        ushort2 tmp_data_0 = src1_data_0 & src2_data_0;
+        ushort2 tmp_data_1 = src1_data_1 & src2_data_1;
+        ushort2 tmp_data_2 = src1_data_2 & src2_data_2;
+
+        data_0.xy = ((dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global ushort2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_bitwise_and_C3_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                  __global   short *dst,  int dst_step,  int dst_offset,
+                                  short4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        short2 src1_data_0 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 0));
+        short2 src1_data_1 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 4));
+        short2 src1_data_2 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 8));
+
+        short2 src2_data_0 = (short2)(src2.x, src2.y);
+        short2 src2_data_1 = (short2)(src2.z, src2.x);
+        short2 src2_data_2 = (short2)(src2.y, src2.z);
+
+        short2 data_0 = *((__global short2 *)((__global char *)dst + dst_index + 0));
+        short2 data_1 = *((__global short2 *)((__global char *)dst + dst_index + 4));
+        short2 data_2 = *((__global short2 *)((__global char *)dst + dst_index + 8));
+
+        short2 tmp_data_0 = src1_data_0 & src2_data_0;
+        short2 tmp_data_1 = src1_data_1 & src2_data_1;
+        short2 tmp_data_2 = src1_data_2 & src2_data_2;
+
+        data_0.xy = ((dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global short2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global short2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global short2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_bitwise_and_C3_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                  __global   int *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        int src1_data_0 = *((__global int *)((__global char *)src1 + src1_index + 0));
+        int src1_data_1 = *((__global int *)((__global char *)src1 + src1_index + 4));
+        int src1_data_2 = *((__global int *)((__global char *)src1 + src1_index + 8));
+
+        int src2_data_0 = src2.x;
+        int src2_data_1 = src2.y;
+        int src2_data_2 = src2.z;
+
+        int data_0 = *((__global int *)((__global char *)dst + dst_index + 0));
+        int data_1 = *((__global int *)((__global char *)dst + dst_index + 4));
+        int data_2 = *((__global int *)((__global char *)dst + dst_index + 8));
+
+        int tmp_data_0 = src1_data_0 & src2_data_0;
+        int tmp_data_1 = src1_data_1 & src2_data_1;
+        int tmp_data_2 = src1_data_2 & src2_data_2;
+
+       *((__global int *)((__global char *)dst + dst_index + 0))= tmp_data_0;
+       *((__global int *)((__global char *)dst + dst_index + 4))= tmp_data_1;
+       *((__global int *)((__global char *)dst + dst_index + 8))= tmp_data_2;
+    }
+}
+__kernel void arithm_s_bitwise_and_C3_D5 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        char4 src1_data_0 = *((__global char4 *)((__global char *)src1 + src1_index + 0));
+        char4 src1_data_1 = *((__global char4 *)((__global char *)src1 + src1_index + 4));
+        char4 src1_data_2 = *((__global char4 *)((__global char *)src1 + src1_index + 8));
+                                             
+        char4 src2_data_0 = (char4)(src2.s0, src2.s1, src2.s2, src2.s3); 
+        char4 src2_data_1 = (char4)(src2.s4, src2.s5, src2.s6, src2.s7);
+        char4 src2_data_2 = (char4)(src2.s8, src2.s9, src2.sA, src2.sB); 
+
+        char4 data_0 = *((__global char4 *)((__global char *)dst + dst_index + 0));
+        char4 data_1 = *((__global char4 *)((__global char *)dst + dst_index + 4));
+        char4 data_2 = *((__global char4 *)((__global char *)dst + dst_index + 8));
+
+        char4 tmp_data_0 = src1_data_0 & src2_data_0;
+        char4 tmp_data_1 = src1_data_1 & src2_data_1;
+        char4 tmp_data_2 = src1_data_2 & src2_data_2;
+
+       *((__global char4 *)((__global char *)dst + dst_index + 0))= tmp_data_0;
+       *((__global char4 *)((__global char *)dst + dst_index + 4))= tmp_data_1;
+       *((__global char4 *)((__global char *)dst + dst_index + 8))= tmp_data_2;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_and_C3_D6 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          short16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 24) + src1_offset); 
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 24));
+
+        short4 src1_data_0 = *((__global short4 *)((__global char *)src1 + src1_index + 0 ));
+        short4 src1_data_1 = *((__global short4 *)((__global char *)src1 + src1_index + 8 ));
+        short4 src1_data_2 = *((__global short4 *)((__global char *)src1 + src1_index + 16));
+                                               
+        short4 src2_data_0 = (short4)(src2.s0, src2.s1, src2.s2, src2.s3);
+        short4 src2_data_1 = (short4)(src2.s4, src2.s5, src2.s6, src2.s7);
+        short4 src2_data_2 = (short4)(src2.s8, src2.s9, src2.sa, src2.sb);
+
+        short4 data_0 = *((__global short4 *)((__global char *)dst + dst_index + 0 ));
+        short4 data_1 = *((__global short4 *)((__global char *)dst + dst_index + 8 ));
+        short4 data_2 = *((__global short4 *)((__global char *)dst + dst_index + 16));
+
+        short4 tmp_data_0 = src1_data_0 & src2_data_0;
+        short4 tmp_data_1 = src1_data_1 & src2_data_1;
+        short4 tmp_data_2 = src1_data_2 & src2_data_2;
+        
+       *((__global short4 *)((__global char *)dst + dst_index + 0 ))= tmp_data_0;
+       *((__global short4 *)((__global char *)dst + dst_index + 8 ))= tmp_data_1;
+       *((__global short4 *)((__global char *)dst + dst_index + 16))= tmp_data_2;
+    }
+}
+#endif
+__kernel void arithm_s_bitwise_and_C4_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                  __global   uchar *dst,  int dst_step,  int dst_offset,
+                                  uchar4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar4 src_data1 = *((__global uchar4 *)(src1 + src1_index));
+
+        uchar4 data = src_data1 & src2;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_and_C4_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        char4 src_data1 = *((__global char4 *)(src1 + src1_index));
+
+        char4 data = src_data1 & src2;
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_bitwise_and_C4_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                  __global   ushort *dst,  int dst_step,  int dst_offset,
+                                  ushort4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        ushort4 src_data1 = *((__global ushort4 *)((__global char *)src1 + src1_index));
+
+        ushort4 data = src_data1 & src2;
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_and_C4_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                  __global   short *dst,  int dst_step,  int dst_offset,
+                                  short4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        short4 src_data1 = *((__global short4 *)((__global char *)src1 + src1_index));
+
+        short4 data = src_data1 & src2;
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_and_C4_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                  __global   int *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        int4 src_data1 = *((__global int4 *)((__global char *)src1 + src1_index));
+
+        int4 data = src_data1 & src2;
+
+        *((__global int4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_and_C4_D5 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        char16 src1_data = *((__global char16 *)((__global char *)src1 + src1_index));
+        char16 src2_data = (char16)(src2.s0, src2.s1, src2.s2, src2.s3, src2.s4, src2.s5, src2.s6, src2.s7,
+                                    src2.s8, src2.s9, src2.sa, src2.sb, src2.sc, src2.sd, src2.se, src2.sf);
+
+        char16 tmp_data = src1_data & src2_data;
+        
+        *((__global char16 *)((__global char *)dst + dst_index)) = tmp_data;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_and_C4_D6 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          short16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 5) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 5) + dst_offset);
+
+        short4 src1_data_0 = *((__global short4 *)((__global char *)src1 + src1_index + 0));
+        short4 src1_data_1 = *((__global short4 *)((__global char *)src1 + src1_index + 8));
+        short4 src1_data_2 = *((__global short4 *)((__global char *)src1 + src1_index + 16));
+        short4 src1_data_3 = *((__global short4 *)((__global char *)src1 + src1_index + 24));
+
+        short4 src2_data_0 = (short4)(src2.s0, src2.s1, src2.s2, src2.s3);
+        short4 src2_data_1 = (short4)(src2.s4, src2.s5, src2.s6, src2.s7);
+        short4 src2_data_2 = (short4)(src2.s8, src2.s9, src2.sa, src2.sb);
+        short4 src2_data_3 = (short4)(src2.sc, src2.sd, src2.se, src2.sf);
+        
+        short4 tmp_data_0 = src1_data_0 & src2_data_0;
+        short4 tmp_data_1 = src1_data_1 & src2_data_1;
+        short4 tmp_data_2 = src1_data_2 & src2_data_2;
+        short4 tmp_data_3 = src1_data_3 & src2_data_3;
+        
+       *((__global short4 *)((__global char *)dst + dst_index + 0 ))= tmp_data_0;
+       *((__global short4 *)((__global char *)dst + dst_index + 8 ))= tmp_data_1;
+       *((__global short4 *)((__global char *)dst + dst_index + 16))= tmp_data_2;
+       *((__global short4 *)((__global char *)dst + dst_index + 24))= tmp_data_3;
+       
+    }
+}
+#endif
diff --git a/modules/ocl/src/kernels/arithm_bitwise_and_scalar_mask.cl b/modules/ocl/src/kernels/arithm_bitwise_and_scalar_mask.cl
new file mode 100644 (file)
index 0000000..8064636
--- /dev/null
@@ -0,0 +1,1058 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jiang Liyuan, jlyuan001.good@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 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
+// 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*/
+#if defined (__ATI__)
+#pragma OPENCL EXTENSION cl_amd_fp64:enable
+#elif defined (__NVIDIA__)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////BITWISE_AND////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+/**************************************bitwise_and with scalar with mask**************************************/
+__kernel void arithm_s_bitwise_and_with_mask_C1_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                            __global   uchar *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            uchar4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = (uchar4)(src2.x, src2.x, src2.x, src2.x);
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = src1_data & src2_data;
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((mask_data.z) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((mask_data.w) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_and_with_mask_C1_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                            __global   char *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            char4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+        char4 src2_data = (char4)(src2.x, src2.x, src2.x, src2.x);
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        char4 data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = src1_data & src2_data;
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((mask_data.z) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((mask_data.w) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_bitwise_and_with_mask_C1_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                            __global   ushort *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar  *mask, int mask_step, int mask_offset,
+                                            ushort4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        ushort2 src1_data = vload2(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort2 src2_data = (ushort2)(src2.x, src2.x);
+        uchar2  mask_data = vload2(0, mask + mask_index);
+
+        ushort2 data = *((__global ushort2 *)((__global uchar *)dst + dst_index));
+        ushort2 tmp_data = src1_data & src2_data;
+        
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.y : data.y;
+
+        *((__global ushort2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_and_with_mask_C1_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                            __global   short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            short4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        short2 src1_data = vload2(0, (__global short *)((__global char *)src1 + src1_index));
+        short2 src2_data = (short2)(src2.x, src2.x);
+        uchar2  mask_data = vload2(0, mask + mask_index);
+
+        short2 data = *((__global short2 *)((__global uchar *)dst + dst_index));
+        short2 tmp_data = src1_data & src2_data;
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.y : data.y;
+
+        *((__global short2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_and_with_mask_C1_D4 (__global   int   *src1, int src1_step, int src1_offset,
+                                            __global   int   *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int src_data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int src_data2 = src2.x;
+        int dst_data  = *((__global int *)((__global char *)dst  + dst_index));
+
+        int data = src_data1 & src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global int *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_bitwise_and_with_mask_C1_D5 (__global char *src1, int src1_step, int src1_offset,
+                                                    __global char *dst,  int dst_step,  int dst_offset,
+                                                    __global   uchar *mask, int mask_step, int mask_offset,
+                                                    char16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char4 src1_data = *((__global char4 *)((__global char *)src1 + src1_index));
+        char4 src2_data = (char4)(src2.s0, src2.s1, src2.s2, src2.s3);
+        char4 dst_data  = *((__global char4 *)((__global char *)dst  + dst_index));
+
+        char4 data = src1_data & src2_data;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_and_with_mask_C1_D6 (__global short *src1, int src1_step, int src1_offset,
+                                            __global short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            short16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short4 src1_data = *((__global short4 *)((__global char *)src1 + src1_index));
+        short4 src2_data = (short4)(src2.s0, src2.s1, src2.s2, src2.s3);
+        short4 dst_data  = *((__global short4 *)((__global char *)dst  + dst_index));
+
+        short4 data = src1_data & src2_data;
+        data = mask_data ? data : dst_data; 
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+__kernel void arithm_s_bitwise_and_with_mask_C2_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                            __global   uchar *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            uchar4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = (uchar4)(src2.x, src2.y, src2.x, src2.y);
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = src1_data & src2_data;
+
+        data.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.xy : data.xy;
+        data.zw = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.zw : data.zw;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_and_with_mask_C2_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                            __global   char *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            char4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+        char4 src2_data = (char4)(src2.x, src2.y, src2.x, src2.y);
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        char4 data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = src1_data & src2_data;
+
+        data.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.xy : data.xy;
+        data.zw = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.zw : data.zw;
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_bitwise_and_with_mask_C2_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                            __global   ushort *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            ushort4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        ushort2 src_data1 = *((__global ushort2 *)((__global char *)src1 + src1_index));
+        ushort2 src_data2 = (ushort2)(src2.x, src2.y);
+        ushort2 dst_data  = *((__global ushort2 *)((__global char *)dst  + dst_index));
+
+        ushort2 data = src_data1 & src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global ushort2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_and_with_mask_C2_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                            __global   short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            short4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short2 src_data1 = *((__global short2 *)((__global char *)src1 + src1_index));
+        short2 src_data2 = (short2)(src2.x, src2.y);
+        short2 dst_data  = *((__global short2 *)((__global char *)dst  + dst_index));
+
+        short2 data = src_data1 & src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global short2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_and_with_mask_C2_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                            __global   int *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int2 src_data1 = *((__global int2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = (int2)(src2.x, src2.y);
+        int2 dst_data  = *((__global int2 *)((__global char *)dst  + dst_index));
+
+        int2 data = src_data1 & src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global int2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_and_with_mask_C2_D5 (__global   char *src1, int src1_step, int src1_offset,
+                                            __global  char *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            char16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char8 src1_data = *((__global char8 *)((__global char *)src1 + src1_index));
+        char8 src2_data = (char8)(src2.s0, src2.s1, src2.s2, src2.s3, src2.s4, src2.s5, src2.s6, src2.s7);
+        char8 dst_data = *((__global char8 *)((__global char *)dst  + dst_index));
+
+        char8 data = src1_data & src2_data;
+        
+        data = mask_data ? data : dst_data;
+
+        *((__global char8 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_and_with_mask_C2_D6 (__global short *src1, int src1_step, int src1_offset,
+                                                    __global short *dst,  int dst_step,  int dst_offset,
+                                                    __global uchar *mask, int mask_step, int mask_offset,
+                                                    short16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short8 src1_data = *((__global short8 *)((__global char *)src1 + src1_index));
+        short8 src2_data = (short8)(src2.s0, src2.s1, src2.s2, src2.s3, src2.s4, src2.s5, src2.s6, src2.s7);
+        short8 dst_data = *((__global short8 *)((__global char *)dst  + dst_index));
+
+        short8 data = src1_data & src2_data;
+        data = mask_data ? data : dst_data; 
+
+        *((__global short8 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+__kernel void arithm_s_bitwise_and_with_mask_C3_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                            __global   uchar *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            uchar4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        uchar4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        uchar4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        uchar4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        uchar4 src2_data_0 = (uchar4)(src2.x, src2.y, src2.z, src2.x); 
+        uchar4 src2_data_1 = (uchar4)(src2.y, src2.z, src2.x, src2.y);
+        uchar4 src2_data_2 = (uchar4)(src2.z, src2.x, src2.y, src2.z); 
+
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        uchar4 data_0 = *((__global uchar4 *)(dst + dst_index + 0));
+        uchar4 data_1 = *((__global uchar4 *)(dst + dst_index + 4));
+        uchar4 data_2 = *((__global uchar4 *)(dst + dst_index + 8));
+
+        uchar4 tmp_data_0 = src1_data_0 & src2_data_0;
+        uchar4 tmp_data_1 = src1_data_1 & src2_data_1;
+        uchar4 tmp_data_2 = src1_data_2 & src2_data_2;
+
+        data_0.xyz = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((mask_data.w) && (dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global uchar4 *)(dst + dst_index + 0)) = data_0;
+        *((__global uchar4 *)(dst + dst_index + 4)) = data_1;
+        *((__global uchar4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_and_with_mask_C3_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                            __global   char *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            char4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        char4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        char4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        char4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        char4 src2_data_0 = (char4)(src2.x, src2.y, src2.z, src2.x); 
+        char4 src2_data_1 = (char4)(src2.y, src2.z, src2.x, src2.y);
+        char4 src2_data_2 = (char4)(src2.z, src2.x, src2.y, src2.z); 
+
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        char4 data_0 = *((__global char4 *)(dst + dst_index + 0));
+        char4 data_1 = *((__global char4 *)(dst + dst_index + 4));
+        char4 data_2 = *((__global char4 *)(dst + dst_index + 8));
+
+        char4 tmp_data_0 = src1_data_0 & src2_data_0;
+        char4 tmp_data_1 = src1_data_1 & src2_data_1;
+        char4 tmp_data_2 = src1_data_2 & src2_data_2;
+        
+        data_0.xyz = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((mask_data.w) && (dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global char4 *)(dst + dst_index + 0)) = data_0;
+        *((__global char4 *)(dst + dst_index + 4)) = data_1;
+        *((__global char4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+
+__kernel void arithm_s_bitwise_and_with_mask_C3_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                            __global   ushort *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            ushort4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        ushort2 src1_data_0 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 0));
+        ushort2 src1_data_1 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 4));
+        ushort2 src1_data_2 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 8));
+
+        ushort2 src2_data_0 = (ushort2)(src2.x, src2.y);
+        ushort2 src2_data_1 = (ushort2)(src2.z, src2.x);
+        ushort2 src2_data_2 = (ushort2)(src2.y, src2.z);
+
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        ushort2 data_0 = *((__global ushort2 *)((__global char *)dst + dst_index + 0));
+        ushort2 data_1 = *((__global ushort2 *)((__global char *)dst + dst_index + 4));
+        ushort2 data_2 = *((__global ushort2 *)((__global char *)dst + dst_index + 8));
+
+        ushort2 tmp_data_0 = src1_data_0 & src2_data_0;
+        ushort2 tmp_data_1 = src1_data_1 & src2_data_1;
+        ushort2 tmp_data_2 = src1_data_2 & src2_data_2;
+        
+        data_0.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global ushort2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_bitwise_and_with_mask_C3_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                            __global   short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            short4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        short2 src1_data_0 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 0));
+        short2 src1_data_1 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 4));
+        short2 src1_data_2 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 8));
+
+        short2 src2_data_0 = (short2)(src2.x, src2.y);
+        short2 src2_data_1 = (short2)(src2.z, src2.x);
+        short2 src2_data_2 = (short2)(src2.y, src2.z);
+
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        short2 data_0 = *((__global short2 *)((__global char *)dst + dst_index + 0));
+        short2 data_1 = *((__global short2 *)((__global char *)dst + dst_index + 4));
+        short2 data_2 = *((__global short2 *)((__global char *)dst + dst_index + 8));
+
+        short2 tmp_data_0 = src1_data_0 & src2_data_0;
+        short2 tmp_data_1 = src1_data_1 & src2_data_1;
+        short2 tmp_data_2 = src1_data_2 & src2_data_2;
+
+        data_0.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global short2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global short2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global short2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_bitwise_and_with_mask_C3_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                            __global   int *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        int src1_data_0 = *((__global int *)((__global char *)src1 + src1_index + 0));
+        int src1_data_1 = *((__global int *)((__global char *)src1 + src1_index + 4));
+        int src1_data_2 = *((__global int *)((__global char *)src1 + src1_index + 8));
+
+        int src2_data_0 = src2.x;
+        int src2_data_1 = src2.y;
+        int src2_data_2 = src2.z;
+
+        uchar mask_data = * (mask + mask_index);
+
+        int data_0 = *((__global int *)((__global char *)dst + dst_index + 0));
+        int data_1 = *((__global int *)((__global char *)dst + dst_index + 4));
+        int data_2 = *((__global int *)((__global char *)dst + dst_index + 8));
+
+        int tmp_data_0 = src1_data_0 & src2_data_0;
+        int tmp_data_1 = src1_data_1 & src2_data_1;
+        int tmp_data_2 = src1_data_2 & src2_data_2;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global int *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global int *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global int *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_bitwise_and_with_mask_C3_D5 (__global   char *src1, int src1_step, int src1_offset,
+                                            __global   char *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            char16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        char4 src1_data_0 = *((__global char4 *)((__global char *)src1 + src1_index + 0));
+        char4 src1_data_1 = *((__global char4 *)((__global char *)src1 + src1_index + 4));
+        char4 src1_data_2 = *((__global char4 *)((__global char *)src1 + src1_index + 8));
+                                             
+        char4 src2_data_0 = (char4)(src2.s0, src2.s1, src2.s2, src2.s3); 
+        char4 src2_data_1 = (char4)(src2.s4, src2.s5, src2.s6, src2.s7);
+        char4 src2_data_2 = (char4)(src2.s8, src2.s9, src2.sA, src2.sB); 
+        
+        uchar mask_data = * (mask + mask_index);
+
+        char4 data_0 = *((__global char4 *)((__global char *)dst + dst_index + 0));
+        char4 data_1 = *((__global char4 *)((__global char *)dst + dst_index + 4));
+        char4 data_2 = *((__global char4 *)((__global char *)dst + dst_index + 8));
+
+        char4 tmp_data_0 = src1_data_0 & src2_data_0;
+        char4 tmp_data_1 = src1_data_1 & src2_data_1;
+        char4 tmp_data_2 = src1_data_2 & src2_data_2;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global char4 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global char4 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global char4 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_and_with_mask_C3_D6 (__global short *src1, int src1_step, int src1_offset,
+                                                    __global short *dst,  int dst_step,  int dst_offset,
+                                                    __global uchar  *mask, int mask_step, int mask_offset,
+                                                    short16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 24) + src1_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 24));
+
+        short4 src1_data_0 = *((__global short4 *)((__global char *)src1 + src1_index + 0 ));
+        short4 src1_data_1 = *((__global short4 *)((__global char *)src1 + src1_index + 8 ));
+        short4 src1_data_2 = *((__global short4 *)((__global char *)src1 + src1_index + 16));
+                                               
+        short4 src2_data_0 = (short4)(src2.s0, src2.s1, src2.s2, src2.s3);
+        short4 src2_data_1 = (short4)(src2.s4, src2.s5, src2.s6, src2.s7);
+        short4 src2_data_2 = (short4)(src2.s8, src2.s9, src2.sa, src2.sb);
+        
+        uchar mask_data = * (mask + mask_index);
+
+        short4 data_0 = *((__global short4 *)((__global char *)dst + dst_index + 0 ));
+        short4 data_1 = *((__global short4 *)((__global char *)dst + dst_index + 8 ));
+        short4 data_2 = *((__global short4 *)((__global char *)dst + dst_index + 16));
+
+        short4 tmp_data_0 = src1_data_0 & src2_data_0;
+        short4 tmp_data_1 = src1_data_1 & src2_data_1;
+        short4 tmp_data_2 = src1_data_2 & src2_data_2;
+        
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global short4 *)((__global char *)dst + dst_index + 0 ))= data_0;
+       *((__global short4 *)((__global char *)dst + dst_index + 8 ))= data_1;
+       *((__global short4 *)((__global char *)dst + dst_index + 16))= data_2;
+    }
+}
+#endif
+__kernel void arithm_s_bitwise_and_with_mask_C4_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                            __global   uchar *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            uchar4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        uchar4 src_data1 = *((__global uchar4 *)(src1 + src1_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+
+        uchar4 data = src_data1 & src2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_and_with_mask_C4_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                            __global   char *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            char4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char4 src_data1 = *((__global char4 *)(src1 + src1_index));
+        char4 dst_data  = *((__global char4 *)(dst  + dst_index));
+
+        char4 data = src_data1 & src2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_bitwise_and_with_mask_C4_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                            __global   ushort *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            ushort4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        ushort4 src_data1 = *((__global ushort4 *)((__global char *)src1 + src1_index));
+        ushort4 dst_data  = *((__global ushort4 *)((__global char *)dst  + dst_index));
+
+        ushort4 data = src_data1 & src2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_and_with_mask_C4_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                            __global   short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            short4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short4 src_data1 = *((__global short4 *)((__global char *)src1 + src1_index));
+        short4 dst_data  = *((__global short4 *)((__global char *)dst  + dst_index));
+
+        short4 data = src_data1 & src2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_and_with_mask_C4_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                            __global   int *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int4 src_data1 = *((__global int4 *)((__global char *)src1 + src1_index));
+        int4 dst_data  = *((__global int4 *)((__global char *)dst  + dst_index));
+
+        int4 data = src_data1 & src2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global int4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_and_with_mask_C4_D5 (__global   char *src1, int src1_step, int src1_offset,
+                                                    __global   char *dst,  int dst_step,  int dst_offset,
+                                                    __global   uchar *mask, int mask_step, int mask_offset,
+                                                    char16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char16 src1_data = *((__global char16 *)((__global char *)src1 + src1_index));
+        char16 src2_data = (char16)(src2.s0, src2.s1, src2.s2, src2.s3, src2.s4, src2.s5, src2.s6, src2.s7,
+                                    src2.s8, src2.s9, src2.sa, src2.sb, src2.sc, src2.sd, src2.se, src2.sf);
+        char16 dst_data  = *((__global char16 *)((__global char *)dst  + dst_index));
+
+        char16 data = src1_data & src2_data;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char16 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_and_with_mask_C4_D6 (__global short *src1, int src1_step, int src1_offset,
+                                                    __global short *dst,  int dst_step,  int dst_offset,
+                                                    __global uchar *mask, int mask_step, int mask_offset,
+                                                    short16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 5) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 5) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short4 src1_data_0 = *((__global short4 *)((__global char *)src1 + src1_index + 0));
+        short4 src1_data_1 = *((__global short4 *)((__global char *)src1 + src1_index + 8));
+        short4 src1_data_2 = *((__global short4 *)((__global char *)src1 + src1_index + 16));
+        short4 src1_data_3 = *((__global short4 *)((__global char *)src1 + src1_index + 24));
+
+        short4 src2_data_0 = (short4)(src2.s0, src2.s1, src2.s2, src2.s3);
+        short4 src2_data_1 = (short4)(src2.s4, src2.s5, src2.s6, src2.s7);
+        short4 src2_data_2 = (short4)(src2.s8, src2.s9, src2.sa, src2.sb);
+        short4 src2_data_3 = (short4)(src2.sc, src2.sd, src2.se, src2.sf);
+        
+        short4 dst_data_0  = *((__global short4 *)((__global char *)dst  + dst_index + 0));
+        short4 dst_data_1  = *((__global short4 *)((__global char *)dst  + dst_index + 8));
+        short4 dst_data_2  = *((__global short4 *)((__global char *)dst  + dst_index + 16));
+        short4 dst_data_3  = *((__global short4 *)((__global char *)dst  + dst_index + 24));
+
+        short4 data_0 = src1_data_0 & src2_data_0;
+        short4 data_1 = src1_data_1 & src2_data_1;
+        short4 data_2 = src1_data_2 & src2_data_2;
+        short4 data_3 = src1_data_3 & src2_data_3;
+             
+        data_0 = mask_data ? data_0 : dst_data_0; 
+        data_1 = mask_data ? data_1 : dst_data_1; 
+        data_2 = mask_data ? data_2 : dst_data_2; 
+        data_3 = mask_data ? data_3 : dst_data_3;
+
+        *((__global short4 *)((__global char *)dst + dst_index + 0)) = data_0;
+        *((__global short4 *)((__global char *)dst + dst_index + 8)) = data_1;
+        *((__global short4 *)((__global char *)dst + dst_index + 16)) = data_2;
+        *((__global short4 *)((__global char *)dst + dst_index + 24)) = data_3;
+    }
+}
+#endif
+
diff --git a/modules/ocl/src/kernels/arithm_bitwise_not.cl b/modules/ocl/src/kernels/arithm_bitwise_not.cl
new file mode 100644 (file)
index 0000000..cdad29a
--- /dev/null
@@ -0,0 +1,251 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jiang Liyuan, jlyuan001.good@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*/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////BITWISE_NOT////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+/**************************************bitwise_not without mask**************************************/
+__kernel void arithm_bitwise_not_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                     __global uchar *dst,  int dst_step,  int dst_offset,
+                                     int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = ~ src1_data;
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+
+__kernel void arithm_bitwise_not_D1 (__global char *src1, int src1_step, int src1_offset,
+                             __global char *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+
+        char4 dst_data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = ~ src1_data;
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global char4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+
+__kernel void arithm_bitwise_not_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                             __global ushort *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        ushort4 src1_data = vload4(0, (__global ushort *)((__global char *)src1 + src1_index));
+
+        ushort4 dst_data = *((__global ushort4 *)((__global char *)dst + dst_index));
+        ushort4 tmp_data = ~ src1_data;
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_not_D3 (__global short *src1, int src1_step, int src1_offset,
+                             __global short *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        short4 src1_data = vload4(0, (__global short *)((__global char *)src1 + src1_index));
+
+        short4 dst_data = *((__global short4 *)((__global char *)dst + dst_index));
+        short4 tmp_data = ~ src1_data;
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_not_D4 (__global int *src1, int src1_step, int src1_offset,
+                             __global int *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        int data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int tmp  = ~ data1;
+
+        *((__global int *)((__global char *)dst + dst_index)) = tmp;
+    }
+}
+
+__kernel void arithm_bitwise_not_D5 (__global char *src, int src_step, int src_offset,
+                                     __global char *dst, int dst_step, int dst_offset,
+                                     int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src_index = mad24(y, src_step, (x << 2) + src_offset);
+        int dst_index = mad24(y, dst_step, (x << 2) + dst_offset);
+
+        char4 data;
+
+        data = *((__global char4 *)((__global char *)src + src_index));
+        data = ~ data;
+
+        *((__global char4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_bitwise_not_D6 (__global char *src, int src_step, int src_offset,
+                                     __global char *dst, int dst_step, int dst_offset,
+                                     int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src_index = mad24(y, src_step, (x << 3) + src_offset);
+        int dst_index = mad24(y, dst_step,  (x << 3) + dst_offset);
+         
+        char8 data;
+
+        data = *((__global char8 *)((__global char *)src + src_index));
+        data = ~ data;
+        
+        *((__global char8 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+
diff --git a/modules/ocl/src/kernels/arithm_bitwise_or.cl b/modules/ocl/src/kernels/arithm_bitwise_or.cl
new file mode 100644 (file)
index 0000000..90eb28d
--- /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.
+//
+//
+//                           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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jiang Liyuan, jlyuan001.good@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*/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////BITWISE_OR////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+/**************************************bitwise_or without mask**************************************/
+__kernel void arithm_bitwise_or_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                             __global uchar *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = src1_data | src2_data;
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+
+__kernel void arithm_bitwise_or_D1 (__global char *src1, int src1_step, int src1_offset,
+                             __global char *src2, int src2_step, int src2_offset,
+                             __global char *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+        char4 src2_data = vload4(0, src2 + src2_index);
+
+        char4 dst_data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = src1_data | src2_data;
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global char4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+
+__kernel void arithm_bitwise_or_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                             __global ushort *src2, int src2_step, int src2_offset,
+                             __global ushort *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        ushort4 src1_data = vload4(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort4 src2_data = vload4(0, (__global ushort *)((__global char *)src2 + src2_index));
+
+        ushort4 dst_data = *((__global ushort4 *)((__global char *)dst + dst_index));
+        ushort4 tmp_data = src1_data | src2_data;
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_or_D3 (__global short *src1, int src1_step, int src1_offset,
+                             __global short *src2, int src2_step, int src2_offset,
+                             __global short *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        short4 src1_data = vload4(0, (__global short *)((__global char *)src1 + src1_index));
+        short4 src2_data = vload4(0, (__global short *)((__global char *)src2 + src2_index));
+
+        short4 dst_data = *((__global short4 *)((__global char *)dst + dst_index));
+        short4 tmp_data = src1_data | src2_data;
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_or_D4 (__global int *src1, int src1_step, int src1_offset,
+                             __global int *src2, int src2_step, int src2_offset,
+                             __global int *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        int data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int data2 = *((__global int *)((__global char *)src2 + src2_index));
+        int tmp  = data1 | data2;
+
+        *((__global int *)((__global char *)dst + dst_index)) = tmp;
+    }
+}
+
+__kernel void arithm_bitwise_or_D5 (__global char *src1, int src1_step, int src1_offset,
+                             __global char *src2, int src2_step, int src2_offset,
+                             __global char *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        char4 data1 = *((__global char4 *)((__global char *)src1 + src1_index));
+        char4 data2 = *((__global char4 *)((__global char *)src2 + src2_index));
+        char4 tmp = data1 | data2;
+
+        *((__global char4 *)((__global char *)dst + dst_index)) = tmp;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_bitwise_or_D6 (__global char *src1, int src1_step, int src1_offset,
+                             __global char *src2, int src2_step, int src2_offset,
+                             __global char *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        char8 data1 = *((__global char8 *)((__global char *)src1 + src1_index));
+        char8 data2 = *((__global char8 *)((__global char *)src2 + src2_index));
+
+        *((__global char8 *)((__global char *)dst + dst_index)) = data1 | data2;
+    }
+}
+#endif
+
diff --git a/modules/ocl/src/kernels/arithm_bitwise_or_mask.cl b/modules/ocl/src/kernels/arithm_bitwise_or_mask.cl
new file mode 100644 (file)
index 0000000..099ee9b
--- /dev/null
@@ -0,0 +1,1138 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jiang Liyuan, jlyuan001.good@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*/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////BITWISE_OR////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+/**************************************bitwise_or with mask**************************************/
+__kernel void arithm_bitwise_or_with_mask_C1_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                          __global uchar *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global uchar *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = src1_data | src2_data;
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((mask_data.z) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((mask_data.w) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_or_with_mask_C1_D1 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+        char4 src2_data = vload4(0, src2 + src2_index);
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        char4 data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = src1_data | src2_data;
+
+        data.x = convert_char((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = convert_char((mask_data.y) && (dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = convert_char((mask_data.z) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = convert_char((mask_data.w) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_or_with_mask_C1_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                                          __global ushort *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global ushort *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        ushort2 src1_data = vload2(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort2 src2_data = vload2(0, (__global ushort *)((__global char *)src2 + src2_index));
+        uchar2  mask_data = vload2(0, mask + mask_index);
+
+        ushort2 data = *((__global ushort2 *)((__global uchar *)dst + dst_index));
+        ushort2 tmp_data = src1_data | src2_data;
+
+        data.x = convert_ushort((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = convert_ushort((mask_data.y) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : data.y;
+
+        *((__global ushort2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_or_with_mask_C1_D3 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        short2 src1_data = vload2(0, (__global short *)((__global char *)src1 + src1_index));
+        short2 src2_data = vload2(0, (__global short *)((__global char *)src2 + src2_index));
+        uchar2  mask_data = vload2(0, mask + mask_index);
+
+       short2 data = *((__global short2 *)((__global uchar *)dst + dst_index));
+       short2 tmp_data = src1_data | src2_data;
+
+        data.x = convert_short((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = convert_short((mask_data.y) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : data.y;
+
+        *((__global short2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_or_with_mask_C1_D4 (__global int   *src1, int src1_step, int src1_offset,
+                                          __global int   *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global int   *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int src_data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int src_data2 = *((__global int *)((__global char *)src2 + src2_index));
+        int dst_data  = *((__global int *)((__global char *)dst  + dst_index));
+
+        int data = src_data1 | src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global int *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_or_with_mask_C1_D5 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char4 src_data1 = *((__global char4 *)((__global char *)src1 + src1_index));
+        char4 src_data2 = *((__global char4 *)((__global char *)src2 + src2_index));
+        char4 dst_data  = *((__global char4 *)((__global char *)dst  + dst_index));
+
+        char4 data = src_data1 | src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_bitwise_or_with_mask_C1_D6 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char8 src_data1 = *((__global char8 *)((__global char *)src1 + src1_index));
+        char8 src_data2 = *((__global char8 *)((__global char *)src2 + src2_index));
+        char8 dst_data  = *((__global char8 *)((__global char *)dst  + dst_index));
+
+        char8 data = src_data1 | src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char8 *)((__global char *)dst + dst_index)) = data;
+    }
+
+}
+#endif
+
+
+
+__kernel void arithm_bitwise_or_with_mask_C2_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                          __global uchar *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global uchar *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = src1_data | src2_data;
+
+        data.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.xy : data.xy;
+        data.zw = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.zw : data.zw;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_bitwise_or_with_mask_C2_D1 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+        char4 src2_data = vload4(0, src2 + src2_index);
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        char4 data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = src1_data | src2_data;
+
+        data.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.xy : data.xy;
+        data.zw = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.zw : data.zw;
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_bitwise_or_with_mask_C2_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                                          __global ushort *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global ushort *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        ushort2 src_data1 = *((__global ushort2 *)((__global char *)src1 + src1_index));
+        ushort2 src_data2 = *((__global ushort2 *)((__global char *)src2 + src2_index));
+        ushort2 dst_data  = *((__global ushort2 *)((__global char *)dst  + dst_index));
+
+        ushort2 data = src_data1 | src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global ushort2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_bitwise_or_with_mask_C2_D3 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short2 src_data1 = *((__global short2 *)((__global char *)src1 + src1_index));
+        short2 src_data2 = *((__global short2 *)((__global char *)src2 + src2_index));
+        short2 dst_data  = *((__global short2 *)((__global char *)dst  + dst_index));
+
+        short2 data = src_data1 | src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global short2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_bitwise_or_with_mask_C2_D4 (__global int   *src1, int src1_step, int src1_offset,
+                                          __global int   *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global int    *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int2 src_data1 = *((__global int2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = *((__global int2 *)((__global char *)src2 + src2_index));
+        int2 dst_data  = *((__global int2 *)((__global char *)dst  + dst_index));
+
+        int2 data = src_data1 | src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global int2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_bitwise_or_with_mask_C2_D5 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char8 src_data1 = *((__global char8 *)((__global char *)src1 + src1_index));
+        char8 src_data2 = *((__global char8 *)((__global char *)src2 + src2_index));
+        char8 dst_data  = *((__global char8 *)((__global char *)dst  + dst_index));
+
+        char8 data = src_data1 | src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char8 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_bitwise_or_with_mask_C2_D6 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 4) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char16 src_data1 = *((__global char16 *)((__global char *)src1 + src1_index));
+        char16 src_data2 = *((__global char16 *)((__global char *)src2 + src2_index));
+        char16 dst_data  = *((__global char16 *)((__global char *)dst  + dst_index));
+
+        char16 data = src_data1 | src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char16 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+
+
+
+__kernel void arithm_bitwise_or_with_mask_C3_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                          __global uchar *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global uchar *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+        int src2_index = mad24(y, src2_step, (x * 3) + src2_offset - (dst_align * 3)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        uchar4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        uchar4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        uchar4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        uchar4 src2_data_0 = vload4(0, src2 + src2_index + 0);
+        uchar4 src2_data_1 = vload4(0, src2 + src2_index + 4);
+        uchar4 src2_data_2 = vload4(0, src2 + src2_index + 8);
+
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        uchar4 data_0 = *((__global uchar4 *)(dst + dst_index + 0));
+        uchar4 data_1 = *((__global uchar4 *)(dst + dst_index + 4));
+        uchar4 data_2 = *((__global uchar4 *)(dst + dst_index + 8));
+
+        uchar4 tmp_data_0 =  src1_data_0 | src2_data_0;
+        uchar4 tmp_data_1 =  src1_data_1 | src2_data_1;
+        uchar4 tmp_data_2 =  src1_data_2 | src2_data_2;
+
+        data_0.xyz = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((mask_data.w) && (dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global uchar4 *)(dst + dst_index + 0)) = data_0;
+        *((__global uchar4 *)(dst + dst_index + 4)) = data_1;
+        *((__global uchar4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+
+
+__kernel void arithm_bitwise_or_with_mask_C3_D1 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+        int src2_index = mad24(y, src2_step, (x * 3) + src2_offset - (dst_align * 3)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        char4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        char4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        char4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        char4 src2_data_0 = vload4(0, src2 + src2_index + 0);
+        char4 src2_data_1 = vload4(0, src2 + src2_index + 4);
+        char4 src2_data_2 = vload4(0, src2 + src2_index + 8);
+
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        char4 data_0 = *((__global char4 *)(dst + dst_index + 0));
+        char4 data_1 = *((__global char4 *)(dst + dst_index + 4));
+        char4 data_2 = *((__global char4 *)(dst + dst_index + 8));
+
+        char4 tmp_data_0 =  src1_data_0 | src2_data_0;
+        char4 tmp_data_1 =  src1_data_1 | src2_data_1;
+        char4 tmp_data_2 =  src1_data_2 | src2_data_2;
+
+        data_0.xyz = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((mask_data.w) && (dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global char4 *)(dst + dst_index + 0)) = data_0;
+        *((__global char4 *)(dst + dst_index + 4)) = data_1;
+        *((__global char4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+
+__kernel void arithm_bitwise_or_with_mask_C3_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                                          __global ushort *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global ushort *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+        int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        ushort2 src1_data_0 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 0));
+        ushort2 src1_data_1 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 4));
+        ushort2 src1_data_2 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 8));
+
+        ushort2 src2_data_0 = vload2(0, (__global ushort *)((__global char *)src2 + src2_index + 0));
+        ushort2 src2_data_1 = vload2(0, (__global ushort *)((__global char *)src2 + src2_index + 4));
+        ushort2 src2_data_2 = vload2(0, (__global ushort *)((__global char *)src2 + src2_index + 8));
+
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        ushort2 data_0 = *((__global ushort2 *)((__global char *)dst + dst_index + 0));
+        ushort2 data_1 = *((__global ushort2 *)((__global char *)dst + dst_index + 4));
+        ushort2 data_2 = *((__global ushort2 *)((__global char *)dst + dst_index + 8));
+
+        ushort2 tmp_data_0 =  src1_data_0 | src2_data_0 ;
+        ushort2 tmp_data_1 =  src1_data_1 | src2_data_1 ;
+        ushort2 tmp_data_2 =  src1_data_2 | src2_data_2 ;
+
+        data_0.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global ushort2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_bitwise_or_with_mask_C3_D3 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+        int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        short2 src1_data_0 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 0));
+        short2 src1_data_1 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 4));
+        short2 src1_data_2 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 8));
+
+        short2 src2_data_0 = vload2(0, (__global short *)((__global char *)src2 + src2_index + 0));
+        short2 src2_data_1 = vload2(0, (__global short *)((__global char *)src2 + src2_index + 4));
+        short2 src2_data_2 = vload2(0, (__global short *)((__global char *)src2 + src2_index + 8));
+
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        short2 data_0 = *((__global short2 *)((__global char *)dst + dst_index + 0));
+        short2 data_1 = *((__global short2 *)((__global char *)dst + dst_index + 4));
+        short2 data_2 = *((__global short2 *)((__global char *)dst + dst_index + 8));
+
+        short2 tmp_data_0 =  src1_data_0 | src2_data_0 ;
+        short2 tmp_data_1 =  src1_data_1 | src2_data_1 ;
+        short2 tmp_data_2 =  src1_data_2 | src2_data_2 ;
+
+        data_0.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global short2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global short2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global short2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_bitwise_or_with_mask_C3_D4 (__global int   *src1, int src1_step, int src1_offset,
+                                          __global int   *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global int   *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int src2_index = mad24(y, src2_step, (x * 12) + src2_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        int src1_data_0 = *((__global int *)((__global char *)src1 + src1_index + 0));
+        int src1_data_1 = *((__global int *)((__global char *)src1 + src1_index + 4));
+        int src1_data_2 = *((__global int *)((__global char *)src1 + src1_index + 8));
+
+        int src2_data_0 = *((__global int *)((__global char *)src2 + src2_index + 0));
+        int src2_data_1 = *((__global int *)((__global char *)src2 + src2_index + 4));
+        int src2_data_2 = *((__global int *)((__global char *)src2 + src2_index + 8));
+
+        uchar mask_data = * (mask + mask_index);
+
+        int data_0 = *((__global int *)((__global char *)dst + dst_index + 0));
+        int data_1 = *((__global int *)((__global char *)dst + dst_index + 4));
+        int data_2 = *((__global int *)((__global char *)dst + dst_index + 8));
+
+        int tmp_data_0 =  src1_data_0 |  src2_data_0 ;
+        int tmp_data_1 =  src1_data_1 |  src2_data_1 ;
+        int tmp_data_2 =  src1_data_2 |  src2_data_2 ;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global int *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global int *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global int *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_bitwise_or_with_mask_C3_D5 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int src2_index = mad24(y, src2_step, (x * 12) + src2_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        char4 src1_data_0 = *((__global char4 *)((__global char *)src1 + src1_index + 0));
+        char4 src1_data_1 = *((__global char4 *)((__global char *)src1 + src1_index + 4));
+        char4 src1_data_2 = *((__global char4 *)((__global char *)src1 + src1_index + 8));
+                                             
+        char4 src2_data_0 = *((__global char4 *)((__global char *)src2 + src2_index + 0));
+        char4 src2_data_1 = *((__global char4 *)((__global char *)src2 + src2_index + 4));
+        char4 src2_data_2 = *((__global char4 *)((__global char *)src2 + src2_index + 8));
+
+        uchar mask_data = * (mask + mask_index);
+
+        char4 data_0 = *((__global char4 *)((__global char *)dst + dst_index + 0));
+        char4 data_1 = *((__global char4 *)((__global char *)dst + dst_index + 4));
+        char4 data_2 = *((__global char4 *)((__global char *)dst + dst_index + 8));
+
+        char4 tmp_data_0 = src1_data_0 | src2_data_0;
+        char4 tmp_data_1 = src1_data_1 | src2_data_1;
+        char4 tmp_data_2 = src1_data_2 | src2_data_2;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global char4 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global char4 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global char4 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_bitwise_or_with_mask_C3_D6 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 24) + src1_offset); 
+        int src2_index = mad24(y, src2_step, (x * 24) + src2_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 24));
+
+        char8 src1_data_0 = *((__global char8 *)((__global char *)src1 + src1_index + 0 ));
+        char8 src1_data_1 = *((__global char8 *)((__global char *)src1 + src1_index + 8 ));
+        char8 src1_data_2 = *((__global char8 *)((__global char *)src1 + src1_index + 16));
+                                               
+        char8 src2_data_0 = *((__global char8 *)((__global char *)src2 + src2_index + 0 ));
+        char8 src2_data_1 = *((__global char8 *)((__global char *)src2 + src2_index + 8 ));
+        char8 src2_data_2 = *((__global char8 *)((__global char *)src2 + src2_index + 16));
+
+        uchar mask_data = * (mask + mask_index);
+
+        char8 data_0 = *((__global char8 *)((__global char *)dst + dst_index + 0 ));
+        char8 data_1 = *((__global char8 *)((__global char *)dst + dst_index + 8 ));
+        char8 data_2 = *((__global char8 *)((__global char *)dst + dst_index + 16));
+
+        char8 tmp_data_0 = src1_data_0 | src2_data_0;
+        char8 tmp_data_1 = src1_data_1 | src2_data_1;
+        char8 tmp_data_2 = src1_data_2 | src2_data_2;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global char8 *)((__global char *)dst + dst_index + 0 ))= data_0;
+       *((__global char8 *)((__global char *)dst + dst_index + 8 ))= data_1;
+       *((__global char8 *)((__global char *)dst + dst_index + 16))= data_2;
+    }
+}
+#endif
+
+
+
+__kernel void arithm_bitwise_or_with_mask_C4_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                          __global uchar *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global uchar *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        uchar4 src_data1 = *((__global uchar4 *)(src1 + src1_index));
+        uchar4 src_data2 = *((__global uchar4 *)(src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+
+        uchar4 data = src_data1 | src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_bitwise_or_with_mask_C4_D1 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char4 src_data1 = *((__global char4 *)(src1 + src1_index));
+        char4 src_data2 = *((__global char4 *)(src2 + src2_index));
+        char4 dst_data  = *((__global char4 *)(dst  + dst_index));
+
+        char4 data = src_data1 | src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_bitwise_or_with_mask_C4_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                                          __global ushort *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global ushort *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        ushort4 src_data1 = *((__global ushort4 *)((__global char *)src1 + src1_index));
+        ushort4 src_data2 = *((__global ushort4 *)((__global char *)src2 + src2_index));
+        ushort4 dst_data  = *((__global ushort4 *)((__global char *)dst  + dst_index));
+
+        ushort4 data = src_data1 | src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_bitwise_or_with_mask_C4_D3 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short4 src_data1 = *((__global short4 *)((__global char *)src1 + src1_index));
+        short4 src_data2 = *((__global short4 *)((__global char *)src2 + src2_index));
+        short4 dst_data  = *((__global short4 *)((__global char *)dst  + dst_index));
+
+        short4 data = src_data1 | src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_bitwise_or_with_mask_C4_D4 (__global int   *src1, int src1_step, int src1_offset,
+                                          __global int   *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global int   *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 4) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int4 src_data1 = *((__global int4 *)((__global char *)src1 + src1_index));
+        int4 src_data2 = *((__global int4 *)((__global char *)src2 + src2_index));
+        int4 dst_data  = *((__global int4 *)((__global char *)dst  + dst_index));
+
+        int4 data = src_data1 | src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global int4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_bitwise_or_with_mask_C4_D5 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 4) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char16 src_data1 = *((__global char16 *)((__global char *)src1 + src1_index));
+        char16 src_data2 = *((__global char16 *)((__global char *)src2 + src2_index));
+        char16 dst_data  = *((__global char16 *)((__global char *)dst  + dst_index));
+
+        char16 data = src_data1 | src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char16 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_bitwise_or_with_mask_C4_D6 (__global char *src1, int src1_step, int src1_offset,
+                                                  __global char *src2, int src2_step, int src2_offset,
+                                                  __global uchar  *mask, int mask_step, int mask_offset,
+                                                  __global char *dst,  int dst_step,  int dst_offset,
+                                                  int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 5) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 5) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 5) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char8 src_data1_0 = *((__global char8 *)((__global char *)src1 + src1_index + 0));
+        char8 src_data1_1 = *((__global char8 *)((__global char *)src1 + src1_index + 8));
+        char8 src_data1_2 = *((__global char8 *)((__global char *)src1 + src1_index + 16));
+        char8 src_data1_3 = *((__global char8 *)((__global char *)src1 + src1_index + 24));
+
+        char8 src_data2_0 = *((__global char8 *)((__global char *)src2 + src2_index + 0));
+        char8 src_data2_1 = *((__global char8 *)((__global char *)src2 + src2_index + 8));
+        char8 src_data2_2 = *((__global char8 *)((__global char *)src2 + src2_index + 16));
+        char8 src_data2_3 = *((__global char8 *)((__global char *)src2 + src2_index + 24));
+
+        char8 dst_data_0  = *((__global char8 *)((__global char *)dst  + dst_index + 0));
+        char8 dst_data_1  = *((__global char8 *)((__global char *)dst  + dst_index + 8));
+        char8 dst_data_2  = *((__global char8 *)((__global char *)dst  + dst_index + 16));
+        char8 dst_data_3  = *((__global char8 *)((__global char *)dst  + dst_index + 24));
+
+        char8 data_0 = src_data1_0 | src_data2_0;
+        char8 data_1 = src_data1_1 | src_data2_1;
+        char8 data_2 = src_data1_2 | src_data2_2;
+        char8 data_3 = src_data1_3 | src_data2_3;
+
+        data_0 = mask_data ? data_0 : dst_data_0; 
+        data_1 = mask_data ? data_1 : dst_data_1; 
+        data_2 = mask_data ? data_2 : dst_data_2; 
+        data_3 = mask_data ? data_3 : dst_data_3; 
+
+        *((__global char8 *)((__global char *)dst + dst_index + 0)) = data_0;
+        *((__global char8 *)((__global char *)dst + dst_index + 8)) = data_1;
+        *((__global char8 *)((__global char *)dst + dst_index + 16)) = data_2;
+        *((__global char8 *)((__global char *)dst + dst_index + 24)) = data_3;
+    }
+}
+#endif
+
diff --git a/modules/ocl/src/kernels/arithm_bitwise_or_scalar.cl b/modules/ocl/src/kernels/arithm_bitwise_or_scalar.cl
new file mode 100644 (file)
index 0000000..ef9bfe3
--- /dev/null
@@ -0,0 +1,914 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jiang Liyuan, jlyuan001.good@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*/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////BITWISE_OR////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+/**************************************and with scalar without mask**************************************/
+__kernel void arithm_s_bitwise_or_C1_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                  __global   uchar *dst,  int dst_step,  int dst_offset,
+                                  uchar4 src2, int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = (uchar4)(src2.x, src2.x, src2.x, src2.x);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = src1_data | src2_data;
+
+        data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_or_C1_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char4 src2, int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+        char4 src2_data = (char4)(src2.x, src2.x, src2.x, src2.x);
+
+        char4 data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = src1_data | src2_data;
+
+        data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_bitwise_or_C1_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                  __global   ushort *dst,  int dst_step,  int dst_offset,
+                                  ushort4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        ushort2 src1_data = vload2(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort2 src2_data = (ushort2)(src2.x, src2.x);
+
+        ushort2 data = *((__global ushort2 *)((__global uchar *)dst + dst_index));
+        ushort2 tmp_data = src1_data | src2_data;
+
+        data.x = (dst_index + 0 >= dst_start) ? tmp_data.x : data.x;
+        data.y = (dst_index + 2 <  dst_end  ) ? tmp_data.y : data.y;
+
+        *((__global ushort2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_or_C1_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                  __global   short *dst,  int dst_step,  int dst_offset,
+                                  short4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        short2 src1_data = vload2(0, (__global short *)((__global char *)src1 + src1_index));
+        short2 src2_data = (short2)(src2.x, src2.x);
+        short2 data = *((__global short2 *)((__global uchar *)dst + dst_index));
+
+        short2 tmp_data = src1_data | src2_data;
+
+        data.x = (dst_index + 0 >= dst_start) ? tmp_data.x : data.x;
+        data.y = (dst_index + 2 <  dst_end  ) ? tmp_data.y : data.y;
+
+        *((__global short2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_or_C1_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                  __global   int *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        int src_data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int src_data2 = src2.x;
+
+        int data = src_data1 | src_data2;
+
+        *((__global int *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_or_C1_D5 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        char4 src_data1 = *((__global char4 *)((__global char *)src1 + src1_index));
+        char4 src_data2 = (char4)(src2.s0, src2.s1, src2.s2, src2.s3);
+
+        char4 data = src_data1 | src_data2;
+
+        *((__global char4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_or_C1_D6 (__global short *src1, int src1_step, int src1_offset,
+                                  __global short *dst,  int dst_step,  int dst_offset,
+                                  short16 src2, int rows, int cols, int dst_step1)
+                                  
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        short4 src1_data = *((__global short4 *)((__global char *)src1 + src1_index));
+        short4 src2_data = (short4)(src2.s0, src2.s1, src2.s2, src2.s3);
+
+        short4 tmp_data = src1_data | src2_data;
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = tmp_data;
+    }
+}
+#endif
+
+__kernel void arithm_s_bitwise_or_C2_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                  __global   uchar *dst,  int dst_step,  int dst_offset,
+                                  uchar4 src2, int rows, int cols, int dst_step1)
+                                 
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = (uchar4)(src2.x, src2.y, src2.x, src2.y);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = src1_data | src2_data;
+
+        data.xy = (dst_index + 0 >= dst_start) ? tmp_data.xy : data.xy;
+        data.zw = (dst_index + 2 <  dst_end  ) ? tmp_data.zw : data.zw;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_or_C2_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char4 src2, int rows, int cols, int dst_step1)
+                                  
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+        char4 src2_data = (char4)(src2.x, src2.y, src2.x, src2.y);
+
+        char4 data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = src1_data | src2_data;
+
+        data.xy = (dst_index + 0 >= dst_start) ? tmp_data.xy : data.xy;
+        data.zw = (dst_index + 2 <  dst_end  ) ? tmp_data.zw : data.zw;
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_bitwise_or_C2_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                  __global   ushort *dst,  int dst_step,  int dst_offset,
+                                  ushort4 src2, int rows, int cols, int dst_step1)
+                                  
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        ushort2 src_data1 = *((__global ushort2 *)((__global char *)src1 + src1_index));
+        ushort2 src_data2 = (ushort2)(src2.x, src2.y);
+
+        ushort2 data = src_data1 | src_data2;
+
+        *((__global ushort2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_or_C2_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                  __global   short *dst,  int dst_step,  int dst_offset,
+                                  short4 src2, int rows, int cols, int dst_step1)
+                                  
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        short2 src_data1 = *((__global short2 *)((__global char *)src1 + src1_index));
+        short2 src_data2 = (short2)(src2.x, src2.y);
+
+        short2 data = src_data1 | src_data2;
+
+        *((__global short2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_or_C2_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                  __global   int *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+                                  
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        int2 src_data1 = *((__global int2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = (int2)(src2.x, src2.y);
+
+        int2 data = src_data1 | src_data2;
+        *((__global int2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_or_C2_D5 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char16 src2, int rows, int cols, int dst_step1)
+                                  
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        char8 src_data1 = *((__global char8 *)((__global char *)src1 + src1_index));
+        char8 src_data2 = (char8)(src2.s0, src2.s1, src2.s2, src2.s3, src2.s4, src2.s5, src2.s6, src2.s7);
+
+        char8 data = src_data1 | src_data2;
+        *((__global char8 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_or_C2_D6 (__global short *src1, int src1_step, int src1_offset,
+                                  __global short *dst,  int dst_step,  int dst_offset,
+                                  short16 src2, int rows, int cols, int dst_step1)
+                                  
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        short8 src1_data = *((__global short8 *)((__global char *)src1 + src1_index));
+        short8 src2_data = (short8)(src2.s0, src2.s1, src2.s2, src2.s3, src2.s4, src2.s5, src2.s6, src2.s7);
+
+        short8 tmp_data = src1_data & src2_data;
+
+        *((__global short8 *)((__global char *)dst + dst_index)) = tmp_data;
+    }
+}
+#endif
+__kernel void arithm_s_bitwise_or_C3_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                  __global   uchar *dst,  int dst_step,  int dst_offset,
+                                  uchar4 src2, int rows, int cols, int dst_step1)
+                                  
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        uchar4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        uchar4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        uchar4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        uchar4 src2_data_0 = (uchar4)(src2.x, src2.y, src2.z, src2.x); 
+        uchar4 src2_data_1 = (uchar4)(src2.y, src2.z, src2.x, src2.y);
+        uchar4 src2_data_2 = (uchar4)(src2.z, src2.x, src2.y, src2.z); 
+
+        uchar4 data_0 = *((__global uchar4 *)(dst + dst_index + 0));
+        uchar4 data_1 = *((__global uchar4 *)(dst + dst_index + 4));
+        uchar4 data_2 = *((__global uchar4 *)(dst + dst_index + 8));
+
+        uchar4 tmp_data_0 =  src1_data_0  |  src2_data_0  ;
+        uchar4 tmp_data_1 =  src1_data_1  |  src2_data_1  ;
+        uchar4 tmp_data_2 =  src1_data_2  |  src2_data_2  ;
+
+        data_0.xyz = ((dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global uchar4 *)(dst + dst_index + 0)) = data_0;
+        *((__global uchar4 *)(dst + dst_index + 4)) = data_1;
+        *((__global uchar4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_or_C3_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char4 src2, int rows, int cols, int dst_step1)
+                                  
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        char4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        char4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        char4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        char4 src2_data_0 = (char4)(src2.x, src2.y, src2.z, src2.x); 
+        char4 src2_data_1 = (char4)(src2.y, src2.z, src2.x, src2.y);
+        char4 src2_data_2 = (char4)(src2.z, src2.x, src2.y, src2.z); 
+
+        char4 data_0 = *((__global char4 *)(dst + dst_index + 0));
+        char4 data_1 = *((__global char4 *)(dst + dst_index + 4));
+        char4 data_2 = *((__global char4 *)(dst + dst_index + 8));
+
+        char4 tmp_data_0 =  src1_data_0  |  src2_data_0;
+        char4 tmp_data_1 =  src1_data_1  |  src2_data_1;
+        char4 tmp_data_2 =  src1_data_2  |  src2_data_2;
+
+        data_0.xyz = ((dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global char4 *)(dst + dst_index + 0)) = data_0;
+        *((__global char4 *)(dst + dst_index + 4)) = data_1;
+        *((__global char4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+
+__kernel void arithm_s_bitwise_or_C3_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                  __global   ushort *dst,  int dst_step,  int dst_offset,
+                                  ushort4 src2, int rows, int cols, int dst_step1)
+                                 
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        ushort2 src1_data_0 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 0));
+        ushort2 src1_data_1 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 4));
+        ushort2 src1_data_2 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 8));
+
+        ushort2 src2_data_0 = (ushort2)(src2.x, src2.y);
+        ushort2 src2_data_1 = (ushort2)(src2.z, src2.x);
+        ushort2 src2_data_2 = (ushort2)(src2.y, src2.z);
+
+        ushort2 data_0 = *((__global ushort2 *)((__global char *)dst + dst_index + 0));
+        ushort2 data_1 = *((__global ushort2 *)((__global char *)dst + dst_index + 4));
+        ushort2 data_2 = *((__global ushort2 *)((__global char *)dst + dst_index + 8));
+
+        ushort2 tmp_data_0 = src1_data_0  |  src2_data_0  ;
+        ushort2 tmp_data_1 = src1_data_1  |  src2_data_1  ;
+        ushort2 tmp_data_2 = src1_data_2  |  src2_data_2  ;
+
+        data_0.xy = ((dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global ushort2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_bitwise_or_C3_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                  __global   short *dst,  int dst_step,  int dst_offset,
+                                  short4 src2, int rows, int cols, int dst_step1)
+                                  
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        short2 src1_data_0 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 0));
+        short2 src1_data_1 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 4));
+        short2 src1_data_2 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 8));
+
+        short2 src2_data_0 = (short2)(src2.x, src2.y);
+        short2 src2_data_1 = (short2)(src2.z, src2.x);
+        short2 src2_data_2 = (short2)(src2.y, src2.z);
+
+        short2 data_0 = *((__global short2 *)((__global char *)dst + dst_index + 0));
+        short2 data_1 = *((__global short2 *)((__global char *)dst + dst_index + 4));
+        short2 data_2 = *((__global short2 *)((__global char *)dst + dst_index + 8));
+
+        short2 tmp_data_0 =  src1_data_0  |  src2_data_0  ;
+        short2 tmp_data_1 =  src1_data_1  |  src2_data_1  ;
+        short2 tmp_data_2 =  src1_data_2  |  src2_data_2  ;
+
+        data_0.xy = ((dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global short2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global short2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global short2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_bitwise_or_C3_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                  __global   int *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+                                  
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        int src1_data_0 = *((__global int *)((__global char *)src1 + src1_index + 0));
+        int src1_data_1 = *((__global int *)((__global char *)src1 + src1_index + 4));
+        int src1_data_2 = *((__global int *)((__global char *)src1 + src1_index + 8));
+
+        int src2_data_0 = src2.x;
+        int src2_data_1 = src2.y;
+        int src2_data_2 = src2.z;
+
+        int data_0 = *((__global int *)((__global char *)dst + dst_index + 0));
+        int data_1 = *((__global int *)((__global char *)dst + dst_index + 4));
+        int data_2 = *((__global int *)((__global char *)dst + dst_index + 8));
+
+        int tmp_data_0 = src1_data_0 | src2_data_0;
+        int tmp_data_1 = src1_data_1 | src2_data_1;
+        int tmp_data_2 = src1_data_2 | src2_data_2;
+
+       *((__global int *)((__global char *)dst + dst_index + 0))= tmp_data_0;
+       *((__global int *)((__global char *)dst + dst_index + 4))= tmp_data_1;
+       *((__global int *)((__global char *)dst + dst_index + 8))= tmp_data_2;
+    }
+}
+__kernel void arithm_s_bitwise_or_C3_D5 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char16 src2, int rows, int cols, int dst_step1)
+                                  
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        char4 src1_data_0 = *((__global char4 *)((__global char *)src1 + src1_index + 0));
+        char4 src1_data_1 = *((__global char4 *)((__global char *)src1 + src1_index + 4));
+        char4 src1_data_2 = *((__global char4 *)((__global char *)src1 + src1_index + 8));
+                                             
+        char4 src2_data_0 = (char4)(src2.s0, src2.s1, src2.s2, src2.s3); 
+        char4 src2_data_1 = (char4)(src2.s4, src2.s5, src2.s6, src2.s7);
+        char4 src2_data_2 = (char4)(src2.s8, src2.s9, src2.sA, src2.sB); 
+
+        char4 tmp_data_0 = src1_data_0 | src2_data_0;
+        char4 tmp_data_1 = src1_data_1 | src2_data_1;
+        char4 tmp_data_2 = src1_data_2 | src2_data_2;
+
+       *((__global char4 *)((__global char *)dst + dst_index + 0))= tmp_data_0;
+       *((__global char4 *)((__global char *)dst + dst_index + 4))= tmp_data_1;
+       *((__global char4 *)((__global char *)dst + dst_index + 8))= tmp_data_2;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_or_C3_D6 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          short16 src2, int rows, int cols, int dst_step1)
+                                  
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 24) + src1_offset); 
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 24));
+
+        short4 src1_data_0 = *((__global short4 *)((__global char *)src1 + src1_index + 0 ));
+        short4 src1_data_1 = *((__global short4 *)((__global char *)src1 + src1_index + 8 ));
+        short4 src1_data_2 = *((__global short4 *)((__global char *)src1 + src1_index + 16));
+                                               
+        short4 src2_data_0 = (short4)(src2.s0, src2.s1, src2.s2, src2.s3);
+        short4 src2_data_1 = (short4)(src2.s4, src2.s5, src2.s6, src2.s7);
+        short4 src2_data_2 = (short4)(src2.s8, src2.s9, src2.sa, src2.sb);
+
+        short4 data_0 = *((__global short4 *)((__global char *)dst + dst_index + 0 ));
+        short4 data_1 = *((__global short4 *)((__global char *)dst + dst_index + 8 ));
+        short4 data_2 = *((__global short4 *)((__global char *)dst + dst_index + 16));
+
+        short4 tmp_data_0 = src1_data_0 | src2_data_0;
+        short4 tmp_data_1 = src1_data_1 | src2_data_1;
+        short4 tmp_data_2 = src1_data_2 | src2_data_2;
+        
+       *((__global short4 *)((__global char *)dst + dst_index + 0 ))= tmp_data_0;
+       *((__global short4 *)((__global char *)dst + dst_index + 8 ))= tmp_data_1;
+       *((__global short4 *)((__global char *)dst + dst_index + 16))= tmp_data_2;
+    }
+}
+#endif
+__kernel void arithm_s_bitwise_or_C4_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                  __global   uchar *dst,  int dst_step,  int dst_offset,
+                                  uchar4 src2, int rows, int cols, int dst_step1)
+                                  
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar4 src_data1 = *((__global uchar4 *)(src1 + src1_index));
+
+        uchar4 data = src_data1 | src2;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_or_C4_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char4 src2, int rows, int cols, int dst_step1)
+                                  
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        char4 src_data1 = *((__global char4 *)(src1 + src1_index));
+
+        char4 data = src_data1 | src2;
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_bitwise_or_C4_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                  __global   ushort *dst,  int dst_step,  int dst_offset,
+                                  ushort4 src2, int rows, int cols, int dst_step1)
+                                  
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        ushort4 src_data1 = *((__global ushort4 *)((__global char *)src1 + src1_index));
+
+        ushort4 data = src_data1 | src2;
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_or_C4_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                  __global   short *dst,  int dst_step,  int dst_offset,
+                                  short4 src2, int rows, int cols, int dst_step1)
+                                  
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        short4 src_data1 = *((__global short4 *)((__global char *)src1 + src1_index));
+
+        short4 data = src_data1 | src2;
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_or_C4_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                  __global   int *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+                                  
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        int4 src_data1 = *((__global int4 *)((__global char *)src1 + src1_index));
+
+        int4 data = src_data1 | src2;
+
+        *((__global int4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_or_C4_D5 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char16 src2, int rows, int cols, int dst_step1)
+                                  
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        char16 src_data1 = *((__global char16 *)((__global char *)src1 + src1_index));
+        char16 src_data2 = (char16)(src2.s0, src2.s1, src2.s2, src2.s3, src2.s4, src2.s5, src2.s6, src2.s7,
+                                    src2.s8, src2.s9, src2.sa, src2.sb, src2.sc, src2.sd, src2.se, src2.sf);
+
+        char16 data = src_data1 | src_data2;
+
+        *((__global char16 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_or_C4_D6 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          short16 src2, int rows, int cols, int dst_step1)
+                                  
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 5) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 5) + dst_offset);
+
+        short4 src1_data_0 = *((__global short4 *)((__global char *)src1 + src1_index + 0));
+        short4 src1_data_1 = *((__global short4 *)((__global char *)src1 + src1_index + 8));
+        short4 src1_data_2 = *((__global short4 *)((__global char *)src1 + src1_index + 16));
+        short4 src1_data_3 = *((__global short4 *)((__global char *)src1 + src1_index + 24));
+
+        short4 src2_data_0 = (short4)(src2.s0, src2.s1, src2.s2, src2.s3);
+        short4 src2_data_1 = (short4)(src2.s4, src2.s5, src2.s6, src2.s7);
+        short4 src2_data_2 = (short4)(src2.s8, src2.s9, src2.sa, src2.sb);
+        short4 src2_data_3 = (short4)(src2.sc, src2.sd, src2.se, src2.sf);
+        
+        short4 tmp_data_0 = src1_data_0 | src2_data_0;
+        short4 tmp_data_1 = src1_data_1 | src2_data_1;
+        short4 tmp_data_2 = src1_data_2 | src2_data_2;
+        short4 tmp_data_3 = src1_data_3 | src2_data_3;
+        
+       *((__global short4 *)((__global char *)dst + dst_index + 0 ))= tmp_data_0;
+       *((__global short4 *)((__global char *)dst + dst_index + 8 ))= tmp_data_1;
+       *((__global short4 *)((__global char *)dst + dst_index + 16))= tmp_data_2;
+       *((__global short4 *)((__global char *)dst + dst_index + 24))= tmp_data_3;
+       
+    }
+}
+#endif
+
diff --git a/modules/ocl/src/kernels/arithm_bitwise_or_scalar_mask.cl b/modules/ocl/src/kernels/arithm_bitwise_or_scalar_mask.cl
new file mode 100644 (file)
index 0000000..ca63785
--- /dev/null
@@ -0,0 +1,1081 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jiang Liyuan, jlyuan001.good@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 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
+// 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*/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////BITWISE_OR////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+/**************************************bitwise_or with scalar with mask**************************************/
+__kernel void arithm_s_bitwise_or_with_mask_C1_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                            __global   uchar *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            uchar4 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = (uchar4)(src2.x, src2.x, src2.x, src2.x);
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = src1_data | src2_data;
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((mask_data.z) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((mask_data.w) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_or_with_mask_C1_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                            __global   char *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            char4 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+        char4 src2_data = (char4)(src2.x, src2.x, src2.x, src2.x);
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        char4 data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = src1_data | src2_data;
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((mask_data.z) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((mask_data.w) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_bitwise_or_with_mask_C1_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                            __global   ushort *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar  *mask, int mask_step, int mask_offset,
+                                            ushort4 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        ushort2 src1_data = vload2(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort2 src2_data = (ushort2)(src2.x, src2.x);
+        uchar2  mask_data = vload2(0, mask + mask_index);
+
+        ushort2 data = *((__global ushort2 *)((__global uchar *)dst + dst_index));
+        ushort2 tmp_data = src1_data | src2_data;
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.y : data.y;
+
+        *((__global ushort2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_or_with_mask_C1_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                            __global   short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            short4 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        short2 src1_data = vload2(0, (__global short *)((__global char *)src1 + src1_index));
+        short2 src2_data = (short2)(src2.x, src2.x);
+        uchar2  mask_data = vload2(0, mask + mask_index);
+
+        short2 data = *((__global short2 *)((__global uchar *)dst + dst_index));
+        short2 tmp_data = src1_data | src2_data;
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.y : data.y;
+
+        *((__global short2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_or_with_mask_C1_D4 (__global   int   *src1, int src1_step, int src1_offset,
+                                            __global   int   *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int src_data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int src_data2 = src2.x;
+        int dst_data  = *((__global int *)((__global char *)dst  + dst_index));
+
+        int data = src_data1 | src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global int *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_bitwise_or_with_mask_C1_D5 (__global   char   *src1, int src1_step, int src1_offset,
+                                            __global   char   *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            char16 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char4 src_data1 = *((__global char4 *)((__global char *)src1 + src1_index));
+        char4 src_data2 = (char4)(src2.s0, src2.s1, src2.s2, src2.s3);
+        char4 dst_data  = *((__global char4 *)((__global char *)dst  + dst_index));
+
+        char4 data = src_data1 | src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_or_with_mask_C1_D6 (__global short *src1, int src1_step, int src1_offset,
+                                            __global short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            short16 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short4 src1_data = *((__global short4 *)((__global char *)src1 + src1_index));
+        short4 src2_data = (short4)(src2.s0, src2.s1, src2.s2, src2.s3);
+        short4 dst_data  = *((__global short4 *)((__global char *)dst  + dst_index));
+
+        short4 data = src1_data | src2_data;
+        data = mask_data ? data : dst_data; 
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+__kernel void arithm_s_bitwise_or_with_mask_C2_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                            __global   uchar *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            uchar4 src2, int rows, int cols, int dst_step1)
+                                           
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = (uchar4)(src2.x, src2.y, src2.x, src2.y);
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = src1_data | src2_data;
+
+        data.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.xy : data.xy;
+        data.zw = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.zw : data.zw;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_or_with_mask_C2_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                            __global   char *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            char4 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+        char4 src2_data = (char4)(src2.x, src2.y, src2.x, src2.y);
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        char4 data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = src1_data | src2_data;
+
+        data.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.xy : data.xy;
+        data.zw = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.zw : data.zw;
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_bitwise_or_with_mask_C2_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                            __global   ushort *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            ushort4 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        ushort2 src_data1 = *((__global ushort2 *)((__global char *)src1 + src1_index));
+        ushort2 src_data2 = (ushort2)(src2.x, src2.y);
+        ushort2 dst_data  = *((__global ushort2 *)((__global char *)dst  + dst_index));
+
+        ushort2 data = src_data1 | src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global ushort2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_or_with_mask_C2_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                            __global   short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            short4 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short2 src_data1 = *((__global short2 *)((__global char *)src1 + src1_index));
+        short2 src_data2 = (short2)(src2.x, src2.y);
+        short2 dst_data  = *((__global short2 *)((__global char *)dst  + dst_index));
+
+        short2 data = src_data1 | src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global short2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_or_with_mask_C2_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                            __global   int *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int2 src_data1 = *((__global int2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = (int2)(src2.x, src2.y);
+        int2 dst_data  = *((__global int2 *)((__global char *)dst  + dst_index));
+
+        int2 data = src_data1 | src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global int2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_or_with_mask_C2_D5 (__global   char *src1, int src1_step, int src1_offset,
+                                            __global   char *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            char16 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char8 src_data1 = *((__global char8 *)((__global char *)src1 + src1_index));
+        char8 src_data2 = (char8)(src2.s0, src2.s1, src2.s2, src2.s3, src2.s4, src2.s5, src2.s6, src2.s7);
+        char8 dst_data = *((__global char8 *)((__global char *)dst  + dst_index));
+             char8 data = src_data1 | src_data2;
+        data = mask_data ? data : dst_data; 
+        *((__global char8 *)((__global char *)dst + dst_index)) = data;
+
+      }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_or_with_mask_C2_D6 (__global   char *src1, int src1_step, int src1_offset,
+                                            __global   char *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            short16 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short8 src1_data = *((__global short8 *)((__global char *)src1 + src1_index));
+        short8 src2_data = (short8)(src2.s0, src2.s1, src2.s2, src2.s3, src2.s4, src2.s5, src2.s6, src2.s7);
+        short8 dst_data = *((__global short8 *)((__global char *)dst  + dst_index));
+
+        short8 data = src1_data | src2_data;
+        data = mask_data ? data : dst_data; 
+
+        *((__global short8 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+__kernel void arithm_s_bitwise_or_with_mask_C3_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                            __global   uchar *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            uchar4 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        uchar4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        uchar4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        uchar4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        uchar4 src2_data_0 = (uchar4)(src2.x, src2.y, src2.z, src2.x); 
+        uchar4 src2_data_1 = (uchar4)(src2.y, src2.z, src2.x, src2.y);
+        uchar4 src2_data_2 = (uchar4)(src2.z, src2.x, src2.y, src2.z); 
+
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        uchar4 data_0 = *((__global uchar4 *)(dst + dst_index + 0));
+        uchar4 data_1 = *((__global uchar4 *)(dst + dst_index + 4));
+        uchar4 data_2 = *((__global uchar4 *)(dst + dst_index + 8));
+
+        uchar4 tmp_data_0 = src1_data_0 | src2_data_0;
+        uchar4 tmp_data_1 = src1_data_1 | src2_data_1;
+        uchar4 tmp_data_2 = src1_data_2 | src2_data_2;
+
+        data_0.xyz = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((mask_data.w) && (dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global uchar4 *)(dst + dst_index + 0)) = data_0;
+        *((__global uchar4 *)(dst + dst_index + 4)) = data_1;
+        *((__global uchar4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_or_with_mask_C3_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                            __global   char *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            char4 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        char4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        char4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        char4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        char4 src2_data_0 = (char4)(src2.x, src2.y, src2.z, src2.x); 
+        char4 src2_data_1 = (char4)(src2.y, src2.z, src2.x, src2.y);
+        char4 src2_data_2 = (char4)(src2.z, src2.x, src2.y, src2.z); 
+
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        char4 data_0 = *((__global char4 *)(dst + dst_index + 0));
+        char4 data_1 = *((__global char4 *)(dst + dst_index + 4));
+        char4 data_2 = *((__global char4 *)(dst + dst_index + 8));
+
+        char4 tmp_data_0 = src1_data_0 | src2_data_0;
+        char4 tmp_data_1 = src1_data_1 | src2_data_1;
+        char4 tmp_data_2 = src1_data_2 | src2_data_2;
+
+        data_0.xyz = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((mask_data.w) && (dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global char4 *)(dst + dst_index + 0)) = data_0;
+        *((__global char4 *)(dst + dst_index + 4)) = data_1;
+        *((__global char4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+
+__kernel void arithm_s_bitwise_or_with_mask_C3_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                            __global   ushort *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            ushort4 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        ushort2 src1_data_0 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 0));
+        ushort2 src1_data_1 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 4));
+        ushort2 src1_data_2 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 8));
+
+        ushort2 src2_data_0 = (ushort2)(src2.x, src2.y);
+        ushort2 src2_data_1 = (ushort2)(src2.z, src2.x);
+        ushort2 src2_data_2 = (ushort2)(src2.y, src2.z);
+
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        ushort2 data_0 = *((__global ushort2 *)((__global char *)dst + dst_index + 0));
+        ushort2 data_1 = *((__global ushort2 *)((__global char *)dst + dst_index + 4));
+        ushort2 data_2 = *((__global ushort2 *)((__global char *)dst + dst_index + 8));
+
+        ushort2 tmp_data_0 = src1_data_0 | src2_data_0;
+        ushort2 tmp_data_1 = src1_data_1 | src2_data_1;
+        ushort2 tmp_data_2 = src1_data_2 | src2_data_2;
+
+        data_0.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global ushort2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_bitwise_or_with_mask_C3_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                            __global   short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            short4 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        short2 src1_data_0 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 0));
+        short2 src1_data_1 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 4));
+        short2 src1_data_2 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 8));
+
+        short2 src2_data_0 = (short2)(src2.x, src2.y);
+        short2 src2_data_1 = (short2)(src2.z, src2.x);
+        short2 src2_data_2 = (short2)(src2.y, src2.z);
+
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        short2 data_0 = *((__global short2 *)((__global char *)dst + dst_index + 0));
+        short2 data_1 = *((__global short2 *)((__global char *)dst + dst_index + 4));
+        short2 data_2 = *((__global short2 *)((__global char *)dst + dst_index + 8));
+
+        short2 tmp_data_0 = src1_data_0 | src2_data_0;
+        short2 tmp_data_1 = src1_data_1 | src2_data_1;
+        short2 tmp_data_2 = src1_data_2 | src2_data_2;
+
+        data_0.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global short2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global short2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global short2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_bitwise_or_with_mask_C3_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                            __global   int *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        int src1_data_0 = *((__global int *)((__global char *)src1 + src1_index + 0));
+        int src1_data_1 = *((__global int *)((__global char *)src1 + src1_index + 4));
+        int src1_data_2 = *((__global int *)((__global char *)src1 + src1_index + 8));
+
+        int src2_data_0 = src2.x;
+        int src2_data_1 = src2.y;
+        int src2_data_2 = src2.z;
+
+        uchar mask_data = * (mask + mask_index);
+
+        int data_0 = *((__global int *)((__global char *)dst + dst_index + 0));
+        int data_1 = *((__global int *)((__global char *)dst + dst_index + 4));
+        int data_2 = *((__global int *)((__global char *)dst + dst_index + 8));
+
+        int tmp_data_0 = src1_data_0 | src2_data_0;
+        int tmp_data_1 = src1_data_1 | src2_data_1;
+        int tmp_data_2 = src1_data_2 | src2_data_2;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global int *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global int *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global int *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_bitwise_or_with_mask_C3_D5 (__global   char *src1, int src1_step, int src1_offset,
+                                            __global   char *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            char16 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        char4 src1_data_0 = *((__global char4 *)((__global char *)src1 + src1_index + 0));
+        char4 src1_data_1 = *((__global char4 *)((__global char *)src1 + src1_index + 4));
+        char4 src1_data_2 = *((__global char4 *)((__global char *)src1 + src1_index + 8));
+                                             
+        char4 src2_data_0 = (char4)(src2.s0, src2.s1, src2.s2, src2.s3); 
+        char4 src2_data_1 = (char4)(src2.s4, src2.s5, src2.s6, src2.s7);
+        char4 src2_data_2 = (char4)(src2.s8, src2.s9, src2.sA, src2.sB); 
+                
+        uchar mask_data = * (mask + mask_index);
+
+        char4 data_0 = *((__global char4 *)((__global char *)dst + dst_index + 0));
+        char4 data_1 = *((__global char4 *)((__global char *)dst + dst_index + 4));
+        char4 data_2 = *((__global char4 *)((__global char *)dst + dst_index + 8));
+
+        char4 tmp_data_0 = src1_data_0 | src2_data_0;
+        char4 tmp_data_1 = src1_data_1 | src2_data_1;
+        char4 tmp_data_2 = src1_data_2 | src2_data_2;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global char4 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global char4 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global char4 *)((__global char *)dst + dst_index + 8))= data_2;
+
+       }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_or_with_mask_C3_D6 (__global short *src1, int src1_step, int src1_offset,
+                                                    __global short *dst,  int dst_step,  int dst_offset,
+                                                    __global uchar  *mask, int mask_step, int mask_offset,
+                                                    short16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 24) + src1_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 24));
+
+        short4 src1_data_0 = *((__global short4 *)((__global char *)src1 + src1_index + 0 ));
+        short4 src1_data_1 = *((__global short4 *)((__global char *)src1 + src1_index + 8 ));
+        short4 src1_data_2 = *((__global short4 *)((__global char *)src1 + src1_index + 16));
+                                               
+        short4 src2_data_0 = (short4)(src2.s0, src2.s1, src2.s2, src2.s3);
+        short4 src2_data_1 = (short4)(src2.s4, src2.s5, src2.s6, src2.s7);
+        short4 src2_data_2 = (short4)(src2.s8, src2.s9, src2.sa, src2.sb);
+        
+        uchar mask_data = * (mask + mask_index);
+
+        short4 data_0 = *((__global short4 *)((__global char *)dst + dst_index + 0 ));
+        short4 data_1 = *((__global short4 *)((__global char *)dst + dst_index + 8 ));
+        short4 data_2 = *((__global short4 *)((__global char *)dst + dst_index + 16));
+
+        short4 tmp_data_0 = src1_data_0 | src2_data_0;
+        short4 tmp_data_1 = src1_data_1 | src2_data_1;
+        short4 tmp_data_2 = src1_data_2 | src2_data_2;
+        
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global short4 *)((__global char *)dst + dst_index + 0 ))= data_0;
+       *((__global short4 *)((__global char *)dst + dst_index + 8 ))= data_1;
+       *((__global short4 *)((__global char *)dst + dst_index + 16))= data_2;
+    }
+}
+#endif
+__kernel void arithm_s_bitwise_or_with_mask_C4_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                            __global   uchar *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            uchar4 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        uchar4 src_data1 = *((__global uchar4 *)(src1 + src1_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+
+        uchar4 data = src_data1 | src2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_or_with_mask_C4_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                            __global   char *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            char4 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char4 src_data1 = *((__global char4 *)(src1 + src1_index));
+        char4 dst_data  = *((__global char4 *)(dst  + dst_index));
+
+        char4 data = src_data1 | src2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_bitwise_or_with_mask_C4_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                            __global   ushort *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            ushort4 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        ushort4 src_data1 = *((__global ushort4 *)((__global char *)src1 + src1_index));
+        ushort4 dst_data  = *((__global ushort4 *)((__global char *)dst  + dst_index));
+
+        ushort4 data = src_data1 | src2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_or_with_mask_C4_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                            __global   short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            short4 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short4 src_data1 = *((__global short4 *)((__global char *)src1 + src1_index));
+        short4 dst_data  = *((__global short4 *)((__global char *)dst  + dst_index));
+
+        short4 data = src_data1 | src2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_or_with_mask_C4_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                            __global   int *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int4 src_data1 = *((__global int4 *)((__global char *)src1 + src1_index));
+        int4 dst_data  = *((__global int4 *)((__global char *)dst  + dst_index));
+
+        int4 data = src_data1 | src2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global int4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_or_with_mask_C4_D5 (__global   char *src1, int src1_step, int src1_offset,
+                                            __global   char *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            char16 src2, int rows, int cols, int dst_step1)
+                                            
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char16 src_data1 = *((__global char16 *)((__global char *)src1 + src1_index));
+        char16 src_data2 = (char16)(src2.s0, src2.s1, src2.s2, src2.s3, src2.s4, src2.s5, src2.s6, src2.s7,
+                                    src2.s8, src2.s9, src2.sa, src2.sb, src2.sc, src2.sd, src2.se, src2.sf);
+        char16 dst_data  = *((__global char16 *)((__global char *)dst  + dst_index));
+
+        char16 data = src_data1 | src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char16 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_or_with_mask_C4_D6 (__global short *src1, int src1_step, int src1_offset,
+                                                    __global short *dst,  int dst_step,  int dst_offset,
+                                                    __global uchar *mask, int mask_step, int mask_offset,
+                                                    short16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 5) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 5) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short4 src1_data_0 = *((__global short4 *)((__global char *)src1 + src1_index + 0));
+        short4 src1_data_1 = *((__global short4 *)((__global char *)src1 + src1_index + 8));
+        short4 src1_data_2 = *((__global short4 *)((__global char *)src1 + src1_index + 16));
+        short4 src1_data_3 = *((__global short4 *)((__global char *)src1 + src1_index + 24));
+
+        short4 src2_data_0 = (short4)(src2.s0, src2.s1, src2.s2, src2.s3);
+        short4 src2_data_1 = (short4)(src2.s4, src2.s5, src2.s6, src2.s7);
+        short4 src2_data_2 = (short4)(src2.s8, src2.s9, src2.sa, src2.sb);
+        short4 src2_data_3 = (short4)(src2.sc, src2.sd, src2.se, src2.sf);
+        
+        short4 dst_data_0  = *((__global short4 *)((__global char *)dst  + dst_index + 0));
+        short4 dst_data_1  = *((__global short4 *)((__global char *)dst  + dst_index + 8));
+        short4 dst_data_2  = *((__global short4 *)((__global char *)dst  + dst_index + 16));
+        short4 dst_data_3  = *((__global short4 *)((__global char *)dst  + dst_index + 24));
+
+        short4 data_0 = src1_data_0 | src2_data_0;
+        short4 data_1 = src1_data_1 | src2_data_1;
+        short4 data_2 = src1_data_2 | src2_data_2;
+        short4 data_3 = src1_data_3 | src2_data_3;
+             
+        data_0 = mask_data ? data_0 : dst_data_0; 
+        data_1 = mask_data ? data_1 : dst_data_1; 
+        data_2 = mask_data ? data_2 : dst_data_2; 
+        data_3 = mask_data ? data_3 : dst_data_3;
+
+        *((__global short4 *)((__global char *)dst + dst_index + 0)) = data_0;
+        *((__global short4 *)((__global char *)dst + dst_index + 8)) = data_1;
+        *((__global short4 *)((__global char *)dst + dst_index + 16)) = data_2;
+        *((__global short4 *)((__global char *)dst + dst_index + 24)) = data_3;
+    }
+}
+#endif
+
diff --git a/modules/ocl/src/kernels/arithm_bitwise_xor.cl b/modules/ocl/src/kernels/arithm_bitwise_xor.cl
new file mode 100644 (file)
index 0000000..e2de843
--- /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.
+//
+//
+//                           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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jiang Liyuan, jlyuan001.good@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 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
+// 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*/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////BITWISE_XOR////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+/**************************************bitwise_xor without mask**************************************/
+__kernel void arithm_bitwise_xor_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                             __global uchar *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = src1_data ^ src2_data;
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+
+__kernel void arithm_bitwise_xor_D1 (__global char *src1, int src1_step, int src1_offset,
+                             __global char *src2, int src2_step, int src2_offset,
+                             __global char *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+        char4 src2_data = vload4(0, src2 + src2_index);
+
+        char4 dst_data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = src1_data ^ src2_data;
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global char4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+
+__kernel void arithm_bitwise_xor_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                             __global ushort *src2, int src2_step, int src2_offset,
+                             __global ushort *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        ushort4 src1_data = vload4(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort4 src2_data = vload4(0, (__global ushort *)((__global char *)src2 + src2_index));
+
+        ushort4 dst_data = *((__global ushort4 *)((__global char *)dst + dst_index));
+        ushort4 tmp_data = src1_data ^ src2_data;
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_xor_D3 (__global short *src1, int src1_step, int src1_offset,
+                             __global short *src2, int src2_step, int src2_offset,
+                             __global short *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        short4 src1_data = vload4(0, (__global short *)((__global char *)src1 + src1_index));
+        short4 src2_data = vload4(0, (__global short *)((__global char *)src2 + src2_index));
+
+        short4 dst_data = *((__global short4 *)((__global char *)dst + dst_index));
+        short4 tmp_data = src1_data ^ src2_data;
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_xor_D4 (__global int *src1, int src1_step, int src1_offset,
+                             __global int *src2, int src2_step, int src2_offset,
+                             __global int *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        int data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int data2 = *((__global int *)((__global char *)src2 + src2_index));
+        int tmp  = data1 ^ data2;
+
+        *((__global int *)((__global char *)dst + dst_index)) = tmp;
+    }
+}
+
+__kernel void arithm_bitwise_xor_D5 (__global char *src1, int src1_step, int src1_offset,
+                             __global char *src2, int src2_step, int src2_offset,
+                             __global char *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        char4 data1 = *((__global char4 *)((__global char *)src1 + src1_index));
+        char4 data2 = *((__global char4 *)((__global char *)src2 + src2_index));
+        char4 tmp = data1 ^ data2;
+
+        *((__global char4 *)((__global char *)dst + dst_index)) = tmp;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_bitwise_xor_D6 (__global char *src1, int src1_step, int src1_offset,
+                             __global char *src2, int src2_step, int src2_offset,
+                             __global char *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        char8 data1 = *((__global char8 *)((__global char *)src1 + src1_index));
+        char8 data2 = *((__global char8 *)((__global char *)src2 + src2_index));
+
+        *((__global char8 *)((__global char *)dst + dst_index)) = data1 ^ data2;
+    }
+}
+#endif
+
diff --git a/modules/ocl/src/kernels/arithm_bitwise_xor_mask.cl b/modules/ocl/src/kernels/arithm_bitwise_xor_mask.cl
new file mode 100644 (file)
index 0000000..7abedf2
--- /dev/null
@@ -0,0 +1,1138 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jiang Liyuan, jlyuan001.good@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*/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////BITWISE_XOR////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+/**************************************bitwise_xor with mask**************************************/
+__kernel void arithm_bitwise_xor_with_mask_C1_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                          __global uchar *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global uchar *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = src1_data ^ src2_data;
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((mask_data.z) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((mask_data.w) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_xor_with_mask_C1_D1 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+        char4 src2_data = vload4(0, src2 + src2_index);
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        char4 data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = src1_data ^ src2_data;
+
+        data.x = convert_char((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = convert_char((mask_data.y) && (dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = convert_char((mask_data.z) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = convert_char((mask_data.w) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_xor_with_mask_C1_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                                          __global ushort *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global ushort *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        ushort2 src1_data = vload2(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort2 src2_data = vload2(0, (__global ushort *)((__global char *)src2 + src2_index));
+        uchar2  mask_data = vload2(0, mask + mask_index);
+
+        ushort2 data = *((__global ushort2 *)((__global uchar *)dst + dst_index));
+        ushort2 tmp_data = src1_data ^ src2_data;
+
+        data.x = convert_ushort((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = convert_ushort((mask_data.y) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : data.y;
+
+        *((__global ushort2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_xor_with_mask_C1_D3 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        short2 src1_data = vload2(0, (__global short *)((__global char *)src1 + src1_index));
+        short2 src2_data = vload2(0, (__global short *)((__global char *)src2 + src2_index));
+        uchar2  mask_data = vload2(0, mask + mask_index);
+
+       short2 data = *((__global short2 *)((__global uchar *)dst + dst_index));
+       short2 tmp_data = src1_data ^ src2_data;
+
+        data.x = convert_short((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = convert_short((mask_data.y) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : data.y;
+
+        *((__global short2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_xor_with_mask_C1_D4 (__global int   *src1, int src1_step, int src1_offset,
+                                          __global int   *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global int   *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int src_data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int src_data2 = *((__global int *)((__global char *)src2 + src2_index));
+        int dst_data  = *((__global int *)((__global char *)dst  + dst_index));
+
+        int data = src_data1 ^ src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global int *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+
+
+__kernel void arithm_bitwise_xor_with_mask_C1_D5 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char4 src_data1 = *((__global char4 *)((__global char *)src1 + src1_index));
+        char4 src_data2 = *((__global char4 *)((__global char *)src2 + src2_index));
+        char4 dst_data  = *((__global char4 *)((__global char *)dst  + dst_index));
+
+        char4 data = src_data1 ^ src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_bitwise_xor_with_mask_C1_D6 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char8 src_data1 = *((__global char8 *)((__global char *)src1 + src1_index));
+        char8 src_data2 = *((__global char8 *)((__global char *)src2 + src2_index));
+        char8 dst_data  = *((__global char8 *)((__global char *)dst  + dst_index));
+
+        char8 data = src_data1 ^ src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char8 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+
+
+
+
+__kernel void arithm_bitwise_xor_with_mask_C2_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                          __global uchar *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global uchar *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = src1_data ^ src2_data;
+
+        data.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.xy : data.xy;
+        data.zw = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.zw : data.zw;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_bitwise_xor_with_mask_C2_D1 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+        char4 src2_data = vload4(0, src2 + src2_index);
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        char4 data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = src1_data ^ src2_data;
+
+        data.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.xy : data.xy;
+        data.zw = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.zw : data.zw;
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_bitwise_xor_with_mask_C2_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                                          __global ushort *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global ushort *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        ushort2 src_data1 = *((__global ushort2 *)((__global char *)src1 + src1_index));
+        ushort2 src_data2 = *((__global ushort2 *)((__global char *)src2 + src2_index));
+        ushort2 dst_data  = *((__global ushort2 *)((__global char *)dst  + dst_index));
+
+        ushort2 data = src_data1 ^ src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global ushort2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_bitwise_xor_with_mask_C2_D3 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short2 src_data1 = *((__global short2 *)((__global char *)src1 + src1_index));
+        short2 src_data2 = *((__global short2 *)((__global char *)src2 + src2_index));
+        short2 dst_data  = *((__global short2 *)((__global char *)dst  + dst_index));
+
+        short2 data = src_data1 ^ src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global short2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_bitwise_xor_with_mask_C2_D4 (__global int   *src1, int src1_step, int src1_offset,
+                                          __global int   *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global int    *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int2 src_data1 = *((__global int2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = *((__global int2 *)((__global char *)src2 + src2_index));
+        int2 dst_data  = *((__global int2 *)((__global char *)dst  + dst_index));
+
+        int2 data = src_data1 ^ src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global int2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_bitwise_xor_with_mask_C2_D5 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char8 src_data1 = *((__global char8 *)((__global char *)src1 + src1_index));
+        char8 src_data2 = *((__global char8 *)((__global char *)src2 + src2_index));
+        char8 dst_data  = *((__global char8 *)((__global char *)dst  + dst_index));
+
+        char8 data = src_data1 ^ src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char8 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_bitwise_xor_with_mask_C2_D6 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 4) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char16 src_data1 = *((__global char16 *)((__global char *)src1 + src1_index));
+        char16 src_data2 = *((__global char16 *)((__global char *)src2 + src2_index));
+        char16 dst_data  = *((__global char16 *)((__global char *)dst  + dst_index));
+
+        char16 data = src_data1 ^ src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char16 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+
+
+
+__kernel void arithm_bitwise_xor_with_mask_C3_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                          __global uchar *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global uchar *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+        int src2_index = mad24(y, src2_step, (x * 3) + src2_offset - (dst_align * 3)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        uchar4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        uchar4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        uchar4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        uchar4 src2_data_0 = vload4(0, src2 + src2_index + 0);
+        uchar4 src2_data_1 = vload4(0, src2 + src2_index + 4);
+        uchar4 src2_data_2 = vload4(0, src2 + src2_index + 8);
+
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        uchar4 data_0 = *((__global uchar4 *)(dst + dst_index + 0));
+        uchar4 data_1 = *((__global uchar4 *)(dst + dst_index + 4));
+        uchar4 data_2 = *((__global uchar4 *)(dst + dst_index + 8));
+
+        uchar4 tmp_data_0 =  src1_data_0 ^ src2_data_0;
+        uchar4 tmp_data_1 =  src1_data_1 ^ src2_data_1;
+        uchar4 tmp_data_2 =  src1_data_2 ^ src2_data_2;
+
+        data_0.xyz = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((mask_data.w) && (dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global uchar4 *)(dst + dst_index + 0)) = data_0;
+        *((__global uchar4 *)(dst + dst_index + 4)) = data_1;
+        *((__global uchar4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+
+
+__kernel void arithm_bitwise_xor_with_mask_C3_D1 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+        int src2_index = mad24(y, src2_step, (x * 3) + src2_offset - (dst_align * 3)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        char4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        char4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        char4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        char4 src2_data_0 = vload4(0, src2 + src2_index + 0);
+        char4 src2_data_1 = vload4(0, src2 + src2_index + 4);
+        char4 src2_data_2 = vload4(0, src2 + src2_index + 8);
+
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        char4 data_0 = *((__global char4 *)(dst + dst_index + 0));
+        char4 data_1 = *((__global char4 *)(dst + dst_index + 4));
+        char4 data_2 = *((__global char4 *)(dst + dst_index + 8));
+
+        char4 tmp_data_0 =  src1_data_0 ^ src2_data_0;
+        char4 tmp_data_1 =  src1_data_1 ^ src2_data_1;
+        char4 tmp_data_2 =  src1_data_2 ^ src2_data_2;
+
+        data_0.xyz = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((mask_data.w) && (dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global char4 *)(dst + dst_index + 0)) = data_0;
+        *((__global char4 *)(dst + dst_index + 4)) = data_1;
+        *((__global char4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+
+__kernel void arithm_bitwise_xor_with_mask_C3_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                                          __global ushort *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global ushort *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+        int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        ushort2 src1_data_0 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 0));
+        ushort2 src1_data_1 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 4));
+        ushort2 src1_data_2 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 8));
+
+        ushort2 src2_data_0 = vload2(0, (__global ushort *)((__global char *)src2 + src2_index + 0));
+        ushort2 src2_data_1 = vload2(0, (__global ushort *)((__global char *)src2 + src2_index + 4));
+        ushort2 src2_data_2 = vload2(0, (__global ushort *)((__global char *)src2 + src2_index + 8));
+
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        ushort2 data_0 = *((__global ushort2 *)((__global char *)dst + dst_index + 0));
+        ushort2 data_1 = *((__global ushort2 *)((__global char *)dst + dst_index + 4));
+        ushort2 data_2 = *((__global ushort2 *)((__global char *)dst + dst_index + 8));
+
+        ushort2 tmp_data_0 =  src1_data_0 ^ src2_data_0 ;
+        ushort2 tmp_data_1 =  src1_data_1 ^ src2_data_1 ;
+        ushort2 tmp_data_2 =  src1_data_2 ^ src2_data_2 ;
+
+        data_0.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global ushort2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_bitwise_xor_with_mask_C3_D3 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+        int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        short2 src1_data_0 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 0));
+        short2 src1_data_1 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 4));
+        short2 src1_data_2 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 8));
+
+        short2 src2_data_0 = vload2(0, (__global short *)((__global char *)src2 + src2_index + 0));
+        short2 src2_data_1 = vload2(0, (__global short *)((__global char *)src2 + src2_index + 4));
+        short2 src2_data_2 = vload2(0, (__global short *)((__global char *)src2 + src2_index + 8));
+
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        short2 data_0 = *((__global short2 *)((__global char *)dst + dst_index + 0));
+        short2 data_1 = *((__global short2 *)((__global char *)dst + dst_index + 4));
+        short2 data_2 = *((__global short2 *)((__global char *)dst + dst_index + 8));
+
+        short2 tmp_data_0 =  src1_data_0 ^ src2_data_0 ;
+        short2 tmp_data_1 =  src1_data_1 ^ src2_data_1 ;
+        short2 tmp_data_2 =  src1_data_2 ^ src2_data_2 ;
+
+        data_0.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global short2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global short2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global short2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_bitwise_xor_with_mask_C3_D4 (__global int   *src1, int src1_step, int src1_offset,
+                                          __global int   *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global int   *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int src2_index = mad24(y, src2_step, (x * 12) + src2_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        int src1_data_0 = *((__global int *)((__global char *)src1 + src1_index + 0));
+        int src1_data_1 = *((__global int *)((__global char *)src1 + src1_index + 4));
+        int src1_data_2 = *((__global int *)((__global char *)src1 + src1_index + 8));
+
+        int src2_data_0 = *((__global int *)((__global char *)src2 + src2_index + 0));
+        int src2_data_1 = *((__global int *)((__global char *)src2 + src2_index + 4));
+        int src2_data_2 = *((__global int *)((__global char *)src2 + src2_index + 8));
+
+        uchar mask_data = * (mask + mask_index);
+
+        int data_0 = *((__global int *)((__global char *)dst + dst_index + 0));
+        int data_1 = *((__global int *)((__global char *)dst + dst_index + 4));
+        int data_2 = *((__global int *)((__global char *)dst + dst_index + 8));
+
+        int tmp_data_0 =  src1_data_0 ^  src2_data_0 ;
+        int tmp_data_1 =  src1_data_1 ^  src2_data_1 ;
+        int tmp_data_2 =  src1_data_2 ^  src2_data_2 ;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global int *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global int *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global int *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_bitwise_xor_with_mask_C3_D5 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int src2_index = mad24(y, src2_step, (x * 12) + src2_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        char4 src1_data_0 = *((__global char4 *)((__global char *)src1 + src1_index + 0));
+        char4 src1_data_1 = *((__global char4 *)((__global char *)src1 + src1_index + 4));
+        char4 src1_data_2 = *((__global char4 *)((__global char *)src1 + src1_index + 8));
+                                             
+        char4 src2_data_0 = *((__global char4 *)((__global char *)src2 + src2_index + 0));
+        char4 src2_data_1 = *((__global char4 *)((__global char *)src2 + src2_index + 4));
+        char4 src2_data_2 = *((__global char4 *)((__global char *)src2 + src2_index + 8));
+
+        uchar mask_data = * (mask + mask_index);
+
+        char4 data_0 = *((__global char4 *)((__global char *)dst + dst_index + 0));
+        char4 data_1 = *((__global char4 *)((__global char *)dst + dst_index + 4));
+        char4 data_2 = *((__global char4 *)((__global char *)dst + dst_index + 8));
+
+        char4 tmp_data_0 = src1_data_0 ^ src2_data_0;
+        char4 tmp_data_1 = src1_data_1 ^ src2_data_1;
+        char4 tmp_data_2 = src1_data_2 ^ src2_data_2;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global char4 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global char4 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global char4 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_bitwise_xor_with_mask_C3_D6 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 24) + src1_offset); 
+        int src2_index = mad24(y, src2_step, (x * 24) + src2_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 24));
+
+        char8 src1_data_0 = *((__global char8 *)((__global char *)src1 + src1_index + 0 ));
+        char8 src1_data_1 = *((__global char8 *)((__global char *)src1 + src1_index + 8 ));
+        char8 src1_data_2 = *((__global char8 *)((__global char *)src1 + src1_index + 16));
+                                               
+        char8 src2_data_0 = *((__global char8 *)((__global char *)src2 + src2_index + 0 ));
+        char8 src2_data_1 = *((__global char8 *)((__global char *)src2 + src2_index + 8 ));
+        char8 src2_data_2 = *((__global char8 *)((__global char *)src2 + src2_index + 16));
+
+        uchar mask_data = * (mask + mask_index);
+
+        char8 data_0 = *((__global char8 *)((__global char *)dst + dst_index + 0 ));
+        char8 data_1 = *((__global char8 *)((__global char *)dst + dst_index + 8 ));
+        char8 data_2 = *((__global char8 *)((__global char *)dst + dst_index + 16));
+
+        char8 tmp_data_0 = src1_data_0 ^ src2_data_0;
+        char8 tmp_data_1 = src1_data_1 ^ src2_data_1;
+        char8 tmp_data_2 = src1_data_2 ^ src2_data_2;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global char8 *)((__global char *)dst + dst_index + 0 ))= data_0;
+       *((__global char8 *)((__global char *)dst + dst_index + 8 ))= data_1;
+       *((__global char8 *)((__global char *)dst + dst_index + 16))= data_2;
+    }
+}
+#endif
+
+
+
+__kernel void arithm_bitwise_xor_with_mask_C4_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                          __global uchar *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global uchar *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        uchar4 src_data1 = *((__global uchar4 *)(src1 + src1_index));
+        uchar4 src_data2 = *((__global uchar4 *)(src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+
+        uchar4 data = src_data1 ^ src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_bitwise_xor_with_mask_C4_D1 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char4 src_data1 = *((__global char4 *)(src1 + src1_index));
+        char4 src_data2 = *((__global char4 *)(src2 + src2_index));
+        char4 dst_data  = *((__global char4 *)(dst  + dst_index));
+
+        char4 data = src_data1 ^ src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_bitwise_xor_with_mask_C4_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                                          __global ushort *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global ushort *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        ushort4 src_data1 = *((__global ushort4 *)((__global char *)src1 + src1_index));
+        ushort4 src_data2 = *((__global ushort4 *)((__global char *)src2 + src2_index));
+        ushort4 dst_data  = *((__global ushort4 *)((__global char *)dst  + dst_index));
+
+        ushort4 data = src_data1 ^ src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_bitwise_xor_with_mask_C4_D3 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short4 src_data1 = *((__global short4 *)((__global char *)src1 + src1_index));
+        short4 src_data2 = *((__global short4 *)((__global char *)src2 + src2_index));
+        short4 dst_data  = *((__global short4 *)((__global char *)dst  + dst_index));
+
+        short4 data = src_data1 ^ src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_bitwise_xor_with_mask_C4_D4 (__global int   *src1, int src1_step, int src1_offset,
+                                          __global int   *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global int   *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 4) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int4 src_data1 = *((__global int4 *)((__global char *)src1 + src1_index));
+        int4 src_data2 = *((__global int4 *)((__global char *)src2 + src2_index));
+        int4 dst_data  = *((__global int4 *)((__global char *)dst  + dst_index));
+
+        int4 data = src_data1 ^ src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global int4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_bitwise_xor_with_mask_C4_D5 (__global char *src1, int src1_step, int src1_offset,
+                                          __global char *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global char *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 4) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char16 src_data1 = *((__global char16 *)((__global char *)src1 + src1_index));
+        char16 src_data2 = *((__global char16 *)((__global char *)src2 + src2_index));
+        char16 dst_data  = *((__global char16 *)((__global char *)dst  + dst_index));
+
+        char16 data = src_data1 ^ src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char16 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_bitwise_xor_with_mask_C4_D6 (__global char *src1, int src1_step, int src1_offset,
+                                                  __global char *src2, int src2_step, int src2_offset,
+                                                  __global uchar  *mask, int mask_step, int mask_offset,
+                                                  __global char *dst,  int dst_step,  int dst_offset,
+                                                  int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 5) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 5) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 5) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char8 src_data1_0 = *((__global char8 *)((__global char *)src1 + src1_index + 0));
+        char8 src_data1_1 = *((__global char8 *)((__global char *)src1 + src1_index + 8));
+        char8 src_data1_2 = *((__global char8 *)((__global char *)src1 + src1_index + 16));
+        char8 src_data1_3 = *((__global char8 *)((__global char *)src1 + src1_index + 24));
+
+        char8 src_data2_0 = *((__global char8 *)((__global char *)src2 + src2_index + 0));
+        char8 src_data2_1 = *((__global char8 *)((__global char *)src2 + src2_index + 8));
+        char8 src_data2_2 = *((__global char8 *)((__global char *)src2 + src2_index + 16));
+        char8 src_data2_3 = *((__global char8 *)((__global char *)src2 + src2_index + 24));
+
+        char8 dst_data_0  = *((__global char8 *)((__global char *)dst  + dst_index + 0));
+        char8 dst_data_1  = *((__global char8 *)((__global char *)dst  + dst_index + 8));
+        char8 dst_data_2  = *((__global char8 *)((__global char *)dst  + dst_index + 16));
+        char8 dst_data_3  = *((__global char8 *)((__global char *)dst  + dst_index + 24));
+
+        char8 data_0 = src_data1_0 ^ src_data2_0;
+        char8 data_1 = src_data1_1 ^ src_data2_1;
+        char8 data_2 = src_data1_2 ^ src_data2_2;
+        char8 data_3 = src_data1_3 ^ src_data2_3;
+
+        data_0 = mask_data ? data_0 : dst_data_0; 
+        data_1 = mask_data ? data_1 : dst_data_1; 
+        data_2 = mask_data ? data_2 : dst_data_2; 
+        data_3 = mask_data ? data_3 : dst_data_3; 
+
+        *((__global char8 *)((__global char *)dst + dst_index + 0)) = data_0;
+        *((__global char8 *)((__global char *)dst + dst_index + 8)) = data_1;
+        *((__global char8 *)((__global char *)dst + dst_index + 16)) = data_2;
+        *((__global char8 *)((__global char *)dst + dst_index + 24)) = data_3;
+    }
+}
+#endif
+
diff --git a/modules/ocl/src/kernels/arithm_bitwise_xor_scalar.cl b/modules/ocl/src/kernels/arithm_bitwise_xor_scalar.cl
new file mode 100644 (file)
index 0000000..d12d5ad
--- /dev/null
@@ -0,0 +1,907 @@
+////////////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jiang Liyuan, jlyuan001.good@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.
+//
+//
+#if defined (__ATI__)
+#pragma OPENCL EXTENSION cl_amd_fp64:enable
+#elif defined (__NVIDIA__)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////BITWISE_XOR////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+/**************************************xor with scalar without mask**************************************/
+__kernel void arithm_s_bitwise_xor_C1_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                  __global   uchar *dst,  int dst_step,  int dst_offset,
+                                  uchar4 src2, int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = (uchar4)(src2.x, src2.x, src2.x, src2.x);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = src1_data ^ src2_data;
+
+        data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_xor_C1_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char4 src2, int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+        char4 src2_data = (char4)(src2.x, src2.x, src2.x, src2.x);
+
+        char4 data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = src1_data ^ src2_data;
+
+        data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_bitwise_xor_C1_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                  __global   ushort *dst,  int dst_step,  int dst_offset,
+                                  ushort4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        ushort2 src1_data = vload2(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort2 src2_data = (ushort2)(src2.x, src2.x);
+
+        ushort2 data = *((__global ushort2 *)((__global uchar *)dst + dst_index));
+        ushort2 tmp_data = src1_data ^ src2_data;
+
+        data.x = (dst_index + 0 >= dst_start) ? tmp_data.x : data.x;
+        data.y = (dst_index + 2 <  dst_end  ) ? tmp_data.y : data.y;
+
+        *((__global ushort2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_xor_C1_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                  __global   short *dst,  int dst_step,  int dst_offset,
+                                  short4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        short2 src1_data = vload2(0, (__global short *)((__global char *)src1 + src1_index));
+        short2 src2_data = (short2)(src2.x, src2.x);
+        short2 data = *((__global short2 *)((__global uchar *)dst + dst_index));
+
+        short2 tmp_data = src1_data ^ src2_data;
+
+        data.x = (dst_index + 0 >= dst_start) ? tmp_data.x : data.x;
+        data.y = (dst_index + 2 <  dst_end  ) ? tmp_data.y : data.y;
+
+        *((__global short2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_xor_C1_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                  __global   int *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        int src_data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int src_data2 = src2.x;
+
+        int data = src_data1 ^ src_data2;
+
+        *((__global int *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_xor_C1_D5 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        char4 src1_data = *((__global char4 *)((__global char *)src1 + src1_index));
+        char4 src2_data = (char4)(src2.s0, src2.s1, src2.s2, src2.s3);
+
+        char4 data  = *((__global char4 *)((__global char *)dst  + dst_index));
+        char4 tmp_data = src1_data ^ src2_data;
+
+        data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global char4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_xor_C1_D6 (__global short *src1, int src1_step, int src1_offset,
+                                  __global short *dst,  int dst_step,  int dst_offset,
+                                  short16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        short4 src1_data = *((__global short4 *)((__global char *)src1 + src1_index));
+        short4 src2_data = (short4)(src2.s0, src2.s1, src2.s2, src2.s3);
+        
+        short4 tmp_data = src1_data ^ src2_data;
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = tmp_data;
+    }
+}
+#endif
+__kernel void arithm_s_bitwise_xor_C2_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                  __global   uchar *dst,  int dst_step,  int dst_offset,
+                                  uchar4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = (uchar4)(src2.x, src2.y, src2.x, src2.y);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = src1_data ^ src2_data;
+        
+
+        data.xy = (dst_index + 0 >= dst_start) ? tmp_data.xy : data.xy;
+        data.zw = (dst_index + 2 <  dst_end  ) ? tmp_data.zw : data.zw;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_xor_C2_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+        char4 src2_data = (char4)(src2.x, src2.y, src2.x, src2.y);
+        
+        char4 data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = src1_data ^ src2_data;
+        
+        data.xy = (dst_index + 0 >= dst_start) ? tmp_data.xy : data.xy;
+        data.zw = (dst_index + 2 <  dst_end  ) ? tmp_data.zw : data.zw;
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_bitwise_xor_C2_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                  __global   ushort *dst,  int dst_step,  int dst_offset,
+                                  ushort4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        ushort2 src_data1 = *((__global ushort2 *)((__global char *)src1 + src1_index));
+        ushort2 src_data2 = (ushort2)(src2.x, src2.y);
+
+        ushort2 data = src_data1 ^ src_data2;
+        
+        *((__global ushort2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_xor_C2_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                  __global   short *dst,  int dst_step,  int dst_offset,
+                                  short4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        short2 src_data1 = *((__global short2 *)((__global char *)src1 + src1_index));
+        short2 src_data2 = (short2)(src2.x, src2.y);
+
+        short2 data = src_data1 ^ src_data2;
+        
+        *((__global short2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_xor_C2_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                  __global   int *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        int2 src_data1 = *((__global int2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = (int2)(src2.x, src2.y);
+
+        int2 data = src_data1 ^ src_data2;
+        *((__global int2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_xor_C2_D5 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        char8 src1_data = *((__global char8 *)((__global char *)src1 + src1_index));
+        char8 src2_data = (char8)(src2.s0, src2.s1, src2.s2, src2.s3, src2.s4, src2.s5, src2.s6, src2.s7);
+
+        char8 tmp_data = src1_data ^ src2_data;
+        
+        *((__global char8 *)((__global char *)dst + dst_index)) = tmp_data;
+      }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_xor_C2_D6 (__global short *src1, int src1_step, int src1_offset,
+                                  __global short *dst,  int dst_step,  int dst_offset,
+                                  short16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        short8 src1_data = *((__global short8 *)((__global char *)src1 + src1_index));
+        short8 src2_data = (short8)(src2.s0, src2.s1, src2.s2, src2.s3, src2.s4, src2.s5, src2.s6, src2.s7);
+
+        short8 tmp_data = src1_data ^ src2_data;
+        
+        *((__global short8 *)((__global char *)dst + dst_index)) = tmp_data;
+    }
+}
+#endif
+__kernel void arithm_s_bitwise_xor_C3_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                  __global   uchar *dst,  int dst_step,  int dst_offset,
+                                  uchar4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        uchar4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        uchar4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        uchar4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        uchar4 src2_data_0 = (uchar4)(src2.x, src2.y, src2.z, src2.x); 
+        uchar4 src2_data_1 = (uchar4)(src2.y, src2.z, src2.x, src2.y);
+        uchar4 src2_data_2 = (uchar4)(src2.z, src2.x, src2.y, src2.z); 
+
+        uchar4 data_0 = *((__global uchar4 *)(dst + dst_index + 0));
+        uchar4 data_1 = *((__global uchar4 *)(dst + dst_index + 4));
+        uchar4 data_2 = *((__global uchar4 *)(dst + dst_index + 8));
+
+        uchar4 tmp_data_0 = src1_data_0 ^ src2_data_0;
+        uchar4 tmp_data_1 = src1_data_1 ^ src2_data_1;
+        uchar4 tmp_data_2 = src1_data_2 ^ src2_data_2;
+        
+        data_0.xyz = ((dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global uchar4 *)(dst + dst_index + 0)) = data_0;
+        *((__global uchar4 *)(dst + dst_index + 4)) = data_1;
+        *((__global uchar4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_xor_C3_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        char4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        char4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        char4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        char4 src2_data_0 = (char4)(src2.x, src2.y, src2.z, src2.x); 
+        char4 src2_data_1 = (char4)(src2.y, src2.z, src2.x, src2.y);
+        char4 src2_data_2 = (char4)(src2.z, src2.x, src2.y, src2.z); 
+
+        char4 data_0 = *((__global char4 *)(dst + dst_index + 0));
+        char4 data_1 = *((__global char4 *)(dst + dst_index + 4));
+        char4 data_2 = *((__global char4 *)(dst + dst_index + 8));
+
+        char4 tmp_data_0 = src1_data_0 ^ src2_data_0;
+        char4 tmp_data_1 = src1_data_1 ^ src2_data_1;
+        char4 tmp_data_2 = src1_data_2 ^ src2_data_2;
+
+        data_0.xyz = ((dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global char4 *)(dst + dst_index + 0)) = data_0;
+        *((__global char4 *)(dst + dst_index + 4)) = data_1;
+        *((__global char4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+
+__kernel void arithm_s_bitwise_xor_C3_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                  __global   ushort *dst,  int dst_step,  int dst_offset,
+                                  ushort4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        ushort2 src1_data_0 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 0));
+        ushort2 src1_data_1 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 4));
+        ushort2 src1_data_2 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 8));
+
+        ushort2 src2_data_0 = (ushort2)(src2.x, src2.y);
+        ushort2 src2_data_1 = (ushort2)(src2.z, src2.x);
+        ushort2 src2_data_2 = (ushort2)(src2.y, src2.z);
+
+        ushort2 data_0 = *((__global ushort2 *)((__global char *)dst + dst_index + 0));
+        ushort2 data_1 = *((__global ushort2 *)((__global char *)dst + dst_index + 4));
+        ushort2 data_2 = *((__global ushort2 *)((__global char *)dst + dst_index + 8));
+
+        ushort2 tmp_data_0 = src1_data_0 ^ src2_data_0;
+        ushort2 tmp_data_1 = src1_data_1 ^ src2_data_1;
+        ushort2 tmp_data_2 = src1_data_2 ^ src2_data_2;
+
+        data_0.xy = ((dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global ushort2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_bitwise_xor_C3_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                  __global   short *dst,  int dst_step,  int dst_offset,
+                                  short4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        short2 src1_data_0 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 0));
+        short2 src1_data_1 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 4));
+        short2 src1_data_2 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 8));
+
+        short2 src2_data_0 = (short2)(src2.x, src2.y);
+        short2 src2_data_1 = (short2)(src2.z, src2.x);
+        short2 src2_data_2 = (short2)(src2.y, src2.z);
+
+        short2 data_0 = *((__global short2 *)((__global char *)dst + dst_index + 0));
+        short2 data_1 = *((__global short2 *)((__global char *)dst + dst_index + 4));
+        short2 data_2 = *((__global short2 *)((__global char *)dst + dst_index + 8));
+
+        short2 tmp_data_0 = src1_data_0 ^ src2_data_0;
+        short2 tmp_data_1 = src1_data_1 ^ src2_data_1;
+        short2 tmp_data_2 = src1_data_2 ^ src2_data_2;
+
+        data_0.xy = ((dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global short2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global short2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global short2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_bitwise_xor_C3_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                  __global   int *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        int src1_data_0 = *((__global int *)((__global char *)src1 + src1_index + 0));
+        int src1_data_1 = *((__global int *)((__global char *)src1 + src1_index + 4));
+        int src1_data_2 = *((__global int *)((__global char *)src1 + src1_index + 8));
+
+        int src2_data_0 = src2.x;
+        int src2_data_1 = src2.y;
+        int src2_data_2 = src2.z;
+
+        int data_0 = *((__global int *)((__global char *)dst + dst_index + 0));
+        int data_1 = *((__global int *)((__global char *)dst + dst_index + 4));
+        int data_2 = *((__global int *)((__global char *)dst + dst_index + 8));
+
+        int tmp_data_0 = src1_data_0 ^ src2_data_0;
+        int tmp_data_1 = src1_data_1 ^ src2_data_1;
+        int tmp_data_2 = src1_data_2 ^ src2_data_2;
+
+       *((__global int *)((__global char *)dst + dst_index + 0))= tmp_data_0;
+       *((__global int *)((__global char *)dst + dst_index + 4))= tmp_data_1;
+       *((__global int *)((__global char *)dst + dst_index + 8))= tmp_data_2;
+    }
+}
+__kernel void arithm_s_bitwise_xor_C3_D5 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        char4 src1_data_0 = *((__global char4 *)((__global char *)src1 + src1_index + 0));
+        char4 src1_data_1 = *((__global char4 *)((__global char *)src1 + src1_index + 4));
+        char4 src1_data_2 = *((__global char4 *)((__global char *)src1 + src1_index + 8));
+                                             
+        char4 src2_data_0 = (char4)(src2.s0, src2.s1, src2.s2, src2.s3); 
+        char4 src2_data_1 = (char4)(src2.s4, src2.s5, src2.s6, src2.s7);
+        char4 src2_data_2 = (char4)(src2.s8, src2.s9, src2.sA, src2.sB); 
+
+        char4 data_0 = *((__global char4 *)((__global char *)dst + dst_index + 0));
+        char4 data_1 = *((__global char4 *)((__global char *)dst + dst_index + 4));
+        char4 data_2 = *((__global char4 *)((__global char *)dst + dst_index + 8));
+
+        char4 tmp_data_0 = src1_data_0 ^ src2_data_0;
+        char4 tmp_data_1 = src1_data_1 ^ src2_data_1;
+        char4 tmp_data_2 = src1_data_2 ^ src2_data_2;
+
+       *((__global char4 *)((__global char *)dst + dst_index + 0))= tmp_data_0;
+       *((__global char4 *)((__global char *)dst + dst_index + 4))= tmp_data_1;
+       *((__global char4 *)((__global char *)dst + dst_index + 8))= tmp_data_2;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_xor_C3_D6 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          short16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 24) + src1_offset); 
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 24));
+
+        short4 src1_data_0 = *((__global short4 *)((__global char *)src1 + src1_index + 0 ));
+        short4 src1_data_1 = *((__global short4 *)((__global char *)src1 + src1_index + 8 ));
+        short4 src1_data_2 = *((__global short4 *)((__global char *)src1 + src1_index + 16));
+                                               
+        short4 src2_data_0 = (short4)(src2.s0, src2.s1, src2.s2, src2.s3);
+        short4 src2_data_1 = (short4)(src2.s4, src2.s5, src2.s6, src2.s7);
+        short4 src2_data_2 = (short4)(src2.s8, src2.s9, src2.sa, src2.sb);
+
+        short4 data_0 = *((__global short4 *)((__global char *)dst + dst_index + 0 ));
+        short4 data_1 = *((__global short4 *)((__global char *)dst + dst_index + 8 ));
+        short4 data_2 = *((__global short4 *)((__global char *)dst + dst_index + 16));
+
+        short4 tmp_data_0 = src1_data_0 ^ src2_data_0;
+        short4 tmp_data_1 = src1_data_1 ^ src2_data_1;
+        short4 tmp_data_2 = src1_data_2 ^ src2_data_2;
+        
+       *((__global short4 *)((__global char *)dst + dst_index + 0 ))= tmp_data_0;
+       *((__global short4 *)((__global char *)dst + dst_index + 8 ))= tmp_data_1;
+       *((__global short4 *)((__global char *)dst + dst_index + 16))= tmp_data_2;
+    }
+}
+#endif
+__kernel void arithm_s_bitwise_xor_C4_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                  __global   uchar *dst,  int dst_step,  int dst_offset,
+                                  uchar4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar4 src_data1 = *((__global uchar4 *)(src1 + src1_index));
+
+        uchar4 data = src_data1 ^ src2;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_xor_C4_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        char4 src_data1 = *((__global char4 *)(src1 + src1_index));
+
+        char4 data = src_data1 ^ src2;
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_bitwise_xor_C4_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                  __global   ushort *dst,  int dst_step,  int dst_offset,
+                                  ushort4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        ushort4 src_data1 = *((__global ushort4 *)((__global char *)src1 + src1_index));
+
+        ushort4 data = src_data1 ^ src2;
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_xor_C4_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                  __global   short *dst,  int dst_step,  int dst_offset,
+                                  short4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        short4 src_data1 = *((__global short4 *)((__global char *)src1 + src1_index));
+
+        short4 data = src_data1 ^ src2;
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_xor_C4_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                  __global   int *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        int4 src_data1 = *((__global int4 *)((__global char *)src1 + src1_index));
+
+        int4 data = src_data1 ^ src2;
+
+        *((__global int4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_xor_C4_D5 (__global   char *src1, int src1_step, int src1_offset,
+                                  __global   char *dst,  int dst_step,  int dst_offset,
+                                  char16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        char16 src1_data = *((__global char16 *)((__global char *)src1 + src1_index));
+        char16 src2_data = (char16)(src2.s0, src2.s1, src2.s2, src2.s3, src2.s4, src2.s5, src2.s6, src2.s7,
+                                    src2.s8, src2.s9, src2.sa, src2.sb, src2.sc, src2.sd, src2.se, src2.sf);
+
+        char16 tmp_data = src1_data ^ src2_data;
+        
+        *((__global char16 *)((__global char *)dst + dst_index)) = tmp_data;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_xor_C4_D6 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          short16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 5) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 5) + dst_offset);
+
+        short4 src1_data_0 = *((__global short4 *)((__global char *)src1 + src1_index + 0));
+        short4 src1_data_1 = *((__global short4 *)((__global char *)src1 + src1_index + 8));
+        short4 src1_data_2 = *((__global short4 *)((__global char *)src1 + src1_index + 16));
+        short4 src1_data_3 = *((__global short4 *)((__global char *)src1 + src1_index + 24));
+
+        short4 src2_data_0 = (short4)(src2.s0, src2.s1, src2.s2, src2.s3);
+        short4 src2_data_1 = (short4)(src2.s4, src2.s5, src2.s6, src2.s7);
+        short4 src2_data_2 = (short4)(src2.s8, src2.s9, src2.sa, src2.sb);
+        short4 src2_data_3 = (short4)(src2.sc, src2.sd, src2.se, src2.sf);
+        
+        short4 tmp_data_0 = src1_data_0 ^ src2_data_0;
+        short4 tmp_data_1 = src1_data_1 ^ src2_data_1;
+        short4 tmp_data_2 = src1_data_2 ^ src2_data_2;
+        short4 tmp_data_3 = src1_data_3 ^ src2_data_3;
+        
+       *((__global short4 *)((__global char *)dst + dst_index + 0 ))= tmp_data_0;
+       *((__global short4 *)((__global char *)dst + dst_index + 8 ))= tmp_data_1;
+       *((__global short4 *)((__global char *)dst + dst_index + 16))= tmp_data_2;
+       *((__global short4 *)((__global char *)dst + dst_index + 24))= tmp_data_3;
+       
+    }
+}
+#endif
diff --git a/modules/ocl/src/kernels/arithm_bitwise_xor_scalar_mask.cl b/modules/ocl/src/kernels/arithm_bitwise_xor_scalar_mask.cl
new file mode 100644 (file)
index 0000000..867bfc6
--- /dev/null
@@ -0,0 +1,1058 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jiang Liyuan, jlyuan001.good@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 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
+// 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*/
+#if defined (__ATI__)
+#pragma OPENCL EXTENSION cl_amd_fp64:enable
+#elif defined (__NVIDIA__)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////BITWISE_XOR////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+/**************************************bitwise_xor with scalar with mask**************************************/
+__kernel void arithm_s_bitwise_xor_with_mask_C1_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                            __global   uchar *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            uchar4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = (uchar4)(src2.x, src2.x, src2.x, src2.x);
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = src1_data ^ src2_data;
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((mask_data.z) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((mask_data.w) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_xor_with_mask_C1_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                            __global   char *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            char4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+        char4 src2_data = (char4)(src2.x, src2.x, src2.x, src2.x);
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        char4 data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = src1_data ^ src2_data;
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((mask_data.z) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((mask_data.w) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_bitwise_xor_with_mask_C1_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                            __global   ushort *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar  *mask, int mask_step, int mask_offset,
+                                            ushort4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        ushort2 src1_data = vload2(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort2 src2_data = (ushort2)(src2.x, src2.x);
+        uchar2  mask_data = vload2(0, mask + mask_index);
+
+        ushort2 data = *((__global ushort2 *)((__global uchar *)dst + dst_index));
+        ushort2 tmp_data = src1_data ^ src2_data;
+        
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.y : data.y;
+
+        *((__global ushort2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_xor_with_mask_C1_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                            __global   short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            short4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        short2 src1_data = vload2(0, (__global short *)((__global char *)src1 + src1_index));
+        short2 src2_data = (short2)(src2.x, src2.x);
+        uchar2  mask_data = vload2(0, mask + mask_index);
+
+        short2 data = *((__global short2 *)((__global uchar *)dst + dst_index));
+        short2 tmp_data = src1_data ^ src2_data;
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.y : data.y;
+
+        *((__global short2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_xor_with_mask_C1_D4 (__global   int   *src1, int src1_step, int src1_offset,
+                                            __global   int   *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int src_data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int src_data2 = src2.x;
+        int dst_data  = *((__global int *)((__global char *)dst  + dst_index));
+
+        int data = src_data1 ^ src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global int *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_bitwise_xor_with_mask_C1_D5 (__global char *src1, int src1_step, int src1_offset,
+                                                    __global char *dst,  int dst_step,  int dst_offset,
+                                                    __global   uchar *mask, int mask_step, int mask_offset,
+                                                    char16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char4 src1_data = *((__global char4 *)((__global char *)src1 + src1_index));
+        char4 src2_data = (char4)(src2.s0, src2.s1, src2.s2, src2.s3);
+        char4 dst_data  = *((__global char4 *)((__global char *)dst  + dst_index));
+
+        char4 data = src1_data ^ src2_data;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_xor_with_mask_C1_D6 (__global short *src1, int src1_step, int src1_offset,
+                                            __global short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            short16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short4 src1_data = *((__global short4 *)((__global char *)src1 + src1_index));
+        short4 src2_data = (short4)(src2.s0, src2.s1, src2.s2, src2.s3);
+        short4 dst_data  = *((__global short4 *)((__global char *)dst  + dst_index));
+
+        short4 data = src1_data ^ src2_data;
+        data = mask_data ? data : dst_data; 
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+__kernel void arithm_s_bitwise_xor_with_mask_C2_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                            __global   uchar *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            uchar4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = (uchar4)(src2.x, src2.y, src2.x, src2.y);
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = src1_data ^ src2_data;
+
+        data.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.xy : data.xy;
+        data.zw = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.zw : data.zw;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_xor_with_mask_C2_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                            __global   char *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            char4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        char4 src1_data = vload4(0, src1 + src1_index);
+        char4 src2_data = (char4)(src2.x, src2.y, src2.x, src2.y);
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        char4 data = *((__global char4 *)(dst + dst_index));
+        char4 tmp_data = src1_data ^ src2_data;
+
+        data.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.xy : data.xy;
+        data.zw = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.zw : data.zw;
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_bitwise_xor_with_mask_C2_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                            __global   ushort *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            ushort4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        ushort2 src_data1 = *((__global ushort2 *)((__global char *)src1 + src1_index));
+        ushort2 src_data2 = (ushort2)(src2.x, src2.y);
+        ushort2 dst_data  = *((__global ushort2 *)((__global char *)dst  + dst_index));
+
+        ushort2 data = src_data1 ^ src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global ushort2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_xor_with_mask_C2_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                            __global   short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            short4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short2 src_data1 = *((__global short2 *)((__global char *)src1 + src1_index));
+        short2 src_data2 = (short2)(src2.x, src2.y);
+        short2 dst_data  = *((__global short2 *)((__global char *)dst  + dst_index));
+
+        short2 data = src_data1 ^ src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global short2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_xor_with_mask_C2_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                            __global   int *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int2 src_data1 = *((__global int2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = (int2)(src2.x, src2.y);
+        int2 dst_data  = *((__global int2 *)((__global char *)dst  + dst_index));
+
+        int2 data = src_data1 ^ src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global int2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_xor_with_mask_C2_D5 (__global   char *src1, int src1_step, int src1_offset,
+                                            __global  char *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            char16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char8 src1_data = *((__global char8 *)((__global char *)src1 + src1_index));
+        char8 src2_data = (char8)(src2.s0, src2.s1, src2.s2, src2.s3, src2.s4, src2.s5, src2.s6, src2.s7);
+        char8 dst_data = *((__global char8 *)((__global char *)dst  + dst_index));
+
+        char8 data = src1_data ^ src2_data;
+        
+        data = mask_data ? data : dst_data;
+
+        *((__global char8 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_xor_with_mask_C2_D6 (__global short *src1, int src1_step, int src1_offset,
+                                                    __global short *dst,  int dst_step,  int dst_offset,
+                                                    __global uchar *mask, int mask_step, int mask_offset,
+                                                    short16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short8 src1_data = *((__global short8 *)((__global char *)src1 + src1_index));
+        short8 src2_data = (short8)(src2.s0, src2.s1, src2.s2, src2.s3, src2.s4, src2.s5, src2.s6, src2.s7);
+        short8 dst_data = *((__global short8 *)((__global char *)dst  + dst_index));
+
+        short8 data = src1_data ^ src2_data;
+        data = mask_data ? data : dst_data; 
+
+        *((__global short8 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+__kernel void arithm_s_bitwise_xor_with_mask_C3_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                            __global   uchar *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            uchar4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        uchar4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        uchar4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        uchar4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        uchar4 src2_data_0 = (uchar4)(src2.x, src2.y, src2.z, src2.x); 
+        uchar4 src2_data_1 = (uchar4)(src2.y, src2.z, src2.x, src2.y);
+        uchar4 src2_data_2 = (uchar4)(src2.z, src2.x, src2.y, src2.z); 
+
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        uchar4 data_0 = *((__global uchar4 *)(dst + dst_index + 0));
+        uchar4 data_1 = *((__global uchar4 *)(dst + dst_index + 4));
+        uchar4 data_2 = *((__global uchar4 *)(dst + dst_index + 8));
+
+        uchar4 tmp_data_0 = src1_data_0 ^ src2_data_0;
+        uchar4 tmp_data_1 = src1_data_1 ^ src2_data_1;
+        uchar4 tmp_data_2 = src1_data_2 ^ src2_data_2;
+
+        data_0.xyz = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((mask_data.w) && (dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global uchar4 *)(dst + dst_index + 0)) = data_0;
+        *((__global uchar4 *)(dst + dst_index + 4)) = data_1;
+        *((__global uchar4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_xor_with_mask_C3_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                            __global   char *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            char4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        char4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        char4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        char4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        char4 src2_data_0 = (char4)(src2.x, src2.y, src2.z, src2.x); 
+        char4 src2_data_1 = (char4)(src2.y, src2.z, src2.x, src2.y);
+        char4 src2_data_2 = (char4)(src2.z, src2.x, src2.y, src2.z); 
+
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        char4 data_0 = *((__global char4 *)(dst + dst_index + 0));
+        char4 data_1 = *((__global char4 *)(dst + dst_index + 4));
+        char4 data_2 = *((__global char4 *)(dst + dst_index + 8));
+
+        char4 tmp_data_0 = src1_data_0 ^ src2_data_0;
+        char4 tmp_data_1 = src1_data_1 ^ src2_data_1;
+        char4 tmp_data_2 = src1_data_2 ^ src2_data_2;
+        
+        data_0.xyz = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((mask_data.w) && (dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global char4 *)(dst + dst_index + 0)) = data_0;
+        *((__global char4 *)(dst + dst_index + 4)) = data_1;
+        *((__global char4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+
+__kernel void arithm_s_bitwise_xor_with_mask_C3_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                            __global   ushort *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            ushort4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        ushort2 src1_data_0 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 0));
+        ushort2 src1_data_1 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 4));
+        ushort2 src1_data_2 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 8));
+
+        ushort2 src2_data_0 = (ushort2)(src2.x, src2.y);
+        ushort2 src2_data_1 = (ushort2)(src2.z, src2.x);
+        ushort2 src2_data_2 = (ushort2)(src2.y, src2.z);
+
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        ushort2 data_0 = *((__global ushort2 *)((__global char *)dst + dst_index + 0));
+        ushort2 data_1 = *((__global ushort2 *)((__global char *)dst + dst_index + 4));
+        ushort2 data_2 = *((__global ushort2 *)((__global char *)dst + dst_index + 8));
+
+        ushort2 tmp_data_0 = src1_data_0 ^ src2_data_0;
+        ushort2 tmp_data_1 = src1_data_1 ^ src2_data_1;
+        ushort2 tmp_data_2 = src1_data_2 ^ src2_data_2;
+        
+        data_0.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global ushort2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_bitwise_xor_with_mask_C3_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                            __global   short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            short4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        short2 src1_data_0 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 0));
+        short2 src1_data_1 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 4));
+        short2 src1_data_2 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 8));
+
+        short2 src2_data_0 = (short2)(src2.x, src2.y);
+        short2 src2_data_1 = (short2)(src2.z, src2.x);
+        short2 src2_data_2 = (short2)(src2.y, src2.z);
+
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        short2 data_0 = *((__global short2 *)((__global char *)dst + dst_index + 0));
+        short2 data_1 = *((__global short2 *)((__global char *)dst + dst_index + 4));
+        short2 data_2 = *((__global short2 *)((__global char *)dst + dst_index + 8));
+
+        short2 tmp_data_0 = src1_data_0 ^ src2_data_0;
+        short2 tmp_data_1 = src1_data_1 ^ src2_data_1;
+        short2 tmp_data_2 = src1_data_2 ^ src2_data_2;
+
+        data_0.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global short2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global short2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global short2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_bitwise_xor_with_mask_C3_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                            __global   int *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        int src1_data_0 = *((__global int *)((__global char *)src1 + src1_index + 0));
+        int src1_data_1 = *((__global int *)((__global char *)src1 + src1_index + 4));
+        int src1_data_2 = *((__global int *)((__global char *)src1 + src1_index + 8));
+
+        int src2_data_0 = src2.x;
+        int src2_data_1 = src2.y;
+        int src2_data_2 = src2.z;
+
+        uchar mask_data = * (mask + mask_index);
+
+        int data_0 = *((__global int *)((__global char *)dst + dst_index + 0));
+        int data_1 = *((__global int *)((__global char *)dst + dst_index + 4));
+        int data_2 = *((__global int *)((__global char *)dst + dst_index + 8));
+
+        int tmp_data_0 = src1_data_0 ^ src2_data_0;
+        int tmp_data_1 = src1_data_1 ^ src2_data_1;
+        int tmp_data_2 = src1_data_2 ^ src2_data_2;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global int *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global int *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global int *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_bitwise_xor_with_mask_C3_D5 (__global   char *src1, int src1_step, int src1_offset,
+                                            __global   char *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            char16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        char4 src1_data_0 = *((__global char4 *)((__global char *)src1 + src1_index + 0));
+        char4 src1_data_1 = *((__global char4 *)((__global char *)src1 + src1_index + 4));
+        char4 src1_data_2 = *((__global char4 *)((__global char *)src1 + src1_index + 8));
+                                             
+        char4 src2_data_0 = (char4)(src2.s0, src2.s1, src2.s2, src2.s3); 
+        char4 src2_data_1 = (char4)(src2.s4, src2.s5, src2.s6, src2.s7);
+        char4 src2_data_2 = (char4)(src2.s8, src2.s9, src2.sA, src2.sB); 
+        
+        uchar mask_data = * (mask + mask_index);
+
+        char4 data_0 = *((__global char4 *)((__global char *)dst + dst_index + 0));
+        char4 data_1 = *((__global char4 *)((__global char *)dst + dst_index + 4));
+        char4 data_2 = *((__global char4 *)((__global char *)dst + dst_index + 8));
+
+        char4 tmp_data_0 = src1_data_0 ^ src2_data_0;
+        char4 tmp_data_1 = src1_data_1 ^ src2_data_1;
+        char4 tmp_data_2 = src1_data_2 ^ src2_data_2;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global char4 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global char4 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global char4 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_xor_with_mask_C3_D6 (__global short *src1, int src1_step, int src1_offset,
+                                                    __global short *dst,  int dst_step,  int dst_offset,
+                                                    __global uchar  *mask, int mask_step, int mask_offset,
+                                                    short16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 24) + src1_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 24));
+
+        short4 src1_data_0 = *((__global short4 *)((__global char *)src1 + src1_index + 0 ));
+        short4 src1_data_1 = *((__global short4 *)((__global char *)src1 + src1_index + 8 ));
+        short4 src1_data_2 = *((__global short4 *)((__global char *)src1 + src1_index + 16));
+                                               
+        short4 src2_data_0 = (short4)(src2.s0, src2.s1, src2.s2, src2.s3);
+        short4 src2_data_1 = (short4)(src2.s4, src2.s5, src2.s6, src2.s7);
+        short4 src2_data_2 = (short4)(src2.s8, src2.s9, src2.sa, src2.sb);
+        
+        uchar mask_data = * (mask + mask_index);
+
+        short4 data_0 = *((__global short4 *)((__global char *)dst + dst_index + 0 ));
+        short4 data_1 = *((__global short4 *)((__global char *)dst + dst_index + 8 ));
+        short4 data_2 = *((__global short4 *)((__global char *)dst + dst_index + 16));
+
+        short4 tmp_data_0 = src1_data_0 ^ src2_data_0;
+        short4 tmp_data_1 = src1_data_1 ^ src2_data_1;
+        short4 tmp_data_2 = src1_data_2 ^ src2_data_2;
+        
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global short4 *)((__global char *)dst + dst_index + 0 ))= data_0;
+       *((__global short4 *)((__global char *)dst + dst_index + 8 ))= data_1;
+       *((__global short4 *)((__global char *)dst + dst_index + 16))= data_2;
+    }
+}
+#endif
+__kernel void arithm_s_bitwise_xor_with_mask_C4_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                            __global   uchar *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            uchar4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        uchar4 src_data1 = *((__global uchar4 *)(src1 + src1_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+
+        uchar4 data = src_data1 ^ src2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+
+
+__kernel void arithm_s_bitwise_xor_with_mask_C4_D1 (__global   char *src1, int src1_step, int src1_offset,
+                                            __global   char *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            char4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char4 src_data1 = *((__global char4 *)(src1 + src1_index));
+        char4 dst_data  = *((__global char4 *)(dst  + dst_index));
+
+        char4 data = src_data1 ^ src2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char4 *)(dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_bitwise_xor_with_mask_C4_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                            __global   ushort *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            ushort4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        ushort4 src_data1 = *((__global ushort4 *)((__global char *)src1 + src1_index));
+        ushort4 dst_data  = *((__global ushort4 *)((__global char *)dst  + dst_index));
+
+        ushort4 data = src_data1 ^ src2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_xor_with_mask_C4_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                            __global   short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            short4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short4 src_data1 = *((__global short4 *)((__global char *)src1 + src1_index));
+        short4 dst_data  = *((__global short4 *)((__global char *)dst  + dst_index));
+
+        short4 data = src_data1 ^ src2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_xor_with_mask_C4_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                            __global   int *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int4 src_data1 = *((__global int4 *)((__global char *)src1 + src1_index));
+        int4 dst_data  = *((__global int4 *)((__global char *)dst  + dst_index));
+
+        int4 data = src_data1 ^ src2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global int4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_bitwise_xor_with_mask_C4_D5 (__global   char *src1, int src1_step, int src1_offset,
+                                                    __global   char *dst,  int dst_step,  int dst_offset,
+                                                    __global   uchar *mask, int mask_step, int mask_offset,
+                                                    char16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        char16 src1_data = *((__global char16 *)((__global char *)src1 + src1_index));
+        char16 src2_data = (char16)(src2.s0, src2.s1, src2.s2, src2.s3, src2.s4, src2.s5, src2.s6, src2.s7,
+                                    src2.s8, src2.s9, src2.sa, src2.sb, src2.sc, src2.sd, src2.se, src2.sf);
+        char16 dst_data  = *((__global char16 *)((__global char *)dst  + dst_index));
+
+        char16 data = src1_data ^ src2_data;
+        data = mask_data ? data : dst_data; 
+
+        *((__global char16 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_bitwise_xor_with_mask_C4_D6 (__global short *src1, int src1_step, int src1_offset,
+                                                    __global short *dst,  int dst_step,  int dst_offset,
+                                                    __global uchar *mask, int mask_step, int mask_offset,
+                                                    short16 src2, int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 5) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 5) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short4 src1_data_0 = *((__global short4 *)((__global char *)src1 + src1_index + 0));
+        short4 src1_data_1 = *((__global short4 *)((__global char *)src1 + src1_index + 8));
+        short4 src1_data_2 = *((__global short4 *)((__global char *)src1 + src1_index + 16));
+        short4 src1_data_3 = *((__global short4 *)((__global char *)src1 + src1_index + 24));
+
+        short4 src2_data_0 = (short4)(src2.s0, src2.s1, src2.s2, src2.s3);
+        short4 src2_data_1 = (short4)(src2.s4, src2.s5, src2.s6, src2.s7);
+        short4 src2_data_2 = (short4)(src2.s8, src2.s9, src2.sa, src2.sb);
+        short4 src2_data_3 = (short4)(src2.sc, src2.sd, src2.se, src2.sf);
+        
+        short4 dst_data_0  = *((__global short4 *)((__global char *)dst  + dst_index + 0));
+        short4 dst_data_1  = *((__global short4 *)((__global char *)dst  + dst_index + 8));
+        short4 dst_data_2  = *((__global short4 *)((__global char *)dst  + dst_index + 16));
+        short4 dst_data_3  = *((__global short4 *)((__global char *)dst  + dst_index + 24));
+
+        short4 data_0 = src1_data_0 ^ src2_data_0;
+        short4 data_1 = src1_data_1 ^ src2_data_1;
+        short4 data_2 = src1_data_2 ^ src2_data_2;
+        short4 data_3 = src1_data_3 ^ src2_data_3;
+             
+        data_0 = mask_data ? data_0 : dst_data_0; 
+        data_1 = mask_data ? data_1 : dst_data_1; 
+        data_2 = mask_data ? data_2 : dst_data_2; 
+        data_3 = mask_data ? data_3 : dst_data_3;
+
+        *((__global short4 *)((__global char *)dst + dst_index + 0)) = data_0;
+        *((__global short4 *)((__global char *)dst + dst_index + 8)) = data_1;
+        *((__global short4 *)((__global char *)dst + dst_index + 16)) = data_2;
+        *((__global short4 *)((__global char *)dst + dst_index + 24)) = data_3;
+    }
+}
+#endif
+
diff --git a/modules/ocl/src/kernels/arithm_cartToPolar.cl b/modules/ocl/src/kernels/arithm_cartToPolar.cl
new file mode 100644 (file)
index 0000000..d4aa83a
--- /dev/null
@@ -0,0 +1,132 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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*/
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+#define CV_PI   3.1415926535897932384626433832795
+
+__kernel void arithm_cartToPolar_D5 (__global float *src1, int src1_step, int src1_offset,
+                                     __global float *src2, int src2_step, int src2_offset,
+                                     __global float *dst1, int dst1_step, int dst1_offset, //magnitude
+                                     __global float *dst2, int dst2_step, int dst2_offset, //cartToPolar
+                                     int rows, int cols, int angInDegree)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+
+        int dst1_index = mad24(y, dst1_step, (x << 2) + dst1_offset);
+        int dst2_index = mad24(y, dst2_step, (x << 2) + dst2_offset);
+
+        float x = *((__global float *)((__global char *)src1 + src1_index));
+        float y = *((__global float *)((__global char *)src2 + src2_index));
+
+        float x2 = x * x;
+        float y2 = y * y;
+
+        float magnitude = sqrt(x2 + y2);
+        float cartToPolar;
+
+        float tmp = y >= 0 ? 0 : CV_PI*2;
+        tmp = x < 0 ? CV_PI : tmp;
+
+        float tmp1 = y >= 0 ? CV_PI*0.5 : CV_PI*1.5;
+        cartToPolar = y2 <= x2 ? x*y/(x2 + 0.28f*y2 + (float)DBL_EPSILON)  + tmp :
+                                 tmp1 - x*y/(y2 + 0.28f*x2 + (float)DBL_EPSILON);
+
+        cartToPolar = angInDegree == 0 ? cartToPolar : cartToPolar * (float)(180/CV_PI);
+
+        *((__global float *)((__global char *)dst1 + dst1_index)) = magnitude;
+        *((__global float *)((__global char *)dst2 + dst2_index)) = cartToPolar;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_cartToPolar_D6 (__global double *src1, int src1_step, int src1_offset,
+                                     __global double *src2, int src2_step, int src2_offset,
+                                     __global double *dst1, int dst1_step, int dst1_offset,
+                                     __global double *dst2, int dst2_step, int dst2_offset,
+                                     int rows, int cols, int angInDegree)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+
+        int dst1_index = mad24(y, dst1_step, (x << 3) + dst1_offset);
+        int dst2_index = mad24(y, dst2_step, (x << 3) + dst2_offset);
+
+        double x = *((__global double *)((__global char *)src1 + src1_index));
+        double y = *((__global double *)((__global char *)src2 + src2_index));
+
+        double x2 = x * x;
+        double y2 = y * y;
+
+        double magnitude = sqrt(x2 + y2);
+        double cartToPolar;
+
+        float tmp = y >= 0 ? 0 : CV_PI*2;
+        tmp = x < 0 ? CV_PI : tmp;
+
+        float tmp1 = y >= 0 ? CV_PI*0.5 : CV_PI*1.5;
+        cartToPolar = y2 <= x2 ? x*y/(x2 + 0.28f*y2 + (float)DBL_EPSILON)  + tmp :
+                                 tmp1 - x*y/(y2 + 0.28f*x2 + (float)DBL_EPSILON);
+
+        cartToPolar = angInDegree == 0 ? cartToPolar : cartToPolar * (float)(180/CV_PI);
+
+        *((__global double *)((__global char *)dst1 + dst1_index)) = magnitude;
+        *((__global double *)((__global char *)dst2 + dst2_index)) = cartToPolar;
+    }
+}
+#endif
diff --git a/modules/ocl/src/kernels/arithm_compare_eq.cl b/modules/ocl/src/kernels/arithm_compare_eq.cl
new file mode 100644 (file)
index 0000000..aa79172
--- /dev/null
@@ -0,0 +1,691 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jiang Liyuan, jlyuan001.good@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*/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////Compare EQ////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+
+__kernel void arithm_compare_eq_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                             __global uchar *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data == src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+__kernel void arithm_compare_eq_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                             __global ushort *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        ushort4 src1_data = vload4(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort4 src2_data = vload4(0, (__global ushort *)((__global char *)src2 + src2_index));
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data == src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+
+
+__kernel void arithm_compare_eq_D3 (__global short *src1, int src1_step, int src1_offset,
+                             __global short *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        short4 src1_data = vload4(0, (__global short *)((__global char *)src1 + src1_index));
+        short4 src2_data = vload4(0, (__global short *)((__global char *)src2 + src2_index));
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data == src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+
+
+__kernel void arithm_compare_eq_D4 (__global int *src1, int src1_step, int src1_offset,
+                             __global int *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {   
+        x = x << 2;
+        #define dst_align ((dst_offset >> 2) & 3)
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset - (dst_align << 2)); 
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset - (dst_align << 2)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        int4 src1_data = vload4(0, (__global int *)((__global char *)src1 + src1_index));
+        int4 src2_data = vload4(0, (__global int *)((__global char *)src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data == src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+__kernel void arithm_compare_eq_D5 (__global float *src1, int src1_step, int src1_offset,
+                             __global float *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+        #define dst_align ((dst_offset >> 2) & 3)
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset - (dst_align << 2)); 
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset - (dst_align << 2)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        float4 src1_data = vload4(0, (__global float *)((__global char *)src1 + src1_index));
+        float4 src2_data = vload4(0, (__global float *)((__global char *)src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data == src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_compare_eq_D6 (__global double *src1, int src1_step, int src1_offset,
+                             __global double *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+        #define dst_align ((dst_offset >> 3) & 3)
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset - (dst_align << 3)); 
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset - (dst_align << 3)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        double4 src1_data = vload4(0, (__global double *)((__global char *)src1 + src1_index));
+        double4 src2_data = vload4(0, (__global double *)((__global char *)src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data == src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+#endif
+
+/***********************************Compare GT**************************/
+__kernel void arithm_compare_gt_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                             __global uchar *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data > src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+__kernel void arithm_compare_gt_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                             __global ushort *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        ushort4 src1_data = vload4(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort4 src2_data = vload4(0, (__global ushort *)((__global char *)src2 + src2_index));
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data > src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+
+
+__kernel void arithm_compare_gt_D3 (__global short *src1, int src1_step, int src1_offset,
+                             __global short *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        short4 src1_data = vload4(0, (__global short *)((__global char *)src1 + src1_index));
+        short4 src2_data = vload4(0, (__global short *)((__global char *)src2 + src2_index));
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data > src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+__kernel void arithm_compare_gt_D4 (__global int *src1, int src1_step, int src1_offset,
+                             __global int *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+        #define dst_align ((dst_offset >> 2) & 3)
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset - (dst_align << 2)); 
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset - (dst_align << 2)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        int4 src1_data = vload4(0, (__global int *)((__global char *)src1 + src1_index));
+        int4 src2_data = vload4(0, (__global int *)((__global char *)src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data > src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+__kernel void arithm_compare_gt_D5 (__global float *src1, int src1_step, int src1_offset,
+                             __global float *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+        #define dst_align ((dst_offset >> 2) & 3)
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset - (dst_align << 2)); 
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset - (dst_align << 2)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        float4 src1_data = vload4(0, (__global float *)((__global char *)src1 + src1_index));
+        float4 src2_data = vload4(0, (__global float *)((__global char *)src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data > src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_compare_gt_D6 (__global double *src1, int src1_step, int src1_offset,
+                             __global double *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+        #define dst_align ((dst_offset >> 3) & 3)
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset - (dst_align << 3)); 
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset - (dst_align << 3)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        double4 src1_data = vload4(0, (__global double *)((__global char *)src1 + src1_index));
+        double4 src2_data = vload4(0, (__global double *)((__global char *)src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data > src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+#endif
+
+/***********************************Compare GE**************************/
+__kernel void arithm_compare_ge_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                             __global uchar *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data >= src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+
+
+__kernel void arithm_compare_ge_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                             __global ushort *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        ushort4 src1_data = vload4(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort4 src2_data = vload4(0, (__global ushort *)((__global char *)src2 + src2_index));
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data >= src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+
+
+__kernel void arithm_compare_ge_D3 (__global short *src1, int src1_step, int src1_offset,
+                             __global short *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1)& 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        short4 src1_data = vload4(0, (__global short *)((__global char *)src1 + src1_index));
+        short4 src2_data = vload4(0, (__global short *)((__global char *)src2 + src2_index));
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data >= src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+__kernel void arithm_compare_ge_D4 (__global int *src1, int src1_step, int src1_offset,
+                             __global int *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 2)& 3)
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset - (dst_align << 2)); 
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset - (dst_align << 2)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        int4 src1_data = vload4(0, (__global int *)((__global char *)src1 + src1_index));
+        int4 src2_data = vload4(0, (__global int *)((__global char *)src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data >= src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+__kernel void arithm_compare_ge_D5 (__global float *src1, int src1_step, int src1_offset,
+                             __global float *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 2)& 3)
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset - (dst_align << 2)); 
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset - (dst_align << 2)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        float4 src1_data = vload4(0, (__global float *)((__global char *)src1 + src1_index));
+        float4 src2_data = vload4(0, (__global float *)((__global char *)src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data >= src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_compare_ge_D6 (__global double *src1, int src1_step, int src1_offset,
+                             __global double *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 3)& 3)
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset - (dst_align << 3)); 
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset - (dst_align << 3)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        double4 src1_data = vload4(0, (__global double *)((__global char *)src1 + src1_index));
+        double4 src2_data = vload4(0, (__global double *)((__global char *)src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data >= src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+#endif
+
diff --git a/modules/ocl/src/kernels/arithm_compare_ne.cl b/modules/ocl/src/kernels/arithm_compare_ne.cl
new file mode 100644 (file)
index 0000000..f8b6f9c
--- /dev/null
@@ -0,0 +1,688 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jiang Liyuan, jlyuan001.good@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*/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+/***********************************Compare NE*******************************/
+__kernel void arithm_compare_ne_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                             __global uchar *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data != src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+
+
+__kernel void arithm_compare_ne_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                             __global ushort *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1)& 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        ushort4 src1_data = vload4(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort4 src2_data = vload4(0, (__global ushort *)((__global char *)src2 + src2_index));
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data != src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+
+
+__kernel void arithm_compare_ne_D3 (__global short *src1, int src1_step, int src1_offset,
+                             __global short *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1)& 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        short4 src1_data = vload4(0, (__global short *)((__global char *)src1 + src1_index));
+        short4 src2_data = vload4(0, (__global short *)((__global char *)src2 + src2_index));
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data != src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+__kernel void arithm_compare_ne_D4 (__global int *src1, int src1_step, int src1_offset,
+                             __global int *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+        #define dst_align ((dst_offset >> 2)& 3)
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset - (dst_align << 2)); 
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset - (dst_align << 2)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        int4 src1_data = vload4(0, (__global int *)((__global char *)src1 + src1_index));
+        int4 src2_data = vload4(0, (__global int *)((__global char *)src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data != src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+__kernel void arithm_compare_ne_D5 (__global float *src1, int src1_step, int src1_offset,
+                             __global float *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+        #define dst_align ((dst_offset >> 2) & 3)
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset - (dst_align << 2)); 
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset - (dst_align << 2)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        float4 src1_data = vload4(0, (__global float *)((__global char *)src1 + src1_index));
+        float4 src2_data = vload4(0, (__global float *)((__global char *)src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data != src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_compare_ne_D6 (__global double *src1, int src1_step, int src1_offset,
+                             __global double *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+        #define dst_align ((dst_offset >> 3) & 3)
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset - (dst_align << 3)); 
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset - (dst_align << 3)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        double4 src1_data = vload4(0, (__global double *)((__global char *)src1 + src1_index));
+        double4 src2_data = vload4(0, (__global double *)((__global char *)src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data != src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+#endif
+
+   
+/***********************************Compare LT*******************************/
+__kernel void arithm_compare_lt_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                             __global uchar *src2, int src2_step, int src2_offset,
+                             __global  uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data < src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+
+
+__kernel void arithm_compare_lt_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                             __global ushort *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        ushort4 src1_data = vload4(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort4 src2_data = vload4(0, (__global ushort *)((__global char *)src2 + src2_index));
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data < src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+
+
+__kernel void arithm_compare_lt_D3 (__global short *src1, int src1_step, int src1_offset,
+                             __global short *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        short4 src1_data = vload4(0, (__global short *)((__global char *)src1 + src1_index));
+        short4 src2_data = vload4(0, (__global short *)((__global char *)src2 + src2_index));
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data < src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+__kernel void arithm_compare_lt_D4 (__global int *src1, int src1_step, int src1_offset,
+                             __global int *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+        #define dst_align ((dst_offset >> 2) & 3)
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset - (dst_align << 2)); 
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset - (dst_align << 2)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        int4 src1_data = vload4(0, (__global int *)((__global char *)src1 + src1_index));
+        int4 src2_data = vload4(0, (__global int *)((__global char *)src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data < src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+__kernel void arithm_compare_lt_D5 (__global float *src1, int src1_step, int src1_offset,
+                             __global float *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+        #define dst_align ((dst_offset >> 2) & 3)
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset - (dst_align << 2)); 
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset - (dst_align << 2)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        float4 src1_data = vload4(0, (__global float *)((__global char *)src1 + src1_index));
+        float4 src2_data = vload4(0, (__global float *)((__global char *)src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data < src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_compare_lt_D6 (__global double *src1, int src1_step, int src1_offset,
+                             __global double *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+        #define dst_align ((dst_offset >> 3) & 3)
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset - (dst_align << 3)); 
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset - (dst_align << 3)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        double4 src1_data = vload4(0, (__global double *)((__global char *)src1 + src1_index));
+        double4 src2_data = vload4(0, (__global double *)((__global char *)src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data < src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+#endif
+
+/***********************************Compare LE*******************************/
+__kernel void arithm_compare_le_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                             __global uchar *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data <= src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+
+
+__kernel void arithm_compare_le_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                             __global ushort *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        ushort4 src1_data = vload4(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort4 src2_data = vload4(0, (__global ushort *)((__global char *)src2 + src2_index));
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data <= src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+
+
+__kernel void arithm_compare_le_D3 (__global short *src1, int src1_step, int src1_offset,
+                             __global short *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        short4 src1_data = vload4(0, (__global short *)((__global char *)src1 + src1_index));
+        short4 src2_data = vload4(0, (__global short *)((__global char *)src2 + src2_index));
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data <= src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+__kernel void arithm_compare_le_D4 (__global int *src1, int src1_step, int src1_offset,
+                             __global int *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+        #define dst_align ((dst_offset >> 2)& 3)
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset - (dst_align << 2)); 
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset - (dst_align << 2)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        int4 src1_data = vload4(0, (__global int *)((__global char *)src1 + src1_index));
+        int4 src2_data = vload4(0, (__global int *)((__global char *)src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+        uchar4 tmp_data =convert_uchar4((src1_data <= src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+__kernel void arithm_compare_le_D5 (__global float *src1, int src1_step, int src1_offset,
+                             __global float *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+        #define dst_align ((dst_offset >> 2)& 3)
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset - (dst_align << 2)); 
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset - (dst_align << 2)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        float4 src1_data = vload4(0, (__global float *)((__global char *)src1 + src1_index));
+        float4 src2_data = vload4(0, (__global float *)((__global char *)src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data <= src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_compare_le_D6 (__global double *src1, int src1_step, int src1_offset,
+                             __global double *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+        #define dst_align ((dst_offset >> 3)& 3)
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset - (dst_align << 3)); 
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset - (dst_align << 3)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        double4 src1_data = vload4(0, (__global double *)((__global char *)src1 + src1_index));
+        double4 src2_data = vload4(0, (__global double *)((__global char *)src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+        uchar4 tmp_data = convert_uchar4((src1_data <= src2_data));
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+#endif
+
+
diff --git a/modules/ocl/src/kernels/arithm_div.cl b/modules/ocl/src/kernels/arithm_div.cl
new file mode 100644 (file)
index 0000000..43858f0
--- /dev/null
@@ -0,0 +1,446 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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*/
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+uchar round2_uchar(double v){
+
+    uchar v1 = convert_uchar_sat(v);
+    uchar v2 = convert_uchar_sat(v+(v>=0 ? 0.5 : -0.5));
+
+    return (((v-v1)==0.5) && (v1%2==0)) ? v1 : v2;
+}
+
+ushort round2_ushort(double v){
+
+    ushort v1 = convert_ushort_sat(v);
+    ushort v2 = convert_ushort_sat(v+(v>=0 ? 0.5 : -0.5));
+
+    return (((v-v1)==0.5) && (v1%2==0)) ? v1 : v2;
+}
+short round2_short(double v){
+
+    short v1 = convert_short_sat(v);
+    short v2 = convert_short_sat(v+(v>=0 ? 0.5 : -0.5));
+
+    return (((v-v1)==0.5) && (v1%2==0)) ? v1 : v2;
+}
+int round2_int(double v){
+
+    int v1 = convert_int_sat(v);
+    int v2 = convert_int_sat(v+(v>=0 ? 0.5 : -0.5));
+
+    return (((v-v1)==0.5) && (v1%2==0)) ? v1 : v2;
+}
+///////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////divide///////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////
+/**********************************div*********************************************/
+__kernel void arithm_div_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                             __global uchar *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1, double scalar)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+        uchar4 dst_data  = *((__global uchar4 *)(dst + dst_index));
+
+        double4 tmp      = convert_double4(src1_data) * scalar;
+
+        uchar4 tmp_data;
+        tmp_data.x = ((tmp.x == 0) || (src2_data.x == 0)) ? 0 : round2_uchar(tmp.x / (double)src2_data.x);
+        tmp_data.y = ((tmp.y == 0) || (src2_data.y == 0)) ? 0 : round2_uchar(tmp.y / (double)src2_data.y);
+        tmp_data.z = ((tmp.z == 0) || (src2_data.z == 0)) ? 0 : round2_uchar(tmp.z / (double)src2_data.z);
+        tmp_data.w = ((tmp.w == 0) || (src2_data.w == 0)) ? 0 : round2_uchar(tmp.w / (double)src2_data.w);
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+__kernel void arithm_div_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                             __global ushort *src2, int src2_step, int src2_offset,
+                             __global ushort *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1, double scalar)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        ushort4 src1_data = vload4(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort4 src2_data = vload4(0, (__global ushort *)((__global char *)src2 + src2_index));
+        ushort4 dst_data = *((__global ushort4 *)((__global char *)dst + dst_index));
+
+        double4 tmp   = convert_double4(src1_data) * scalar;
+
+        ushort4 tmp_data;
+        tmp_data.x = ((tmp.x == 0) || (src2_data.x == 0)) ? 0 : round2_ushort(tmp.x / (double)src2_data.x);
+        tmp_data.y = ((tmp.y == 0) || (src2_data.y == 0)) ? 0 : round2_ushort(tmp.y / (double)src2_data.y);
+        tmp_data.z = ((tmp.z == 0) || (src2_data.z == 0)) ? 0 : round2_ushort(tmp.z / (double)src2_data.z);
+        tmp_data.w = ((tmp.w == 0) || (src2_data.w == 0)) ? 0 : round2_ushort(tmp.w / (double)src2_data.w);
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+}
+__kernel void arithm_div_D3 (__global short *src1, int src1_step, int src1_offset,
+                             __global short *src2, int src2_step, int src2_offset,
+                             __global short *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1, double scalar)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        short4 src1_data = vload4(0, (__global short *)((__global char *)src1 + src1_index));
+        short4 src2_data = vload4(0, (__global short *)((__global char *)src2 + src2_index));
+        short4 dst_data = *((__global short4 *)((__global char *)dst + dst_index));
+
+        double4 tmp   = convert_double4(src1_data) * scalar;
+
+        short4 tmp_data;
+        tmp_data.x = ((tmp.x == 0) || (src2_data.x == 0)) ? 0 : round2_short(tmp.x / (double)src2_data.x);
+        tmp_data.y = ((tmp.y == 0) || (src2_data.y == 0)) ? 0 : round2_short(tmp.y / (double)src2_data.y);
+        tmp_data.z = ((tmp.z == 0) || (src2_data.z == 0)) ? 0 : round2_short(tmp.z / (double)src2_data.z);
+        tmp_data.w = ((tmp.w == 0) || (src2_data.w == 0)) ? 0 : round2_short(tmp.w / (double)src2_data.w);
+
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+}
+
+__kernel void arithm_div_D4 (__global int *src1, int src1_step, int src1_offset,
+                             __global int *src2, int src2_step, int src2_offset,
+                             __global int *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1, double scalar)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        int data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int data2 = *((__global int *)((__global char *)src2 + src2_index));
+
+        double tmp  = convert_double(data1) * scalar;
+        int tmp_data = (tmp == 0 || data2 == 0) ? 0 : round2_int(tmp / (convert_double)(data2));
+
+        *((__global int *)((__global char *)dst + dst_index)) =tmp_data;
+    }
+}
+
+__kernel void arithm_div_D5 (__global float *src1, int src1_step, int src1_offset,
+                             __global float *src2, int src2_step, int src2_offset,
+                             __global float *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1, double scalar)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        float data1 = *((__global float *)((__global char *)src1 + src1_index));
+        float data2 = *((__global float *)((__global char *)src2 + src2_index));
+
+        double tmp  = convert_double(data1) * scalar;
+        float tmp_data = (tmp == 0 || data2 == 0) ? 0 : convert_float(tmp / (convert_double)(data2));
+
+        *((__global float *)((__global char *)dst + dst_index)) = tmp_data;
+    }
+}
+
+__kernel void arithm_div_D6 (__global double *src1, int src1_step, int src1_offset,
+                             __global double *src2, int src2_step, int src2_offset,
+                             __global double *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1, double scalar)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        double data1 = *((__global double *)((__global char *)src1 + src1_index));
+        double data2 = *((__global double *)((__global char *)src2 + src2_index));
+
+        double tmp  = data1 * scalar;
+        double tmp_data = (tmp == 0 || data2 == 0) ? 0 : (tmp / data2);
+
+        *((__global double *)((__global char *)dst + dst_index)) = tmp_data;
+    }
+}
+/************************************div with scalar************************************/
+__kernel void arithm_s_div_D0 (__global uchar *src, int src_step, int src_offset,
+                               __global uchar *dst,  int dst_step,  int dst_offset,
+                               int rows, int cols, int dst_step1, double scalar)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src_index = mad24(y, src_step, x + src_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src_data = vload4(0, src + src_index);
+        uchar4 dst_data  = *((__global uchar4 *)(dst + dst_index));
+
+        uchar4 tmp_data;
+        tmp_data.x = ((scalar == 0) || (src_data.x == 0)) ? 0 : round2_uchar(scalar / (double)src_data.x);
+        tmp_data.y = ((scalar == 0) || (src_data.y == 0)) ? 0 : round2_uchar(scalar / (double)src_data.y);
+        tmp_data.z = ((scalar == 0) || (src_data.z == 0)) ? 0 : round2_uchar(scalar / (double)src_data.z);
+        tmp_data.w = ((scalar == 0) || (src_data.w == 0)) ? 0 : round2_uchar(scalar / (double)src_data.w);
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+
+__kernel void arithm_s_div_D2 (__global ushort *src, int src_step, int src_offset,
+                               __global ushort *dst,  int dst_step,  int dst_offset,
+                               int rows, int cols, int dst_step1, double scalar)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src_index = mad24(y, src_step, (x << 1) + src_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        ushort4 src_data = vload4(0, (__global ushort *)((__global char *)src + src_index));
+        ushort4 dst_data = *((__global ushort4 *)((__global char *)dst + dst_index));
+
+        ushort4 tmp_data;
+        tmp_data.x = ((scalar == 0) || (src_data.x == 0)) ? 0 : round2_ushort(scalar / (double)src_data.x);
+        tmp_data.y = ((scalar == 0) || (src_data.y == 0)) ? 0 : round2_ushort(scalar / (double)src_data.y);
+        tmp_data.z = ((scalar == 0) || (src_data.z == 0)) ? 0 : round2_ushort(scalar / (double)src_data.z);
+        tmp_data.w = ((scalar == 0) || (src_data.w == 0)) ? 0 : round2_ushort(scalar / (double)src_data.w);
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+}
+__kernel void arithm_s_div_D3 (__global short *src, int src_step, int src_offset,
+                               __global short *dst,  int dst_step,  int dst_offset,
+                               int rows, int cols, int dst_step1, double scalar)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src_index = mad24(y, src_step, (x << 1) + src_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        short4 src_data = vload4(0, (__global short *)((__global char *)src + src_index));
+        short4 dst_data = *((__global short4 *)((__global char *)dst + dst_index));
+
+        short4 tmp_data;
+        tmp_data.x = ((scalar == 0) || (src_data.x == 0)) ? 0 : round2_short(scalar / (double)src_data.x);
+        tmp_data.y = ((scalar == 0) || (src_data.y == 0)) ? 0 : round2_short(scalar / (double)src_data.y);
+        tmp_data.z = ((scalar == 0) || (src_data.z == 0)) ? 0 : round2_short(scalar / (double)src_data.z);
+        tmp_data.w = ((scalar == 0) || (src_data.w == 0)) ? 0 : round2_short(scalar / (double)src_data.w);
+
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+}
+
+__kernel void arithm_s_div_D4 (__global int *src, int src_step, int src_offset,
+                               __global int *dst,  int dst_step,  int dst_offset,
+                               int rows, int cols, int dst_step1, double scalar)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src_index = mad24(y, src_step, (x << 2) + src_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        int data = *((__global int *)((__global char *)src + src_index));
+
+        int tmp_data = (scalar == 0 || data == 0) ? 0 : round2_int(scalar / (convert_double)(data));
+
+        *((__global int *)((__global char *)dst + dst_index)) =tmp_data;
+    }
+}
+
+__kernel void arithm_s_div_D5 (__global float *src, int src_step, int src_offset,
+                               __global float *dst,  int dst_step,  int dst_offset,
+                               int rows, int cols, int dst_step1, double scalar)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src_index = mad24(y, src_step, (x << 2) + src_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        float data = *((__global float *)((__global char *)src + src_index));
+
+        float tmp_data = (scalar == 0 || data == 0) ? 0 : convert_float(scalar / (convert_double)(data));
+
+        *((__global float *)((__global char *)dst + dst_index)) = tmp_data;
+    }
+}
+
+__kernel void arithm_s_div_D6 (__global double *src, int src_step, int src_offset,
+                               __global double *dst,  int dst_step,  int dst_offset,
+                               int rows, int cols, int dst_step1, double scalar)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src_index = mad24(y, src_step, (x << 3) + src_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        double data = *((__global double *)((__global char *)src + src_index));
+
+        double tmp_data = (scalar == 0 || data == 0) ? 0 : (scalar / data);
+
+        *((__global double *)((__global char *)dst + dst_index)) = tmp_data;
+    }
+}
+
+
diff --git a/modules/ocl/src/kernels/arithm_exp.cl b/modules/ocl/src/kernels/arithm_exp.cl
new file mode 100644 (file)
index 0000000..18f7f01
--- /dev/null
@@ -0,0 +1,89 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+//  By downloading, copying, installing or using the software you agree to this license.
+//  If you do not agree to this license, do not download, install,
+//  copy or use the software.
+//
+//
+//                           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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Wu Zailong, bullet@yeah.net
+//
+// 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*/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////EXP//////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+
+__kernel void arithm_exp_D5(int rows, int cols, int srcStep, int dstStep, int srcOffset, int dstOffset, __global float *src, __global float *dst)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if(x < cols && y < rows)
+    {
+      x = x << 2;
+      int srcIdx = mad24( y, srcStep, x + srcOffset);
+      int dstIdx = mad24( y, dstStep, x + dstOffset);
+
+      float src_data = *((__global float *)((__global char *)src + srcIdx));
+      float dst_data = exp(src_data);
+
+      *((__global float *)((__global char *)dst + dstIdx)) = dst_data;
+
+    }
+}
+__kernel void arithm_exp_D6(int rows, int cols, int srcStep, int dstStep, int srcOffset, int dstOffset, __global double *src, __global double *dst)
+{
+  int x = get_global_id(0);
+  int y = get_global_id(1);
+  if(x < cols && y < rows )
+  {
+      x = x << 3;
+      int srcIdx = mad24( y, srcStep, x + srcOffset);
+      int dstIdx = mad24( y, dstStep, x + dstOffset);
+
+      double src_data = *((__global double *)((__global char *)src + srcIdx));
+      double dst_data = exp(src_data);
+      
+      *((__global double *)((__global char *)dst + dstIdx )) = dst_data;
+     // dst[dstIdx] = exp(src[srcIdx]);
+  }
+}
diff --git a/modules/ocl/src/kernels/arithm_flip.cl b/modules/ocl/src/kernels/arithm_flip.cl
new file mode 100644 (file)
index 0000000..0e12021
--- /dev/null
@@ -0,0 +1,992 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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*/
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////flip rows/////////////////////////////////////////////// 
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void arithm_flip_rows_D0 (__global uchar *src, int src_step, int src_offset,
+                                   __global uchar *dst, int dst_step, int dst_offset,
+                                   int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src_index_0 = mad24(y,            src_step, x + src_offset - dst_align); 
+        int src_index_1 = mad24(rows - y - 1, src_step, x + src_offset - dst_align); 
+
+        int dst_start_0  = mad24(y,            dst_step, dst_offset);
+        int dst_start_1  = mad24(rows - y - 1, dst_step, dst_offset);
+        int dst_end_0    = mad24(y,            dst_step, dst_offset + dst_step1);
+        int dst_end_1    = mad24(rows - y - 1, dst_step, dst_offset + dst_step1);
+        int dst_index_0  = mad24(y,            dst_step, dst_offset + x & (int)0xfffffffc);
+        int dst_index_1  = mad24(rows - y - 1, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src_data_0 = vload4(0, src + src_index_0);
+        uchar4 src_data_1 = vload4(0, src + src_index_1);
+
+        uchar4 dst_data_0 = *((__global uchar4 *)(dst + dst_index_0));
+        uchar4 dst_data_1 = *((__global uchar4 *)(dst + dst_index_1));
+
+        dst_data_0.x =  (dst_index_0 + 0 >= dst_start_0)                                   ? src_data_1.x : dst_data_0.x;
+        dst_data_0.y = ((dst_index_0 + 1 >= dst_start_0) && (dst_index_0 + 1 < dst_end_0)) ? src_data_1.y : dst_data_0.y;
+        dst_data_0.z = ((dst_index_0 + 2 >= dst_start_0) && (dst_index_0 + 2 < dst_end_0)) ? src_data_1.z : dst_data_0.z;
+        dst_data_0.w =  (dst_index_0 + 3 < dst_end_0)                                      ? src_data_1.w : dst_data_0.w;
+
+        dst_data_1.x =  (dst_index_1 + 0 >= dst_start_1)                                   ? src_data_0.x : dst_data_1.x;
+        dst_data_1.y = ((dst_index_1 + 1 >= dst_start_1) && (dst_index_1 + 1 < dst_end_1)) ? src_data_0.y : dst_data_1.y;
+        dst_data_1.z = ((dst_index_1 + 2 >= dst_start_1) && (dst_index_1 + 2 < dst_end_1)) ? src_data_0.z : dst_data_1.z;
+        dst_data_1.w =  (dst_index_1 + 3 < dst_end_1)                                      ? src_data_0.w : dst_data_1.w;
+
+        *((__global uchar4 *)(dst + dst_index_0)) = dst_data_0;
+        *((__global uchar4 *)(dst + dst_index_1)) = dst_data_1;
+    }
+}
+__kernel void arithm_flip_rows_D1 (__global char *src, int src_step, int src_offset,
+                                   __global char *dst, int dst_step, int dst_offset,
+                                   int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src_index_0 = mad24(y,            src_step, x + src_offset - dst_align); 
+        int src_index_1 = mad24(rows - y - 1, src_step, x + src_offset - dst_align); 
+
+        int dst_start_0  = mad24(y,            dst_step, dst_offset);
+        int dst_start_1  = mad24(rows - y - 1, dst_step, dst_offset);
+        int dst_end_0    = mad24(y,            dst_step, dst_offset + dst_step1);
+        int dst_end_1    = mad24(rows - y - 1, dst_step, dst_offset + dst_step1);
+        int dst_index_0  = mad24(y,            dst_step, dst_offset + x & (int)0xfffffffc);
+        int dst_index_1  = mad24(rows - y - 1, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        char4 src_data_0 = vload4(0, src + src_index_0);
+        char4 src_data_1 = vload4(0, src + src_index_1);
+
+        char4 dst_data_0 = *((__global char4 *)(dst + dst_index_0));
+        char4 dst_data_1 = *((__global char4 *)(dst + dst_index_1));
+
+        dst_data_0.x =  (dst_index_0 + 0 >= dst_start_0)                                   ? src_data_1.x : dst_data_0.x;
+        dst_data_0.y = ((dst_index_0 + 1 >= dst_start_0) && (dst_index_0 + 1 < dst_end_0)) ? src_data_1.y : dst_data_0.y;
+        dst_data_0.z = ((dst_index_0 + 2 >= dst_start_0) && (dst_index_0 + 2 < dst_end_0)) ? src_data_1.z : dst_data_0.z;
+        dst_data_0.w =  (dst_index_0 + 3 < dst_end_0)                                      ? src_data_1.w : dst_data_0.w;
+
+        dst_data_1.x =  (dst_index_1 + 0 >= dst_start_1)                                   ? src_data_0.x : dst_data_1.x;
+        dst_data_1.y = ((dst_index_1 + 1 >= dst_start_1) && (dst_index_1 + 1 < dst_end_1)) ? src_data_0.y : dst_data_1.y;
+        dst_data_1.z = ((dst_index_1 + 2 >= dst_start_1) && (dst_index_1 + 2 < dst_end_1)) ? src_data_0.z : dst_data_1.z;
+        dst_data_1.w =  (dst_index_1 + 3 < dst_end_1)                                      ? src_data_0.w : dst_data_1.w;
+
+        *((__global char4 *)(dst + dst_index_0)) = dst_data_0;
+        *((__global char4 *)(dst + dst_index_1)) = dst_data_1;
+    }
+}
+__kernel void arithm_flip_rows_D2 (__global ushort *src, int src_step, int src_offset,
+                                   __global ushort *dst, int dst_step, int dst_offset,
+                                   int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset >> 1) & 3) << 1)
+        int src_index_0 = mad24(y,            src_step, (x << 1) + src_offset - dst_align); 
+        int src_index_1 = mad24(rows - y - 1, src_step, (x << 1) + src_offset - dst_align); 
+
+        int dst_start_0  = mad24(y,            dst_step, dst_offset);
+        int dst_start_1  = mad24(rows - y - 1, dst_step, dst_offset);
+        int dst_end_0    = mad24(y,            dst_step, dst_offset + dst_step1);
+        int dst_end_1    = mad24(rows - y - 1, dst_step, dst_offset + dst_step1);
+        int dst_index_0  = mad24(y,            dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+        int dst_index_1  = mad24(rows - y - 1, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        ushort4 src_data_0 = vload4(0, (__global ushort *)((__global char *)src + src_index_0));
+        ushort4 src_data_1 = vload4(0, (__global ushort *)((__global char *)src + src_index_1));
+
+        ushort4 dst_data_0 = *((__global ushort4 *)((__global char *)dst + dst_index_0));
+        ushort4 dst_data_1 = *((__global ushort4 *)((__global char *)dst + dst_index_1));
+
+        dst_data_0.x =  (dst_index_0 + 0 >= dst_start_0)                                   ? src_data_1.x : dst_data_0.x;
+        dst_data_0.y = ((dst_index_0 + 2 >= dst_start_0) && (dst_index_0 + 2 < dst_end_0)) ? src_data_1.y : dst_data_0.y;
+        dst_data_0.z = ((dst_index_0 + 4 >= dst_start_0) && (dst_index_0 + 4 < dst_end_0)) ? src_data_1.z : dst_data_0.z;
+        dst_data_0.w =  (dst_index_0 + 6 < dst_end_0)                                      ? src_data_1.w : dst_data_0.w;
+
+        dst_data_1.x =  (dst_index_1 + 0 >= dst_start_1)                                   ? src_data_0.x : dst_data_1.x;
+        dst_data_1.y = ((dst_index_1 + 2 >= dst_start_1) && (dst_index_1 + 2 < dst_end_1)) ? src_data_0.y : dst_data_1.y;
+        dst_data_1.z = ((dst_index_1 + 4 >= dst_start_1) && (dst_index_1 + 4 < dst_end_1)) ? src_data_0.z : dst_data_1.z;
+        dst_data_1.w =  (dst_index_1 + 6 < dst_end_1)                                      ? src_data_0.w : dst_data_1.w;
+
+        *((__global ushort4 *)((__global char *)dst + dst_index_0)) = dst_data_0;
+        *((__global ushort4 *)((__global char *)dst + dst_index_1)) = dst_data_1;
+    }
+}
+__kernel void arithm_flip_rows_D3 (__global short *src, int src_step, int src_offset,
+                                   __global short *dst, int dst_step, int dst_offset,
+                                   int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset >> 1) & 3) << 1)
+        int src_index_0 = mad24(y,            src_step, (x << 1) + src_offset - dst_align); 
+        int src_index_1 = mad24(rows - y - 1, src_step, (x << 1) + src_offset - dst_align); 
+
+        int dst_start_0  = mad24(y,            dst_step, dst_offset);
+        int dst_start_1  = mad24(rows - y - 1, dst_step, dst_offset);
+        int dst_end_0    = mad24(y,            dst_step, dst_offset + dst_step1);
+        int dst_end_1    = mad24(rows - y - 1, dst_step, dst_offset + dst_step1);
+        int dst_index_0  = mad24(y,            dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+        int dst_index_1  = mad24(rows - y - 1, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        short4 src_data_0 = vload4(0, (__global short *)((__global char *)src + src_index_0));
+        short4 src_data_1 = vload4(0, (__global short *)((__global char *)src + src_index_1));
+
+        short4 dst_data_0 = *((__global short4 *)((__global char *)dst + dst_index_0));
+        short4 dst_data_1 = *((__global short4 *)((__global char *)dst + dst_index_1));
+
+        dst_data_0.x =  (dst_index_0 + 0 >= dst_start_0)                                   ? src_data_1.x : dst_data_0.x;
+        dst_data_0.y = ((dst_index_0 + 2 >= dst_start_0) && (dst_index_0 + 2 < dst_end_0)) ? src_data_1.y : dst_data_0.y;
+        dst_data_0.z = ((dst_index_0 + 4 >= dst_start_0) && (dst_index_0 + 4 < dst_end_0)) ? src_data_1.z : dst_data_0.z;
+        dst_data_0.w =  (dst_index_0 + 6 < dst_end_0)                                      ? src_data_1.w : dst_data_0.w;
+
+        dst_data_1.x =  (dst_index_1 + 0 >= dst_start_1)                                   ? src_data_0.x : dst_data_1.x;
+        dst_data_1.y = ((dst_index_1 + 2 >= dst_start_1) && (dst_index_1 + 2 < dst_end_1)) ? src_data_0.y : dst_data_1.y;
+        dst_data_1.z = ((dst_index_1 + 4 >= dst_start_1) && (dst_index_1 + 4 < dst_end_1)) ? src_data_0.z : dst_data_1.z;
+        dst_data_1.w =  (dst_index_1 + 6 < dst_end_1)                                      ? src_data_0.w : dst_data_1.w;
+
+        *((__global short4 *)((__global char *)dst + dst_index_0)) = dst_data_0;
+        *((__global short4 *)((__global char *)dst + dst_index_1)) = dst_data_1;
+    }
+}
+
+__kernel void arithm_flip_rows_D4 (__global int *src, int src_step, int src_offset,
+                                   __global int *dst, int dst_step, int dst_offset,
+                                   int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 2) + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, (x << 2) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 2) + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, (x << 2) + dst_offset);
+
+        int data0 = *((__global int *)((__global char *)src + src_index_0));
+        int data1 = *((__global int *)((__global char *)src + src_index_1));
+
+        *((__global int *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global int *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_rows_D5 (__global float *src, int src_step, int src_offset,
+                                   __global float *dst, int dst_step, int dst_offset,
+                                   int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 2) + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, (x << 2) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 2) + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, (x << 2) + dst_offset);
+
+        float data0 = *((__global float *)((__global char *)src + src_index_0));
+        float data1 = *((__global float *)((__global char *)src + src_index_1));
+
+        *((__global float *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global float *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_flip_rows_D6 (__global double *src, int src_step, int src_offset,
+                                   __global double *dst, int dst_step, int dst_offset,
+                                   int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 3) + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, (x << 3) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 3) + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, (x << 3) + dst_offset);
+
+        double data0 = *((__global double *)((__global char *)src + src_index_0));
+        double data1 = *((__global double *)((__global char *)src + src_index_1));
+
+        *((__global double *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global double *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+#endif
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////flip cols/////////////////////////////////////////////// 
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void arithm_flip_cols_C1_D0 (__global uchar *src, int src_step, int src_offset,
+                                      __global uchar *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x)           + src_offset);
+        int src_index_1 = mad24(y, src_step, (cols - x -1) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x)           + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, (cols - x -1) + dst_offset);
+
+        uchar data0 = *(src + src_index_0);
+        uchar data1 = *(src + src_index_1);
+
+        *(dst + dst_index_0) = data1;
+        *(dst + dst_index_1) = data0;
+    }
+}
+__kernel void arithm_flip_cols_C1_D1 (__global char *src, int src_step, int src_offset,
+                                      __global char *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x)           + src_offset);
+        int src_index_1 = mad24(y, src_step, (cols - x -1) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x)           + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, (cols - x -1) + dst_offset);
+
+        char data0 = *(src + src_index_0);
+        char data1 = *(src + src_index_1);
+
+        *(dst + dst_index_0) = data1;
+        *(dst + dst_index_1) = data0;
+    }
+}
+__kernel void arithm_flip_cols_C1_D2 (__global ushort *src, int src_step, int src_offset,
+                                      __global ushort *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x << 1)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) << 1) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x << 1)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) << 1) + dst_offset);
+
+        ushort data0 = *((__global ushort *)((__global char *)src + src_index_0));
+        ushort data1 = *((__global ushort *)((__global char *)src + src_index_1));
+
+        *((__global ushort *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global ushort *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_cols_C1_D3 (__global short *src, int src_step, int src_offset,
+                                      __global short *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x << 1)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) << 1) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x << 1)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) << 1) + dst_offset);
+
+        short data0 = *((__global short *)((__global char *)src + src_index_0));
+        short data1 = *((__global short *)((__global char *)src + src_index_1));
+
+        *((__global short *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global short *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_cols_C1_D4 (__global int *src, int src_step, int src_offset,
+                                      __global int *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x << 2)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) << 2) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x << 2)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) << 2) + dst_offset);
+
+        int data0 = *((__global int *)((__global char *)src + src_index_0));
+        int data1 = *((__global int *)((__global char *)src + src_index_1));
+
+        *((__global int *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global int *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_cols_C1_D5 (__global float *src, int src_step, int src_offset,
+                                      __global float *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x << 2)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) << 2) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x << 2)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) << 2) + dst_offset);
+
+        float data0 = *((__global float *)((__global char *)src + src_index_0));
+        float data1 = *((__global float *)((__global char *)src + src_index_1));
+
+        *((__global float *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global float *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_flip_cols_C1_D6 (__global double *src, int src_step, int src_offset,
+                                      __global double *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x << 3)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) << 3) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x << 3)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) << 3) + dst_offset);
+
+        double data0 = *((__global double *)((__global char *)src + src_index_0));
+        double data1 = *((__global double *)((__global char *)src + src_index_1));
+
+        *((__global double *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global double *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+#endif
+__kernel void arithm_flip_cols_C2_D0 (__global uchar *src, int src_step, int src_offset,
+                                      __global uchar *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x << 1)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) << 1) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x << 1)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) << 1) + dst_offset);
+
+        uchar2 data0 = *((__global uchar2 *)((__global char *)src + src_index_0));
+        uchar2 data1 = *((__global uchar2 *)((__global char *)src + src_index_1));
+
+        *((__global uchar2 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global uchar2 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_cols_C2_D1 (__global char *src, int src_step, int src_offset,
+                                      __global char *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x << 1)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) << 1) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x << 1)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) << 1) + dst_offset);
+
+        char2 data0 = *((__global char2 *)((__global char *)src + src_index_0));
+        char2 data1 = *((__global char2 *)((__global char *)src + src_index_1));
+
+        *((__global char2 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global char2 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_cols_C2_D2 (__global ushort *src, int src_step, int src_offset,
+                                      __global ushort *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x << 2)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) << 2) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x << 2)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) << 2) + dst_offset);
+
+        ushort2 data0 = *((__global ushort2 *)((__global char *)src + src_index_0));
+        ushort2 data1 = *((__global ushort2 *)((__global char *)src + src_index_1));
+
+        *((__global ushort2 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global ushort2 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_cols_C2_D3 (__global short *src, int src_step, int src_offset,
+                                      __global short *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x << 2)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) << 2) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x << 2)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) << 2) + dst_offset);
+
+        short2 data0 = *((__global short2 *)((__global char *)src + src_index_0));
+        short2 data1 = *((__global short2 *)((__global char *)src + src_index_1));
+
+        *((__global short2 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global short2 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_cols_C2_D4 (__global int *src, int src_step, int src_offset,
+                                      __global int *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x << 3)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) << 3) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x << 3)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) << 3) + dst_offset);
+
+        int2 data0 = *((__global int2 *)((__global char *)src + src_index_0));
+        int2 data1 = *((__global int2 *)((__global char *)src + src_index_1));
+
+        *((__global int2 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global int2 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_cols_C2_D5 (__global float *src, int src_step, int src_offset,
+                                      __global float *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x << 3)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) << 3) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x << 3)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) << 3) + dst_offset);
+
+        float2 data0 = *((__global float2 *)((__global char *)src + src_index_0));
+        float2 data1 = *((__global float2 *)((__global char *)src + src_index_1));
+
+        *((__global float2 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global float2 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_flip_cols_C2_D6 (__global double *src, int src_step, int src_offset,
+                                      __global double *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x << 4)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) << 4) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x << 4)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) << 4) + dst_offset);
+
+        double2 data0 = *((__global double2 *)((__global char *)src + src_index_0));
+        double2 data1 = *((__global double2 *)((__global char *)src + src_index_1));
+
+        *((__global double2 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global double2 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+#endif
+
+__kernel void arithm_flip_cols_C3_D0 (__global uchar *src, int src_step, int src_offset,
+                                      __global uchar *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x) * 3           + src_offset);
+        int src_index_1 = mad24(y, src_step, (cols - x -1) * 3 + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x) * 3           + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, (cols - x -1) * 3 + dst_offset);
+
+        uchar data0_0 = *(src + src_index_0 + 0);
+        uchar data0_1 = *(src + src_index_0 + 1);
+        uchar data0_2 = *(src + src_index_0 + 2);
+
+        uchar data1_0 = *(src + src_index_1 + 0);
+        uchar data1_1 = *(src + src_index_1 + 1);
+        uchar data1_2 = *(src + src_index_1 + 2);
+
+        *(dst + dst_index_0 + 0 ) = data1_0;
+        *(dst + dst_index_0 + 1 ) = data1_1;
+        *(dst + dst_index_0 + 2 ) = data1_2;
+
+        *(dst + dst_index_1 + 0) = data0_0;
+        *(dst + dst_index_1 + 1) = data0_1;
+        *(dst + dst_index_1 + 2) = data0_2;
+    }
+}
+__kernel void arithm_flip_cols_C3_D1 (__global char *src, int src_step, int src_offset,
+                                      __global char *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x) * 3           + src_offset);
+        int src_index_1 = mad24(y, src_step, (cols - x -1) * 3 + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x) * 3           + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, (cols - x -1) * 3 + dst_offset);
+
+        char data0_0 = *(src + src_index_0 + 0);
+        char data0_1 = *(src + src_index_0 + 1);
+        char data0_2 = *(src + src_index_0 + 2);
+
+        char data1_0 = *(src + src_index_1 + 0);
+        char data1_1 = *(src + src_index_1 + 1);
+        char data1_2 = *(src + src_index_1 + 2);
+
+        *(dst + dst_index_0 + 0 ) = data1_0;
+        *(dst + dst_index_0 + 1 ) = data1_1;
+        *(dst + dst_index_0 + 2 ) = data1_2;
+
+        *(dst + dst_index_1 + 0) = data0_0;
+        *(dst + dst_index_1 + 1) = data0_1;
+        *(dst + dst_index_1 + 2) = data0_2;
+    }
+}
+__kernel void arithm_flip_cols_C3_D2 (__global ushort *src, int src_step, int src_offset,
+                                      __global ushort *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x * 3 << 1)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) * 3 << 1) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x * 3 << 1)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) * 3 << 1) + dst_offset);
+
+        ushort data0_0 = *((__global ushort *)((__global char *)src + src_index_0 + 0));
+        ushort data0_1 = *((__global ushort *)((__global char *)src + src_index_0 + 2));
+        ushort data0_2 = *((__global ushort *)((__global char *)src + src_index_0 + 4));
+
+        ushort data1_0 = *((__global ushort *)((__global char *)src + src_index_1 + 0));
+        ushort data1_1 = *((__global ushort *)((__global char *)src + src_index_1 + 2));
+        ushort data1_2 = *((__global ushort *)((__global char *)src + src_index_1 + 4));
+
+        *((__global ushort *)((__global char *)dst + dst_index_0 + 0)) = data1_0;
+        *((__global ushort *)((__global char *)dst + dst_index_0 + 2)) = data1_1;
+        *((__global ushort *)((__global char *)dst + dst_index_0 + 4)) = data1_2;
+
+        *((__global ushort *)((__global char *)dst + dst_index_1 + 0)) = data0_0;
+        *((__global ushort *)((__global char *)dst + dst_index_1 + 2)) = data0_1;
+        *((__global ushort *)((__global char *)dst + dst_index_1 + 4)) = data0_2;
+    }
+}
+__kernel void arithm_flip_cols_C3_D3 (__global short *src, int src_step, int src_offset,
+                                      __global short *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x * 3 << 1)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) * 3 << 1) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x * 3 << 1)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) * 3 << 1) + dst_offset);
+
+        short data0_0 = *((__global short *)((__global char *)src + src_index_0 + 0));
+        short data0_1 = *((__global short *)((__global char *)src + src_index_0 + 2));
+        short data0_2 = *((__global short *)((__global char *)src + src_index_0 + 4));
+
+        short data1_0 = *((__global short *)((__global char *)src + src_index_1 + 0));
+        short data1_1 = *((__global short *)((__global char *)src + src_index_1 + 2));
+        short data1_2 = *((__global short *)((__global char *)src + src_index_1 + 4));
+
+        *((__global short *)((__global char *)dst + dst_index_0 + 0)) = data1_0;
+        *((__global short *)((__global char *)dst + dst_index_0 + 2)) = data1_1;
+        *((__global short *)((__global char *)dst + dst_index_0 + 4)) = data1_2;
+
+        *((__global short *)((__global char *)dst + dst_index_1 + 0)) = data0_0;
+        *((__global short *)((__global char *)dst + dst_index_1 + 2)) = data0_1;
+        *((__global short *)((__global char *)dst + dst_index_1 + 4)) = data0_2;
+    }
+}
+__kernel void arithm_flip_cols_C3_D4 (__global int *src, int src_step, int src_offset,
+                                      __global int *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x * 3 << 2)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) * 3 << 2) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x * 3 << 2)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) * 3 << 2) + dst_offset);
+
+        int data0_0 = *((__global int *)((__global char *)src + src_index_0 + 0));
+        int data0_1 = *((__global int *)((__global char *)src + src_index_0 + 4));
+        int data0_2 = *((__global int *)((__global char *)src + src_index_0 + 8));
+           
+        int data1_0 = *((__global int *)((__global char *)src + src_index_1 + 0));
+        int data1_1 = *((__global int *)((__global char *)src + src_index_1 + 4));
+        int data1_2 = *((__global int *)((__global char *)src + src_index_1 + 8));
+
+        *((__global int *)((__global char *)dst + dst_index_0 + 0)) = data1_0;
+        *((__global int *)((__global char *)dst + dst_index_0 + 4)) = data1_1;
+        *((__global int *)((__global char *)dst + dst_index_0 + 8)) = data1_2;
+                                                                 
+        *((__global int *)((__global char *)dst + dst_index_1 + 0)) = data0_0;
+        *((__global int *)((__global char *)dst + dst_index_1 + 4)) = data0_1;
+        *((__global int *)((__global char *)dst + dst_index_1 + 8)) = data0_2;
+    }
+}
+__kernel void arithm_flip_cols_C3_D5 (__global float *src, int src_step, int src_offset,
+                                      __global float *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x * 3 << 2)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) * 3 << 2) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x * 3 << 2)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) * 3 << 2) + dst_offset);
+
+        float data0_0 = *((__global float *)((__global char *)src + src_index_0 + 0));
+        float data0_1 = *((__global float *)((__global char *)src + src_index_0 + 4));
+        float data0_2 = *((__global float *)((__global char *)src + src_index_0 + 8));
+             
+        float data1_0 = *((__global float *)((__global char *)src + src_index_1 + 0));
+        float data1_1 = *((__global float *)((__global char *)src + src_index_1 + 4));
+        float data1_2 = *((__global float *)((__global char *)src + src_index_1 + 8));
+
+        *((__global float *)((__global char *)dst + dst_index_0 + 0)) = data1_0;
+        *((__global float *)((__global char *)dst + dst_index_0 + 4)) = data1_1;
+        *((__global float *)((__global char *)dst + dst_index_0 + 8)) = data1_2;
+                                                                   
+        *((__global float *)((__global char *)dst + dst_index_1 + 0)) = data0_0;
+        *((__global float *)((__global char *)dst + dst_index_1 + 4)) = data0_1;
+        *((__global float *)((__global char *)dst + dst_index_1 + 8)) = data0_2;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_flip_cols_C3_D6 (__global double *src, int src_step, int src_offset,
+                                      __global double *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x * 3 << 3)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) * 3 << 3) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x * 3 << 3)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) * 3 << 3) + dst_offset);
+
+        double data0_0 = *((__global double *)((__global char *)src + src_index_0 + 0));
+        double data0_1 = *((__global double *)((__global char *)src + src_index_0 + 8));
+        double data0_2 = *((__global double *)((__global char *)src + src_index_0 + 16));
+              
+        double data1_0 = *((__global double *)((__global char *)src + src_index_1 + 0));
+        double data1_1 = *((__global double *)((__global char *)src + src_index_1 + 8));
+        double data1_2 = *((__global double *)((__global char *)src + src_index_1 + 16));
+
+        *((__global double *)((__global char *)dst + dst_index_0 + 0 )) = data1_0;
+        *((__global double *)((__global char *)dst + dst_index_0 + 8 )) = data1_1;
+        *((__global double *)((__global char *)dst + dst_index_0 + 16)) = data1_2;
+                                                                    
+        *((__global double *)((__global char *)dst + dst_index_1 + 0 )) = data0_0;
+        *((__global double *)((__global char *)dst + dst_index_1 + 8 )) = data0_1;
+        *((__global double *)((__global char *)dst + dst_index_1 + 16)) = data0_2;
+    }
+}
+#endif
+__kernel void arithm_flip_cols_C4_D0 (__global uchar *src, int src_step, int src_offset,
+                                      __global uchar *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x << 2)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) << 2) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x << 2)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) << 2) + dst_offset);
+
+        uchar4 data0 = *((__global uchar4 *)(src + src_index_0));
+        uchar4 data1 = *((__global uchar4 *)(src + src_index_1));
+
+        *((__global uchar4 *)(dst + dst_index_0)) = data1;
+        *((__global uchar4 *)(dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_cols_C4_D1 (__global char *src, int src_step, int src_offset,
+                                      __global char *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x << 2)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) << 2) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x << 2)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) << 2) + dst_offset);
+
+        char4 data0 = *((__global char4 *)(src + src_index_0));
+        char4 data1 = *((__global char4 *)(src + src_index_1));
+
+        *((__global char4 *)(dst + dst_index_0)) = data1;
+        *((__global char4 *)(dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_cols_C4_D2 (__global ushort *src, int src_step, int src_offset,
+                                      __global ushort *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x << 3)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) << 3) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x << 3)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) << 3) + dst_offset);
+
+        ushort4 data0 = *((__global ushort4 *)((__global char *)src + src_index_0));
+        ushort4 data1 = *((__global ushort4 *)((__global char *)src + src_index_1));
+
+        *((__global ushort4 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global ushort4 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_cols_C4_D3 (__global short *src, int src_step, int src_offset,
+                                      __global short *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x << 3)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) << 3) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x << 3)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) << 3) + dst_offset);
+
+        short4 data0 = *((__global short4 *)((__global char *)src + src_index_0));
+        short4 data1 = *((__global short4 *)((__global char *)src + src_index_1));
+
+        *((__global short4 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global short4 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+
+__kernel void arithm_flip_cols_C4_D4 (__global int *src, int src_step, int src_offset,
+                                      __global int *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x << 4)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) << 4) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x << 4)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) << 4) + dst_offset);
+
+        int4 data0 = *((__global int4 *)((__global char *)src + src_index_0));
+        int4 data1 = *((__global int4 *)((__global char *)src + src_index_1));
+
+        *((__global int4 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global int4 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_cols_C4_D5 (__global float *src, int src_step, int src_offset,
+                                      __global float *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x << 4)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) << 4) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x << 4)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) << 4) + dst_offset);
+
+        float4 data0 = *((__global float4 *)((__global char *)src + src_index_0));
+        float4 data1 = *((__global float4 *)((__global char *)src + src_index_1));
+
+        *((__global float4 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global float4 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_flip_cols_C4_D6 (__global double *src, int src_step, int src_offset,
+                                      __global double *dst, int dst_step, int dst_offset,
+                                      int rows, int cols, int thread_cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < thread_cols && y < rows)
+    {
+        int src_index_0 = mad24(y, src_step, (x << 5)             + src_offset);
+        int src_index_1 = mad24(y, src_step, ((cols - x -1) << 5) + src_offset);
+        
+        int dst_index_0 = mad24(y, dst_step, (x << 5)             + dst_offset);
+        int dst_index_1 = mad24(y, dst_step, ((cols - x -1) << 5) + dst_offset);
+
+        double4 data0 = *((__global double4 *)((__global char *)src + src_index_0));
+        double4 data1 = *((__global double4 *)((__global char *)src + src_index_1));
+
+        *((__global double4 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global double4 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+#endif
diff --git a/modules/ocl/src/kernels/arithm_flip_rc.cl b/modules/ocl/src/kernels/arithm_flip_rc.cl
new file mode 100644 (file)
index 0000000..7b4b760
--- /dev/null
@@ -0,0 +1,753 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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*/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////flip rows and cols///////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void arithm_flip_rc_C1_D0 (__global uchar *src, int src_step, int src_offset,
+                                    __global uchar *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x)           + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, (cols - x -1) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x)           + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, (cols - x -1) + dst_offset);
+
+        uchar data0 = *(src + src_index_0);
+        uchar data1 = *(src + src_index_1);
+
+        *(dst + dst_index_0) = data1;
+        *(dst + dst_index_1) = data0;
+    }
+}
+__kernel void arithm_flip_rc_C1_D1 (__global char *src, int src_step, int src_offset,
+                                    __global char *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x)           + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, (cols - x -1) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x)           + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, (cols - x -1) + dst_offset);
+
+        char data0 = *(src + src_index_0);
+        char data1 = *(src + src_index_1);
+
+        *(dst + dst_index_0) = data1;
+        *(dst + dst_index_1) = data0;
+    }
+}
+__kernel void arithm_flip_rc_C1_D2 (__global ushort *src, int src_step, int src_offset,
+                                    __global ushort *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 1)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) << 1) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 1)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) << 1) + dst_offset);
+
+        ushort data0 = *((__global ushort *)((__global char *)src + src_index_0));
+        ushort data1 = *((__global ushort *)((__global char *)src + src_index_1));
+
+        *((__global ushort *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global ushort *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_rc_C1_D3 (__global short *src, int src_step, int src_offset,
+                                    __global short *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 1)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) << 1) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 1)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) << 1) + dst_offset);
+
+        short data0 = *((__global short *)((__global char *)src + src_index_0));
+        short data1 = *((__global short *)((__global char *)src + src_index_1));
+
+        *((__global short *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global short *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_rc_C1_D4 (__global int *src, int src_step, int src_offset,
+                                    __global int *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 2)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) << 2) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 2)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) << 2) + dst_offset);
+
+        int data0 = *((__global int *)((__global char *)src + src_index_0));
+        int data1 = *((__global int *)((__global char *)src + src_index_1));
+
+        *((__global int *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global int *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_rc_C1_D5 (__global float *src, int src_step, int src_offset,
+                                    __global float *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 2)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) << 2) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 2)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) << 2) + dst_offset);
+
+        float data0 = *((__global float *)((__global char *)src + src_index_0));
+        float data1 = *((__global float *)((__global char *)src + src_index_1));
+
+        *((__global float *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global float *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_flip_rc_C1_D6 (__global double *src, int src_step, int src_offset,
+                                    __global double *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 3)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) << 3) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 3)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) << 3) + dst_offset);
+
+        double data0 = *((__global double *)((__global char *)src + src_index_0));
+        double data1 = *((__global double *)((__global char *)src + src_index_1));
+
+        *((__global double *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global double *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+#endif
+__kernel void arithm_flip_rc_C2_D0 (__global uchar *src, int src_step, int src_offset,
+                                    __global uchar *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 1)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) << 1) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 1)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) << 1) + dst_offset);
+
+        uchar2 data0 = *((__global uchar2 *)(src + src_index_0));
+        uchar2 data1 = *((__global uchar2 *)(src + src_index_1));
+
+        *((__global uchar2 *)(dst + dst_index_0)) = data1;
+        *((__global uchar2 *)(dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_rc_C2_D1 (__global char *src, int src_step, int src_offset,
+                                    __global char *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 1)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) << 1) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 1)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) << 1) + dst_offset);
+
+        char2 data0 = *((__global char2 *)(src + src_index_0));
+        char2 data1 = *((__global char2 *)(src + src_index_1));
+
+        *((__global char2 *)(dst + dst_index_0)) = data1;
+        *((__global char2 *)(dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_rc_C2_D2 (__global ushort *src, int src_step, int src_offset,
+                                    __global ushort *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 2)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) << 2) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 2)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) << 2) + dst_offset);
+
+        ushort2 data0 = *((__global ushort2 *)((__global char *)src + src_index_0));
+        ushort2 data1 = *((__global ushort2 *)((__global char *)src + src_index_1));
+
+        *((__global ushort2 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global ushort2 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_rc_C2_D3 (__global short *src, int src_step, int src_offset,
+                                    __global short *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 2)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) << 2) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 2)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) << 2) + dst_offset);
+
+        short2 data0 = *((__global short2 *)((__global char *)src + src_index_0));
+        short2 data1 = *((__global short2 *)((__global char *)src + src_index_1));
+
+        *((__global short2 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global short2 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_rc_C2_D4 (__global int *src, int src_step, int src_offset,
+                                    __global int *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 3)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) << 3) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 3)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) << 3) + dst_offset);
+
+        int2 data0 = *((__global int2 *)((__global char *)src + src_index_0));
+        int2 data1 = *((__global int2 *)((__global char *)src + src_index_1));
+
+        *((__global int2 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global int2 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_rc_C2_D5 (__global float *src, int src_step, int src_offset,
+                                    __global float *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 3)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) << 3) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 3)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) << 3) + dst_offset);
+
+        float2 data0 = *((__global float2 *)((__global char *)src + src_index_0));
+        float2 data1 = *((__global float2 *)((__global char *)src + src_index_1));
+
+        *((__global float2 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global float2 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_flip_rc_C2_D6 (__global double *src, int src_step, int src_offset,
+                                    __global double *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 4)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) << 4) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 4)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) << 4) + dst_offset);
+
+        double2 data0 = *((__global double2 *)((__global char *)src + src_index_0));
+        double2 data1 = *((__global double2 *)((__global char *)src + src_index_1));
+
+        *((__global double2 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global double2 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+#endif
+
+__kernel void arithm_flip_rc_C3_D0 (__global uchar *src, int src_step, int src_offset,
+                                    __global uchar *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x * 3)            + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, (cols - x -1) * 3  + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x * 3)           + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, (cols - x -1) * 3 + dst_offset);
+
+
+        uchar data0_0 = *(src + src_index_0 + 0);
+        uchar data0_1 = *(src + src_index_0 + 1);
+        uchar data0_2 = *(src + src_index_0 + 2);
+
+        uchar data1_0 = *(src + src_index_1 + 0);
+        uchar data1_1 = *(src + src_index_1 + 1);
+        uchar data1_2 = *(src + src_index_1 + 2);
+
+        *(dst + dst_index_0 + 0 ) = data1_0;
+        *(dst + dst_index_0 + 1 ) = data1_1;
+        *(dst + dst_index_0 + 2 ) = data1_2;
+
+        *(dst + dst_index_1 + 0) = data0_0;
+        *(dst + dst_index_1 + 1) = data0_1;
+        *(dst + dst_index_1 + 2) = data0_2;
+    }
+}
+__kernel void arithm_flip_rc_C3_D1 (__global char *src, int src_step, int src_offset,
+                                    __global char *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x * 3)            + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, (cols - x -1) * 3  + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x * 3)           + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, (cols - x -1) * 3 + dst_offset);
+
+
+        char data0_0 = *(src + src_index_0 + 0);
+        char data0_1 = *(src + src_index_0 + 1);
+        char data0_2 = *(src + src_index_0 + 2);
+
+        char data1_0 = *(src + src_index_1 + 0);
+        char data1_1 = *(src + src_index_1 + 1);
+        char data1_2 = *(src + src_index_1 + 2);
+
+        *(dst + dst_index_0 + 0 ) = data1_0;
+        *(dst + dst_index_0 + 1 ) = data1_1;
+        *(dst + dst_index_0 + 2 ) = data1_2;
+
+        *(dst + dst_index_1 + 0) = data0_0;
+        *(dst + dst_index_1 + 1) = data0_1;
+        *(dst + dst_index_1 + 2) = data0_2;
+    }
+}
+__kernel void arithm_flip_rc_C3_D2 (__global ushort *src, int src_step, int src_offset,
+                                    __global ushort *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x * 3 << 1)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) * 3 << 1) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x * 3 << 1)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) * 3 << 1) + dst_offset);
+
+        ushort data0_0 = *((__global ushort *)((__global char *)src + src_index_0 + 0));
+        ushort data0_1 = *((__global ushort *)((__global char *)src + src_index_0 + 2));
+        ushort data0_2 = *((__global ushort *)((__global char *)src + src_index_0 + 4));
+
+        ushort data1_0 = *((__global ushort *)((__global char *)src + src_index_1 + 0));
+        ushort data1_1 = *((__global ushort *)((__global char *)src + src_index_1 + 2));
+        ushort data1_2 = *((__global ushort *)((__global char *)src + src_index_1 + 4));
+
+        *((__global ushort *)((__global char *)dst + dst_index_0 + 0)) = data1_0;
+        *((__global ushort *)((__global char *)dst + dst_index_0 + 2)) = data1_1;
+        *((__global ushort *)((__global char *)dst + dst_index_0 + 4)) = data1_2;
+
+        *((__global ushort *)((__global char *)dst + dst_index_1 + 0)) = data0_0;
+        *((__global ushort *)((__global char *)dst + dst_index_1 + 2)) = data0_1;
+        *((__global ushort *)((__global char *)dst + dst_index_1 + 4)) = data0_2;
+    }
+}
+__kernel void arithm_flip_rc_C3_D3 (__global short *src, int src_step, int src_offset,
+                                    __global short *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x * 3 << 1)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) * 3 << 1) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x * 3 << 1)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) * 3 << 1) + dst_offset);
+
+        short data0_0 = *((__global short *)((__global char *)src + src_index_0 + 0));
+        short data0_1 = *((__global short *)((__global char *)src + src_index_0 + 2));
+        short data0_2 = *((__global short *)((__global char *)src + src_index_0 + 4));
+
+        short data1_0 = *((__global short *)((__global char *)src + src_index_1 + 0));
+        short data1_1 = *((__global short *)((__global char *)src + src_index_1 + 2));
+        short data1_2 = *((__global short *)((__global char *)src + src_index_1 + 4));
+
+        *((__global short *)((__global char *)dst + dst_index_0 + 0)) = data1_0;
+        *((__global short *)((__global char *)dst + dst_index_0 + 2)) = data1_1;
+        *((__global short *)((__global char *)dst + dst_index_0 + 4)) = data1_2;
+
+        *((__global short *)((__global char *)dst + dst_index_1 + 0)) = data0_0;
+        *((__global short *)((__global char *)dst + dst_index_1 + 2)) = data0_1;
+        *((__global short *)((__global char *)dst + dst_index_1 + 4)) = data0_2;
+    }
+}
+
+__kernel void arithm_flip_rc_C3_D4 (__global int *src, int src_step, int src_offset,
+                                    __global int *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x * 3 << 2)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) * 3 << 2) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x * 3 << 2)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) * 3 << 2) + dst_offset);
+
+        int data0_0 = *((__global int *)((__global char *)src + src_index_0 + 0));
+        int data0_1 = *((__global int *)((__global char *)src + src_index_0 + 4));
+        int data0_2 = *((__global int *)((__global char *)src + src_index_0 + 8));
+           
+        int data1_0 = *((__global int *)((__global char *)src + src_index_1 + 0));
+        int data1_1 = *((__global int *)((__global char *)src + src_index_1 + 4));
+        int data1_2 = *((__global int *)((__global char *)src + src_index_1 + 8));
+
+        *((__global int *)((__global char *)dst + dst_index_0 + 0)) = data1_0;
+        *((__global int *)((__global char *)dst + dst_index_0 + 4)) = data1_1;
+        *((__global int *)((__global char *)dst + dst_index_0 + 8)) = data1_2;
+                                                                 
+        *((__global int *)((__global char *)dst + dst_index_1 + 0)) = data0_0;
+        *((__global int *)((__global char *)dst + dst_index_1 + 4)) = data0_1;
+        *((__global int *)((__global char *)dst + dst_index_1 + 8)) = data0_2;
+    }
+}
+__kernel void arithm_flip_rc_C3_D5 (__global float *src, int src_step, int src_offset,
+                                    __global float *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x * 3 << 2)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) * 3 << 2) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x * 3 << 2)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) * 3 << 2) + dst_offset);
+
+        float data0_0 = *((__global float *)((__global char *)src + src_index_0 + 0));
+        float data0_1 = *((__global float *)((__global char *)src + src_index_0 + 4));
+        float data0_2 = *((__global float *)((__global char *)src + src_index_0 + 8));
+                                                                                   
+        float data1_0 = *((__global float *)((__global char *)src + src_index_1 + 0));
+        float data1_1 = *((__global float *)((__global char *)src + src_index_1 + 4));
+        float data1_2 = *((__global float *)((__global char *)src + src_index_1 + 8));
+
+        *((__global float *)((__global char *)dst + dst_index_0 + 0)) = data1_0;
+        *((__global float *)((__global char *)dst + dst_index_0 + 4)) = data1_1;
+        *((__global float *)((__global char *)dst + dst_index_0 + 8)) = data1_2;
+                                                                   
+        *((__global float *)((__global char *)dst + dst_index_1 + 0)) = data0_0;
+        *((__global float *)((__global char *)dst + dst_index_1 + 4)) = data0_1;
+        *((__global float *)((__global char *)dst + dst_index_1 + 8)) = data0_2;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_flip_rc_C3_D6 (__global double *src, int src_step, int src_offset,
+                                    __global double *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x * 3 << 3)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) * 3 << 3) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x * 3 << 3)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) * 3 << 3) + dst_offset);
+
+        double data0_0 = *((__global double *)((__global char *)src + src_index_0 + 0 ));
+        double data0_1 = *((__global double *)((__global char *)src + src_index_0 + 8 ));
+        double data0_2 = *((__global double *)((__global char *)src + src_index_0 + 16));
+              
+        double data1_0 = *((__global double *)((__global char *)src + src_index_1 + 0 ));
+        double data1_1 = *((__global double *)((__global char *)src + src_index_1 + 8 ));
+        double data1_2 = *((__global double *)((__global char *)src + src_index_1 + 16));
+
+        *((__global double *)((__global char *)dst + dst_index_0 + 0 )) = data1_0;
+        *((__global double *)((__global char *)dst + dst_index_0 + 8 )) = data1_1;
+        *((__global double *)((__global char *)dst + dst_index_0 + 16)) = data1_2;
+                                                                     
+        *((__global double *)((__global char *)dst + dst_index_1 + 0 )) = data0_0;
+        *((__global double *)((__global char *)dst + dst_index_1 + 8 )) = data0_1;
+        *((__global double *)((__global char *)dst + dst_index_1 + 16)) = data0_2;
+    }
+}
+#endif
+__kernel void arithm_flip_rc_C4_D0 (__global uchar *src, int src_step, int src_offset,
+                                    __global uchar *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 2)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) << 2) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 2)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) << 2) + dst_offset);
+
+        uchar4 data0 = *((__global uchar4 *)(src + src_index_0));
+        uchar4 data1 = *((__global uchar4 *)(src + src_index_1));
+
+        *((__global uchar4 *)(dst + dst_index_0)) = data1;
+        *((__global uchar4 *)(dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_rc_C4_D1 (__global char *src, int src_step, int src_offset,
+                                    __global char *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 2)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) << 2) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 2)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) << 2) + dst_offset);
+
+        char4 data0 = *((__global char4 *)(src + src_index_0));
+        char4 data1 = *((__global char4 *)(src + src_index_1));
+
+        *((__global char4 *)(dst + dst_index_0)) = data1;
+        *((__global char4 *)(dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_rc_C4_D2 (__global ushort *src, int src_step, int src_offset,
+                                    __global ushort *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 3)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) << 3) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 3)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) << 3) + dst_offset);
+
+        ushort4 data0 = *((__global ushort4 *)((__global char *)src + src_index_0));
+        ushort4 data1 = *((__global ushort4 *)((__global char *)src + src_index_1));
+
+        *((__global ushort4 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global ushort4 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_rc_C4_D3 (__global short *src, int src_step, int src_offset,
+                                    __global short *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 3)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) << 3) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 3)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) << 3) + dst_offset);
+
+        short4 data0 = *((__global short4 *)((__global char *)src + src_index_0));
+        short4 data1 = *((__global short4 *)((__global char *)src + src_index_1));
+
+        *((__global short4 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global short4 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_rc_C4_D4 (__global int *src, int src_step, int src_offset,
+                                    __global int *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 4)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) << 4) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 4)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) << 4) + dst_offset);
+
+        int4 data0 = *((__global int4 *)((__global char *)src + src_index_0));
+        int4 data1 = *((__global int4 *)((__global char *)src + src_index_1));
+
+        *((__global int4 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global int4 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+__kernel void arithm_flip_rc_C4_D5 (__global float *src, int src_step, int src_offset,
+                                    __global float *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 4)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) << 4) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 4)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) << 4) + dst_offset);
+
+        float4 data0 = *((__global float4 *)((__global char *)src + src_index_0));
+        float4 data1 = *((__global float4 *)((__global char *)src + src_index_1));
+
+        *((__global float4 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global float4 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_flip_rc_C4_D6 (__global double *src, int src_step, int src_offset,
+                                    __global double *dst, int dst_step, int dst_offset,
+                                    int rows, int cols, int thread_rows, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < thread_rows)
+    {
+        int src_index_0 = mad24(y,            src_step, (x << 5)             + src_offset);
+        int src_index_1 = mad24(rows - y - 1, src_step, ((cols - x -1) << 5) + src_offset);
+        
+        int dst_index_0 = mad24(y,            dst_step, (x << 5)             + dst_offset);
+        int dst_index_1 = mad24(rows - y - 1, dst_step, ((cols - x -1) << 5) + dst_offset);
+
+        double4 data0 = *((__global double4 *)((__global char *)src + src_index_0));
+        double4 data1 = *((__global double4 *)((__global char *)src + src_index_1));
+
+        *((__global double4 *)((__global char *)dst + dst_index_0)) = data1;
+        *((__global double4 *)((__global char *)dst + dst_index_1)) = data0;
+    }
+}
+#endif
diff --git a/modules/ocl/src/kernels/arithm_log.cl b/modules/ocl/src/kernels/arithm_log.cl
new file mode 100644 (file)
index 0000000..ba93cc3
--- /dev/null
@@ -0,0 +1,94 @@
+
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Wu Zailong, bullet@yeah.net
+//
+// 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*/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+#define INF_FLOAT -88.029694
+#define INF_DOUBLE -709.0895657128241 
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////LOG/////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+
+__kernel void arithm_log_D5(int rows, int cols, int srcStep, int dstStep, int srcOffset, int dstOffset, __global float *src, __global float *dst)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if(x < cols && y < rows )
+    {
+      x = x << 2;
+      int srcIdx = mad24( y, srcStep, x + srcOffset);
+      int dstIdx = mad24( y, dstStep, x + dstOffset);
+
+      float src_data = *((__global float *)((__global char *)src + srcIdx));
+      float dst_data = (src_data == 0) ? INF_FLOAT : log(fabs(src_data));
+
+      *((__global float *)((__global char *)dst + dstIdx)) = dst_data;
+    }
+}
+
+
+__kernel void arithm_log_D6(int rows, int cols, int srcStep, int dstStep, int srcOffset, int dstOffset, __global double *src, __global double *dst)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if(x < cols && y < rows )
+    {
+      x = x << 3;
+      int srcIdx = mad24( y, srcStep, x + srcOffset);
+      int dstIdx = mad24( y, dstStep, x + dstOffset);
+
+      double src_data = *((__global double *)((__global char *)src + srcIdx));
+      double dst_data = (src_data == 0) ? INF_DOUBLE : log(fabs(src_data));
+      *((__global double *)((__global char *)dst + dstIdx)) = dst_data;
+
+    }
+}
+
diff --git a/modules/ocl/src/kernels/arithm_magnitude.cl b/modules/ocl/src/kernels/arithm_magnitude.cl
new file mode 100644 (file)
index 0000000..3403f5c
--- /dev/null
@@ -0,0 +1,96 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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
+// 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*/
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+__kernel void arithm_magnitude_D5 (__global float *src1, int src1_step, int src1_offset,
+                                   __global float *src2, int src2_step, int src2_offset,
+                                   __global float *dst,  int dst_step,  int dst_offset,
+                                  int rows, int cols)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        float data1 = *((__global float *)((__global char *)src1 + src1_index));
+        float data2 = *((__global float *)((__global char *)src2 + src2_index));
+
+        float tmp = sqrt(data1 * data1 + data2 * data2);
+
+        *((__global float *)((__global char *)dst + dst_index)) = tmp;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_magnitude_D6 (__global double *src1, int src1_step, int src1_offset,
+                                   __global double *src2, int src2_step, int src2_offset,
+                                   __global double *dst,  int dst_step,  int dst_offset,
+                                  int rows, int cols)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        double data1 = *((__global double *)((__global char *)src1 + src1_index));
+        double data2 = *((__global double *)((__global char *)src2 + src2_index));
+
+        double tmp = sqrt(data1 * data1 + data2 * data2);
+
+        *((__global double *)((__global char *)dst + dst_index)) = tmp;
+    }
+}
+#endif
diff --git a/modules/ocl/src/kernels/arithm_magnitudeSqr.cl b/modules/ocl/src/kernels/arithm_magnitudeSqr.cl
new file mode 100644 (file)
index 0000000..ba1b809
--- /dev/null
@@ -0,0 +1,153 @@
+
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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 softwareif advised of the possibility of such damage.
+//
+//M*/
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////magnitudeSqr//////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void magnitudeSqr_C1_D5 (__global float *src1,int src1_step,int src1_offset,
+                           __global float *src2, int src2_step,int src2_offset,
+                           __global float *dst,  int dst_step,int dst_offset,
+                           int rows,  int cols,int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    
+
+    {
+            
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 2) & 3)
+
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset - (dst_align << 2)); 
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset - (dst_align << 2)); 
+       
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 2) -(dst_align << 2));
+
+        float4 src1_data = vload4(0, (__global float  *)((__global char *)src1 + src1_index));
+        float4 src2_data = vload4(0, (__global float *)((__global char *)src2 + src2_index));
+        float4 dst_data = *((__global float4 *)((__global char *)dst + dst_index));
+
+        float4   tmp_data  ;
+      tmp_data.x = src1_data.x * src1_data.x + src2_data.x * src2_data.x;
+
+      tmp_data.y = src1_data.y * src1_data.y + src2_data.y * src2_data.y;
+
+      tmp_data.z = src1_data.z * src1_data.z + src2_data.z * src2_data.z;
+
+      tmp_data.w = src1_data.w * src1_data.w + src2_data.w * src2_data.w;
+
+
+
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 8 >= dst_start) && (dst_index + 8 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 12 >= dst_start) && (dst_index + 12 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global float4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+
+}
+
+
+#if defined (DOUBLE_SUPPORT)
+
+__kernel void magnitudeSqr_C2_D5 (__global float *src1,int src1_step,int src1_offset,
+                           __global float *dst,  int dst_step,int dst_offset,
+                           int rows,  int cols,int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    
+
+    {
+            
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 2) & 3)
+
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset - (dst_align << 3)); 
+       
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 2) -(dst_align << 2));
+
+        float8 src1_data = vload8(0, (__global float  *)((__global char *)src1 + src1_index));
+        float4 dst_data = *((__global float4 *)((__global char *)dst + dst_index));
+
+        float4   tmp_data  ;
+      tmp_data.x = src1_data.s0 * src1_data.s0 + src1_data.s1 * src1_data.s1;
+
+      tmp_data.y = src1_data.s2 * src1_data.s2 + src1_data.s3 * src1_data.s3;
+
+      tmp_data.z = src1_data.s4 * src1_data.s4 + src1_data.s5 * src1_data.s5;
+
+      tmp_data.w = src1_data.s6 * src1_data.s6 + src1_data.s7 * src1_data.s7;
+
+
+
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 8 >= dst_start) && (dst_index + 8 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 12 >= dst_start) && (dst_index + 12 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global float4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+
+}
+#endif
diff --git a/modules/ocl/src/kernels/arithm_minMax.cl b/modules/ocl/src/kernels/arithm_minMax.cl
new file mode 100644 (file)
index 0000000..30502d7
--- /dev/null
@@ -0,0 +1,218 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Shengen Yan,yanshengen@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 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
+// 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*/
+
+/**************************************PUBLICFUNC*************************************/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+#if defined (DEPTH_0)
+#define VEC_TYPE uchar8
+#define CONVERT_TYPE convert_uchar8
+#define MIN_VAL 0
+#define MAX_VAL 255
+#endif
+#if defined (DEPTH_1)
+#define VEC_TYPE char8
+#define CONVERT_TYPE convert_char8
+#define MIN_VAL -128 
+#define MAX_VAL 127
+#endif
+#if defined (DEPTH_2)
+#define VEC_TYPE ushort8
+#define CONVERT_TYPE convert_ushort8
+#define MIN_VAL 0 
+#define MAX_VAL 65535
+#endif
+#if defined (DEPTH_3)
+#define VEC_TYPE short8
+#define CONVERT_TYPE convert_short8
+#define MIN_VAL -32768 
+#define MAX_VAL 32767
+#endif
+#if defined (DEPTH_4)
+#define VEC_TYPE int8
+#define CONVERT_TYPE convert_int8
+#define MIN_VAL INT_MIN 
+#define MAX_VAL INT_MAX
+#endif
+#if defined (DEPTH_5)
+#define VEC_TYPE float8
+#define CONVERT_TYPE convert_float8
+#define MIN_VAL (-FLT_MAX) 
+#define MAX_VAL FLT_MAX
+#endif
+#if defined (DEPTH_6)
+#define VEC_TYPE double8
+#define CONVERT_TYPE convert_double8
+#define MIN_VAL (-DBL_MAX) 
+#define MAX_VAL DBL_MAX
+#endif
+
+#if defined (REPEAT_S0)
+#define repeat_s(a) a = a;
+#endif
+#if defined (REPEAT_S1)
+#define repeat_s(a) a.s0 = a.s1;
+#endif
+#if defined (REPEAT_S2)
+#define repeat_s(a) a.s0 = a.s2;a.s1 = a.s2;
+#endif
+#if defined (REPEAT_S3)
+#define repeat_s(a) a.s0 = a.s3;a.s1 = a.s3;a.s2 = a.s3;
+#endif
+#if defined (REPEAT_S4)
+#define repeat_s(a) a.s0 = a.s4;a.s1 = a.s4;a.s2 = a.s4;a.s3 = a.s4;
+#endif
+#if defined (REPEAT_S5)
+#define repeat_s(a) a.s0 = a.s5;a.s1 = a.s5;a.s2 = a.s5;a.s3 = a.s5;a.s4 = a.s5;
+#endif
+#if defined (REPEAT_S6)
+#define repeat_s(a) a.s0 = a.s6;a.s1 = a.s6;a.s2 = a.s6;a.s3 = a.s6;a.s4 = a.s6;a.s5 = a.s6;
+#endif
+#if defined (REPEAT_S7)
+#define repeat_s(a) a.s0 = a.s7;a.s1 = a.s7;a.s2 = a.s7;a.s3 = a.s7;a.s4 = a.s7;a.s5 = a.s7;a.s6 = a.s7;
+#endif
+
+#if defined (REPEAT_E0)
+#define repeat_e(a) a = a;
+#endif
+#if defined (REPEAT_E1)
+#define repeat_e(a) a.s7 = a.s6;
+#endif
+#if defined (REPEAT_E2)
+#define repeat_e(a) a.s7 = a.s5;a.s6 = a.s5;
+#endif
+#if defined (REPEAT_E3)
+#define repeat_e(a) a.s7 = a.s4;a.s6 = a.s4;a.s5 = a.s4;
+#endif
+#if defined (REPEAT_E4)
+#define repeat_e(a) a.s7 = a.s3;a.s6 = a.s3;a.s5 = a.s3;a.s4 = a.s3;
+#endif
+#if defined (REPEAT_E5)
+#define repeat_e(a) a.s7 = a.s2;a.s6 = a.s2;a.s5 = a.s2;a.s4 = a.s2;a.s3 = a.s2;
+#endif
+#if defined (REPEAT_E6)
+#define repeat_e(a) a.s7 = a.s1;a.s6 = a.s1;a.s5 = a.s1;a.s4 = a.s1;a.s3 = a.s1;a.s2 = a.s1;
+#endif
+#if defined (REPEAT_E7)
+#define repeat_e(a) a.s7 = a.s0;a.s6 = a.s0;a.s5 = a.s0;a.s4 = a.s0;a.s3 = a.s0;a.s2 = a.s0;a.s1 = a.s0;
+#endif
+
+#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics:enable
+#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics:enable
+
+/**************************************Array minMax**************************************/
+__kernel void arithm_op_minMax (int cols,int invalid_cols,int offset,int elemnum,int groupnum,
+                                  __global VEC_TYPE *src, __global VEC_TYPE *dst)
+{
+   unsigned int lid = get_local_id(0);
+   unsigned int gid = get_group_id(0);
+   unsigned int  id = get_global_id(0);
+   unsigned int idx = offset + id + (id / cols) * invalid_cols;
+   __local VEC_TYPE localmem_max[128],localmem_min[128];
+   VEC_TYPE minval,maxval,temp;
+   if(id < elemnum)
+   {
+       temp = src[idx];
+       if(id % cols == 0 ) 
+       {
+           repeat_s(temp);
+       }
+       if(id % cols == cols - 1)
+       {
+           repeat_e(temp);
+       }
+       minval = temp;
+       maxval = temp;
+   }
+   else
+   {
+       minval = MAX_VAL;
+       maxval = MIN_VAL;
+   }
+   for(id=id + (groupnum << 8); id < elemnum;id = id + (groupnum << 8))
+   {
+       idx = offset + id + (id / cols) * invalid_cols;
+       temp = src[idx];
+       if(id % cols == 0 ) 
+       {
+               repeat_s(temp);
+       }
+       if(id % cols == cols - 1)
+       {
+               repeat_e(temp);
+       }
+       minval = min(minval,temp);
+       maxval = max(maxval,temp);
+   }
+   if(lid > 127)
+   {
+       localmem_min[lid - 128] = minval;
+       localmem_max[lid - 128] = maxval;
+   }
+   barrier(CLK_LOCAL_MEM_FENCE);
+   if(lid < 128)
+   {
+       localmem_min[lid] = min(minval,localmem_min[lid]);
+       localmem_max[lid] = max(maxval,localmem_max[lid]);
+   }
+   barrier(CLK_LOCAL_MEM_FENCE);
+   for(int lsize = 64; lsize > 0; lsize >>= 1)
+   {
+       if(lid < lsize)
+       {
+           int lid2 = lsize + lid;
+           localmem_min[lid] = min(localmem_min[lid] , localmem_min[lid2]);
+           localmem_max[lid] = max(localmem_max[lid] , localmem_max[lid2]);
+       }
+       barrier(CLK_LOCAL_MEM_FENCE);
+   }
+   if( lid == 0)
+   {
+       dst[gid] = localmem_min[0];
+       dst[gid + groupnum] = localmem_max[0];
+   }
+}
diff --git a/modules/ocl/src/kernels/arithm_minMaxLoc.cl b/modules/ocl/src/kernels/arithm_minMaxLoc.cl
new file mode 100644 (file)
index 0000000..6937630
--- /dev/null
@@ -0,0 +1,423 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Shengen Yan, yanshengen@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 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
+// 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*/
+
+/**************************************PUBLICFUNC*************************************/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#define RES_TYPE double8
+#define CONVERT_RES_TYPE convert_double8
+#else
+#define RES_TYPE float8
+#define CONVERT_RES_TYPE convert_float8
+#endif
+
+#if defined (DEPTH_0)
+#define VEC_TYPE uchar8
+#define VEC_TYPE_LOC int8
+#define CONVERT_TYPE convert_uchar8
+#define CONDITION_FUNC(a,b,c) (convert_int8(a) ? b : c)
+#define MIN_VAL 0
+#define MAX_VAL 255
+#endif
+#if defined (DEPTH_1)
+#define VEC_TYPE char8
+#define VEC_TYPE_LOC int8
+#define CONVERT_TYPE convert_char8
+#define CONDITION_FUNC(a,b,c) (convert_int8(a) ? b : c)
+#define MIN_VAL -128 
+#define MAX_VAL 127
+#endif
+#if defined (DEPTH_2)
+#define VEC_TYPE ushort8
+#define VEC_TYPE_LOC int8
+#define CONVERT_TYPE convert_ushort8
+#define CONDITION_FUNC(a,b,c) (convert_int8(a) ? b : c)
+#define MIN_VAL 0 
+#define MAX_VAL 65535
+#endif
+#if defined (DEPTH_3)
+#define VEC_TYPE short8
+#define VEC_TYPE_LOC int8
+#define CONVERT_TYPE convert_short8
+#define CONDITION_FUNC(a,b,c) (convert_int8(a) ? b : c)
+#define MIN_VAL -32768 
+#define MAX_VAL 32767
+#endif
+#if defined (DEPTH_4)
+#define VEC_TYPE int8
+#define VEC_TYPE_LOC int8
+#define CONVERT_TYPE convert_int8
+#define CONDITION_FUNC(a,b,c) ((a) ? b : c)
+#define MIN_VAL INT_MIN 
+#define MAX_VAL INT_MAX
+#endif
+#if defined (DEPTH_5)
+#define VEC_TYPE float8
+#define VEC_TYPE_LOC float8
+#define CONVERT_TYPE convert_float8
+#define CONDITION_FUNC(a,b,c) ((a) ? b : c)
+#define MIN_VAL (-FLT_MAX) 
+#define MAX_VAL FLT_MAX
+#endif
+#if defined (DEPTH_6)
+#define VEC_TYPE double8
+#define VEC_TYPE_LOC double8
+#define CONVERT_TYPE convert_double8
+#define CONDITION_FUNC(a,b,c) ((a) ? b : c)
+#define MIN_VAL (-DBL_MAX) 
+#define MAX_VAL DBL_MAX
+#endif
+
+#if defined (REPEAT_S0)
+#define repeat_s(a) a=a; 
+#endif
+#if defined (REPEAT_S1)
+#define repeat_s(a) a.s0 = a.s1;
+#endif
+#if defined (REPEAT_S2)
+#define repeat_s(a) a.s0 = a.s2;a.s1 = a.s2;
+#endif
+#if defined (REPEAT_S3)
+#define repeat_s(a) a.s0 = a.s3;a.s1 = a.s3;a.s2 = a.s3;
+#endif
+#if defined (REPEAT_S4)
+#define repeat_s(a) a.s0 = a.s4;a.s1 = a.s4;a.s2 = a.s4;a.s3 = a.s4;
+#endif
+#if defined (REPEAT_S5)
+#define repeat_s(a) a.s0 = a.s5;a.s1 = a.s5;a.s2 = a.s5;a.s3 = a.s5;a.s4 = a.s5;
+#endif
+#if defined (REPEAT_S6)
+#define repeat_s(a) a.s0 = a.s6;a.s1 = a.s6;a.s2 = a.s6;a.s3 = a.s6;a.s4 = a.s6;a.s5 = a.s6;
+#endif
+#if defined (REPEAT_S7)
+#define repeat_s(a) a.s0 = a.s7;a.s1 = a.s7;a.s2 = a.s7;a.s3 = a.s7;a.s4 = a.s7;a.s5 = a.s7;a.s6 = a.s7;
+#endif
+
+#if defined (REPEAT_E0)
+#define repeat_e(a) a=a; 
+#endif
+#if defined (REPEAT_E1)
+#define repeat_e(a) a.s7 = a.s6;
+#endif
+#if defined (REPEAT_E2)
+#define repeat_e(a) a.s7 = a.s5;a.s6 = a.s5;
+#endif
+#if defined (REPEAT_E3)
+#define repeat_e(a) a.s7 = a.s4;a.s6 = a.s4;a.s5 = a.s4;
+#endif
+#if defined (REPEAT_E4)
+#define repeat_e(a) a.s7 = a.s3;a.s6 = a.s3;a.s5 = a.s3;a.s4 = a.s3;
+#endif
+#if defined (REPEAT_E5)
+#define repeat_e(a) a.s7 = a.s2;a.s6 = a.s2;a.s5 = a.s2;a.s4 = a.s2;a.s3 = a.s2;
+#endif
+#if defined (REPEAT_E6)
+#define repeat_e(a) a.s7 = a.s1;a.s6 = a.s1;a.s5 = a.s1;a.s4 = a.s1;a.s3 = a.s1;a.s2 = a.s1;
+#endif
+#if defined (REPEAT_E7)
+#define repeat_e(a) a.s7 = a.s0;a.s6 = a.s0;a.s5 = a.s0;a.s4 = a.s0;a.s3 = a.s0;a.s2 = a.s0;a.s1 = a.s0;
+#endif
+
+#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics:enable
+#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics:enable
+
+/**************************************Array minMax**************************************/
+__kernel void arithm_op_minMaxLoc (int cols,int invalid_cols,int offset,int elemnum,int groupnum,
+                                  __global VEC_TYPE *src, __global RES_TYPE *dst)
+{
+   unsigned int lid = get_local_id(0);
+   unsigned int gid = get_group_id(0);
+   unsigned int  id = get_global_id(0);
+   unsigned int idx = offset + id + (id / cols) * invalid_cols;
+   __local VEC_TYPE localmem_max[128],localmem_min[128];
+   VEC_TYPE minval,maxval,temp;
+   __local VEC_TYPE_LOC localmem_maxloc[128],localmem_minloc[128];
+   VEC_TYPE_LOC minloc,maxloc,temploc,negative = -1;
+   int idx_c;
+   if(id < elemnum)
+   {
+       temp = src[idx];
+       idx_c = idx << 3;
+       temploc = (VEC_TYPE_LOC)(idx_c,idx_c+1,idx_c+2,idx_c+3,idx_c+4,idx_c+5,idx_c+6,idx_c+7);
+       if(id % cols == 0 ) 
+       {
+           repeat_s(temp);
+           repeat_s(temploc);
+       }
+       if(id % cols == cols - 1)
+       {
+           repeat_e(temp);
+           repeat_e(temploc);
+       }
+       minval = temp;
+       maxval = temp;
+       minloc = temploc;
+       maxloc = temploc;
+   }
+   else
+   {
+       minval = MAX_VAL;
+       maxval = MIN_VAL;
+       minloc = negative;
+       maxloc = negative;
+   }
+   float8 aaa;
+   for(id=id + (groupnum << 8); id < elemnum;id = id + (groupnum << 8))
+   {
+       idx = offset + id + (id / cols) * invalid_cols;
+       temp = src[idx];
+       idx_c = idx << 3;
+       temploc = (VEC_TYPE_LOC)(idx_c,idx_c+1,idx_c+2,idx_c+3,idx_c+4,idx_c+5,idx_c+6,idx_c+7);
+       if(id % cols == 0 ) 
+       {
+               repeat_s(temp);
+               repeat_s(temploc);
+       }
+       if(id % cols == cols - 1)
+       {
+               repeat_e(temp);
+               repeat_e(temploc);
+       }
+       minval = min(minval,temp);
+       maxval = max(maxval,temp);
+       minloc = CONDITION_FUNC(minval == temp, temploc , minloc);
+       maxloc = CONDITION_FUNC(maxval == temp, temploc , maxloc);
+       aaa= convert_float8(maxval == temp);
+       maxloc = convert_int8(aaa) ? temploc : maxloc;
+   }
+   if(lid > 127)
+   {
+       localmem_min[lid - 128] = minval;
+       localmem_max[lid - 128] = maxval;
+       localmem_minloc[lid - 128] = minloc;
+       localmem_maxloc[lid - 128] = maxloc;
+   }
+   barrier(CLK_LOCAL_MEM_FENCE);
+   if(lid < 128)
+   {
+       localmem_min[lid] = min(minval,localmem_min[lid]);
+       localmem_max[lid] = max(maxval,localmem_max[lid]);
+       localmem_minloc[lid] = CONDITION_FUNC(localmem_min[lid] == minval, minloc , localmem_minloc[lid]);
+       localmem_maxloc[lid] = CONDITION_FUNC(localmem_max[lid] == maxval, maxloc , localmem_maxloc[lid]);
+   }
+   barrier(CLK_LOCAL_MEM_FENCE);
+   for(int lsize = 64; lsize > 0; lsize >>= 1)
+   {
+       if(lid < lsize)
+       {
+           int lid2 = lsize + lid;
+           localmem_min[lid] = min(localmem_min[lid] , localmem_min[lid2]);
+           localmem_max[lid] = max(localmem_max[lid] , localmem_max[lid2]);
+           localmem_minloc[lid] = 
+                   CONDITION_FUNC(localmem_min[lid] == localmem_min[lid2], localmem_minloc[lid2] , localmem_minloc[lid]);
+           localmem_maxloc[lid] = 
+                   CONDITION_FUNC(localmem_max[lid] == localmem_max[lid2], localmem_maxloc[lid2] , localmem_maxloc[lid]);
+       }
+       barrier(CLK_LOCAL_MEM_FENCE);
+   }
+   if( lid == 0)
+   {
+       dst[gid] = CONVERT_RES_TYPE(localmem_min[0]);
+       dst[gid + groupnum] = CONVERT_RES_TYPE(localmem_max[0]);
+       dst[gid + 2 * groupnum] = CONVERT_RES_TYPE(localmem_minloc[0]);
+       dst[gid + 3 * groupnum] = CONVERT_RES_TYPE(localmem_maxloc[0]);
+   }
+}
+
+#if defined (REPEAT_S0)
+#define repeat_ms(a) a = a;
+#endif
+#if defined (REPEAT_S1)
+#define repeat_ms(a) a.s0 = 0;
+#endif
+#if defined (REPEAT_S2)
+#define repeat_ms(a) a.s0 = 0;a.s1 = 0;
+#endif
+#if defined (REPEAT_S3)
+#define repeat_ms(a) a.s0 = 0;a.s1 = 0;a.s2 = 0;
+#endif
+#if defined (REPEAT_S4)
+#define repeat_ms(a) a.s0 = 0;a.s1 = 0;a.s2 = 0;a.s3 = 0;
+#endif
+#if defined (REPEAT_S5)
+#define repeat_ms(a) a.s0 = 0;a.s1 = 0;a.s2 = 0;a.s3 = 0;a.s4 = 0;
+#endif
+#if defined (REPEAT_S6)
+#define repeat_ms(a) a.s0 = 0;a.s1 = 0;a.s2 = 0;a.s3 = 0;a.s4 = 0;a.s5 = 0;
+#endif
+#if defined (REPEAT_S7)
+#define repeat_ms(a) a.s0 = 0;a.s1 = 0;a.s2 = 0;a.s3 = 0;a.s4 = 0;a.s5 = 0;a.s6 = 0;
+#endif
+
+#if defined (REPEAT_E0)
+#define repeat_me(a) a = a;
+#endif
+#if defined (REPEAT_E1)
+#define repeat_me(a) a.s7 = 0;
+#endif
+#if defined (REPEAT_E2)
+#define repeat_me(a) a.s7 = 0;a.s6 = 0;
+#endif
+#if defined (REPEAT_E3)
+#define repeat_me(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;
+#endif
+#if defined (REPEAT_E4)
+#define repeat_me(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;a.s4 = 0;
+#endif
+#if defined (REPEAT_E5)
+#define repeat_me(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;a.s4 = 0;a.s3 = 0;
+#endif
+#if defined (REPEAT_E6)
+#define repeat_me(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;a.s4 = 0;a.s3 = 0;a.s2 = 0;
+#endif
+#if defined (REPEAT_E7)
+#define repeat_me(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;a.s4 = 0;a.s3 = 0;a.s2 = 0;a.s1 = 0;
+#endif
+
+/**************************************Array minMaxLoc mask**************************************/
+__kernel void arithm_op_minMaxLoc_mask (int cols,int invalid_cols,int offset,int elemnum,int groupnum,__global VEC_TYPE *src,
+                                        int minvalid_cols,int moffset,__global uchar8 *mask,__global RES_TYPE  *dst)
+{
+   unsigned int lid = get_local_id(0);
+   unsigned int gid = get_group_id(0);
+   unsigned int  id = get_global_id(0);
+   unsigned int idx = offset + id + (id / cols) * invalid_cols;
+   unsigned int midx = moffset + id + (id / cols) * minvalid_cols;
+   __local VEC_TYPE localmem_max[128],localmem_min[128];
+   VEC_TYPE minval,maxval,temp,max_val = MAX_VAL,min_val = MIN_VAL,zero = 0,m_temp;
+   __local VEC_TYPE_LOC localmem_maxloc[128],localmem_minloc[128];
+   VEC_TYPE_LOC minloc,maxloc,temploc,negative = -1;
+   if(id < elemnum)
+   {
+       temp = src[idx];
+       m_temp = CONVERT_TYPE(mask[midx]);
+       int idx_c = idx << 3;
+       temploc = (VEC_TYPE_LOC)(idx_c,idx_c+1,idx_c+2,idx_c+3,idx_c+4,idx_c+5,idx_c+6,idx_c+7);
+       if(id % cols == 0 ) 
+       {
+           repeat_ms(m_temp);
+           repeat_s(temploc);
+       }
+       if(id % cols == cols - 1)
+       {
+           repeat_me(m_temp);
+           repeat_e(temploc);
+       }
+       minval = m_temp > zero ? temp : max_val;
+       maxval = m_temp > zero ? temp : min_val;
+       minloc = CONDITION_FUNC(m_temp > zero, temploc , negative);
+       maxloc = minloc;
+   }
+   else
+   {
+       minval = MAX_VAL;
+       maxval = MIN_VAL;
+       minloc = negative;
+       maxloc = negative;
+   }
+   for(id=id + (groupnum << 8); id < elemnum;id = id + (groupnum << 8))
+   {
+       idx = offset + id + (id / cols) * invalid_cols;
+       midx = moffset + id + (id / cols) * minvalid_cols;
+       temp = src[idx];
+       m_temp = CONVERT_TYPE(mask[midx]);
+       int idx_c = idx << 3;
+       temploc = (VEC_TYPE_LOC)(idx_c,idx_c+1,idx_c+2,idx_c+3,idx_c+4,idx_c+5,idx_c+6,idx_c+7);
+       if(id % cols == 0 ) 
+       {
+           repeat_ms(m_temp);
+           repeat_s(temploc);
+       }
+       if(id % cols == cols - 1)
+       {
+           repeat_me(m_temp);
+           repeat_e(temploc);
+       }
+       minval = min(minval,m_temp > zero ? temp : max_val);
+       maxval = max(maxval,m_temp > zero ? temp : min_val);
+       
+       temploc = CONDITION_FUNC(m_temp > zero, temploc , negative);
+       minloc = CONDITION_FUNC(minval == temp, temploc , minloc);
+       maxloc = CONDITION_FUNC(maxval == temp, temploc , maxloc);
+   }
+   if(lid > 127)
+   {
+       localmem_min[lid - 128] = minval;
+       localmem_max[lid - 128] = maxval;
+       localmem_minloc[lid - 128] = minloc;
+       localmem_maxloc[lid - 128] = maxloc;
+   }
+   barrier(CLK_LOCAL_MEM_FENCE);
+   if(lid < 128)
+   {
+       localmem_min[lid] = min(minval,localmem_min[lid]);
+       localmem_max[lid] = max(maxval,localmem_max[lid]);
+       localmem_minloc[lid] = CONDITION_FUNC(localmem_min[lid] == minval, minloc , localmem_minloc[lid]);
+       localmem_maxloc[lid] = CONDITION_FUNC(localmem_max[lid] == maxval, maxloc , localmem_maxloc[lid]);
+   }
+   barrier(CLK_LOCAL_MEM_FENCE);
+   for(int lsize = 64; lsize > 0; lsize >>= 1)
+   {
+       if(lid < lsize)
+       {
+           int lid2 = lsize + lid;
+           localmem_min[lid] = min(localmem_min[lid] , localmem_min[lid2]);
+           localmem_max[lid] = max(localmem_max[lid] , localmem_max[lid2]);
+           localmem_minloc[lid] = 
+                   CONDITION_FUNC(localmem_min[lid] == localmem_min[lid2], localmem_minloc[lid2] , localmem_minloc[lid]);
+           localmem_maxloc[lid] = 
+                   CONDITION_FUNC(localmem_max[lid] == localmem_max[lid2], localmem_maxloc[lid2] , localmem_maxloc[lid]);
+       }
+       barrier(CLK_LOCAL_MEM_FENCE);
+   }
+   if( lid == 0)
+   {
+       dst[gid] = CONVERT_RES_TYPE(localmem_min[0]);
+       dst[gid + groupnum] = CONVERT_RES_TYPE(localmem_max[0]);
+       dst[gid + 2 * groupnum] = CONVERT_RES_TYPE(localmem_minloc[0]);
+       dst[gid + 3 * groupnum] = CONVERT_RES_TYPE(localmem_maxloc[0]);
+   }
+}
+
diff --git a/modules/ocl/src/kernels/arithm_minMaxLoc_mask.cl b/modules/ocl/src/kernels/arithm_minMaxLoc_mask.cl
new file mode 100644 (file)
index 0000000..21cd4c1
--- /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.
+//
+//
+//                           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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Shengen Yan, yanshengen@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 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
+// 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*/
+
+/**************************************PUBLICFUNC*************************************/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#define RES_TYPE double8
+#define CONVERT_RES_TYPE convert_double8
+#else
+#define RES_TYPE float8
+#define CONVERT_RES_TYPE convert_float8
+#endif
+
+#if defined (DEPTH_0)
+#define TYPE uchar
+#define VEC_TYPE uchar8
+#define VEC_TYPE_LOC int8
+#define CONVERT_TYPE convert_uchar8
+#define CONDITION_FUNC(a,b,c) (convert_int8(a) ? b : c)
+#define MIN_VAL 0
+#define MAX_VAL 255
+#endif
+#if defined (DEPTH_1)
+#define TYPE char
+#define VEC_TYPE char8
+#define VEC_TYPE_LOC int8
+#define CONVERT_TYPE convert_char8
+#define CONDITION_FUNC(a,b,c) (convert_int8(a) ? b : c)
+#define MIN_VAL -128 
+#define MAX_VAL 127
+#endif
+#if defined (DEPTH_2)
+#define TYPE ushort
+#define VEC_TYPE ushort8
+#define VEC_TYPE_LOC int8
+#define CONVERT_TYPE convert_ushort8
+#define CONDITION_FUNC(a,b,c) (convert_int8(a) ? b : c)
+#define MIN_VAL 0 
+#define MAX_VAL 65535
+#endif
+#if defined (DEPTH_3)
+#define TYPE short
+#define VEC_TYPE short8
+#define VEC_TYPE_LOC int8
+#define CONVERT_TYPE convert_short8
+#define CONDITION_FUNC(a,b,c) (convert_int8(a) ? b : c)
+#define MIN_VAL -32768 
+#define MAX_VAL 32767
+#endif
+#if defined (DEPTH_4)
+#define TYPE int
+#define VEC_TYPE int8
+#define VEC_TYPE_LOC int8
+#define CONVERT_TYPE convert_int8
+#define CONDITION_FUNC(a,b,c) ((a) ? b : c)
+#define MIN_VAL INT_MIN 
+#define MAX_VAL INT_MAX
+#endif
+#if defined (DEPTH_5)
+#define TYPE float
+#define VEC_TYPE float8
+#define VEC_TYPE_LOC float8
+#define CONVERT_TYPE convert_float8
+#define CONDITION_FUNC(a,b,c) ((a) ? b : c)
+#define MIN_VAL (-FLT_MAX) 
+#define MAX_VAL FLT_MAX
+#endif
+#if defined (DEPTH_6)
+#define TYPE double
+#define VEC_TYPE double8
+#define VEC_TYPE_LOC double8
+#define CONVERT_TYPE convert_double8
+#define CONDITION_FUNC(a,b,c) ((a) ? b : c)
+#define MIN_VAL (-DBL_MAX) 
+#define MAX_VAL DBL_MAX
+#endif
+
+#if defined (REPEAT_E0)
+#define repeat_e(a) a = a;
+#endif
+#if defined (REPEAT_E1)
+#define repeat_e(a) a.s7 = a.s6;
+#endif
+#if defined (REPEAT_E2)
+#define repeat_e(a) a.s7 = a.s5;a.s6 = a.s5;
+#endif
+#if defined (REPEAT_E3)
+#define repeat_e(a) a.s7 = a.s4;a.s6 = a.s4;a.s5 = a.s4;
+#endif
+#if defined (REPEAT_E4)
+#define repeat_e(a) a.s7 = a.s3;a.s6 = a.s3;a.s5 = a.s3;a.s4 = a.s3;
+#endif
+#if defined (REPEAT_E5)
+#define repeat_e(a) a.s7 = a.s2;a.s6 = a.s2;a.s5 = a.s2;a.s4 = a.s2;a.s3 = a.s2;
+#endif
+#if defined (REPEAT_E6)
+#define repeat_e(a) a.s7 = a.s1;a.s6 = a.s1;a.s5 = a.s1;a.s4 = a.s1;a.s3 = a.s1;a.s2 = a.s1;
+#endif
+#if defined (REPEAT_E7)
+#define repeat_e(a) a.s7 = a.s0;a.s6 = a.s0;a.s5 = a.s0;a.s4 = a.s0;a.s3 = a.s0;a.s2 = a.s0;a.s1 = a.s0;
+#endif
+
+#if defined (REPEAT_E0)
+#define repeat_me(a) a = a;
+#endif
+#if defined (REPEAT_E1)
+#define repeat_me(a) a.s7 = 0;
+#endif
+#if defined (REPEAT_E2)
+#define repeat_me(a) a.s7 = 0;a.s6 = 0;
+#endif
+#if defined (REPEAT_E3)
+#define repeat_me(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;
+#endif
+#if defined (REPEAT_E4)
+#define repeat_me(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;a.s4 = 0;
+#endif
+#if defined (REPEAT_E5)
+#define repeat_me(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;a.s4 = 0;a.s3 = 0;
+#endif
+#if defined (REPEAT_E6)
+#define repeat_me(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;a.s4 = 0;a.s3 = 0;a.s2 = 0;
+#endif
+#if defined (REPEAT_E7)
+#define repeat_me(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;a.s4 = 0;a.s3 = 0;a.s2 = 0;a.s1 = 0;
+#endif
+
+/**************************************Array minMaxLoc mask**************************************/
+__kernel void arithm_op_minMaxLoc_mask (int cols,int invalid_cols,int offset,int elemnum,int groupnum,__global TYPE *src,
+                                        int minvalid_cols,int moffset,__global uchar *mask,__global RES_TYPE  *dst)
+{
+   unsigned int lid = get_local_id(0);
+   unsigned int gid = get_group_id(0);
+   unsigned int  id = get_global_id(0);
+   unsigned int idx = id + (id / cols) * invalid_cols;
+   unsigned int midx = id + (id / cols) * minvalid_cols;
+   __local VEC_TYPE lm_max[128],lm_min[128];
+   VEC_TYPE minval,maxval,temp,m_temp;
+   __local VEC_TYPE_LOC lm_maxloc[128],lm_minloc[128];
+   VEC_TYPE_LOC minloc,maxloc,temploc,negative = -1,one = 1,zero = 0;
+   if(id < elemnum)
+   {
+       temp = vload8(idx, &src[offset]);
+       m_temp = CONVERT_TYPE(vload8(midx,&mask[moffset]));
+       int idx_c = (idx << 3) + offset;
+       temploc = (VEC_TYPE_LOC)(idx_c,idx_c+1,idx_c+2,idx_c+3,idx_c+4,idx_c+5,idx_c+6,idx_c+7);
+       if(id % cols == cols - 1)
+       {
+           repeat_me(m_temp);
+           repeat_e(temploc);
+       }
+       minval = m_temp != (VEC_TYPE)0 ? temp : (VEC_TYPE)MAX_VAL;
+       maxval = m_temp != (VEC_TYPE)0 ? temp : (VEC_TYPE)MIN_VAL;
+       minloc = CONDITION_FUNC(m_temp != (VEC_TYPE)0, temploc , negative);
+       maxloc = minloc;
+   }
+   else
+   {
+       minval = MAX_VAL;
+       maxval = MIN_VAL;
+       minloc = negative;
+       maxloc = negative;
+   }
+   for(id=id + (groupnum << 8); id < elemnum;id = id + (groupnum << 8))
+   {
+       idx = id + (id / cols) * invalid_cols;
+       midx = id + (id / cols) * minvalid_cols;
+       temp = vload8(idx, &src[offset]);
+       m_temp = CONVERT_TYPE(vload8(midx,&mask[moffset]));
+       int idx_c = (idx << 3) + offset;
+       temploc = (VEC_TYPE_LOC)(idx_c,idx_c+1,idx_c+2,idx_c+3,idx_c+4,idx_c+5,idx_c+6,idx_c+7);
+       if(id % cols == cols - 1)
+       {
+           repeat_me(m_temp);
+           repeat_e(temploc);
+       }
+       minval = min(minval,m_temp != (VEC_TYPE)0 ? temp : minval);
+       maxval = max(maxval,m_temp != (VEC_TYPE)0 ? temp : maxval);
+       
+       minloc = CONDITION_FUNC((minval == temp) && (m_temp != (VEC_TYPE)0), temploc , minloc);
+       maxloc = CONDITION_FUNC((maxval == temp) && (m_temp != (VEC_TYPE)0), temploc , maxloc);
+   }
+   if(lid > 127)
+   {
+       lm_min[lid - 128] = minval;
+       lm_max[lid - 128] = maxval;
+       lm_minloc[lid - 128] = minloc;
+       lm_maxloc[lid - 128] = maxloc;
+   }
+   barrier(CLK_LOCAL_MEM_FENCE);
+   if(lid < 128)
+   {
+       lm_min[lid] = min(minval,lm_min[lid]);
+       lm_max[lid] = max(maxval,lm_max[lid]);
+       VEC_TYPE con_min = CONVERT_TYPE(minloc != negative ? one : zero);
+       VEC_TYPE con_max = CONVERT_TYPE(maxloc != negative ? one : zero);
+       lm_minloc[lid] = CONDITION_FUNC((lm_min[lid] == minval) && (con_min != (VEC_TYPE)0), minloc , lm_minloc[lid]);
+       lm_maxloc[lid] = CONDITION_FUNC((lm_max[lid] == maxval) && (con_max != (VEC_TYPE)0), maxloc , lm_maxloc[lid]);
+   }
+   barrier(CLK_LOCAL_MEM_FENCE);
+   for(int lsize = 64; lsize > 0; lsize >>= 1)
+   {
+       if(lid < lsize)
+       {
+           int lid2 = lsize + lid;
+           lm_min[lid] = min(lm_min[lid] , lm_min[lid2]);
+           lm_max[lid] = max(lm_max[lid] , lm_max[lid2]);
+           VEC_TYPE con_min = CONVERT_TYPE(lm_minloc[lid2] != negative ? one : zero);
+           VEC_TYPE con_max = CONVERT_TYPE(lm_maxloc[lid2] != negative ? one : zero);
+           lm_minloc[lid] = 
+              CONDITION_FUNC((lm_min[lid] == lm_min[lid2]) && (con_min != (VEC_TYPE)0), lm_minloc[lid2] , lm_minloc[lid]);
+           lm_maxloc[lid] = 
+              CONDITION_FUNC((lm_max[lid] == lm_max[lid2]) && (con_max != (VEC_TYPE)0), lm_maxloc[lid2] , lm_maxloc[lid]);
+       }
+       barrier(CLK_LOCAL_MEM_FENCE);
+   }
+   if( lid == 0)
+   {
+       dst[gid] = CONVERT_RES_TYPE(lm_min[0]);
+       dst[gid + groupnum] = CONVERT_RES_TYPE(lm_max[0]);
+       dst[gid + 2 * groupnum] = CONVERT_RES_TYPE(lm_minloc[0]);
+       dst[gid + 3 * groupnum] = CONVERT_RES_TYPE(lm_maxloc[0]);
+   }
+}
+
diff --git a/modules/ocl/src/kernels/arithm_minMax_mask.cl b/modules/ocl/src/kernels/arithm_minMax_mask.cl
new file mode 100644 (file)
index 0000000..3c8e2f0
--- /dev/null
@@ -0,0 +1,197 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Shengen Yan,yanshengen@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 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
+// 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*/
+
+/**************************************PUBLICFUNC*************************************/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+#if defined (DEPTH_0)
+#define VEC_TYPE uchar8
+#define TYPE uchar
+#define CONVERT_TYPE convert_uchar8
+#define MIN_VAL 0
+#define MAX_VAL 255
+#endif
+#if defined (DEPTH_1)
+#define VEC_TYPE char8
+#define TYPE char
+#define CONVERT_TYPE convert_char8
+#define MIN_VAL -128 
+#define MAX_VAL 127
+#endif
+#if defined (DEPTH_2)
+#define VEC_TYPE ushort8
+#define TYPE ushort
+#define CONVERT_TYPE convert_ushort8
+#define MIN_VAL 0 
+#define MAX_VAL 65535
+#endif
+#if defined (DEPTH_3)
+#define VEC_TYPE short8
+#define TYPE short
+#define CONVERT_TYPE convert_short8
+#define MIN_VAL -32768 
+#define MAX_VAL 32767
+#endif
+#if defined (DEPTH_4)
+#define VEC_TYPE int8
+#define TYPE int
+#define CONVERT_TYPE convert_int8
+#define MIN_VAL INT_MIN 
+#define MAX_VAL INT_MAX
+#endif
+#if defined (DEPTH_5)
+#define VEC_TYPE float8
+#define TYPE float
+#define CONVERT_TYPE convert_float8
+#define MIN_VAL (-FLT_MAX) 
+#define MAX_VAL FLT_MAX
+#endif
+#if defined (DEPTH_6)
+#define VEC_TYPE double8
+#define TYPE double
+#define CONVERT_TYPE convert_double8
+#define MIN_VAL (-DBL_MAX) 
+#define MAX_VAL DBL_MAX
+#endif
+
+#if defined (REPEAT_E0)
+#define repeat_me(a) a = a;
+#endif
+#if defined (REPEAT_E1)
+#define repeat_me(a) a.s7 = 0;
+#endif
+#if defined (REPEAT_E2)
+#define repeat_me(a) a.s7 = 0;a.s6 = 0;
+#endif
+#if defined (REPEAT_E3)
+#define repeat_me(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;
+#endif
+#if defined (REPEAT_E4)
+#define repeat_me(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;a.s4 = 0;
+#endif
+#if defined (REPEAT_E5)
+#define repeat_me(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;a.s4 = 0;a.s3 = 0;
+#endif
+#if defined (REPEAT_E6)
+#define repeat_me(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;a.s4 = 0;a.s3 = 0;a.s2 = 0;
+#endif
+#if defined (REPEAT_E7)
+#define repeat_me(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;a.s4 = 0;a.s3 = 0;a.s2 = 0;a.s1 = 0;
+#endif
+
+#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics:enable
+#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics:enable
+
+/**************************************Array minMax mask**************************************/
+__kernel void arithm_op_minMax_mask (int cols,int invalid_cols,int offset,int elemnum,int groupnum, __global TYPE *src,
+                                     int minvalid_cols,int moffset, __global uchar *mask,__global VEC_TYPE *dst)
+{
+   unsigned int lid = get_local_id(0);
+   unsigned int gid = get_group_id(0);
+   unsigned int  id = get_global_id(0);
+   unsigned int idx = id + (id / cols) * invalid_cols;
+   unsigned int midx = id + (id / cols) * minvalid_cols;
+   __local VEC_TYPE localmem_max[128],localmem_min[128];
+   VEC_TYPE minval,maxval,temp,m_temp;
+   if(id < elemnum)
+   {
+       temp = vload8(idx, &src[offset]);
+       m_temp = CONVERT_TYPE(vload8(midx,&mask[moffset]));
+       if(id % cols == cols - 1)
+       {
+           repeat_me(m_temp);
+       }
+       minval = m_temp != (VEC_TYPE)0 ? temp : (VEC_TYPE)MAX_VAL;
+       maxval = m_temp != (VEC_TYPE)0 ? temp : (VEC_TYPE)MIN_VAL;
+   }
+   else
+   {
+       minval = MAX_VAL;
+       maxval = MIN_VAL;
+   }
+   for(id=id + (groupnum << 8); id < elemnum;id = id + (groupnum << 8))
+   {
+       idx = id + (id / cols) * invalid_cols;
+       midx = id + (id / cols) * minvalid_cols;
+       temp = vload8(idx, &src[offset]);
+       m_temp = CONVERT_TYPE(vload8(midx,&mask[moffset]));
+       if(id % cols == cols - 1)
+       {
+               repeat_me(m_temp);
+       }
+       minval = min(minval,m_temp != (VEC_TYPE)0 ? temp : minval);
+       maxval = max(maxval,m_temp != (VEC_TYPE)0 ? temp : maxval);
+   }
+   if(lid > 127)
+   {
+       localmem_min[lid - 128] = minval;
+       localmem_max[lid - 128] = maxval;
+   }
+   barrier(CLK_LOCAL_MEM_FENCE);
+   if(lid < 128)
+   {
+       localmem_min[lid] = min(minval,localmem_min[lid]);
+       localmem_max[lid] = max(maxval,localmem_max[lid]);
+   }
+   barrier(CLK_LOCAL_MEM_FENCE);
+   for(int lsize = 64; lsize > 0; lsize >>= 1)
+   {
+       if(lid < lsize)
+       {
+           int lid2 = lsize + lid;
+           localmem_min[lid] = min(localmem_min[lid] , localmem_min[lid2]);
+           localmem_max[lid] = max(localmem_max[lid] , localmem_max[lid2]);
+       }
+       barrier(CLK_LOCAL_MEM_FENCE);
+   }
+   if( lid == 0)
+   {
+       dst[gid] = localmem_min[0];
+       dst[gid + groupnum] = localmem_max[0];
+   }
+}
+
diff --git a/modules/ocl/src/kernels/arithm_mul.cl b/modules/ocl/src/kernels/arithm_mul.cl
new file mode 100644 (file)
index 0000000..4465651
--- /dev/null
@@ -0,0 +1,253 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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
+// 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*/
+
+#if defined DOUBLE_SUPPORT
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+int4 round_int4(float4 v){
+    v.s0 = v.s0 + (v.s0 > 0 ? 0.5 : -0.5); 
+    v.s1 = v.s1 + (v.s1 > 0 ? 0.5 : -0.5); 
+    v.s2 = v.s2 + (v.s2 > 0 ? 0.5 : -0.5); 
+    v.s3 = v.s3 + (v.s3 > 0 ? 0.5 : -0.5); 
+
+    return convert_int4_sat(v);
+}
+uint4 round_uint4(float4 v){
+    v.s0 = v.s0 + (v.s0 > 0 ? 0.5 : -0.5); 
+    v.s1 = v.s1 + (v.s1 > 0 ? 0.5 : -0.5); 
+    v.s2 = v.s2 + (v.s2 > 0 ? 0.5 : -0.5); 
+    v.s3 = v.s3 + (v.s3 > 0 ? 0.5 : -0.5); 
+
+    return convert_uint4_sat(v);
+}
+long round_int(float v){
+    v = v + (v > 0 ? 0.5 : -0.5); 
+
+    return convert_int_sat(v);
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////multiply//////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+/**************************************add without mask**************************************/
+__kernel void arithm_mul_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                             __global uchar *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1, float scalar)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        int4 tmp      = convert_int4_sat(src1_data) * convert_int4_sat(src2_data);
+        tmp = round_int4(convert_float4(tmp) * scalar);
+        uchar4 tmp_data = convert_uchar4_sat(tmp);
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+__kernel void arithm_mul_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                             __global ushort *src2, int src2_step, int src2_offset,
+                             __global ushort *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1, float scalar)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        ushort4 src1_data = vload4(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort4 src2_data = vload4(0, (__global ushort *)((__global char *)src2 + src2_index));
+
+        ushort4 dst_data = *((__global ushort4 *)((__global char *)dst + dst_index));
+        uint4    tmp = convert_uint4_sat(src1_data) * convert_uint4_sat(src2_data);
+        tmp = round_uint4(convert_float4(tmp) * scalar);
+        ushort4 tmp_data = convert_ushort4_sat(tmp);
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+}
+__kernel void arithm_mul_D3 (__global short *src1, int src1_step, int src1_offset,
+                             __global short *src2, int src2_step, int src2_offset,
+                             __global short *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1, float scalar)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        short4 src1_data = vload4(0, (__global short *)((__global char *)src1 + src1_index));
+        short4 src2_data = vload4(0, (__global short *)((__global char *)src2 + src2_index));
+
+        short4 dst_data = *((__global short4 *)((__global char *)dst + dst_index));
+        int4   tmp = convert_int4_sat(src1_data) * convert_int4_sat(src2_data);
+        tmp = round_int4(convert_float4(tmp) * scalar);
+        short4 tmp_data = convert_short4_sat(tmp);
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+}
+
+__kernel void arithm_mul_D4 (__global int *src1, int src1_step, int src1_offset,
+                             __global int *src2, int src2_step, int src2_offset,
+                             __global int *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1, float scalar)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        int data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int data2 = *((__global int *)((__global char *)src2 + src2_index));
+        int tmp  = data1 * data2;
+        tmp = round_int((float)tmp * scalar);
+
+        *((__global int *)((__global char *)dst + dst_index)) = convert_int_sat(tmp);
+    }
+}
+__kernel void arithm_mul_D5 (__global float *src1, int src1_step, int src1_offset,
+                             __global float *src2, int src2_step, int src2_offset,
+                             __global float *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1, float scalar)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        float data1 = *((__global float *)((__global char *)src1 + src1_index));
+        float data2 = *((__global float *)((__global char *)src2 + src2_index));
+        float tmp = data1 * data2;
+        tmp = tmp * scalar;
+
+        *((__global float *)((__global char *)dst + dst_index)) = tmp;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_mul_D6 (__global double *src1, int src1_step, int src1_offset,
+                             __global double *src2, int src2_step, int src2_offset,
+                             __global double *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1, double scalar)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        double data1 = *((__global double *)((__global char *)src1 + src1_index));
+        double data2 = *((__global double *)((__global char *)src2 + src2_index));
+
+        double tmp = data1 * data2;
+        tmp = tmp * scalar;
+
+        *((__global double *)((__global char *)dst + dst_index)) = tmp;
+    }
+}
+#endif
diff --git a/modules/ocl/src/kernels/arithm_nonzero.cl b/modules/ocl/src/kernels/arithm_nonzero.cl
new file mode 100644 (file)
index 0000000..2d4c886
--- /dev/null
@@ -0,0 +1,191 @@
+////////////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Shengen Yan,yanshengen@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 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.
+//
+///
+
+/**************************************PUBLICFUNC*************************************/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+#if defined (DEPTH_0)
+#define VEC_TYPE uchar8
+#endif
+#if defined (DEPTH_1)
+#define VEC_TYPE char8
+#endif
+#if defined (DEPTH_2)
+#define VEC_TYPE ushort8
+#endif
+#if defined (DEPTH_3)
+#define VEC_TYPE short8
+#endif
+#if defined (DEPTH_4)
+#define VEC_TYPE int8
+#endif
+#if defined (DEPTH_5)
+#define VEC_TYPE float8
+#endif
+#if defined (DEPTH_6)
+#define VEC_TYPE double8
+#endif
+
+#if defined (REPEAT_S0)
+#define repeat_s(a) a = a;
+#endif
+#if defined (REPEAT_S1)
+#define repeat_s(a) a.s0 = 0;
+#endif
+#if defined (REPEAT_S2)
+#define repeat_s(a) a.s0 = 0;a.s1 = 0;
+#endif
+#if defined (REPEAT_S3)
+#define repeat_s(a) a.s0 = 0;a.s1 = 0;a.s2 = 0;
+#endif
+#if defined (REPEAT_S4)
+#define repeat_s(a) a.s0 = 0;a.s1 = 0;a.s2 = 0;a.s3 = 0;
+#endif
+#if defined (REPEAT_S5)
+#define repeat_s(a) a.s0 = 0;a.s1 = 0;a.s2 = 0;a.s3 = 0;a.s4 = 0;
+#endif
+#if defined (REPEAT_S6)
+#define repeat_s(a) a.s0 = 0;a.s1 = 0;a.s2 = 0;a.s3 = 0;a.s4 = 0;a.s5 = 0;
+#endif
+#if defined (REPEAT_S7)
+#define repeat_s(a) a.s0 = 0;a.s1 = 0;a.s2 = 0;a.s3 = 0;a.s4 = 0;a.s5 = 0;a.s6 = 0;
+#endif
+
+#if defined (REPEAT_E0)
+#define repeat_e(a) a = a;
+#endif
+#if defined (REPEAT_E1)
+#define repeat_e(a) a.s7 = 0;
+#endif
+#if defined (REPEAT_E2)
+#define repeat_e(a) a.s7 = 0;a.s6 = 0;
+#endif
+#if defined (REPEAT_E3)
+#define repeat_e(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;
+#endif
+#if defined (REPEAT_E4)
+#define repeat_e(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;a.s4 = 0;
+#endif
+#if defined (REPEAT_E5)
+#define repeat_e(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;a.s4 = 0;a.s3 = 0;
+#endif
+#if defined (REPEAT_E6)
+#define repeat_e(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;a.s4 = 0;a.s3 = 0;a.s2 = 0;
+#endif
+#if defined (REPEAT_E7)
+#define repeat_e(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;a.s4 = 0;a.s3 = 0;a.s2 = 0;a.s1 = 0;
+#endif
+
+#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics:enable
+#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics:enable
+
+/**************************************Count NonZero**************************************/
+__kernel void arithm_op_nonzero (int cols,int invalid_cols,int offset,int elemnum,int groupnum,
+                                  __global VEC_TYPE *src, __global int8 *dst)
+{
+   unsigned int lid = get_local_id(0);
+   unsigned int gid = get_group_id(0);
+   unsigned int  id = get_global_id(0);
+   unsigned int idx = offset + id + (id / cols) * invalid_cols;
+   __local int8 localmem_nonzero[128];
+   int8 nonzero;
+   VEC_TYPE zero=0,one=1,temp;
+   if(id < elemnum)
+   {
+       temp = src[idx];
+       if(id % cols == 0 ) 
+       {
+           repeat_s(temp);
+       }
+       if(id % cols == cols - 1)
+       {
+           repeat_e(temp);
+       }
+       nonzero = convert_int8(temp == zero ? zero:one);
+   }
+   else
+   {
+       nonzero = 0;
+   }
+   for(id=id + (groupnum << 8); id < elemnum;id = id + (groupnum << 8))
+   {
+       idx = offset + id + (id / cols) * invalid_cols;
+       temp = src[idx];
+       if(id % cols == 0 ) 
+       {
+               repeat_s(temp);
+       }
+       if(id % cols == cols - 1)
+       {
+               repeat_e(temp);
+       }
+       nonzero = nonzero + convert_int8(temp == zero ? zero:one);
+   }
+   if(lid > 127)
+   {
+       localmem_nonzero[lid - 128] = nonzero;
+   }
+   barrier(CLK_LOCAL_MEM_FENCE);
+   if(lid < 128)
+   {
+       localmem_nonzero[lid] = nonzero + localmem_nonzero[lid];
+   }
+   barrier(CLK_LOCAL_MEM_FENCE);
+   for(int lsize = 64; lsize > 0; lsize >>= 1)
+   {
+       if(lid < lsize)
+       {
+           int lid2 = lsize + lid;
+           localmem_nonzero[lid] = localmem_nonzero[lid] + localmem_nonzero[lid2];
+       }
+       barrier(CLK_LOCAL_MEM_FENCE);
+   }
+   if( lid == 0)
+   {
+       dst[gid] = localmem_nonzero[0];
+   }
+}
diff --git a/modules/ocl/src/kernels/arithm_phase.cl b/modules/ocl/src/kernels/arithm_phase.cl
new file mode 100644 (file)
index 0000000..ec3de0b
--- /dev/null
@@ -0,0 +1,154 @@
+////////////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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.
+//
+//
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+#define CV_PI 3.1415926535898
+/**************************************phase inradians**************************************/
+__kernel void arithm_phase_inradians_D5 (__global float *src1, int src1_step, int src1_offset,
+                                         __global float *src2, int src2_step, int src2_offset,
+                                         __global float *dst,  int dst_step,  int dst_offset,
+                                         int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if(x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        float data1 = *((__global float *)((__global char *)src1 + src1_index));
+        float data2 = *((__global float *)((__global char *)src2 + src2_index));
+        float tmp = atan2(data2,data1);
+        
+        *((__global float *)((__global char *)dst + dst_index)) = tmp;
+    }
+
+}
+
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_phase_inradians_D6 (__global double *src1, int src1_step, int src1_offset,
+                                         __global double *src2, int src2_step, int src2_offset,
+                                         __global double *dst,  int dst_step,  int dst_offset,
+                                         int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if(x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        double data1 = *((__global double *)((__global char *)src1 + src1_index));
+        double data2 = *((__global double *)((__global char *)src2 + src2_index));
+        
+        *((__global double *)((__global char *)dst + dst_index)) = atan2(data2,data1);
+    }
+
+}
+#endif
+
+/**************************************phase indegrees**************************************/
+__kernel void arithm_phase_indegrees_D5 (__global float *src1, int src1_step, int src1_offset,
+                                         __global float *src2, int src2_step, int src2_offset,
+                                         __global float *dst,  int dst_step,  int dst_offset,
+                                         int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if(x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        float data1 = *((__global float *)((__global char *)src1 + src1_index));
+        float data2 = *((__global float *)((__global char *)src2 + src2_index));
+        float tmp = atan2(data2,data1);
+        float tmp_data = 180*tmp/CV_PI;
+        
+        *((__global float *)((__global char *)dst + dst_index)) = tmp_data;
+    }
+
+}
+
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_phase_indegrees_D6 (__global double *src1, int src1_step, int src1_offset,
+                                         __global double *src2, int src2_step, int src2_offset,
+                                         __global double *dst,  int dst_step,  int dst_offset,
+                                         int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if(x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        double data1 = *((__global double *)((__global char *)src1 + src1_index));
+        double data2 = *((__global double *)((__global char *)src2 + src2_index));
+        double tmp = atan2(data2,data1);
+        double tmp_data = 180*tmp/CV_PI;
+        
+        *((__global double *)((__global char *)dst + dst_index)) = tmp_data;
+    }
+
+}
+#endif
diff --git a/modules/ocl/src/kernels/arithm_polarToCart.cl b/modules/ocl/src/kernels/arithm_polarToCart.cl
new file mode 100644 (file)
index 0000000..3c799c4
--- /dev/null
@@ -0,0 +1,174 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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
+// 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*/
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+#define CV_PI   3.1415926535897932384626433832795
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////polarToCart with magnitude//////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void arithm_polarToCart_mag_D5 (__global float *src1, int src1_step, int src1_offset,//magnitue
+                                         __global float *src2, int src2_step, int src2_offset,//angle
+                                         __global float *dst1, int dst1_step, int dst1_offset, 
+                                         __global float *dst2, int dst2_step, int dst2_offset, 
+                                         int rows, int cols, int angInDegree)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+
+        int dst1_index = mad24(y, dst1_step, (x << 2) + dst1_offset);
+        int dst2_index = mad24(y, dst2_step, (x << 2) + dst2_offset);
+
+        float x = *((__global float *)((__global char *)src1 + src1_index));
+        float y = *((__global float *)((__global char *)src2 + src2_index));
+
+        float ascale = CV_PI/180.0;
+        float alpha  = angInDegree == 1 ? y * ascale : y;
+        float a = cos(alpha) * x; 
+        float b = sin(alpha) * x;
+
+        *((__global float *)((__global char *)dst1 + dst1_index)) = a;
+        *((__global float *)((__global char *)dst2 + dst2_index)) = b;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_polarToCart_mag_D6 (__global double *src1, int src1_step, int src1_offset,//magnitue
+                                         __global double *src2, int src2_step, int src2_offset,//angle
+                                         __global double *dst1, int dst1_step, int dst1_offset, 
+                                         __global double *dst2, int dst2_step, int dst2_offset, 
+                                         int rows, int cols, int angInDegree)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+
+        int dst1_index = mad24(y, dst1_step, (x << 3) + dst1_offset);
+        int dst2_index = mad24(y, dst2_step, (x << 3) + dst2_offset);
+
+        double x = *((__global double *)((__global char *)src1 + src1_index));
+        double y = *((__global double *)((__global char *)src2 + src2_index));
+
+        float ascale = CV_PI/180.0;
+        double alpha  = angInDegree == 1 ? y * ascale : y;
+        double a = cos(alpha) * x; 
+        double b = sin(alpha) * x;
+
+        *((__global double *)((__global char *)dst1 + dst1_index)) = a;
+        *((__global double *)((__global char *)dst2 + dst2_index)) = b;
+    }
+}
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////polarToCart without magnitude//////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void arithm_polarToCart_D5 (__global float *src,  int src_step,  int src_offset,//angle
+                                     __global float *dst1, int dst1_step, int dst1_offset, 
+                                     __global float *dst2, int dst2_step, int dst2_offset, 
+                                     int rows, int cols, int angInDegree)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src_index  = mad24(y, src_step,  (x << 2) + src_offset);
+
+        int dst1_index = mad24(y, dst1_step, (x << 2) + dst1_offset);
+        int dst2_index = mad24(y, dst2_step, (x << 2) + dst2_offset);
+
+        float y = *((__global float *)((__global char *)src + src_index));
+
+        float ascale = CV_PI/180.0;
+        float alpha  = angInDegree == 1 ? y * ascale : y;
+        float a = cos(alpha); 
+        float b = sin(alpha);
+
+        *((__global float *)((__global char *)dst1 + dst1_index)) = a;
+        *((__global float *)((__global char *)dst2 + dst2_index)) = b;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_polarToCart_D6 (__global float *src,  int src_step,  int src_offset,//angle
+                                     __global float *dst1, int dst1_step, int dst1_offset, 
+                                     __global float *dst2, int dst2_step, int dst2_offset, 
+                                     int rows, int cols, int angInDegree)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src_index  = mad24(y, src_step,  (x << 3) + src_offset);
+
+        int dst1_index = mad24(y, dst1_step, (x << 3) + dst1_offset);
+        int dst2_index = mad24(y, dst2_step, (x << 3) + dst2_offset);
+
+        double y = *((__global double *)((__global char *)src + src_index));
+
+        float ascale = CV_PI/180.0;
+        double alpha  = angInDegree == 1 ? y * ascale : y;
+        double a = cos(alpha); 
+        double b = sin(alpha);
+
+        *((__global double *)((__global char *)dst1 + dst1_index)) = a;
+        *((__global double *)((__global char *)dst2 + dst2_index)) = b;
+    }
+}
+#endif
diff --git a/modules/ocl/src/kernels/arithm_pow.cl b/modules/ocl/src/kernels/arithm_pow.cl
new file mode 100644 (file)
index 0000000..a86a4fa
--- /dev/null
@@ -0,0 +1,97 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jiang Liyuan, jlyuan001.good@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*/
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+/************************************** pow **************************************/
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_pow_D5 (__global float *src1, int src1_step, int src1_offset,
+                             __global float *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1,
+                             double p)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if(x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        float src1_data = *((__global float *)((__global char *)src1 + src1_index));
+        float tmp = src1_data > 0 ? exp(p * log(src1_data)) : (src1_data == 0 ? 0 : exp(p * log(fabs(src1_data))));
+        
+        *((__global float *)((__global char *)dst + dst_index)) = tmp;
+    }
+
+}
+#endif
+
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_pow_D6 (__global double *src1, int src1_step, int src1_offset,
+                             __global double *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1,
+                             double p)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if(x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        double src1_data = *((__global double *)((__global char *)src1 + src1_index));
+        double tmp = src1_data > 0 ? exp(p * log(src1_data)) : (src1_data == 0 ? 0 : exp(p * log(fabs(src1_data)))); 
+        *((__global double *)((__global char *)dst + dst_index)) = tmp;
+    }
+
+}
+#endif
+
diff --git a/modules/ocl/src/kernels/arithm_sub.cl b/modules/ocl/src/kernels/arithm_sub.cl
new file mode 100644 (file)
index 0000000..4fe423f
--- /dev/null
@@ -0,0 +1,1104 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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
+// 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*/
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////SUB////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+/**************************************sub without mask**************************************/
+__kernel void arithm_sub_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                             __global uchar *src2, int src2_step, int src2_offset,
+                             __global uchar *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+        short4 tmp      = convert_short4_sat(src1_data) - convert_short4_sat(src2_data);
+        uchar4 tmp_data = convert_uchar4_sat(tmp);
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = dst_data;
+    }
+}
+__kernel void arithm_sub_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                             __global ushort *src2, int src2_step, int src2_offset,
+                             __global ushort *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        ushort4 src1_data = vload4(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort4 src2_data = vload4(0, (__global ushort *)((__global char *)src2 + src2_index));
+
+        ushort4 dst_data = *((__global ushort4 *)((__global char *)dst + dst_index));
+        int4    tmp = convert_int4_sat(src1_data) - convert_int4_sat(src2_data);
+        ushort4 tmp_data = convert_ushort4_sat(tmp);
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+}
+__kernel void arithm_sub_D3 (__global short *src1, int src1_step, int src1_offset,
+                             __global short *src2, int src2_step, int src2_offset,
+                             __global short *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align ((dst_offset >> 1) & 3)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8);
+
+        short4 src1_data = vload4(0, (__global short *)((__global char *)src1 + src1_index));
+        short4 src2_data = vload4(0, (__global short *)((__global char *)src2 + src2_index));
+
+        short4 dst_data = *((__global short4 *)((__global char *)dst + dst_index));
+        int4   tmp = convert_int4_sat(src1_data) - convert_int4_sat(src2_data);
+        short4 tmp_data = convert_short4_sat(tmp);
+
+        dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
+        dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y;
+        dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z;
+        dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w;
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = dst_data;
+    }
+}
+
+__kernel void arithm_sub_D4 (__global int *src1, int src1_step, int src1_offset,
+                             __global int *src2, int src2_step, int src2_offset,
+                             __global int *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        int data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int data2 = *((__global int *)((__global char *)src2 + src2_index));
+        long tmp  = (long)(data1) - (long)(data2);
+
+        *((__global int *)((__global char *)dst + dst_index)) = convert_int_sat(tmp);
+    }
+}
+__kernel void arithm_sub_D5 (__global float *src1, int src1_step, int src1_offset,
+                             __global float *src2, int src2_step, int src2_offset,
+                             __global float *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        float data1 = *((__global float *)((__global char *)src1 + src1_index));
+        float data2 = *((__global float *)((__global char *)src2 + src2_index));
+        float tmp = data1 - data2;
+
+        *((__global float *)((__global char *)dst + dst_index)) = tmp;
+    }
+}
+
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_sub_D6 (__global double *src1, int src1_step, int src1_offset,
+                             __global double *src2, int src2_step, int src2_offset,
+                             __global double *dst,  int dst_step,  int dst_offset,
+                             int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        double data1 = *((__global double *)((__global char *)src1 + src1_index));
+        double data2 = *((__global double *)((__global char *)src2 + src2_index));
+
+        *((__global double *)((__global char *)dst + dst_index)) = data1 - data2;
+    }
+}
+#endif
+
+/**************************************sub with mask**************************************/
+__kernel void arithm_sub_with_mask_C1_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                          __global uchar *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global uchar *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int src2_index = mad24(y, src2_step, x + src2_offset - dst_align); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        short4 tmp = convert_short4_sat(src1_data) - convert_short4_sat(src2_data);
+        uchar4 tmp_data = convert_uchar4_sat(tmp);
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((mask_data.z) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((mask_data.w) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_sub_with_mask_C1_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                                          __global ushort *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global ushort *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        ushort2 src1_data = vload2(0, (__global ushort *)((__global char *)src1 + src1_index));
+        ushort2 src2_data = vload2(0, (__global ushort *)((__global char *)src2 + src2_index));
+        uchar2  mask_data = vload2(0, mask + mask_index);
+
+        ushort2 data = *((__global ushort2 *)((__global uchar *)dst + dst_index));
+        int2    tmp = convert_int2_sat(src1_data) - convert_int2_sat(src2_data);
+        ushort2 tmp_data = convert_ushort2_sat(tmp);
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.y : data.y;
+
+        *((__global ushort2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_sub_with_mask_C1_D3 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        short2 src1_data = vload2(0, (__global short *)((__global char *)src1 + src1_index));
+        short2 src2_data = vload2(0, (__global short *)((__global char *)src2 + src2_index));
+        uchar2  mask_data = vload2(0, mask + mask_index);
+
+        short2 data = *((__global short2 *)((__global uchar *)dst + dst_index));
+        int2    tmp = convert_int2_sat(src1_data) - convert_int2_sat(src2_data);
+        short2 tmp_data = convert_short2_sat(tmp);
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.y : data.y;
+
+        *((__global short2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_sub_with_mask_C1_D4 (__global int   *src1, int src1_step, int src1_offset,
+                                          __global int   *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global int   *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int src_data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int src_data2 = *((__global int *)((__global char *)src2 + src2_index));
+        int dst_data  = *((__global int *)((__global char *)dst  + dst_index));
+
+        int data = convert_int_sat((long)src_data1 - (long)src_data2);
+        data = mask_data ? data : dst_data; 
+
+        *((__global int *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_sub_with_mask_C1_D5 (__global float *src1, int src1_step, int src1_offset,
+                                          __global float *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global float *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        float src_data1 = *((__global float *)((__global char *)src1 + src1_index));
+        float src_data2 = *((__global float *)((__global char *)src2 + src2_index));
+        float dst_data  = *((__global float *)((__global char *)dst  + dst_index));
+
+        float data = src_data1 - src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global float *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_sub_with_mask_C1_D6 (__global double *src1, int src1_step, int src1_offset,
+                                          __global double *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global double *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        double src_data1 = *((__global double *)((__global char *)src1 + src1_index));
+        double src_data2 = *((__global double *)((__global char *)src2 + src2_index));
+        double dst_data  = *((__global double *)((__global char *)dst  + dst_index));
+
+        double data = src_data1 - src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global double *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+
+__kernel void arithm_sub_with_mask_C2_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                          __global uchar *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global uchar *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        uchar4 src2_data = vload4(0, src2 + src2_index);
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        short4   tmp = convert_short4_sat(src1_data) - convert_short4_sat(src2_data);
+        uchar4 tmp_data = convert_uchar4_sat(tmp);
+
+        data.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.xy : data.xy;
+        data.zw = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.zw : data.zw;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_sub_with_mask_C2_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                                          __global ushort *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global ushort *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        ushort2 src_data1 = *((__global ushort2 *)((__global char *)src1 + src1_index));
+        ushort2 src_data2 = *((__global ushort2 *)((__global char *)src2 + src2_index));
+        ushort2 dst_data  = *((__global ushort2 *)((__global char *)dst  + dst_index));
+
+        int2    tmp = convert_int2_sat(src_data1) - convert_int2_sat(src_data2);
+        ushort2 data = convert_ushort2_sat(tmp);
+        data = mask_data ? data : dst_data; 
+
+        *((__global ushort2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_sub_with_mask_C2_D3 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short2 src_data1 = *((__global short2 *)((__global char *)src1 + src1_index));
+        short2 src_data2 = *((__global short2 *)((__global char *)src2 + src2_index));
+        short2 dst_data  = *((__global short2 *)((__global char *)dst  + dst_index));
+
+        int2    tmp = convert_int2_sat(src_data1) - convert_int2_sat(src_data2);
+        short2 data = convert_short2_sat(tmp);
+        data = mask_data ? data : dst_data; 
+
+        *((__global short2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_sub_with_mask_C2_D4 (__global int   *src1, int src1_step, int src1_offset,
+                                          __global int   *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global int    *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int2 src_data1 = *((__global int2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = *((__global int2 *)((__global char *)src2 + src2_index));
+        int2 dst_data  = *((__global int2 *)((__global char *)dst  + dst_index));
+
+        int2 data = convert_int2_sat(convert_long2_sat(src_data1) - convert_long2_sat(src_data2));
+        data = mask_data ? data : dst_data; 
+
+        *((__global int2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_sub_with_mask_C2_D5 (__global float *src1, int src1_step, int src1_offset,
+                                          __global float *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global float *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        float2 src_data1 = *((__global float2 *)((__global char *)src1 + src1_index));
+        float2 src_data2 = *((__global float2 *)((__global char *)src2 + src2_index));
+        float2 dst_data  = *((__global float2 *)((__global char *)dst  + dst_index));
+
+        float2 data = src_data1 - src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global float2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_sub_with_mask_C2_D6 (__global double *src1, int src1_step, int src1_offset,
+                                          __global double *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global double *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 4) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        double2 src_data1 = *((__global double2 *)((__global char *)src1 + src1_index));
+        double2 src_data2 = *((__global double2 *)((__global char *)src2 + src2_index));
+        double2 dst_data  = *((__global double2 *)((__global char *)dst  + dst_index));
+
+        double2 data = src_data1 - src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global double2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+__kernel void arithm_sub_with_mask_C3_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                          __global uchar *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global uchar *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+        int src2_index = mad24(y, src2_step, (x * 3) + src2_offset - (dst_align * 3)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        uchar4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        uchar4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        uchar4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        uchar4 src2_data_0 = vload4(0, src2 + src2_index + 0);
+        uchar4 src2_data_1 = vload4(0, src2 + src2_index + 4);
+        uchar4 src2_data_2 = vload4(0, src2 + src2_index + 8);
+
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        uchar4 data_0 = *((__global uchar4 *)(dst + dst_index + 0));
+        uchar4 data_1 = *((__global uchar4 *)(dst + dst_index + 4));
+        uchar4 data_2 = *((__global uchar4 *)(dst + dst_index + 8));
+
+        uchar4 tmp_data_0 = convert_uchar4_sat(convert_short4_sat(src1_data_0) - convert_short4_sat(src2_data_0));
+        uchar4 tmp_data_1 = convert_uchar4_sat(convert_short4_sat(src1_data_1) - convert_short4_sat(src2_data_1));
+        uchar4 tmp_data_2 = convert_uchar4_sat(convert_short4_sat(src1_data_2) - convert_short4_sat(src2_data_2));
+
+        data_0.xyz = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((mask_data.w) && (dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global uchar4 *)(dst + dst_index + 0)) = data_0;
+        *((__global uchar4 *)(dst + dst_index + 4)) = data_1;
+        *((__global uchar4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+__kernel void arithm_sub_with_mask_C3_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                                          __global ushort *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global ushort *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+        int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        ushort2 src1_data_0 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 0));
+        ushort2 src1_data_1 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 4));
+        ushort2 src1_data_2 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 8));
+
+        ushort2 src2_data_0 = vload2(0, (__global ushort *)((__global char *)src2 + src2_index + 0));
+        ushort2 src2_data_1 = vload2(0, (__global ushort *)((__global char *)src2 + src2_index + 4));
+        ushort2 src2_data_2 = vload2(0, (__global ushort *)((__global char *)src2 + src2_index + 8));
+
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        ushort2 data_0 = *((__global ushort2 *)((__global char *)dst + dst_index + 0));
+        ushort2 data_1 = *((__global ushort2 *)((__global char *)dst + dst_index + 4));
+        ushort2 data_2 = *((__global ushort2 *)((__global char *)dst + dst_index + 8));
+
+        ushort2 tmp_data_0 = convert_ushort2_sat(convert_int2_sat(src1_data_0) - convert_int2_sat(src2_data_0));
+        ushort2 tmp_data_1 = convert_ushort2_sat(convert_int2_sat(src1_data_1) - convert_int2_sat(src2_data_1));
+        ushort2 tmp_data_2 = convert_ushort2_sat(convert_int2_sat(src1_data_2) - convert_int2_sat(src2_data_2));
+
+        data_0.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global ushort2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_sub_with_mask_C3_D3 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+        int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        short2 src1_data_0 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 0));
+        short2 src1_data_1 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 4));
+        short2 src1_data_2 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 8));
+
+        short2 src2_data_0 = vload2(0, (__global short *)((__global char *)src2 + src2_index + 0));
+        short2 src2_data_1 = vload2(0, (__global short *)((__global char *)src2 + src2_index + 4));
+        short2 src2_data_2 = vload2(0, (__global short *)((__global char *)src2 + src2_index + 8));
+
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        short2 data_0 = *((__global short2 *)((__global char *)dst + dst_index + 0));
+        short2 data_1 = *((__global short2 *)((__global char *)dst + dst_index + 4));
+        short2 data_2 = *((__global short2 *)((__global char *)dst + dst_index + 8));
+
+        short2 tmp_data_0 = convert_short2_sat(convert_int2_sat(src1_data_0) - convert_int2_sat(src2_data_0));
+        short2 tmp_data_1 = convert_short2_sat(convert_int2_sat(src1_data_1) - convert_int2_sat(src2_data_1));
+        short2 tmp_data_2 = convert_short2_sat(convert_int2_sat(src1_data_2) - convert_int2_sat(src2_data_2));
+
+        data_0.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global short2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global short2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global short2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_sub_with_mask_C3_D4 (__global int   *src1, int src1_step, int src1_offset,
+                                          __global int   *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global int   *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int src2_index = mad24(y, src2_step, (x * 12) + src2_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        int src1_data_0 = *((__global int *)((__global char *)src1 + src1_index + 0));
+        int src1_data_1 = *((__global int *)((__global char *)src1 + src1_index + 4));
+        int src1_data_2 = *((__global int *)((__global char *)src1 + src1_index + 8));
+
+        int src2_data_0 = *((__global int *)((__global char *)src2 + src2_index + 0));
+        int src2_data_1 = *((__global int *)((__global char *)src2 + src2_index + 4));
+        int src2_data_2 = *((__global int *)((__global char *)src2 + src2_index + 8));
+
+        uchar mask_data = * (mask + mask_index);
+
+        int data_0 = *((__global int *)((__global char *)dst + dst_index + 0));
+        int data_1 = *((__global int *)((__global char *)dst + dst_index + 4));
+        int data_2 = *((__global int *)((__global char *)dst + dst_index + 8));
+
+        int tmp_data_0 = convert_int_sat((long)src1_data_0 - (long)src2_data_0);
+        int tmp_data_1 = convert_int_sat((long)src1_data_1 - (long)src2_data_1);
+        int tmp_data_2 = convert_int_sat((long)src1_data_2 - (long)src2_data_2);
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global int *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global int *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global int *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_sub_with_mask_C3_D5 (__global float *src1, int src1_step, int src1_offset,
+                                          __global float *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global float *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int src2_index = mad24(y, src2_step, (x * 12) + src2_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        float src1_data_0 = *((__global float *)((__global char *)src1 + src1_index + 0));
+        float src1_data_1 = *((__global float *)((__global char *)src1 + src1_index + 4));
+        float src1_data_2 = *((__global float *)((__global char *)src1 + src1_index + 8));
+                                             
+        float src2_data_0 = *((__global float *)((__global char *)src2 + src2_index + 0));
+        float src2_data_1 = *((__global float *)((__global char *)src2 + src2_index + 4));
+        float src2_data_2 = *((__global float *)((__global char *)src2 + src2_index + 8));
+
+        uchar mask_data = * (mask + mask_index);
+
+        float data_0 = *((__global float *)((__global char *)dst + dst_index + 0));
+        float data_1 = *((__global float *)((__global char *)dst + dst_index + 4));
+        float data_2 = *((__global float *)((__global char *)dst + dst_index + 8));
+
+        float tmp_data_0 = src1_data_0 - src2_data_0;
+        float tmp_data_1 = src1_data_1 - src2_data_1;
+        float tmp_data_2 = src1_data_2 - src2_data_2;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global float *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global float *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global float *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_sub_with_mask_C3_D6 (__global double *src1, int src1_step, int src1_offset,
+                                          __global double *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global double *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 24) + src1_offset); 
+        int src2_index = mad24(y, src2_step, (x * 24) + src2_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 24));
+
+        double src1_data_0 = *((__global double *)((__global char *)src1 + src1_index + 0 ));
+        double src1_data_1 = *((__global double *)((__global char *)src1 + src1_index + 8 ));
+        double src1_data_2 = *((__global double *)((__global char *)src1 + src1_index + 16));
+                                               
+        double src2_data_0 = *((__global double *)((__global char *)src2 + src2_index + 0 ));
+        double src2_data_1 = *((__global double *)((__global char *)src2 + src2_index + 8 ));
+        double src2_data_2 = *((__global double *)((__global char *)src2 + src2_index + 16));
+
+        uchar mask_data = * (mask + mask_index);
+
+        double data_0 = *((__global double *)((__global char *)dst + dst_index + 0 ));
+        double data_1 = *((__global double *)((__global char *)dst + dst_index + 8 ));
+        double data_2 = *((__global double *)((__global char *)dst + dst_index + 16));
+
+        double tmp_data_0 = src1_data_0 - src2_data_0;
+        double tmp_data_1 = src1_data_1 - src2_data_1;
+        double tmp_data_2 = src1_data_2 - src2_data_2;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global double *)((__global char *)dst + dst_index + 0 ))= data_0;
+       *((__global double *)((__global char *)dst + dst_index + 8 ))= data_1;
+       *((__global double *)((__global char *)dst + dst_index + 16))= data_2;
+    }
+}
+#endif
+__kernel void arithm_sub_with_mask_C4_D0 (__global uchar *src1, int src1_step, int src1_offset,
+                                          __global uchar *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global uchar *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 2) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        uchar4 src_data1 = *((__global uchar4 *)(src1 + src1_index));
+        uchar4 src_data2 = *((__global uchar4 *)(src2 + src2_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+
+        uchar4 data = convert_uchar4_sat(convert_short4_sat(src_data1) - convert_short4_sat(src_data2));
+        data = mask_data ? data : dst_data; 
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_sub_with_mask_C4_D2 (__global ushort *src1, int src1_step, int src1_offset,
+                                          __global ushort *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global ushort *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        ushort4 src_data1 = *((__global ushort4 *)((__global char *)src1 + src1_index));
+        ushort4 src_data2 = *((__global ushort4 *)((__global char *)src2 + src2_index));
+        ushort4 dst_data  = *((__global ushort4 *)((__global char *)dst  + dst_index));
+
+        ushort4 data = convert_ushort4_sat(convert_int4_sat(src_data1) - convert_int4_sat(src_data2));
+        data = mask_data ? data : dst_data; 
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_sub_with_mask_C4_D3 (__global short *src1, int src1_step, int src1_offset,
+                                          __global short *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global short *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 3) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short4 src_data1 = *((__global short4 *)((__global char *)src1 + src1_index));
+        short4 src_data2 = *((__global short4 *)((__global char *)src2 + src2_index));
+        short4 dst_data  = *((__global short4 *)((__global char *)dst  + dst_index));
+
+        short4 data = convert_short4_sat(convert_int4_sat(src_data1) - convert_int4_sat(src_data2));
+        data = mask_data ? data : dst_data; 
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_sub_with_mask_C4_D4 (__global int   *src1, int src1_step, int src1_offset,
+                                          __global int   *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global int   *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 4) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int4 src_data1 = *((__global int4 *)((__global char *)src1 + src1_index));
+        int4 src_data2 = *((__global int4 *)((__global char *)src2 + src2_index));
+        int4 dst_data  = *((__global int4 *)((__global char *)dst  + dst_index));
+
+        int4 data = convert_int4_sat(convert_long4_sat(src_data1) - convert_long4_sat(src_data2));
+        data = mask_data ? data : dst_data; 
+
+        *((__global int4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_sub_with_mask_C4_D5 (__global float *src1, int src1_step, int src1_offset,
+                                          __global float *src2, int src2_step, int src2_offset,
+                                          __global uchar *mask, int mask_step, int mask_offset,
+                                          __global float *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 4) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        float4 src_data1 = *((__global float4 *)((__global char *)src1 + src1_index));
+        float4 src_data2 = *((__global float4 *)((__global char *)src2 + src2_index));
+        float4 dst_data  = *((__global float4 *)((__global char *)dst  + dst_index));
+
+        float4 data = src_data1 - src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global float4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_sub_with_mask_C4_D6 (__global double *src1, int src1_step, int src1_offset,
+                                          __global double *src2, int src2_step, int src2_offset,
+                                          __global uchar  *mask, int mask_step, int mask_offset,
+                                          __global double *dst,  int dst_step,  int dst_offset,
+                                          int rows, int cols, int dst_step1)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 5) + src1_offset);
+        int src2_index = mad24(y, src2_step, (x << 5) + src2_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 5) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        double4 src_data1 = *((__global double4 *)((__global char *)src1 + src1_index));
+        double4 src_data2 = *((__global double4 *)((__global char *)src2 + src2_index));
+        double4 dst_data  = *((__global double4 *)((__global char *)dst  + dst_index));
+
+        double4 data = src_data1 - src_data2;
+        data = mask_data ? data : dst_data; 
+
+        *((__global double4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
diff --git a/modules/ocl/src/kernels/arithm_sub_scalar.cl b/modules/ocl/src/kernels/arithm_sub_scalar.cl
new file mode 100644 (file)
index 0000000..00d14eb
--- /dev/null
@@ -0,0 +1,806 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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*/
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+/**************************************sub with scalar without mask**************************************/
+__kernel void arithm_s_sub_C1_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                  __global   uchar *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        int4 src2_data = (int4)(src2.x, src2.x, src2.x, src2.x);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        int4 tmp = convert_int4_sat(src1_data) - src2_data;
+        tmp = isMatSubScalar ? tmp : -tmp;
+        uchar4 tmp_data = convert_uchar4_sat(tmp);
+
+        data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_C1_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                  __global   ushort *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        ushort2 src1_data = vload2(0, (__global ushort *)((__global char *)src1 + src1_index));
+        int2 src2_data = (int2)(src2.x, src2.x);
+
+        ushort2 data = *((__global ushort2 *)((__global uchar *)dst + dst_index));
+        int2    tmp = convert_int2_sat(src1_data) - src2_data;
+        tmp = isMatSubScalar ? tmp : -tmp;
+        ushort2 tmp_data = convert_ushort2_sat(tmp);
+
+        data.x = (dst_index + 0 >= dst_start) ? tmp_data.x : data.x;
+        data.y = (dst_index + 2 <  dst_end  ) ? tmp_data.y : data.y;
+
+        *((__global ushort2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_C1_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                  __global   short *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        short2 src1_data = vload2(0, (__global short *)((__global char *)src1 + src1_index));
+        int2 src2_data = (int2)(src2.x, src2.x);
+        short2 data = *((__global short2 *)((__global uchar *)dst + dst_index));
+
+        int2   tmp = convert_int2_sat(src1_data) - src2_data;
+        tmp = isMatSubScalar ? tmp : -tmp;
+        short2 tmp_data = convert_short2_sat(tmp);
+
+        data.x = (dst_index + 0 >= dst_start) ? tmp_data.x : data.x;
+        data.y = (dst_index + 2 <  dst_end  ) ? tmp_data.y : data.y;
+
+        *((__global short2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_C1_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                  __global   int *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        int src_data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int src_data2 = src2.x;
+
+        long tmp = (long)src_data1 - (long)src_data2;
+        tmp = isMatSubScalar ? tmp : -tmp;
+        int data = convert_int_sat(tmp);
+
+        *((__global int *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_C1_D5 (__global   float *src1, int src1_step, int src1_offset,
+                                  __global   float *dst,  int dst_step,  int dst_offset,
+                                  float4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        float src_data1 = *((__global float *)((__global char *)src1 + src1_index));
+        float src_data2 = src2.x;
+
+        float tmp = src_data1 - src_data2;
+        tmp = isMatSubScalar ? tmp : -tmp;
+
+        *((__global float *)((__global char *)dst + dst_index)) = tmp;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_sub_C1_D6 (__global   double *src1, int src1_step, int src1_offset,
+                                  __global   double *dst,  int dst_step,  int dst_offset,
+                                  double4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        double src_data1 = *((__global double *)((__global char *)src1 + src1_index));
+        double src2_data = src2.x;
+
+        double data = src_data1 - src2_data;
+        data = isMatSubScalar ? data : -data;
+
+        *((__global double *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+
+__kernel void arithm_s_sub_C2_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                  __global   uchar *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        int4 src2_data = (int4)(src2.x, src2.y, src2.x, src2.y);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        int4 tmp = convert_int4_sat(src1_data) - src2_data;
+        tmp = isMatSubScalar ? tmp : -tmp;
+        uchar4 tmp_data = convert_uchar4_sat(tmp);
+
+        data.xy = (dst_index + 0 >= dst_start) ? tmp_data.xy : data.xy;
+        data.zw = (dst_index + 2 <  dst_end  ) ? tmp_data.zw : data.zw;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_C2_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                  __global   ushort *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        ushort2 src_data1 = *((__global ushort2 *)((__global char *)src1 + src1_index));
+        int2 src_data2    = (int2)(src2.x, src2.y);
+        ushort2 dst_data  = *((__global ushort2 *)((__global char *)dst  + dst_index));
+
+        int2    tmp = convert_int2_sat(src_data1) - src_data2;
+        tmp = isMatSubScalar ? tmp : -tmp;
+        ushort2 data = convert_ushort2_sat(tmp);
+
+        *((__global ushort2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_C2_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                  __global   short *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        short2 src_data1 = *((__global short2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = (int2)(src2.x, src2.y);
+        short2 dst_data  = *((__global short2 *)((__global char *)dst  + dst_index));
+
+        int2    tmp = convert_int2_sat(src_data1) - src_data2;
+        tmp = isMatSubScalar ? tmp : -tmp;
+        short2 data = convert_short2_sat(tmp);
+
+        *((__global short2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_C2_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                  __global   int *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        int2 src_data1 = *((__global int2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = (int2)(src2.x, src2.y);
+        int2 dst_data  = *((__global int2 *)((__global char *)dst  + dst_index));
+
+        long2 tmp = convert_long2_sat(src_data1) - convert_long2_sat(src_data2);
+        tmp = isMatSubScalar ? tmp : -tmp;
+        int2 data = convert_int2_sat(tmp);
+
+        *((__global int2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_C2_D5 (__global   float *src1, int src1_step, int src1_offset,
+                                  __global   float *dst,  int dst_step,  int dst_offset,
+                                  float4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        float2 src_data1 = *((__global float2 *)((__global char *)src1 + src1_index));
+        float2 src_data2 = (float2)(src2.x, src2.y);
+        float2 dst_data  = *((__global float2 *)((__global char *)dst  + dst_index));
+
+        float2 tmp = src_data1 - src_data2;
+        tmp = isMatSubScalar ? tmp : -tmp;
+
+        *((__global float2 *)((__global char *)dst + dst_index)) = tmp;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_sub_C2_D6 (__global   double *src1, int src1_step, int src1_offset,
+                                  __global   double *dst,  int dst_step,  int dst_offset,
+                                  double4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        double2 src_data1 = *((__global double2 *)((__global char *)src1 + src1_index));
+        double2 src_data2 = (double2)(src2.x, src2.y);
+        double2 dst_data  = *((__global double2 *)((__global char *)dst  + dst_index));
+
+        double2 data = src_data1 - src_data2;
+        data = isMatSubScalar ? data : -data;
+
+        *((__global double2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+__kernel void arithm_s_sub_C3_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                  __global   uchar *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        uchar4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        uchar4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        uchar4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        int4 src2_data_0 = (int4)(src2.x, src2.y, src2.z, src2.x); 
+        int4 src2_data_1 = (int4)(src2.y, src2.z, src2.x, src2.y);
+        int4 src2_data_2 = (int4)(src2.z, src2.x, src2.y, src2.z); 
+
+        uchar4 data_0 = *((__global uchar4 *)(dst + dst_index + 0));
+        uchar4 data_1 = *((__global uchar4 *)(dst + dst_index + 4));
+        uchar4 data_2 = *((__global uchar4 *)(dst + dst_index + 8));
+
+        int4 tmp_0 = convert_int4_sat(src1_data_0) - src2_data_0;
+        int4 tmp_1 = convert_int4_sat(src1_data_1) - src2_data_1;
+        int4 tmp_2 = convert_int4_sat(src1_data_2) - src2_data_2;
+
+        tmp_0 = isMatSubScalar ? tmp_0 : -tmp_0;
+        tmp_1 = isMatSubScalar ? tmp_1 : -tmp_1;
+        tmp_2 = isMatSubScalar ? tmp_2 : -tmp_2;
+
+        uchar4 tmp_data_0 = convert_uchar4_sat(tmp_0);
+        uchar4 tmp_data_1 = convert_uchar4_sat(tmp_1);
+        uchar4 tmp_data_2 = convert_uchar4_sat(tmp_2);
+
+        data_0.xyz = ((dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global uchar4 *)(dst + dst_index + 0)) = data_0;
+        *((__global uchar4 *)(dst + dst_index + 4)) = data_1;
+        *((__global uchar4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+__kernel void arithm_s_sub_C3_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                  __global   ushort *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        ushort2 src1_data_0 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 0));
+        ushort2 src1_data_1 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 4));
+        ushort2 src1_data_2 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 8));
+
+        int2 src2_data_0 = (int2)(src2.x, src2.y);
+        int2 src2_data_1 = (int2)(src2.z, src2.x);
+        int2 src2_data_2 = (int2)(src2.y, src2.z);
+
+        ushort2 data_0 = *((__global ushort2 *)((__global char *)dst + dst_index + 0));
+        ushort2 data_1 = *((__global ushort2 *)((__global char *)dst + dst_index + 4));
+        ushort2 data_2 = *((__global ushort2 *)((__global char *)dst + dst_index + 8));
+
+        int2 tmp_0 = convert_int2_sat(src1_data_0) - src2_data_0;
+        int2 tmp_1 = convert_int2_sat(src1_data_1) - src2_data_1;
+        int2 tmp_2 = convert_int2_sat(src1_data_2) - src2_data_2;
+
+        tmp_0 = isMatSubScalar ? tmp_0 : -tmp_0;
+        tmp_1 = isMatSubScalar ? tmp_1 : -tmp_1;
+        tmp_2 = isMatSubScalar ? tmp_2 : -tmp_2;
+
+        ushort2 tmp_data_0 = convert_ushort2_sat(tmp_0);
+        ushort2 tmp_data_1 = convert_ushort2_sat(tmp_1);
+        ushort2 tmp_data_2 = convert_ushort2_sat(tmp_2);
+
+        data_0.xy = ((dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global ushort2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_sub_C3_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                  __global   short *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        short2 src1_data_0 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 0));
+        short2 src1_data_1 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 4));
+        short2 src1_data_2 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 8));
+
+        int2 src2_data_0 = (int2)(src2.x, src2.y);
+        int2 src2_data_1 = (int2)(src2.z, src2.x);
+        int2 src2_data_2 = (int2)(src2.y, src2.z);
+
+        short2 data_0 = *((__global short2 *)((__global char *)dst + dst_index + 0));
+        short2 data_1 = *((__global short2 *)((__global char *)dst + dst_index + 4));
+        short2 data_2 = *((__global short2 *)((__global char *)dst + dst_index + 8));
+
+        int2 tmp_0 = convert_int2_sat(src1_data_0) - src2_data_0;
+        int2 tmp_1 = convert_int2_sat(src1_data_1) - src2_data_1;
+        int2 tmp_2 = convert_int2_sat(src1_data_2) - src2_data_2;
+
+        tmp_0 = isMatSubScalar ? tmp_0 : -tmp_0;
+        tmp_1 = isMatSubScalar ? tmp_1 : -tmp_1;
+        tmp_2 = isMatSubScalar ? tmp_2 : -tmp_2;
+
+        short2 tmp_data_0 = convert_short2_sat(tmp_0);
+        short2 tmp_data_1 = convert_short2_sat(tmp_1);
+        short2 tmp_data_2 = convert_short2_sat(tmp_2);
+
+        data_0.xy = ((dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global short2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global short2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global short2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_sub_C3_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                  __global   int *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        int src1_data_0 = *((__global int *)((__global char *)src1 + src1_index + 0));
+        int src1_data_1 = *((__global int *)((__global char *)src1 + src1_index + 4));
+        int src1_data_2 = *((__global int *)((__global char *)src1 + src1_index + 8));
+
+        int src2_data_0 = src2.x;
+        int src2_data_1 = src2.y;
+        int src2_data_2 = src2.z;
+
+        int data_0 = *((__global int *)((__global char *)dst + dst_index + 0));
+        int data_1 = *((__global int *)((__global char *)dst + dst_index + 4));
+        int data_2 = *((__global int *)((__global char *)dst + dst_index + 8));
+
+        long tmp_0 = (long)src1_data_0 - (long)src2_data_0;
+        long tmp_1 = (long)src1_data_1 - (long)src2_data_1;
+        long tmp_2 = (long)src1_data_2 - (long)src2_data_2;
+
+        tmp_0 = isMatSubScalar ? tmp_0 : -tmp_0;
+        tmp_1 = isMatSubScalar ? tmp_1 : -tmp_1;
+        tmp_2 = isMatSubScalar ? tmp_2 : -tmp_2;
+
+        int tmp_data_0 = convert_int_sat(tmp_0);
+        int tmp_data_1 = convert_int_sat(tmp_1);
+        int tmp_data_2 = convert_int_sat(tmp_2);
+
+       *((__global int *)((__global char *)dst + dst_index + 0))= tmp_data_0;
+       *((__global int *)((__global char *)dst + dst_index + 4))= tmp_data_1;
+       *((__global int *)((__global char *)dst + dst_index + 8))= tmp_data_2;
+    }
+}
+__kernel void arithm_s_sub_C3_D5 (__global   float *src1, int src1_step, int src1_offset,
+                                  __global   float *dst,  int dst_step,  int dst_offset,
+                                  float4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        float src1_data_0 = *((__global float *)((__global char *)src1 + src1_index + 0));
+        float src1_data_1 = *((__global float *)((__global char *)src1 + src1_index + 4));
+        float src1_data_2 = *((__global float *)((__global char *)src1 + src1_index + 8));
+                                             
+        float src2_data_0 = src2.x;
+        float src2_data_1 = src2.y;
+        float src2_data_2 = src2.z;
+
+        float data_0 = *((__global float *)((__global char *)dst + dst_index + 0));
+        float data_1 = *((__global float *)((__global char *)dst + dst_index + 4));
+        float data_2 = *((__global float *)((__global char *)dst + dst_index + 8));
+
+        float tmp_0 = src1_data_0 - src2_data_0;
+        float tmp_1 = src1_data_1 - src2_data_1;
+        float tmp_2 = src1_data_2 - src2_data_2;
+
+        tmp_0 = isMatSubScalar ? tmp_0 : -tmp_0;
+        tmp_1 = isMatSubScalar ? tmp_1 : -tmp_1;
+        tmp_2 = isMatSubScalar ? tmp_2 : -tmp_2;
+
+       *((__global float *)((__global char *)dst + dst_index + 0))= tmp_0;
+       *((__global float *)((__global char *)dst + dst_index + 4))= tmp_1;
+       *((__global float *)((__global char *)dst + dst_index + 8))= tmp_2;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_sub_C3_D6 (__global   double *src1, int src1_step, int src1_offset,
+                                  __global   double *dst,  int dst_step,  int dst_offset,
+                                  double4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 24) + src1_offset); 
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 24));
+
+        double src1_data_0 = *((__global double *)((__global char *)src1 + src1_index + 0 ));
+        double src1_data_1 = *((__global double *)((__global char *)src1 + src1_index + 8 ));
+        double src1_data_2 = *((__global double *)((__global char *)src1 + src1_index + 16));
+                                               
+        double src2_data_0 = src2.x;
+        double src2_data_1 = src2.y;
+        double src2_data_2 = src2.z;
+
+        double data_0 = *((__global double *)((__global char *)dst + dst_index + 0 ));
+        double data_1 = *((__global double *)((__global char *)dst + dst_index + 8 ));
+        double data_2 = *((__global double *)((__global char *)dst + dst_index + 16));
+
+        double tmp_data_0 = src1_data_0 - src2_data_0;
+        double tmp_data_1 = src1_data_1 - src2_data_1;
+        double tmp_data_2 = src1_data_2 - src2_data_2;
+
+        tmp_data_0 = isMatSubScalar ? tmp_data_0 : -tmp_data_0;
+        tmp_data_1 = isMatSubScalar ? tmp_data_1 : -tmp_data_1;
+        tmp_data_2 = isMatSubScalar ? tmp_data_2 : -tmp_data_2;
+
+       *((__global double *)((__global char *)dst + dst_index + 0 ))= tmp_data_0;
+       *((__global double *)((__global char *)dst + dst_index + 8 ))= tmp_data_1;
+       *((__global double *)((__global char *)dst + dst_index + 16))= tmp_data_2;
+    }
+}
+#endif
+__kernel void arithm_s_sub_C4_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                  __global   uchar *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar4 src_data1 = *((__global uchar4 *)(src1 + src1_index));
+
+        int4 tmp = convert_int4_sat(src_data1) - src2;
+        tmp = isMatSubScalar ? tmp : -tmp;
+        uchar4 data = convert_uchar4_sat(tmp);
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_C4_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                  __global   ushort *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        ushort4 src_data1 = *((__global ushort4 *)((__global char *)src1 + src1_index));
+
+        int4 tmp = convert_int4_sat(src_data1) - src2;
+        tmp = isMatSubScalar ? tmp : -tmp;
+        ushort4 data = convert_ushort4_sat(tmp);
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_C4_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                  __global   short *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        short4 src_data1 = *((__global short4 *)((__global char *)src1 + src1_index));
+
+        int4 tmp = convert_int4_sat(src_data1) - src2;
+        tmp = isMatSubScalar ? tmp : -tmp;
+        short4 data = convert_short4_sat(tmp);
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_C4_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                  __global   int *dst,  int dst_step,  int dst_offset,
+                                  int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        int4 src_data1 = *((__global int4 *)((__global char *)src1 + src1_index));
+
+        long4 tmp = convert_long4_sat(src_data1) - convert_long4_sat(src2);
+        tmp = isMatSubScalar ? tmp : -tmp;
+        int4 data = convert_int4_sat(tmp);
+
+        *((__global int4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_C4_D5 (__global   float *src1, int src1_step, int src1_offset,
+                                  __global   float *dst,  int dst_step,  int dst_offset,
+                                  float4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        float4 src_data1 = *((__global float4 *)((__global char *)src1 + src1_index));
+
+        float4 tmp = src_data1 - src2;
+        tmp = isMatSubScalar ? tmp : -tmp;
+
+        *((__global float4 *)((__global char *)dst + dst_index)) = tmp;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_sub_C4_D6 (__global   double *src1, int src1_step, int src1_offset,
+                                  __global   double *dst,  int dst_step,  int dst_offset,
+                                  double4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 5) + src1_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 5) + dst_offset);
+
+        double4 src_data1 = *((__global double4 *)((__global char *)src1 + src1_index));
+
+        double4 data = src_data1 - src2;
+        data = isMatSubScalar ? data : -data;
+
+        *((__global double4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
diff --git a/modules/ocl/src/kernels/arithm_sub_scalar_mask.cl b/modules/ocl/src/kernels/arithm_sub_scalar_mask.cl
new file mode 100644 (file)
index 0000000..786dd76
--- /dev/null
@@ -0,0 +1,941 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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
+// 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*/
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+/**************************************sub with scalar with mask**************************************/
+__kernel void arithm_s_sub_with_mask_C1_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                            __global   uchar *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (dst_offset & 3)
+        int src1_index = mad24(y, src1_step, x + src1_offset - dst_align); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        int4 src2_data = (int4)(src2.x, src2.x, src2.x, src2.x);
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        int4 tmp = convert_int4_sat(src1_data) - src2_data;
+        tmp = isMatSubScalar ? tmp : -tmp;
+        uchar4 tmp_data = convert_uchar4_sat(tmp);
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : data.y;
+        data.z = ((mask_data.z) && (dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : data.z;
+        data.w = ((mask_data.w) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : data.w;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_with_mask_C1_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                            __global   ushort *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar  *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        ushort2 src1_data = vload2(0, (__global ushort *)((__global char *)src1 + src1_index));
+        int2 src2_data = (int2)(src2.x, src2.x);
+        uchar2  mask_data = vload2(0, mask + mask_index);
+
+        ushort2 data = *((__global ushort2 *)((__global uchar *)dst + dst_index));
+        int2    tmp = convert_int2_sat(src1_data) - src2_data;
+        tmp = isMatSubScalar ? tmp : -tmp;
+        ushort2 tmp_data = convert_ushort2_sat(tmp);
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.y : data.y;
+
+        *((__global ushort2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_with_mask_C1_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                            __global   short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        short2 src1_data = vload2(0, (__global short *)((__global char *)src1 + src1_index));
+        int2 src2_data = (int2)(src2.x, src2.x);
+        uchar2  mask_data = vload2(0, mask + mask_index);
+
+        short2 data = *((__global short2 *)((__global uchar *)dst + dst_index));
+        int2    tmp = convert_int2_sat(src1_data) - src2_data;
+        tmp = isMatSubScalar ? tmp : -tmp;
+        short2 tmp_data = convert_short2_sat(tmp);
+
+        data.x = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.x : data.x;
+        data.y = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.y : data.y;
+
+        *((__global short2 *)((__global uchar *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_with_mask_C1_D4 (__global   int   *src1, int src1_step, int src1_offset,
+                                            __global   int   *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int src_data1 = *((__global int *)((__global char *)src1 + src1_index));
+        int src_data2 = src2.x;
+        int dst_data  = *((__global int *)((__global char *)dst  + dst_index));
+
+        long tmp = (long)src_data1 - (long)src_data2;
+        tmp = isMatSubScalar ? tmp : - tmp;
+        int data = convert_int_sat(tmp);
+        data = mask_data ? data : dst_data; 
+
+        *((__global int *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+__kernel void arithm_s_sub_with_mask_C1_D5 (__global   float   *src1, int src1_step, int src1_offset,
+                                            __global   float   *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            float4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        float src_data1 = *((__global float *)((__global char *)src1 + src1_index));
+        float src_data2 = src2.x;
+        float dst_data  = *((__global float *)((__global char *)dst  + dst_index));
+
+        float data = src_data1 - src_data2;
+        data = isMatSubScalar ? data : -data;
+        data = mask_data ? data : dst_data; 
+
+        *((__global float *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_sub_with_mask_C1_D6 (__global   double   *src1, int src1_step, int src1_offset,
+                                            __global   double   *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            double4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        double src_data1 = *((__global double *)((__global char *)src1 + src1_index));
+        double src_data2 = src2.x;
+        double dst_data  = *((__global double *)((__global char *)dst  + dst_index));
+
+        double data = src_data1 - src_data2;
+        data = isMatSubScalar ? data : -data;
+        data = mask_data ? data : dst_data; 
+
+        *((__global double *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+__kernel void arithm_s_sub_with_mask_C2_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                            __global   uchar *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align ((dst_offset >> 1) & 1)
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        uchar4 src1_data = vload4(0, src1 + src1_index);
+        int4 src2_data = (int4)(src2.x, src2.y, src2.x, src2.y);
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        uchar4 data = *((__global uchar4 *)(dst + dst_index));
+        int4   tmp = convert_int4_sat(src1_data) - src2_data;
+        tmp = isMatSubScalar ? tmp : -tmp;
+        uchar4 tmp_data = convert_uchar4_sat(tmp);
+
+        data.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data.xy : data.xy;
+        data.zw = ((mask_data.y) && (dst_index + 2 <  dst_end  )) ? tmp_data.zw : data.zw;
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_with_mask_C2_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                            __global   ushort *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        ushort2 src_data1 = *((__global ushort2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = (int2)(src2.x, src2.y); 
+        ushort2 dst_data  = *((__global ushort2 *)((__global char *)dst  + dst_index));
+
+        int2    tmp = convert_int2_sat(src_data1) - src_data2;
+        tmp = isMatSubScalar ? tmp : -tmp;
+        ushort2 data = convert_ushort2_sat(tmp);
+        data = mask_data ? data : dst_data; 
+
+        *((__global ushort2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_with_mask_C2_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                            __global   short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short2 src_data1 = *((__global short2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = (int2)(src2.x, src2.y); 
+        short2 dst_data  = *((__global short2 *)((__global char *)dst  + dst_index));
+
+        int2    tmp = convert_int2_sat(src_data1) - src_data2;
+        tmp = isMatSubScalar ? tmp : -tmp;
+        short2 data = convert_short2_sat(tmp);
+        data = mask_data ? data : dst_data; 
+
+        *((__global short2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_with_mask_C2_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                            __global   int *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int2 src_data1 = *((__global int2 *)((__global char *)src1 + src1_index));
+        int2 src_data2 = (int2)(src2.x, src2.y); 
+        int2 dst_data  = *((__global int2 *)((__global char *)dst  + dst_index));
+
+        long2 tmp = convert_long2_sat(src_data1) - convert_long2_sat(src_data2);
+        tmp = isMatSubScalar ? tmp : -tmp;
+        int2 data = convert_int2_sat(tmp);
+        data = mask_data ? data : dst_data; 
+
+        *((__global int2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_with_mask_C2_D5 (__global   float *src1, int src1_step, int src1_offset,
+                                            __global   float *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            float4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        float2 src_data1 = *((__global float2 *)((__global char *)src1 + src1_index));
+        float2 src_data2 = (float2)(src2.x, src2.y); 
+        float2 dst_data  = *((__global float2 *)((__global char *)dst  + dst_index));
+
+        float2 data = src_data1 - src_data2;
+        data = isMatSubScalar ? data : -data;
+        data = mask_data ? data : dst_data; 
+
+        *((__global float2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_sub_with_mask_C2_D6 (__global   double *src1, int src1_step, int src1_offset,
+                                            __global   double *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            double4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        double2 src_data1 = *((__global double2 *)((__global char *)src1 + src1_index));
+        double2 src_data2 = (double2)(src2.x, src2.y); 
+        double2 dst_data  = *((__global double2 *)((__global char *)dst  + dst_index));
+
+        double2 data = src_data1 - src_data2;
+        data = isMatSubScalar ? data : -data;
+        data = mask_data ? data : dst_data; 
+
+        *((__global double2 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
+__kernel void arithm_s_sub_with_mask_C3_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                            __global   uchar *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 2;
+
+        #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+        int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 3) - (dst_align * 3));
+
+        uchar4 src1_data_0 = vload4(0, src1 + src1_index + 0);
+        uchar4 src1_data_1 = vload4(0, src1 + src1_index + 4);
+        uchar4 src1_data_2 = vload4(0, src1 + src1_index + 8);
+
+        int4 src2_data_0 = (int4)(src2.x, src2.y, src2.z, src2.x); 
+        int4 src2_data_1 = (int4)(src2.y, src2.z, src2.x, src2.y);
+        int4 src2_data_2 = (int4)(src2.z, src2.x, src2.y, src2.z); 
+
+        uchar4 mask_data = vload4(0, mask + mask_index);
+
+        uchar4 data_0 = *((__global uchar4 *)(dst + dst_index + 0));
+        uchar4 data_1 = *((__global uchar4 *)(dst + dst_index + 4));
+        uchar4 data_2 = *((__global uchar4 *)(dst + dst_index + 8));
+
+        int4 tmp_0 = convert_int4_sat(src1_data_0) - src2_data_0;
+        int4 tmp_1 = convert_int4_sat(src1_data_1) - src2_data_1;
+        int4 tmp_2 = convert_int4_sat(src1_data_2) - src2_data_2;
+
+        tmp_0 = isMatSubScalar ? tmp_0 : -tmp_0;
+        tmp_1 = isMatSubScalar ? tmp_1 : -tmp_1;
+        tmp_2 = isMatSubScalar ? tmp_2 : -tmp_2;
+
+        uchar4 tmp_data_0 = convert_uchar4_sat(tmp_0);
+        uchar4 tmp_data_1 = convert_uchar4_sat(tmp_1);
+        uchar4 tmp_data_2 = convert_uchar4_sat(tmp_2);
+
+        data_0.xyz = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xyz : data_0.xyz;
+        data_0.w   = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_0.w : data_0.w;
+
+        data_1.xy  = ((mask_data.y) && (dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) 
+                     ? tmp_data_1.xy : data_1.xy;
+        data_1.zw  = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.zw : data_1.zw;
+
+        data_2.x   = ((mask_data.z) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.x : data_2.x;
+        data_2.yzw = ((mask_data.w) && (dst_index + 9 >= dst_start) && (dst_index + 9 < dst_end)) 
+                     ? tmp_data_2.yzw : data_2.yzw;
+
+        *((__global uchar4 *)(dst + dst_index + 0)) = data_0;
+        *((__global uchar4 *)(dst + dst_index + 4)) = data_1;
+        *((__global uchar4 *)(dst + dst_index + 8)) = data_2;
+    }
+}
+__kernel void arithm_s_sub_with_mask_C3_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                            __global   ushort *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        ushort2 src1_data_0 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 0));
+        ushort2 src1_data_1 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 4));
+        ushort2 src1_data_2 = vload2(0, (__global ushort *)((__global char *)src1 + src1_index + 8));
+
+        int2 src2_data_0 = (int2)(src2.x, src2.y); 
+        int2 src2_data_1 = (int2)(src2.z, src2.x); 
+        int2 src2_data_2 = (int2)(src2.y, src2.z); 
+
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        ushort2 data_0 = *((__global ushort2 *)((__global char *)dst + dst_index + 0));
+        ushort2 data_1 = *((__global ushort2 *)((__global char *)dst + dst_index + 4));
+        ushort2 data_2 = *((__global ushort2 *)((__global char *)dst + dst_index + 8));
+
+        int2 tmp_0 = convert_int2_sat(src1_data_0) - src2_data_0;
+        int2 tmp_1 = convert_int2_sat(src1_data_1) - src2_data_1;
+        int2 tmp_2 = convert_int2_sat(src1_data_2) - src2_data_2;
+
+        tmp_0 = isMatSubScalar ? tmp_0 : -tmp_0;
+        tmp_1 = isMatSubScalar ? tmp_1 : -tmp_1;
+        tmp_2 = isMatSubScalar ? tmp_2 : -tmp_2;
+
+        ushort2 tmp_data_0 = convert_ushort2_sat(tmp_0);
+        ushort2 tmp_data_1 = convert_ushort2_sat(tmp_1);
+        ushort2 tmp_data_2 = convert_ushort2_sat(tmp_2);
+
+        data_0.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global ushort2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global ushort2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_sub_with_mask_C3_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                            __global   short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        x = x << 1;
+
+        #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+        int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6)); 
+        int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 6) - (dst_align * 6));
+
+        short2 src1_data_0 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 0));
+        short2 src1_data_1 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 4));
+        short2 src1_data_2 = vload2(0, (__global short *)((__global char *)src1 + src1_index + 8));
+
+        int2 src2_data_0 = (int2)(src2.x, src2.y); 
+        int2 src2_data_1 = (int2)(src2.z, src2.x); 
+        int2 src2_data_2 = (int2)(src2.y, src2.z); 
+
+        uchar2 mask_data = vload2(0, mask + mask_index);
+
+        short2 data_0 = *((__global short2 *)((__global char *)dst + dst_index + 0));
+        short2 data_1 = *((__global short2 *)((__global char *)dst + dst_index + 4));
+        short2 data_2 = *((__global short2 *)((__global char *)dst + dst_index + 8));
+
+        int2 tmp_0 = convert_int2_sat(src1_data_0) - src2_data_0;
+        int2 tmp_1 = convert_int2_sat(src1_data_1) - src2_data_1;
+        int2 tmp_2 = convert_int2_sat(src1_data_2) - src2_data_2;
+
+        tmp_0 = isMatSubScalar ? tmp_0 : -tmp_0;
+        tmp_1 = isMatSubScalar ? tmp_1 : -tmp_1;
+        tmp_2 = isMatSubScalar ? tmp_2 : -tmp_2;
+
+        short2 tmp_data_0 = convert_short2_sat(tmp_0);
+        short2 tmp_data_1 = convert_short2_sat(tmp_1);
+        short2 tmp_data_2 = convert_short2_sat(tmp_2);
+
+        data_0.xy = ((mask_data.x) && (dst_index + 0 >= dst_start)) ? tmp_data_0.xy : data_0.xy;
+
+        data_1.x  = ((mask_data.x) && (dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) 
+                     ? tmp_data_1.x : data_1.x;
+        data_1.y  = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_1.y : data_1.y;
+
+        data_2.xy = ((mask_data.y) && (dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) 
+                     ? tmp_data_2.xy : data_2.xy;
+
+       *((__global short2 *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global short2 *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global short2 *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_sub_with_mask_C3_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                            __global   int *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        int src1_data_0 = *((__global int *)((__global char *)src1 + src1_index + 0));
+        int src1_data_1 = *((__global int *)((__global char *)src1 + src1_index + 4));
+        int src1_data_2 = *((__global int *)((__global char *)src1 + src1_index + 8));
+
+        int src2_data_0 = src2.x; 
+        int src2_data_1 = src2.y;
+        int src2_data_2 = src2.z; 
+
+        uchar mask_data = * (mask + mask_index);
+
+        int data_0 = *((__global int *)((__global char *)dst + dst_index + 0));
+        int data_1 = *((__global int *)((__global char *)dst + dst_index + 4));
+        int data_2 = *((__global int *)((__global char *)dst + dst_index + 8));
+
+        long tmp_0 = (long)src1_data_0 - (long)src2_data_0;
+        long tmp_1 = (long)src1_data_1 - (long)src2_data_1;
+        long tmp_2 = (long)src1_data_2 - (long)src2_data_2;
+        
+        tmp_0 = isMatSubScalar ? tmp_0 : -tmp_0;
+        tmp_1 = isMatSubScalar ? tmp_1 : -tmp_1;
+        tmp_2 = isMatSubScalar ? tmp_2 : -tmp_2;
+
+        int tmp_data_0 = convert_int_sat(tmp_0);
+        int tmp_data_1 = convert_int_sat(tmp_1);
+        int tmp_data_2 = convert_int_sat(tmp_2);
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global int *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global int *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global int *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+__kernel void arithm_s_sub_with_mask_C3_D5 (__global   float *src1, int src1_step, int src1_offset,
+                                            __global   float *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            float4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 12) + src1_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 12));
+
+        float src1_data_0 = *((__global float *)((__global char *)src1 + src1_index + 0));
+        float src1_data_1 = *((__global float *)((__global char *)src1 + src1_index + 4));
+        float src1_data_2 = *((__global float *)((__global char *)src1 + src1_index + 8));
+                                             
+        float src2_data_0 = src2.x; 
+        float src2_data_1 = src2.y;
+        float src2_data_2 = src2.z; 
+
+        uchar mask_data = * (mask + mask_index);
+
+        float data_0 = *((__global float *)((__global char *)dst + dst_index + 0));
+        float data_1 = *((__global float *)((__global char *)dst + dst_index + 4));
+        float data_2 = *((__global float *)((__global char *)dst + dst_index + 8));
+
+        float tmp_data_0 = src1_data_0 - src2_data_0;
+        float tmp_data_1 = src1_data_1 - src2_data_1;
+        float tmp_data_2 = src1_data_2 - src2_data_2;
+
+        tmp_data_0 = isMatSubScalar ? tmp_data_0 : -tmp_data_0;
+        tmp_data_1 = isMatSubScalar ? tmp_data_1 : -tmp_data_1;
+        tmp_data_2 = isMatSubScalar ? tmp_data_2 : -tmp_data_2;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global float *)((__global char *)dst + dst_index + 0))= data_0;
+       *((__global float *)((__global char *)dst + dst_index + 4))= data_1;
+       *((__global float *)((__global char *)dst + dst_index + 8))= data_2;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_sub_with_mask_C3_D6 (__global   double *src1, int src1_step, int src1_offset,
+                                            __global   double *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar  *mask, int mask_step, int mask_offset,
+                                            double4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x * 24) + src1_offset); 
+        int mask_index = mad24(y, mask_step, x + mask_offset);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x * 24));
+
+        double src1_data_0 = *((__global double *)((__global char *)src1 + src1_index + 0 ));
+        double src1_data_1 = *((__global double *)((__global char *)src1 + src1_index + 8 ));
+        double src1_data_2 = *((__global double *)((__global char *)src1 + src1_index + 16));
+                                               
+        double src2_data_0 = src2.x; 
+        double src2_data_1 = src2.y;
+        double src2_data_2 = src2.z; 
+
+        uchar mask_data = * (mask + mask_index);
+
+        double data_0 = *((__global double *)((__global char *)dst + dst_index + 0 ));
+        double data_1 = *((__global double *)((__global char *)dst + dst_index + 8 ));
+        double data_2 = *((__global double *)((__global char *)dst + dst_index + 16));
+
+        double tmp_data_0 = src1_data_0 - src2_data_0;
+        double tmp_data_1 = src1_data_1 - src2_data_1;
+        double tmp_data_2 = src1_data_2 - src2_data_2;
+
+        tmp_data_0 = isMatSubScalar ? tmp_data_0 : -tmp_data_0;
+        tmp_data_1 = isMatSubScalar ? tmp_data_1 : -tmp_data_1;
+        tmp_data_2 = isMatSubScalar ? tmp_data_2 : -tmp_data_2;
+
+        data_0 = mask_data ? tmp_data_0 : data_0;
+        data_1 = mask_data ? tmp_data_1 : data_1;
+        data_2 = mask_data ? tmp_data_2 : data_2;
+
+       *((__global double *)((__global char *)dst + dst_index + 0 ))= data_0;
+       *((__global double *)((__global char *)dst + dst_index + 8 ))= data_1;
+       *((__global double *)((__global char *)dst + dst_index + 16))= data_2;
+    }
+}
+#endif
+__kernel void arithm_s_sub_with_mask_C4_D0 (__global   uchar *src1, int src1_step, int src1_offset,
+                                            __global   uchar *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 2) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 2) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        uchar4 src_data1 = *((__global uchar4 *)(src1 + src1_index));
+        uchar4 dst_data  = *((__global uchar4 *)(dst  + dst_index));
+
+        int4 tmp = convert_int4_sat(src_data1) - src2;
+        tmp = isMatSubScalar ? tmp : -tmp;
+        uchar4 data = convert_uchar4_sat(tmp);
+
+        data = mask_data ? data : dst_data; 
+
+        *((__global uchar4 *)(dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_with_mask_C4_D2 (__global   ushort *src1, int src1_step, int src1_offset,
+                                            __global   ushort *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        ushort4 src_data1 = *((__global ushort4 *)((__global char *)src1 + src1_index));
+        ushort4 dst_data  = *((__global ushort4 *)((__global char *)dst  + dst_index));
+
+        int4    tmp = convert_int4_sat(src_data1) - src2;
+        tmp = isMatSubScalar ? tmp : -tmp;
+        ushort4 data = convert_ushort4_sat(tmp);
+
+        data = mask_data ? data : dst_data; 
+
+        *((__global ushort4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_with_mask_C4_D3 (__global   short *src1, int src1_step, int src1_offset,
+                                            __global   short *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 3) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 3) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        short4 src_data1 = *((__global short4 *)((__global char *)src1 + src1_index));
+        short4 dst_data  = *((__global short4 *)((__global char *)dst  + dst_index));
+
+        int4    tmp = convert_int4_sat(src_data1) - src2;
+        tmp = isMatSubScalar ? tmp : -tmp;
+        short4 data = convert_short4_sat(tmp);
+
+        data = mask_data ? data : dst_data; 
+
+        *((__global short4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_with_mask_C4_D4 (__global   int *src1, int src1_step, int src1_offset,
+                                            __global   int *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            int4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        int4 src_data1 = *((__global int4 *)((__global char *)src1 + src1_index));
+        int4 dst_data  = *((__global int4 *)((__global char *)dst  + dst_index));
+
+        long4 tmp = convert_long4_sat(src_data1) - convert_long4_sat(src2);
+        tmp = isMatSubScalar ? tmp : -tmp;
+        int4 data = convert_int4_sat(tmp);
+
+        data = mask_data ? data : dst_data; 
+
+        *((__global int4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+__kernel void arithm_s_sub_with_mask_C4_D5 (__global   float *src1, int src1_step, int src1_offset,
+                                            __global   float *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            float4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 4) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 4) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        float4 src_data1 = *((__global float4 *)((__global char *)src1 + src1_index));
+        float4 dst_data  = *((__global float4 *)((__global char *)dst  + dst_index));
+
+        float4 data = src_data1 - src2;
+        data = isMatSubScalar ? data : -data;
+
+        data = mask_data ? data : dst_data; 
+
+        *((__global float4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void arithm_s_sub_with_mask_C4_D6 (__global   double *src1, int src1_step, int src1_offset,
+                                            __global   double *dst,  int dst_step,  int dst_offset,
+                                            __global   uchar *mask, int mask_step, int mask_offset,
+                                            double4 src2, int rows, int cols, int dst_step1, int isMatSubScalar)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (x < cols && y < rows)
+    {
+        int src1_index = mad24(y, src1_step, (x << 5) + src1_offset);
+        int mask_index = mad24(y, mask_step,  x       + mask_offset);
+        int dst_index  = mad24(y, dst_step,  (x << 5) + dst_offset);
+
+        uchar mask_data = *(mask + mask_index);
+
+        double4 src_data1 = *((__global double4 *)((__global char *)src1 + src1_index));
+        double4 dst_data  = *((__global double4 *)((__global char *)dst  + dst_index));
+
+        double4 data = src_data1 - src2;
+        data = isMatSubScalar ? data : -data;
+        data = mask_data ? data : dst_data; 
+
+        *((__global double4 *)((__global char *)dst + dst_index)) = data;
+    }
+}
+#endif
diff --git a/modules/ocl/src/kernels/arithm_sum.cl b/modules/ocl/src/kernels/arithm_sum.cl
new file mode 100644 (file)
index 0000000..0866a52
--- /dev/null
@@ -0,0 +1,206 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Shengen Yan,yanshengen@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 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*/
+
+/**************************************PUBLICFUNC*************************************/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#define RES_TYPE double8
+#define CONVERT_RES_TYPE convert_double8
+#else
+#define RES_TYPE float8
+#define CONVERT_RES_TYPE convert_float8
+#endif
+
+#if defined (DEPTH_0)
+#define VEC_TYPE uchar8
+#endif
+#if defined (DEPTH_1)
+#define VEC_TYPE char8
+#endif
+#if defined (DEPTH_2)
+#define VEC_TYPE ushort8
+#endif
+#if defined (DEPTH_3)
+#define VEC_TYPE short8
+#endif
+#if defined (DEPTH_4)
+#define VEC_TYPE int8
+#endif
+#if defined (DEPTH_5)
+#define VEC_TYPE float8
+#endif
+#if defined (DEPTH_6)
+#define VEC_TYPE double8
+#endif
+
+#if defined (FUNC_TYPE_0)
+#define FUNC(a,b) b += a;
+#endif
+#if defined (FUNC_TYPE_1)
+#define FUNC(a,b) b = b + (a >= 0 ? a : -a);
+#endif
+#if defined (FUNC_TYPE_2)
+#define FUNC(a,b) b = b + a * a;
+#endif
+
+#if defined (REPEAT_S0)
+#define repeat_s(a) a = a;
+#endif
+#if defined (REPEAT_S1)
+#define repeat_s(a) a.s0 = 0;
+#endif
+#if defined (REPEAT_S2)
+#define repeat_s(a) a.s0 = 0;a.s1 = 0;
+#endif
+#if defined (REPEAT_S3)
+#define repeat_s(a) a.s0 = 0;a.s1 = 0;a.s2 = 0;
+#endif
+#if defined (REPEAT_S4)
+#define repeat_s(a) a.s0 = 0;a.s1 = 0;a.s2 = 0;a.s3 = 0;
+#endif
+#if defined (REPEAT_S5)
+#define repeat_s(a) a.s0 = 0;a.s1 = 0;a.s2 = 0;a.s3 = 0;a.s4 = 0;
+#endif
+#if defined (REPEAT_S6)
+#define repeat_s(a) a.s0 = 0;a.s1 = 0;a.s2 = 0;a.s3 = 0;a.s4 = 0;a.s5 = 0;
+#endif
+#if defined (REPEAT_S7)
+#define repeat_s(a) a.s0 = 0;a.s1 = 0;a.s2 = 0;a.s3 = 0;a.s4 = 0;a.s5 = 0;a.s6 = 0;
+#endif
+
+#if defined (REPEAT_E0)
+#define repeat_e(a) a = a;
+#endif
+#if defined (REPEAT_E1)
+#define repeat_e(a) a.s7 = 0;
+#endif
+#if defined (REPEAT_E2)
+#define repeat_e(a) a.s7 = 0;a.s6 = 0;
+#endif
+#if defined (REPEAT_E3)
+#define repeat_e(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;
+#endif
+#if defined (REPEAT_E4)
+#define repeat_e(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;a.s4 = 0;
+#endif
+#if defined (REPEAT_E5)
+#define repeat_e(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;a.s4 = 0;a.s3 = 0;
+#endif
+#if defined (REPEAT_E6)
+#define repeat_e(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;a.s4 = 0;a.s3 = 0;a.s2 = 0;
+#endif
+#if defined (REPEAT_E7)
+#define repeat_e(a) a.s7 = 0;a.s6 = 0;a.s5 = 0;a.s4 = 0;a.s3 = 0;a.s2 = 0;a.s1 = 0;
+#endif
+
+#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics:enable
+#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics:enable
+
+/**************************************Array buffer SUM**************************************/
+__kernel void arithm_op_sum (int cols,int invalid_cols,int offset,int elemnum,int groupnum,
+                                __global VEC_TYPE *src, __global RES_TYPE *dst)
+{
+   unsigned int lid = get_local_id(0);
+   unsigned int gid = get_group_id(0);
+   unsigned int  id = get_global_id(0);
+   unsigned int idx = offset + id + (id / cols) * invalid_cols;
+   __local RES_TYPE localmem_sum[128];
+   RES_TYPE sum = 0,temp;
+   if(id < elemnum)
+   {
+       temp = CONVERT_RES_TYPE(src[idx]);
+       if(id % cols == 0 ) 
+       {
+           repeat_s(temp);
+       }
+       if(id % cols == cols - 1)
+       {
+           repeat_e(temp);
+       }
+       FUNC(temp,sum);
+   }
+   else
+   {
+       sum = 0;
+   }
+   for(id=id + (groupnum << 8); id < elemnum;id = id + (groupnum << 8))
+   {
+       idx = offset + id + (id / cols) * invalid_cols;
+       temp = CONVERT_RES_TYPE(src[idx]);
+       if(id % cols == 0 ) 
+       {
+               repeat_s(temp);
+       }
+       if(id % cols == cols - 1)
+       {
+               repeat_e(temp);
+       }
+       FUNC(temp,sum);
+   }
+   if(lid > 127)
+   {
+       localmem_sum[lid - 128] = sum;
+   }
+   barrier(CLK_LOCAL_MEM_FENCE);
+   if(lid < 128)
+   {
+       localmem_sum[lid] = sum + localmem_sum[lid];
+   }
+   barrier(CLK_LOCAL_MEM_FENCE);
+   for(int lsize = 64; lsize > 0; lsize >>= 1)
+   {
+       if(lid < lsize)
+       {
+           int lid2 = lsize + lid;
+           localmem_sum[lid] = localmem_sum[lid] + localmem_sum[lid2];
+       }
+       barrier(CLK_LOCAL_MEM_FENCE);
+   }
+   if( lid == 0)
+   {
+       dst[gid] = localmem_sum[0];
+   }
+}
+
diff --git a/modules/ocl/src/kernels/arithm_sum_3.cl b/modules/ocl/src/kernels/arithm_sum_3.cl
new file mode 100644 (file)
index 0000000..944ce26
--- /dev/null
@@ -0,0 +1,248 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Shengen Yan,yanshengen@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 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*/
+
+/**************************************PUBLICFUNC*************************************/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#define RES_TYPE double4
+#define CONVERT_RES_TYPE convert_double4
+#else
+#define RES_TYPE float4
+#define CONVERT_RES_TYPE convert_float4
+#endif
+
+#if defined (DEPTH_0)
+#define VEC_TYPE uchar4
+#endif
+#if defined (DEPTH_1)
+#define VEC_TYPE char4
+#endif
+#if defined (DEPTH_2)
+#define VEC_TYPE ushort4
+#endif
+#if defined (DEPTH_3)
+#define VEC_TYPE short4
+#endif
+#if defined (DEPTH_4)
+#define VEC_TYPE int4
+#endif
+#if defined (DEPTH_5)
+#define VEC_TYPE float4
+#endif
+#if defined (DEPTH_6)
+#define VEC_TYPE double4
+#endif
+
+#if defined (FUNC_TYPE_0)
+#define FUNC(a,b) b += a;
+#endif
+#if defined (FUNC_TYPE_1)
+#define FUNC(a,b) b = b + (a >= 0 ? a : -a);
+#endif
+#if defined (FUNC_TYPE_2)
+#define FUNC(a,b) b = b + a * a;
+#endif
+
+#if defined (REPEAT_S0)
+#define repeat_s(a,b,c) a=a; b =b; c=c;
+#endif
+#if defined (REPEAT_S1)
+#define repeat_s(a,b,c) a.s0=0; b=b; c=c;
+#endif
+#if defined (REPEAT_S2)
+#define repeat_s(a,b,c) a.s0=0; a.s1=0; b=b; c=c;
+#endif
+#if defined (REPEAT_S3)
+#define repeat_s(a,b,c) a.s0=0; a.s1=0; a.s2=0; b=b; c=c;
+#endif
+#if defined (REPEAT_S4)
+#define repeat_s(a,b,c) a=0;b=b; c=c;
+#endif
+#if defined (REPEAT_S5)
+#define repeat_s(a,b,c) a=0; b.s0=0;c=c;
+#endif
+#if defined (REPEAT_S6)
+#define repeat_s(a,b,c) a=0; b.s0=0; b.s1=0; c=c;
+#endif
+#if defined (REPEAT_S7)
+#define repeat_s(a,b,c) a=0; b.s0=0; b.s1=0; b.s2=0; c=c;
+#endif
+#if defined (REPEAT_S8)
+#define repeat_s(a,b,c) a=0; b=0; c=c;
+#endif
+#if defined (REPEAT_S9)
+#define repeat_s(a,b,c) a=0; b=0; c.s0=0;
+#endif
+#if defined (REPEAT_S10)
+#define repeat_s(a,b,c) a=0; b=0; c.s0=0; c.s1=0;
+#endif
+#if defined (REPEAT_S11)
+#define repeat_s(a,b,c) a=0; b=0; c.s0=0; c.s1=0; c.s2=0;
+#endif
+
+#if defined (REPEAT_E0)
+#define repeat_e(a,b,c) a=a; b =b; c=c;
+#endif
+#if defined (REPEAT_E1)
+#define repeat_e(a,b,c) a=a; b=b; c.s3=0;
+#endif
+#if defined (REPEAT_E2)
+#define repeat_e(a,b,c) a=a; b=b; c.s3=0; c.s2=0;
+#endif
+#if defined (REPEAT_E3)
+#define repeat_e(a,b,c) a=a; b=b; c.s3=0; c.s2=0; c.s1=0;
+#endif
+#if defined (REPEAT_E4)
+#define repeat_e(a,b,c) a=a; b=b; c=0;
+#endif
+#if defined (REPEAT_E5)
+#define repeat_e(a,b,c) a=a; b.s3=0; c=0;
+#endif
+#if defined (REPEAT_E6)
+#define repeat_e(a,b,c) a=a; b.s3=0; b.s2=0; c=0;
+#endif
+#if defined (REPEAT_E7)
+#define repeat_e(a,b,c) a=a; b.s3=0; b.s2=0; b.s1=0; c=0;
+#endif
+#if defined (REPEAT_E8)
+#define repeat_e(a,b,c) a=a; b=0; c=0;
+#endif
+#if defined (REPEAT_E9)
+#define repeat_e(a,b,c) a.s3=0; b=0; c=0;
+#endif
+#if defined (REPEAT_E10)
+#define repeat_e(a,b,c) a.s3=0; a.s2=0; b=0; c=0;
+#endif
+#if defined (REPEAT_E11)
+#define repeat_e(a,b,c) a.s3=0; a.s2=0; a.s1=0; b=0; c=0;
+#endif
+
+__kernel void arithm_op_sum_3 (int cols,int invalid_cols,int offset,int elemnum,int groupnum,  
+                                __global VEC_TYPE *src, __global RES_TYPE *dst)
+{
+   unsigned int lid = get_local_id(0);
+   unsigned int gid = get_group_id(0);
+   unsigned int id = get_global_id(0);
+   unsigned int idx = offset + id + (id  / cols) * invalid_cols;
+   idx = idx * 3;
+   __local RES_TYPE localmem_sum1[128];
+   __local RES_TYPE localmem_sum2[128];
+   __local RES_TYPE localmem_sum3[128];
+   RES_TYPE sum1 = 0,sum2 = 0,sum3 = 0,temp1,temp2,temp3;
+   if(id < elemnum)
+   {
+       temp1 = CONVERT_RES_TYPE(src[idx]);
+       temp2 = CONVERT_RES_TYPE(src[idx+1]);
+       temp3 = CONVERT_RES_TYPE(src[idx+2]);
+       if(id % cols == 0 ) 
+       {
+           repeat_s(temp1,temp2,temp3);
+       }
+       if(id % cols == cols - 1)
+       {
+           repeat_e(temp1,temp2,temp3);
+       }
+       FUNC(temp1,sum1);
+       FUNC(temp2,sum2);
+       FUNC(temp3,sum3);
+   }
+   else
+   {
+       sum1 = 0;
+       sum2 = 0;
+       sum3 = 0;
+   }
+   for(id=id + (groupnum << 8); id < elemnum;id = id + (groupnum << 8))
+   {
+       idx = offset + id + (id / cols) * invalid_cols;
+       idx = idx * 3;
+       temp1 = CONVERT_RES_TYPE(src[idx]);
+       temp2 = CONVERT_RES_TYPE(src[idx+1]);
+       temp3 = CONVERT_RES_TYPE(src[idx+2]);
+       if(id % cols == 0 ) 
+       {
+               repeat_s(temp1,temp2,temp3);
+       }
+       if(id % cols == cols - 1)
+       {
+               repeat_e(temp1,temp2,temp3);
+       }
+       FUNC(temp1,sum1);
+       FUNC(temp2,sum2);
+       FUNC(temp3,sum3);
+   }
+   if(lid > 127)
+   {
+       localmem_sum1[lid - 128] = sum1;
+       localmem_sum2[lid - 128] = sum2;
+       localmem_sum3[lid - 128] = sum3;
+   }
+   barrier(CLK_LOCAL_MEM_FENCE);
+   if(lid < 128)
+   {
+       localmem_sum1[lid] = sum1 + localmem_sum1[lid];
+       localmem_sum2[lid] = sum2 + localmem_sum2[lid];
+       localmem_sum3[lid] = sum3 + localmem_sum3[lid];
+   }
+   barrier(CLK_LOCAL_MEM_FENCE);
+   for(int lsize = 64; lsize > 0; lsize >>= 1)
+   {
+       if(lid < lsize)
+       {
+           int lid2 = lsize + lid;
+           localmem_sum1[lid] = localmem_sum1[lid] + localmem_sum1[lid2];
+           localmem_sum2[lid] = localmem_sum2[lid] + localmem_sum2[lid2];
+           localmem_sum3[lid] = localmem_sum3[lid] + localmem_sum3[lid2];
+       }
+       barrier(CLK_LOCAL_MEM_FENCE);
+   }
+   if( lid == 0)
+   {
+       dst[gid*3]   = localmem_sum1[0];
+       dst[gid*3+1] = localmem_sum2[0];
+       dst[gid*3+2] = localmem_sum3[0];
+   }
+}
+
diff --git a/modules/ocl/src/kernels/arithm_transpose.cl b/modules/ocl/src/kernels/arithm_transpose.cl
new file mode 100644 (file)
index 0000000..0630c09
--- /dev/null
@@ -0,0 +1,510 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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 TILE_DIM      32 
+#define BLOCK_ROWS    8 
+#define LDS_STEP     (TILE_DIM + 1)
+
+
+//8UC1 is not unoptimized, as the size of write per thread is 8 
+//which will use completepath
+__kernel void transpose_C1_D0(__global uchar* src, int src_step, int src_offset, 
+                              __global uchar* dst, int dst_step, int dst_offset,
+                              int src_rows, int src_cols)
+{
+
+    int gp_x = get_group_id(0),   gp_y = get_group_id(1);
+    int gs_x = get_num_groups(0), gs_y = get_num_groups(1);
+
+    int groupId_x, groupId_y;
+
+    if(src_rows == src_cols)
+    {
+        groupId_y = gp_x;  
+        groupId_x = (gp_x + gp_y) % gs_x;
+    }
+    else
+    {
+        int bid = gp_x + gs_x * gp_y; 
+        groupId_y =  bid % gs_y;  
+        groupId_x = ((bid / gs_y) + groupId_y) % gs_x;
+    }
+
+    int lx = get_local_id(0);
+    int ly = get_local_id(1);
+
+    int x = groupId_x * TILE_DIM + lx;
+    int y = groupId_y * TILE_DIM + ly;
+
+    int x_index = groupId_y * TILE_DIM + lx;
+    int y_index = groupId_x * TILE_DIM + ly;
+
+    __local uchar title[TILE_DIM * LDS_STEP];
+
+    if(x < src_cols && y < src_rows)
+    {
+        int index_src = mad24(y, src_step, x);
+
+        #pragma unroll 
+        for(int i = 0; i < TILE_DIM; i += BLOCK_ROWS)
+        {
+            if(y + i < src_rows)
+            {
+                title[(ly + i) * LDS_STEP + lx] =*(src + src_offset + index_src);
+                index_src = mad24(BLOCK_ROWS, src_step, index_src);
+            }
+        }
+     }
+
+     barrier(CLK_LOCAL_MEM_FENCE);
+
+    if(x_index < src_rows && y_index < src_cols)
+    {
+        int index_dst = mad24(y_index, dst_step, x_index);
+
+        #pragma unroll
+        for(int i = 0; i < TILE_DIM; i += BLOCK_ROWS)
+        {
+            if((y_index + i) < src_cols)
+            {
+                *(dst + dst_offset + index_dst ) = title[lx * LDS_STEP + ly + i];  
+                index_dst +=  dst_step * BLOCK_ROWS ;
+            }
+        }
+    }
+}
+
+__kernel void transpose_C1_D4(__global int* src, int src_step, int src_offset, 
+                              __global int* dst, int dst_step, int dst_offset,
+                              int src_rows, int src_cols)
+{
+
+    int gp_x = get_group_id(0),   gp_y = get_group_id(1);
+    int gs_x = get_num_groups(0), gs_y = get_num_groups(1);
+
+    int groupId_x, groupId_y;
+
+    if(src_rows == src_cols)
+    {
+        groupId_y = gp_x;  
+        groupId_x = (gp_x + gp_y) % gs_x;
+    }
+    else
+    {
+        int bid = gp_x + gs_x * gp_y; 
+        groupId_y =  bid % gs_y;  
+        groupId_x = ((bid / gs_y) + groupId_y) % gs_x;
+    }
+
+    int lx = get_local_id(0);
+    int ly = get_local_id(1);
+
+    int x = groupId_x * TILE_DIM + lx;
+    int y = groupId_y * TILE_DIM + ly;
+
+    int x_index = groupId_y * TILE_DIM + lx;
+    int y_index = groupId_x * TILE_DIM + ly;
+
+    __local int title[TILE_DIM * LDS_STEP];
+
+    if(x < src_cols && y < src_rows)
+    {
+        int index_src = mad24(y, src_step, (x << 2));
+
+        #pragma unroll 
+        for(int i = 0; i < TILE_DIM; i += BLOCK_ROWS)
+        {
+            if(y + i < src_rows)
+            {
+                title[(ly + i) * LDS_STEP + lx] = *((__global int *)((__global char*)src + src_offset + index_src));
+                index_src = mad24(BLOCK_ROWS, src_step, index_src);
+            }
+        }
+     }
+
+     barrier(CLK_LOCAL_MEM_FENCE);
+
+    if(x_index < src_rows && y_index < src_cols)
+    {
+        int index_dst = mad24(y_index, dst_step, (x_index << 2));
+
+        #pragma unroll
+        for(int i = 0; i < TILE_DIM; i += BLOCK_ROWS)
+        {
+            if((y_index + i) < src_cols)
+            {
+                *((__global int*)((__global char*)dst + dst_offset + index_dst )) = title[lx * LDS_STEP + ly + i];  
+                index_dst +=  dst_step * BLOCK_ROWS ;
+            }
+        }
+    }
+}
+__kernel void transpose_C1_D5(__global float* src, int src_step, int src_offset, 
+                              __global float* dst, int dst_step, int dst_offset,
+                              int src_rows, int src_cols)
+{
+
+    int gp_x = get_group_id(0),   gp_y = get_group_id(1);
+    int gs_x = get_num_groups(0), gs_y = get_num_groups(1);
+
+    int groupId_x, groupId_y;
+
+    if(src_rows == src_cols)
+    {
+        groupId_y = gp_x;  
+        groupId_x = (gp_x + gp_y) % gs_x;
+    }
+    else
+    {
+        int bid = gp_x + gs_x * gp_y; 
+        groupId_y =  bid % gs_y;  
+        groupId_x = ((bid / gs_y) + groupId_y) % gs_x;
+    }
+
+    int lx = get_local_id(0);
+    int ly = get_local_id(1);
+
+    int x = groupId_x * TILE_DIM + lx;
+    int y = groupId_y * TILE_DIM + ly;
+
+    int x_index = groupId_y * TILE_DIM + lx;
+    int y_index = groupId_x * TILE_DIM + ly;
+
+    __local float title[TILE_DIM * LDS_STEP];
+
+    if(x < src_cols && y < src_rows)
+    {
+        int index_src = mad24(y, src_step, (x << 2));
+
+        #pragma unroll 
+        for(int i = 0; i < TILE_DIM; i += BLOCK_ROWS)
+        {
+            if(y + i < src_rows)
+            {
+                title[(ly + i) * LDS_STEP + lx] = *((__global float *)((__global char*)src + src_offset + index_src));
+                index_src = mad24(BLOCK_ROWS, src_step, index_src);
+            }
+        }
+     }
+
+     barrier(CLK_LOCAL_MEM_FENCE);
+
+    if(x_index < src_rows && y_index < src_cols)
+    {
+        int index_dst = mad24(y_index, dst_step, (x_index << 2));
+
+        #pragma unroll
+        for(int i = 0; i < TILE_DIM; i += BLOCK_ROWS)
+        {
+            if((y_index + i) < src_cols)
+            {
+                *((__global float*)((__global char*)dst + dst_offset + index_dst )) = title[lx * LDS_STEP + ly + i];  
+                index_dst +=  dst_step * BLOCK_ROWS ;
+            }
+        }
+    }
+}
+
+__kernel void transpose_C2_D2(__global ushort* src, int src_step, int src_offset, 
+                              __global ushort* dst, int dst_step, int dst_offset,
+                              int src_rows, int src_cols)
+{
+
+    int gp_x = get_group_id(0),   gp_y = get_group_id(1);
+    int gs_x = get_num_groups(0), gs_y = get_num_groups(1);
+
+    int groupId_x, groupId_y;
+
+    if(src_rows == src_cols)
+    {
+        groupId_y = gp_x;  
+        groupId_x = (gp_x + gp_y) % gs_x;
+    }
+    else
+    {
+        int bid = gp_x + gs_x * gp_y; 
+        groupId_y =  bid % gs_y;  
+        groupId_x = ((bid / gs_y) + groupId_y) % gs_x;
+    }
+
+    int lx = get_local_id(0);
+    int ly = get_local_id(1);
+
+    int x = groupId_x * TILE_DIM + lx;
+    int y = groupId_y * TILE_DIM + ly;
+
+    int x_index = groupId_y * TILE_DIM + lx;
+    int y_index = groupId_x * TILE_DIM + ly;
+
+    __local ushort2 title[TILE_DIM * LDS_STEP];
+
+    if(x < src_cols && y < src_rows)
+    {
+        int index_src = mad24(y, src_step, (x << 2));
+
+        #pragma unroll 
+        for(int i = 0; i < TILE_DIM; i += BLOCK_ROWS)
+        {
+            if(y + i < src_rows)
+            {
+                title[(ly + i) * LDS_STEP + lx] = *((__global ushort2 *)((__global char*)src + src_offset + index_src));
+                index_src = mad24(BLOCK_ROWS, src_step, index_src);
+            }
+        }
+     }
+
+     barrier(CLK_LOCAL_MEM_FENCE);
+
+    if(x_index < src_rows && y_index < src_cols)
+    {
+        int index_dst = mad24(y_index, dst_step, (x_index << 2));
+
+        #pragma unroll
+        for(int i = 0; i < TILE_DIM; i += BLOCK_ROWS)
+        {
+            if((y_index + i) < src_cols)
+            {
+                *((__global ushort2*)((__global char*)dst + dst_offset + index_dst )) = title[lx * LDS_STEP + ly + i];  
+                index_dst +=  dst_step * BLOCK_ROWS ;
+            }
+        }
+    }
+}
+__kernel void transpose_C2_D3(__global short* src, int src_step, int src_offset, 
+                              __global short* dst, int dst_step, int dst_offset,
+                              int src_rows, int src_cols)
+{
+
+    int gp_x = get_group_id(0),   gp_y = get_group_id(1);
+    int gs_x = get_num_groups(0), gs_y = get_num_groups(1);
+
+    int groupId_x, groupId_y;
+
+    if(src_rows == src_cols)
+    {
+        groupId_y = gp_x;  
+        groupId_x = (gp_x + gp_y) % gs_x;
+    }
+    else
+    {
+        int bid = gp_x + gs_x * gp_y; 
+        groupId_y =  bid % gs_y;  
+        groupId_x = ((bid / gs_y) + groupId_y) % gs_x;
+    }
+
+    int lx = get_local_id(0);
+    int ly = get_local_id(1);
+
+    int x = groupId_x * TILE_DIM + lx;
+    int y = groupId_y * TILE_DIM + ly;
+
+    int x_index = groupId_y * TILE_DIM + lx;
+    int y_index = groupId_x * TILE_DIM + ly;
+
+    __local short2 title[TILE_DIM * LDS_STEP];
+
+    if(x < src_cols && y < src_rows)
+    {
+        int index_src = mad24(y, src_step, (x << 2));
+
+        #pragma unroll 
+        for(int i = 0; i < TILE_DIM; i += BLOCK_ROWS)
+        {
+            if(y + i < src_rows)
+            {
+                title[(ly + i) * LDS_STEP + lx] = *((__global short2 *)((__global char*)src + src_offset + index_src));
+                index_src = mad24(BLOCK_ROWS, src_step, index_src);
+            }
+        }
+     }
+
+     barrier(CLK_LOCAL_MEM_FENCE);
+
+    if(x_index < src_rows && y_index < src_cols)
+    {
+        int index_dst = mad24(y_index, dst_step, (x_index << 2));
+
+        #pragma unroll
+        for(int i = 0; i < TILE_DIM; i += BLOCK_ROWS)
+        {
+            if((y_index + i) < src_cols)
+            {
+                *((__global short2*)((__global char*)dst + dst_offset + index_dst )) = title[lx * LDS_STEP + ly + i];  
+                index_dst +=  dst_step * BLOCK_ROWS ;
+            }
+        }
+    }
+}
+__kernel void transpose_C4_D0(__global uchar* src, int src_step, int src_offset, 
+                              __global uchar* dst, int dst_step, int dst_offset,
+                              int src_rows, int src_cols)
+{
+
+    int gp_x = get_group_id(0),   gp_y = get_group_id(1);
+    int gs_x = get_num_groups(0), gs_y = get_num_groups(1);
+
+    int groupId_x, groupId_y;
+
+    if(src_rows == src_cols)
+    {
+        groupId_y = gp_x;  
+        groupId_x = (gp_x + gp_y) % gs_x;
+    }
+    else
+    {
+        int bid = gp_x + gs_x * gp_y; 
+        groupId_y =  bid % gs_y;  
+        groupId_x = ((bid / gs_y) + groupId_y) % gs_x;
+    }
+
+    int lx = get_local_id(0);
+    int ly = get_local_id(1);
+
+    int x = groupId_x * TILE_DIM + lx;
+    int y = groupId_y * TILE_DIM + ly;
+
+    int x_index = groupId_y * TILE_DIM + lx;
+    int y_index = groupId_x * TILE_DIM + ly;
+
+    __local uchar4 title[TILE_DIM * LDS_STEP];
+
+    if(x < src_cols && y < src_rows)
+    {
+        int index_src = mad24(y, src_step, (x << 2));
+
+        #pragma unroll 
+        for(int i = 0; i < TILE_DIM; i += BLOCK_ROWS)
+        {
+            if(y + i < src_rows)
+            {
+                title[(ly + i) * LDS_STEP + lx] = *((__global uchar4 *)(src + src_offset + index_src));
+                index_src = mad24(BLOCK_ROWS, src_step, index_src);
+            }
+        }
+     }
+
+     barrier(CLK_LOCAL_MEM_FENCE);
+
+    if(x_index < src_rows && y_index < src_cols)
+    {
+        int index_dst = mad24(y_index, dst_step, (x_index << 2));
+
+        #pragma unroll
+        for(int i = 0; i < TILE_DIM; i += BLOCK_ROWS)
+        {
+            if((y_index + i) < src_cols)
+            {
+                *((__global uchar4*)(dst + dst_offset + index_dst )) = title[lx * LDS_STEP + ly + i];  
+                index_dst +=  dst_step * BLOCK_ROWS ;
+            }
+        }
+    }
+}
+
+__kernel void transpose_C4_D1(__global char* src, int src_step, int src_offset, 
+                              __global char* dst, int dst_step, int dst_offset,
+                              int src_rows, int src_cols)
+{
+
+    int gp_x = get_group_id(0),   gp_y = get_group_id(1);
+    int gs_x = get_num_groups(0), gs_y = get_num_groups(1);
+
+    int groupId_x, groupId_y;
+
+    if(src_rows == src_cols)
+    {
+        groupId_y = gp_x;  
+        groupId_x = (gp_x + gp_y) % gs_x;
+    }
+    else
+    {
+        int bid = gp_x + gs_x * gp_y; 
+        groupId_y =  bid % gs_y;  
+        groupId_x = ((bid / gs_y) + groupId_y) % gs_x;
+    }
+
+    int lx = get_local_id(0);
+    int ly = get_local_id(1);
+
+    int x = groupId_x * TILE_DIM + lx;
+    int y = groupId_y * TILE_DIM + ly;
+
+    int x_index = groupId_y * TILE_DIM + lx;
+    int y_index = groupId_x * TILE_DIM + ly;
+
+    __local char4 title[TILE_DIM * LDS_STEP];
+
+    if(x < src_cols && y < src_rows)
+    {
+        int index_src = mad24(y, src_step, (x << 2));
+
+        #pragma unroll 
+        for(int i = 0; i < TILE_DIM; i += BLOCK_ROWS)
+        {
+            if(y + i < src_rows)
+            {
+                title[(ly + i) * LDS_STEP + lx] = *((__global char4 *)(src + src_offset + index_src));
+                index_src = mad24(BLOCK_ROWS, src_step, index_src);
+            }
+        }
+     }
+
+     barrier(CLK_LOCAL_MEM_FENCE);
+
+    if(x_index < src_rows && y_index < src_cols)
+    {
+        int index_dst = mad24(y_index, dst_step, (x_index << 2));
+
+        #pragma unroll
+        for(int i = 0; i < TILE_DIM; i += BLOCK_ROWS)
+        {
+            if((y_index + i) < src_cols)
+            {
+                *((__global char4*)(dst + dst_offset + index_dst )) = title[lx * LDS_STEP + ly + i];  
+                index_dst +=  dst_step * BLOCK_ROWS ;
+            }
+        }
+    }
+}
diff --git a/modules/ocl/src/kernels/convertC3C4.cl b/modules/ocl/src/kernels/convertC3C4.cl
new file mode 100644 (file)
index 0000000..54f0fd9
--- /dev/null
@@ -0,0 +1,137 @@
+//                           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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Zero Lin, zero.lin@amd.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.
+//
+//
+
+__kernel void convertC3C4_D0(__global const char4 * restrict src, __global char4 *dst, int cols, int rows, 
+                                       int srcStep, int dstStep)
+{
+       int id = get_global_id(0);
+       int y = id / cols;
+       int x = id % cols;
+
+       int d = y * srcStep + x * 3;
+       char8 data = (char8)(src[d>>2], src[(d>>2) + 1]);
+       char temp[8] = {data.s0, data.s1, data.s2, data.s3, data.s4, data.s5, data.s6, data.s7};
+       
+       int start = d & 3;
+       char4 ndata = (char4)(temp[start], temp[start + 1], temp[start + 2], 0);
+       if(y < rows)
+               dst[y * dstStep + x] = ndata;
+}
+
+__kernel void convertC3C4_D1(__global const short* restrict src, __global short4 *dst, int cols, int rows, 
+                                       int srcStep, int dstStep)
+{
+       int id = get_global_id(0);
+       int y = id / cols;
+       int x = id % cols;
+
+       int d = (y * srcStep + x * 6)>>1;
+       short4 data = *(__global short4 *)(src + ((d>>1)<<1));
+       short temp[4] = {data.s0, data.s1, data.s2, data.s3};
+       
+       int start = d & 1;
+       short4 ndata = (short4)(temp[start], temp[start + 1], temp[start + 2], 0);
+       if(y < rows)
+               dst[y * dstStep + x] = ndata;
+}
+
+__kernel void convertC3C4_D2(__global const int * restrict src, __global int4 *dst, int cols, int rows, 
+                                       int srcStep, int dstStep)
+{
+       int id = get_global_id(0);
+       int y = id / cols;
+       int x = id % cols;
+
+       int d = (y * srcStep + x * 12)>>2;
+       int4 data = *(__global int4 *)(src + d);
+       data.z = 0;
+       
+       if(y < rows)
+               dst[y * dstStep + x] = data;
+}
+
+__kernel void convertC4C3_D2(__global const int4 * restrict src, __global int *dst, int cols, int rows, 
+                                       int srcStep, int dstStep)
+{
+       int id = get_global_id(0);
+       int y = id / cols;
+       int x = id % cols;
+
+       int4 data = src[y * srcStep + x];
+       
+       if(y < rows)
+       {
+               int d = y * dstStep + x * 3;
+               dst[d] = data.x;
+               dst[d + 1] = data.y;
+               dst[d + 2] = data.z;
+       }
+}
+
+__kernel void convertC4C3_D1(__global const short4 * restrict src, __global short *dst, int cols, int rows, 
+                                       int srcStep, int dstStep)
+{
+       int id = get_global_id(0);
+       int y = id / cols;
+       int x = id % cols;
+
+       short4 data = src[y * srcStep + x];
+       
+       if(y < rows)
+       {
+               int d = y * dstStep + x * 3;
+               dst[d] = data.x;
+               dst[d + 1] = data.y;
+               dst[d + 2] = data.z;
+       }
+}
+
+__kernel void convertC4C3_D0(__global const char4 * restrict src, __global char *dst, int cols, int rows, 
+                                       int srcStep, int dstStep)
+{
+       int id = get_global_id(0);
+       int y = id / cols;
+       int x = id % cols;
+
+       char4 data = src[y * srcStep + x];
+       
+       if(y < rows)
+       {
+               int d = y * dstStep + x * 3;
+               dst[d] = data.x;
+               dst[d + 1] = data.y;
+               dst[d + 2] = data.z;
+       }
+}
diff --git a/modules/ocl/src/kernels/cvt_color.cl b/modules/ocl/src/kernels/cvt_color.cl
new file mode 100644 (file)
index 0000000..9b2cca5
--- /dev/null
@@ -0,0 +1,81 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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*/
+
+/**************************************PUBLICFUNC*************************************/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+#if defined (DEPTH_0)
+#define DATA_TYPE uchar
+#endif
+#if defined (DEPTH_2)
+#define DATA_TYPE ushort
+#endif
+
+#define CV_DESCALE(x,n) (((x) + (1 << ((n)-1))) >> (n))
+enum
+{
+    yuv_shift  = 14,
+    xyz_shift  = 12,
+    R2Y        = 4899,
+    G2Y        = 9617,
+    B2Y        = 1868,
+    BLOCK_SIZE = 256
+};
+
+__kernel void RGB2Gray(int cols,int rows,int src_step,int dst_step,int channels,
+                       int bidx, __global const DATA_TYPE* src, __global DATA_TYPE* dst)
+{
+    const int x = get_global_id(0);
+    const int y = get_global_id(1);
+
+    if (y < rows && x < cols)
+    {
+        int src_idx = y * src_step + x * channels * sizeof(DATA_TYPE);
+        int dst_idx = y * dst_step + x * sizeof(DATA_TYPE);
+        dst[dst_idx] = (DATA_TYPE)CV_DESCALE((src[src_idx + bidx] * B2Y + src[src_idx + 1] * G2Y + src[src_idx + (bidx^2)] * R2Y), yuv_shift);
+    }
+}   
diff --git a/modules/ocl/src/kernels/filter_sep_col.cl b/modules/ocl/src/kernels/filter_sep_col.cl
new file mode 100644 (file)
index 0000000..f85906a
--- /dev/null
@@ -0,0 +1,310 @@
+//                           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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Niko Li, newlife20080214@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 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
+// 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.
+//
+//
+
+#define READ_TIMES_COL ((2*(RADIUSY+LSIZE1)-1)/LSIZE1)
+#define RADIUS 1
+#if CN ==1
+#define ALIGN (((RADIUS)+3)>>2<<2)
+#elif CN==2
+#define ALIGN (((RADIUS)+1)>>1<<1)
+#elif CN==3
+#define ALIGN (((RADIUS)+3)>>2<<2)
+#elif CN==4
+#define ALIGN (RADIUS)
+#define READ_TIMES_ROW ((2*(RADIUS+LSIZE0)-1)/LSIZE0)
+#endif
+
+#ifdef BORDER_CONSTANT
+//BORDER_CONSTANT:      iiiiii|abcdefgh|iiiiiii
+#define ELEM(i,l_edge,r_edge,elem1,elem2) (i)<(l_edge) | (i) >= (r_edge) ? (elem1) : (elem2)
+#endif
+
+#ifdef BORDER_REPLICATE
+//BORDER_REPLICATE:     aaaaaa|abcdefgh|hhhhhhh
+#define ADDR_L(i,l_edge,r_edge)  (i) < (l_edge) ? (l_edge) : (i)
+#define ADDR_R(i,r_edge,addr)   (i) >= (r_edge) ? (r_edge)-1 : (addr)
+#endif
+
+#ifdef BORDER_REFLECT
+//BORDER_REFLECT:       fedcba|abcdefgh|hgfedcb
+#define ADDR_L(i,l_edge,r_edge)  (i) < (l_edge) ? -(i)-1 : (i)
+#define ADDR_R(i,r_edge,addr) (i) >= (r_edge) ? -(i)-1+((r_edge)<<1) : (addr)
+#endif
+
+#ifdef BORDER_REFLECT_101
+//BORDER_REFLECT_101:   gfedcb|abcdefgh|gfedcba
+#define ADDR_L(i,l_edge,r_edge)  (i) < (l_edge) ? -(i) : (i)
+#define ADDR_R(i,r_edge,addr) (i) >= (r_edge) ? -(i)-2+((r_edge)<<1) : (addr)
+#endif
+
+#ifdef BORDER_WRAP
+//BORDER_WRAP:          cdefgh|abcdefgh|abcdefg
+#define ADDR_L(i,l_edge,r_edge)  (i) < (l_edge) ? (i)+(r_edge) : (i)
+#define ADDR_R(i,r_edge,addr)   (i) >= (r_edge) ?   (i)-(r_edge) : (addr)
+#endif
+
+
+/**********************************************************************************
+These kernels are written for separable filters such as Sobel, Scharr, GaussianBlur.
+Now(6/29/2011) the kernels only support 8U data type and the anchor of the convovle
+kernel must be in the center. ROI is not supported either.
+Each kernels read 4 elements(not 4 pixels), save them to LDS and read the data needed
+from LDS to calculate the result.
+The length of the convovle kernel supported is only related to the MAX size of LDS, 
+which is HW related.
+Niko
+6/29/2011
+***********************************************************************************/
+
+
+__kernel __attribute__((reqd_work_group_size(LSIZE0,LSIZE1,1))) void col_filter_C1_D0
+                                               (__global const float * restrict src, 
+                                                __global uchar * dst,
+                         const int dst_cols,
+                         const int dst_rows, 
+                                                const int src_whole_cols,
+                                                const int src_whole_rows,
+                         const int src_step_in_pixel, 
+                         //const int src_offset_x, 
+                         //const int src_offset_y, 
+                         const int dst_step_in_pixel,
+                         const int dst_offset_in_pixel,
+                         __constant float * mat_kernel __attribute__((max_constant_size(4*(2*RADIUSY+1)))))
+{
+       int x = get_global_id(0);
+       int y = get_global_id(1);
+       int l_x = get_local_id(0);
+       int l_y = get_local_id(1);
+       int start_addr = mad24(y,src_step_in_pixel,x);
+       int end_addr = mad24(src_whole_rows - 1,src_step_in_pixel,src_whole_cols);
+       int i;
+       float sum;
+       float temp[READ_TIMES_COL];
+
+       __local float LDS_DAT[LSIZE1*READ_TIMES_COL][LSIZE0+1];
+
+       //read pixels from src
+       for(i = 0;i<READ_TIMES_COL;i++)
+       {
+               int current_addr = start_addr+i*LSIZE1*src_step_in_pixel;
+               current_addr = current_addr < end_addr ? current_addr : 0;
+               temp[i] = src[current_addr];
+       }
+       //save pixels to lds
+       for(i = 0;i<READ_TIMES_COL;i++)
+       {
+               LDS_DAT[l_y+i*LSIZE1][l_x] = temp[i];
+       }
+       barrier(CLK_LOCAL_MEM_FENCE);
+       //read pixels from lds and calculate the result
+       sum = LDS_DAT[l_y+RADIUSY][l_x]*mat_kernel[RADIUSY];
+       for(i=1;i<=RADIUSY;i++)
+       {
+               temp[0]=LDS_DAT[l_y+RADIUSY-i][l_x];
+               temp[1]=LDS_DAT[l_y+RADIUSY+i][l_x];
+               sum += temp[0] * mat_kernel[RADIUSY-i]+temp[1] * mat_kernel[RADIUSY+i];
+       }
+       //write the result to dst
+       if((x<dst_cols) & (y<dst_rows))
+       {
+               start_addr = mad24(y,dst_step_in_pixel,x+dst_offset_in_pixel);
+               dst[start_addr] = convert_uchar_sat(sum);
+       }
+}
+
+__kernel __attribute__((reqd_work_group_size(LSIZE0,LSIZE1,1))) void col_filter_C4_D0
+                                               (__global const float4 * restrict src, 
+                                                __global uchar4 * dst,
+                         const int dst_cols,
+                         const int dst_rows, 
+                                                const int src_whole_cols,
+                                                const int src_whole_rows,
+                         const int src_step_in_pixel, 
+                         //const int src_offset_x, 
+                         //const int src_offset_y, 
+                         const int dst_step_in_pixel,
+                         const int dst_offset_in_pixel,
+                         __constant float * mat_kernel __attribute__((max_constant_size(4*(2*RADIUSY+1)))))
+{
+       int x = get_global_id(0);
+       int y = get_global_id(1);
+       int l_x = get_local_id(0);
+       int l_y = get_local_id(1);
+       int start_addr = mad24(y,src_step_in_pixel,x);
+       int end_addr = mad24(src_whole_rows - 1,src_step_in_pixel,src_whole_cols);
+       int i;
+       float4 sum;
+       float4 temp[READ_TIMES_COL];
+
+       __local float4 LDS_DAT[LSIZE1*READ_TIMES_COL][LSIZE0+1];
+
+       //read pixels from src
+       for(i = 0;i<READ_TIMES_COL;i++)
+       {
+               int current_addr = start_addr+i*LSIZE1*src_step_in_pixel;
+               current_addr = current_addr < end_addr ? current_addr : 0;
+               temp[i] = src[current_addr];
+       }
+       //save pixels to lds
+       for(i = 0;i<READ_TIMES_COL;i++)
+       {
+               LDS_DAT[l_y+i*LSIZE1][l_x] = temp[i];
+       }
+       barrier(CLK_LOCAL_MEM_FENCE);
+       //read pixels from lds and calculate the result
+       sum = LDS_DAT[l_y+RADIUSY][l_x]*mat_kernel[RADIUSY];
+       for(i=1;i<=RADIUSY;i++)
+       {
+               temp[0]=LDS_DAT[l_y+RADIUSY-i][l_x];
+               temp[1]=LDS_DAT[l_y+RADIUSY+i][l_x];
+               sum += temp[0] * mat_kernel[RADIUSY-i]+temp[1] * mat_kernel[RADIUSY+i];
+       }
+       //write the result to dst
+       if((x<dst_cols) & (y<dst_rows))
+       {
+               start_addr = mad24(y,dst_step_in_pixel,x+dst_offset_in_pixel);
+               dst[start_addr] = convert_uchar4_sat(sum);
+       }
+}
+
+__kernel __attribute__((reqd_work_group_size(LSIZE0,LSIZE1,1))) void col_filter_C1_D5
+                                               (__global const float * restrict src, 
+                                                __global float * dst,
+                         const int dst_cols,
+                         const int dst_rows, 
+                                                const int src_whole_cols,
+                                                const int src_whole_rows,
+                         const int src_step_in_pixel, 
+                         //const int src_offset_x, 
+                         //const int src_offset_y, 
+                         const int dst_step_in_pixel,
+                         const int dst_offset_in_pixel,
+                         __constant float * mat_kernel __attribute__((max_constant_size(4*(2*RADIUSY+1)))))
+{
+       int x = get_global_id(0);
+       int y = get_global_id(1);
+       int l_x = get_local_id(0);
+       int l_y = get_local_id(1);
+       int start_addr = mad24(y,src_step_in_pixel,x);
+       int end_addr = mad24(src_whole_rows - 1,src_step_in_pixel,src_whole_cols);
+       int i;
+       float sum;
+       float temp[READ_TIMES_COL];
+
+       __local float LDS_DAT[LSIZE1*READ_TIMES_COL][LSIZE0+1];
+
+       //read pixels from src
+       for(i = 0;i<READ_TIMES_COL;i++)
+       {
+               int current_addr = start_addr+i*LSIZE1*src_step_in_pixel;
+               current_addr = current_addr < end_addr ? current_addr : 0;
+               temp[i] = src[current_addr];
+       }
+       //save pixels to lds
+       for(i = 0;i<READ_TIMES_COL;i++)
+       {
+               LDS_DAT[l_y+i*LSIZE1][l_x] = temp[i];
+       }
+       barrier(CLK_LOCAL_MEM_FENCE);
+       //read pixels from lds and calculate the result
+       sum = LDS_DAT[l_y+RADIUSY][l_x]*mat_kernel[RADIUSY];
+       for(i=1;i<=RADIUSY;i++)
+       {
+               temp[0]=LDS_DAT[l_y+RADIUSY-i][l_x];
+               temp[1]=LDS_DAT[l_y+RADIUSY+i][l_x];
+               sum += temp[0] * mat_kernel[RADIUSY-i]+temp[1] * mat_kernel[RADIUSY+i];
+       }
+       //write the result to dst
+       if((x<dst_cols) & (y<dst_rows))
+       {
+               start_addr = mad24(y,dst_step_in_pixel,x+dst_offset_in_pixel);
+               dst[start_addr] = sum;
+       }
+}
+__kernel __attribute__((reqd_work_group_size(LSIZE0,LSIZE1,1))) void col_filter_C4_D5
+                                               (__global const float4 * restrict src, 
+                                                __global float4 * dst,
+                         const int dst_cols,
+                         const int dst_rows, 
+                                                const int src_whole_cols,
+                                                const int src_whole_rows,
+                         const int src_step_in_pixel, 
+                         //const int src_offset_x, 
+                         //const int src_offset_y, 
+                         const int dst_step_in_pixel,
+                         const int dst_offset_in_pixel,
+                         __constant float * mat_kernel __attribute__((max_constant_size(4*(2*RADIUSY+1)))))
+{
+       int x = get_global_id(0);
+       int y = get_global_id(1);
+       int l_x = get_local_id(0);
+       int l_y = get_local_id(1);
+       int start_addr = mad24(y,src_step_in_pixel,x);
+       int end_addr = mad24(src_whole_rows - 1,src_step_in_pixel,src_whole_cols);
+       int i;
+       float4 sum;
+       float4 temp[READ_TIMES_COL];
+
+       __local float4 LDS_DAT[LSIZE1*READ_TIMES_COL][LSIZE0+1];
+
+       //read pixels from src
+       for(i = 0;i<READ_TIMES_COL;i++)
+       {
+               int current_addr = start_addr+i*LSIZE1*src_step_in_pixel;
+               current_addr = current_addr < end_addr ? current_addr : 0;
+               temp[i] = src[current_addr];
+       }
+       //save pixels to lds
+       for(i = 0;i<READ_TIMES_COL;i++)
+       {
+               LDS_DAT[l_y+i*LSIZE1][l_x] = temp[i];
+       }
+       barrier(CLK_LOCAL_MEM_FENCE);
+       //read pixels from lds and calculate the result
+       sum = LDS_DAT[l_y+RADIUSY][l_x]*mat_kernel[RADIUSY];
+       for(i=1;i<=RADIUSY;i++)
+       {
+               temp[0]=LDS_DAT[l_y+RADIUSY-i][l_x];
+               temp[1]=LDS_DAT[l_y+RADIUSY+i][l_x];
+               sum += temp[0] * mat_kernel[RADIUSY-i]+temp[1] * mat_kernel[RADIUSY+i];
+       }
+       //write the result to dst
+       if((x<dst_cols) & (y<dst_rows))
+       {
+               start_addr = mad24(y,dst_step_in_pixel,x+dst_offset_in_pixel);
+               dst[start_addr] = sum;
+       }
+}
diff --git a/modules/ocl/src/kernels/filter_sep_row.cl b/modules/ocl/src/kernels/filter_sep_row.cl
new file mode 100644 (file)
index 0000000..348ac5c
--- /dev/null
@@ -0,0 +1,469 @@
+//                           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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Niko Li, newlife20080214@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 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.
+//
+//
+
+#define READ_TIMES_ROW ((2*(RADIUSX+LSIZE0)-1)/LSIZE0) //for c4 only
+#define READ_TIMES_COL ((2*(RADIUSY+LSIZE1)-1)/LSIZE1)
+//#pragma OPENCL EXTENSION cl_amd_printf : enable
+#define RADIUS 1
+#if CN ==1
+#define ALIGN (((RADIUS)+3)>>2<<2)
+#elif CN==2
+#define ALIGN (((RADIUS)+1)>>1<<1)
+#elif CN==3
+#define ALIGN (((RADIUS)+3)>>2<<2)
+#elif CN==4
+#define ALIGN (RADIUS)
+#endif
+
+
+#ifdef BORDER_CONSTANT
+//BORDER_CONSTANT:      iiiiii|abcdefgh|iiiiiii
+#define ELEM(i,l_edge,r_edge,elem1,elem2) (i)<(l_edge) | (i) >= (r_edge) ? (elem1) : (elem2)
+#endif
+
+#ifdef BORDER_REPLICATE
+//BORDER_REPLICATE:     aaaaaa|abcdefgh|hhhhhhh
+#define ADDR_L(i,l_edge,r_edge,addr)  (i) < (l_edge) ? (l_edge) : (addr)
+#define ADDR_R(i,r_edge,addr)   (i) >= (r_edge) ? (r_edge)-1 : (addr)
+#endif
+
+#ifdef BORDER_REFLECT
+//BORDER_REFLECT:       fedcba|abcdefgh|hgfedcb
+#define ADDR_L(i,l_edge,r_edge,addr)  (i) < (l_edge) ? -(i)-1 : (addr)
+#define ADDR_R(i,r_edge,addr) (i) >= (r_edge) ? -(i)-1+((r_edge)<<1) : (addr)
+#endif
+
+#ifdef BORDER_REFLECT_101
+//BORDER_REFLECT_101:   gfedcb|abcdefgh|gfedcba
+#define ADDR_L(i,l_edge,r_edge,addr)  (i) < (l_edge) ? -(i) : (addr)
+#define ADDR_R(i,r_edge,addr) (i) >= (r_edge) ? -(i)-2+((r_edge)<<1) : (addr)
+#endif
+
+#ifdef BORDER_WRAP
+//BORDER_WRAP:          cdefgh|abcdefgh|abcdefg
+#define ADDR_L(i,l_edge,r_edge,addr)  (i) < (l_edge) ? (i)+(r_edge) : (addr)
+#define ADDR_R(i,r_edge,addr)   (i) >= (r_edge) ?   (i)-(r_edge) : (addr)
+#endif
+
+/**********************************************************************************
+These kernels are written for separable filters such as Sobel, Scharr, GaussianBlur.
+Now(6/29/2011) the kernels only support 8U data type and the anchor of the convovle
+kernel must be in the center. ROI is not supported either.
+For channels =1,2,4, each kernels read 4 elements(not 4 pixels), and for channels =3,
+the kernel read 4 pixels, save them to LDS and read the data needed from LDS to 
+calculate the result.
+The length of the convovle kernel supported is related to the LSIZE0 and the MAX size
+of LDS, which is HW related.
+For channels = 1,3 the RADIUS is no more than LSIZE0*2
+For channels = 2, the RADIUS is no more than LSIZE0
+For channels = 4, arbitary RADIUS is supported unless the LDS is not enough
+Niko
+6/29/2011
+***********************************************************************************/
+
+__kernel __attribute__((reqd_work_group_size(LSIZE0,LSIZE1,1))) void row_filter_C1_D0
+                                               (__global const uchar * restrict src, 
+                                                __global float * dst,
+                         const int dst_cols,
+                         const int dst_rows, 
+                                                const int src_whole_cols,
+                                                const int src_whole_rows,
+                         const int src_step_in_pixel, 
+                         const int src_offset_x, 
+                         const int src_offset_y, 
+                         const int dst_step_in_pixel,
+                         const int radiusy,
+                         __constant float * mat_kernel __attribute__((max_constant_size(4*(2*RADIUSX+1)))))
+{
+       int x = get_global_id(0)<<2;
+       int y = get_global_id(1);
+       int l_x = get_local_id(0);
+       int l_y = get_local_id(1);
+       int start_x = x+src_offset_x-RADIUSX & 0xfffffffc;
+       int offset = src_offset_x-RADIUSX & 3;
+       int start_y = y+src_offset_y-radiusy;
+       int start_addr = mad24(start_y,src_step_in_pixel,start_x);
+       int i;
+       float4 sum;
+       uchar4 temp[READ_TIMES_ROW];
+
+       __local uchar4 LDS_DAT[LSIZE1][READ_TIMES_ROW*LSIZE0+1];
+       #ifdef BORDER_CONSTANT
+       int end_addr = mad24(src_whole_rows - 1,src_step_in_pixel,src_whole_cols);
+       //read pixels from src
+       for(i = 0;i<READ_TIMES_ROW;i++)
+       {
+               int current_addr = start_addr+i*LSIZE0*4;
+               current_addr = ((current_addr < end_addr) && (current_addr > 0)) ? current_addr : 0;
+               temp[i] = *(__global uchar4*)&src[current_addr];
+       }
+       //judge if read out of boundary
+       for(i = 0;i<READ_TIMES_ROW;i++)
+       {
+               temp[i].x= ELEM(start_x+i*LSIZE0*4,0,src_whole_cols,0,temp[i].x);
+               temp[i].y= ELEM(start_x+i*LSIZE0*4+1,0,src_whole_cols,0,temp[i].y);
+               temp[i].z= ELEM(start_x+i*LSIZE0*4+2,0,src_whole_cols,0,temp[i].z);
+               temp[i].w= ELEM(start_x+i*LSIZE0*4+3,0,src_whole_cols,0,temp[i].w);
+               temp[i]= ELEM(start_y,0,src_whole_rows,(uchar4)0,temp[i]);
+       }
+       #else
+       int not_all_in_range = (start_x<0) | (start_x + READ_TIMES_ROW*LSIZE0*4+4>src_whole_cols)| (start_y<0) | (start_y >= src_whole_rows);
+       int4 index[READ_TIMES_ROW];
+       int4 addr;
+       int s_y;
+       if(not_all_in_range)
+       {
+               //judge if read out of boundary
+               for(i = 0;i<READ_TIMES_ROW;i++)
+               {
+                       index[i].x= ADDR_L(start_x+i*LSIZE0*4,0,src_whole_cols,start_x+i*LSIZE0*4);
+                       index[i].x= ADDR_R(start_x+i*LSIZE0*4,src_whole_cols,index[i].x);
+                       index[i].y= ADDR_L(start_x+i*LSIZE0*4+1,0,src_whole_cols,start_x+i*LSIZE0*4+1);
+                       index[i].y= ADDR_R(start_x+i*LSIZE0*4+1,src_whole_cols,index[i].y);
+                       index[i].z= ADDR_L(start_x+i*LSIZE0*4+2,0,src_whole_cols,start_x+i*LSIZE0*4+2);
+                       index[i].z= ADDR_R(start_x+i*LSIZE0*4+2,src_whole_cols,index[i].z);
+                       index[i].w= ADDR_L(start_x+i*LSIZE0*4+3,0,src_whole_cols,start_x+i*LSIZE0*4+3);
+                       index[i].w= ADDR_R(start_x+i*LSIZE0*4+3,src_whole_cols,index[i].w);
+               }
+               s_y= ADDR_L(start_y,0,src_whole_rows,start_y);
+               s_y= ADDR_R(start_y,src_whole_rows,s_y);
+               //read pixels from src
+               for(i = 0;i<READ_TIMES_ROW;i++)
+               {
+                       addr = mad24((int4)s_y,(int4)src_step_in_pixel,index[i]);
+                       temp[i].x = src[addr.x];
+                       temp[i].y = src[addr.y];
+                       temp[i].z = src[addr.z];
+                       temp[i].w = src[addr.w];
+               }
+       }
+       else
+       {
+               //read pixels from src
+               for(i = 0;i<READ_TIMES_ROW;i++)
+               {
+                       temp[i] = *(__global uchar4*)&src[start_addr+i*LSIZE0*4];
+               }       
+       }       
+       #endif
+
+       //save pixels to lds
+       for(i = 0;i<READ_TIMES_ROW;i++)
+       {
+               LDS_DAT[l_y][l_x+i*LSIZE0]=temp[i];
+       }
+       barrier(CLK_LOCAL_MEM_FENCE);
+
+       //read pixels from lds and calculate the result
+       sum =convert_float4(vload4(0,(__local uchar*)&LDS_DAT[l_y][l_x]+RADIUSX+offset))*mat_kernel[RADIUSX];
+       for(i=1;i<=RADIUSX;i++)
+       {
+               temp[0]=vload4(0,(__local uchar*)&LDS_DAT[l_y][l_x]+RADIUSX+offset-i);
+               temp[1]=vload4(0,(__local uchar*)&LDS_DAT[l_y][l_x]+RADIUSX+offset+i);
+               sum += convert_float4(temp[0])*mat_kernel[RADIUSX-i]+convert_float4(temp[1])*mat_kernel[RADIUSX+i];
+       }
+       start_addr = mad24(y,dst_step_in_pixel,x);
+       //write the result to dst
+       if((x+3<dst_cols) & (y<dst_rows))
+       {
+               *(__global float4*)&dst[start_addr] = sum;
+       }
+       else if((x+2<dst_cols) & (y<dst_rows))
+       {
+               dst[start_addr] = sum.x;
+               dst[start_addr+1] = sum.y;
+               dst[start_addr+2] = sum.z;
+       }
+       else if((x+1<dst_cols) & (y<dst_rows))
+       {
+               dst[start_addr] = sum.x;
+               dst[start_addr+1] = sum.y;
+       }
+       else if((x<dst_cols) & (y<dst_rows))
+       {
+               dst[start_addr] = sum.x;
+       }
+}
+__kernel __attribute__((reqd_work_group_size(LSIZE0,LSIZE1,1))) void row_filter_C4_D0
+                                               (__global const uchar4 * restrict src, 
+                                                __global float4 * dst,
+                         const int dst_cols,
+                         const int dst_rows, 
+                                                const int src_whole_cols,
+                                                const int src_whole_rows,
+                         const int src_step_in_pixel, 
+                         const int src_offset_x, 
+                         const int src_offset_y, 
+                         const int dst_step_in_pixel,
+                         const int radiusy,
+                         __constant float * mat_kernel __attribute__((max_constant_size(4*(2*RADIUSX+1)))))
+{
+       int x = get_global_id(0);
+       int y = get_global_id(1);
+       int l_x = get_local_id(0);
+       int l_y = get_local_id(1);
+       int start_x = x+src_offset_x-RADIUSX;
+       int start_y = y+src_offset_y-radiusy;
+       int start_addr = mad24(start_y,src_step_in_pixel,start_x);
+       int i;
+       float4 sum;
+       uchar4 temp[READ_TIMES_ROW];
+
+       __local uchar4 LDS_DAT[LSIZE1][READ_TIMES_ROW*LSIZE0+1];
+       #ifdef BORDER_CONSTANT
+       int end_addr = mad24(src_whole_rows - 1,src_step_in_pixel,src_whole_cols);
+       //read pixels from src
+       for(i = 0;i<READ_TIMES_ROW;i++)
+       {
+               int current_addr = start_addr+i*LSIZE0;
+               current_addr = ((current_addr < end_addr) && (current_addr > 0)) ? current_addr : 0;
+               temp[i] = src[current_addr];
+       }
+       //judge if read out of boundary
+       for(i = 0;i<READ_TIMES_ROW;i++)
+       {
+               temp[i]= ELEM(start_x+i*LSIZE0,0,src_whole_cols,(uchar4)0,temp[i]);
+               temp[i]= ELEM(start_y,0,src_whole_rows,(uchar4)0,temp[i]);
+       }
+       #else
+       int index[READ_TIMES_ROW];
+       int s_x,s_y;
+       //judge if read out of boundary
+       for(i = 0;i<READ_TIMES_ROW;i++)
+       {
+               s_x= ADDR_L(start_x+i*LSIZE0,0,src_whole_cols,start_x+i*LSIZE0);
+               s_x= ADDR_R(start_x+i*LSIZE0,src_whole_cols,s_x);
+               s_y= ADDR_L(start_y,0,src_whole_rows,start_y);
+               s_y= ADDR_R(start_y,src_whole_rows,s_y);
+               index[i]=mad24(s_y,src_step_in_pixel,s_x);
+       }
+       //read pixels from src
+       for(i = 0;i<READ_TIMES_ROW;i++)
+       {
+               temp[i] = src[index[i]];
+       }       
+       #endif
+
+       //save pixels to lds
+       for(i = 0;i<READ_TIMES_ROW;i++)
+       {
+               LDS_DAT[l_y][l_x+i*LSIZE0]=temp[i];
+       }
+       barrier(CLK_LOCAL_MEM_FENCE);
+
+       //read pixels from lds and calculate the result
+       sum =convert_float4(LDS_DAT[l_y][l_x+RADIUSX])*mat_kernel[RADIUSX];
+       for(i=1;i<=RADIUSX;i++)
+       {
+               temp[0]=LDS_DAT[l_y][l_x+RADIUSX-i];
+               temp[1]=LDS_DAT[l_y][l_x+RADIUSX+i];
+               sum += convert_float4(temp[0])*mat_kernel[RADIUSX-i]+convert_float4(temp[1])*mat_kernel[RADIUSX+i];
+       }
+       //write the result to dst
+       if((x<dst_cols) & (y<dst_rows))
+       {
+               start_addr = mad24(y,dst_step_in_pixel,x);
+               dst[start_addr] = sum;
+       }
+}
+
+__kernel __attribute__((reqd_work_group_size(LSIZE0,LSIZE1,1))) void row_filter_C1_D5
+                                               (__global const float * restrict src, 
+                                                __global float * dst,
+                         const int dst_cols,
+                         const int dst_rows, 
+                                                const int src_whole_cols,
+                                                const int src_whole_rows,
+                         const int src_step_in_pixel, 
+                         const int src_offset_x, 
+                         const int src_offset_y, 
+                         const int dst_step_in_pixel,
+                         const int radiusy,
+                         __constant float * mat_kernel __attribute__((max_constant_size(4*(2*RADIUSX+1)))))
+{
+       int x = get_global_id(0);
+       int y = get_global_id(1);
+       int l_x = get_local_id(0);
+       int l_y = get_local_id(1);
+       int start_x = x+src_offset_x-RADIUSX;
+       int start_y = y+src_offset_y-radiusy;
+       int start_addr = mad24(start_y,src_step_in_pixel,start_x);
+       int i;
+       float sum;
+       float temp[READ_TIMES_ROW];
+
+       __local float LDS_DAT[LSIZE1][READ_TIMES_ROW*LSIZE0+1];
+       #ifdef BORDER_CONSTANT
+       int end_addr = mad24(src_whole_rows - 1,src_step_in_pixel,src_whole_cols);
+       //read pixels from src
+       for(i = 0;i<READ_TIMES_ROW;i++)
+       {
+               int current_addr = start_addr+i*LSIZE0;
+               current_addr = ((current_addr < end_addr) && (current_addr > 0)) ? current_addr : 0;
+               temp[i] = src[current_addr];
+       }
+       //judge if read out of boundary
+       for(i = 0;i<READ_TIMES_ROW;i++)
+       {
+               temp[i]= ELEM(start_x+i*LSIZE0,0,src_whole_cols,0,temp[i]);
+               temp[i]= ELEM(start_y,0,src_whole_rows,0,temp[i]);
+       }
+       #else
+       int index[READ_TIMES_ROW];
+       int s_x,s_y;
+       //judge if read out of boundary
+       for(i = 0;i<READ_TIMES_ROW;i++)
+       {
+               s_x= ADDR_L(start_x+i*LSIZE0,0,src_whole_cols,start_x+i*LSIZE0);
+               s_x= ADDR_R(start_x+i*LSIZE0,src_whole_cols,s_x);
+               s_y= ADDR_L(start_y,0,src_whole_rows,start_y);
+               s_y= ADDR_R(start_y,src_whole_rows,s_y);
+               index[i]=mad24(s_y,src_step_in_pixel,s_x);
+       }
+       //read pixels from src
+       for(i = 0;i<READ_TIMES_ROW;i++)
+       {
+               temp[i] = src[index[i]];
+       }       
+       #endif
+
+       //save pixels to lds
+       for(i = 0;i<READ_TIMES_ROW;i++)
+       {
+               LDS_DAT[l_y][l_x+i*LSIZE0]=temp[i];
+       }
+       barrier(CLK_LOCAL_MEM_FENCE);
+
+       //read pixels from lds and calculate the result
+       sum =LDS_DAT[l_y][l_x+RADIUSX]*mat_kernel[RADIUSX];
+       for(i=1;i<=RADIUSX;i++)
+       {
+               temp[0]=LDS_DAT[l_y][l_x+RADIUSX-i];
+               temp[1]=LDS_DAT[l_y][l_x+RADIUSX+i];
+               sum += temp[0]*mat_kernel[RADIUSX-i]+temp[1]*mat_kernel[RADIUSX+i];
+       }
+       //write the result to dst
+       if((x<dst_cols) & (y<dst_rows))
+       {
+               start_addr = mad24(y,dst_step_in_pixel,x);
+               dst[start_addr] = sum;
+       }
+}
+
+__kernel __attribute__((reqd_work_group_size(LSIZE0,LSIZE1,1))) void row_filter_C4_D5
+                                               (__global const float4 * restrict src, 
+                                                __global float4 * dst,
+                         const int dst_cols,
+                         const int dst_rows, 
+                                                const int src_whole_cols,
+                                                const int src_whole_rows,
+                         const int src_step_in_pixel, 
+                         const int src_offset_x, 
+                         const int src_offset_y, 
+                         const int dst_step_in_pixel,
+                         const int radiusy,
+                         __constant float * mat_kernel __attribute__((max_constant_size(4*(2*RADIUSX+1)))))
+{
+       int x = get_global_id(0);
+       int y = get_global_id(1);
+       int l_x = get_local_id(0);
+       int l_y = get_local_id(1);
+       int start_x = x+src_offset_x-RADIUSX;
+       int start_y = y+src_offset_y-radiusy;
+       int start_addr = mad24(start_y,src_step_in_pixel,start_x);
+       int i;
+       float4 sum;
+       float4 temp[READ_TIMES_ROW];
+
+       __local float4 LDS_DAT[LSIZE1][READ_TIMES_ROW*LSIZE0+1];
+       #ifdef BORDER_CONSTANT
+       int end_addr = mad24(src_whole_rows - 1,src_step_in_pixel,src_whole_cols);
+       //read pixels from src
+       for(i = 0;i<READ_TIMES_ROW;i++)
+       {
+               int current_addr = start_addr+i*LSIZE0;
+               current_addr = ((current_addr < end_addr) && (current_addr > 0)) ? current_addr : 0;
+               temp[i] = src[current_addr];
+       }
+       //judge if read out of boundary
+       for(i = 0;i<READ_TIMES_ROW;i++)
+       {
+               temp[i]= ELEM(start_x+i*LSIZE0,0,src_whole_cols,0,temp[i]);
+               temp[i]= ELEM(start_y,0,src_whole_rows,0,temp[i]);
+       }
+       #else
+       int index[READ_TIMES_ROW];
+       int s_x,s_y;
+       //judge if read out of boundary
+       for(i = 0;i<READ_TIMES_ROW;i++)
+       {
+               s_x= ADDR_L(start_x+i*LSIZE0,0,src_whole_cols,start_x+i*LSIZE0);
+               s_x= ADDR_R(start_x+i*LSIZE0,src_whole_cols,s_x);
+               s_y= ADDR_L(start_y,0,src_whole_rows,start_y);
+               s_y= ADDR_R(start_y,src_whole_rows,s_y);
+               index[i]=mad24(s_y,src_step_in_pixel,s_x);
+       }
+       //read pixels from src
+       for(i = 0;i<READ_TIMES_ROW;i++)
+       {
+               temp[i] = src[index[i]];
+       }       
+       #endif
+
+       //save pixels to lds
+       for(i = 0;i<READ_TIMES_ROW;i++)
+       {
+               LDS_DAT[l_y][l_x+i*LSIZE0]=temp[i];
+       }
+       barrier(CLK_LOCAL_MEM_FENCE);
+
+       //read pixels from lds and calculate the result
+       sum =LDS_DAT[l_y][l_x+RADIUSX]*mat_kernel[RADIUSX];
+       for(i=1;i<=RADIUSX;i++)
+       {
+               temp[0]=LDS_DAT[l_y][l_x+RADIUSX-i];
+               temp[1]=LDS_DAT[l_y][l_x+RADIUSX+i];
+               sum += temp[0]*mat_kernel[RADIUSX-i]+temp[1]*mat_kernel[RADIUSX+i];
+       }
+       //write the result to dst
+       if((x<dst_cols) & (y<dst_rows))
+       {
+               start_addr = mad24(y,dst_step_in_pixel,x);
+               dst[start_addr] = sum;
+       }
+}
+
+
diff --git a/modules/ocl/src/kernels/filtering_boxFilter.cl b/modules/ocl/src/kernels/filtering_boxFilter.cl
new file mode 100644 (file)
index 0000000..d523dda
--- /dev/null
@@ -0,0 +1,458 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Zhang Ying, zhangying913@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 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*/
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////Macro for border type////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////
+#ifdef BORDER_REPLICATE
+//BORDER_REPLICATE:     aaaaaa|abcdefgh|hhhhhhh
+#define ADDR_L(i, l_edge, r_edge)  ((i) <  (l_edge) ? (l_edge)   : (i))
+#define ADDR_R(i, r_edge, addr)    ((i) >= (r_edge) ? (r_edge)-1 : (addr))
+#define ADDR_H(i, t_edge, b_edge)  ((i) <  (t_edge) ? (t_edge)   :(i)) 
+#define ADDR_B(i, b_edge, addr)    ((i) >= (b_edge) ? (b_edge)-1 :(addr)) 
+#endif
+
+#ifdef BORDER_REFLECT
+//BORDER_REFLECT:       fedcba|abcdefgh|hgfedcb
+#define ADDR_L(i, l_edge, r_edge)  ((i) <  (l_edge) ? -(i)-1               : (i))
+#define ADDR_R(i, r_edge, addr)    ((i) >= (r_edge) ? -(i)-1+((r_edge)<<1) : (addr))
+#define ADDR_H(i, t_edge, b_edge)  ((i) <  (t_edge) ? -(i)-1 : (i))
+#define ADDR_B(i, b_edge, addr)    ((i) >= (b_edge) ? -(i)-1+((b_edge)<<1) : (addr))
+#endif
+
+#ifdef BORDER_REFLECT_101
+//BORDER_REFLECT_101:   gfedcb|abcdefgh|gfedcba
+#define ADDR_L(i, l_edge, r_edge)  ((i) <  (l_edge) ? -(i)                 : (i))
+#define ADDR_R(i, r_edge, addr)    ((i) >= (r_edge) ? -(i)-2+((r_edge)<<1) : (addr))
+#define ADDR_H(i, t_edge, b_edge)  ((i) <  (t_edge) ? -(i)                 : (i))
+#define ADDR_B(i, b_edge, addr)    ((i) >= (b_edge) ? -(i)-2+((b_edge)<<1) : (addr))
+#endif
+
+//blur function does not support BORDER_WRAP
+#ifdef BORDER_WRAP
+//BORDER_WRAP:          cdefgh|abcdefgh|abcdefg
+#define ADDR_L(i, l_edge, r_edge)  ((i) <  (l_edge) ? (i)+(r_edge) : (i))
+#define ADDR_R(i, r_edge, addr)    ((i) >= (r_edge) ? (i)-(r_edge) : (addr))
+#define ADDR_H(i, t_edge, b_edge)  ((i) <  (t_edge) ? (i)+(b_edge) : (i))
+#define ADDR_B(i, b_edge, addr)    ((i) >= (b_edge) ? (i)-(b_edge) : (addr))
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////8uC1////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+#define THREADS 256
+#define ELEM(i, l_edge, r_edge, elem1, elem2) (i) >= (l_edge) && (i) < (r_edge) ? (elem1) : (elem2)
+__kernel void boxFilter_C1_D0(__global const uchar * restrict src, __global uchar *dst, float alpha,
+                                     int src_offset, int src_whole_rows, int src_whole_cols, int src_step,
+                                     int dst_offset, int dst_rows, int dst_cols, int dst_step
+                                     )
+{
+
+    int col = get_local_id(0);
+    const int gX = get_group_id(0);
+    const int gY = get_group_id(1);
+    int src_x_off = src_offset % src_step;
+    int src_y_off = src_offset / src_step;
+    int dst_x_off = dst_offset % dst_step;
+    int dst_y_off = dst_offset / dst_step;
+
+    int head_off = dst_x_off%4;
+    int startX = ((gX * (THREADS-ksX+1)-anX) * 4) - head_off + src_x_off;
+    int startY = (gY << 1) - anY + src_y_off;
+    int dst_startX = (gX * (THREADS-ksX+1) * 4) - head_off + dst_x_off;
+    int dst_startY = (gY << 1) + dst_y_off;
+    
+    uint4 data[ksY+1];
+    __local uint4 temp[(THREADS<<1)];   
+        
+#ifdef BORDER_CONSTANT
+    
+        for(int i=0; i < ksY+1; i++)
+        {
+            if(startY+i >=0 && startY+i < src_whole_rows && startX+col*4 >=0 && startX+col*4+3<src_whole_cols)
+                data[i] = convert_uint4(vload4(col,(__global uchar*)(src+(startY+i)*src_step + startX)));
+            else
+            {
+                data[i]=0;
+                int con = startY+i >=0 && startY+i < src_whole_rows && startX+col*4 >=0 && startX+col*4<src_whole_cols;
+                if(con)data[i].s0 = *(src+(startY+i)*src_step + startX + col*4);
+                con = startY+i >=0 && startY+i < src_whole_rows && startX+col*4+1 >=0 && startX+col*4+1<src_whole_cols;
+                if(con)data[i].s1 = *(src+(startY+i)*src_step + startX + col*4+1) ;
+                con = startY+i >=0 && startY+i < src_whole_rows && startX+col*4+2 >=0 && startX+col*4+2<src_whole_cols;
+                if(con)data[i].s2 = *(src+(startY+i)*src_step + startX + col*4+2);
+                con = startY+i >=0 && startY+i < src_whole_rows && startX+col*4+3 >=0 && startX+col*4+3<src_whole_cols;
+                if(con)data[i].s3 = *(src+(startY+i)*src_step + startX + col*4+3);
+            }
+        }
+        
+#else
+   int not_all_in_range;
+   for(int i=0; i < ksY+1; i++)
+   {
+      not_all_in_range = (startX+col*4<0) | (startX+col*4+3>src_whole_cols-1) 
+                        | (startY+i<0) | (startY+i>src_whole_rows-1);
+      if(not_all_in_range)
+      {   
+          int selected_row;
+          int4 selected_col;
+          selected_row = ADDR_H(startY+i, 0, src_whole_rows);
+          selected_row = ADDR_B(startY+i, src_whole_rows, selected_row);
+
+          selected_col.x = ADDR_L(startX+col*4, 0, src_whole_cols);
+          selected_col.x = ADDR_R(startX+col*4, src_whole_cols, selected_col.x);
+          
+          selected_col.y = ADDR_L(startX+col*4+1, 0, src_whole_cols);
+          selected_col.y = ADDR_R(startX+col*4+1, src_whole_cols, selected_col.y);
+          
+          selected_col.z = ADDR_L(startX+col*4+2, 0, src_whole_cols);
+          selected_col.z = ADDR_R(startX+col*4+2, src_whole_cols, selected_col.z);
+          
+          selected_col.w = ADDR_L(startX+col*4+3, 0, src_whole_cols);
+          selected_col.w = ADDR_R(startX+col*4+3, src_whole_cols, selected_col.w);
+
+          data[i].x = *(src + selected_row * src_step + selected_col.x);
+          data[i].y = *(src + selected_row * src_step + selected_col.y);
+          data[i].z = *(src + selected_row * src_step + selected_col.z);
+          data[i].w = *(src + selected_row * src_step + selected_col.w);
+      }
+      else
+      {
+          data[i] =  convert_uint4(vload4(col,(__global uchar*)(src+(startY+i)*src_step + startX)));
+      }
+   }
+#endif
+    uint4 sum0 = 0, sum1 = 0, sum2 = 0;
+    for(int i=1; i < ksY; i++)
+    {
+        sum0 += (data[i]);
+    }
+    sum1 = sum0 + (data[0]);
+    sum2 = sum0 + (data[ksY]);
+
+    temp[col] = sum1;
+    temp[col+THREADS] = sum2;
+    barrier(CLK_LOCAL_MEM_FENCE);
+    
+    if(col >= anX && col < (THREADS-ksX+anX+1))
+    {
+        int posX = dst_startX - dst_x_off + (col-anX)*4;
+        int posY = (gY << 1);
+        uint4 tmp_sum1=0, tmp_sum2=0;
+        for(int i=-anX; i<=anX; i++)
+        {
+           tmp_sum1 += vload4(col, (__local uint*)temp+i);
+        }
+
+        for(int i=-anX; i<=anX; i++)
+        {
+           tmp_sum2 += vload4(col, (__local uint*)(temp+THREADS)+i);
+        }
+       
+        if(posY < dst_rows && posX < dst_cols)
+        {
+           if(posX >= 0 && posX < dst_cols)
+               *(dst+dst_startY * dst_step + dst_startX + (col-anX)*4) = tmp_sum1.x/alpha;
+           if(posX+1 >= 0 && posX+1 < dst_cols)
+               *(dst+dst_startY * dst_step + dst_startX+1 + (col-anX)*4) = tmp_sum1.y/alpha;
+           if(posX+2 >= 0 && posX+2 < dst_cols)
+               *(dst+dst_startY * dst_step + dst_startX+2 + (col-anX)*4) = tmp_sum1.z/alpha;
+           if(posX+3 >= 0 && posX+3 < dst_cols)
+               *(dst+dst_startY * dst_step + dst_startX+3 + (col-anX)*4) = tmp_sum1.w/alpha;
+        }   
+        if(posY+1 < dst_rows && posX < dst_cols)
+        {
+           dst_startY+=1;
+           if(posX >= 0 && posX < dst_cols)
+               *(dst+dst_startY * dst_step + dst_startX + (col-anX)*4) = tmp_sum2.x/alpha;
+           if(posX+1 >= 0 && posX+1 < dst_cols)
+               *(dst+dst_startY * dst_step + dst_startX+1 + (col-anX)*4) = tmp_sum2.y/alpha;
+           if(posX+2 >= 0 && posX+2 < dst_cols)
+               *(dst+dst_startY * dst_step + dst_startX+2 + (col-anX)*4) = tmp_sum2.z/alpha;
+           if(posX+3 >= 0 && posX+3 < dst_cols)
+               *(dst+dst_startY * dst_step + dst_startX+3 + (col-anX)*4) = tmp_sum2.w/alpha;
+        }   
+    }
+        
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////8uC4////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void boxFilter_C4_D0(__global const uchar4 * restrict src, __global uchar4 *dst, float alpha,
+                                     int src_offset, int src_whole_rows, int src_whole_cols, int src_step,
+                                     int dst_offset, int dst_rows, int dst_cols, int dst_step
+                                     )
+{
+    int col = get_local_id(0);
+    const int gX = get_group_id(0);
+    const int gY = get_group_id(1);
+
+    int src_x_off = (src_offset % src_step) >> 2;
+    int src_y_off = src_offset / src_step;
+    int dst_x_off = (dst_offset % dst_step) >> 2;
+    int dst_y_off = dst_offset / dst_step;
+
+    int startX = gX * (THREADS-ksX+1) - anX + src_x_off;
+    int startY = (gY << 1) - anY + src_y_off;
+    int dst_startX = gX * (THREADS-ksX+1) + dst_x_off;
+    int dst_startY = (gY << 1) + dst_y_off;  
+       int end_addr = (src_whole_rows-1)*(src_step>>2) + src_whole_cols-4;
+    uint4 data[ksY+1];
+    __local uint4 temp[2][THREADS];   
+#ifdef BORDER_CONSTANT
+    bool con;
+    uint4 ss;
+    for(int i=0; i < ksY+1; i++)
+    {
+        con = startX+col >= 0 && startX+col < src_whole_cols && startY+i >= 0 && startY+i < src_whole_rows;
+               int cur_addr = clamp((startY+i)*(src_step>>2)+(startX+col),0,end_addr);
+        ss = convert_uint4(src[cur_addr]); 
+        data[i] = con ? ss : 0;
+    }
+#else
+   for(int i=0; i < ksY+1; i++)
+   {
+          int selected_row;
+          int selected_col;
+          selected_row = ADDR_H(startY+i, 0, src_whole_rows);
+          selected_row = ADDR_B(startY+i, src_whole_rows, selected_row);
+
+          selected_col = ADDR_L(startX+col, 0, src_whole_cols);
+          selected_col = ADDR_R(startX+col, src_whole_cols, selected_col);
+          
+          data[i] = convert_uint4(src[selected_row * (src_step>>2) + selected_col]);
+   }
+    
+#endif
+    uint4 sum0 = 0, sum1 = 0, sum2 = 0;
+    for(int i=1; i < ksY; i++)
+    {
+        sum0 += (data[i]);
+    }
+    sum1 = sum0 + (data[0]);
+    sum2 = sum0 + (data[ksY]);
+    temp[0][col] = sum1;
+    temp[1][col] = sum2;
+    barrier(CLK_LOCAL_MEM_FENCE);
+    if(col < (THREADS-(ksX-1)))
+    {
+        col += anX;
+        int posX = dst_startX - dst_x_off + col - anX;
+        int posY = (gY << 1);
+       
+        uint4 tmp_sum[2]={(uint4)(0,0,0,0),(uint4)(0,0,0,0)};
+        for(int k=0; k<2; k++)
+            for(int i=-anX; i<=anX; i++)
+            {
+                tmp_sum[k] += temp[k][col+i];
+            }
+        for(int i=0; i<2; i++)
+        {    
+            if(posX >= 0 && posX < dst_cols && (posY+i) >= 0 && (posY+i) < dst_rows)
+                dst[(dst_startY+i) * (dst_step>>2)+ dst_startX + col - anX] = convert_uchar4(convert_float4(tmp_sum[i])/alpha);
+        }
+        
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////32fC1////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void boxFilter_C1_D5(__global const float *restrict src, __global float *dst, float alpha,
+                                     int src_offset, int src_whole_rows, int src_whole_cols, int src_step,
+                                     int dst_offset, int dst_rows, int dst_cols, int dst_step
+                                     )
+{
+    int col = get_local_id(0);
+    const int gX = get_group_id(0);
+    const int gY = get_group_id(1);
+
+    int src_x_off = (src_offset % src_step) >> 2;
+    int src_y_off = src_offset / src_step;
+    int dst_x_off = (dst_offset % dst_step) >> 2;
+    int dst_y_off = dst_offset / dst_step;
+
+    int startX = gX * (THREADS-ksX+1) - anX + src_x_off;
+    int startY = (gY << 1) - anY + src_y_off;
+    int dst_startX = gX * (THREADS-ksX+1) + dst_x_off;
+    int dst_startY = (gY << 1) + dst_y_off;  
+       int end_addr = (src_whole_rows-1)*(src_step>>2) + src_whole_cols-4;
+    float data[ksY+1];
+    __local float temp[2][THREADS];   
+#ifdef BORDER_CONSTANT
+    bool con;
+    float ss;
+    for(int i=0; i < ksY+1; i++)
+    {
+        con = startX+col >= 0 && startX+col < src_whole_cols && startY+i >= 0 && startY+i < src_whole_rows;
+               int cur_addr = clamp((startY+i)*(src_step>>2)+(startX+col),0,end_addr);         
+        ss = src[cur_addr]; 
+        data[i] = con ? ss : 0.f;
+    }
+#else
+   for(int i=0; i < ksY+1; i++)
+   {
+          int selected_row;
+          int selected_col;
+          selected_row = ADDR_H(startY+i, 0, src_whole_rows);
+          selected_row = ADDR_B(startY+i, src_whole_rows, selected_row);
+
+          selected_col = ADDR_L(startX+col, 0, src_whole_cols);
+          selected_col = ADDR_R(startX+col, src_whole_cols, selected_col);
+          
+          data[i] = src[selected_row * (src_step>>2) + selected_col];
+   }
+    
+#endif
+    float sum0 = 0.0, sum1 = 0.0, sum2 = 0.0;
+    for(int i=1; i < ksY; i++)
+    {
+        sum0 += (data[i]);
+    }
+    sum1 = sum0 + (data[0]);
+    sum2 = sum0 + (data[ksY]);
+    temp[0][col] = sum1;
+    temp[1][col] = sum2;
+    barrier(CLK_LOCAL_MEM_FENCE);
+    if(col < (THREADS-(ksX-1)))
+    {
+        col += anX;
+        int posX = dst_startX - dst_x_off + col - anX;
+        int posY = (gY << 1);
+       
+        float tmp_sum[2]={0.0, 0.0};
+        for(int k=0; k<2; k++)
+            for(int i=-anX; i<=anX; i++)
+            {
+                tmp_sum[k] += temp[k][col+i];
+            }
+        for(int i=0; i<2; i++)
+        {    
+            if(posX >= 0 && posX < dst_cols && (posY+i) >= 0 && (posY+i) < dst_rows)
+                dst[(dst_startY+i) * (dst_step>>2)+ dst_startX + col - anX] = tmp_sum[i]/alpha;
+        }
+        
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////32fC4////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void boxFilter_C4_D5(__global const float4 *restrict src, __global float4 *dst, float alpha,
+                                     int src_offset, int src_whole_rows, int src_whole_cols, int src_step,
+                                     int dst_offset, int dst_rows, int dst_cols, int dst_step
+                                     )
+{
+    int col = get_local_id(0);
+    const int gX = get_group_id(0);
+    const int gY = get_group_id(1);
+
+    int src_x_off = (src_offset % src_step) >> 4;
+    int src_y_off = src_offset / src_step;
+    int dst_x_off = (dst_offset % dst_step) >> 4;
+    int dst_y_off = dst_offset / dst_step;
+
+    int startX = gX * (THREADS-ksX+1) - anX + src_x_off;
+    int startY = (gY << 1) - anY + src_y_off;
+    int dst_startX = gX * (THREADS-ksX+1) + dst_x_off;
+    int dst_startY = (gY << 1) + dst_y_off;  
+       int end_addr = (src_whole_rows-1)*(src_step>>4) + src_whole_cols-16;
+    float4 data[ksY+1];
+    __local float4 temp[2][THREADS];   
+#ifdef BORDER_CONSTANT
+    bool con;
+    float4 ss;
+    for(int i=0; i < ksY+1; i++)
+    {
+        con = startX+col >= 0 && startX+col < src_whole_cols && startY+i >= 0 && startY+i < src_whole_rows;
+               int cur_addr = clamp((startY+i)*(src_step>>4)+(startX+col),0,end_addr);         
+        ss = src[cur_addr]; 
+        data[i] = con ? ss : (float4)(0.0,0.0,0.0,0.0);
+    }
+#else
+   for(int i=0; i < ksY+1; i++)
+   {
+          int selected_row;
+          int selected_col;
+          selected_row = ADDR_H(startY+i, 0, src_whole_rows);
+          selected_row = ADDR_B(startY+i, src_whole_rows, selected_row);
+
+          selected_col = ADDR_L(startX+col, 0, src_whole_cols);
+          selected_col = ADDR_R(startX+col, src_whole_cols, selected_col);
+          
+          data[i] = src[selected_row * (src_step>>4) + selected_col];
+   }
+    
+#endif
+    float4 sum0 = 0.0, sum1 = 0.0, sum2 = 0.0;
+    for(int i=1; i < ksY; i++)
+    {
+        sum0 += (data[i]);
+    }
+    sum1 = sum0 + (data[0]);
+    sum2 = sum0 + (data[ksY]);
+    temp[0][col] = sum1;
+    temp[1][col] = sum2;
+    barrier(CLK_LOCAL_MEM_FENCE);
+    if(col < (THREADS-(ksX-1)))
+    {
+        col += anX;
+        int posX = dst_startX - dst_x_off + col - anX;
+        int posY = (gY << 1);
+       
+        float4 tmp_sum[2]={(float4)(0.0,0.0,0.0,0.0), (float4)(0.0,0.0,0.0,0.0)};
+        for(int k=0; k<2; k++)
+            for(int i=-anX; i<=anX; i++)
+            {
+                tmp_sum[k] += temp[k][col+i];
+            }
+        for(int i=0; i<2; i++)
+        {    
+            if(posX >= 0 && posX < dst_cols && (posY+i) >= 0 && (posY+i) < dst_rows)
+                dst[(dst_startY+i) * (dst_step>>4)+ dst_startX + col - anX] = tmp_sum[i]/alpha;
+        }
+        
+    }
+}
diff --git a/modules/ocl/src/kernels/filtering_dilateFilter.cl b/modules/ocl/src/kernels/filtering_dilateFilter.cl
new file mode 100644 (file)
index 0000000..72e6fa8
--- /dev/null
@@ -0,0 +1,192 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Zhang Ying, zhangying913@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 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
+// 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 FP_CONTRACT ON
+#define UCHAR_MIN 0
+__kernel void dilate_C4_D5(__global const float4 * restrict src, __global float4 *dst, int srcOffset, int dstOffset, 
+                                       int mincols, int maxcols, int minrows, int maxrows, int cols, int rows, 
+                                       int srcStep, int dstStep, __constant uchar * mat_kernel, int src_whole_cols, int src_whole_rows)
+{
+    int mX = get_global_id(0);
+    int mY = get_global_id(1);
+    int kX = mX - anX, kY = mY - anY;
+       int end_addr = mad24(src_whole_rows-1,srcStep,src_whole_cols);
+    float4 maxVal = (float4)(-FLT_MAX);
+         int k=0;
+         for(int i=0;i<ksY;i++, kY++ , kX = mX - anX)
+    {
+        for(int j=0;j<ksX; j++, kX++)
+        {
+                       int current_addr = mad24(kY,srcStep,kX) + srcOffset;
+                       current_addr = ((current_addr < end_addr) && (current_addr > 0)) ? current_addr : 0;
+                       float4 v = src[current_addr];           
+                       uchar now = mat_kernel[k++];
+                   float4 flag = (kX >= mincols & kX <= maxcols & kY >= minrows & kY <= maxrows & now != 0) ? v : (float4)(-FLT_MAX);
+            maxVal = max(maxVal , flag);
+        }
+    }
+
+         if(mX < cols && mY < rows)
+        dst[mY * dstStep + mX + dstOffset] = (maxVal);            
+}
+
+__kernel void dilate_C1_D5(__global float4 * src, __global float *dst, int srcOffset, int dstOffset, 
+                                       int mincols, int maxcols, int minrows, int maxrows, int cols, int rows, 
+                                       int srcStep, int dstStep, __constant uchar * mat_kernel, int src_whole_cols, int src_whole_rows)
+{
+    int mX = (get_global_id(0)<<2) - (dstOffset&3);
+    int mY = get_global_id(1);
+    int kX = mX - anX, kY = mY - anY;
+       int end_addr = mad24(src_whole_rows-1,srcStep,src_whole_cols);
+    float4 maxVal = (float4)(-FLT_MAX);
+         int k=0;
+         for(int i=0;i<ksY;i++, kY++ , kX = mX - anX)
+    {
+        for(int j=0;j<ksX;j++, kX++)
+        {
+                       int start = mad24(kY,srcStep,kX) + srcOffset;
+                       start = ((start < end_addr) && (start > 0)) ? start : 0;
+                       int start2 = ((start + 4 < end_addr) && (start > 0)) ? start + 4 : 0;
+                           float8 sVal = (float8)(src[start>>2], src[start2>>2]);
+                       
+                       float sAry[8]= {sVal.s0, sVal.s1, sVal.s2, sVal.s3, sVal.s4, sVal.s5, sVal.s6, sVal.s7};
+                       int det = start & 3;
+                       float4 v=(float4)(sAry[det], sAry[det+1], sAry[det+2], sAry[det+3]);            
+                           uchar now = mat_kernel[k++];
+                           float4 flag = (kY >= minrows & kY <= maxrows & now != 0) ? v : maxVal;
+                           flag.x = (kX >= mincols & kX <= maxcols) ? flag.x : -FLT_MAX;
+                           flag.y = (kX+1 >= mincols & kX+1 <= maxcols) ? flag.y : -FLT_MAX;
+                           flag.z = (kX+2 >= mincols & kX+2 <= maxcols) ? flag.z : -FLT_MAX;
+                           flag.w = (kX+3 >= mincols & kX+3 <= maxcols) ? flag.w : -FLT_MAX;
+                       
+          maxVal = max(maxVal , flag);
+        }
+    }
+    if(mY < rows && mX < cols)
+         {
+                   __global float4* d = (__global float4*)(dst + mY * dstStep + mX + dstOffset);
+                   float4 dVal = *d;
+               maxVal.x = (mX >=0 & mX < cols) ? maxVal.x : dVal.x;
+               maxVal.y = (mX+1 >=0 & mX+1 < cols) ? maxVal.y : dVal.y;
+               maxVal.z = (mX+2 >=0 & mX+2 < cols) ? maxVal.z : dVal.z;
+               maxVal.w = (mX+3 >=0 & mX+3 < cols) ? maxVal.w : dVal.w;
+               
+        *d = (maxVal); 
+         }
+}
+
+__kernel void dilate_C1_D0(__global const uchar4 * restrict src, __global uchar *dst, int srcOffset, int dstOffset, 
+                                       int mincols, int maxcols, int minrows, int maxrows, int cols, int rows, 
+                                       int srcStep, int dstStep, __constant uchar * mat_kernel, int src_whole_cols, int src_whole_rows)
+{
+    int mX = (get_global_id(0)<<2) - (dstOffset&3);;
+    int mY = get_global_id(1);
+    int kX = mX - anX, kY = mY - anY;
+       int end_addr = mad24(src_whole_rows-1,srcStep,src_whole_cols);
+    uchar4 maxVal = (uchar4)(UCHAR_MIN);
+         int k=0;
+         for(int i=0;i<ksY;i++, kY++ , kX = mX - anX)
+    {
+        for(int j=0;j<ksX;j++, kX++)
+        {
+                           int start = mad24(kY,srcStep,kX) + srcOffset;
+                               start = ((start < end_addr) && (start > 0)) ? start : 0;
+                               int start2 = ((start + 4 < end_addr) && (start > 0)) ? start + 4 : 0;
+                           uchar8 sVal = (uchar8)(src[start>>2], src[start2>>2]);
+                       
+                           uchar sAry[8]= {sVal.s0, sVal.s1, sVal.s2, sVal.s3, sVal.s4, sVal.s5, sVal.s6, sVal.s7};
+                           int det = start & 3;
+                           uchar4 v=(uchar4)(sAry[det], sAry[det+1], sAry[det+2], sAry[det+3]);
+
+                           uchar4 flag = (kY >= minrows & kY <= maxrows & mat_kernel[k++] != 0) ? v : maxVal;
+                           flag.x = (kX >= mincols & kX <= maxcols) ? flag.x : UCHAR_MIN;
+                           flag.y = (kX+1 >= mincols & kX+1 <= maxcols) ? flag.y : UCHAR_MIN;
+                           flag.z = (kX+2 >= mincols & kX+2 <= maxcols) ? flag.z : UCHAR_MIN;
+                           flag.w = (kX+3 >= mincols & kX+3 <= maxcols) ? flag.w : UCHAR_MIN;                  
+
+          maxVal = max(maxVal , flag);
+        }
+    }
+         if(mY < rows)
+         {
+                   __global uchar4* d = (__global uchar4*)(dst + mY * dstStep + mX + dstOffset);
+                   uchar4 dVal = *d;
+               
+               maxVal.x = (mX >=0 & mX < cols) ? maxVal.x : dVal.x;
+               maxVal.y = (mX+1 >=0 & mX+1 < cols) ? maxVal.y : dVal.y;
+               maxVal.z = (mX+2 >=0 & mX+2 < cols) ? maxVal.z : dVal.z;
+               maxVal.w = (mX+3 >=0 & mX+3 < cols) ? maxVal.w : dVal.w;
+               
+        *d = (maxVal); 
+         }
+}
+
+__kernel void dilate_C4_D0(__global const uchar4 * restrict src, __global uchar4 *dst, int srcOffset, int dstOffset, 
+                                       int mincols, int maxcols, int minrows, int maxrows, int cols, int rows, 
+                                       int srcStep, int dstStep, __constant uchar * mat_kernel, int src_whole_cols, int src_whole_rows)
+{
+    int mX = get_global_id(0);
+    int mY = get_global_id(1);
+    int kX = mX - anX, kY = mY - anY;
+       int end_addr = mad24(src_whole_rows-1,srcStep,src_whole_cols);
+    uchar4 maxVal = (uchar4)(UCHAR_MIN);
+         int k=0;
+         for(int i=0;i<ksY;i++, kY++ , kX = mX - anX)
+    {
+        for(int j=0;j<ksX;j++, kX++)
+        {
+                       int current_addr = mad24(kY,srcStep,kX) + srcOffset;
+                       current_addr = ((current_addr < end_addr) && (current_addr > 0)) ? current_addr : 0;            
+                       uchar4 v = src[current_addr];
+                           uchar now = mat_kernel[k++];
+                           uchar4 flag = (kX >= mincols & kX <= maxcols & kY >= minrows & kY <= maxrows & now != 0) ? v : maxVal;
+          maxVal = max(maxVal , flag);
+        }
+    }
+
+         if(mX < cols && mY < rows)
+        dst[mY * dstStep + mX + dstOffset] = (maxVal);            
+}
+
diff --git a/modules/ocl/src/kernels/filtering_erodeFilter.cl b/modules/ocl/src/kernels/filtering_erodeFilter.cl
new file mode 100644 (file)
index 0000000..1714fb0
--- /dev/null
@@ -0,0 +1,183 @@
+//                           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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Niko Li, newlife20080214@gmail.com
+//    Zero Lin, zero.lin@amd.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.
+//
+//
+
+__kernel void erode_C4_D5(__global const float4 * restrict src, __global float4 *dst, int srcOffset, int dstOffset, 
+                                       int mincols, int maxcols, int minrows, int maxrows, int cols, int rows, 
+                                       int srcStep, int dstStep, __constant uchar * mat_kernel, int src_whole_cols, int src_whole_rows)
+{
+    int mX = get_global_id(0);
+    int mY = get_global_id(1);
+    int kX = mX - anX, kY = mY - anY;
+       int end_addr = mad24(src_whole_rows-1,srcStep,src_whole_cols);
+    float4 minVal = (float4)(3.4e+38);
+       int k=0;
+       for(int i=0;i<ksY;i++, kY++ , kX = mX - anX)
+    {
+        for(int j=0;j<ksX; j++, kX++)
+        {
+                       int current_addr = mad24(kY,srcStep,kX) + srcOffset;
+                       current_addr = ((current_addr < end_addr) && (current_addr > 0)) ? current_addr : 0;
+                       float4 v = src[current_addr];
+                       uchar now = mat_kernel[k++];
+                       float4 flag = (kX >= mincols & kX <= maxcols & kY >= minrows & kY <= maxrows & now != 0) ? v : (float4)(3.4e+38);
+            minVal = min(minVal , flag);
+        }
+    }
+
+       if(mX < cols && mY < rows)
+        dst[mY * dstStep + mX + dstOffset] = (minVal);            
+}
+
+__kernel void erode_C1_D5(__global float4 * src, __global float *dst, int srcOffset, int dstOffset, 
+                                       int mincols, int maxcols, int minrows, int maxrows, int cols, int rows, 
+                                       int srcStep, int dstStep, __constant uchar * mat_kernel, int src_whole_cols, int src_whole_rows)
+{
+    int mX = (get_global_id(0)<<2) - (dstOffset&3);
+    int mY = get_global_id(1);
+    int kX = mX - anX, kY = mY - anY;
+       int end_addr = mad24(src_whole_rows-1,srcStep,src_whole_cols);
+    float4 minVal = (float4)(3.4e+38);
+       int k=0;
+       for(int i=0;i<ksY;i++, kY++ , kX = mX - anX)
+    {
+        for(int j=0;j<ksX;j++, kX++)
+        {
+                       int start = mad24(kY,srcStep,kX) + srcOffset;
+                       start = ((start < end_addr) && (start > 0)) ? start : 0;
+                       int start2 = ((start + 4 < end_addr) && (start > 0)) ? start + 4 : 0;
+                       float8 sVal = (float8)(src[start>>2], src[start2>>2]);
+                       
+                       float sAry[8]= {sVal.s0, sVal.s1, sVal.s2, sVal.s3, sVal.s4, sVal.s5, sVal.s6, sVal.s7};
+                       int det = start & 3;
+                       float4 v=(float4)(sAry[det], sAry[det+1], sAry[det+2], sAry[det+3]);            
+                       uchar now = mat_kernel[k++];
+                       float4 flag = (kY >= minrows & kY <= maxrows & now != 0) ? v : (float4)(3.4e+38);
+                       flag.x = (kX >= mincols & kX <= maxcols) ? flag.x : 3.4e+38;
+                       flag.y = (kX+1 >= mincols & kX+1 <= maxcols) ? flag.y : 3.4e+38;
+                       flag.z = (kX+2 >= mincols & kX+2 <= maxcols) ? flag.z : 3.4e+38;
+                       flag.w = (kX+3 >= mincols & kX+3 <= maxcols) ? flag.w : 3.4e+38;
+                       
+            minVal = min(minVal , flag);
+        }
+    }
+
+       if(mY < rows && mX < cols)
+       {
+               __global float4* d = (__global float4*)(dst + mY * dstStep + mX + dstOffset);
+               float4 dVal = *d;
+               minVal.x = (mX >=0 & mX < cols) ? minVal.x : dVal.x;
+               minVal.y = (mX+1 >=0 & mX+1 < cols) ? minVal.y : dVal.y;
+               minVal.z = (mX+2 >=0 & mX+2 < cols) ? minVal.z : dVal.z;
+               minVal.w = (mX+3 >=0 & mX+3 < cols) ? minVal.w : dVal.w;
+               
+        *d = (minVal); 
+       }
+}
+
+__kernel void erode_C1_D0(__global const uchar4 * restrict src, __global uchar *dst, int srcOffset, int dstOffset, 
+                                       int mincols, int maxcols, int minrows, int maxrows, int cols, int rows, 
+                                       int srcStep, int dstStep, __constant uchar * mat_kernel, int src_whole_cols, int src_whole_rows)
+{
+    int mX = (get_global_id(0)<<2) - (dstOffset&3);
+    int mY = get_global_id(1);
+    int kX = mX - anX, kY = mY - anY;
+       int end_addr = mad24(src_whole_rows-1,srcStep,src_whole_cols);
+    uchar4 minVal = (uchar4)(0xff);
+       int k=0;
+       for(int i=0;i<ksY;i++, kY++ , kX = mX - anX)
+    {
+        for(int j=0;j<ksX;j++, kX++)
+        {
+                       int start = mad24(kY,srcStep,kX) + srcOffset;
+                       start = ((start < end_addr) && (start > 0)) ? start : 0;
+                       int start2 = ((start + 4 < end_addr) && (start > 0)) ? start + 4 : 0;
+                       uchar8 sVal = (uchar8)(src[start>>2], src[start2>>2]);
+                       
+                       uchar sAry[8]= {sVal.s0, sVal.s1, sVal.s2, sVal.s3, sVal.s4, sVal.s5, sVal.s6, sVal.s7};
+                       int det = start & 3;
+                       uchar4 v=(uchar4)(sAry[det], sAry[det+1], sAry[det+2], sAry[det+3]);
+
+                       uchar4 flag = (kY >= minrows & kY <= maxrows & mat_kernel[k++] != 0) ? v : (uchar4)(0xff);
+                       flag.x = (kX >= mincols & kX <= maxcols) ? flag.x : 0xff;
+                       flag.y = (kX+1 >= mincols & kX+1 <= maxcols) ? flag.y : 0xff;
+                       flag.z = (kX+2 >= mincols & kX+2 <= maxcols) ? flag.z : 0xff;
+                       flag.w = (kX+3 >= mincols & kX+3 <= maxcols) ? flag.w : 0xff;                   
+
+            minVal = min(minVal , flag);
+        }
+    }
+
+       if(mY < rows)
+       {
+               __global uchar4* d = (__global uchar4*)(dst + mY * dstStep + mX + dstOffset);
+               uchar4 dVal = *d;
+               
+               minVal.x = (mX >=0 & mX < cols) ? minVal.x : dVal.x;
+               minVal.y = (mX+1 >=0 & mX+1 < cols) ? minVal.y : dVal.y;
+               minVal.z = (mX+2 >=0 & mX+2 < cols) ? minVal.z : dVal.z;
+               minVal.w = (mX+3 >=0 & mX+3 < cols) ? minVal.w : dVal.w;
+               
+        *d = (minVal); 
+       }
+}
+
+__kernel void erode_C4_D0(__global const uchar4 * restrict src, __global uchar4 *dst, int srcOffset, int dstOffset, 
+                                       int mincols, int maxcols, int minrows, int maxrows, int cols, int rows, 
+                                       int srcStep, int dstStep, __constant uchar * mat_kernel, int src_whole_cols, int src_whole_rows)
+{
+    int mX = get_global_id(0);
+    int mY = get_global_id(1);
+    int kX = mX - anX, kY = mY - anY;
+       int end_addr = mad24(src_whole_rows-1,srcStep,src_whole_cols);
+    uchar4 minVal = (uchar4)(0xff);
+       int k=0;
+       for(int i=0;i<ksY;i++, kY++ , kX = mX - anX)
+    {
+        for(int j=0;j<ksX;j++, kX++)
+        {
+                       int current_addr = mad24(kY,srcStep,kX) + srcOffset;
+                       current_addr = ((current_addr < end_addr) && (current_addr > 0)) ? current_addr : 0;            
+                       uchar4 v = src[current_addr];
+                       uchar now = mat_kernel[k++];
+                       uchar4 flag = (kX >= mincols & kX <= maxcols & kY >= minrows & kY <= maxrows & now != 0) ? v : (uchar4)(0xff);
+            minVal = min(minVal , flag);
+        }
+    }
+
+       if(mX < cols && mY < rows)
+        dst[mY * dstStep + mX + dstOffset] = (minVal);            
+}
+
diff --git a/modules/ocl/src/kernels/filtering_laplacian.cl b/modules/ocl/src/kernels/filtering_laplacian.cl
new file mode 100644 (file)
index 0000000..f4eb19f
--- /dev/null
@@ -0,0 +1,531 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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 BORDER_REFLECT_101
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////Macro for border type////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////
+#ifdef BORDER_REPLICATE
+//BORDER_REPLICATE:     aaaaaa|abcdefgh|hhhhhhh
+#define ADDR_L(i, l_edge, r_edge)  ((i) <  (l_edge) ? (l_edge)   : (i))
+#define ADDR_R(i, r_edge, addr)    ((i) >= (r_edge) ? (r_edge)-1 : (addr))
+#define ADDR_H(i, t_edge, b_edge)  ((i) <  (t_edge) ? (t_edge)   :(i)) 
+#define ADDR_B(i, b_edge, addr)    ((i) >= (b_edge) ? (b_edge)-1 :(addr)) 
+#endif
+
+#ifdef BORDER_REFLECT
+//BORDER_REFLECT:       fedcba|abcdefgh|hgfedcb
+#define ADDR_L(i, l_edge, r_edge)  ((i) <  (l_edge) ? -(i)-1               : (i))
+#define ADDR_R(i, r_edge, addr)    ((i) >= (r_edge) ? -(i)-1+((r_edge)<<1) : (addr))
+#define ADDR_H(i, t_edge, b_edge)  ((i) <  (t_edge) ? -(i)-1 : (i))
+#define ADDR_B(i, b_edge, addr)    ((i) >= (b_edge) ? -(i)-1+((b_edge)<<1) : (addr))
+#endif
+
+#ifdef BORDER_REFLECT_101
+//BORDER_REFLECT_101:   gfedcb|abcdefgh|gfedcba
+#define ADDR_L(i, l_edge, r_edge)  ((i) <  (l_edge) ? -(i)                 : (i))
+#define ADDR_R(i, r_edge, addr)    ((i) >= (r_edge) ? -(i)-2+((r_edge)<<1) : (addr))
+#define ADDR_H(i, t_edge, b_edge)  ((i) <  (t_edge) ? -(i)                 : (i))
+#define ADDR_B(i, b_edge, addr)    ((i) >= (b_edge) ? -(i)-2+((b_edge)<<1) : (addr))
+#endif
+
+#ifdef BORDER_WRAP
+//BORDER_WRAP:          cdefgh|abcdefgh|abcdefg
+#define ADDR_L(i, l_edge, r_edge)  ((i) <  (l_edge) ? (i)+(r_edge) : (i))
+#define ADDR_R(i, r_edge, addr)    ((i) >= (r_edge) ? (i)-(r_edge) : (addr))
+#define ADDR_H(i, t_edge, b_edge)  ((i) <  (t_edge) ? (i)+(b_edge) : (i))
+#define ADDR_B(i, b_edge, addr)    ((i) >= (b_edge) ? (i)-(b_edge) : (addr))
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////Macro for define elements number per thread/////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+#define ANCHOR                  3
+#define ANX                     1
+#define ANY                     1
+
+#define ROWS_PER_GROUP          4
+#define ROWS_PER_GROUP_BITS     2
+#define ROWS_FETCH              (ROWS_PER_GROUP + ANY + ANY)   //(ROWS_PER_GROUP + anY * 2)
+
+#define THREADS_PER_ROW         64 
+#define THREADS_PER_ROW_BIT     6 
+
+#define ELEMENTS_PER_THREAD     4 
+#define ELEMENTS_PER_THREAD_BIT 2
+
+#define LOCAL_MEM_STEP          260 //divup((get_local_size(0) + anX * 2), 4) * 4
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////8uC1////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void filter2D_C1_D0(__global uchar *src, int src_step, int src_offset_x, int src_offset_y, 
+                             __global uchar *dst, int dst_step, int dst_offset_x, int dst_offset_y, 
+                             __constant int *mat_kernel __attribute__((max_constant_size (16384))),
+                             int cols,int rows, int operate_cols, int wholecols, int wholerows) 
+{
+    int gX = get_global_id(0);
+    int gY = get_global_id(1);
+
+    int lX = get_local_id(0);
+
+    int groupX_size = get_local_size(0);
+    int groupX_id   = get_group_id(0);
+
+    #define dst_align (dst_offset_x & 3)     
+    int cols_start_index_group = src_offset_x - dst_align + groupX_size * groupX_id - ANX; 
+    int rows_start_index       = src_offset_y + (gY << ROWS_PER_GROUP_BITS) - ANY; 
+        
+    __local uchar local_data[LOCAL_MEM_STEP * ROWS_FETCH];
+    if((gY << 2) < rows)
+    {
+        for(int i = 0; i < ROWS_FETCH; ++i)
+        {
+            if((rows_start_index - src_offset_y) + i < rows + ANY)  
+            {
+                #ifdef BORDER_CONSTANT
+                int selected_row  = rows_start_index + i;
+                int selected_cols = cols_start_index_group + lX;
+
+                uchar data = *(src + selected_row * src_step + selected_cols);
+                int con = selected_row >=0 && selected_row < wholerows && selected_cols >=0 && selected_cols < wholecols;
+                data = con ? data : 0;
+                local_data[i * LOCAL_MEM_STEP + lX ] =data; 
+
+                if(lX < (ANX << 1))
+                {
+                    selected_cols = cols_start_index_group + lX + groupX_size;
+
+                    data = *(src + selected_row * src_step + selected_cols);
+                    con = selected_row >=0 && selected_row < wholerows && selected_cols >=0 && selected_cols < wholecols;
+                    data = con ? data : 0;
+                    local_data[i * LOCAL_MEM_STEP + lX + groupX_size] =data; 
+                }
+                #else
+                int selected_row = ADDR_H(rows_start_index + i,  0, wholerows);
+                selected_row     = ADDR_B(rows_start_index + i, wholerows, selected_row);
+
+                int selected_cols = ADDR_L(cols_start_index_group + lX, 0, wholecols);
+                selected_cols     = ADDR_R(cols_start_index_group + lX, wholecols, selected_cols);
+
+                uchar data = *(src + selected_row * src_step + selected_cols);
+
+                local_data[i * LOCAL_MEM_STEP + lX ] =data; 
+
+                if(lX < (ANX << 1))
+                {
+                    selected_cols = cols_start_index_group + lX + groupX_size;
+                    selected_cols = ADDR_R(selected_cols, wholecols, selected_cols);
+
+                    data = *(src + selected_row * src_step + selected_cols);
+                    local_data[i * LOCAL_MEM_STEP + lX + groupX_size] =data; 
+                }
+                #endif
+            }
+        }
+    }
+    barrier(CLK_LOCAL_MEM_FENCE);
+
+    int process_col = groupX_size * groupX_id + ((lX % THREADS_PER_ROW) << 2);
+    if(((gY << 2) < rows) && (process_col < operate_cols))
+    {
+        int dst_cols_start = dst_offset_x; 
+        int dst_cols_end   = dst_offset_x + cols;
+        int dst_cols_index = (dst_offset_x + process_col) & 0xfffffffc;  
+
+        int dst_rows_end   = dst_offset_y + rows;
+        int dst_rows_index = dst_offset_y + (gY << ROWS_PER_GROUP_BITS) + (lX >> THREADS_PER_ROW_BIT);
+
+        uchar4 dst_data = *((__global uchar4 *)(dst + dst_rows_index * dst_step + dst_cols_index));
+
+        int4 sum = (int4)(0);
+        uchar4 data;
+
+        for(int i = 0; i < ANCHOR; i++)
+        {
+           #pragma unroll 3
+           for(int j = 0; j < ANCHOR; j++)
+           {
+                if(dst_rows_index < dst_rows_end)
+                {
+                     int local_row = (lX >> THREADS_PER_ROW_BIT) + i;
+                     int local_cols = ((lX % THREADS_PER_ROW) << ELEMENTS_PER_THREAD_BIT) + j; 
+
+                     data = vload4(0, local_data+local_row * LOCAL_MEM_STEP + local_cols); 
+                     sum = sum + (mat_kernel[i * ANCHOR + j] * convert_int4_sat(data));
+                 }
+            }
+        }
+
+        if(dst_rows_index < dst_rows_end)
+        {
+            sum.x = ((dst_cols_index + 0 >= dst_cols_start) && (dst_cols_index + 0 < dst_cols_end)) ? sum.x : dst_data.x;
+            sum.y = ((dst_cols_index + 1 >= dst_cols_start) && (dst_cols_index + 1 < dst_cols_end)) ? sum.y : dst_data.y;
+            sum.z = ((dst_cols_index + 2 >= dst_cols_start) && (dst_cols_index + 2 < dst_cols_end)) ? sum.z : dst_data.z;
+            sum.w = ((dst_cols_index + 3 >= dst_cols_start) && (dst_cols_index + 3 < dst_cols_end)) ? sum.w : dst_data.w;
+            *((__global uchar4 *)(dst + dst_rows_index * dst_step + dst_cols_index)) = convert_uchar4_sat(sum); 
+        }
+   }
+}
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////32FC1////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void filter2D_C1_D5(__global float *src, int src_step, int src_offset_x, int src_offset_y, 
+                             __global float *dst, int dst_step, int dst_offset_x, int dst_offset_y, 
+                             __constant int *mat_kernel __attribute__((max_constant_size (16384))),
+                             int cols,int rows, int operate_cols, int wholecols, int wholerows) 
+{
+    int gX = get_global_id(0);
+    int gY = get_global_id(1);
+
+    int lX = get_local_id(0);
+
+    int groupX_size = get_local_size(0);
+    int groupX_id   = get_group_id(0);
+
+    #define dst_align (dst_offset_x & 3)     
+    int cols_start_index_group = src_offset_x - dst_align + groupX_size * groupX_id - ANX; 
+    int rows_start_index       = src_offset_y + (gY << ROWS_PER_GROUP_BITS) - ANY; 
+        
+    __local float local_data[LOCAL_MEM_STEP * ROWS_FETCH];
+    if(((gY << 2) < rows))
+    {
+        for(int i = 0; i < ROWS_FETCH; ++i)
+        {
+            if((rows_start_index - src_offset_y) + i < rows + ANY)  
+            {
+                #ifdef BORDER_CONSTANT
+                int selected_row  = rows_start_index + i;
+                int selected_cols = cols_start_index_group + lX;
+
+                float data = *((__global float *)((__global char *)src + selected_row * src_step + (selected_cols << 2)));
+                int con = selected_row >=0 && selected_row < wholerows && selected_cols >=0 && selected_cols < wholecols;
+                data = con ? data : 0;
+                local_data[i * LOCAL_MEM_STEP + lX ] =data; 
+
+                if(lX < (ANX << 1))
+                {
+                    selected_cols = cols_start_index_group + lX + groupX_size;
+
+                    data = *((__global float *)((__global char *)src + selected_row * src_step + (selected_cols << 2)));
+                    con = selected_row >=0 && selected_row < wholerows && selected_cols >=0 && selected_cols < wholecols;
+                    data = con ? data : 0;
+                    local_data[i * LOCAL_MEM_STEP + lX + groupX_size] =data; 
+                }
+                #else
+                int selected_row = ADDR_H(rows_start_index + i,  0, wholerows);
+                selected_row     = ADDR_B(rows_start_index + i, wholerows, selected_row);
+
+                int selected_cols = ADDR_L(cols_start_index_group + lX, 0, wholecols);
+                selected_cols     = ADDR_R(cols_start_index_group + lX, wholecols, selected_cols);
+
+                float data = *((__global float *)((__global char *)src + selected_row * src_step + (selected_cols << 2)));
+                local_data[i * LOCAL_MEM_STEP + lX] =data; 
+
+                if(lX < (ANX << 1))
+                {
+                    selected_cols = cols_start_index_group + lX + groupX_size;
+                    selected_cols = ADDR_R(selected_cols, wholecols, selected_cols);
+
+                    data = *((__global float *)((__global char *)src + selected_row * src_step + (selected_cols << 2)));
+                    local_data[i * LOCAL_MEM_STEP + lX + groupX_size] =data; 
+                }
+                #endif
+            }
+        }
+    }
+    barrier(CLK_LOCAL_MEM_FENCE);
+
+    int process_col = groupX_size * groupX_id + ((lX % THREADS_PER_ROW) << 2);
+    if(((gY << 2) < rows) && (process_col < operate_cols))
+    {
+        int dst_cols_start = dst_offset_x; 
+        int dst_cols_end   = dst_offset_x + cols;
+        int dst_cols_index = (dst_offset_x + process_col) & 0xfffffffc;  
+
+        int dst_rows_end   = dst_offset_y + rows;
+        int dst_rows_index = dst_offset_y + (gY << ROWS_PER_GROUP_BITS) + (lX >> THREADS_PER_ROW_BIT);
+
+        float4 dst_data = *((__global float4*)((__global char *)dst + dst_rows_index * dst_step + (dst_cols_index << 2)));
+
+        float4 sum = (float4)(0);
+        float4 data;
+
+        for(int i = 0; i < ANCHOR; i++)
+        {
+           #pragma unroll 3
+           for(int j = 0; j < ANCHOR; j++)
+           {
+                if(dst_rows_index < dst_rows_end)
+                {
+                     int local_row = (lX >> THREADS_PER_ROW_BIT) + i;
+                     int local_cols = ((lX % THREADS_PER_ROW) << ELEMENTS_PER_THREAD_BIT) + j; 
+
+                     data = vload4(0, local_data+local_row * LOCAL_MEM_STEP + local_cols); 
+                     sum = sum + (mat_kernel[i * ANCHOR + j] * data);
+                 }
+            }
+        }
+
+        if(dst_rows_index < dst_rows_end)
+        {
+            sum.x = ((dst_cols_index + 0 >= dst_cols_start) && (dst_cols_index + 0 < dst_cols_end)) ? sum.x : dst_data.x;
+            sum.y = ((dst_cols_index + 1 >= dst_cols_start) && (dst_cols_index + 1 < dst_cols_end)) ? sum.y : dst_data.y;
+            sum.z = ((dst_cols_index + 2 >= dst_cols_start) && (dst_cols_index + 2 < dst_cols_end)) ? sum.z : dst_data.z;
+            sum.w = ((dst_cols_index + 3 >= dst_cols_start) && (dst_cols_index + 3 < dst_cols_end)) ? sum.w : dst_data.w;
+
+            *((__global float4 *)((__global char *)dst + dst_rows_index * dst_step + (dst_cols_index << 2))) = sum; 
+        }
+   }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////8uC4////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void filter2D_C4_D0(__global uchar4 *src, int src_step, int src_offset_x, int src_offset_y, 
+                             __global uchar4 *dst, int dst_step, int dst_offset_x, int dst_offset_y, 
+                             __constant int *mat_kernel __attribute__((max_constant_size (16384))),
+                             int cols,int rows, int operate_cols, int wholecols, int wholerows) 
+{
+    int gX = get_global_id(0);
+    int gY = get_global_id(1);
+
+    int lX = get_local_id(0);
+
+    int groupX_size = get_local_size(0);
+    int groupX_id   = get_group_id(0);
+
+    #define dst_align (dst_offset_x & 3)     
+    int cols_start_index_group = src_offset_x - dst_align + groupX_size * groupX_id - ANX; 
+    int rows_start_index       = src_offset_y + (gY << ROWS_PER_GROUP_BITS) - ANY; 
+        
+    __local uchar4 local_data[LOCAL_MEM_STEP * ROWS_FETCH];
+        
+    if(((gY << 2) < rows))
+    {
+        for(int i = 0; i < ROWS_FETCH; ++i)
+        {
+            if((rows_start_index - src_offset_y) + i < rows + ANY)  
+            {
+                #ifdef BORDER_CONSTANT
+                int selected_row  = rows_start_index + i;
+                int selected_cols = cols_start_index_group + lX;
+
+                uchar4 data = *((__global uchar4*)((__global char*)src + selected_row * src_step + (selected_cols << 2)));
+                int con = selected_row >=0 && selected_row < wholerows && selected_cols >=0 && selected_cols < wholecols;
+                data = con ? data : 0;
+                local_data[i * LOCAL_MEM_STEP + lX ] =data; 
+
+                if(lX < (ANX << 1))
+                {
+                    selected_cols = cols_start_index_group + lX + groupX_size;
+
+                    data = *((__global uchar4*)((__global char*)src + selected_row * src_step + (selected_cols << 2)));
+                    con = selected_row >=0 && selected_row < wholerows && selected_cols >=0 && selected_cols < wholecols;
+                    data = con ? data : 0;
+                    local_data[i * LOCAL_MEM_STEP + lX + groupX_size] =data; 
+                }
+                #else
+                int selected_row = ADDR_H(rows_start_index + i,  0, wholerows);
+                selected_row     = ADDR_B(rows_start_index + i, wholerows, selected_row);
+
+                int selected_cols = ADDR_L(cols_start_index_group + lX, 0, wholecols);
+                selected_cols     = ADDR_R(cols_start_index_group + lX, wholecols, selected_cols);
+
+                uchar4 data = *((__global uchar4*)((__global char*)src + selected_row * src_step + (selected_cols << 2)));
+
+                local_data[i * LOCAL_MEM_STEP + lX] =data; 
+
+                if(lX < (ANX << 1))
+                {
+                    selected_cols = cols_start_index_group + lX + groupX_size;
+                    selected_cols = ADDR_R(selected_cols, wholecols, selected_cols);
+
+                    data = *((__global uchar4*)((__global char*)src + selected_row * src_step + (selected_cols << 2)));
+                    local_data[i * LOCAL_MEM_STEP + lX + groupX_size] =data; 
+                }
+                #endif
+            }
+        }
+    }
+    barrier(CLK_LOCAL_MEM_FENCE);
+
+    int process_col = groupX_size * groupX_id + ((lX % THREADS_PER_ROW) << 2);
+    if(((gY << 2) < rows) && (process_col < operate_cols))
+    {
+        int dst_cols_start = dst_offset_x; 
+        int dst_cols_end   = dst_offset_x + cols;
+        int dst_cols_index = (dst_offset_x + process_col) & 0xfffffffc;  
+
+        int dst_rows_end   = dst_offset_y + rows;
+        int dst_rows_index = dst_offset_y + (gY << ROWS_PER_GROUP_BITS) + (lX >> THREADS_PER_ROW_BIT);
+
+        uchar16 dst_data;
+        dst_data = *((__global uchar16*)((__global char *)dst + dst_rows_index * dst_step + (dst_cols_index << 2)));
+
+        int16 sum = (int16)(0);
+        uchar16 data;
+
+        for(int i = 0; i < ANCHOR; i++)
+        {
+           #pragma unroll 3
+           for(int j = 0; j < ANCHOR; j++)
+           {
+                if(dst_rows_index < dst_rows_end)
+                {
+                     int local_row = (lX >> THREADS_PER_ROW_BIT) + i;
+                     int local_cols = ((lX % THREADS_PER_ROW) << ELEMENTS_PER_THREAD_BIT) + j; 
+
+                     data = vload16(0, (__local uchar *)(local_data+local_row * LOCAL_MEM_STEP + local_cols)); 
+                     sum = sum + (mat_kernel[i * ANCHOR + j] * convert_int16_sat(data));
+                 }
+            }
+        }
+
+        if(dst_rows_index < dst_rows_end)
+        {
+            uchar16 sum1 = convert_uchar16_sat(sum);
+            sum1.s0123 = ((dst_cols_index + 0 >= dst_cols_start) && (dst_cols_index + 0 < dst_cols_end))?  
+                         sum1.s0123 : dst_data.s0123;
+            sum1.s4567 = ((dst_cols_index + 1 >= dst_cols_start) && (dst_cols_index + 1 < dst_cols_end))? 
+                         sum1.s4567 : dst_data.s4567;
+            sum1.s89ab = ((dst_cols_index + 2 >= dst_cols_start) && (dst_cols_index + 2 < dst_cols_end))? 
+                         sum1.s89ab : dst_data.s89ab;
+            sum1.scdef = ((dst_cols_index + 3 >= dst_cols_start) && (dst_cols_index + 3 < dst_cols_end))? 
+                         sum1.scdef : dst_data.scdef;
+
+            *((__global uchar16*)((__global char *)dst + dst_rows_index * dst_step + (dst_cols_index << 2))) = sum1; 
+        }
+    }
+}
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////32FC4////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+#define ROWS_FETCH_C4              (1 + ANY + ANY)   //(ROWS_PER_GROUP + anY * 2)
+#define LOCAL_MEM_STEP_C4           260 //divup((get_local_size(0) + anX * 2), 4) * 4)
+__kernel void filter2D_C4_D5(__global float4 *src, int src_step, int src_offset_x, int src_offset_y, 
+                             __global float4 *dst, int dst_step, int dst_offset_x, int dst_offset_y, 
+                             __constant int *mat_kernel __attribute__((max_constant_size (16384))),
+                             int cols,int rows, int operate_cols, int wholecols, int wholerows) 
+{
+    int gX = get_global_id(0);
+    int gY = get_global_id(1);
+
+    int lX = get_local_id(0);
+
+    int groupX_size = get_local_size(0);
+    int groupX_id   = get_group_id(0);
+
+    int cols_start_index_group = src_offset_x + groupX_size * groupX_id - ANX; 
+    int rows_start_index       = src_offset_y + gY - ANY; 
+        
+    __local float4 local_data[LOCAL_MEM_STEP_C4 * ROWS_FETCH_C4];
+    if((gY < rows) && (gX < (operate_cols + ANX + ANX)))
+    {
+        for(int i = 0; i < ROWS_FETCH_C4; ++i)
+        {
+            if((rows_start_index - src_offset_y) + i < rows + ANY)  
+            {
+                #ifdef BORDER_CONSTANT
+                int selected_row  = rows_start_index + i;
+                int selected_cols = cols_start_index_group + lX;
+
+                float4 data = *((__global float4*)((__global char*)src + selected_row * src_step + (selected_cols << 4)));
+                int con = selected_row >=0 && selected_row < wholerows && selected_cols >=0 && selected_cols < wholecols;
+                data = con ? data : 0;
+                local_data[i * LOCAL_MEM_STEP + lX ] =data; 
+
+                if(lX < (ANX << 1))
+                {
+                    selected_cols = cols_start_index_group + lX + groupX_size;
+
+                    data = *((__global float4*)((__global char*)src + selected_row * src_step + (selected_cols << 4)));
+                    con = selected_row >=0 && selected_row < wholerows && selected_cols >=0 && selected_cols < wholecols;
+                    data = con ? data : 0;
+                    local_data[i * LOCAL_MEM_STEP + lX + groupX_size] =data; 
+                }
+                #else
+                int selected_row = ADDR_H(rows_start_index + i,  0, wholerows);
+                selected_row     = ADDR_B(rows_start_index + i, wholerows, selected_row);
+
+                int selected_cols = ADDR_L(cols_start_index_group + lX, 0, wholecols);
+                selected_cols     = ADDR_R(cols_start_index_group + lX, wholecols, selected_cols);
+
+                float4 data = *((__global float4*)((__global char*)src + selected_row * src_step + (selected_cols << 4)));
+                local_data[i * LOCAL_MEM_STEP_C4 + lX] =data; 
+
+                if(lX < (ANX << 1))
+                {
+                    selected_cols = cols_start_index_group + lX + groupX_size;
+                    selected_cols = ADDR_R(selected_cols, wholecols, selected_cols);
+
+                    data = *((__global float4*)((__global char*)src + selected_row * src_step + (selected_cols << 4)));
+                    local_data[i * LOCAL_MEM_STEP_C4 + lX + groupX_size] =data; 
+                }
+                #endif
+            }
+        }
+    }
+    barrier(CLK_LOCAL_MEM_FENCE);
+
+    if((gY < rows) && (gX < operate_cols))
+    {
+        int dst_cols_index = dst_offset_x + gX;  
+        int dst_rows_index = dst_offset_y + gY;
+
+        float4 sum = (float4)(0);
+
+        for(int i = 0; i < ANCHOR; i++)
+        {
+           for(int j = 0; j < ANCHOR; j++)
+           {
+               int local_cols = lX + j; 
+               sum = sum + mat_kernel[i * ANCHOR + j] * local_data[i * LOCAL_MEM_STEP_C4 + local_cols];
+            }
+        }
+
+        *((__global float4*)((__global char *)dst + dst_rows_index * dst_step + (dst_cols_index << 4))) = sum; 
+    }
+}
diff --git a/modules/ocl/src/kernels/haarobjectdetect.cl b/modules/ocl/src/kernels/haarobjectdetect.cl
new file mode 100644 (file)
index 0000000..d0f6ceb
--- /dev/null
@@ -0,0 +1,550 @@
+//                           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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Niko Li, newlife20080214@gmail.com
+//    Wang Weiyan, wangweiyanster@gmail.com
+//    Jia Haipeng, jiahaipeng95@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 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.
+//
+//
+
+#pragma OPENCL EXTENSION cl_amd_printf : enable
+#define CV_HAAR_FEATURE_MAX           3
+
+#define calc_sum(rect,offset)        (sum[(rect).p0+offset] - sum[(rect).p1+offset] - sum[(rect).p2+offset] + sum[(rect).p3+offset])
+#define calc_sum1(rect,offset,i)     (sum[(rect).p0[i]+offset] - sum[(rect).p1[i]+offset] - sum[(rect).p2[i]+offset] + sum[(rect).p3[i]+offset])
+
+typedef int   sumtype;
+typedef float sqsumtype;
+
+typedef struct  __attribute__((aligned (128)))  GpuHidHaarFeature
+{
+       struct __attribute__((aligned (32)))
+       {
+               int p0 __attribute__((aligned (4))); 
+               int p1 __attribute__((aligned (4))); 
+               int p2 __attribute__((aligned (4))); 
+               int p3 __attribute__((aligned (4)));
+               float weight __attribute__((aligned (4)));
+       }
+       rect[CV_HAAR_FEATURE_MAX] __attribute__((aligned (32)));
+}
+GpuHidHaarFeature;
+
+
+typedef struct __attribute__((aligned (128) )) GpuHidHaarTreeNode
+{
+       int p[CV_HAAR_FEATURE_MAX][4] __attribute__((aligned (64)));
+       float weight[CV_HAAR_FEATURE_MAX] /*__attribute__((aligned (16)))*/;
+       float threshold /*__attribute__((aligned (4)))*/;
+       float alpha[2] __attribute__((aligned (8)));
+       int left __attribute__((aligned (4)));
+       int right __attribute__((aligned (4)));
+}
+GpuHidHaarTreeNode;
+
+
+typedef struct __attribute__((aligned (32))) GpuHidHaarClassifier
+{
+       int count __attribute__((aligned (4)));
+       GpuHidHaarTreeNode* node __attribute__((aligned (8)));
+       float* alpha __attribute__((aligned (8)));
+}
+GpuHidHaarClassifier;
+
+
+typedef struct __attribute__((aligned (64))) GpuHidHaarStageClassifier
+{
+       int  count __attribute__((aligned (4)));
+       float threshold __attribute__((aligned (4)));
+       int two_rects __attribute__((aligned (4)));
+       int reserved0 __attribute__((aligned (8)));
+       int reserved1 __attribute__((aligned (8)));
+       int reserved2 __attribute__((aligned (8)));
+       int reserved3 __attribute__((aligned (8)));
+}
+GpuHidHaarStageClassifier;
+
+
+typedef struct __attribute__((aligned (64))) GpuHidHaarClassifierCascade
+{
+       int  count __attribute__((aligned (4)));
+       int  is_stump_based __attribute__((aligned (4)));
+       int  has_tilted_features __attribute__((aligned (4)));
+       int  is_tree __attribute__((aligned (4)));
+       int pq0 __attribute__((aligned (4))); 
+       int pq1 __attribute__((aligned (4)));
+       int pq2 __attribute__((aligned (4)));
+       int pq3 __attribute__((aligned (4)));
+       int p0 __attribute__((aligned (4)));
+       int p1 __attribute__((aligned (4))); 
+       int p2 __attribute__((aligned (4))); 
+       int p3 __attribute__((aligned (4)));
+       float inv_window_area __attribute__((aligned (4)));
+}GpuHidHaarClassifierCascade;
+
+
+__kernel void __attribute__((reqd_work_group_size(8,8,1)))gpuRunHaarClassifierCascade(//constant GpuHidHaarClassifierCascade * cascade,
+                                                                                 global GpuHidHaarStageClassifier * stagecascadeptr,
+                                                                                 global int4 * info,    
+                                                                                 global GpuHidHaarTreeNode * nodeptr,
+                                                                                 global const int * restrict sum1, 
+                                                                                 global const float * restrict sqsum1, 
+                                                                                 global int4 * candidate,
+                                                                                 const int pixelstep,
+                                                                                 const int loopcount,
+                                                                                 const int start_stage, 
+                                                                                 const int split_stage,
+                                                                                 const int end_stage,
+                                                                                 const int startnode,
+                                                                                 const int splitnode,
+                                                                                 const int4 p, 
+                                                                                 const int4 pq, 
+                                                                                 const float correction 
+                                                                                 //const int width, 
+                                                                                 //const int height,
+                                                                                 //const int grpnumperline,
+                                                                                 //const int totalgrp
+                                                                                 )
+{
+       int grpszx = get_local_size(0);
+       int grpszy = get_local_size(1);
+       int grpnumx = get_num_groups(0);
+       int grpidx = get_group_id(0);
+       int lclidx = get_local_id(0);
+       int lclidy = get_local_id(1);
+
+       int lcl_sz = mul24(grpszx,grpszy);
+       int lcl_id = mad24(lclidy,grpszx,lclidx);
+
+       //assume lcl_sz == 256 or 128 or 64
+       //int lcl_sz_shift = (lcl_sz == 256) ? 8 : 7;
+       //lcl_sz_shift = (lcl_sz == 64) ? 6 : lcl_sz_shift;
+       __local int lclshare[1024];
+
+#define OFF 0
+       __local int* lcldata = lclshare + OFF;//for save win data
+       __local int* glboutindex = lcldata + 28*28;//for save global out index 
+       __local int* lclcount = glboutindex + 1;//for save the numuber of temp pass pixel
+       __local int* lcloutindex = lclcount + 1;//for save info of temp pass pixel
+       __local float* partialsum = (__local float*)(lcloutindex + (lcl_sz<<1));
+       glboutindex[0]=0;
+       int outputoff = mul24(grpidx,256);
+
+       //assume window size is 20X20
+#define WINDOWSIZE 20+1
+       //make sure readwidth is the multiple of 4
+       //ystep =1, from host code
+       int readwidth = ((grpszx-1 + WINDOWSIZE+3)>>2)<<2;
+       int readheight = grpszy-1+WINDOWSIZE;
+       int read_horiz_cnt = readwidth >> 2;//each read int4
+       int total_read = mul24(read_horiz_cnt,readheight);
+       int read_loop = (total_read + lcl_sz - 1) >> 6;
+       candidate[outputoff+(lcl_id<<2)] = (int4)0;
+       candidate[outputoff+(lcl_id<<2)+1] = (int4)0;
+       candidate[outputoff+(lcl_id<<2)+2] = (int4)0;
+       candidate[outputoff+(lcl_id<<2)+3] = (int4)0;
+       for(int scalei = 0; scalei <loopcount; scalei++)
+       {
+               int4 scaleinfo1= info[scalei];
+               int width = (scaleinfo1.x & 0xffff0000) >> 16;
+               int height = scaleinfo1.x & 0xffff;
+               int grpnumperline =(scaleinfo1.y & 0xffff0000) >> 16;
+               int totalgrp = scaleinfo1.y & 0xffff;
+               int imgoff = scaleinfo1.z;
+               float factor = as_float(scaleinfo1.w);
+               //int ystep =1;// factor > 2.0 ? 1 : 2;
+
+               __global const int * sum = sum1 + imgoff;
+               __global const float * sqsum = sqsum1 + imgoff;
+               for(int grploop=grpidx;grploop<totalgrp;grploop+=grpnumx)
+               {
+                       int grpidy = grploop / grpnumperline;
+                       int grpidx = grploop - mul24(grpidy, grpnumperline);
+                       int x = mad24(grpidx,grpszx,lclidx);
+                       int y = mad24(grpidy,grpszy,lclidy);
+                       //candidate_result.x = convert_int_rtn(x*factor);
+                       //candidate_result.y = convert_int_rtn(y*factor);
+                       int grpoffx = x-lclidx;
+                       int grpoffy = y-lclidy;
+
+                       for(int i=0;i<read_loop;i++)
+                       {
+                               int pos_id = mad24(i,lcl_sz,lcl_id);
+                               pos_id = pos_id < total_read ? pos_id : 0;
+
+                               int lcl_y = pos_id / read_horiz_cnt;
+                               int lcl_x = pos_id - mul24(lcl_y, read_horiz_cnt);
+
+                               int glb_x = grpoffx + (lcl_x<<2);
+                               int glb_y = grpoffy + lcl_y;
+
+                               int glb_off = mad24(glb_y,pixelstep,glb_x);
+                               int4 data = *(__global int4*)&sum[glb_off];
+                               int lcl_off = mad24(lcl_y, readwidth, lcl_x<<2);
+
+                               lcldata[lcl_off] = data.x;
+                               lcldata[lcl_off+1] = data.y;
+                               lcldata[lcl_off+2] = data.z;
+                               lcldata[lcl_off+3] = data.w;
+                       }
+
+                       lcloutindex[lcl_id] = 0;
+                       lclcount[0] = 0;
+                       int result = 1;
+                       int nodecounter= startnode;
+                       float mean, variance_norm_factor;
+                       barrier(CLK_LOCAL_MEM_FENCE);
+
+                       int lcl_off = mad24(lclidy,readwidth,lclidx);
+                       int4 cascadeinfo1, cascadeinfo2;
+                       cascadeinfo1 = p;
+                       cascadeinfo2 = pq;// + mad24(y, pixelstep, x);
+
+
+                       //if((x < width) && (y < height))
+                       {
+                               cascadeinfo1.x +=lcl_off;
+                               cascadeinfo1.z +=lcl_off;
+                               mean = (lcldata[mad24(cascadeinfo1.y,readwidth,cascadeinfo1.x)] - lcldata[mad24(cascadeinfo1.y,readwidth,cascadeinfo1.z)] - 
+                                       lcldata[mad24(cascadeinfo1.w,readwidth,cascadeinfo1.x)] + lcldata[mad24(cascadeinfo1.w,readwidth,cascadeinfo1.z)])
+                                       *correction;
+
+                               int p_offset = mad24(y, pixelstep, x);
+
+                               cascadeinfo2.x +=p_offset;
+                               cascadeinfo2.z +=p_offset;
+                               variance_norm_factor =sqsum[mad24(cascadeinfo2.y, pixelstep, cascadeinfo2.x)] - sqsum[mad24(cascadeinfo2.y, pixelstep, cascadeinfo2.z)] -   
+                                       sqsum[mad24(cascadeinfo2.w, pixelstep, cascadeinfo2.x)] + sqsum[mad24(cascadeinfo2.w, pixelstep, cascadeinfo2.z)]; 
+
+                               variance_norm_factor = variance_norm_factor * correction - mean * mean;
+                               variance_norm_factor = variance_norm_factor >=0.f ? sqrt(variance_norm_factor) : 1.f;
+                               //if( cascade->is_stump_based )              
+                               //{
+                               for(int stageloop = start_stage; (stageloop < split_stage)  && result; stageloop++ )
+                               {
+                                       float stage_sum = 0.f;
+                                       int2 stageinfo = *(global int2*)(stagecascadeptr+stageloop);
+                                       float stagethreshold = as_float(stageinfo.y);
+                                       for(int nodeloop = 0; nodeloop < stageinfo.x; nodeloop++ )
+                                       {
+                                               __global GpuHidHaarTreeNode* currentnodeptr = (nodeptr + nodecounter);
+
+                                               int4 info1 = *(__global int4*)(&(currentnodeptr->p[0][0]));
+                                               int4 info2 = *(__global int4*)(&(currentnodeptr->p[1][0]));
+                                               int4 info3 = *(__global int4*)(&(currentnodeptr->p[2][0]));
+                                               float4 w = *(__global float4*)(&(currentnodeptr->weight[0]));
+                                               float2 alpha2 = *(__global float2*)(&(currentnodeptr->alpha[0]));
+                                               float nodethreshold  = w.w * variance_norm_factor;
+
+                                               info1.x +=lcl_off;
+                                               info1.z +=lcl_off;
+                                               info2.x +=lcl_off;
+                                               info2.z +=lcl_off;
+
+                                               float classsum = (lcldata[mad24(info1.y,readwidth,info1.x)] - lcldata[mad24(info1.y,readwidth,info1.z)] - 
+                                                       lcldata[mad24(info1.w,readwidth,info1.x)] + lcldata[mad24(info1.w,readwidth,info1.z)]) * w.x;
+
+
+                                               classsum += (lcldata[mad24(info2.y,readwidth,info2.x)] - lcldata[mad24(info2.y,readwidth,info2.z)] - 
+                                                       lcldata[mad24(info2.w,readwidth,info2.x)] + lcldata[mad24(info2.w,readwidth,info2.z)]) * w.y;
+
+
+                                               //if((info3.z - info3.x) && (!stageinfo.z))
+                                               //{
+                                                       info3.x +=lcl_off;
+                                                       info3.z +=lcl_off;
+                                                       classsum += (lcldata[mad24(info3.y,readwidth,info3.x)] - lcldata[mad24(info3.y,readwidth,info3.z)] - 
+                                                               lcldata[mad24(info3.w,readwidth,info3.x)] + lcldata[mad24(info3.w,readwidth,info3.z)]) * w.z;
+                                               //}
+                                               stage_sum += classsum >= nodethreshold ? alpha2.y : alpha2.x;
+                                               nodecounter++;
+                                       }
+
+                                       result = (stage_sum >= stagethreshold);
+                               }
+
+                               if(result && (x < width) && (y < height))
+                               {
+                                       int queueindex = atomic_inc(lclcount);
+                                       lcloutindex[queueindex<<1] = (lclidy << 16) | lclidx;
+                                       lcloutindex[(queueindex<<1)+1] = as_int(variance_norm_factor);
+                               }
+                               barrier(CLK_LOCAL_MEM_FENCE);
+                               int queuecount  = lclcount[0];
+                               nodecounter = splitnode;
+                               for(int stageloop = split_stage; stageloop< end_stage && queuecount>0;stageloop++)
+                               {
+                                       lclcount[0]=0;
+                                       barrier(CLK_LOCAL_MEM_FENCE);
+
+                                       int2 stageinfo = *(global int2*)(stagecascadeptr+stageloop);
+                                       float stagethreshold = as_float(stageinfo.y);
+
+                                       int perfscale = queuecount > 4 ? 3 : 2;
+                                       int queuecount_loop = (queuecount + (1<<perfscale)-1) >> perfscale;
+                                       int lcl_compute_win = lcl_sz >> perfscale;
+                                       int lcl_compute_win_id = (lcl_id >>(6-perfscale));
+                                       int lcl_loops = (stageinfo.x + lcl_compute_win -1) >> (6-perfscale);
+                                       int lcl_compute_id = lcl_id - (lcl_compute_win_id << (6-perfscale));
+                                       for(int queueloop=0;queueloop<queuecount_loop && lcl_compute_win_id < queuecount;queueloop++)
+                                       {
+                                               float stage_sum = 0.f;
+                                               int temp_coord = lcloutindex[lcl_compute_win_id<<1];
+                                               float variance_norm_factor = as_float(lcloutindex[(lcl_compute_win_id<<1)+1]);
+                                               int queue_pixel = mad24(((temp_coord  & (int)0xffff0000)>>16),readwidth,temp_coord & 0xffff);
+
+                                               int tempnodecounter = lcl_compute_id;
+                                               float part_sum = 0.f;
+                                               for(int lcl_loop=0;lcl_loop<lcl_loops && tempnodecounter<stageinfo.x;lcl_loop++)
+                                               {
+                                                       __global GpuHidHaarTreeNode* currentnodeptr = (nodeptr + nodecounter + tempnodecounter);
+
+                                                       int4 info1 = *(__global int4*)(&(currentnodeptr->p[0][0]));
+                                                       int4 info2 = *(__global int4*)(&(currentnodeptr->p[1][0]));
+                                                       int4 info3 = *(__global int4*)(&(currentnodeptr->p[2][0]));
+                                                       float4 w = *(__global float4*)(&(currentnodeptr->weight[0]));
+                                                       float2 alpha2 = *(__global float2*)(&(currentnodeptr->alpha[0]));
+                                                       float nodethreshold  = w.w * variance_norm_factor;
+
+                                                       info1.x +=queue_pixel;
+                                                       info1.z +=queue_pixel;
+                                                       info2.x +=queue_pixel;
+                                                       info2.z +=queue_pixel;
+
+                                                       float classsum = (lcldata[mad24(info1.y,readwidth,info1.x)] - lcldata[mad24(info1.y,readwidth,info1.z)] - 
+                                                               lcldata[mad24(info1.w,readwidth,info1.x)] + lcldata[mad24(info1.w,readwidth,info1.z)]) * w.x;
+
+
+                                                       classsum += (lcldata[mad24(info2.y,readwidth,info2.x)] - lcldata[mad24(info2.y,readwidth,info2.z)] - 
+                                                               lcldata[mad24(info2.w,readwidth,info2.x)] + lcldata[mad24(info2.w,readwidth,info2.z)]) * w.y;
+                                               //if((info3.z - info3.x) && (!stageinfo.z))
+                                               //{
+                                                               info3.x +=queue_pixel;
+                                                               info3.z +=queue_pixel;
+                                                               classsum += (lcldata[mad24(info3.y,readwidth,info3.x)] - lcldata[mad24(info3.y,readwidth,info3.z)] - 
+                                                                       lcldata[mad24(info3.w,readwidth,info3.x)] + lcldata[mad24(info3.w,readwidth,info3.z)]) * w.z;
+                                               //}
+                                                       part_sum += classsum >= nodethreshold ? alpha2.y : alpha2.x;
+                                                       tempnodecounter+=lcl_compute_win;
+                                               }//end for(int lcl_loop=0;lcl_loop<lcl_loops;lcl_loop++)
+                                               partialsum[lcl_id]=part_sum;
+                                               barrier(CLK_LOCAL_MEM_FENCE);
+                                               for(int i=0;i<lcl_compute_win && (lcl_compute_id==0);i++)
+                                               {
+                                                       stage_sum += partialsum[lcl_id+i];
+                                               }
+                                               if(stage_sum >= stagethreshold && (lcl_compute_id==0))
+                                               {
+                                                       int queueindex = atomic_inc(lclcount);
+                                                       lcloutindex[queueindex<<1] = temp_coord;
+                                                       lcloutindex[(queueindex<<1)+1] = as_int(variance_norm_factor);
+                                               }
+                                               lcl_compute_win_id +=(1<<perfscale);
+                                               barrier(CLK_LOCAL_MEM_FENCE);
+                                       }//end for(int queueloop=0;queueloop<queuecount_loop;queueloop++)
+                                       queuecount = lclcount[0];
+                                       nodecounter += stageinfo.x;
+                               }//end for(int stageloop = splitstage; stageloop< endstage && queuecount>0;stageloop++)
+                               if(lcl_id<queuecount)
+                               {
+                                       int temp = lcloutindex[lcl_id<<1];
+                                       int x = mad24(grpidx,grpszx,temp & 0xffff);
+                                       int y = mad24(grpidy,grpszy,((temp & (int)0xffff0000) >> 16));
+                                       temp = glboutindex[0];
+                                       int4 candidate_result;
+                                       candidate_result.zw = (int2)convert_int_rtn(factor*20.f);
+                                       candidate_result.x = convert_int_rtn(x*factor);
+                                       candidate_result.y = convert_int_rtn(y*factor);
+                                       atomic_inc(glboutindex);
+                                       candidate[outputoff+temp+lcl_id] = candidate_result;
+                               }
+                               barrier(CLK_LOCAL_MEM_FENCE);
+                       }//end if((x < width) && (y < height))
+               }//end for(int grploop=grpidx;grploop<totalgrp;grploop+=grpnumx)
+               //outputoff +=mul24(width,height);
+       }//end for(int scalei = 0; scalei <loopcount; scalei++)
+}
+       
+                               
+       
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                /*
+                if(stagecascade->two_rects) 
+                {
+                    #pragma unroll
+                    for( n = 0; n < stagecascade->count; n++ )
+                    {
+                        t1 = *(node + counter);
+                        t = t1.threshold * variance_norm_factor;
+                        classsum = calc_sum1(t1,p_offset,0) * t1.weight[0];
+                       
+                        classsum  += calc_sum1(t1, p_offset,1) * t1.weight[1];
+                        stage_sum += classsum >= t ? t1.alpha[1]:t1.alpha[0];
+                       
+                        counter++;
+                    }
+                }
+                else
+                {
+                    #pragma unroll
+                    for( n = 0; n < stagecascade->count; n++ )
+                    {
+                        t = node[counter].threshold*variance_norm_factor;
+                        classsum = calc_sum1(node[counter],p_offset,0) * node[counter].weight[0];
+                        classsum += calc_sum1(node[counter],p_offset,1) * node[counter].weight[1];
+                       
+                        if( node[counter].p0[2] )
+                            classsum += calc_sum1(node[counter],p_offset,2) * node[counter].weight[2];
+                         
+                        stage_sum += classsum >= t ? node[counter].alpha[1]:node[counter].alpha[0];// modify
+                       
+                        counter++;
+                    }
+                }
+                */
+                               /*
+__kernel void gpuRunHaarClassifierCascade_ScaleWindow(
+                                                                                 constant GpuHidHaarClassifierCascade * _cascade, 
+                                                                                 global GpuHidHaarStageClassifier * stagecascadeptr,
+                                          //global GpuHidHaarClassifier * classifierptr,    
+                                                                                 global GpuHidHaarTreeNode * nodeptr,
+                                          global int * sum, 
+                                                                                 global float * sqsum, 
+                                                                                 global int * _candidate,
+                                          int pixel_step,
+                                                                                 int cols,
+                                                                                 int rows,
+                                                                                 int start_stage, 
+                                                                                 int end_stage,
+                                          //int counts,
+                                                                                 int nodenum, 
+                                                                                 int ystep, 
+                                                                                 int detect_width, 
+                                                                                 //int detect_height,
+                                                                                 int loopcount,
+                                                                                 int outputstep)
+                                                                                 //float scalefactor)
+{
+       unsigned int x1 = get_global_id(0);
+       unsigned int y1 = get_global_id(1);
+       int p_offset;
+       int m, n;
+       int result;
+       int counter;
+       float mean, variance_norm_factor;
+       for(int i=0;i<loopcount;i++)
+       {
+               constant GpuHidHaarClassifierCascade * cascade = _cascade + i;
+               global int * candidate = _candidate + i*outputstep;
+               int window_width = cascade->p1 - cascade->p0;
+               int window_height = window_width;
+               result = 1;
+               counter = 0;
+                       unsigned int x = mul24(x1,ystep);
+                       unsigned int y = mul24(y1,ystep);
+               if((x < cols - window_width - 1) && (y < rows - window_height -1))
+               {
+                       global GpuHidHaarStageClassifier *stagecascade = stagecascadeptr +cascade->count*i+ start_stage;
+                       //global GpuHidHaarClassifier      *classifier   = classifierptr;
+                       global GpuHidHaarTreeNode        *node         = nodeptr + nodenum*i;
+
+                       p_offset = mad24(y, pixel_step, x);// modify
+
+                       mean = (*(sum + p_offset + (int)cascade->p0) - *(sum + p_offset + (int)cascade->p1) - 
+                                       *(sum + p_offset + (int)cascade->p2) + *(sum + p_offset + (int)cascade->p3))
+                                       *cascade->inv_window_area;
+
+                       variance_norm_factor = *(sqsum + p_offset + cascade->p0) - *(sqsum + cascade->p1 + p_offset) -
+                                                                       *(sqsum + p_offset + cascade->p2) + *(sqsum + cascade->p3 + p_offset);
+                       variance_norm_factor = variance_norm_factor * cascade->inv_window_area - mean * mean;
+                       variance_norm_factor = variance_norm_factor >=0.f ? sqrt(variance_norm_factor) : 1;//modify
+
+                       // if( cascade->is_stump_based )              
+                       //{
+            for( m = start_stage; m < end_stage; m++ )
+            {
+                float stage_sum = 0.f;
+                float t,  classsum;
+                GpuHidHaarTreeNode t1;
+
+                //#pragma unroll
+                for( n = 0; n < stagecascade->count; n++ )
+                {
+                     t1 = *(node + counter);
+                     t  = t1.threshold * variance_norm_factor;
+                     classsum = calc_sum1(t1, p_offset ,0) * t1.weight[0] + calc_sum1(t1, p_offset ,1) * t1.weight[1];
+
+                     if((t1.p0[2]) && (!stagecascade->two_rects))
+                         classsum += calc_sum1(t1, p_offset, 2) * t1.weight[2];
+
+                     stage_sum += classsum >= t ? t1.alpha[1] : t1.alpha[0];// modify
+                     counter++;
+                }
+                      
+                if (stage_sum < stagecascade->threshold)
+                {
+                                       result = 0;
+                    break;   
+                }
+
+                stagecascade++;
+
+            }
+                               if(result)
+                               {
+                                       candidate[4 * (y1 * detect_width + x1)]     = x;
+                                       candidate[4 * (y1 * detect_width + x1) + 1] = y;
+                                       candidate[4 * (y1 * detect_width + x1)+2]     = window_width;
+                                       candidate[4 * (y1 * detect_width + x1) + 3] = window_height;
+                               }
+                       //}
+               }
+       }
+}
+*/
+
+                               
+                               
+       
diff --git a/modules/ocl/src/kernels/haarobjectdetect_scaled2.cl b/modules/ocl/src/kernels/haarobjectdetect_scaled2.cl
new file mode 100644 (file)
index 0000000..611b3b6
--- /dev/null
@@ -0,0 +1,334 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Wu Xinglong, wxl370@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*/
+
+// Enter your kernel in this window
+#pragma OPENCL EXTENSION cl_amd_printf:enable
+#define CV_HAAR_FEATURE_MAX           3
+typedef int   sumtype;
+typedef float sqsumtype;
+typedef struct  __attribute__((aligned (128)))  GpuHidHaarFeature
+{
+       struct __attribute__((aligned (32)))
+       {
+               int p0 __attribute__((aligned (4))); 
+               int p1 __attribute__((aligned (4))); 
+               int p2 __attribute__((aligned (4))); 
+               int p3 __attribute__((aligned (4)));
+               float weight __attribute__((aligned (4)));
+       }
+       rect[CV_HAAR_FEATURE_MAX] __attribute__((aligned (32)));
+}
+GpuHidHaarFeature;
+typedef struct __attribute__((aligned (128) )) GpuHidHaarTreeNode
+{
+       int p[CV_HAAR_FEATURE_MAX][4] __attribute__((aligned (64)));
+       float weight[CV_HAAR_FEATURE_MAX] /*__attribute__((aligned (16)))*/;
+       float threshold /*__attribute__((aligned (4)))*/;
+       float alpha[2] __attribute__((aligned (8)));
+       int left __attribute__((aligned (4)));
+       int right __attribute__((aligned (4)));
+}
+GpuHidHaarTreeNode;
+typedef struct __attribute__((aligned (32))) GpuHidHaarClassifier
+{
+       int count __attribute__((aligned (4)));
+       GpuHidHaarTreeNode* node __attribute__((aligned (8)));
+       float* alpha __attribute__((aligned (8)));
+}
+GpuHidHaarClassifier;
+typedef struct __attribute__((aligned (64))) GpuHidHaarStageClassifier
+{
+       int  count __attribute__((aligned (4)));
+       float threshold __attribute__((aligned (4)));
+       int two_rects __attribute__((aligned (4)));
+       int reserved0 __attribute__((aligned (8)));
+       int reserved1 __attribute__((aligned (8)));
+       int reserved2 __attribute__((aligned (8)));
+       int reserved3 __attribute__((aligned (8)));
+}
+GpuHidHaarStageClassifier;
+typedef struct __attribute__((aligned (64))) GpuHidHaarClassifierCascade
+{
+       int  count __attribute__((aligned (4)));
+       int  is_stump_based __attribute__((aligned (4)));
+       int  has_tilted_features __attribute__((aligned (4)));
+       int  is_tree __attribute__((aligned (4)));
+       int pq0 __attribute__((aligned (4))); 
+       int pq1 __attribute__((aligned (4)));
+       int pq2 __attribute__((aligned (4)));
+       int pq3 __attribute__((aligned (4)));
+       int p0 __attribute__((aligned (4)));
+       int p1 __attribute__((aligned (4))); 
+       int p2 __attribute__((aligned (4))); 
+       int p3 __attribute__((aligned (4)));
+       float inv_window_area __attribute__((aligned (4)));
+}GpuHidHaarClassifierCascade;
+__kernel void gpuRunHaarClassifierCascade_scaled2(
+       global GpuHidHaarStageClassifier * stagecascadeptr,
+       global int4 * info, 
+       global GpuHidHaarTreeNode * nodeptr,
+       global const int * restrict sum,
+       global const float *  restrict sqsum,
+       global int4 * candidate,
+       const int step,
+       const int loopcount,
+       const int start_stage,
+    const int split_stage,
+       const int end_stage,
+       const int startnode,
+    const int splitnode,
+    global int4 * p,
+                                                                         //const int4 * pq,
+       global float * correction,
+   const int nodecount)
+{
+       int grpszx = get_local_size(0);
+       int grpszy = get_local_size(1);
+       int grpnumx = get_num_groups(0);
+    int grpidx=get_group_id(0);
+       int lclidx = get_local_id(0);
+       int lclidy = get_local_id(1);
+       int lcl_sz = mul24(grpszx,grpszy);
+       int lcl_id = mad24(lclidy,grpszx,lclidx);
+    __local int lclshare[1024];
+    __local int* glboutindex=lclshare+0;
+    __local int* lclcount=glboutindex+1;
+    __local int* lcloutindex=lclcount+1;
+    __local float* partialsum=(__local float*)(lcloutindex+(lcl_sz<<1));
+    glboutindex[0]=0;
+    int outputoff = mul24(grpidx,256);
+       candidate[outputoff+(lcl_id<<2)] = (int4)0;
+       candidate[outputoff+(lcl_id<<2)+1] = (int4)0;
+       candidate[outputoff+(lcl_id<<2)+2] = (int4)0;
+       candidate[outputoff+(lcl_id<<2)+3] = (int4)0;
+       for(int scalei = 0; scalei <loopcount; scalei++)
+       {
+               int4 scaleinfo1;
+               scaleinfo1 = info[scalei];
+               int width = (scaleinfo1.x & 0xffff0000) >> 16;
+               int height = scaleinfo1.x & 0xffff;
+               int grpnumperline =(scaleinfo1.y & 0xffff0000) >> 16;
+               int totalgrp = scaleinfo1.y & 0xffff;
+               float factor = as_float(scaleinfo1.w);
+               float correction_t=correction[scalei];
+               int ystep=(int)(max(2.0f,factor)+0.5f);
+               for(int grploop=get_group_id(0);grploop<totalgrp;grploop+=grpnumx){
+                   int4 cascadeinfo=p[scalei];
+                       int grpidy = grploop / grpnumperline;
+                       int grpidx = grploop - mul24(grpidy, grpnumperline);
+                       int ix = mad24(grpidx,grpszx,lclidx);
+                       int iy = mad24(grpidy,grpszy,lclidy);
+            int x=ix*ystep;
+            int y=iy*ystep;
+            lcloutindex[lcl_id]=0;
+            lclcount[0]=0;
+                   int result=1,nodecounter;
+                   float mean,variance_norm_factor;
+                       //if((ix < width) && (iy < height))
+            {
+                               const int p_offset = mad24(y, step, x);
+                               cascadeinfo.x +=p_offset;
+                               cascadeinfo.z +=p_offset;
+                               mean = (sum[mad24(cascadeinfo.y,step,cascadeinfo.x)] - sum[mad24(cascadeinfo.y,step,cascadeinfo.z)] - 
+                                       sum[mad24(cascadeinfo.w,step,cascadeinfo.x)] + sum[mad24(cascadeinfo.w,step,cascadeinfo.z)])
+                                       *correction_t;
+                               variance_norm_factor =sqsum[mad24(cascadeinfo.y,step, cascadeinfo.x)] - sqsum[mad24(cascadeinfo.y, step, cascadeinfo.z)] -   
+                               sqsum[mad24(cascadeinfo.w, step, cascadeinfo.x)] + sqsum[mad24(cascadeinfo.w, step, cascadeinfo.z)]; 
+                               variance_norm_factor = variance_norm_factor * correction_t - mean * mean;
+                               variance_norm_factor = variance_norm_factor >=0.f ? sqrt(variance_norm_factor) : 1.f;
+                               result = 1;
+                               nodecounter = startnode+nodecount*scalei;
+                               for(int stageloop = start_stage; stageloop < split_stage&&result; stageloop++ )
+                               {
+                                       float stage_sum = 0.f;
+                                       int4 stageinfo = *(global int4*)(stagecascadeptr+stageloop);
+                                       float stagethreshold = as_float(stageinfo.y);
+                                       for(int nodeloop = 0; nodeloop < stageinfo.x; nodeloop++ )
+                                       {
+                                               __global GpuHidHaarTreeNode* currentnodeptr = (nodeptr + nodecounter);
+                                               int4 info1 = *(__global int4*)(&(currentnodeptr->p[0][0]));
+                                               int4 info2 = *(__global int4*)(&(currentnodeptr->p[1][0]));
+                                               int4 info3 = *(__global int4*)(&(currentnodeptr->p[2][0]));
+                                               float4 w = *(__global float4*)(&(currentnodeptr->weight[0]));
+                                               float2 alpha2 = *(__global float2*)(&(currentnodeptr->alpha[0]));
+                       float nodethreshold  = w.w * variance_norm_factor;
+                                               info1.x +=p_offset;
+                                               info1.z +=p_offset;
+                                               info2.x +=p_offset;
+                                               info2.z +=p_offset;
+                                               float classsum = (sum[mad24(info1.y,step,info1.x)] - sum[mad24(info1.y,step,info1.z)] - 
+                                                       sum[mad24(info1.w,step,info1.x)] + sum[mad24(info1.w,step,info1.z)]) * w.x;
+                                               classsum += (sum[mad24(info2.y,step,info2.x)] - sum[mad24(info2.y,step,info2.z)] - 
+                                                       sum[mad24(info2.w,step,info2.x)] + sum[mad24(info2.w,step,info2.z)]) * w.y;
+                                               info3.x +=p_offset;
+                                               info3.z +=p_offset;
+                                                classsum += (sum[mad24(info3.y,step,info3.x)] - sum[mad24(info3.y,step,info3.z)] - 
+                                                       sum[mad24(info3.w,step,info3.x)] + sum[mad24(info3.w,step,info3.z)]) * w.z;
+                                               stage_sum += classsum >= nodethreshold ? alpha2.y : alpha2.x;
+                                               nodecounter++;
+                                       }
+                                       result=(stage_sum>=stagethreshold);
+                               }
+                               if(result&&(ix<width)&&(iy<height))
+                {
+                     int queueindex=atomic_inc(lclcount);
+                     lcloutindex[queueindex<<1]=(y<<16)|x;
+                     lcloutindex[(queueindex<<1)+1]=as_int(variance_norm_factor);
+                }
+                barrier(CLK_LOCAL_MEM_FENCE); 
+                int queuecount=lclcount[0];
+                nodecounter=splitnode+nodecount*scalei;
+                for(int stageloop=split_stage;stageloop<end_stage&&queuecount>0;stageloop++)
+                {
+                     lclcount[0]=0;
+                     barrier(CLK_LOCAL_MEM_FENCE);
+                     int2 stageinfo=*(global int2*)(stagecascadeptr+stageloop);
+                     float stagethreshold=as_float(stageinfo.y);
+                     int perfscale=queuecount>4?3:2;
+                     int queuecount_loop=(queuecount+(1<<perfscale)-1)>>perfscale;
+                     int lcl_compute_win=lcl_sz>>perfscale;
+                     int lcl_compute_win_id=(lcl_id>>(6-perfscale));
+                     int lcl_loops=(stageinfo.x+lcl_compute_win-1)>>(6-perfscale);
+                     int lcl_compute_id=lcl_id-(lcl_compute_win_id<<(6-perfscale));
+                     for(int queueloop=0;queueloop<queuecount_loop&&lcl_compute_win_id<queuecount;queueloop++)
+                     {
+                          float stage_sum=0.f;
+                          int temp_coord=lcloutindex[lcl_compute_win_id<<1];
+                          float variance_norm_factor=as_float(lcloutindex[(lcl_compute_win_id<<1)+1]);
+                          int queue_offset=mad24(((temp_coord&(int)0xffff0000)>>16),step,temp_coord&0xffff);
+                          int tempnodecounter=lcl_compute_id;
+                          float part_sum=0.f;
+                          for(int lcl_loop=0;lcl_loop<lcl_loops&&tempnodecounter<stageinfo.x;lcl_loop++)
+                          {
+                              __global  GpuHidHaarTreeNode* currentnodeptr = (nodeptr + nodecounter + tempnodecounter);
+                                                         int4 info1 = *(__global int4*)(&(currentnodeptr->p[0][0]));
+                                                         int4 info2 = *(__global int4*)(&(currentnodeptr->p[1][0]));
+                                                         int4 info3 = *(__global int4*)(&(currentnodeptr->p[2][0]));
+                                                         float4 w = *(__global float4*)(&(currentnodeptr->weight[0]));
+                                                         float2 alpha2 = *(__global float2*)(&(currentnodeptr->alpha[0]));
+                                                         float nodethreshold  = w.w * variance_norm_factor;
+                                                         info1.x +=queue_offset;
+                                                         info1.z +=queue_offset;
+                                                         info2.x +=queue_offset;
+                                                         info2.z +=queue_offset;
+                                                         float classsum = (sum[mad24(info1.y,step,info1.x)] - sum[mad24(info1.y,step,info1.z)] - 
+                                                               sum[mad24(info1.w,step,info1.x)] + sum[mad24(info1.w,step,info1.z)]) * w.x;
+                                                         classsum += (sum[mad24(info2.y,step,info2.x)] - sum[mad24(info2.y,step,info2.z)] - 
+                                                         sum[mad24(info2.w,step,info2.x)] + sum[mad24(info2.w,step,info2.z)]) * w.y;
+                       
+                                                         info3.x +=queue_offset;
+                                                         info3.z +=queue_offset;
+                                                         classsum += (sum[mad24(info3.y,step,info3.x)] - sum[mad24(info3.y,step,info3.z)] - 
+                                                                       sum[mad24(info3.w,step,info3.x)] + sum[mad24(info3.w,step,info3.z)]) * w.z;
+                                                         part_sum += classsum >= nodethreshold ? alpha2.y : alpha2.x;
+                                                         tempnodecounter+=lcl_compute_win;
+                         }
+                         partialsum[lcl_id]=part_sum;
+                         barrier(CLK_LOCAL_MEM_FENCE);  
+                         for(int i=0;i<lcl_compute_win&&(lcl_compute_id==0);i++)
+                         {
+                              stage_sum+=partialsum[lcl_id+i];
+                         } 
+                         if(stage_sum>=stagethreshold&&(lcl_compute_id==0))
+                         {
+                              int queueindex=atomic_inc(lclcount);
+                              lcloutindex[queueindex<<1]=temp_coord;
+                              lcloutindex[(queueindex<<1)+1]=as_int(variance_norm_factor);
+                         }
+                         lcl_compute_win_id+=(1<<perfscale);
+                         barrier(CLK_LOCAL_MEM_FENCE);
+                     }
+                     queuecount=lclcount[0];
+                     nodecounter+=stageinfo.x;
+                 }
+                 if(lcl_id<queuecount)
+                 {
+                     int temp=lcloutindex[lcl_id<<1];
+                     int x=temp&0xffff;
+                     int y=(temp&(int)0xffff0000)>>16;
+                     temp=glboutindex[0];
+                     int4 candidate_result;
+                     candidate_result.zw=(int2)convert_int_rtn(factor*20.f);
+                     candidate_result.x=x;
+                     candidate_result.y=y;
+                     atomic_inc(glboutindex);
+                     candidate[outputoff+temp+lcl_id]=candidate_result;
+                 }
+                 barrier(CLK_LOCAL_MEM_FENCE);
+                       }
+               }
+   }
+}
+__kernel void gpuscaleclassifier(global GpuHidHaarTreeNode * orinode, global GpuHidHaarTreeNode * newnode,float scale,float weight_scale,int nodenum)
+{
+    int counter=get_global_id(0);
+    int tr_x[3],tr_y[3],tr_h[3],tr_w[3],i=0;
+    GpuHidHaarTreeNode t1 = *(orinode + counter);
+    #pragma unroll
+    for(i=0;i<3;i++){
+       tr_x[i]=(int)(t1.p[i][0]*scale+0.5f);
+       tr_y[i]=(int)(t1.p[i][1]*scale+0.5f);
+       tr_w[i]=(int)(t1.p[i][2]*scale+0.5f);
+       tr_h[i]=(int)(t1.p[i][3]*scale+0.5f);
+    }
+    t1.weight[0]=t1.p[2][0]?-(t1.weight[1]*tr_h[1]*tr_w[1]+t1.weight[2]*tr_h[2]*tr_w[2])/(tr_h[0]*tr_w[0]):-t1.weight[1]*tr_h[1]*tr_w[1]/(tr_h[0]*tr_w[0]);
+   counter+=nodenum;
+   #pragma unroll
+   for(i=0;i<3;i++)
+   {
+         newnode[counter].p[i][0]=tr_x[i];
+         newnode[counter].p[i][1]=tr_y[i];
+         newnode[counter].p[i][2]=tr_x[i]+tr_w[i];
+         newnode[counter].p[i][3]=tr_y[i]+tr_h[i];
+         newnode[counter].weight[i]=t1.weight[i]*weight_scale;
+   }
+   newnode[counter].left=t1.left;
+   newnode[counter].right=t1.right;
+   newnode[counter].threshold=t1.threshold;
+   newnode[counter].alpha[0]=t1.alpha[0];
+   newnode[counter].alpha[1]=t1.alpha[1];
+}
+
diff --git a/modules/ocl/src/kernels/img_proc.cl b/modules/ocl/src/kernels/img_proc.cl
new file mode 100644 (file)
index 0000000..5d2a70b
--- /dev/null
@@ -0,0 +1,1331 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Shengen Yan,yanshengen@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 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*/
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+//wrapAffine kernel
+//support four data types: CV_8U, CV_16U, CV_32S, CV_32F, and three interpolation methods: NN, Linear, Cubic.
+
+#define INTER_BITS 5
+#define INTER_TAB_SIZE (1 << INTER_BITS)
+#define AB_BITS max(10, (int)INTER_BITS) 
+#define AB_SCALE (1 << AB_BITS) 
+#define INTER_REMAP_COEF_BITS 15
+#define INTER_REMAP_COEF_SCALE (1 << INTER_REMAP_COEF_BITS)
+
+//this round operation is to approximate CPU's saturate_cast<int>
+int round2_int(double v)
+{
+    int v1=(int)v;
+    if(((v-v1)==0.5 || (v1-v)==0.5) && (v1%2)==0)
+        return v1;
+    else
+        return convert_int_sat(v+(v>=0 ? 0.5 : -0.5));
+}
+
+inline void interpolateCubic( float x, float* coeffs )
+{
+    const float A = -0.75f;
+
+    coeffs[0] = ((A*(x + 1) - 5*A)*(x + 1) + 8*A)*(x + 1) - 4*A;
+    coeffs[1] = ((A + 2)*x - (A + 3))*x*x + 1;
+    coeffs[2] = ((A + 2)*(1 - x) - (A + 3))*(1 - x)*(1 - x) + 1;
+    coeffs[3] = 1.f - coeffs[0] - coeffs[1] - coeffs[2];
+}
+
+__kernel void warpAffine_8u_NN(__global uchar * src, __global uchar * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    int round_delta = AB_SCALE/2;
+    
+    int X0 = round2_int(M[0] * dx * AB_SCALE);
+    int Y0 = round2_int(M[3] * dx * AB_SCALE);
+    X0 += round2_int((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += round2_int((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+
+    short sx = (short)(X0 >> AB_BITS);
+    short sy = (short)(Y0 >> AB_BITS);
+    for(int c = 0; c < cn; c++)
+        dst[dy*dstStep+dx*cn+c] = (sx >= 0 && sx < cols && sy >= 0 && sy < rows) ? src[sy*srcStep+sx*cn+c] : 0; 
+}
+
+__kernel void warpAffine_8u_Linear(__global uchar * src, __global uchar * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    int round_delta = AB_SCALE/INTER_TAB_SIZE/2;
+    
+    int X0 = round2_int(M[0] * dx * AB_SCALE);
+    int Y0 = round2_int(M[3] * dx * AB_SCALE);
+    X0 += round2_int((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += round2_int((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+    int X = X0 >> (AB_BITS - INTER_BITS);
+    int Y = Y0 >> (AB_BITS - INTER_BITS);
+
+    short sx = (short)(X >> INTER_BITS);
+    short sy = (short)(Y >> INTER_BITS);
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+    
+    int v[16];
+    int i, j, c;
+
+    for(i=0; i<2;  i++)
+        for(j=0; j<2; j++)
+            for(c=0; c<cn; c++)
+                v[i*2*cn + j*cn + c] = (sx+j >= 0 && sx+j < cols && sy+i >= 0 && sy+i < rows) ? src[(sy+i) * srcStep + (sx+j)*cn + c] : 0;
+   
+    short itab[4];
+    float tab1y[2], tab1x[2];
+    tab1y[0] = 1.0 - 1.f/INTER_TAB_SIZE*ay;
+    tab1y[1] = 1.f/INTER_TAB_SIZE*ay;
+    tab1x[0] = 1.0 - 1.f/INTER_TAB_SIZE*ax;
+    tab1x[1] = 1.f/INTER_TAB_SIZE*ax;
+    
+    for( i=0; i<2; i++ )
+    {
+        for( j=0; j<2; j++)
+        {
+            float v = tab1y[i] * tab1x[j];
+            itab[i*2+j] = convert_short_sat(round2_int( v * INTER_REMAP_COEF_SCALE ));
+        }
+    }
+    if( sx+1 < 0 || sx >= cols || sy+1 < 0 || sy >= rows)
+    {
+        for(c = 0; c < cn; c++)
+            dst[dy*dstStep+dx*cn+c] = 0;
+    }
+    else
+    {
+        int sum;
+        for(c = 0; c < cn; c++)
+        {
+            sum = 0;
+            for ( i =0; i<4; i++ )
+            {
+                sum += v[i*cn+c] * itab[i] ;
+            }
+            dst[dy*dstStep+dx*cn+c] = convert_uchar_sat ( ((int)sum + (1 << (INTER_REMAP_COEF_BITS-1))) >> INTER_REMAP_COEF_BITS ) ;
+        }
+    }
+}
+
+__kernel void warpAffine_8u_Cubic(__global uchar * src, __global uchar * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    int round_delta = AB_SCALE/INTER_TAB_SIZE/2;
+    
+    int X0 = round2_int(M[0] * dx * AB_SCALE);
+    int Y0 = round2_int(M[3] * dx * AB_SCALE);
+    X0 += round2_int((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += round2_int((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+    int X = X0 >> (AB_BITS - INTER_BITS);
+    int Y = Y0 >> (AB_BITS - INTER_BITS);
+
+    short sx = (short)(X >> INTER_BITS) - 1;
+    short sy = (short)(Y >> INTER_BITS) - 1;
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+    
+    uchar v[64];
+    int i, j, c;
+
+    for(i=0; i<4;  i++)
+        for(j=0; j<4; j++)
+            for(c=0; c<cn; c++)
+                v[i*4*cn + j*cn + c] = (sx+j >= 0 && sx+j < cols && sy+i >= 0 && sy+i < rows) ? src[(sy+i) * srcStep + (sx+j)*cn + c] : 0;
+   
+    short itab[16];
+    float tab1y[4], tab1x[4];
+    float axx, ayy;
+
+    ayy = 1.f/INTER_TAB_SIZE * ay;
+    axx = 1.f/INTER_TAB_SIZE * ax;
+    interpolateCubic(ayy, tab1y);
+    interpolateCubic(axx, tab1x);
+    int isum = 0;
+    for( i=0; i<4; i++ )
+    {
+        for( j=0; j<4; j++)
+        {
+            double v = tab1y[i] * tab1x[j];
+            isum += itab[i*4+j] = convert_short_sat( round2_int( v * INTER_REMAP_COEF_SCALE ) );
+        }
+    }
+    if( isum != INTER_REMAP_COEF_SCALE )
+    {
+        int k1, k2, ksize = 4;
+        int diff = isum - INTER_REMAP_COEF_SCALE;
+        int ksize2 = ksize/2, Mk1=ksize2, Mk2=ksize2, mk1=ksize2, mk2=ksize2;
+        for( k1 = ksize2; k1 < ksize2+2; k1++ )
+            for( k2 = ksize2; k2 < ksize2+2; k2++ )
+            {
+                if( itab[k1*ksize+k2] < itab[mk1*ksize+mk2] )
+                    mk1 = k1, mk2 = k2;
+                else if( itab[k1*ksize+k2] > itab[Mk1*ksize+Mk2] )
+                     Mk1 = k1, Mk2 = k2;
+            }
+            if( diff < 0 )
+                itab[Mk1*ksize + Mk2] = (short)(itab[Mk1*ksize + Mk2] - diff);
+            else
+                itab[mk1*ksize + mk2] = (short)(itab[mk1*ksize + mk2] - diff);
+    }
+
+    if( sx+4 < 0 || sx >= cols || sy+4 < 0 || sy >= rows)
+    {
+        for(c = 0; c < cn; c++)
+            dst[dy*dstStep+dx*cn+c] = 0;
+    }
+    else
+    {
+        int sum;
+        for(c = 0; c < cn; c++)
+        {
+            sum = 0;
+            for ( i =0; i<16; i++ )
+            {
+                sum += v[i*cn+c] * itab[i] ;
+            }
+            dst[dy*dstStep+dx*cn+c] = convert_uchar_sat( (int)(sum + (1 << (INTER_REMAP_COEF_BITS-1))) >> INTER_REMAP_COEF_BITS ) ;
+        }
+    }
+}
+
+__kernel void warpAffine_16u_NN(__global ushort * src, __global ushort * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    int round_delta = AB_SCALE/2;
+    
+    int X0 = round2_int(M[0] * dx * AB_SCALE);
+    int Y0 = round2_int(M[3] * dx * AB_SCALE);
+    X0 += round2_int((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += round2_int((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+
+    short sx = (short)(X0 >> AB_BITS);
+    short sy = (short)(Y0 >> AB_BITS);
+    for(int c = 0; c < cn; c++)
+        dst[dy*dstStep+dx*cn+c] = (sx >= 0 && sx < cols && sy >= 0 && sy < rows) ? src[sy*srcStep+sx*cn+c] : 0; 
+}
+
+__kernel void warpAffine_16u_Linear(__global ushort * src, __global ushort * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    int round_delta = AB_SCALE/INTER_TAB_SIZE/2;
+    
+    int X0 = round2_int(M[0] * dx * AB_SCALE);
+    int Y0 = round2_int(M[3] * dx * AB_SCALE);
+    X0 += round2_int((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += round2_int((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+    int X = X0 >> (AB_BITS - INTER_BITS);
+    int Y = Y0 >> (AB_BITS - INTER_BITS);
+
+    short sx = (short)(X >> INTER_BITS);
+    short sy = (short)(Y >> INTER_BITS);
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+    
+    ushort v[16];
+    int i, j, c;
+
+    for(i=0; i<2;  i++)
+        for(j=0; j<2; j++)
+            for(c=0; c<cn; c++)
+                v[i*2*cn + j*cn + c] = (sx+j >= 0 && sx+j < cols && sy+i >= 0 && sy+i < rows) ? src[(sy+i) * srcStep + (sx+j)*cn + c] : 0;
+   
+    float tab[4];
+    float tab1y[2], tab1x[2];
+    tab1y[0] = 1.0 - 1.f/INTER_TAB_SIZE*ay;
+    tab1y[1] = 1.f/INTER_TAB_SIZE*ay;
+    tab1x[0] = 1.0 - 1.f/INTER_TAB_SIZE*ax;
+    tab1x[1] = 1.f/INTER_TAB_SIZE*ax;
+    
+    for( i=0; i<2; i++ )
+    {
+        for( j=0; j<2; j++)
+        {
+            tab[i*2+j] = tab1y[i] * tab1x[j];
+        }
+    }
+    if( sx+1 < 0 || sx >= cols || sy+1 < 0 || sy >= rows)
+    {
+        for(c = 0; c < cn; c++)
+            dst[dy*dstStep+dx*cn+c] = 0;
+    }
+    else
+    {
+        float sum;
+        for(c = 0; c < cn; c++)
+        {
+            sum = 0;
+            for ( i =0; i<4; i++ )
+            {
+                sum += v[i*cn+c] * tab[i] ;
+            }
+            dst[dy*dstStep+dx*cn+c] = convert_ushort_sat( round2_int(sum) ) ;
+        }
+    }
+}
+
+__kernel void warpAffine_16u_Cubic(__global ushort * src, __global ushort * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    int round_delta = AB_SCALE/INTER_TAB_SIZE/2;
+    
+    int X0 = round2_int(M[0] * dx * AB_SCALE);
+    int Y0 = round2_int(M[3] * dx * AB_SCALE);
+    X0 += round2_int((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += round2_int((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+    int X = X0 >> (AB_BITS - INTER_BITS);
+    int Y = Y0 >> (AB_BITS - INTER_BITS);
+
+    short sx = (short)(X >> INTER_BITS) - 1;
+    short sy = (short)(Y >> INTER_BITS) - 1;
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+    
+    ushort v[64];
+    int i, j, c;
+
+    for(i=0; i<4;  i++)
+        for(j=0; j<4; j++)
+            for(c=0; c<cn; c++)
+                v[i*4*cn + j*cn + c] = (sx+j >= 0 && sx+j < cols && sy+i >= 0 && sy+i < rows) ? src[(sy+i) * srcStep + (sx+j)*cn + c] : 0;
+   
+    float tab[16];
+    float tab1y[4], tab1x[4];
+    float axx, ayy;
+
+    ayy = 1.f/INTER_TAB_SIZE * ay;
+    axx = 1.f/INTER_TAB_SIZE * ax;
+    interpolateCubic(ayy, tab1y);
+    interpolateCubic(axx, tab1x);
+    for( i=0; i<4; i++ )
+    {
+        for( j=0; j<4; j++)
+        {
+            tab[i*4+j] = tab1y[i] * tab1x[j];
+        }
+    }
+
+    int width = cols-3>0 ? cols-3 : 0;
+    int height = rows-3>0 ? rows-3 : 0;
+    if((unsigned)sx < width && (unsigned)sy < height )
+    {
+        float sum;
+        for(c = 0; c < cn; c++)
+        {
+            sum = 0;
+            for ( i =0; i<4; i++ )
+            {
+                    sum += v[i*4*cn+c] * tab[i*4] + v[i*4*cn+c+1]*tab[i*4+1]
+                          +v[i*4*cn+c+2] * tab[i*4+2] + v[i*4*cn+c+3]*tab[i*4+3];
+            }
+            dst[dy*dstStep+dx*cn+c] = convert_ushort_sat( round2_int(sum ));
+        }
+    }
+    else if( sx+4 < 0 || sx >= cols || sy+4 < 0 || sy >= rows)
+    {
+        for(c = 0; c < cn; c++)
+            dst[dy*dstStep+dx*cn+c] = 0;
+    }
+    else
+    {
+        float sum;
+        for(c = 0; c < cn; c++)
+        {
+            sum = 0;
+            for ( i =0; i<16; i++ )
+            {
+                    sum += v[i*cn+c] * tab[i];
+            }
+            dst[dy*dstStep+dx*cn+c] = convert_ushort_sat( round2_int(sum ));
+        }
+    }
+}
+
+
+__kernel void warpAffine_32s_NN(__global int * src, __global int * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    int round_delta = AB_SCALE/2;
+    
+    int X0 = round2_int(M[0] * dx * AB_SCALE);
+    int Y0 = round2_int(M[3] * dx * AB_SCALE);
+    X0 += round2_int((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += round2_int((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+
+    short sx = (short)(X0 >> AB_BITS);
+    short sy = (short)(Y0 >> AB_BITS);
+    for(int c = 0; c < cn; c++)
+        dst[dy*dstStep+dx*cn+c] = (sx >= 0 && sx < cols && sy >= 0 && sy < rows) ? src[sy*srcStep+sx*cn+c] : 0; 
+}
+
+__kernel void warpAffine_32s_Linear(__global int * src, __global int * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    int round_delta = AB_SCALE/INTER_TAB_SIZE/2;
+    
+    int X0 = round2_int(M[0] * dx * AB_SCALE);
+    int Y0 = round2_int(M[3] * dx * AB_SCALE);
+    X0 += round2_int((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += round2_int((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+    int X = X0 >> (AB_BITS - INTER_BITS);
+    int Y = Y0 >> (AB_BITS - INTER_BITS);
+
+    short sx = (short)(X >> INTER_BITS);
+    short sy = (short)(Y >> INTER_BITS);
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+    
+    int v[16];
+    int i, j, c;
+
+    for(i=0; i<2;  i++)
+        for(j=0; j<2; j++)
+            for(c=0; c<cn; c++)
+                v[i*2*cn + j*cn + c] = (sx+j >= 0 && sx+j < cols && sy+i >= 0 && sy+i < rows) ? src[(sy+i) * srcStep + (sx+j)*cn + c] : 0;
+   
+    float tab[4];
+    float tab1y[2], tab1x[2];
+    tab1y[0] = 1.0 - 1.f/INTER_TAB_SIZE*ay;
+    tab1y[1] = 1.f/INTER_TAB_SIZE*ay;
+    tab1x[0] = 1.0 - 1.f/INTER_TAB_SIZE*ax;
+    tab1x[1] = 1.f/INTER_TAB_SIZE*ax;
+    
+    for( i=0; i<2; i++ )
+    {
+        for( j=0; j<2; j++)
+        {
+            tab[i*2+j] = tab1y[i] * tab1x[j];
+        }
+    }
+    if( sx+1 < 0 || sx >= cols || sy+1 < 0 || sy >= rows)
+    {
+        for(c = 0; c < cn; c++)
+            dst[dy*dstStep+dx*cn+c] = 0;
+    }
+    else
+    {
+        float sum;
+        for(c = 0; c < cn; c++)
+        {
+            sum = 0;
+            for ( i =0; i<4; i++ )
+            {
+                sum += v[i*cn+c] * tab[i] ;
+            }
+            dst[dy*dstStep+dx*cn+c] = convert_int_sat( round2_int(sum) ) ;
+        }
+    }
+}
+
+__kernel void warpAffine_32s_Cubic(__global int * src, __global int * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    int round_delta = AB_SCALE/INTER_TAB_SIZE/2;
+    
+    int X0 = round2_int(M[0] * dx * AB_SCALE);
+    int Y0 = round2_int(M[3] * dx * AB_SCALE);
+    X0 += round2_int((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += round2_int((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+    int X = X0 >> (AB_BITS - INTER_BITS);
+    int Y = Y0 >> (AB_BITS - INTER_BITS);
+
+    short sx = (short)(X >> INTER_BITS) - 1;
+    short sy = (short)(Y >> INTER_BITS) - 1;
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+    
+    int v[64];
+    int i, j, c;
+
+    for(i=0; i<4;  i++)
+        for(j=0; j<4; j++)
+            for(c=0; c<cn; c++)
+                v[i*4*cn + j*cn + c] = (sx+j >= 0 && sx+j < cols && sy+i >= 0 && sy+i < rows) ? src[(sy+i) * srcStep + (sx+j)*cn + c] : 0;
+   
+    float tab[16];
+    float tab1y[4], tab1x[4];
+    float axx, ayy;
+
+    ayy = 1.f/INTER_TAB_SIZE * ay;
+    axx = 1.f/INTER_TAB_SIZE * ax;
+    interpolateCubic(ayy, tab1y);
+    interpolateCubic(axx, tab1x);
+    for( i=0; i<4; i++ )
+    {
+        for( j=0; j<4; j++)
+        {
+            tab[i*4+j] = tab1y[i] * tab1x[j];
+        }
+    }
+
+    if( sx+4 < 0 || sx >= cols || sy+4 < 0 || sy >= rows)
+    {
+        for(c = 0; c < cn; c++)
+            dst[dy*dstStep+dx*cn+c] = 0;
+    }
+    else
+    {
+        float sum;
+        for(c = 0; c < cn; c++)
+        {
+            sum = 0;
+            for ( i =0; i<16; i++ )
+            {
+                sum += v[i*cn+c] * tab[i] ;
+            }
+            dst[dy*dstStep+dx*cn+c] = convert_int_sat( round2_int(sum ));
+        }
+    }
+}
+
+
+__kernel void warpAffine_32f_NN(__global float * src, __global float * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    int round_delta = AB_SCALE/2;
+    
+    int X0 = round2_int(M[0] * dx * AB_SCALE);
+    int Y0 = round2_int(M[3] * dx * AB_SCALE);
+    X0 += round2_int((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += round2_int((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+
+    short sx = (short)(X0 >> AB_BITS);
+    short sy = (short)(Y0 >> AB_BITS);
+    for(int c = 0; c < cn; c++)
+        dst[dy*dstStep+dx*cn+c] = (sx >= 0 && sx < cols && sy >= 0 && sy < rows) ? src[sy*srcStep+sx*cn+c] : 0; 
+}
+
+__kernel void warpAffine_32f_Linear(__global float * src, __global float * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    int round_delta = AB_SCALE/INTER_TAB_SIZE/2;
+    
+    int X0 = round2_int(M[0] * dx * AB_SCALE);
+    int Y0 = round2_int(M[3] * dx * AB_SCALE);
+    X0 += round2_int((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += round2_int((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+    int X = X0 >> (AB_BITS - INTER_BITS);
+    int Y = Y0 >> (AB_BITS - INTER_BITS);
+
+    short sx = (short)(X >> INTER_BITS);
+    short sy = (short)(Y >> INTER_BITS);
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+    
+    float v[16];
+    int i, j, c;
+
+    for(i=0; i<2;  i++)
+        for(j=0; j<2; j++)
+            for(c=0; c<cn; c++)
+                v[i*2*cn + j*cn + c] = (sx+j >= 0 && sx+j < cols && sy+i >= 0 && sy+i < rows) ? src[(sy+i) * srcStep + (sx+j)*cn + c] : 0;
+   
+    float tab[4];
+    float tab1y[2], tab1x[2];
+    tab1y[0] = 1.0 - 1.f/INTER_TAB_SIZE*ay;
+    tab1y[1] = 1.f/INTER_TAB_SIZE*ay;
+    tab1x[0] = 1.0 - 1.f/INTER_TAB_SIZE*ax;
+    tab1x[1] = 1.f/INTER_TAB_SIZE*ax;
+    
+    for( i=0; i<2; i++ )
+    {
+        for( j=0; j<2; j++)
+        {
+            tab[i*2+j] = tab1y[i] * tab1x[j];
+        }
+    }
+    if( sx+1 < 0 || sx >= cols || sy+1 < 0 || sy >= rows)
+    {
+        for(c = 0; c < cn; c++)
+            dst[dy*dstStep+dx*cn+c] = 0;
+    }
+    else
+    {
+        float sum;
+        for(c = 0; c < cn; c++)
+        {
+            sum = 0;
+            for ( i =0; i<4; i++ )
+            {
+                sum += v[i*cn+c] * tab[i] ;
+            }
+            dst[dy*dstStep+dx*cn+c] = sum ;
+        }
+    }
+}
+
+__kernel void warpAffine_32f_Cubic(__global float * src, __global float * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    int round_delta = AB_SCALE/INTER_TAB_SIZE/2;
+    
+    int X0 = round2_int(M[0] * dx * AB_SCALE);
+    int Y0 = round2_int(M[3] * dx * AB_SCALE);
+    X0 += round2_int((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += round2_int((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+    int X = X0 >> (AB_BITS - INTER_BITS);
+    int Y = Y0 >> (AB_BITS - INTER_BITS);
+
+    short sx = (short)(X >> INTER_BITS) - 1;
+    short sy = (short)(Y >> INTER_BITS) - 1;
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+    
+    float v[64];
+    int i, j, c;
+
+    for(i=0; i<4;  i++)
+        for(j=0; j<4; j++)
+            for(c=0; c<cn; c++)
+                v[i*4*cn + j*cn + c] = (sx+j >= 0 && sx+j < cols && sy+i >= 0 && sy+i < rows) ? src[(sy+i) * srcStep + (sx+j)*cn + c] : 0;
+   
+    float tab[16];
+    float tab1y[4], tab1x[4];
+    float axx, ayy;
+
+    ayy = 1.f/INTER_TAB_SIZE * ay;
+    axx = 1.f/INTER_TAB_SIZE * ax;
+    interpolateCubic(ayy, tab1y);
+    interpolateCubic(axx, tab1x);
+    for( i=0; i<4; i++ )
+    {
+        for( j=0; j<4; j++)
+        {
+            tab[i*4+j] = tab1y[i] * tab1x[j];
+        }
+    }
+    int width = cols-3>0 ? cols-3 : 0;
+    int height = rows-3>0 ? rows-3 : 0;
+    if((unsigned)sx < width && (unsigned)sy < height )
+    {
+        float sum;
+        for(c = 0; c < cn; c++)
+        {
+            sum = 0;
+            for ( i =0; i<4; i++ )
+            {
+                    sum += v[i*4*cn+c] * tab[i*4] + v[i*4*cn+c+1]*tab[i*4+1]
+                          +v[i*4*cn+c+2] * tab[i*4+2] + v[i*4*cn+c+3]*tab[i*4+3];
+            }
+            dst[dy*dstStep+dx*cn+c] = sum;
+        }
+    }
+    else if( sx+4 < 0 || sx >= cols || sy+4 < 0 || sy >= rows)
+    {
+        for(c = 0; c < cn; c++)
+            dst[dy*dstStep+dx*cn+c] = 0;
+    }
+    else
+    {
+        float sum;
+        for(c = 0; c < cn; c++)
+        {
+            sum = 0;
+            for ( i =0; i<16; i++ )
+            {
+                    sum += v[i*cn+c] * tab[i];
+            }
+            dst[dy*dstStep+dx*cn+c] = sum;
+        }
+    }
+}
+
+__kernel void warpPerspective_8u_NN(__global uchar * src, __global uchar * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    double X0 = M[0]*dx + M[1]*dy + M[2];
+    double Y0 = M[3]*dx + M[4]*dy + M[5];
+    double W = M[6]*dx + M[7]*dy + M[8];
+    W = W ? 1./W : 0;
+    int X = round2_int(X0*W);
+    int Y = round2_int(Y0*W);
+    short sx = (short)X;
+    short sy = (short)Y;
+
+    for(int c = 0; c < cn; c++)
+        dst[dy*dstStep+dx*cn+c] = (sx >= 0 && sx < cols && sy >= 0 && sy < rows) ? src[sy*srcStep+sx*cn+c] : 0; 
+}
+
+__kernel void warpPerspective_8u_Linear(__global uchar * src, __global uchar * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    double X0 = M[0]*dx + M[1]*dy + M[2];
+    double Y0 = M[3]*dx + M[4]*dy + M[5];
+    double W = M[6]*dx + M[7]*dy + M[8];
+    W = W ? INTER_TAB_SIZE/W : 0;
+    int X = round2_int(X0*W);
+    int Y = round2_int(Y0*W);
+    
+    short sx = (short)(X >> INTER_BITS);
+    short sy = (short)(Y >> INTER_BITS);
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+    
+    uchar v[16];
+    int i, j, c;
+
+    for(i=0; i<2;  i++)
+        for(j=0; j<2; j++)
+            for(c=0; c<cn; c++)
+                v[i*2*cn + j*cn + c] = (sx+j >= 0 && sx+j < cols && sy+i >= 0 && sy+i < rows) ? src[(sy+i) * srcStep + (sx+j)*cn + c] : 0;
+   
+    short itab[4];
+    float tab1y[2], tab1x[2];
+    tab1y[0] = 1.0 - 1.f/INTER_TAB_SIZE*ay;
+    tab1y[1] = 1.f/INTER_TAB_SIZE*ay;
+    tab1x[0] = 1.0 - 1.f/INTER_TAB_SIZE*ax;
+    tab1x[1] = 1.f/INTER_TAB_SIZE*ax;
+    
+    for( i=0; i<2; i++ )
+    {
+        for( j=0; j<2; j++)
+        {
+            float v = tab1y[i] * tab1x[j];
+            itab[i*2+j] = convert_short_sat(round2_int( v * INTER_REMAP_COEF_SCALE ));
+        }
+    }
+    if( sx+1 < 0 || sx >= cols || sy+1 < 0 || sy >= rows)
+    {
+        for(c = 0; c < cn; c++)
+            dst[dy*dstStep+dx*cn+c] = 0;
+    }
+    else
+    {
+        int sum;
+        for(c = 0; c < cn; c++)
+        {
+            sum = 0;
+            for ( i =0; i<4; i++ )
+            {
+                sum += v[i*cn+c] * itab[i] ;
+            }
+            dst[dy*dstStep+dx*cn+c] = convert_uchar_sat ( round2_int(sum + (1 << (INTER_REMAP_COEF_BITS-1))) >> INTER_REMAP_COEF_BITS ) ;
+        }
+    }
+}
+
+__kernel void warpPerspective_8u_Cubic(__global uchar * src, __global uchar * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    double X0 = M[0]*dx + M[1]*dy + M[2];
+    double Y0 = M[3]*dx + M[4]*dy + M[5];
+    double W = M[6]*dx + M[7]*dy + M[8];
+    W = W ? INTER_TAB_SIZE/W : 0;
+    int X = round2_int(X0*W);
+    int Y = round2_int(Y0*W);
+    
+    short sx = (short)(X >> INTER_BITS) - 1;
+    short sy = (short)(Y >> INTER_BITS) - 1;
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+    
+    uchar v[64];
+    int i, j, c;
+
+    for(i=0; i<4;  i++)
+        for(j=0; j<4; j++)
+            for(c=0; c<cn; c++)
+                v[i*4*cn + j*cn + c] = (sx+j >= 0 && sx+j < cols && sy+i >= 0 && sy+i < rows) ? src[(sy+i) * srcStep + (sx+j)*cn + c] : 0;
+   
+    short itab[16];
+    float tab1y[4], tab1x[4];
+    float axx, ayy;
+
+    ayy = 1.f/INTER_TAB_SIZE * ay;
+    axx = 1.f/INTER_TAB_SIZE * ax;
+    interpolateCubic(ayy, tab1y);
+    interpolateCubic(axx, tab1x);
+    int isum = 0;
+    for( i=0; i<4; i++ )
+    {
+        for( j=0; j<4; j++)
+        {
+            double v = tab1y[i] * tab1x[j];
+            isum += itab[i*4+j] = convert_short_sat( round2_int( v * INTER_REMAP_COEF_SCALE ) );
+        }
+    }
+    if( isum != INTER_REMAP_COEF_SCALE )
+    {
+        int k1, k2, ksize = 4;
+        int diff = isum - INTER_REMAP_COEF_SCALE;
+        int ksize2 = ksize/2, Mk1=ksize2, Mk2=ksize2, mk1=ksize2, mk2=ksize2;
+        for( k1 = ksize2; k1 < ksize2+2; k1++ )
+            for( k2 = ksize2; k2 < ksize2+2; k2++ )
+            {
+                if( itab[k1*ksize+k2] < itab[mk1*ksize+mk2] )
+                    mk1 = k1, mk2 = k2;
+                else if( itab[k1*ksize+k2] > itab[Mk1*ksize+Mk2] )
+                     Mk1 = k1, Mk2 = k2;
+            }
+            if( diff < 0 )
+                itab[Mk1*ksize + Mk2] = (short)(itab[Mk1*ksize + Mk2] - diff);
+            else
+                itab[mk1*ksize + mk2] = (short)(itab[mk1*ksize + mk2] - diff);
+    }
+
+    if( sx+4 < 0 || sx >= cols || sy+4 < 0 || sy >= rows)
+    {
+        for(c = 0; c < cn; c++)
+            dst[dy*dstStep+dx*cn+c] = 0;
+    }
+    else
+    {
+        int sum;
+        for(c = 0; c < cn; c++)
+        {
+            sum = 0;
+            for ( i =0; i<16; i++ )
+            {
+                sum += v[i*cn+c] * itab[i] ;
+            }
+            dst[dy*dstStep+dx*cn+c] = convert_uchar_sat( round2_int(sum + (1 << (INTER_REMAP_COEF_BITS-1))) >> INTER_REMAP_COEF_BITS ) ;
+        }
+    }
+}
+
+__kernel void warpPerspective_16u_NN(__global ushort * src, __global ushort * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    double X0 = M[0]*dx + M[1]*dy + M[2];
+    double Y0 = M[3]*dx + M[4]*dy + M[5];
+    double W = M[6]*dx + M[7]*dy + M[8];
+    W = W ? 1./W : 0;
+    int X = round2_int(X0*W);
+    int Y = round2_int(Y0*W);
+    short sx = (short)X;
+    short sy = (short)Y;
+
+    for(int c = 0; c < cn; c++)
+        dst[dy*dstStep+dx*cn+c] = (sx >= 0 && sx < cols && sy >= 0 && sy < rows) ? src[sy*srcStep+sx*cn+c] : 0; 
+}
+
+__kernel void warpPerspective_16u_Linear(__global ushort * src, __global ushort * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    double X0 = M[0]*dx + M[1]*dy + M[2];
+    double Y0 = M[3]*dx + M[4]*dy + M[5];
+    double W = M[6]*dx + M[7]*dy + M[8];
+    W = W ? INTER_TAB_SIZE/W : 0;
+    int X = round2_int(X0*W);
+    int Y = round2_int(Y0*W);
+    
+    short sx = (short)(X >> INTER_BITS);
+    short sy = (short)(Y >> INTER_BITS);
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+    
+    ushort v[16];
+    int i, j, c;
+
+    for(i=0; i<2;  i++)
+        for(j=0; j<2; j++)
+            for(c=0; c<cn; c++)
+                v[i*2*cn + j*cn + c] = (sx+j >= 0 && sx+j < cols && sy+i >= 0 && sy+i < rows) ? src[(sy+i) * srcStep + (sx+j)*cn + c] : 0;
+   
+    float tab[4];
+    float tab1y[2], tab1x[2];
+    tab1y[0] = 1.0 - 1.f/INTER_TAB_SIZE*ay;
+    tab1y[1] = 1.f/INTER_TAB_SIZE*ay;
+    tab1x[0] = 1.0 - 1.f/INTER_TAB_SIZE*ax;
+    tab1x[1] = 1.f/INTER_TAB_SIZE*ax;
+    
+    for( i=0; i<2; i++ )
+    {
+        for( j=0; j<2; j++)
+        {
+            tab[i*2+j] = tab1y[i] * tab1x[j];
+        }
+    }
+    if( sx+1 < 0 || sx >= cols || sy+1 < 0 || sy >= rows)
+    {
+        for(c = 0; c < cn; c++)
+            dst[dy*dstStep+dx*cn+c] = 0;
+    }
+    else
+    {
+        float sum;
+        for(c = 0; c < cn; c++)
+        {
+            sum = 0;
+            for ( i =0; i<4; i++ )
+            {
+                sum += v[i*cn+c] * tab[i] ;
+            }
+            dst[dy*dstStep+dx*cn+c] = convert_ushort_sat( round2_int(sum) ) ;
+        }
+    }
+}
+
+__kernel void warpPerspective_16u_Cubic(__global ushort * src, __global ushort * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    double X0 = M[0]*dx + M[1]*dy + M[2];
+    double Y0 = M[3]*dx + M[4]*dy + M[5];
+    double W = M[6]*dx + M[7]*dy + M[8];
+    W = W ? INTER_TAB_SIZE/W : 0;
+    int X = round2_int(X0*W);
+    int Y = round2_int(Y0*W);
+    
+    short sx = (short)(X >> INTER_BITS) - 1;
+    short sy = (short)(Y >> INTER_BITS) - 1;
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+    
+    ushort v[64];
+    int i, j, c;
+
+    for(i=0; i<4;  i++)
+        for(j=0; j<4; j++)
+            for(c=0; c<cn; c++)
+                v[i*4*cn + j*cn + c] = (sx+j >= 0 && sx+j < cols && sy+i >= 0 && sy+i < rows) ? src[(sy+i) * srcStep + (sx+j)*cn + c] : 0;
+   
+    float tab[16];
+    float tab1y[4], tab1x[4];
+    float axx, ayy;
+
+    ayy = 1.f/INTER_TAB_SIZE * ay;
+    axx = 1.f/INTER_TAB_SIZE * ax;
+    interpolateCubic(ayy, tab1y);
+    interpolateCubic(axx, tab1x);
+    for( i=0; i<4; i++ )
+    {
+        for( j=0; j<4; j++)
+        {
+            tab[i*4+j] = tab1y[i] * tab1x[j];
+        }
+    }
+
+    int width = cols-3>0 ? cols-3 : 0;
+    int height = rows-3>0 ? rows-3 : 0;
+    if((unsigned)sx < width && (unsigned)sy < height )
+    {
+        float sum;
+        for(c = 0; c < cn; c++)
+        {
+            sum = 0;
+            for ( i =0; i<4; i++ )
+            {
+                    sum += v[i*4*cn+c] * tab[i*4] + v[i*4*cn+c+1]*tab[i*4+1]
+                          +v[i*4*cn+c+2] * tab[i*4+2] + v[i*4*cn+c+3]*tab[i*4+3];
+            }
+            dst[dy*dstStep+dx*cn+c] = convert_ushort_sat( round2_int(sum ));
+        }
+    }
+    else if( sx+4 < 0 || sx >= cols || sy+4 < 0 || sy >= rows)
+    {
+        for(c = 0; c < cn; c++)
+            dst[dy*dstStep+dx*cn+c] = 0;
+    }
+    else
+    {
+        float sum;
+        for(c = 0; c < cn; c++)
+        {
+            sum = 0;
+            for ( i =0; i<16; i++ )
+            {
+                    sum += v[i*cn+c] * tab[i];
+            }
+            dst[dy*dstStep+dx*cn+c] = convert_ushort_sat( round2_int(sum ));
+        }
+    }
+}
+
+
+__kernel void warpPerspective_32s_NN(__global int * src, __global int * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    double X0 = M[0]*dx + M[1]*dy + M[2];
+    double Y0 = M[3]*dx + M[4]*dy + M[5];
+    double W = M[6]*dx + M[7]*dy + M[8];
+    W = W ? 1./W : 0;
+    int X = round2_int(X0*W);
+    int Y = round2_int(Y0*W);
+    short sx = (short)X;
+    short sy = (short)Y;
+
+    for(int c = 0; c < cn; c++)
+        dst[dy*dstStep+dx*cn+c] = (sx >= 0 && sx < cols && sy >= 0 && sy < rows) ? src[sy*srcStep+sx*cn+c] : 0; 
+}
+
+__kernel void warpPerspective_32s_Linear(__global int * src, __global int * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    double X0 = M[0]*dx + M[1]*dy + M[2];
+    double Y0 = M[3]*dx + M[4]*dy + M[5];
+    double W = M[6]*dx + M[7]*dy + M[8];
+    W = W ? INTER_TAB_SIZE/W : 0;
+    int X = round2_int(X0*W);
+    int Y = round2_int(Y0*W);
+    
+    short sx = (short)(X >> INTER_BITS);
+    short sy = (short)(Y >> INTER_BITS);
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+    
+    int v[16];
+    int i, j, c;
+
+    for(i=0; i<2;  i++)
+        for(j=0; j<2; j++)
+            for(c=0; c<cn; c++)
+                v[i*2*cn + j*cn + c] = (sx+j >= 0 && sx+j < cols && sy+i >= 0 && sy+i < rows) ? src[(sy+i) * srcStep + (sx+j)*cn + c] : 0;
+   
+    float tab[4];
+    float tab1y[2], tab1x[2];
+    tab1y[0] = 1.0 - 1.f/INTER_TAB_SIZE*ay;
+    tab1y[1] = 1.f/INTER_TAB_SIZE*ay;
+    tab1x[0] = 1.0 - 1.f/INTER_TAB_SIZE*ax;
+    tab1x[1] = 1.f/INTER_TAB_SIZE*ax;
+    
+    for( i=0; i<2; i++ )
+    {
+        for( j=0; j<2; j++)
+        {
+            tab[i*2+j] = tab1y[i] * tab1x[j];
+        }
+    }
+    if( sx+1 < 0 || sx >= cols || sy+1 < 0 || sy >= rows)
+    {
+        for(c = 0; c < cn; c++)
+            dst[dy*dstStep+dx*cn+c] = 0;
+    }
+    else
+    {
+        float sum;
+        for(c = 0; c < cn; c++)
+        {
+            sum = 0;
+            for ( i =0; i<4; i++ )
+            {
+                sum += v[i*cn+c] * tab[i] ;
+            }
+            dst[dy*dstStep+dx*cn+c] = convert_int_sat( round2_int(sum) ) ;
+        }
+    }
+}
+
+__kernel void warpPerspective_32s_Cubic(__global int * src, __global int * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    double X0 = M[0]*dx + M[1]*dy + M[2];
+    double Y0 = M[3]*dx + M[4]*dy + M[5];
+    double W = M[6]*dx + M[7]*dy + M[8];
+    W = W ? INTER_TAB_SIZE/W : 0;
+    int X = round2_int(X0*W);
+    int Y = round2_int(Y0*W);
+    
+    short sx = (short)(X >> INTER_BITS) - 1;
+    short sy = (short)(Y >> INTER_BITS) - 1;
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+
+    int v[64];
+    int i, j, c;
+
+    for(i=0; i<4;  i++)
+        for(j=0; j<4; j++)
+            for(c=0; c<cn; c++)
+                v[i*4*cn + j*cn + c] = (sx+j >= 0 && sx+j < cols && sy+i >= 0 && sy+i < rows) ? src[(sy+i) * srcStep + (sx+j)*cn + c] : 0;
+   
+    float tab[16];
+    float tab1y[4], tab1x[4];
+    float axx, ayy;
+
+    ayy = 1.f/INTER_TAB_SIZE * ay;
+    axx = 1.f/INTER_TAB_SIZE * ax;
+    interpolateCubic(ayy, tab1y);
+    interpolateCubic(axx, tab1x);
+    for( i=0; i<4; i++ )
+    {
+        for( j=0; j<4; j++)
+        {
+            tab[i*4+j] = tab1y[i] * tab1x[j];
+        }
+    }
+
+    if( sx+4 < 0 || sx >= cols || sy+4 < 0 || sy >= rows)
+    {
+        for(c = 0; c < cn; c++)
+            dst[dy*dstStep+dx*cn+c] = 0;
+    }
+    else
+    {
+        float sum;
+        for(c = 0; c < cn; c++)
+        {
+            sum = 0;
+            for ( i =0; i<16; i++ )
+            {
+                sum += v[i*cn+c] * tab[i] ;
+            }
+            dst[dy*dstStep+dx*cn+c] = convert_int_sat( round2_int(sum ));
+        }
+    }
+}
+
+
+__kernel void warpPerspective_32f_NN(__global float * src, __global float * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    double X0 = M[0]*dx + M[1]*dy + M[2];
+    double Y0 = M[3]*dx + M[4]*dy + M[5];
+    double W = M[6]*dx + M[7]*dy + M[8];
+    W = W ? 1./W : 0;
+    int X = round2_int(X0*W);
+    int Y = round2_int(Y0*W);
+    short sx = (short)X;
+    short sy = (short)Y;
+
+    for(int c = 0; c < cn; c++)
+        dst[dy*dstStep+dx*cn+c] = (sx >= 0 && sx < cols && sy >= 0 && sy < rows) ? src[sy*srcStep+sx*cn+c] : 0; 
+}
+
+__kernel void warpPerspective_32f_Linear(__global float * src, __global float * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    double X0 = M[0]*dx + M[1]*dy + M[2];
+    double Y0 = M[3]*dx + M[4]*dy + M[5];
+    double W = M[6]*dx + M[7]*dy + M[8];
+    W = W ? INTER_TAB_SIZE/W : 0;
+    int X = round2_int(X0*W);
+    int Y = round2_int(Y0*W);
+    
+    short sx = (short)(X >> INTER_BITS);
+    short sy = (short)(Y >> INTER_BITS);
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+    
+    float v[16];
+    int i, j, c;
+
+    for(i=0; i<2;  i++)
+        for(j=0; j<2; j++)
+            for(c=0; c<cn; c++)
+                v[i*2*cn + j*cn + c] = (sx+j >= 0 && sx+j < cols && sy+i >= 0 && sy+i < rows) ? src[(sy+i) * srcStep + (sx+j)*cn + c] : 0;
+   
+    float tab[4];
+    float tab1y[2], tab1x[2];
+    tab1y[0] = 1.0 - 1.f/INTER_TAB_SIZE*ay;
+    tab1y[1] = 1.f/INTER_TAB_SIZE*ay;
+    tab1x[0] = 1.0 - 1.f/INTER_TAB_SIZE*ax;
+    tab1x[1] = 1.f/INTER_TAB_SIZE*ax;
+    
+    for( i=0; i<2; i++ )
+    {
+        for( j=0; j<2; j++)
+        {
+            tab[i*2+j] = tab1y[i] * tab1x[j];
+        }
+    }
+    if( sx+1 < 0 || sx >= cols || sy+1 < 0 || sy >= rows)
+    {
+        for(c = 0; c < cn; c++)
+            dst[dy*dstStep+dx*cn+c] = 0;
+    }
+    else
+    {
+        float sum;
+        for(c = 0; c < cn; c++)
+        {
+            sum = 0;
+            for ( i =0; i<4; i++ )
+            {
+                sum += v[i*cn+c] * tab[i] ;
+            }
+            dst[dy*dstStep+dx*cn+c] = sum ;
+        }
+    }
+}
+
+__kernel void warpPerspective_32f_Cubic(__global float * src, __global float * dst, int cols, int rows,  int cn,
+                            int srcStep, int dstStep, __global double * M, int interpolation)
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    double X0 = M[0]*dx + M[1]*dy + M[2];
+    double Y0 = M[3]*dx + M[4]*dy + M[5];
+    double W = M[6]*dx + M[7]*dy + M[8];
+    W = W ? INTER_TAB_SIZE/W : 0;
+    int X = round2_int(X0*W);
+    int Y = round2_int(Y0*W);
+    
+    short sx = (short)(X >> INTER_BITS) - 1;
+    short sy = (short)(Y >> INTER_BITS) - 1;
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+
+    float v[64];
+    int i, j, c;
+
+    for(i=0; i<4;  i++)
+        for(j=0; j<4; j++)
+            for(c=0; c<cn; c++)
+                v[i*4*cn + j*cn + c] = (sx+j >= 0 && sx+j < cols && sy+i >= 0 && sy+i < rows) ? src[(sy+i) * srcStep + (sx+j)*cn + c] : 0;
+   
+    float tab[16];
+    float tab1y[4], tab1x[4];
+    float axx, ayy;
+
+    ayy = 1.f/INTER_TAB_SIZE * ay;
+    axx = 1.f/INTER_TAB_SIZE * ax;
+    interpolateCubic(ayy, tab1y);
+    interpolateCubic(axx, tab1x);
+    for( i=0; i<4; i++ )
+    {
+        for( j=0; j<4; j++)
+        {
+            tab[i*4+j] = tab1y[i] * tab1x[j];
+        }
+    }
+
+    int width = cols-3>0 ? cols-3 : 0;
+    int height = rows-3>0 ? rows-3 : 0;
+    if((unsigned)sx < width && (unsigned)sy < height )
+    {
+        float sum;
+        for(c = 0; c < cn; c++)
+        {
+            sum = 0;
+            for ( i =0; i<4; i++ )
+            {
+                    sum += v[i*4*cn+c] * tab[i*4] + v[i*4*cn+c+1]*tab[i*4+1]
+                          +v[i*4*cn+c+2] * tab[i*4+2] + v[i*4*cn+c+3]*tab[i*4+3];
+            }
+            dst[dy*dstStep+dx*cn+c] = sum;
+        }
+    }
+    else if( sx+4 < 0 || sx >= cols || sy+4 < 0 || sy >= rows)
+    {
+        for(c = 0; c < cn; c++)
+            dst[dy*dstStep+dx*cn+c] = 0;
+    }
+    else
+    {
+        float sum;
+        for(c = 0; c < cn; c++)
+        {
+            sum = 0;
+            for ( i =0; i<16; i++ )
+            {
+                    sum += v[i*cn+c] * tab[i];
+            }
+            dst[dy*dstStep+dx*cn+c] = sum;
+        }
+    }
+}
+#endif
diff --git a/modules/ocl/src/kernels/imgproc_bilateral.cl b/modules/ocl/src/kernels/imgproc_bilateral.cl
new file mode 100644 (file)
index 0000000..978d677
--- /dev/null
@@ -0,0 +1,178 @@
+//                           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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Rock Li, Rock.li@amd.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 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
+// 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.
+//
+//
+
+
+//#pragma OPENCL EXTENSION cl_amd_printf :enable
+__kernel
+void bilateral4(__global uchar4 *dst,
+               __global uchar4 *src,
+               int rows,
+               int cols,
+               int channels,
+               int radius,
+               int wholerows,
+               int wholecols,
+               int src_step,
+               int dst_step,
+               int src_offset,
+               int dst_offset,
+               __constant float *sigClr,
+               __constant float *sigSpc)
+{
+       uint lidx = get_local_id(0);
+       uint lidy = get_local_id(1);
+       
+       uint gdx = get_global_id(0);
+       uint gdy = get_global_id(1);
+
+       uint gidx = gdx >=cols?cols-1:gdx;
+       uint gidy = gdy >=rows?rows-1:gdy;
+
+       uchar4 p,q,tmp;
+
+       float4 pf = 0,pq = 0,pd = 0;
+        float wt =0;
+
+       int r = radius;
+       int ij = 0;
+       int ct = 0;
+
+       uint index_src = src_offset/4 + gidy*src_step/4 + gidx;
+       uint index_dst = dst_offset/4 + gidy*dst_step/4 + gidx;
+
+       p = src[index_src];
+
+       uint gx,gy;
+       uint src_index,dst_index;
+
+       for(int ii = -r;ii<r+1;ii++)
+       {
+               for(int jj =-r;jj<r+1;jj++)
+                       {
+                                       ij = ii*ii+jj*jj;
+                                       if(ij > mul24(radius,radius)) continue;
+                                       gx = gidx + jj;
+                                       gy = gidy + ii;
+
+                                       src_index = src_offset/4 + gy *  src_step/4 + gx;
+                                       q = src[src_index];
+                                       
+
+                                       ct = abs(p.x-q.x)+abs(p.y-q.y)+abs(p.z-q.z);
+                                       wt =sigClr[ct]*sigSpc[(ii+radius)*(2*radius+1)+jj+radius];
+
+                                       pf.x += q.x*wt;
+                                       pf.y += q.y*wt;
+                                       pf.z += q.z*wt;
+//                                     pf.w += q.w*wt;
+
+                                       pq += wt;
+
+                       }
+       }
+
+       pd = pf/pq;
+       dst[index_dst] = convert_uchar4_rte(pd);
+}
+
+__kernel
+void bilateral(__global uchar *dst,
+               __global uchar *src,
+               int rows,
+               int cols,
+               int channels,
+               int radius,
+               int wholerows,
+               int wholecols,
+               int src_step,
+               int dst_step,
+               int src_offset,
+               int dst_offset,
+               __constant float *sigClr,
+               __constant float *sigSpc)
+{
+       uint lidx = get_local_id(0);
+       uint lidy = get_local_id(1);
+       
+       uint gdx = get_global_id(0);
+       uint gdy = get_global_id(1);
+
+       uint gidx = gdx >=cols?cols-1:gdx;
+       uint gidy = gdy >=rows?rows-1:gdy;
+
+       uchar p,q,tmp;
+
+       float pf = 0,pq = 0,wt = 0,pd = 0;
+
+       int r =radius;
+       int ij = 0;
+       int ct = 0;
+
+       uint index_src = src_offset + gidy*src_step + gidx;
+       uint index_dst = dst_offset + gidy*dst_step + gidx;
+
+       p = src[index_src];
+
+       uint gx,gy;
+       uint src_index,dst_index;
+
+       for(int ii = -r;ii<r+1;ii++)
+       {
+               for(int jj =-r;jj<r+1;jj++)
+                       {
+                                       ij = ii*ii+jj*jj;
+                                       if(ij > mul24(radius,radius)) continue;
+
+                                       gx = gidx + jj;
+                                       gy = gidy + ii;
+
+                                       
+                                       src_index = src_offset + gy * src_step + gx;
+                                       q = src[src_index];
+
+                                       ct = abs(p-q);
+                                       wt =sigClr[ct]*sigSpc[(ii+radius)*(2*radius+1)+jj+radius];
+
+                                       pf += q*wt;
+                                       
+                                       pq += wt;
+                       }
+       }
+       pd = pf/pq;
+       dst[index_dst] = convert_uchar_rte(pd);
+
+}
+
diff --git a/modules/ocl/src/kernels/imgproc_calcHarris.cl b/modules/ocl/src/kernels/imgproc_calcHarris.cl
new file mode 100644 (file)
index 0000000..6bc85cc
--- /dev/null
@@ -0,0 +1,199 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Shengen Yan,yanshengen@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 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
+// 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*/
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////Macro for border type////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////
+#ifdef BORDER_REPLICATE
+//BORDER_REPLICATE:     aaaaaa|abcdefgh|hhhhhhh
+#define ADDR_L(i, l_edge, r_edge)  ((i) <  (l_edge) ? (l_edge)   : (i))
+#define ADDR_R(i, r_edge, addr)    ((i) >= (r_edge) ? (r_edge)-1 : (addr))
+#define ADDR_H(i, t_edge, b_edge)  ((i) <  (t_edge) ? (t_edge)   :(i)) 
+#define ADDR_B(i, b_edge, addr)    ((i) >= (b_edge) ? (b_edge)-1 :(addr)) 
+#endif
+
+#ifdef BORDER_REFLECT
+//BORDER_REFLECT:       fedcba|abcdefgh|hgfedcb
+#define ADDR_L(i, l_edge, r_edge)  ((i) <  (l_edge) ? -(i)-1               : (i))
+#define ADDR_R(i, r_edge, addr)    ((i) >= (r_edge) ? -(i)-1+((r_edge)<<1) : (addr))
+#define ADDR_H(i, t_edge, b_edge)  ((i) <  (t_edge) ? -(i)-1 : (i))
+#define ADDR_B(i, b_edge, addr)    ((i) >= (b_edge) ? -(i)-1+((b_edge)<<1) : (addr))
+#endif
+
+#ifdef BORDER_REFLECT_101
+//BORDER_REFLECT_101:   gfedcb|abcdefgh|gfedcba
+#define ADDR_L(i, l_edge, r_edge)  ((i) <  (l_edge) ? -(i)                 : (i))
+#define ADDR_R(i, r_edge, addr)    ((i) >= (r_edge) ? -(i)-2+((r_edge)<<1) : (addr))
+#define ADDR_H(i, t_edge, b_edge)  ((i) <  (t_edge) ? -(i)                 : (i))
+#define ADDR_B(i, b_edge, addr)    ((i) >= (b_edge) ? -(i)-2+((b_edge)<<1) : (addr))
+#endif
+
+#ifdef BORDER_WRAP
+//BORDER_WRAP:          cdefgh|abcdefgh|abcdefg
+#define ADDR_L(i, l_edge, r_edge)  ((i) <  (l_edge) ? (i)+(r_edge) : (i))
+#define ADDR_R(i, r_edge, addr)    ((i) >= (r_edge) ? (i)-(r_edge) : (addr))
+#define ADDR_H(i, t_edge, b_edge)  ((i) <  (t_edge) ? (i)+(b_edge) : (i))
+#define ADDR_B(i, b_edge, addr)    ((i) >= (b_edge) ? (i)-(b_edge) : (addr))
+#endif
+
+#define THREADS 256
+#define ELEM(i, l_edge, r_edge, elem1, elem2) (i) >= (l_edge) && (i) < (r_edge) ? (elem1) : (elem2)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////calcHarris////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void calcHarris(__global const float *Dx,__global const float *Dy, __global float *dst,
+                              int dx_offset, int dx_whole_rows, int dx_whole_cols, int dx_step,
+                              int dy_offset, int dy_whole_rows, int dy_whole_cols, int dy_step,
+                              int dst_offset, int dst_rows, int dst_cols, int dst_step,
+                              float k)
+{
+    int col = get_local_id(0);
+    const int gX = get_group_id(0);
+    const int gY = get_group_id(1);
+
+    int dx_x_off = (dx_offset % dx_step) >> 2;
+    int dx_y_off = dx_offset / dx_step;
+    int dy_x_off = (dy_offset % dy_step) >> 2;
+    int dy_y_off = dy_offset / dy_step;
+    int dst_x_off = (dst_offset % dst_step) >> 2;
+    int dst_y_off = dst_offset / dst_step;
+
+    int dx_startX = gX * (THREADS-ksX+1) - anX + dx_x_off;
+    int dx_startY = (gY << 1) - anY + dx_y_off;
+    int dy_startX = gX * (THREADS-ksX+1) - anX + dy_x_off;
+    int dy_startY = (gY << 1) - anY + dy_y_off;
+    int dst_startX = gX * (THREADS-ksX+1) + dst_x_off;
+    int dst_startY = (gY << 1) + dst_y_off;
+
+    float dx_data[ksY+1],dy_data[ksY+1],data[3][ksY+1];
+    __local float temp[6][THREADS];
+#ifdef BORDER_CONSTANT
+    bool dx_con,dy_con;
+    float dx_s,dy_s;
+    for(int i=0; i < ksY+1; i++)
+    {
+        dx_con = dx_startX+col >= 0 && dx_startX+col < dx_whole_cols && dx_startY+i >= 0 && dx_startY+i < dx_whole_rows;
+        dx_s = Dx[(dx_startY+i)*(dx_step>>2)+(dx_startX+dx_col)]; 
+        dx_data[i] = dx_con ? dx_s : 0.0;
+        dy_con = dy_startX+col >= 0 && dy_startX+col < dy_whole_cols && dy_startY+i >= 0 && dy_startY+i < dy_whole_rows;
+        dy_s = Dy[(dy_startY+i)*(dy_step>>2)+(dy_startX+dy_col)]; 
+        dy_data[i] = dy_con ? dy_s : 0.0;
+        data[0][i] = dx_data[i] * dx_data[i];
+        data[1][i] = dx_data[i] * dy_data[i];
+        data[2][i] = dy_data[i] * dy_data[i];
+    }
+#else
+   for(int i=0; i < ksY+1; i++)
+   {
+        int dx_selected_row;
+        int dx_selected_col;
+        dx_selected_row = ADDR_H(dx_startY+i, 0, dx_whole_rows);
+        dx_selected_row = ADDR_B(dx_startY+i, dx_whole_rows, dx_selected_row);
+        dx_selected_col = ADDR_L(dx_startX+col, 0, dx_whole_cols);
+        dx_selected_col = ADDR_R(dx_startX+col, dx_whole_cols, dx_selected_col);
+        dx_data[i] = Dx[dx_selected_row * (dx_step>>2) + dx_selected_col];
+        
+        int dy_selected_row;
+        int dy_selected_col;
+        dy_selected_row = ADDR_H(dy_startY+i, 0, dy_whole_rows);
+        dy_selected_row = ADDR_B(dy_startY+i, dy_whole_rows, dy_selected_row);
+        dy_selected_col = ADDR_L(dy_startX+col, 0, dy_whole_cols);
+        dy_selected_col = ADDR_R(dy_startX+col, dy_whole_cols, dy_selected_col);
+        dy_data[i] = Dy[dx_selected_row * (dy_step>>2) + dy_selected_col];
+       
+        data[0][i] = dx_data[i] * dx_data[i];
+        data[1][i] = dx_data[i] * dy_data[i];
+        data[2][i] = dy_data[i] * dy_data[i];
+   }
+#endif
+    float sum0 = 0.0, sum1 = 0.0, sum2 = 0.0;
+    for(int i=1; i < ksY; i++)
+    {
+        sum0 += (data[0][i]);
+        sum1 += (data[1][i]);
+        sum2 += (data[2][i]);
+    }
+    float sum01,sum02,sum11,sum12,sum21,sum22;
+    sum01 = sum0 + (data[0][0]);
+    sum02 = sum0 + (data[0][ksY]);
+    temp[0][col] = sum01;
+    temp[1][col] = sum02;
+    sum11 = sum1 + (data[1][0]);
+    sum12 = sum1 + (data[1][ksY]);
+    temp[2][col] = sum11;
+    temp[3][col] = sum12;
+    sum21 = sum2 + (data[2][0]);
+    sum22 = sum2 + (data[2][ksY]);
+    temp[4][col] = sum21;
+    temp[5][col] = sum22;
+    barrier(CLK_LOCAL_MEM_FENCE);
+    if(col < (THREADS-(ksX-1)))
+    {
+        col += anX;
+        int posX = dst_startX - dst_x_off + col - anX;
+        int posY = (gY << 1);
+        int till = (ksX + 1)%2;
+        float tmp_sum[6]={ 0.0, 0.0 , 0.0, 0.0, 0.0, 0.0 };
+        for(int k=0; k<6; k++)
+            for(int i=-anX; i<=anX - till; i++)
+            {
+                tmp_sum[k] += temp[k][col+i];
+            }
+
+        if(posX < dst_cols && (posY) < dst_rows)
+        {
+            dst[(dst_startY+0) * (dst_step>>2)+ dst_startX + col - anX] = 
+                    tmp_sum[0] * tmp_sum[4] - tmp_sum[2] * tmp_sum[2] - k * (tmp_sum[0] + tmp_sum[4]) * (tmp_sum[0] + tmp_sum[4]);
+        }
+        if(posX < dst_cols && (posY + 1) < dst_rows)
+        {
+            dst[(dst_startY+1) * (dst_step>>2)+ dst_startX + col - anX] = 
+                    tmp_sum[1] * tmp_sum[5] - tmp_sum[3] * tmp_sum[3] - k * (tmp_sum[1] + tmp_sum[5]) * (tmp_sum[1] + tmp_sum[5]);
+        }
+    }
+}
diff --git a/modules/ocl/src/kernels/imgproc_calcMinEigenVal.cl b/modules/ocl/src/kernels/imgproc_calcMinEigenVal.cl
new file mode 100644 (file)
index 0000000..2d4b43f
--- /dev/null
@@ -0,0 +1,203 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Shengen Yan,yanshengen@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 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
+// 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*/
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////Macro for border type////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////
+#ifdef BORDER_REPLICATE
+//BORDER_REPLICATE:     aaaaaa|abcdefgh|hhhhhhh
+#define ADDR_L(i, l_edge, r_edge)  ((i) <  (l_edge) ? (l_edge)   : (i))
+#define ADDR_R(i, r_edge, addr)    ((i) >= (r_edge) ? (r_edge)-1 : (addr))
+#define ADDR_H(i, t_edge, b_edge)  ((i) <  (t_edge) ? (t_edge)   :(i)) 
+#define ADDR_B(i, b_edge, addr)    ((i) >= (b_edge) ? (b_edge)-1 :(addr)) 
+#endif
+
+#ifdef BORDER_REFLECT
+//BORDER_REFLECT:       fedcba|abcdefgh|hgfedcb
+#define ADDR_L(i, l_edge, r_edge)  ((i) <  (l_edge) ? -(i)-1               : (i))
+#define ADDR_R(i, r_edge, addr)    ((i) >= (r_edge) ? -(i)-1+((r_edge)<<1) : (addr))
+#define ADDR_H(i, t_edge, b_edge)  ((i) <  (t_edge) ? -(i)-1 : (i))
+#define ADDR_B(i, b_edge, addr)    ((i) >= (b_edge) ? -(i)-1+((b_edge)<<1) : (addr))
+#endif
+
+#ifdef BORDER_REFLECT_101
+//BORDER_REFLECT_101:   gfedcb|abcdefgh|gfedcba
+#define ADDR_L(i, l_edge, r_edge)  ((i) <  (l_edge) ? -(i)                 : (i))
+#define ADDR_R(i, r_edge, addr)    ((i) >= (r_edge) ? -(i)-2+((r_edge)<<1) : (addr))
+#define ADDR_H(i, t_edge, b_edge)  ((i) <  (t_edge) ? -(i)                 : (i))
+#define ADDR_B(i, b_edge, addr)    ((i) >= (b_edge) ? -(i)-2+((b_edge)<<1) : (addr))
+#endif
+
+#ifdef BORDER_WRAP
+//BORDER_WRAP:          cdefgh|abcdefgh|abcdefg
+#define ADDR_L(i, l_edge, r_edge)  ((i) <  (l_edge) ? (i)+(r_edge) : (i))
+#define ADDR_R(i, r_edge, addr)    ((i) >= (r_edge) ? (i)-(r_edge) : (addr))
+#define ADDR_H(i, t_edge, b_edge)  ((i) <  (t_edge) ? (i)+(b_edge) : (i))
+#define ADDR_B(i, b_edge, addr)    ((i) >= (b_edge) ? (i)-(b_edge) : (addr))
+#endif
+
+#define THREADS 256
+#define ELEM(i, l_edge, r_edge, elem1, elem2) (i) >= (l_edge) && (i) < (r_edge) ? (elem1) : (elem2)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////calcHarris////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void calcMinEigenVal(__global const float *Dx,__global const float *Dy, __global float *dst,
+                              int dx_offset, int dx_whole_rows, int dx_whole_cols, int dx_step,
+                              int dy_offset, int dy_whole_rows, int dy_whole_cols, int dy_step,
+                              int dst_offset, int dst_rows, int dst_cols, int dst_step,
+                              float k)
+{
+    int col = get_local_id(0);
+    const int gX = get_group_id(0);
+    const int gY = get_group_id(1);
+
+    int dx_x_off = (dx_offset % dx_step) >> 2;
+    int dx_y_off = dx_offset / dx_step;
+    int dy_x_off = (dy_offset % dy_step) >> 2;
+    int dy_y_off = dy_offset / dy_step;
+    int dst_x_off = (dst_offset % dst_step) >> 2;
+    int dst_y_off = dst_offset / dst_step;
+
+    int dx_startX = gX * (THREADS-ksX+1) - anX + dx_x_off;
+    int dx_startY = (gY << 1) - anY + dx_y_off;
+    int dy_startX = gX * (THREADS-ksX+1) - anX + dy_x_off;
+    int dy_startY = (gY << 1) - anY + dy_y_off;
+    int dst_startX = gX * (THREADS-ksX+1) + dst_x_off;
+    int dst_startY = (gY << 1) + dst_y_off;
+
+    float dx_data[ksY+1],dy_data[ksY+1],data[3][ksY+1];
+    __local float temp[6][THREADS];
+#ifdef BORDER_CONSTANT
+    bool dx_con,dy_con;
+    float dx_s,dy_s;
+    for(int i=0; i < ksY+1; i++)
+    {
+        dx_con = dx_startX+col >= 0 && dx_startX+col < dx_whole_cols && dx_startY+i >= 0 && dx_startY+i < dx_whole_rows;
+        dx_s = Dx[(dx_startY+i)*(dx_step>>2)+(dx_startX+dx_col)]; 
+        dx_data[i] = dx_con ? dx_s : 0.0;
+        dy_con = dy_startX+col >= 0 && dy_startX+col < dy_whole_cols && dy_startY+i >= 0 && dy_startY+i < dy_whole_rows;
+        dy_s = Dy[(dy_startY+i)*(dy_step>>2)+(dy_startX+dy_col)]; 
+        dy_data[i] = dy_con ? dy_s : 0.0;
+        data[0][i] = dx_data[i] * dx_data[i];
+        data[1][i] = dx_data[i] * dy_data[i];
+        data[2][i] = dy_data[i] * dy_data[i];
+    }
+#else
+   for(int i=0; i < ksY+1; i++)
+   {
+        int dx_selected_row;
+        int dx_selected_col;
+        dx_selected_row = ADDR_H(dx_startY+i, 0, dx_whole_rows);
+        dx_selected_row = ADDR_B(dx_startY+i, dx_whole_rows, dx_selected_row);
+        dx_selected_col = ADDR_L(dx_startX+col, 0, dx_whole_cols);
+        dx_selected_col = ADDR_R(dx_startX+col, dx_whole_cols, dx_selected_col);
+        dx_data[i] = Dx[dx_selected_row * (dx_step>>2) + dx_selected_col];
+        
+        int dy_selected_row;
+        int dy_selected_col;
+        dy_selected_row = ADDR_H(dy_startY+i, 0, dy_whole_rows);
+        dy_selected_row = ADDR_B(dy_startY+i, dy_whole_rows, dy_selected_row);
+        dy_selected_col = ADDR_L(dy_startX+col, 0, dy_whole_cols);
+        dy_selected_col = ADDR_R(dy_startX+col, dy_whole_cols, dy_selected_col);
+        dy_data[i] = Dy[dx_selected_row * (dy_step>>2) + dy_selected_col];
+       
+        data[0][i] = dx_data[i] * dx_data[i];
+        data[1][i] = dx_data[i] * dy_data[i];
+        data[2][i] = dy_data[i] * dy_data[i];
+   }
+#endif
+    float sum0 = 0.0, sum1 = 0.0, sum2 = 0.0;
+    for(int i=1; i < ksY; i++)
+    {
+        sum0 += (data[0][i]);
+        sum1 += (data[1][i]);
+        sum2 += (data[2][i]);
+    }
+    float sum01,sum02,sum11,sum12,sum21,sum22;
+    sum01 = sum0 + (data[0][0]);
+    sum02 = sum0 + (data[0][ksY]);
+    temp[0][col] = sum01;
+    temp[1][col] = sum02;
+    sum11 = sum1 + (data[1][0]);
+    sum12 = sum1 + (data[1][ksY]);
+    temp[2][col] = sum11;
+    temp[3][col] = sum12;
+    sum21 = sum2 + (data[2][0]);
+    sum22 = sum2 + (data[2][ksY]);
+    temp[4][col] = sum21;
+    temp[5][col] = sum22;
+    barrier(CLK_LOCAL_MEM_FENCE);
+    if(col < (THREADS-(ksX-1)))
+    {
+        col += anX;
+        int posX = dst_startX - dst_x_off + col - anX;
+        int posY = (gY << 1);
+        int till = (ksX + 1)%2;
+        float tmp_sum[6]={ 0.0, 0.0 , 0.0, 0.0, 0.0, 0.0 };
+        for(int k=0; k<6; k++)
+            for(int i=-anX; i<=anX - till; i++)
+            {
+                tmp_sum[k] += temp[k][col+i];
+            }
+
+        if(posX < dst_cols && (posY) < dst_rows)
+        {
+            float a = tmp_sum[0] * 0.5f;
+            float b = tmp_sum[2];
+            float c = tmp_sum[4] * 0.5f;
+            dst[(dst_startY+0) * (dst_step>>2)+ dst_startX + col - anX] = (float)((a+c) - sqrt((a-c)*(a-c) + b*b));
+        }
+        if(posX < dst_cols && (posY + 1) < dst_rows)
+        {
+            float a = tmp_sum[1] * 0.5f;
+            float b = tmp_sum[3];
+            float c = tmp_sum[5] * 0.5f;
+            dst[(dst_startY+1) * (dst_step>>2)+ dst_startX + col - anX] = (float)((a+c) - sqrt((a-c)*(a-c) + b*b));
+        }
+    }
+}
diff --git a/modules/ocl/src/kernels/imgproc_copymakeboder.cl b/modules/ocl/src/kernels/imgproc_copymakeboder.cl
new file mode 100644 (file)
index 0000000..9270d9a
--- /dev/null
@@ -0,0 +1,246 @@
+//                           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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Niko Li, newlife20080214@gmail.com
+//    Zero Lin zero.lin@amd.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.
+//
+//
+
+
+#define get(a,b,c) (( b >= top & b < srcRows+top & a >= left & a < srcCols+left )? c : 8)
+__kernel void copyConstBorder_C1_D0(__global uchar * src, __global uchar * dst, int srcOffset, int dstOffset, 
+                                                               int srcCols, int srcRows, int dstCols, int dstRows, 
+                                                               int top, int left, uchar nVal, int srcStep, int dstStep)
+{
+       int idx = get_global_id(0);
+       int tpr = (dstCols + 3 + (dstOffset&3))>>2;
+       int dx  = ((idx%(tpr))<<2) - (dstOffset&3);
+    int dy = idx/(tpr);
+    
+       __global uchar4 * d=(__global uchar4 *)(dst + dstOffset + dy*dstStep + dx);
+       int start=srcOffset + (dy-top)*srcStep + (dx-left);
+       uchar8 s=*((__global uchar8 *)(src + ((start>>2)<<2) ));
+       uchar4 v;
+       
+       uchar sv[9]={s.s0,s.s1,s.s2,s.s3,s.s4,s.s5,s.s6,s.s7,nVal};
+       
+       int det=start&3;
+       v.x=sv[get(dx,dy,det)];
+       v.y=sv[get(dx+1,dy,det+1)];
+       v.z=sv[get(dx+2,dy,det+2)];
+       v.w=sv[get(dx+3,dy,det+3)];
+       
+       if(dy<dstRows)
+       {
+               uchar4 res = *d;
+               res.x = (dx>=0 && dx<dstCols) ? v.x : res.x;
+               res.y = (dx+1>=0 && dx+1<dstCols) ? v.y : res.y;
+               res.z = (dx+2>=0 && dx+2<dstCols) ? v.z : res.z;
+               res.w = (dx+3>=0 && dx+3<dstCols) ? v.w : res.w;
+       
+               *d=res;
+       }
+}
+#undef get(a,b,c)
+
+#define get(a,b,c,d) (( b >= top & b < srcRows+top & a >= left & a < srcCols+left )? c : d)
+__kernel void copyConstBorder_C1_D4(__global int * src, __global int * dst, int srcOffset, int dstOffset, 
+                                                               int srcCols, int srcRows, int dstCols, int dstRows, 
+                                                               int top, int left, int nVal, int srcStep, int dstStep)
+{
+    int idx = get_global_id(0);
+       int tpr = (dstCols + 3)>>2;
+       int dx  = (idx%(tpr))<<2;
+    int dy = idx/(tpr);
+    
+       __global int4 * d=(__global int4 *)(dst+dy*dstStep+dx);
+       int4 s=*((__global int4 *)(src + srcOffset + (dy-top)*srcStep + (dx-left) ));
+       int4 v;
+       
+       v.x=get(dx,dy,s.x,nVal);
+       v.y=get(dx+1,dy,s.y,nVal);
+       v.z=get(dx+2,dy,s.z,nVal);
+       v.w=get(dx+3,dy,s.w,nVal);
+       
+       if(dy<dstRows)
+       {
+               int4 res = *d;
+               v.y = (dx+1<dstCols) ? v.y : res.y;
+               v.z = (dx+2<dstCols) ? v.z : res.z;
+               v.w = (dx+3<dstCols) ? v.w : res.w;
+       
+               *d=v;
+       }
+}
+#undef get(a,b,c,d)
+
+#define get(a,b,c) ( a < srcCols+left ? b : c)
+__kernel void copyReplicateBorder_C1_D4(__global int * src, __global int * dst, int srcOffset, int dstOffset, 
+                                                               int srcCols, int srcRows, int dstCols, int dstRows, 
+                                                               int top, int left, int nVal, int srcStep, int dstStep)
+{
+    int idx = get_global_id(0);
+       int tpr = (dstCols + 3)>>2;
+       int dx  = (idx%(tpr))<<2;
+    int dy = idx/(tpr);
+
+       __global int4 * d=(__global int4 *)(dst + dstOffset + dy*dstStep + dx);
+       int c=clamp(dx-left,0,srcCols-1);
+       int4 s=*((__global int4 *)(src + srcOffset + clamp(dy-top,0,srcRows-1) * srcStep + c ));
+       int sa[4]={s.x,s.y,s.z,s.w};
+       int4 v;
+       
+       v.x=get(dx,sa[max(0,(dx-left)-c)],sa[srcCols-1-c]);
+       v.y=get(dx+1,sa[max(0,(dx+1-left)-c)],sa[srcCols-1-c]);
+       v.z=get(dx+2,sa[max(0,(dx+2-left)-c)],sa[srcCols-1-c]);
+       v.w=get(dx+3,sa[max(0,(dx+3-left)-c)],sa[srcCols-1-c]);
+       
+       if(dy<dstRows)
+       {
+               int4 res = *d;
+               v.y = (dx+1<dstCols) ? v.y : res.y;
+               v.z = (dx+2<dstCols) ? v.z : res.z;
+               v.w = (dx+3<dstCols) ? v.w : res.w;
+       
+               *d=v;
+       }
+}
+
+__kernel void copyReplicateBorder_C1_D0(__global uchar * src, __global uchar * dst, int srcOffset, int dstOffset, 
+                                                               int srcCols, int srcRows, int dstCols, int dstRows, 
+                                                               int top, int left, uchar nVal, int srcStep, int dstStep)
+{
+       int idx = get_global_id(0);
+       int tpr = (dstCols + 3 + (dstOffset&3))>>2;
+       int dx  = ((idx%(tpr))<<2) - (dstOffset&3);
+    int dy = idx/(tpr);
+    
+       __global uchar4 * d=(__global uchar4 *)(dst + dstOffset + dy*dstStep + dx);
+       int c=clamp(dx-left,0,srcCols-1);
+       int start= srcOffset + clamp(dy-top,0,srcRows-1) * srcStep + c;
+       uchar8 s=*((__global uchar8 *)(src + ((start>>2)<<2) ));
+       uchar4 v;
+       
+       uchar sa[8]={s.s0,s.s1,s.s2,s.s3,s.s4,s.s5,s.s6,s.s7};
+       
+       int det=start&3;
+       v.x=get(dx,sa[max(0,(dx-left)-c)+det],sa[srcCols-1-c+det]);
+       v.y=get(dx+1,sa[max(0,(dx+1-left)-c)+det],sa[srcCols-1-c+det]);
+       v.z=get(dx+2,sa[max(0,(dx+2-left)-c)+det],sa[srcCols-1-c+det]);
+       v.w=get(dx+3,sa[max(0,(dx+3-left)-c)+det],sa[srcCols-1-c+det]);
+       
+       if(dy<dstRows)
+       {
+               uchar4 res = *d;
+               res.x = (dx>=0 && dx<dstCols) ? v.x : res.x;
+               res.y = (dx+1>=0 && dx+1<dstCols) ? v.y : res.y;
+               res.z = (dx+2>=0 && dx+2<dstCols) ? v.z : res.z;
+               res.w = (dx+3>=0 && dx+3<dstCols) ? v.w : res.w;
+       
+               *d=res;
+       }
+}
+#undef get(a,b,c)
+
+//BORDER_REFLECT_101:   gfedcb|abcdefgh|gfedcba
+#define edge(x,size,rx) rx = abs(x) % ((size<<1)-2); rx = (rx>=size?(size<<1)-2:rx<<1) - rx;
+__kernel void copyReflectBorder_C1_D4(__global int * src, __global int * dst, int srcOffset, int dstOffset, 
+                                                               int srcCols, int srcRows, int dstCols, int dstRows, 
+                                                               int top, int left, int nVal, int srcStep, int dstStep)
+{
+    int idx = get_global_id(0);
+       int tpr = (dstCols + 3)>>2;
+       int dx  = (idx%(tpr))<<2;
+    int dy = idx/(tpr);
+
+       __global int4 * d=(__global int4 *)(dst + dstOffset + dy*dstStep + dx);
+       uint4 id;
+       edge(dx-left,srcCols,id.x);
+       edge(dx-left+1,srcCols,id.x);
+       edge(dx-left+2,srcCols,id.x);
+       edge(dx-left+3,srcCols,id.x);
+
+
+
+       int start=min(id.x,id.w);
+       int4 s=*((__global int4 *)(src + srcOffset + clamp(dy-top,0,srcRows-1) * srcStep + start));
+       int sa[4]={s.x,s.y,s.z,s.w};
+
+       int4 v=(int4)(sa[(id.x-start)],sa[(id.y-start)],sa[(id.z-start)],sa[(id.w-start)]);
+       
+       
+       if(dy<dstRows)
+       {
+               int4 res = *d;
+               v.y = (dx+1<dstCols) ? v.y : res.y;
+               v.z = (dx+2<dstCols) ? v.z : res.z;
+               v.w = (dx+3<dstCols) ? v.w : res.w;
+       
+               *d=v;
+       }
+}
+
+__kernel void copyReflectBorder_C1_D0(__global uchar * src, __global uchar * dst, int srcOffset, int dstOffset, 
+                                                               int srcCols, int srcRows, int dstCols, int dstRows, 
+                                                               int top, int left, uchar nVal, int srcStep, int dstStep)
+{
+    int idx = get_global_id(0);
+       int tpr = (dstCols + 3 + (dstOffset&3))>>2;
+       int dx  = ((idx%(tpr))<<2) - (dstOffset&3);
+    int dy = idx/(tpr);
+    
+       __global uchar4 * d=(__global uchar4 *)(dst + dstOffset + dy*dstStep + dx);
+       uint4 id;
+       edge(dx-left,srcCols,id.x);
+       edge(dx-left+1,srcCols,id.x);
+       edge(dx-left+2,srcCols,id.x);
+       edge(dx-left+3,srcCols,id.x);
+
+       int start=min(id.x,id.w) + srcOffset;
+       uchar8 s=*((__global uchar8 *)(src + clamp(dy-top,0,srcRows-1) * srcStep + ((start>>2)<<2) ));
+       uchar sa[8]={s.s0,s.s1,s.s2,s.s3,s.s4,s.s5,s.s6,s.s7};
+       
+       int det=start&3;
+       uchar4 v=(uchar4)(sa[(id.x-start)+det],sa[(id.y-start)+det],sa[(id.z-start)+det],sa[(id.w-start)+det]);
+       
+       if(dy<dstRows)
+       {
+               uchar4 res = *d;
+               res.x = (dx>=0 && dx<dstCols) ? v.x : res.x;
+               res.y = (dx+1>=0 && dx+1<dstCols) ? v.y : res.y;
+               res.z = (dx+2>=0 && dx+2<dstCols) ? v.z : res.z;
+               res.w = (dx+3>=0 && dx+3<dstCols) ? v.w : res.w;
+       
+               *d=res;
+       }
+}
+#undef edge(x,size,rx)
+
diff --git a/modules/ocl/src/kernels/imgproc_histogram.cl b/modules/ocl/src/kernels/imgproc_histogram.cl
new file mode 100644 (file)
index 0000000..25c9034
--- /dev/null
@@ -0,0 +1,222 @@
+//                           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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Niko Li, newlife20080214@gmail.com
+//    Jia Haipeng, jiahaipeng95@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 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
+// 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.
+//
+//
+#define PARTITAL_HISTGRAM256_COUNT     (256) 
+#define HISTOGRAM256_BIN_COUNT         (256)
+
+#define HISTGRAM256_WORK_GROUP_SIZE     (256)
+#define HISTGRAM256_LOCAL_MEM_SIZE      (HISTOGRAM256_BIN_COUNT)
+
+__kernel __attribute__((reqd_work_group_size(256,1,1)))void calc_sub_hist_D0(__global const uchar4* src, 
+                                                          int src_step, 
+                                                          int src_offset,
+                               __global int*   buf,
+                               int data_count, 
+                                                          int cols, 
+                                                          int inc_x, 
+                                                          int inc_y,
+                                                          int dst_offset)
+{
+    int x  = get_global_id(0);
+    int lx = get_local_id(0);
+    int gx = get_group_id(0);
+    int total_threads = get_global_size(0);
+    src +=  src_offset;
+    __local int s_hist[HISTGRAM256_LOCAL_MEM_SIZE];
+    s_hist[lx] = 0;
+
+    int pos_y = x / cols;
+    int pos_x = x - mul24(pos_y, cols);
+    barrier(CLK_LOCAL_MEM_FENCE);
+    for(int pos = x; pos < data_count; pos += total_threads)
+    {
+        int4 data = convert_int4(src[mad24(pos_y,src_step,pos_x)]);
+        atomic_inc(s_hist + data.x);
+        atomic_inc(s_hist + data.y);
+        atomic_inc(s_hist + data.z);
+        atomic_inc(s_hist + data.w);
+               
+        pos_x +=inc_x;
+        int off = (pos_x >= cols ? -1 : 0);
+        pos_x =  mad24(off,cols,pos_x);
+        pos_y += inc_y - off;
+               
+        //pos_x = pos_x > cols ? pos_x - cols : pos_x;
+        //pos_y = pos_x > cols ? pos_y + 1 : pos_y;
+    }
+    barrier(CLK_LOCAL_MEM_FENCE);
+    buf[ mad24(gx, dst_offset, lx)] = s_hist[lx];
+}
+
+__kernel void __attribute__((reqd_work_group_size(1,256,1)))calc_sub_hist2_D0( __global const uchar* src, 
+                                int src_step, 
+                                int src_offset,
+                 __global int*   buf,
+                 int left_col, 
+                                int cols,
+                                int rows,
+                                int dst_offset)
+{
+       int gidx = get_global_id(0);
+       int gidy = get_global_id(1);
+       int gx = get_group_id(0);
+       int gy = get_group_id(1);
+       int gnum = get_num_groups(0);
+       int output_row = mad24(gy,gnum,gx);
+       //int lidx = get_local_id(0);
+       int lidy = get_local_id(1);
+
+    __local int s_hist[HISTGRAM256_LOCAL_MEM_SIZE+1];
+    s_hist[lidy] = 0;
+       //mem_fence(CLK_LOCAL_MEM_FENCE);
+
+
+       //clamp(gidx,mask,cols-1);
+       gidx = gidx >= left_col ? cols+gidx : gidx;
+       //gidy = gidy >= rows?rows-1:gidy;
+
+       int src_index = src_offset + mad24(gidy,src_step,gidx); 
+       //int dst_index = dst_offset + mad24(gidy,dst_step,gidx);
+       //uchar4 p,q;
+       barrier(CLK_LOCAL_MEM_FENCE);
+       int p = (int)src[src_index];
+       p = gidy >= rows ? HISTGRAM256_LOCAL_MEM_SIZE : p;
+       atomic_inc(s_hist + p);
+    barrier(CLK_LOCAL_MEM_FENCE);
+    buf[ mad24(output_row, dst_offset, lidy)] += s_hist[lidy];
+}
+__kernel __attribute__((reqd_work_group_size(256,1,1)))void merge_hist(__global int* buf,  
+                               __global int* hist,
+                               int src_step)
+{
+    int lx = get_local_id(0);
+    int gx = get_group_id(0);
+
+    int sum = 0;
+
+    for(int i = lx; i < PARTITAL_HISTGRAM256_COUNT; i += HISTGRAM256_WORK_GROUP_SIZE)
+        sum += buf[ mad24(i, src_step, gx)];
+
+    __local int data[HISTGRAM256_WORK_GROUP_SIZE];
+    data[lx] = sum;
+
+    for(int stride = HISTGRAM256_WORK_GROUP_SIZE /2; stride > 0; stride >>= 1)
+    {
+        barrier(CLK_LOCAL_MEM_FENCE);
+        if(lx < stride)
+            data[lx] += data[lx + stride];
+    }
+
+    if(lx == 0)
+        hist[gx] = data[0]; 
+}
+
+__kernel __attribute__((reqd_work_group_size(256,1,1)))void calLUT(
+                                                       __global uchar * dst,
+                                                       __constant int * hist,
+                                                       float scale)
+{
+       int lid = get_local_id(0);
+       __local int sumhist[HISTOGRAM256_BIN_COUNT];
+       //__local uchar lut[HISTOGRAM256_BIN_COUNT+1];
+
+       sumhist[lid]=hist[lid];
+       barrier(CLK_LOCAL_MEM_FENCE);
+       if(lid==0)
+       {
+               int sum = 0;
+               for(int i=0;i<HISTOGRAM256_BIN_COUNT;i++)
+               {
+                       sum+=sumhist[i];
+                       sumhist[i]=sum;
+               }
+       }
+       barrier(CLK_LOCAL_MEM_FENCE);
+       dst[lid]= lid == 0 ? 0 : convert_uchar_sat(convert_float(sumhist[lid])*scale);
+}
+/*
+///////////////////////////////equalizeHist//////////////////////////////////////////////////
+__kernel __attribute__((reqd_work_group_size(256,1,1)))void equalizeHist(
+                                                       __global uchar * src,
+                                                       __global uchar * dst,
+                                                       __constant int * hist,
+                                                       int srcstep,
+                                                       int srcoffset,
+                                                       int dststep,
+                                                       int dstoffset,
+                                                       int width,
+                                                       int height,
+                                                       float scale,
+                                                       int inc_x,
+                                                       int inc_y)
+{
+       int gidx = get_global_id(0);
+       int lid = get_local_id(0);
+       int glb_size = get_global_size(0);
+       src+=srcoffset;
+       dst+=dstoffset;
+       __local int sumhist[HISTOGRAM256_BIN_COUNT];
+       __local uchar lut[HISTOGRAM256_BIN_COUNT+1];
+
+       sumhist[lid]=hist[lid];
+       barrier(CLK_LOCAL_MEM_FENCE);
+       if(lid==0)
+       {
+               int sum = 0;
+               for(int i=0;i<HISTOGRAM256_BIN_COUNT;i++)
+               {
+                       sum+=sumhist[i];
+                       sumhist[i]=sum;
+               }
+       }
+       barrier(CLK_LOCAL_MEM_FENCE);
+       lut[lid]= convert_uchar_sat(convert_float(sumhist[lid])*scale);
+       lut[0]=0;
+    int pos_y = gidx / width;
+    int pos_x = gidx - mul24(pos_y, width);
+
+    for(int pos = gidx; pos < mul24(width,height); pos += glb_size)
+       {
+               int inaddr = mad24(pos_y,srcstep,pos_x);
+               int outaddr = mad24(pos_y,dststep,pos_x);
+               dst[outaddr] = lut[src[inaddr]];
+               pos_x +=inc_x;
+               int off = (pos_x >= width ? -1 : 0);
+               pos_x =  mad24(off,width,pos_x);
+               pos_y += inc_y - off;
+       }
+}
+*/
+
diff --git a/modules/ocl/src/kernels/imgproc_integral.cl b/modules/ocl/src/kernels/imgproc_integral.cl
new file mode 100644 (file)
index 0000000..5c71864
--- /dev/null
@@ -0,0 +1,269 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Shengen Yan,yanshengen@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 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
+// 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*/
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+#define LSIZE 256
+#define LSIZE_1 255
+#define LSIZE_2 254
+#define HF_LSIZE 128
+#define LOG_LSIZE 8
+#define LOG_NUM_BANKS 5
+#define NUM_BANKS 32
+#define GET_CONFLICT_OFFSET(lid) ((lid) >> LOG_NUM_BANKS)
+
+
+kernel void integral_cols(__global uchar4 *src,__global int *sum ,__global float *sqsum,
+                          int src_offset,int pre_invalid,int rows,int cols,int src_step,int dst_step)
+{
+    unsigned int lid = get_local_id(0);
+    unsigned int gid = get_group_id(0);
+    int4 src_t[2], sum_t[2];
+    float4 sqsum_t[2];
+    __local int4 lm_sum[2][LSIZE + LOG_LSIZE];
+    __local float4 lm_sqsum[2][LSIZE + LOG_LSIZE];
+    __local int* sum_p;
+    __local float* sqsum_p;
+    src_step = src_step >> 2;
+    gid = gid << 1;
+    for(int i = 0; i < rows; i =i + LSIZE_1)
+    {
+        src_t[0] = (i + lid < rows ? convert_int4(src[src_offset + (lid+i) * src_step + gid]) : 0);
+        src_t[1] = (i + lid < rows ? convert_int4(src[src_offset + (lid+i) * src_step + gid + 1]) : 0);
+        
+        sum_t[0] =  (i == 0 ? 0 : lm_sum[0][LSIZE_2 + LOG_LSIZE]);
+        sqsum_t[0] =  (i == 0 ? 0 : lm_sqsum[0][LSIZE_2 + LOG_LSIZE]);
+        sum_t[1] =  (i == 0 ? 0 : lm_sum[1][LSIZE_2 + LOG_LSIZE]);
+        sqsum_t[1] =  (i == 0 ? 0 : lm_sqsum[1][LSIZE_2 + LOG_LSIZE]);
+        barrier(CLK_LOCAL_MEM_FENCE);
+        
+        int bf_loc = lid + GET_CONFLICT_OFFSET(lid);
+        lm_sum[0][bf_loc] = src_t[0];
+        lm_sqsum[0][bf_loc] = convert_float4(src_t[0] * src_t[0]);
+
+        lm_sum[1][bf_loc] = src_t[1];
+        lm_sqsum[1][bf_loc] = convert_float4(src_t[1] * src_t[1]);
+        
+        int offset = 1;
+        for(int d = LSIZE >> 1 ;  d > 0; d>>=1)
+        {
+            barrier(CLK_LOCAL_MEM_FENCE);
+            int ai = offset * (((lid & 127)<<1) +1) - 1,bi = ai + offset;
+            ai += GET_CONFLICT_OFFSET(ai); 
+            bi += GET_CONFLICT_OFFSET(bi); 
+
+            if((lid & 127) < d)
+            {
+                lm_sum[lid >> 7][bi]  +=  lm_sum[lid >> 7][ai];
+                lm_sqsum[lid >> 7][bi]  +=  lm_sqsum[lid >> 7][ai];
+            }
+            offset <<= 1;
+        }
+        if(lid < 2)
+        {
+            lm_sum[lid][LSIZE_2 + LOG_LSIZE] = 0;
+            lm_sqsum[lid][LSIZE_2 + LOG_LSIZE] = 0;
+        }
+        for(int d = 1;  d < LSIZE; d <<= 1)
+        {
+            barrier(CLK_LOCAL_MEM_FENCE);
+            offset >>= 1;
+            int ai = offset * (((lid & 127)<<1) +1) - 1,bi = ai + offset;
+            ai += GET_CONFLICT_OFFSET(ai); 
+            bi += GET_CONFLICT_OFFSET(bi); 
+            
+            if((lid & 127) < d)
+            {
+                lm_sum[lid >> 7][bi] += lm_sum[lid >> 7][ai];
+                lm_sum[lid >> 7][ai] = lm_sum[lid >> 7][bi] - lm_sum[lid >> 7][ai];
+                
+                lm_sqsum[lid >> 7][bi] += lm_sqsum[lid >> 7][ai];
+                lm_sqsum[lid >> 7][ai] = lm_sqsum[lid >> 7][bi] - lm_sqsum[lid >> 7][ai];
+            }
+        }
+        if(lid > 0 & (i+lid) <= rows){
+            int loc_s0 = gid * dst_step + i + lid - 1 - pre_invalid * dst_step / 4, loc_s1 = loc_s0 + dst_step ;
+            lm_sum[0][bf_loc] += sum_t[0]; 
+            lm_sum[1][bf_loc] += sum_t[1]; 
+            lm_sqsum[0][bf_loc] += sqsum_t[0];
+            lm_sqsum[1][bf_loc] += sqsum_t[1];
+            sum_p = (__local int*)(&(lm_sum[0][bf_loc]));
+            sqsum_p = (__local float*)(&(lm_sqsum[0][bf_loc]));
+            for(int k = 0; k < 4; k++)
+            {
+                if(gid * 4 + k >= cols + pre_invalid || gid * 4 + k < pre_invalid) continue;
+                sum[loc_s0 + k * dst_step / 4] = sum_p[k];
+                sqsum[loc_s0 + k * dst_step / 4] = sqsum_p[k];
+            } 
+            sum_p = (__local int*)(&(lm_sum[1][bf_loc]));
+            sqsum_p = (__local float*)(&(lm_sqsum[1][bf_loc]));
+            for(int k = 0; k < 4; k++)
+            {
+                if(gid * 4 + k + 4 >= cols + pre_invalid) break;
+                sum[loc_s1 + k * dst_step / 4] = sum_p[k];
+                sqsum[loc_s1 + k * dst_step / 4] = sqsum_p[k];
+            } 
+        }
+        barrier(CLK_LOCAL_MEM_FENCE);
+    }
+}
+
+
+kernel void integral_rows(__global int4 *srcsum,__global float4 * srcsqsum,__global int *sum ,
+                          __global float *sqsum,int rows,int cols,int src_step,int sum_step,
+                          int sqsum_step,int sum_offset,int sqsum_offset)
+{
+    unsigned int lid = get_local_id(0);
+    unsigned int gid = get_group_id(0);
+    int4 src_t[2], sum_t[2];
+    float4 sqsrc_t[2],sqsum_t[2];
+    __local int4 lm_sum[2][LSIZE + LOG_LSIZE];
+    __local float4 lm_sqsum[2][LSIZE + LOG_LSIZE];
+    __local int *sum_p;
+    __local float *sqsum_p;
+    src_step = src_step >> 4;
+    for(int i = 0; i < rows; i =i + LSIZE_1)
+    {
+        src_t[0] = i + lid < rows ? srcsum[(lid+i) * src_step + gid * 2] : 0;
+        sqsrc_t[0] = i + lid < rows ? srcsqsum[(lid+i) * src_step + gid * 2] : 0;
+        src_t[1] = i + lid < rows ? srcsum[(lid+i) * src_step + gid * 2 + 1] : 0;
+        sqsrc_t[1] = i + lid < rows ? srcsqsum[(lid+i) * src_step + gid * 2 + 1] : 0;
+        
+        sum_t[0] =  (i == 0 ? 0 : lm_sum[0][LSIZE_2 + LOG_LSIZE]);
+        sqsum_t[0] =  (i == 0 ? 0 : lm_sqsum[0][LSIZE_2 + LOG_LSIZE]);
+        sum_t[1] =  (i == 0 ? 0 : lm_sum[1][LSIZE_2 + LOG_LSIZE]);
+        sqsum_t[1] =  (i == 0 ? 0 : lm_sqsum[1][LSIZE_2 + LOG_LSIZE]);
+        barrier(CLK_LOCAL_MEM_FENCE);
+        
+        int bf_loc = lid + GET_CONFLICT_OFFSET(lid);
+        lm_sum[0][bf_loc] = src_t[0];
+        lm_sqsum[0][bf_loc] = sqsrc_t[0];
+            
+        lm_sum[1][bf_loc] = src_t[1];
+        lm_sqsum[1][bf_loc] = sqsrc_t[1];
+        
+        int offset = 1;
+        for(int d = LSIZE >> 1 ;  d > 0; d>>=1)
+        {
+            barrier(CLK_LOCAL_MEM_FENCE);
+            int ai = offset * (((lid & 127)<<1) +1) - 1,bi = ai + offset;
+            ai += GET_CONFLICT_OFFSET(ai); 
+            bi += GET_CONFLICT_OFFSET(bi); 
+
+            if((lid & 127) < d)
+            {
+                lm_sum[lid >> 7][bi]  +=  lm_sum[lid >> 7][ai];
+                lm_sqsum[lid >> 7][bi]  +=  lm_sqsum[lid >> 7][ai];
+            }
+            offset <<= 1;
+        }
+        if(lid < 2)
+        {
+            lm_sum[lid][LSIZE_2 + LOG_LSIZE] = 0;
+            lm_sqsum[lid][LSIZE_2 + LOG_LSIZE] = 0;
+        }
+        for(int d = 1;  d < LSIZE; d <<= 1)
+        {
+            barrier(CLK_LOCAL_MEM_FENCE);
+            offset >>= 1;
+            int ai = offset * (((lid & 127)<<1) +1) - 1,bi = ai + offset;
+            ai += GET_CONFLICT_OFFSET(ai); 
+            bi += GET_CONFLICT_OFFSET(bi); 
+            
+            if((lid & 127) < d)
+            {
+                lm_sum[lid >> 7][bi] += lm_sum[lid >> 7][ai];
+                lm_sum[lid >> 7][ai] = lm_sum[lid >> 7][bi] - lm_sum[lid >> 7][ai];
+                
+                lm_sqsum[lid >> 7][bi] += lm_sqsum[lid >> 7][ai];
+                lm_sqsum[lid >> 7][ai] = lm_sqsum[lid >> 7][bi] - lm_sqsum[lid >> 7][ai];
+            }
+        }
+        
+        if(gid == 0 && (i + lid) <= rows)
+        {
+           sum[sum_offset + i + lid] = 0;
+           sqsum[sqsum_offset + i + lid] = 0;
+        }
+        if(i + lid == 0)
+        {
+            int loc0 = gid * 2 * sum_step;
+            int loc1 = gid * 2 * sqsum_step;
+            for(int k = 1;k <= 8;k++) 
+            {
+                if(gid * 8 + k > cols) break;
+                sum[sum_offset + loc0 + k * sum_step / 4] = 0;
+                sqsum[sqsum_offset + loc1 + k * sqsum_step / 4] = 0;
+            }
+        }
+        
+        if(lid > 0 & (i+lid) <= rows){
+            int loc_s0 = sum_offset + gid * 2 * sum_step + sum_step / 4 + i + lid, loc_s1 = loc_s0 + sum_step ;
+            int loc_sq0 = sqsum_offset + gid * 2 * sqsum_step + sqsum_step / 4 + i + lid, loc_sq1 = loc_sq0 + sqsum_step ;
+            lm_sum[0][bf_loc] += sum_t[0]; 
+            lm_sum[1][bf_loc] += sum_t[1]; 
+            lm_sqsum[0][bf_loc] += sqsum_t[0];
+            lm_sqsum[1][bf_loc] += sqsum_t[1];
+            sum_p = (__local int*)(&(lm_sum[0][bf_loc]));
+            sqsum_p = (__local float*)(&(lm_sqsum[0][bf_loc]));
+            for(int k = 0; k < 4; k++)
+            {
+                if(gid * 8 + k >= cols) break;
+                sum[loc_s0 + k * sum_step / 4] = sum_p[k];
+                sqsum[loc_sq0 + k * sqsum_step / 4] = sqsum_p[k];
+            } 
+            sum_p = (__local int*)(&(lm_sum[1][bf_loc]));
+            sqsum_p = (__local float*)(&(lm_sqsum[1][bf_loc]));
+            for(int k = 0; k < 4; k++)
+            {
+                if(gid * 8 + 4 + k >= cols) break;
+                sum[loc_s1 + k * sum_step / 4] = sum_p[k];
+                sqsum[loc_sq1 + k * sqsum_step / 4] = sqsum_p[k];
+            } 
+        }
+        barrier(CLK_LOCAL_MEM_FENCE);
+    }
+}
diff --git a/modules/ocl/src/kernels/imgproc_integral_sum.cl b/modules/ocl/src/kernels/imgproc_integral_sum.cl
new file mode 100644 (file)
index 0000000..0d90300
--- /dev/null
@@ -0,0 +1,227 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Shengen Yan,yanshengen@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 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
+// 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*/
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+#define LSIZE 256
+#define LSIZE_1 255
+#define LSIZE_2 254
+#define HF_LSIZE 128
+#define LOG_LSIZE 8
+#define LOG_NUM_BANKS 5
+#define NUM_BANKS 32
+#define GET_CONFLICT_OFFSET(lid) ((lid) >> LOG_NUM_BANKS)
+
+
+kernel void integral_cols(__global uchar4 *src,__global int *sum ,
+                          int src_offset,int pre_invalid,int rows,int cols,int src_step,int dst_step)
+{
+    unsigned int lid = get_local_id(0);
+    unsigned int gid = get_group_id(0);
+    int4 src_t[2], sum_t[2];
+    __local int4 lm_sum[2][LSIZE + LOG_LSIZE];
+    __local int* sum_p;
+    src_step = src_step >> 2;
+    gid = gid << 1;
+    for(int i = 0; i < rows; i =i + LSIZE_1)
+    {
+        src_t[0] = (i + lid < rows ? convert_int4(src[src_offset + (lid+i) * src_step + gid]) : 0);
+        src_t[1] = (i + lid < rows ? convert_int4(src[src_offset + (lid+i) * src_step + gid + 1]) : 0);
+        
+        sum_t[0] =  (i == 0 ? 0 : lm_sum[0][LSIZE_2 + LOG_LSIZE]);
+        sum_t[1] =  (i == 0 ? 0 : lm_sum[1][LSIZE_2 + LOG_LSIZE]);
+        barrier(CLK_LOCAL_MEM_FENCE);
+        
+        int bf_loc = lid + GET_CONFLICT_OFFSET(lid);
+        lm_sum[0][bf_loc] = src_t[0];
+
+        lm_sum[1][bf_loc] = src_t[1];
+        
+        int offset = 1;
+        for(int d = LSIZE >> 1 ;  d > 0; d>>=1)
+        {
+            barrier(CLK_LOCAL_MEM_FENCE);
+            int ai = offset * (((lid & 127)<<1) +1) - 1,bi = ai + offset;
+            ai += GET_CONFLICT_OFFSET(ai); 
+            bi += GET_CONFLICT_OFFSET(bi); 
+
+            if((lid & 127) < d)
+            {
+                lm_sum[lid >> 7][bi]  +=  lm_sum[lid >> 7][ai];
+            }
+            offset <<= 1;
+        }
+        if(lid < 2)
+        {
+            lm_sum[lid][LSIZE_2 + LOG_LSIZE] = 0;
+        }
+        for(int d = 1;  d < LSIZE; d <<= 1)
+        {
+            barrier(CLK_LOCAL_MEM_FENCE);
+            offset >>= 1;
+            int ai = offset * (((lid & 127)<<1) +1) - 1,bi = ai + offset;
+            ai += GET_CONFLICT_OFFSET(ai); 
+            bi += GET_CONFLICT_OFFSET(bi); 
+            
+            if((lid & 127) < d)
+            {
+                lm_sum[lid >> 7][bi] += lm_sum[lid >> 7][ai];
+                lm_sum[lid >> 7][ai] = lm_sum[lid >> 7][bi] - lm_sum[lid >> 7][ai];
+            }
+        }
+        if(lid > 0 & (i+lid) <= rows){
+            int loc_s0 = gid * dst_step + i + lid - 1 - pre_invalid * dst_step / 4, loc_s1 = loc_s0 + dst_step ;
+            lm_sum[0][bf_loc] += sum_t[0]; 
+            lm_sum[1][bf_loc] += sum_t[1]; 
+            sum_p = (__local int*)(&(lm_sum[0][bf_loc]));
+            for(int k = 0; k < 4; k++)
+            {
+                if(gid * 4 + k >= cols + pre_invalid || gid * 4 + k < pre_invalid) continue;
+                sum[loc_s0 + k * dst_step / 4] = sum_p[k];
+            } 
+            sum_p = (__local int*)(&(lm_sum[1][bf_loc]));
+            for(int k = 0; k < 4; k++)
+            {
+                if(gid * 4 + k + 4 >= cols + pre_invalid) break;
+                sum[loc_s1 + k * dst_step / 4] = sum_p[k];
+            } 
+        }
+        barrier(CLK_LOCAL_MEM_FENCE);
+    }
+}
+
+
+kernel void integral_rows(__global int4 *srcsum,__global int *sum ,
+                          int rows,int cols,int src_step,int sum_step,
+                          int sum_offset)
+{
+    unsigned int lid = get_local_id(0);
+    unsigned int gid = get_group_id(0);
+    int4 src_t[2], sum_t[2];
+    __local int4 lm_sum[2][LSIZE + LOG_LSIZE];
+    __local int *sum_p;
+    src_step = src_step >> 4;
+    for(int i = 0; i < rows; i =i + LSIZE_1)
+    {
+        src_t[0] = i + lid < rows ? srcsum[(lid+i) * src_step + gid * 2] : 0;
+        src_t[1] = i + lid < rows ? srcsum[(lid+i) * src_step + gid * 2 + 1] : 0;
+        
+        sum_t[0] =  (i == 0 ? 0 : lm_sum[0][LSIZE_2 + LOG_LSIZE]);
+        sum_t[1] =  (i == 0 ? 0 : lm_sum[1][LSIZE_2 + LOG_LSIZE]);
+        barrier(CLK_LOCAL_MEM_FENCE);
+        
+        int bf_loc = lid + GET_CONFLICT_OFFSET(lid);
+        lm_sum[0][bf_loc] = src_t[0];
+            
+        lm_sum[1][bf_loc] = src_t[1];
+        
+        int offset = 1;
+        for(int d = LSIZE >> 1 ;  d > 0; d>>=1)
+        {
+            barrier(CLK_LOCAL_MEM_FENCE);
+            int ai = offset * (((lid & 127)<<1) +1) - 1,bi = ai + offset;
+            ai += GET_CONFLICT_OFFSET(ai); 
+            bi += GET_CONFLICT_OFFSET(bi); 
+
+            if((lid & 127) < d)
+            {
+                lm_sum[lid >> 7][bi]  +=  lm_sum[lid >> 7][ai];
+            }
+            offset <<= 1;
+        }
+        if(lid < 2)
+        {
+            lm_sum[lid][LSIZE_2 + LOG_LSIZE] = 0;
+        }
+        for(int d = 1;  d < LSIZE; d <<= 1)
+        {
+            barrier(CLK_LOCAL_MEM_FENCE);
+            offset >>= 1;
+            int ai = offset * (((lid & 127)<<1) +1) - 1,bi = ai + offset;
+            ai += GET_CONFLICT_OFFSET(ai); 
+            bi += GET_CONFLICT_OFFSET(bi); 
+            
+            if((lid & 127) < d)
+            {
+                lm_sum[lid >> 7][bi] += lm_sum[lid >> 7][ai];
+                lm_sum[lid >> 7][ai] = lm_sum[lid >> 7][bi] - lm_sum[lid >> 7][ai];
+            }
+        }
+        
+        if(gid == 0 && (i + lid) <= rows)
+        {
+           sum[sum_offset + i + lid] = 0;
+        }
+        if(i + lid == 0)
+        {
+            int loc0 = gid * 2 * sum_step;
+            for(int k = 1;k <= 8;k++) 
+            {
+                if(gid * 8 + k > cols) break;
+                sum[sum_offset + loc0 + k * sum_step / 4] = 0;
+            }
+        }
+        
+        if(lid > 0 & (i+lid) <= rows){
+            int loc_s0 = sum_offset + gid * 2 * sum_step + sum_step / 4 + i + lid, loc_s1 = loc_s0 + sum_step ;
+            lm_sum[0][bf_loc] += sum_t[0]; 
+            lm_sum[1][bf_loc] += sum_t[1]; 
+            sum_p = (__local int*)(&(lm_sum[0][bf_loc]));
+            for(int k = 0; k < 4; k++)
+            {
+                if(gid * 8 + k >= cols) break;
+                sum[loc_s0 + k * sum_step / 4] = sum_p[k];
+            } 
+            sum_p = (__local int*)(&(lm_sum[1][bf_loc]));
+            for(int k = 0; k < 4; k++)
+            {
+                if(gid * 8 + 4 + k >= cols) break;
+                sum[loc_s1 + k * sum_step / 4] = sum_p[k];
+            } 
+        }
+        barrier(CLK_LOCAL_MEM_FENCE);
+    }
+}
diff --git a/modules/ocl/src/kernels/imgproc_median.cl b/modules/ocl/src/kernels/imgproc_median.cl
new file mode 100644 (file)
index 0000000..4c4731f
--- /dev/null
@@ -0,0 +1,487 @@
+//                           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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Niko Li, newlife20080214@gmail.com
+//    Zero Lin, zero.lin@amd.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 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
+// 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.
+//
+//
+
+
+/*
+__kernel void medianFilter_C1(__global uchar * src, __global uchar * dst,  int srcOffset, int dstOffset, int cols,
+                                int rows, int srcStep, int dstStep, int m)
+{
+       int dx = get_global_id(0)-(m>>1);
+    int dy = get_global_id(1)-(m>>1);
+    
+       short histom[256];
+       for(int i=0;i<256;++i)
+               histom[i]=0;
+
+       
+       for(int i=0;i<m;++i)
+       {       
+               __global uchar * data = src + srcOffset + mul24(srcStep,clamp(dy + (i), 0, rows-1));
+               for(int j=dx;j<dx+m;++j)
+               {
+                       histom[data[clamp(j, 0, cols-1)]]++;
+               }
+       }
+
+       int now=0;
+       int goal=(m*m+1)>>1;
+       int v;
+       for(int i=0;i<256;++i)
+       {
+               v=(now<goal?i:v);
+               now+=histom[i];
+       }
+       
+       if(dy<rows && dx<cols)
+               dst[dstOffset + get_global_id(1)*dstStep + get_global_id(0)]=v;
+}
+*/
+#define op(a,b) {mid=a; a=min(a,b); b=max(mid,b);}
+__kernel void medianFilter3_C4_D0(__global uchar4 * src, __global uchar4 * dst,  int srcOffset, int dstOffset, int cols,
+                                int rows, int srcStep, int dstStep)
+{
+       
+       __local uchar4 data[18][18];
+       __global uchar4* source=src + srcOffset;
+
+       int dx = get_global_id(0) - get_local_id(0) -1;
+    int dy = get_global_id(1) - get_local_id(1) -1;
+    
+       const int id = min((int)(get_local_id(0)*16+get_local_id(1)), 9*18-1);
+
+       int dr=id/18;
+       int dc=id%18;
+       int r=clamp(dy+dr, 0, rows-1);
+       int c=clamp(dx+dc, 0, cols-1);
+
+       data[dr][dc] = source[r*srcStep + c];
+       r=clamp(dy+dr+9, 0, rows-1);
+       data[dr+9][dc] = source[r*srcStep + c];
+
+       barrier(CLK_LOCAL_MEM_FENCE);
+
+       int x =get_local_id(0);
+       int y =get_local_id(1);
+       uchar4 p0=data[y][x], p1=data[y][x+1], p2=data[y][x+2];
+       uchar4 p3=data[y+1][x], p4=data[y+1][x+1], p5=data[y+1][x+2];
+       uchar4 p6=data[y+2][x], p7=data[y+2][x+1], p8=data[y+2][x+2]; 
+       uchar4 mid;
+
+       op(p1, p2); op(p4, p5); op(p7, p8); op(p0, p1);
+    op(p3, p4); op(p6, p7); op(p1, p2); op(p4, p5);
+    op(p7, p8); op(p0, p3); op(p5, p8); op(p4, p7);
+    op(p3, p6); op(p1, p4); op(p2, p5); op(p4, p7);
+    op(p4, p2); op(p6, p4); op(p4, p2);
+       
+       if(get_global_id(1)<rows && get_global_id(0)<cols)
+               dst[dstOffset + get_global_id(1)*dstStep + get_global_id(0)]=p4;
+}
+#undef op(a,b)
+
+#define op(a,b) {mid=a; a=min(a,b); b=max(mid,b);}
+__kernel void medianFilter3_C1_D0(__global uchar * src, __global uchar * dst,  int srcOffset, int dstOffset, int cols,
+                                int rows, int srcStep, int dstStep)
+{
+       
+       __local uchar data[18][18];
+       __global uchar* source=src + srcOffset;
+
+       int dx = get_global_id(0) - get_local_id(0) -1;
+    int dy = get_global_id(1) - get_local_id(1) -1;
+    
+       const int id = min((int)(get_local_id(0)*16+get_local_id(1)), 9*18-1);
+
+       int dr=id/18;
+       int dc=id%18;
+       int r=clamp(dy+dr, 0, rows-1);
+       int c=clamp(dx+dc, 0, cols-1);
+
+       data[dr][dc] = source[r*srcStep + c];
+       r=clamp(dy+dr+9, 0, rows-1);
+       data[dr+9][dc] = source[r*srcStep + c];
+
+       barrier(CLK_LOCAL_MEM_FENCE);
+
+       int x =get_local_id(0);
+       int y =get_local_id(1);
+       uchar p0=data[y][x], p1=data[y][x+1], p2=data[y][x+2];
+       uchar p3=data[y+1][x], p4=data[y+1][x+1], p5=data[y+1][x+2];
+       uchar p6=data[y+2][x], p7=data[y+2][x+1], p8=data[y+2][x+2]; 
+       uchar mid;
+
+       op(p1, p2); op(p4, p5); op(p7, p8); op(p0, p1);
+    op(p3, p4); op(p6, p7); op(p1, p2); op(p4, p5);
+    op(p7, p8); op(p0, p3); op(p5, p8); op(p4, p7);
+    op(p3, p6); op(p1, p4); op(p2, p5); op(p4, p7);
+    op(p4, p2); op(p6, p4); op(p4, p2);
+       
+       if(get_global_id(1)<rows && get_global_id(0)<cols)
+               dst[dstOffset + get_global_id(1)*dstStep + get_global_id(0)]=p4;
+}
+#undef op(a,b)
+
+#define op(a,b) {mid=a; a=min(a,b); b=max(mid,b);}
+__kernel void medianFilter3_C1_D5(__global float * src, __global float * dst,  int srcOffset, int dstOffset, int cols,
+                                int rows, int srcStep, int dstStep)
+{
+       
+       __local float data[18][18];
+       __global float* source=src + srcOffset;
+
+       int dx = get_global_id(0) - get_local_id(0) -1;
+    int dy = get_global_id(1) - get_local_id(1) -1;
+    
+       const int id = min((int)(get_local_id(0)*16+get_local_id(1)), 9*18-1);
+
+       int dr=id/18;
+       int dc=id%18;
+       int r=clamp(dy+dr, 0, rows-1);
+       int c=clamp(dx+dc, 0, cols-1);
+
+       data[dr][dc] = source[r*srcStep + c];
+       r=clamp(dy+dr+9, 0, rows-1);
+       data[dr+9][dc] = source[r*srcStep + c];
+
+       barrier(CLK_LOCAL_MEM_FENCE);
+
+       int x =get_local_id(0);
+       int y =get_local_id(1);
+       float p0=data[y][x], p1=data[y][x+1], p2=data[y][x+2];
+       float p3=data[y+1][x], p4=data[y+1][x+1], p5=data[y+1][x+2];
+       float p6=data[y+2][x], p7=data[y+2][x+1], p8=data[y+2][x+2]; 
+       float mid;
+
+       op(p1, p2); op(p4, p5); op(p7, p8); op(p0, p1);
+    op(p3, p4); op(p6, p7); op(p1, p2); op(p4, p5);
+    op(p7, p8); op(p0, p3); op(p5, p8); op(p4, p7);
+    op(p3, p6); op(p1, p4); op(p2, p5); op(p4, p7);
+    op(p4, p2); op(p6, p4); op(p4, p2);
+       
+       if(get_global_id(1)<rows && get_global_id(0)<cols)
+               dst[dstOffset + get_global_id(1)*dstStep + get_global_id(0)]=p4;
+}
+#undef op(a,b)
+
+#define op(a,b) {mid=a; a=min(a,b); b=max(mid,b);}
+__kernel void medianFilter3_C4_D5(__global float4 * src, __global float4 * dst,  int srcOffset, int dstOffset, int cols,
+                                int rows, int srcStep, int dstStep)
+{
+       
+       __local float4 data[18][18];
+       __global float4* source=src + srcOffset;
+
+       int dx = get_global_id(0) - get_local_id(0) -1;
+    int dy = get_global_id(1) - get_local_id(1) -1;
+    
+       const int id = min((int)(get_local_id(0)*16+get_local_id(1)), 9*18-1);
+
+       int dr=id/18;
+       int dc=id%18;
+       int r=clamp(dy+dr, 0, rows-1);
+       int c=clamp(dx+dc, 0, cols-1);
+
+       data[dr][dc] = source[r*srcStep + c];
+       r=clamp(dy+dr+9, 0, rows-1);
+       data[dr+9][dc] = source[r*srcStep + c];
+
+       barrier(CLK_LOCAL_MEM_FENCE);
+
+       int x =get_local_id(0);
+       int y =get_local_id(1);
+       float4 p0=data[y][x], p1=data[y][x+1], p2=data[y][x+2];
+       float4 p3=data[y+1][x], p4=data[y+1][x+1], p5=data[y+1][x+2];
+       float4 p6=data[y+2][x], p7=data[y+2][x+1], p8=data[y+2][x+2]; 
+       float4 mid;
+
+       op(p1, p2); op(p4, p5); op(p7, p8); op(p0, p1);
+    op(p3, p4); op(p6, p7); op(p1, p2); op(p4, p5);
+    op(p7, p8); op(p0, p3); op(p5, p8); op(p4, p7);
+    op(p3, p6); op(p1, p4); op(p2, p5); op(p4, p7);
+    op(p4, p2); op(p6, p4); op(p4, p2);
+       
+       if(get_global_id(1)<rows && get_global_id(0)<cols)
+               dst[dstOffset + get_global_id(1)*dstStep + get_global_id(0)]=p4;
+}
+#undef op(a,b)
+
+#define op(a,b) {mid=a; a=min(a,b); b=max(mid,b);}
+__kernel void medianFilter5_C4_D0(__global uchar4 * src, __global uchar4 * dst,  int srcOffset, int dstOffset, int cols,
+                                int rows, int srcStep, int dstStep)
+{
+       
+       __local uchar4 data[20][20];
+       __global uchar4* source=src + srcOffset;
+
+       int dx = get_global_id(0) - get_local_id(0) -2;
+    int dy = get_global_id(1) - get_local_id(1) -2;
+    
+       const int id = min((int)(get_local_id(0)*16+get_local_id(1)), 10*20-1);
+
+       int dr=id/20;
+       int dc=id%20;
+       int r=clamp(dy+dr, 0, rows-1);
+       int c=clamp(dx+dc, 0, cols-1);
+
+       data[dr][dc] = source[r*srcStep + c];
+       r=clamp(dy+dr+10, 0, rows-1);
+       data[dr+10][dc] = source[r*srcStep + c];
+
+       barrier(CLK_LOCAL_MEM_FENCE);
+
+       int x =get_local_id(0);
+       int y =get_local_id(1);
+       uchar4 p0=data[y][x], p1=data[y][x+1], p2=data[y][x+2], p3=data[y][x+3], p4=data[y][x+4];
+       uchar4 p5=data[y+1][x], p6=data[y+1][x+1], p7=data[y+1][x+2], p8=data[y+1][x+3], p9=data[y+1][x+4];
+       uchar4 p10=data[y+2][x], p11=data[y+2][x+1], p12=data[y+2][x+2], p13=data[y+2][x+3], p14=data[y+2][x+4];
+       uchar4 p15=data[y+3][x], p16=data[y+3][x+1], p17=data[y+3][x+2], p18=data[y+3][x+3], p19=data[y+3][x+4];
+       uchar4 p20=data[y+4][x], p21=data[y+4][x+1], p22=data[y+4][x+2], p23=data[y+4][x+3], p24=data[y+4][x+4];
+       uchar4 mid;
+
+       op(p1, p2); op(p0, p1); op(p1, p2); op(p4, p5); op(p3, p4);
+    op(p4, p5); op(p0, p3); op(p2, p5); op(p2, p3); op(p1, p4);
+    op(p1, p2); op(p3, p4); op(p7, p8); op(p6, p7); op(p7, p8);
+    op(p10, p11); op(p9, p10); op(p10, p11); op(p6, p9); op(p8, p11);
+    op(p8, p9); op(p7, p10); op(p7, p8); op(p9, p10); op(p0, p6);
+    op(p4, p10); op(p4, p6); op(p2, p8); op(p2, p4); op(p6, p8);
+    op(p1, p7); op(p5, p11); op(p5, p7); op(p3, p9); op(p3, p5);
+    op(p7, p9); op(p1, p2); op(p3, p4); op(p5, p6); op(p7, p8);
+    op(p9, p10); op(p13, p14); op(p12, p13); op(p13, p14); op(p16, p17);
+    op(p15, p16); op(p16, p17); op(p12, p15); op(p14, p17); op(p14, p15);
+    op(p13, p16); op(p13, p14); op(p15, p16); op(p19, p20); op(p18, p19);
+    op(p19, p20); op(p21, p22); op(p23, p24); op(p21, p23); op(p22, p24);
+    op(p22, p23); op(p18, p21); op(p20, p23); op(p20, p21); op(p19, p22);
+    op(p22, p24); op(p19, p20); op(p21, p22); op(p23, p24); op(p12, p18);
+    op(p16, p22); op(p16, p18); op(p14, p20); op(p20, p24); op(p14, p16);
+    op(p18, p20); op(p22, p24); op(p13, p19); op(p17, p23); op(p17, p19);
+    op(p15, p21); op(p15, p17); op(p19, p21); op(p13, p14); op(p15, p16);
+    op(p17, p18); op(p19, p20); op(p21, p22); op(p23, p24); op(p0, p12);
+    op(p8, p20); op(p8, p12); op(p4, p16); op(p16, p24); op(p12, p16);
+    op(p2, p14); op(p10, p22); op(p10, p14); op(p6, p18); op(p6, p10);
+    op(p10, p12); op(p1, p13); op(p9, p21); op(p9, p13); op(p5, p17);
+    op(p13, p17); op(p3, p15); op(p11, p23); op(p11, p15); op(p7, p19);
+    op(p7, p11); op(p11, p13); op(p11, p12);
+       
+       if(get_global_id(1)<rows && get_global_id(0)<cols)
+               dst[dstOffset + get_global_id(1)*dstStep + get_global_id(0)]=p12;
+}
+#undef op(a,b)
+
+#define op(a,b) {mid=a; a=min(a,b); b=max(mid,b);}
+__kernel void medianFilter5_C1_D0(__global uchar * src, __global uchar * dst,  int srcOffset, int dstOffset, int cols,
+                                int rows, int srcStep, int dstStep)
+{
+       
+       __local uchar data[20][20];
+       __global uchar* source=src + srcOffset;
+
+       int dx = get_global_id(0) - get_local_id(0) -2;
+    int dy = get_global_id(1) - get_local_id(1) -2;
+    
+       const int id = min((int)(get_local_id(0)*16+get_local_id(1)), 10*20-1);
+
+       int dr=id/20;
+       int dc=id%20;
+       int r=clamp(dy+dr, 0, rows-1);
+       int c=clamp(dx+dc, 0, cols-1);
+
+       data[dr][dc] = source[r*srcStep + c];
+       r=clamp(dy+dr+10, 0, rows-1);
+       data[dr+10][dc] = source[r*srcStep + c];
+
+       barrier(CLK_LOCAL_MEM_FENCE);
+
+       int x =get_local_id(0);
+       int y =get_local_id(1);
+       uchar p0=data[y][x], p1=data[y][x+1], p2=data[y][x+2], p3=data[y][x+3], p4=data[y][x+4];
+       uchar p5=data[y+1][x], p6=data[y+1][x+1], p7=data[y+1][x+2], p8=data[y+1][x+3], p9=data[y+1][x+4];
+       uchar p10=data[y+2][x], p11=data[y+2][x+1], p12=data[y+2][x+2], p13=data[y+2][x+3], p14=data[y+2][x+4];
+       uchar p15=data[y+3][x], p16=data[y+3][x+1], p17=data[y+3][x+2], p18=data[y+3][x+3], p19=data[y+3][x+4];
+       uchar p20=data[y+4][x], p21=data[y+4][x+1], p22=data[y+4][x+2], p23=data[y+4][x+3], p24=data[y+4][x+4];
+       uchar mid;
+
+       op(p1, p2); op(p0, p1); op(p1, p2); op(p4, p5); op(p3, p4);
+    op(p4, p5); op(p0, p3); op(p2, p5); op(p2, p3); op(p1, p4);
+    op(p1, p2); op(p3, p4); op(p7, p8); op(p6, p7); op(p7, p8);
+    op(p10, p11); op(p9, p10); op(p10, p11); op(p6, p9); op(p8, p11);
+    op(p8, p9); op(p7, p10); op(p7, p8); op(p9, p10); op(p0, p6);
+    op(p4, p10); op(p4, p6); op(p2, p8); op(p2, p4); op(p6, p8);
+    op(p1, p7); op(p5, p11); op(p5, p7); op(p3, p9); op(p3, p5);
+    op(p7, p9); op(p1, p2); op(p3, p4); op(p5, p6); op(p7, p8);
+    op(p9, p10); op(p13, p14); op(p12, p13); op(p13, p14); op(p16, p17);
+    op(p15, p16); op(p16, p17); op(p12, p15); op(p14, p17); op(p14, p15);
+    op(p13, p16); op(p13, p14); op(p15, p16); op(p19, p20); op(p18, p19);
+    op(p19, p20); op(p21, p22); op(p23, p24); op(p21, p23); op(p22, p24);
+    op(p22, p23); op(p18, p21); op(p20, p23); op(p20, p21); op(p19, p22);
+    op(p22, p24); op(p19, p20); op(p21, p22); op(p23, p24); op(p12, p18);
+    op(p16, p22); op(p16, p18); op(p14, p20); op(p20, p24); op(p14, p16);
+    op(p18, p20); op(p22, p24); op(p13, p19); op(p17, p23); op(p17, p19);
+    op(p15, p21); op(p15, p17); op(p19, p21); op(p13, p14); op(p15, p16);
+    op(p17, p18); op(p19, p20); op(p21, p22); op(p23, p24); op(p0, p12);
+    op(p8, p20); op(p8, p12); op(p4, p16); op(p16, p24); op(p12, p16);
+    op(p2, p14); op(p10, p22); op(p10, p14); op(p6, p18); op(p6, p10);
+    op(p10, p12); op(p1, p13); op(p9, p21); op(p9, p13); op(p5, p17);
+    op(p13, p17); op(p3, p15); op(p11, p23); op(p11, p15); op(p7, p19);
+    op(p7, p11); op(p11, p13); op(p11, p12);
+       
+       if(get_global_id(1)<rows && get_global_id(0)<cols)
+               dst[dstOffset + get_global_id(1)*dstStep + get_global_id(0)]=p12;
+}
+#undef op(a,b)
+
+#define op(a,b) {mid=a; a=min(a,b); b=max(mid,b);}
+__kernel void medianFilter5_C4_D5(__global float4 * src, __global float4 * dst,  int srcOffset, int dstOffset, int cols,
+                                int rows, int srcStep, int dstStep)
+{
+       
+       __local float4 data[20][20];
+       __global float4* source=src + srcOffset;
+
+       int dx = get_global_id(0) - get_local_id(0) -2;
+    int dy = get_global_id(1) - get_local_id(1) -2;
+    
+       const int id = min((int)(get_local_id(0)*16+get_local_id(1)), 10*20-1);
+
+       int dr=id/20;
+       int dc=id%20;
+       int r=clamp(dy+dr, 0, rows-1);
+       int c=clamp(dx+dc, 0, cols-1);
+
+       data[dr][dc] = source[r*srcStep + c];
+       r=clamp(dy+dr+10, 0, rows-1);
+       data[dr+10][dc] = source[r*srcStep + c];
+
+       barrier(CLK_LOCAL_MEM_FENCE);
+
+       int x =get_local_id(0);
+       int y =get_local_id(1);
+       float4 p0=data[y][x], p1=data[y][x+1], p2=data[y][x+2], p3=data[y][x+3], p4=data[y][x+4];
+       float4 p5=data[y+1][x], p6=data[y+1][x+1], p7=data[y+1][x+2], p8=data[y+1][x+3], p9=data[y+1][x+4];
+       float4 p10=data[y+2][x], p11=data[y+2][x+1], p12=data[y+2][x+2], p13=data[y+2][x+3], p14=data[y+2][x+4];
+       float4 p15=data[y+3][x], p16=data[y+3][x+1], p17=data[y+3][x+2], p18=data[y+3][x+3], p19=data[y+3][x+4];
+       float4 p20=data[y+4][x], p21=data[y+4][x+1], p22=data[y+4][x+2], p23=data[y+4][x+3], p24=data[y+4][x+4];
+       float4 mid;
+
+       op(p1, p2); op(p0, p1); op(p1, p2); op(p4, p5); op(p3, p4);
+    op(p4, p5); op(p0, p3); op(p2, p5); op(p2, p3); op(p1, p4);
+    op(p1, p2); op(p3, p4); op(p7, p8); op(p6, p7); op(p7, p8);
+    op(p10, p11); op(p9, p10); op(p10, p11); op(p6, p9); op(p8, p11);
+    op(p8, p9); op(p7, p10); op(p7, p8); op(p9, p10); op(p0, p6);
+    op(p4, p10); op(p4, p6); op(p2, p8); op(p2, p4); op(p6, p8);
+    op(p1, p7); op(p5, p11); op(p5, p7); op(p3, p9); op(p3, p5);
+    op(p7, p9); op(p1, p2); op(p3, p4); op(p5, p6); op(p7, p8);
+    op(p9, p10); op(p13, p14); op(p12, p13); op(p13, p14); op(p16, p17);
+    op(p15, p16); op(p16, p17); op(p12, p15); op(p14, p17); op(p14, p15);
+    op(p13, p16); op(p13, p14); op(p15, p16); op(p19, p20); op(p18, p19);
+    op(p19, p20); op(p21, p22); op(p23, p24); op(p21, p23); op(p22, p24);
+    op(p22, p23); op(p18, p21); op(p20, p23); op(p20, p21); op(p19, p22);
+    op(p22, p24); op(p19, p20); op(p21, p22); op(p23, p24); op(p12, p18);
+    op(p16, p22); op(p16, p18); op(p14, p20); op(p20, p24); op(p14, p16);
+    op(p18, p20); op(p22, p24); op(p13, p19); op(p17, p23); op(p17, p19);
+    op(p15, p21); op(p15, p17); op(p19, p21); op(p13, p14); op(p15, p16);
+    op(p17, p18); op(p19, p20); op(p21, p22); op(p23, p24); op(p0, p12);
+    op(p8, p20); op(p8, p12); op(p4, p16); op(p16, p24); op(p12, p16);
+    op(p2, p14); op(p10, p22); op(p10, p14); op(p6, p18); op(p6, p10);
+    op(p10, p12); op(p1, p13); op(p9, p21); op(p9, p13); op(p5, p17);
+    op(p13, p17); op(p3, p15); op(p11, p23); op(p11, p15); op(p7, p19);
+    op(p7, p11); op(p11, p13); op(p11, p12);
+       
+       if(get_global_id(1)<rows && get_global_id(0)<cols)
+               dst[dstOffset + get_global_id(1)*dstStep + get_global_id(0)]=p12;
+}
+#undef op(a,b)
+
+#define op(a,b) {mid=a; a=min(a,b); b=max(mid,b);}
+__kernel void medianFilter5_C1_D5(__global float * src, __global float * dst,  int srcOffset, int dstOffset, int cols,
+                                int rows, int srcStep, int dstStep)
+{
+       
+       __local float data[20][20];
+       __global float* source=src + srcOffset;
+
+       int dx = get_global_id(0) - get_local_id(0) -2;
+    int dy = get_global_id(1) - get_local_id(1) -2;
+    
+       const int id = min((int)(get_local_id(0)*16+get_local_id(1)), 10*20-1);
+
+       int dr=id/20;
+       int dc=id%20;
+       int r=clamp(dy+dr, 0, rows-1);
+       int c=clamp(dx+dc, 0, cols-1);
+
+       data[dr][dc] = source[r*srcStep + c];
+       r=clamp(dy+dr+10, 0, rows-1);
+       data[dr+10][dc] = source[r*srcStep + c];
+
+       barrier(CLK_LOCAL_MEM_FENCE);
+
+       int x =get_local_id(0);
+       int y =get_local_id(1);
+       float p0=data[y][x], p1=data[y][x+1], p2=data[y][x+2], p3=data[y][x+3], p4=data[y][x+4];
+       float p5=data[y+1][x], p6=data[y+1][x+1], p7=data[y+1][x+2], p8=data[y+1][x+3], p9=data[y+1][x+4];
+       float p10=data[y+2][x], p11=data[y+2][x+1], p12=data[y+2][x+2], p13=data[y+2][x+3], p14=data[y+2][x+4];
+       float p15=data[y+3][x], p16=data[y+3][x+1], p17=data[y+3][x+2], p18=data[y+3][x+3], p19=data[y+3][x+4];
+       float p20=data[y+4][x], p21=data[y+4][x+1], p22=data[y+4][x+2], p23=data[y+4][x+3], p24=data[y+4][x+4];
+       float mid;
+
+       op(p1, p2); op(p0, p1); op(p1, p2); op(p4, p5); op(p3, p4);
+    op(p4, p5); op(p0, p3); op(p2, p5); op(p2, p3); op(p1, p4);
+    op(p1, p2); op(p3, p4); op(p7, p8); op(p6, p7); op(p7, p8);
+    op(p10, p11); op(p9, p10); op(p10, p11); op(p6, p9); op(p8, p11);
+    op(p8, p9); op(p7, p10); op(p7, p8); op(p9, p10); op(p0, p6);
+    op(p4, p10); op(p4, p6); op(p2, p8); op(p2, p4); op(p6, p8);
+    op(p1, p7); op(p5, p11); op(p5, p7); op(p3, p9); op(p3, p5);
+    op(p7, p9); op(p1, p2); op(p3, p4); op(p5, p6); op(p7, p8);
+    op(p9, p10); op(p13, p14); op(p12, p13); op(p13, p14); op(p16, p17);
+    op(p15, p16); op(p16, p17); op(p12, p15); op(p14, p17); op(p14, p15);
+    op(p13, p16); op(p13, p14); op(p15, p16); op(p19, p20); op(p18, p19);
+    op(p19, p20); op(p21, p22); op(p23, p24); op(p21, p23); op(p22, p24);
+    op(p22, p23); op(p18, p21); op(p20, p23); op(p20, p21); op(p19, p22);
+    op(p22, p24); op(p19, p20); op(p21, p22); op(p23, p24); op(p12, p18);
+    op(p16, p22); op(p16, p18); op(p14, p20); op(p20, p24); op(p14, p16);
+    op(p18, p20); op(p22, p24); op(p13, p19); op(p17, p23); op(p17, p19);
+    op(p15, p21); op(p15, p17); op(p19, p21); op(p13, p14); op(p15, p16);
+    op(p17, p18); op(p19, p20); op(p21, p22); op(p23, p24); op(p0, p12);
+    op(p8, p20); op(p8, p12); op(p4, p16); op(p16, p24); op(p12, p16);
+    op(p2, p14); op(p10, p22); op(p10, p14); op(p6, p18); op(p6, p10);
+    op(p10, p12); op(p1, p13); op(p9, p21); op(p9, p13); op(p5, p17);
+    op(p13, p17); op(p3, p15); op(p11, p23); op(p11, p15); op(p7, p19);
+    op(p7, p11); op(p11, p13); op(p11, p12);
+       
+       if(get_global_id(1)<rows && get_global_id(0)<cols)
+               dst[dstOffset + get_global_id(1)*dstStep + get_global_id(0)]=p12;
+}
+#undef op(a,b)
+
diff --git a/modules/ocl/src/kernels/imgproc_remap.cl b/modules/ocl/src/kernels/imgproc_remap.cl
new file mode 100644 (file)
index 0000000..81ea56d
--- /dev/null
@@ -0,0 +1,555 @@
+
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Wu Zailong, bullet@yeah.net
+//
+// 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 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
+// 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_amd_printf : enable
+
+#if defined DOUBLE_SUPPORT
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+__kernel void remapNNSConstant_C1_D0(__global unsigned char* dst, __global unsigned char const * restrict  src,
+        __global short * map1, int dst_offset, int src_offset, int map1_offset, int dst_step, int src_step,
+        int map1_step, int src_cols, int src_rows, int dst_cols, int dst_rows, int map1_cols, int map1_rows , double4 nVal)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+    /*
+    if(x < dst_cols && y < dst_rows)
+    {
+        int dstIdx = y * dst_step + x + dst_offset;
+        int map1Idx = y * (map1_step>>2) + x + (map1_offset>>2) - (map1_offset & 1);
+        short2 map1_data = *(map1 + map1Idx);
+        int srcIdx = map1_data.y*src_step+map1_data.x + src_offset;       
+        uchar src_data = *(src +srcIdx);      
+        uchar dst_data = src_data; 
+        *(dst +dstIdx)=(map1_data.x >= map1_cols || map1_data.y >= map1_rows) ? val : dst_data;
+    }
+    */
+    
+    int gx = (x << 2) - (dst_offset&3);
+    int4 Gx = (int4)(gx, gx+1, gx+2, gx+3);
+
+    uchar4 nval =convert_uchar4(nVal);
+    char val = nval.s0;
+
+    x = x << 2;
+
+    int dstStart = (y * dst_step + x  + dst_offset) - (dst_offset&3);
+
+    int map1Start = y * map1_step + (x << 2) + map1_offset - ((dst_offset & 3) << 2);
+    short8 map1_data;
+
+     map1_data.s01 = *((__global short2 *)((__global char*)map1 + map1Start));
+     map1_data.s23 = *((__global short2 *)((__global char*)map1 + map1Start + 4));
+     map1_data.s45 = *((__global short2 *)((__global char*)map1 + map1Start + 8));
+     map1_data.s67 = *((__global short2 *)((__global char*)map1 + map1Start + 12));
+    
+    int4 srcIdx ;
+    srcIdx.s0 = map1_data.s1 * src_step + map1_data.s0 + src_offset;
+    srcIdx.s1 = map1_data.s3 * src_step + map1_data.s2 + src_offset;
+    srcIdx.s2 = map1_data.s5 * src_step + map1_data.s4 + src_offset;
+    srcIdx.s3 = map1_data.s7 * src_step + map1_data.s6 + src_offset;
+    
+        //uchar4 src_data = *(src + srcIdx);
+    uchar4 src_data;
+    src_data.s0 = *(src + srcIdx.s0);
+    src_data.s1 = *(src + srcIdx.s1);
+    src_data.s2 = *(src + srcIdx.s2);
+    src_data.s3 = *(src + srcIdx.s3);
+
+    uchar4 dst_data;
+    dst_data.s0 = (map1_data.s0 >= src_cols || map1_data.s1 >= src_rows)? val : src_data.s0;
+    dst_data.s1 = (map1_data.s2 >= src_cols || map1_data.s3 >= src_rows)? val : src_data.s1;
+    dst_data.s2 = (map1_data.s4 >= src_cols || map1_data.s5 >= src_rows)? val : src_data.s2;
+    dst_data.s3 = (map1_data.s6 >= src_cols || map1_data.s7 >= src_rows)? val : src_data.s3;
+    
+    __global uchar4* d = (__global uchar4 *)(dst + dstStart);
+
+    uchar4 dVal = *d;      
+    int4 con = (Gx >= 0 && Gx < dst_cols && y >= 0 && y < dst_rows);
+    dst_data = (convert_uchar4(con) != 0) ? dst_data : dVal;
+
+    *d = dst_data;
+}
+
+__kernel void remapNNSConstant_C2_D0(__global unsigned char* dst, __global unsigned char const * restrict  src,
+        __global short * map1, int dst_offset, int src_offset, int map1_offset, int dst_step, int src_step,
+        int map1_step, int src_cols, int src_rows, int dst_cols, int dst_rows, int map1_cols, int map1_rows , double4 nVal)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+    int gx = (x << 3) - (dst_offset&7);
+    int8 Gx = (int8)(gx, gx+1, gx+2, gx+3, gx+4, gx+5, gx+6, gx+7);
+
+    uchar4 nval =convert_uchar4(nVal);
+    uchar2 val = nval.s01;//testing
+
+    x = x << 3;
+
+    int dstStart = (y * dst_step + x + dst_offset) - (dst_offset&7);
+
+    int map1Start = y * map1_step + (x << 1) + map1_offset - (((dst_offset>>1) & 3) << 2);
+    short8 map1_data;
+
+     map1_data.s01 = *((__global short2 *)((__global char*)map1 + map1Start));
+     map1_data.s23 = *((__global short2 *)((__global char*)map1 + map1Start + 4));
+     map1_data.s45 = *((__global short2 *)((__global char*)map1 + map1Start + 8));
+     map1_data.s67 = *((__global short2 *)((__global char*)map1 + map1Start + 12));
+    
+    int4 srcIdx ;
+    srcIdx.s0 = map1_data.s1 * src_step + (map1_data.s0 << 1) + src_offset;
+    srcIdx.s1 = map1_data.s3 * src_step + (map1_data.s2 << 1) + src_offset;
+    srcIdx.s2 = map1_data.s5 * src_step + (map1_data.s4 << 1) + src_offset;
+    srcIdx.s3 = map1_data.s7 * src_step + (map1_data.s6 << 1) + src_offset;
+    
+        //uchar4 src_data = *(src + srcIdx);
+    uchar8 src_data;
+    src_data.s01 = *((__global uchar2 *)((__global char*)src + srcIdx.s0));
+    src_data.s23 = *((__global uchar2 *)((__global char*)src + srcIdx.s1));
+    src_data.s45 = *((__global uchar2 *)((__global char*)src + srcIdx.s2));
+    src_data.s67 = *((__global uchar2 *)((__global char*)src + srcIdx.s3));
+
+    uchar8 dst_data;
+    dst_data.s01 = (map1_data.s0 >= src_cols || map1_data.s1 >= src_rows) ? val : (convert_uchar2(src_data.s01));
+    dst_data.s23 = (map1_data.s2 >= src_cols || map1_data.s3 >= src_rows) ? val : (convert_uchar2(src_data.s23));
+    dst_data.s45 = (map1_data.s4 >= src_cols || map1_data.s5 >= src_rows) ? val : (convert_uchar2(src_data.s45));
+    dst_data.s67 = (map1_data.s6 >= src_cols || map1_data.s7 >= src_rows) ? val : (convert_uchar2(src_data.s67));
+    __global uchar8* d = (__global uchar8 *)(dst + dstStart);
+
+    uchar8 dVal = *d;      
+    int8 con = (Gx >= 0 && Gx < (dst_cols << 1) && y >= 0 && y < dst_rows);
+    dst_data = (convert_uchar8(con) != 0) ? dst_data : dVal;
+    *d = dst_data;
+}
+__kernel void remapNNSConstant_C4_D0(__global unsigned char* dst, __global unsigned char const * restrict  src,
+        __global short * map1, int dst_offset, int src_offset, int map1_offset, int dst_step, int src_step,
+        int map1_step, int src_cols, int src_rows, int dst_cols, int dst_rows, int map1_cols, int map1_rows , double4 nVal)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+    int gx = (x << 4) - (dst_offset&15);
+    int16 Gx = (int16)(gx, gx+1, gx+2, gx+3, gx+4, gx+5, gx+6, gx+7, gx+8, gx+9, gx+10, gx+11, gx+12, gx+13, gx+14, gx+15);
+
+    uchar4 nval =convert_uchar4(nVal);
+
+    x = x << 4;
+
+    int dstStart = (y * dst_step + x + dst_offset) - (dst_offset&15);
+
+    int map1Start = y * map1_step + x + map1_offset - (((dst_offset>>2) & 3) << 2);
+    short8 map1_data;
+
+     map1_data.s01 = *((__global short2 *)((__global char*)map1 + map1Start));
+     map1_data.s23 = *((__global short2 *)((__global char*)map1 + map1Start + 4));
+     map1_data.s45 = *((__global short2 *)((__global char*)map1 + map1Start + 8));
+     map1_data.s67 = *((__global short2 *)((__global char*)map1 + map1Start + 12));
+    
+    int4 srcIdx ;
+    srcIdx.s0 = map1_data.s1 * src_step + (map1_data.s0 << 2) + src_offset;
+    srcIdx.s1 = map1_data.s3 * src_step + (map1_data.s2 << 2) + src_offset;
+    srcIdx.s2 = map1_data.s5 * src_step + (map1_data.s4 << 2) + src_offset;
+    srcIdx.s3 = map1_data.s7 * src_step + (map1_data.s6 << 2) + src_offset;
+    
+  //  uchar16 src_data;
+    uchar4 src_a, src_b, src_c, src_d;
+    src_a = *((__global uchar4 *)((__global char*)src + srcIdx.s0));
+    src_b = *((__global uchar4 *)((__global char*)src + srcIdx.s1));
+    src_c = *((__global uchar4 *)((__global char*)src + srcIdx.s2));
+    src_d = *((__global uchar4 *)((__global char*)src + srcIdx.s3));
+  //  src_data = (uchar16)(src_a, src_b, src_c, src_d);
+    uchar16 dst_data;
+    uchar4 dst_a, dst_b, dst_c, dst_d;
+    dst_a = (map1_data.s0 >= src_cols || map1_data.s1 >= src_rows) ? nval : src_a;
+    dst_b = (map1_data.s2 >= src_cols || map1_data.s3 >= src_rows) ? nval : src_b;
+    dst_c = (map1_data.s4 >= src_cols || map1_data.s5 >= src_rows) ? nval : src_c;
+    dst_d = (map1_data.s6 >= src_cols || map1_data.s7 >= src_rows) ? nval : src_d;
+    dst_data = (uchar16)(dst_a, dst_b, dst_c, dst_d);
+    __global uchar16* d = (__global uchar16 *)(dst + dstStart);
+
+    uchar16 dVal = *d;      
+    int16 con = (Gx >= 0 && Gx < (dst_cols << 2) && y >= 0 && y < dst_rows);
+    dst_data = (convert_uchar16(con) != 0) ? dst_data : dVal;
+
+    *d = dst_data;
+}
+
+__kernel void remapNNFConstant_C1_D0(__global unsigned char* dst, __global unsigned char const * restrict  src,
+        __global float * map1, int dst_offset, int src_offset, int map1_offset, int dst_step, int src_step,
+        int map1_step, int src_cols, int src_rows, int dst_cols, int dst_rows, int map1_cols, int map1_rows , double4 nVal)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+     
+    int gx = (x << 2) - (dst_offset&3);
+    int4 Gx = (int4)(gx, gx+1, gx+2, gx+3);
+
+    uchar4 nval =convert_uchar4_sat_rte(nVal);
+    char val = nval.s0;
+
+    x = x << 2;
+
+    int dstStart = (y * dst_step + x  + dst_offset) - (dst_offset&3);
+
+    int map1Start = y * map1_step + (x << 3) + map1_offset - ((dst_offset & 3) << 3);
+    float8 map1_data;
+
+    map1_data = *((__global float8 *)((__global char*)map1 + map1Start));
+ /*   map1_data.s01 = *((__global float2 *)((__global char*)map1 + map1Start));
+    map1_data.s23 = *((__global float2 *)((__global char*)map1 + map1Start + 8));
+    map1_data.s45 = *((__global float2 *)((__global char*)map1 + map1Start + 16));
+    map1_data.s67 = *((__global float2 *)((__global char*)map1 + map1Start + 24));
+*/
+    int8 map1_dataZ;
+
+    map1_dataZ = convert_int8_sat_rte(map1_data);
+
+    int4 srcIdx ;
+    srcIdx.s0 = map1_dataZ.s1 * src_step + map1_dataZ.s0 + src_offset;
+    srcIdx.s1 = map1_dataZ.s3 * src_step + map1_dataZ.s2 + src_offset;
+    srcIdx.s2 = map1_dataZ.s5 * src_step + map1_dataZ.s4 + src_offset;
+    srcIdx.s3 = map1_dataZ.s7 * src_step + map1_dataZ.s6 + src_offset;
+    
+        //uchar4 src_data = *(src + srcIdx);
+    uchar4 src_data;
+    src_data.s0 = *(src + srcIdx.s0);
+    src_data.s1 = *(src + srcIdx.s1);
+    src_data.s2 = *(src + srcIdx.s2);
+    src_data.s3 = *(src + srcIdx.s3);
+
+    uchar4 dst_data;
+    dst_data.s0 = (map1_dataZ.s0 >= src_cols || map1_dataZ.s1 >= src_rows)? val : src_data.s0;
+    dst_data.s1 = (map1_dataZ.s2 >= src_cols || map1_dataZ.s3 >= src_rows)? val : src_data.s1;
+    dst_data.s2 = (map1_dataZ.s4 >= src_cols || map1_dataZ.s5 >= src_rows)? val : src_data.s2;
+    dst_data.s3 = (map1_dataZ.s6 >= src_cols || map1_dataZ.s7 >= src_rows)? val : src_data.s3;
+    
+    __global uchar4* d = (__global uchar4 *)(dst + dstStart);
+
+    uchar4 dVal = *d;      
+    int4 con = (Gx >= 0 && Gx < dst_cols && y >= 0 && y < dst_rows);
+    dst_data = (convert_uchar4(con) != 0) ? dst_data : dVal;
+
+    *d = dst_data;
+}
+
+
+__kernel void remapLNFConstant_C1_D0(__global unsigned char* dst, __global unsigned char const * restrict  src,
+        __global float * map1, int dst_offset, int src_offset, int map1_offset, int dst_step, int src_step,
+        int map1_step, int src_cols, int src_rows, int dst_cols, int dst_rows, int map1_cols, int map1_rows , double4 nVal)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+     
+    int gx = (x << 2) - (dst_offset&3);
+    int4 Gx = (int4)(gx, gx+1, gx+2, gx+3);
+
+    uchar4 nval =convert_uchar4(nVal);
+    uchar val = nval.s0;
+  
+    x = x << 2;
+
+    int dstStart = (y * dst_step + x  + dst_offset) - (dst_offset&3);
+
+    int map1Start = y * map1_step + (x << 3) + map1_offset - ((dst_offset & 3) << 3);
+    float8 map1_data;
+
+    map1_data = *((__global float8 *)((__global char*)map1 + map1Start));
+    int8 map1_dataD = convert_int8(map1_data);
+    float8 temp = map1_data - convert_float8(map1_dataD);
+
+    float4 u = temp.even;
+    float4 v = temp.odd;
+    float4 ud = 1.0 - u;
+    float4 vd = 1.0 - v;
+    //float8 map1_dataU = map1_dataD + 1;
+
+    int4 map1_dataDx = map1_dataD.even;
+    int4 map1_dataDy = map1_dataD.odd;
+    int4 map1_dataDx1 = map1_dataDx + 1;
+    int4 map1_dataDy1 = map1_dataDy + 1;
+
+    int4 src_StartU = map1_dataDy * src_step + map1_dataDx + src_offset;
+    int4 src_StartD = src_StartU + src_step;
+    int4 src_StartU1 = src_StartU + 1;
+    int4 src_StartD1 = src_StartD + 1;
+
+    uchar4 a, b, c, d;
+    a.x = *(src_StartU.x + src);
+    a.y = *(src_StartU.y + src);
+    a.z = *(src_StartU.z + src);
+    a.w = *(src_StartU.w + src);
+    
+    b.x = *(src_StartU1.x + src);
+    b.y = *(src_StartU1.y + src);
+    b.z = *(src_StartU1.z + src);
+    b.w = *(src_StartU1.w + src);
+
+    c.x = *(src_StartD.x + src);
+    c.y = *(src_StartD.y + src);
+    c.z = *(src_StartD.z + src);
+    c.w = *(src_StartD.w + src);
+
+    d.x = *(src_StartD1.x + src);
+    d.y = *(src_StartD1.y + src);
+    d.z = *(src_StartD1.z + src);
+    d.w = *(src_StartD1.w + src);
+    int4 ac =(map1_dataDx >= src_cols || map1_dataDy >= src_rows || map1_dataDy< 0 || map1_dataDy < 0);
+    int4 bc =(map1_dataDx1 >= src_cols || map1_dataDy >= src_rows || map1_dataDx1 < 0 || map1_dataDy < 0);
+    int4 cc =(map1_dataDx >= src_cols || map1_dataDy1 >= src_rows || map1_dataDy1 < 0 || map1_dataDx < 0);
+    int4 dc =(map1_dataDx1 >= src_cols || map1_dataDy1 >= src_rows || map1_dataDy1 < 0 || map1_dataDy1 < 0);
+    a = (convert_uchar4(ac) == 0)? a : val;
+    b = (convert_uchar4(bc) == 0)? b : val;
+    c = (convert_uchar4(cc) == 0)? c : val;
+    d = (convert_uchar4(dc) == 0)? d : val;
+
+    uchar4 dst_data = convert_uchar4_sat_rte((convert_float4(a))* ud * vd +(convert_float4(b))* u * vd + (convert_float4(c))* ud * v + (convert_float4(d)) * u * v );
+    
+    __global uchar4* D = (__global uchar4 *)(dst + dstStart);
+
+    uchar4 dVal = *D;      
+    int4 con = (Gx >= 0 && Gx < dst_cols && y >= 0 && y < dst_rows);
+    dst_data = (convert_uchar4(con) != 0) ? dst_data : dVal;
+
+    *D = dst_data;
+}
+
+
+__kernel void remapLNFConstant_C2_D0(__global unsigned char* dst, __global unsigned char const * restrict  src,
+        __global float * map1, int dst_offset, int src_offset, int map1_offset, int dst_step, int src_step,
+        int map1_step, int src_cols, int src_rows, int dst_cols, int dst_rows, int map1_cols, int map1_rows , double4 nVal)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+     
+    int gx = (x << 3) - (dst_offset&7);
+    int8 Gx = (int8)(gx, gx+1, gx+2, gx+3, gx+4, gx+5, gx+6, gx+7);
+
+    uchar4 nval =convert_uchar4(nVal);
+    uchar8 val = (uchar8)(nval.s01, nval.s01, nval.s01, nval.s01);
+  
+    x = x << 3;
+
+    int dstStart = (y * dst_step + x  + dst_offset) - (dst_offset&7);
+
+    int map1Start = y * map1_step + (x << 2) + map1_offset - (((dst_offset>>1) & 3) << 3);
+    float8 map1_data;
+
+    map1_data = *((__global float8 *)((__global char*)map1 + map1Start));
+    int8 map1_dataD = convert_int8(map1_data);
+    float8 temp = map1_data - convert_float8(map1_dataD);
+
+    float4 U = temp.even;
+    float4 V = temp.odd;
+    float4 UD = 1.0 - U;
+    float4 VD = 1.0 - V;
+
+    float8 u, v, ud, vd;
+    u = (float8)(U.x, U.x, U.y, U.y, U.z, U.z, U.w, U.w);
+    v = (float8)(V.x, V.x, V.y, V.y, V.z, V.z, V.w, V.w);
+    ud = (float8)(UD.x, UD.x, UD.y, UD.y, UD.z, UD.z, UD.w, UD.w);
+    vd = (float8)(VD.x, VD.x, VD.y, VD.y, VD.z, VD.z, VD.w, VD.w);
+
+    //float8 map1_dataU = map1_dataD + 1;
+
+    int4 map1_dataDx = map1_dataD.even;
+    int4 map1_dataDy = map1_dataD.odd;
+    int4 map1_dataDx1 = map1_dataDx + 1;
+    int4 map1_dataDy1 = map1_dataDy + 1;
+
+    int4 src_StartU = map1_dataDy * src_step + (map1_dataDx << 1) + src_offset;
+    int4 src_StartD = src_StartU + src_step;
+    int4 src_StartU1 = src_StartU + 2;
+    int4 src_StartD1 = src_StartD + 2;
+
+    uchar8 a, b, c, d;
+    a.s01 = *((__global uchar2 *)((__global char*)src + src_StartU.x));
+    a.s23 = *((__global uchar2 *)((__global char*)src + src_StartU.y));
+    a.s45 = *((__global uchar2 *)((__global char*)src + src_StartU.z));
+    a.s67 = *((__global uchar2 *)((__global char*)src + src_StartU.w));
+
+    b.s01 = *((__global uchar2 *)((__global char*)src + src_StartU1.x));
+    b.s23 = *((__global uchar2 *)((__global char*)src + src_StartU1.y));
+    b.s45 = *((__global uchar2 *)((__global char*)src + src_StartU1.z));
+    b.s67 = *((__global uchar2 *)((__global char*)src + src_StartU1.w));
+
+    c.s01 = *((__global uchar2 *)((__global char*)src + src_StartD.x));
+    c.s23 = *((__global uchar2 *)((__global char*)src + src_StartD.y));
+    c.s45 = *((__global uchar2 *)((__global char*)src + src_StartD.z));
+    c.s67 = *((__global uchar2 *)((__global char*)src + src_StartD.w));
+
+    d.s01 = *((__global uchar2 *)((__global char*)src + src_StartD1.x));
+    d.s23 = *((__global uchar2 *)((__global char*)src + src_StartD1.y));
+    d.s45 = *((__global uchar2 *)((__global char*)src + src_StartD1.z));
+    d.s67 = *((__global uchar2 *)((__global char*)src + src_StartD1.w));
+
+    int4 ac =(map1_dataDx >= src_cols || map1_dataDy >= src_rows || map1_dataDy< 0 || map1_dataDy < 0);
+    int4 bc =(map1_dataDx1 >= src_cols || map1_dataDy >= src_rows || map1_dataDx1 < 0 || map1_dataDy < 0);
+    int4 cc =(map1_dataDx >= src_cols || map1_dataDy1 >= src_rows || map1_dataDy1 < 0 || map1_dataDx < 0);
+    int4 dc =(map1_dataDx1 >= src_cols || map1_dataDy1 >= src_rows || map1_dataDy1 < 0 || map1_dataDy1 < 0);
+
+ /*   a.even = (convert_uchar4(ac) == 0)? a.even : val.even;
+    a.odd = (convert_uchar4(ac) == 0)? a.odd : val.odd;
+    b.even = (convert_uchar4(bc) == 0)? b.even : val.even;
+    b.odd = (convert_uchar4(bc) == 0)? b.odd : val.odd;
+    c.even = (convert_uchar4(cc) == 0)? c.even : val.even;
+    c.odd = (convert_uchar4(cc) == 0)? c.odd : val.odd;
+    d.even = (convert_uchar4(dc) == 0)? d.even : val.even;
+    d.odd = (convert_uchar4(dc) == 0)? d.odd : val.odd;
+*/
+    int8 aC = (int8)(ac.x, ac.x, ac.y, ac.y, ac.z, ac.z, ac.w, ac.w);
+    int8 bC = (int8)(bc.x, bc.x, bc.y, bc.y, bc.z, bc.z, bc.w, bc.w);
+    int8 cC = (int8)(cc.x, cc.x, cc.y, cc.y, cc.z, cc.z, cc.w, cc.w);
+    int8 dC = (int8)(dc.x, dc.x, dc.y, dc.y, dc.z, dc.z, dc.w, dc.w);
+
+    a = (convert_uchar8(aC) == 0)? a : val;
+    b = (convert_uchar8(bC) == 0)? b : val;
+    c = (convert_uchar8(cC) == 0)? c : val;
+    d = (convert_uchar8(dC) == 0)? d : val;
+    uchar8 dst_data = convert_uchar8_sat_rte((convert_float8(a))* ud * vd +(convert_float8(b))* u * vd + (convert_float8(c))* ud * v + (convert_float8(d)) * u * v );
+    
+    __global uchar8* D = (__global uchar8 *)(dst + dstStart);
+
+    uchar8 dVal = *D;      
+    int8 con = (Gx >= 0 && Gx < (dst_cols << 1) && y >= 0 && y < dst_rows);
+    dst_data = (convert_uchar8(con) != 0) ? dst_data : dVal;
+
+    *D = dst_data;
+}
+
+/*
+__kernel void remapLNFConstant_C4_D0(__global unsigned char* dst, __global unsigned char const * restrict  src,
+        __global float * map1, int dst_offset, int src_offset, int map1_offset, int dst_step, int src_step,
+        int map1_step, int src_cols, int src_rows, int dst_cols, int dst_rows, int map1_cols, int map1_rows , double4 nVal)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+     
+    int gx = (x << 4) - (dst_offset&15);
+    int16 Gx = (int16)(gx, gx+1, gx+2, gx+3, gx+4, gx+5, gx+6, gx+7, gx+8, gx+9, gx+10, gx+11, gx+12, gx+13, gx+14, gx+15);
+
+    uchar4 nval =convert_uchar4(nVal);
+    uchar16 val = (uchar16)(nval.s01, nval.s01, nval.s01, nval.s01, nval.s01, nval.s01, nval.s01, nval.s01, nval.s01, nval.s01, nval.s01, nval.s01, nval.s01, nval.s01, nval.s01, nval.s01);
+  
+    x = x << 4;
+
+    int dstStart = (y * dst_step + x  + dst_offset) - (dst_offset&15);
+
+    int map1Start = y * map1_step + (x << 1) + map1_offset - (((dst_offset>>2) & 3) << 3);
+    float8 map1_data;
+
+    map1_data = *((__global float8 *)((__global char*)map1 + map1Start));
+    int8 map1_dataD = convert_int8(map1_data);
+    float8 temp = map1_data - convert_float8(map1_dataD);
+
+    float4 U = temp.even;
+    float4 V = temp.odd;
+    float4 UD = 1.0 - U;
+    float4 VD = 1.0 - V;
+
+    float16 u, v, ud, vd;
+    u = (float16)(U.x, U.x, U.x, U.x, U.y, U.y, U.y, U.y, U.z, U.z, U.z, U.z, U.w, U.w, U.w, U.w);
+    v = (float16)(V.x, V.x, V.x, V.x, V.y, V.y, V.y, V.y, V.z, V.z, V.z, V.z, V.w, V.w, V.w, V.w);
+    ud = (float16)(UD.x, UD.x, UD.x, UD.x, UD.y, UD.y, UD.y, UD.y, UD.z, UD.z, UD.z, UD.z, UD.w, UD.w, UD.w, UD.w);
+    vd = (float16)(VD.x, VD.x, VD.y, VD.y, VD.z, VD.z, VD.w, VD.w);
+
+    //float8 map1_dataU = map1_dataD + 1;
+
+    int4 map1_dataDx = map1_dataD.even;
+    int4 map1_dataDy = map1_dataD.odd;
+    int4 map1_dataDx1 = map1_dataDx + 1;
+    int4 map1_dataDy1 = map1_dataDy + 1;
+
+    int4 src_StartU = map1_dataDy * src_step + (map1_dataDx << 1) + src_offset;
+    int4 src_StartD = src_StartU + src_step;
+    int4 src_StartU1 = src_StartU + 2;
+    int4 src_StartD1 = src_StartD + 2;
+
+    uchar8 a, b, c, d;
+    a.s01 = *((__global uchar2 *)((__global char*)src + src_StartU.x));
+    a.s23 = *((__global uchar2 *)((__global char*)src + src_StartU.y));
+    a.s45 = *((__global uchar2 *)((__global char*)src + src_StartU.z));
+    a.s67 = *((__global uchar2 *)((__global char*)src + src_StartU.w));
+
+    b.s01 = *((__global uchar2 *)((__global char*)src + src_StartU1.x));
+    b.s23 = *((__global uchar2 *)((__global char*)src + src_StartU1.y));
+    b.s45 = *((__global uchar2 *)((__global char*)src + src_StartU1.z));
+    b.s67 = *((__global uchar2 *)((__global char*)src + src_StartU1.w));
+
+    c.s01 = *((__global uchar2 *)((__global char*)src + src_StartD.x));
+    c.s23 = *((__global uchar2 *)((__global char*)src + src_StartD.y));
+    c.s45 = *((__global uchar2 *)((__global char*)src + src_StartD.z));
+    c.s67 = *((__global uchar2 *)((__global char*)src + src_StartD.w));
+
+    d.s01 = *((__global uchar2 *)((__global char*)src + src_StartD1.x));
+    d.s23 = *((__global uchar2 *)((__global char*)src + src_StartD1.y));
+    d.s45 = *((__global uchar2 *)((__global char*)src + src_StartD1.z));
+    d.s67 = *((__global uchar2 *)((__global char*)src + src_StartD1.w));
+
+    int4 ac =(map1_dataDx >= src_cols || map1_dataDy >= src_rows || map1_dataDy< 0 || map1_dataDy < 0);
+    int4 bc =(map1_dataDx1 >= src_cols || map1_dataDy >= src_rows || map1_dataDx1 < 0 || map1_dataDy < 0);
+    int4 cc =(map1_dataDx >= src_cols || map1_dataDy1 >= src_rows || map1_dataDy1 < 0 || map1_dataDx < 0);
+    int4 dc =(map1_dataDx1 >= src_cols || map1_dataDy1 >= src_rows || map1_dataDy1 < 0 || map1_dataDy1 < 0);
+
+    int8 aC = (int8)(ac.x, ac.x, ac.y, ac.y, ac.z, ac.z, ac.w, ac.w);
+    int8 bC = (int8)(bc.x, bc.x, bc.y, bc.y, bc.z, bc.z, bc.w, bc.w);
+    int8 cC = (int8)(cc.x, cc.x, cc.y, cc.y, cc.z, cc.z, cc.w, cc.w);
+    int8 dC = (int8)(dc.x, dc.x, dc.y, dc.y, dc.z, dc.z, dc.w, dc.w);
+
+    a = (convert_uchar8(aC) == 0)? a : val;
+    b = (convert_uchar8(bC) == 0)? b : val;
+    c = (convert_uchar8(cC) == 0)? c : val;
+    d = (convert_uchar8(dC) == 0)? d : val;
+    uchar8 dst_data = convert_uchar8_sat_rte((convert_float8(a))* ud * vd +(convert_float8(b))* u * vd + (convert_float8(c))* ud * v + (convert_float8(d)) * u * v );
+    
+    __global uchar8* D = (__global uchar8 *)(dst + dstStart);
+
+    uchar8 dVal = *D;      
+    int8 con = (Gx >= 0 && Gx < (dst_cols << 1) && y >= 0 && y < dst_rows);
+    dst_data = (convert_uchar8(con) != 0) ? dst_data : dVal;
+
+    *D = dst_data;
+    
+}
+*/
+
diff --git a/modules/ocl/src/kernels/imgproc_resize.cl b/modules/ocl/src/kernels/imgproc_resize.cl
new file mode 100644 (file)
index 0000000..2841886
--- /dev/null
@@ -0,0 +1,353 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Zhang Ying, zhangying913@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 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
+// 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*/
+
+
+// resize kernel 
+// Currently, CV_8UC1  CV_8UC4  CV_32FC1 and CV_32FC4are supported.
+// We shall support other types later if necessary.
+
+#if defined DOUBLE_SUPPORT
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+typedef double F ;
+#else 
+typedef float F;
+#endif
+
+inline uint4 getPoint_8uc4(__global uchar4 * data, int offset, int x, int y, int step)
+{
+    return convert_uint4(data[(offset>>2)+ y * (step>>2) + x]);
+}
+
+inline float getPoint_32fc1(__global float * data, int offset, int x, int y, int step)
+{
+    return data[(offset>>2)+ y * (step>>2) + x];
+}
+
+
+#define INTER_RESIZE_COEF_BITS 11
+#define INTER_RESIZE_COEF_SCALE (1 << INTER_RESIZE_COEF_BITS)
+#define CAST_BITS (INTER_RESIZE_COEF_BITS << 1)
+#define CAST_SCALE (1.0f/(1<<CAST_BITS))
+#define INC(x,l) ((x+1) >= (l) ? (x):((x)+1))
+
+__kernel void resizeLN_C1_D0(__global unsigned char * dst, __global unsigned char const * restrict 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 gx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    float4  sx, u, xf;
+    int4 x, DX;
+    gx = (gx<<2) - (dst_offset&3);
+    DX = (int4)(gx, gx+1, gx+2, gx+3);
+    sx = (convert_float4(DX) + 0.5f) * ifx - 0.5f;
+    xf = floor(sx);
+    x = convert_int4(xf);
+    u = sx - xf;
+    float sy = ((dy+0.5f) * ify - 0.5f);
+    int y = floor(sy);
+    float v = sy - y;
+    u = x < 0 ? 0 : u;
+    u = (x >= src_cols) ? 0 : u;
+    x = x < 0 ? 0 : x;
+    x = (x >= src_cols) ? src_cols-1 : x;
+    y<0 ? y=0,v=0 : y;
+    y>=src_rows ? y=src_rows-1,v=0 : y;
+    int4 U, U1;
+    int V, V1;
+    float4 utmp1, utmp2;
+    float vtmp;
+    float4 scale_vec = INTER_RESIZE_COEF_SCALE;
+    utmp1 = u * scale_vec;
+    utmp2 = scale_vec - utmp1;
+    U = convert_int4(rint(utmp1)); 
+    U1 = convert_int4(rint(utmp2)); 
+    vtmp = v * INTER_RESIZE_COEF_SCALE;
+    V = rint(vtmp);
+    V1= rint(INTER_RESIZE_COEF_SCALE - vtmp);
+
+    int y_ = INC(y,src_rows);
+    int4 x_;
+    x_ =  ((x+1 >= src_cols) != 0) ? x : x+1;
+
+    int4 val1, val2, val;
+    int4 sdata1, sdata2, sdata3, sdata4;
+
+    int4 pos1 = src_offset + y * src_step + x;
+    int4 pos2 = src_offset + y * src_step + x_;
+    int4 pos3 = src_offset + y_ * src_step + x;
+    int4 pos4 = src_offset + y_ * src_step + x_;
+
+    sdata1.s0 = src[pos1.s0];
+    sdata1.s1 = src[pos1.s1];
+    sdata1.s2 = src[pos1.s2];
+    sdata1.s3 = src[pos1.s3];
+
+    sdata2.s0 = src[pos2.s0];
+    sdata2.s1 = src[pos2.s1];
+    sdata2.s2 = src[pos2.s2];
+    sdata2.s3 = src[pos2.s3];
+
+    sdata3.s0 = src[pos3.s0];
+    sdata3.s1 = src[pos3.s1];
+    sdata3.s2 = src[pos3.s2];
+    sdata3.s3 = src[pos3.s3];
+
+    sdata4.s0 = src[pos4.s0];
+    sdata4.s1 = src[pos4.s1];
+    sdata4.s2 = src[pos4.s2];
+    sdata4.s3 = src[pos4.s3];
+
+    val1 = U1 * sdata1 + U * sdata2;
+    val2 = U1 * sdata3 + U * sdata4;
+    val = V1 * val1 + V * val2;
+    
+    __global uchar4* d = (__global uchar4*)(dst + dst_offset + dy * dst_step + gx);
+    uchar4 dVal = *d;
+    int4 con = ( DX >= 0 && DX < dst_cols && dy >= 0 && dy < dst_rows);
+    val = ((val + (1<<(CAST_BITS-1))) >> CAST_BITS);
+    *d = convert_uchar4(con != 0) ? convert_uchar4_sat(val) : dVal;
+    
+}
+
+__kernel void resizeLN_C4_D0(__global uchar4 * dst, __global 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);
+
+    float sx = ((dx+0.5f) * ifx - 0.5f), sy = ((dy+0.5f) * ify - 0.5f);
+    int x = floor(sx), y = floor(sy);
+    float u = sx - x, v = sy - y;
+
+    x<0 ? x=0,u=0 : x,u;
+    x>=src_cols ? x=src_cols-1,u=0 : x,u;
+    y<0 ? y=0,v=0 : y,v;
+    y>=src_rows ? y=src_rows-1,v=0 : y,v;
+    
+    u = u * INTER_RESIZE_COEF_SCALE;
+    v = v * INTER_RESIZE_COEF_SCALE;
+   
+    int U = rint(u);
+    int V = rint(v);
+    int U1= rint(INTER_RESIZE_COEF_SCALE - u);
+    int V1= rint(INTER_RESIZE_COEF_SCALE - v);
+
+    int y_ = INC(y,src_rows);
+    int x_ = INC(x,src_cols);
+      
+    uint4 val = U1* V1 *  getPoint_8uc4(src,src_offset,x,y,src_step) +
+               U1* V  *  getPoint_8uc4(src,src_offset,x,y_,src_step) +
+               U * V1 *  getPoint_8uc4(src,src_offset,x_,y,src_step) +
+               U * V  *  getPoint_8uc4(src,src_offset,x_,y_,src_step);
+               
+    if(dx>=0 && dx<dst_cols && dy>=0 && dy<dst_rows)
+         dst[(dst_offset>>2) + dy * (dst_step>>2) + dx] = convert_uchar4((val + (1<<(CAST_BITS-1)))>>CAST_BITS);
+}
+
+__kernel void resizeLN_C1_D5(__global float * dst, __global float * 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);
+
+    float sx = ((dx+0.5f) * ifx - 0.5f), sy = ((dy+0.5f) * ify - 0.5f);
+    int x = floor(sx), y = floor(sy);
+    float u = sx - x, v = sy - y;
+
+    x<0 ? x=0,u=0 : x,u;
+    x>=src_cols ? x=src_cols-1,u=0 : x,u;
+    y<0 ? y=0,v=0 : y,v;
+    y>=src_rows ? y=src_rows-1,v=0 : y,v;
+    
+    int y_ = INC(y,src_rows);
+    int x_ = INC(x,src_cols);
+
+    float val1 = (1.0f-u) *  getPoint_32fc1(src,src_offset,x,y,src_step) +
+                u  *  getPoint_32fc1(src,src_offset,x_,y,src_step) ;
+    float val2 = (1.0f-u) *  getPoint_32fc1(src,src_offset,x,y_,src_step) +
+                u *  getPoint_32fc1(src,src_offset,x_,y_,src_step);
+    float val = (1.0f-v) * val1 + v * val2;
+
+    if(dx>=0 && dx<dst_cols && dy>=0 && dy<dst_rows)
+         dst[(dst_offset>>2) + dy * (dst_step>>2) + dx] = val; 
+}
+
+__kernel void resizeLN_C4_D5(__global float4 * dst, __global float4 * 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);
+
+    float sx = ((dx+0.5f) * ifx - 0.5f), sy = ((dy+0.5f) * ify - 0.5f);
+    int x = floor(sx), y = floor(sy);
+    float u = sx - x, v = sy - y;
+
+    x<0 ? x=0,u=0 : x;
+    x>=src_cols ? x=src_cols-1,u=0 : x;
+    y<0 ? y=0,v=0 : y;
+    y>=src_rows ? y=src_rows-1,v=0 : y;
+    
+    int y_ = INC(y,src_rows);
+    int x_ = INC(x,src_cols);
+
+    float4 s_data1, s_data2, s_data3, s_data4;
+    src_offset = (src_offset >> 4);
+    src_step = (src_step >> 4);
+    s_data1 = src[src_offset + y*src_step + x];
+    s_data2 = src[src_offset + y*src_step + x_];
+    s_data3 = src[src_offset + y_*src_step + x];
+    s_data4 = src[src_offset + y_*src_step + x_];
+    s_data1 = (1.0f-u) * s_data1 + u * s_data2;
+    s_data2 = (1.0f-u) * s_data3 + u * s_data4;
+    s_data3 = (1.0f-v) * s_data1 + v * s_data2;
+
+    if(dx>=0 && dx<dst_cols && dy>=0 && dy<dst_rows)
+         dst[(dst_offset>>4) + dy * (dst_step>>4) + dx] = s_data3; 
+}
+
+__kernel void resizeNN_C1_D0(__global uchar * dst, __global 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, F ifx, F ify )
+{
+    int gx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    gx = (gx<<2) - (dst_offset&3);
+    int4 GX = (int4)(gx, gx+1, gx+2, gx+3);
+    
+    int4 sx;
+    int sy;
+    F ss1 = gx*ifx;
+    F ss2 = (gx+1)*ifx; 
+    F ss3 = (gx+2)*ifx;
+    F ss4 = (gx+3)*ifx;
+    F s5 = dy * ify;
+    sx.s0 = min((int)floor(ss1), src_cols-1);
+    sx.s1 = min((int)floor(ss2), src_cols-1);
+    sx.s2 = min((int)floor(ss3), src_cols-1);
+    sx.s3 = min((int)floor(ss4), src_cols-1);
+    sy = min((int)floor(s5), src_rows-1);
+    
+    uchar4 val;
+    int4 pos = src_offset + sy * src_step + sx;
+    val.s0 = src[pos.s0];
+    val.s1 = src[pos.s1];
+    val.s2 = src[pos.s2];
+    val.s3 = src[pos.s3];
+    
+    __global uchar4* d = (__global uchar4*)(dst + dst_offset + dy * dst_step + gx);
+    uchar4 dVal = *d;
+    int4 con = (GX >= 0 && GX < dst_cols && dy >= 0 && dy < dst_rows);
+    val = convert_uchar4(con != 0) ? val : dVal;
+    
+    *d = val;
+}
+
+__kernel void resizeNN_C4_D0(__global uchar4 * dst, __global 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, F ifx, F ify )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    F s1 = dx*ifx;
+    F s2 = dy*ify;
+    int sx = fmin((float)floor(s1), (float)src_cols-1);
+    int sy = fmin((float)floor(s2), (float)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>=0 && dx<dst_cols && dy>=0 && dy<dst_rows)
+        dst[dpos] = src[spos];
+   
+}
+
+__kernel void resizeNN_C1_D5(__global float * dst, __global float * 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, F ifx, F ify )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    F s1 = dx*ifx;
+    F s2 = dy*ify;
+    int sx = fmin((float)floor(s1), (float)src_cols-1);
+    int sy = fmin((float)floor(s2), (float)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>=0 && dx<dst_cols && dy>=0 && dy<dst_rows)
+        dst[dpos] = src[spos];
+   
+}
+
+__kernel void resizeNN_C4_D5(__global float4 * dst, __global float4 * 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, F ifx, F ify )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    F s1 = dx*ifx;
+    F s2 = dy*ify;
+    int s_col = floor(s1);
+    int s_row = floor(s2);
+    int sx = min(s_col, src_cols-1);
+    int sy = min(s_row, src_rows-1);
+    int dpos = (dst_offset>>4) + dy * (dst_step>>4) + dx;
+    int spos = (src_offset>>4) + sy * (src_step>>4) + sx;
+    
+    if(dx>=0 && dx<dst_cols && dy>=0 && dy<dst_rows)
+        dst[dpos] = src[spos];
+   
+}
+
diff --git a/modules/ocl/src/kernels/imgproc_threshold.cl b/modules/ocl/src/kernels/imgproc_threshold.cl
new file mode 100644 (file)
index 0000000..f96bee8
--- /dev/null
@@ -0,0 +1,153 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Zhang Ying, zhangying913@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 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*/
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+// threshold type:
+// enum { THRESH_BINARY=0, THRESH_BINARY_INV=1, THRESH_TRUNC=2, THRESH_TOZERO=3,
+//       THRESH_TOZERO_INV=4, THRESH_MASK=7, THRESH_OTSU=8 };
+
+__kernel void threshold_C1_D0(__global const uchar * restrict src, __global uchar *dst, 
+                              int src_offset, int src_step,
+                              int dst_offset, int dst_rows, int dst_cols, int dst_step,
+                              uchar thresh, uchar max_val, int thresh_type
+                              )
+{
+    int gx = get_global_id(0);
+    const int gy = get_global_id(1);
+
+       int offset = (dst_offset & 15);
+       src_offset -= offset;
+       
+       int dstart = (gx << 4) - offset;
+    if(dstart < dst_cols && gy < dst_rows)
+    {
+               uchar16 sdata = vload16(gx, src+src_offset+gy*src_step);
+        uchar16 ddata;
+               uchar16 zero = 0;
+        switch (thresh_type)
+        {
+            case 0:
+                ddata = ((sdata > thresh) ) ? (uchar16)(max_val) : (uchar16)(0);
+                break;
+            case 1:
+                ddata = ((sdata > thresh)) ? zero  : (uchar16)(max_val);
+                break;
+            case 2:
+                ddata = ((sdata > thresh)) ? (uchar16)(thresh) : sdata;
+                break;
+            case 3:
+                ddata = ((sdata > thresh)) ? sdata : zero;
+                break;
+            case 4:
+                ddata = ((sdata > thresh)) ? zero : sdata;
+                break;
+            default:
+                ddata = sdata;
+        }
+           int16 dpos = (int16)(dstart, dstart+1, dstart+2, dstart+3, dstart+4, dstart+5, dstart+6, dstart+7, dstart+8,
+                                    dstart+9, dstart+10, dstart+11, dstart+12, dstart+13, dstart+14, dstart+15);       
+               uchar16 dVal = *(__global uchar16*)(dst+dst_offset+gy*dst_step+dstart);
+               int16 con = dpos >= 0 && dpos < dst_cols;
+               ddata = convert_uchar16(con != 0) ? ddata : dVal;
+               if(dstart < dst_cols)
+               {
+                       *(__global uchar16*)(dst+dst_offset+gy*dst_step+dstart) = ddata;
+               }
+    }
+}
+
+
+__kernel void threshold_C1_D5(__global const float * restrict src, __global float *dst, 
+                              int src_offset, int src_step,
+                              int dst_offset, int dst_rows, int dst_cols, int dst_step,
+                              float thresh, float max_val, int thresh_type
+                              )
+{
+    const int gx = get_global_id(0);
+    const int gy = get_global_id(1);
+    
+       int offset = (dst_offset & 3);
+       src_offset -= offset;
+       
+       int dstart = (gx << 2) - offset;
+    if(dstart < dst_cols && gy < dst_rows)
+    {
+        float4 sdata = vload4(gx, src+src_offset+gy*src_step);
+        float4 ddata;
+               float4 zero = 0;
+        switch (thresh_type)
+        {
+            case 0:
+                ddata = sdata > thresh ? (float4)(max_val) : (float4)(0.f);
+                break;
+            case 1:
+                ddata = sdata > thresh ? zero : (float4)max_val;
+                break;
+            case 2:
+                ddata = sdata > thresh ? (float4)thresh : sdata;
+                break;
+            case 3:
+                ddata = sdata > thresh ? sdata : (float4)(0.f);
+                break;
+            case 4:
+                ddata = sdata > thresh ? (float4)(0.f) : sdata;
+                break;
+            default:
+                ddata = sdata;
+        }
+           int4 dpos = (int4)(dstart, dstart+1, dstart+2, dstart+3);
+               float4 dVal = *(__global float4*)(dst+dst_offset+gy*dst_step+dstart);
+               int4 con = dpos >= 0 && dpos < dst_cols;
+               ddata = convert_float4(con) != 0 ? ddata : dVal;
+               if(dstart < dst_cols)
+               {
+                       *(__global float4*)(dst+dst_offset+gy*dst_step+dstart) = ddata;
+               }
+    }
+}
+
diff --git a/modules/ocl/src/kernels/imgproc_warpAffine.cl b/modules/ocl/src/kernels/imgproc_warpAffine.cl
new file mode 100644 (file)
index 0000000..59860d1
--- /dev/null
@@ -0,0 +1,718 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Zhang Ying, zhangying913@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 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
+// 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*/
+
+
+//warpAffine kernel
+//support data types: CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4, and three interpolation methods: NN, Linear, Cubic.
+
+#if defined DOUBLE_SUPPORT
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+typedef double F;
+typedef double4 F4;
+#define convert_F4 convert_double4
+#else 
+typedef float F;
+typedef float4 F4;
+#define convert_F4 convert_float4
+#endif
+
+
+#define INTER_BITS 5
+#define INTER_TAB_SIZE (1 << INTER_BITS)
+#define INTER_SCALE 1.f/INTER_TAB_SIZE 
+#define AB_BITS max(10, (int)INTER_BITS) 
+#define AB_SCALE (1 << AB_BITS) 
+#define INTER_REMAP_COEF_BITS 15
+#define INTER_REMAP_COEF_SCALE (1 << INTER_REMAP_COEF_BITS)
+
+inline void interpolateCubic( float x, float* coeffs )
+{
+    const float A = -0.75f;
+
+    coeffs[0] = ((A*(x + 1.f) - 5.0f*A)*(x + 1.f) + 8.0f*A)*(x + 1.f) - 4.0f*A;
+    coeffs[1] = ((A + 2.f)*x - (A + 3.f))*x*x + 1.f;
+    coeffs[2] = ((A + 2.f)*(1.f - x) - (A + 3.f))*(1.f - x)*(1.f - x) + 1.f;
+    coeffs[3] = 1.f - coeffs[0] - coeffs[1] - coeffs[2];
+}
+
+
+/**********************************************8UC1*********************************************
+***********************************************************************************************/
+__kernel void warpAffineNN_C1_D0(__global uchar const * restrict src, __global uchar * dst, int src_cols, int src_rows,
+                            int dst_cols, int dst_rows, int srcStep, int dstStep, 
+                            int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    dx = (dx<<2) - (dst_offset&3);
+    
+    int round_delta = (AB_SCALE>>1);
+  
+    int4 X, Y;
+    int4 sx, sy;
+    int4 DX = (int4)(dx, dx+1, dx+2, dx+3);
+    DX = (DX << AB_BITS);
+    F4 M0DX, M3DX;
+    M0DX = M[0] * convert_F4(DX);
+    M3DX = M[3] * convert_F4(DX);
+    X = convert_int4(rint(M0DX));
+    Y = convert_int4(rint(M3DX));
+    int tmp1, tmp2;
+    tmp1 = rint((M[1]*dy + M[2]) * AB_SCALE);
+    tmp2 = rint((M[4]*dy + M[5]) * AB_SCALE);
+     
+    X += tmp1 + round_delta;
+    Y += tmp2 + round_delta;
+   
+    sx = convert_int4(convert_short4(X >> AB_BITS));
+    sy = convert_int4(convert_short4(Y >> AB_BITS));
+    
+    __global uchar4 * d = (__global uchar4 *)(dst+dst_offset+dy*dstStep+dx);
+    uchar4 dval = *d;
+    DX = (int4)(dx, dx+1, dx+2, dx+3);
+    int4 dcon = DX >= 0 && DX < dst_cols && dy >= 0 && dy < dst_rows;
+    int4 scon = sx >= 0 && sx < src_cols && sy >= 0 && sy < src_rows;
+    int4 spos = src_offset + sy * srcStep + sx;
+    uchar4 sval;
+    sval.s0 = scon.s0 ? src[spos.s0] : 0;
+    sval.s1 = scon.s1 ? src[spos.s1] : 0;
+    sval.s2 = scon.s2 ? src[spos.s2] : 0;
+    sval.s3 = scon.s3 ? src[spos.s3] : 0;
+    dval = convert_uchar4(dcon != 0) ? sval : dval;
+    *d = dval;
+}
+
+__kernel void warpAffineLinear_C1_D0(__global const uchar * restrict src, __global uchar * dst, int src_cols, int src_rows,
+                            int dst_cols, int dst_rows, int srcStep, int dstStep, 
+                            int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    dx = (dx<<2) - (dst_offset&3);
+     
+    int round_delta = ((AB_SCALE >> INTER_BITS) >> 1);
+   
+    int4 X, Y;
+    short4  ax, ay;
+    int4 sx, sy;
+    int4 DX = (int4)(dx, dx+1, dx+2, dx+3);
+    DX = (DX << AB_BITS);
+    F4 M0DX, M3DX;
+    M0DX = M[0] * convert_F4(DX);
+    M3DX = M[3] * convert_F4(DX);
+    X = convert_int4(rint(M0DX));
+    Y = convert_int4(rint(M3DX));
+    
+    int tmp1, tmp2;
+    tmp1 = rint((M[1]*dy + M[2]) * AB_SCALE);
+    tmp2 = rint((M[4]*dy + M[5]) * AB_SCALE);
+     
+    X += tmp1 + round_delta;
+    Y += tmp2 + round_delta;
+   
+    X = X >> (AB_BITS - INTER_BITS);
+    Y = Y >> (AB_BITS - INTER_BITS);
+   
+    sx = convert_int4(convert_short4(X >> INTER_BITS));
+    sy = convert_int4(convert_short4(Y >> INTER_BITS));
+    ax = convert_short4(X & (INTER_TAB_SIZE-1));
+    ay = convert_short4(Y & (INTER_TAB_SIZE-1));
+    
+    uchar4 v0, v1, v2,v3;
+    int4 scon0, scon1, scon2, scon3;
+    int4 spos0, spos1, spos2, spos3;
+
+    scon0 = (sx >= 0 && sx < src_cols && sy >= 0 && sy < src_rows);
+    scon1 = (sx+1 >= 0 && sx+1 < src_cols && sy >= 0 && sy < src_rows);
+    scon2 = (sx >= 0 && sx < src_cols && sy+1 >= 0 && sy+1 < src_rows);
+    scon3 = (sx+1 >= 0 && sx+1 < src_cols && sy+1 >= 0 && sy+1 < src_rows);
+    spos0 = src_offset + sy * srcStep + sx;
+    spos1 = src_offset + sy * srcStep + sx + 1;
+    spos2 = src_offset + (sy+1) * srcStep + sx;
+    spos3 = src_offset + (sy+1) * srcStep + sx + 1;
+
+    v0.s0 = scon0.s0 ? src[spos0.s0] : 0;
+    v1.s0 = scon1.s0 ? src[spos1.s0] : 0;
+    v2.s0 = scon2.s0 ? src[spos2.s0] : 0;
+    v3.s0 = scon3.s0 ? src[spos3.s0] : 0;
+
+    v0.s1 = scon0.s1 ? src[spos0.s1] : 0;
+    v1.s1 = scon1.s1 ? src[spos1.s1] : 0;
+    v2.s1 = scon2.s1 ? src[spos2.s1] : 0;
+    v3.s1 = scon3.s1 ? src[spos3.s1] : 0;
+
+    v0.s2 = scon0.s2 ? src[spos0.s2] : 0;
+    v1.s2 = scon1.s2 ? src[spos1.s2] : 0;
+    v2.s2 = scon2.s2 ? src[spos2.s2] : 0;
+    v3.s2 = scon3.s2 ? src[spos3.s2] : 0;
+
+    v0.s3 = scon0.s3 ? src[spos0.s3] : 0;
+    v1.s3 = scon1.s3 ? src[spos1.s3] : 0;
+    v2.s3 = scon2.s3 ? src[spos2.s3] : 0;
+    v3.s3 = scon3.s3 ? src[spos3.s3] : 0;
+   
+    short4 itab0, itab1, itab2, itab3;
+    float4 taby, tabx;
+    taby = INTER_SCALE * convert_float4(ay);
+    tabx = INTER_SCALE * convert_float4(ax);
+    itab0 = convert_short4_sat(( (1.0f-taby)*(1.0f-tabx) * INTER_REMAP_COEF_SCALE ));
+    itab1 = convert_short4_sat(( (1.0f-taby)*tabx * INTER_REMAP_COEF_SCALE ));
+    itab2 = convert_short4_sat(( taby*(1.0f-tabx) * INTER_REMAP_COEF_SCALE ));
+    itab3 = convert_short4_sat(( taby*tabx * INTER_REMAP_COEF_SCALE ));
+
+
+    int4 val;
+    uchar4 tval;
+    val = convert_int4(v0) * convert_int4(itab0) + convert_int4(v1) * convert_int4(itab1) 
+        + convert_int4(v2) * convert_int4(itab2) + convert_int4(v3) * convert_int4(itab3);
+    tval = convert_uchar4_sat ( (val + (1 << (INTER_REMAP_COEF_BITS-1))) >> INTER_REMAP_COEF_BITS ) ;
+    
+    __global uchar4 * d =(__global uchar4 *)(dst+dst_offset+dy*dstStep+dx);
+    uchar4 dval = *d;
+    DX = (int4)(dx, dx+1, dx+2, dx+3);
+    int4 dcon = DX >= 0 && DX < dst_cols && dy >= 0 && dy < dst_rows;
+    dval = convert_uchar4(dcon != 0) ? tval : dval;
+    *d = dval;
+    
+}
+
+__kernel void warpAffineCubic_C1_D0(__global uchar * src, __global uchar * dst, int src_cols, int src_rows,
+                            int dst_cols, int dst_rows, int srcStep, int dstStep, 
+                            int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    int round_delta = ((AB_SCALE>>INTER_BITS)>>1);
+    
+    int X0 = rint(M[0] * dx * AB_SCALE);
+    int Y0 = rint(M[3] * dx * AB_SCALE);
+    X0 += rint((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += rint((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+    int X = X0 >> (AB_BITS - INTER_BITS);
+    int Y = Y0 >> (AB_BITS - INTER_BITS);
+
+    short sx = (short)(X >> INTER_BITS) - 1;
+    short sy = (short)(Y >> INTER_BITS) - 1;
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+    
+    uchar v[16];
+    int i, j;
+   
+#pragma unroll 4
+    for(i=0; i<4;  i++)
+    for(j=0; j<4;  j++)
+    {
+        v[i*4+j] = (sx+j >= 0 && sx+j < src_cols && sy+i >= 0 && sy+i < src_rows) ? src[src_offset+(sy+i) * srcStep + (sx+j)] : 0;
+    }
+
+    short itab[16];
+    float tab1y[4], tab1x[4];
+    float axx, ayy;
+
+    ayy = 1.f/INTER_TAB_SIZE * ay;
+    axx = 1.f/INTER_TAB_SIZE * ax;
+    interpolateCubic(ayy, tab1y);
+    interpolateCubic(axx, tab1x);
+    int isum = 0;
+    
+#pragma unroll 16
+    for( i=0; i<16; i++ )
+    {
+        F v = tab1y[(i>>2)] * tab1x[(i&3)];
+        isum += itab[i] = convert_short_sat( rint( v * INTER_REMAP_COEF_SCALE ) );
+    }
+    
+    if( isum != INTER_REMAP_COEF_SCALE )
+    {
+        int k1, k2;
+        int diff = isum - INTER_REMAP_COEF_SCALE;
+        int Mk1=2, Mk2=2, mk1=2, mk2=2;
+        for( k1 = 2; k1 < 4; k1++ )
+            for( k2 = 2; k2 < 4; k2++ )
+            {
+                if( itab[(k1<<2)+k2] < itab[(mk1<<2)+mk2] )
+                    mk1 = k1, mk2 = k2;
+                else if( itab[(k1<<2)+k2] > itab[(Mk1<<2)+Mk2] )
+                     Mk1 = k1, Mk2 = k2;
+            }
+        diff<0 ? (itab[(Mk1<<2)+Mk2]=(short)(itab[(Mk1<<2)+Mk2]-diff)) : (itab[(mk1<<2)+mk2]=(short)(itab[(mk1<<2)+mk2]-diff));
+    }
+
+    if( dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
+    {
+        int sum=0;
+        for ( i =0; i<16; i++ )
+        {
+            sum += v[i] * itab[i] ;
+        }
+        dst[dst_offset+dy*dstStep+dx] = convert_uchar_sat( (sum + (1 << (INTER_REMAP_COEF_BITS-1))) >> INTER_REMAP_COEF_BITS ) ;
+    }
+}
+
+/**********************************************8UC4*********************************************
+***********************************************************************************************/
+
+__kernel void warpAffineNN_C4_D0(__global uchar4 const * restrict src, __global uchar4 * dst, int src_cols, int src_rows,
+                            int dst_cols, int dst_rows, int srcStep, int dstStep, 
+                            int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    int round_delta = (AB_SCALE >> 1);
+    
+    int X0 = rint(M[0] * dx * AB_SCALE);
+    int Y0 = rint(M[3] * dx * AB_SCALE);
+    X0 += rint((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += rint((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+
+    int sx0 = (short)(X0 >> AB_BITS);
+    int sy0 = (short)(Y0 >> AB_BITS);
+    if(dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
+        dst[(dst_offset>>2)+dy*(dstStep>>2)+dx]= (sx0>=0 && sx0<src_cols && sy0>=0 && sy0<src_rows) ? src[(src_offset>>2)+sy0*(srcStep>>2)+sx0] : (uchar4)0; 
+}
+
+__kernel void warpAffineLinear_C4_D0(__global uchar4 const * restrict src, __global uchar4 * dst, int src_cols, int src_rows,
+                            int dst_cols, int dst_rows, int srcStep, int dstStep, 
+                            int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    int round_delta = AB_SCALE/INTER_TAB_SIZE/2;
+    
+    src_offset = (src_offset>>2);
+    srcStep = (srcStep>>2); 
+
+    int tmp = (dx << AB_BITS);
+    int X0 = rint(M[0] * tmp);
+    int Y0 = rint(M[3] * tmp);
+    X0 += rint((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += rint((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+    X0 = X0 >> (AB_BITS - INTER_BITS);
+    Y0 = Y0 >> (AB_BITS - INTER_BITS);
+
+    short sx0 = (short)(X0 >> INTER_BITS);
+    short sy0 = (short)(Y0 >> INTER_BITS);
+    short ax0 = (short)(X0 & (INTER_TAB_SIZE-1));
+    short ay0 = (short)(Y0 & (INTER_TAB_SIZE-1));
+    
+    int4 v0, v1, v2, v3;
+
+    v0 = (sx0 >= 0 && sx0 < src_cols && sy0 >= 0 && sy0 < src_rows) ? convert_int4(src[src_offset+sy0 * srcStep + sx0]) : 0;
+    v1 = (sx0+1 >= 0 && sx0+1 < src_cols && sy0 >= 0 && sy0 < src_rows) ? convert_int4(src[src_offset+sy0 * srcStep + sx0+1]) : 0;
+    v2 = (sx0 >= 0 && sx0 < src_cols && sy0+1 >= 0 && sy0+1 < src_rows) ? convert_int4(src[src_offset+(sy0+1) * srcStep + sx0]) : 0;
+    v3 = (sx0+1 >= 0 && sx0+1 < src_cols && sy0+1 >= 0 && sy0+1 < src_rows) ? convert_int4(src[src_offset+(sy0+1) * srcStep + sx0+1]) : 0;
+
+    int itab0, itab1, itab2, itab3;
+    float taby, tabx;
+    taby = 1.f/INTER_TAB_SIZE*ay0;
+    tabx = 1.f/INTER_TAB_SIZE*ax0;
+    
+    itab0 = convert_short_sat(rint( (1.0f-taby)*(1.0f-tabx) * INTER_REMAP_COEF_SCALE ));
+    itab1 = convert_short_sat(rint( (1.0f-taby)*tabx * INTER_REMAP_COEF_SCALE ));
+    itab2 = convert_short_sat(rint( taby*(1.0f-tabx) * INTER_REMAP_COEF_SCALE ));
+    itab3 = convert_short_sat(rint( taby*tabx * INTER_REMAP_COEF_SCALE ));
+    
+    int4 val;
+    val = v0 * itab0 +  v1 * itab1 + v2 * itab2 + v3 * itab3;
+        
+    if(dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
+        dst[(dst_offset>>2)+dy*(dstStep>>2)+dx] =  convert_uchar4_sat ( (val + (1 << (INTER_REMAP_COEF_BITS-1))) >> INTER_REMAP_COEF_BITS ) ;
+}
+
+__kernel void warpAffineCubic_C4_D0(__global uchar4 const * restrict src, __global uchar4 * dst, int src_cols, int src_rows,
+                            int dst_cols, int dst_rows, int srcStep, int dstStep, 
+                            int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    int round_delta = ((AB_SCALE>>INTER_BITS)>>1);
+    
+    src_offset = (src_offset>>2);
+    srcStep = (srcStep>>2); 
+    dst_offset = (dst_offset>>2);
+    dstStep = (dstStep>>2); 
+   
+    int tmp = (dx << AB_BITS);
+    int X0 = rint(M[0] * tmp);
+    int Y0 = rint(M[3] * tmp);
+    X0 += rint((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += rint((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+    X0 = X0 >> (AB_BITS - INTER_BITS);
+    Y0 = Y0 >> (AB_BITS - INTER_BITS);
+
+    int sx = (short)(X0 >> INTER_BITS) - 1;
+    int sy = (short)(Y0 >> INTER_BITS) - 1;
+    int ay = (short)(Y0 & (INTER_TAB_SIZE-1));
+    int ax = (short)(X0 & (INTER_TAB_SIZE-1));
+    
+    uchar4 v[16];
+    int i,j;
+#pragma unroll 4
+    for(i=0; i<4; i++)
+    for(j=0; j<4; j++)
+    {
+        v[i*4+j] = (sx+j >= 0 && sx+j < src_cols && sy+i >= 0 && sy+i < src_rows) ? (src[src_offset+(sy+i) * srcStep + (sx+j)])  : (uchar4)0;
+    }
+    int itab[16];
+    float tab1y[4], tab1x[4];
+    float axx, ayy;
+
+    ayy = INTER_SCALE * ay;
+    axx = INTER_SCALE * ax;
+    interpolateCubic(ayy, tab1y);
+    interpolateCubic(axx, tab1x);
+    int isum = 0;
+    
+#pragma unroll 16
+    for( i=0; i<16; i++ )
+    {
+        float tmp;
+        tmp = tab1y[(i>>2)] * tab1x[(i&3)] * INTER_REMAP_COEF_SCALE;
+        itab[i] = rint(tmp);
+        isum += itab[i];
+    }
+
+    if( isum != INTER_REMAP_COEF_SCALE )
+    {
+        int k1, k2;
+        int diff = isum - INTER_REMAP_COEF_SCALE;
+        int Mk1=2, Mk2=2, mk1=2, mk2=2;
+        
+           for( k1 = 2; k1 < 4; k1++ )
+            for( k2 = 2; k2 < 4; k2++ )
+            {
+                
+                if( itab[(k1<<2)+k2] < itab[(mk1<<2)+mk2] )
+                    mk1 = k1, mk2 = k2;
+                else if( itab[(k1<<2)+k2] > itab[(Mk1<<2)+Mk2] )
+                     Mk1 = k1, Mk2 = k2;
+            }
+            
+        diff<0 ? (itab[(Mk1<<2)+Mk2]=(short)(itab[(Mk1<<2)+Mk2]-diff)) : (itab[(mk1<<2)+mk2]=(short)(itab[(mk1<<2)+mk2]-diff));
+    }
+
+    if( dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
+    {
+        int4 sum=0;
+        for ( i =0; i<16; i++ )
+        {
+            sum += convert_int4(v[i]) * itab[i];
+        }
+        dst[dst_offset+dy*dstStep+dx] = convert_uchar4_sat( (sum + (1 << (INTER_REMAP_COEF_BITS-1))) >> INTER_REMAP_COEF_BITS ) ;
+    }
+}
+
+
+/**********************************************32FC1********************************************
+***********************************************************************************************/
+
+__kernel void warpAffineNN_C1_D5(__global float * src, __global float * dst, int src_cols, int src_rows,
+                            int dst_cols, int dst_rows, int srcStep, int dstStep, 
+                            int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    int round_delta = AB_SCALE/2;
+    
+    int X0 = rint(M[0] * dx * AB_SCALE);
+    int Y0 = rint(M[3] * dx * AB_SCALE);
+    X0 += rint((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += rint((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+
+    short sx0 = (short)(X0 >> AB_BITS);
+    short sy0 = (short)(Y0 >> AB_BITS);
+    
+    if(dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
+        dst[(dst_offset>>2)+dy*dstStep+dx]= (sx0>=0 && sx0<src_cols && sy0>=0 && sy0<src_rows) ? src[(src_offset>>2)+sy0*srcStep+sx0] : 0; 
+}
+
+__kernel void warpAffineLinear_C1_D5(__global float * src, __global float * dst, int src_cols, int src_rows,
+                            int dst_cols, int dst_rows, int srcStep, int dstStep, 
+                            int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    int round_delta = AB_SCALE/INTER_TAB_SIZE/2;
+    
+    src_offset = (src_offset>>2);
+    
+    int X0 = rint(M[0] * dx * AB_SCALE);
+    int Y0 = rint(M[3] * dx * AB_SCALE);
+    X0 += rint((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += rint((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+    X0 = X0 >> (AB_BITS - INTER_BITS);
+    Y0 = Y0 >> (AB_BITS - INTER_BITS);
+
+    short sx0 = (short)(X0 >> INTER_BITS);
+    short sy0 = (short)(Y0 >> INTER_BITS);
+    short ax0 = (short)(X0 & (INTER_TAB_SIZE-1));
+    short ay0 = (short)(Y0 & (INTER_TAB_SIZE-1));
+    
+    float v0, v1, v2, v3;
+
+    v0 = (sx0 >= 0 && sx0 < src_cols && sy0 >= 0 && sy0 < src_rows) ? src[src_offset+sy0 * srcStep + sx0] : 0;
+    v1 = (sx0+1 >= 0 && sx0+1 < src_cols && sy0 >= 0 && sy0 < src_rows) ? src[src_offset+sy0 * srcStep + sx0+1] : 0;
+    v2 = (sx0 >= 0 && sx0 < src_cols && sy0+1 >= 0 && sy0+1 < src_rows) ? src[src_offset+(sy0+1) * srcStep + sx0] : 0;
+    v3 = (sx0+1 >= 0 && sx0+1 < src_cols && sy0+1 >= 0 && sy0+1 < src_rows) ? src[src_offset+(sy0+1) * srcStep + sx0+1] : 0;
+
+    float tab[4];
+    float taby[2], tabx[2];
+    taby[0] = 1.0 - 1.f/INTER_TAB_SIZE*ay0;
+    taby[1] = 1.f/INTER_TAB_SIZE*ay0;
+    tabx[0] = 1.0 - 1.f/INTER_TAB_SIZE*ax0;
+    tabx[1] = 1.f/INTER_TAB_SIZE*ax0;
+   
+    tab[0] = taby[0] * tabx[0];
+    tab[1] = taby[0] * tabx[1];
+    tab[2] = taby[1] * tabx[0];
+    tab[3] = taby[1] * tabx[1];
+
+    float sum = 0;
+    sum += v0 * tab[0] +  v1 * tab[1] +  v2 * tab[2] +  v3 * tab[3]; 
+    if(dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
+        dst[(dst_offset>>2)+dy*dstStep+dx] = sum;
+}
+    
+__kernel void warpAffineCubic_C1_D5(__global float * src, __global float * dst, int src_cols, int src_rows,
+                            int dst_cols, int dst_rows, int srcStep, int dstStep, 
+                            int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    int round_delta = AB_SCALE/INTER_TAB_SIZE/2;
+    
+    src_offset = (src_offset>>2);
+    dst_offset = (dst_offset>>2);
+    
+    int X0 = rint(M[0] * dx * AB_SCALE);
+    int Y0 = rint(M[3] * dx * AB_SCALE);
+    X0 += rint((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += rint((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+    X0 = X0 >> (AB_BITS - INTER_BITS);
+    Y0 = Y0 >> (AB_BITS - INTER_BITS);
+
+    short sx = (short)(X0 >> INTER_BITS) - 1;
+    short sy = (short)(Y0 >> INTER_BITS) - 1;
+    short ay = (short)(Y0 & (INTER_TAB_SIZE-1));
+    short ax = (short)(X0 & (INTER_TAB_SIZE-1));
+    
+    float v[16];
+    int i;
+
+    for(i=0; i<16;  i++)
+        v[i] = (sx+(i&3) >= 0 && sx+(i&3) < src_cols && sy+(i>>2) >= 0 && sy+(i>>2) < src_rows) ? src[src_offset+(sy+(i>>2)) * srcStep + (sx+(i&3))] : 0;
+
+    float tab[16];
+    float tab1y[4], tab1x[4];
+    float axx, ayy;
+
+    ayy = 1.f/INTER_TAB_SIZE * ay;
+    axx = 1.f/INTER_TAB_SIZE * ax;
+    interpolateCubic(ayy, tab1y);
+    interpolateCubic(axx, tab1x);
+
+#pragma unroll 4
+    for( i=0; i<16; i++ )
+    {
+        tab[i] = tab1y[(i>>2)] * tab1x[(i&3)];
+    }
+    
+    if( dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
+    {
+        float sum = 0;
+#pragma unroll 4
+        for ( i =0; i<16; i++ )
+        {
+            sum += v[i] * tab[i];
+        }
+        dst[dst_offset+dy*dstStep+dx] = sum;
+
+    }
+}
+
+
+/**********************************************32FC4********************************************
+***********************************************************************************************/
+
+__kernel void warpAffineNN_C4_D5(__global float4 * src, __global float4 * dst, int src_cols, int src_rows,
+                            int dst_cols, int dst_rows, int srcStep, int dstStep, 
+                            int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    int round_delta = AB_SCALE/2;
+    
+    int X0 = rint(M[0] * dx * AB_SCALE);
+    int Y0 = rint(M[3] * dx * AB_SCALE);
+    X0 += rint((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += rint((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+
+    short sx0 = (short)(X0 >> AB_BITS);
+    short sy0 = (short)(Y0 >> AB_BITS);
+    
+    if(dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
+        dst[(dst_offset>>4)+dy*(dstStep>>2)+dx]= (sx0>=0 && sx0<src_cols && sy0>=0 && sy0<src_rows) ? src[(src_offset>>4)+sy0*(srcStep>>2)+sx0] : 0; 
+}
+
+__kernel void warpAffineLinear_C4_D5(__global float4 * src, __global float4 * dst, int src_cols, int src_rows,
+                            int dst_cols, int dst_rows, int srcStep, int dstStep, 
+                            int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    int round_delta = AB_SCALE/INTER_TAB_SIZE/2;
+    
+    src_offset = (src_offset>>4);
+    dst_offset = (dst_offset>>4);
+    srcStep = (srcStep>>2);
+    dstStep = (dstStep>>2);
+    
+    int X0 = rint(M[0] * dx * AB_SCALE);
+    int Y0 = rint(M[3] * dx * AB_SCALE);
+    X0 += rint((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += rint((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+    X0 = X0 >> (AB_BITS - INTER_BITS);
+    Y0 = Y0 >> (AB_BITS - INTER_BITS);
+
+    short sx0 = (short)(X0 >> INTER_BITS);
+    short sy0 = (short)(Y0 >> INTER_BITS);
+    short ax0 = (short)(X0 & (INTER_TAB_SIZE-1));
+    short ay0 = (short)(Y0 & (INTER_TAB_SIZE-1));
+    
+    float4 v0, v1, v2, v3;
+
+    v0 = (sx0 >= 0 && sx0 < src_cols && sy0 >= 0 && sy0 < src_rows) ? src[src_offset+sy0 * srcStep + sx0] : 0;
+    v1 = (sx0+1 >= 0 && sx0+1 < src_cols && sy0 >= 0 && sy0 < src_rows) ? src[src_offset+sy0 * srcStep + sx0+1] : 0;
+    v2 = (sx0 >= 0 && sx0 < src_cols && sy0+1 >= 0 && sy0+1 < src_rows) ? src[src_offset+(sy0+1) * srcStep + sx0] : 0;
+    v3 = (sx0+1 >= 0 && sx0+1 < src_cols && sy0+1 >= 0 && sy0+1 < src_rows) ? src[src_offset+(sy0+1) * srcStep + sx0+1] : 0;
+
+    float tab[4];
+    float taby[2], tabx[2];
+    taby[0] = 1.0 - 1.f/INTER_TAB_SIZE*ay0;
+    taby[1] = 1.f/INTER_TAB_SIZE*ay0;
+    tabx[0] = 1.0 - 1.f/INTER_TAB_SIZE*ax0;
+    tabx[1] = 1.f/INTER_TAB_SIZE*ax0;
+   
+    tab[0] = taby[0] * tabx[0];
+    tab[1] = taby[0] * tabx[1];
+    tab[2] = taby[1] * tabx[0];
+    tab[3] = taby[1] * tabx[1];
+
+    float4 sum = 0;
+    sum += v0 * tab[0] +  v1 * tab[1] +  v2 * tab[2] +  v3 * tab[3]; 
+    if(dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
+        dst[dst_offset+dy*dstStep+dx] = sum;
+}
+    
+__kernel void warpAffineCubic_C4_D5(__global float4 * src, __global float4 * dst, int src_cols, int src_rows,
+                            int dst_cols, int dst_rows, int srcStep, int dstStep, 
+                            int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    int round_delta = AB_SCALE/INTER_TAB_SIZE/2;
+    
+    src_offset = (src_offset>>4);
+    dst_offset = (dst_offset>>4);
+    srcStep = (srcStep>>2);
+    dstStep = (dstStep>>2);
+    
+    int X0 = rint(M[0] * dx * AB_SCALE);
+    int Y0 = rint(M[3] * dx * AB_SCALE);
+    X0 += rint((M[1]*dy + M[2]) * AB_SCALE) + round_delta;
+    Y0 += rint((M[4]*dy + M[5]) * AB_SCALE) + round_delta;
+    X0 = X0 >> (AB_BITS - INTER_BITS);
+    Y0 = Y0 >> (AB_BITS - INTER_BITS);
+
+    short sx = (short)(X0 >> INTER_BITS) - 1;
+    short sy = (short)(Y0 >> INTER_BITS) - 1;
+    short ay = (short)(Y0 & (INTER_TAB_SIZE-1));
+    short ax = (short)(X0 & (INTER_TAB_SIZE-1));
+    
+    float4 v[16];
+    int i;
+
+    for(i=0; i<16;  i++)
+        v[i] = (sx+(i&3) >= 0 && sx+(i&3) < src_cols && sy+(i>>2) >= 0 && sy+(i>>2) < src_rows) ? src[src_offset+(sy+(i>>2)) * srcStep + (sx+(i&3))] : 0;
+
+    float tab[16];
+    float tab1y[4], tab1x[4];
+    float axx, ayy;
+
+    ayy = 1.f/INTER_TAB_SIZE * ay;
+    axx = 1.f/INTER_TAB_SIZE * ax;
+    interpolateCubic(ayy, tab1y);
+    interpolateCubic(axx, tab1x);
+
+#pragma unroll 4
+    for( i=0; i<16; i++ )
+    {
+        tab[i] = tab1y[(i>>2)] * tab1x[(i&3)];
+    }
+    
+    if( dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
+    {
+        float4 sum = 0;
+#pragma unroll 4
+        for ( i =0; i<16; i++ )
+        {
+            sum += v[i] * tab[i];
+        }
+        dst[dst_offset+dy*dstStep+dx] = sum;
+
+    }
+}
diff --git a/modules/ocl/src/kernels/imgproc_warpPerspective.cl b/modules/ocl/src/kernels/imgproc_warpPerspective.cl
new file mode 100644 (file)
index 0000000..e6521d6
--- /dev/null
@@ -0,0 +1,648 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Zhang Ying, zhangying913@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 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
+// 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*/
+
+
+//wrapPerspective kernel
+//support data types: CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4, and three interpolation methods: NN, Linear, Cubic.
+
+#if defined DOUBLE_SUPPORT
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+typedef double F;
+typedef double4 F4;
+#define convert_F4 convert_double4
+#else 
+typedef float F;
+typedef float4 F4;
+#define convert_F4 convert_float4
+#endif
+
+
+#define INTER_BITS 5
+#define INTER_TAB_SIZE (1 << INTER_BITS)
+#define INTER_SCALE 1.f/INTER_TAB_SIZE 
+#define AB_BITS max(10, (int)INTER_BITS) 
+#define AB_SCALE (1 << AB_BITS) 
+#define INTER_REMAP_COEF_BITS 15
+#define INTER_REMAP_COEF_SCALE (1 << INTER_REMAP_COEF_BITS)
+
+inline void interpolateCubic( float x, float* coeffs )
+{
+    const float A = -0.75f;
+
+    coeffs[0] = ((A*(x + 1.f) - 5.0f*A)*(x + 1.f) + 8.0f*A)*(x + 1.f) - 4.0f*A;
+    coeffs[1] = ((A + 2.f)*x - (A + 3.f))*x*x + 1.f;
+    coeffs[2] = ((A + 2.f)*(1.f - x) - (A + 3.f))*(1.f - x)*(1.f - x) + 1.f;
+    coeffs[3] = 1.f - coeffs[0] - coeffs[1] - coeffs[2];
+}
+
+
+/**********************************************8UC1*********************************************
+***********************************************************************************************/
+__kernel void warpPerspectiveNN_C1_D0(__global uchar const * restrict src, __global uchar * dst, int src_cols, int src_rows,
+                            int dst_cols, int dst_rows, int srcStep, int dstStep, 
+                            int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    dx = (dx<<2) - (dst_offset&3);
+    
+    F4 DX = (F4)(dx, dx+1, dx+2, dx+3);
+    F4 X0 = M[0]*DX + M[1]*dy + M[2];
+    F4 Y0 = M[3]*DX + M[4]*dy + M[5];
+    F4 W = M[6]*DX + M[7]*dy + M[8];
+    W = (W!=0) ? 1./W : 0;
+    short4 X = convert_short4(rint(X0*W));
+    short4 Y = convert_short4(rint(Y0*W));
+    int4 sx = convert_int4(X);
+    int4 sy = convert_int4(Y);
+
+    int4 DXD = (int4)(dx, dx+1, dx+2, dx+3);
+    __global uchar4 * d = (__global uchar4 *)(dst+dst_offset+dy*dstStep+dx);
+    uchar4 dval = *d;
+    int4 dcon = DXD >= 0 && DXD < dst_cols && dy >= 0 && dy < dst_rows;
+    int4 scon = sx >= 0 && sx < src_cols && sy >= 0 && sy < src_rows;
+    int4 spos = src_offset + sy * srcStep + sx;
+    uchar4 sval;
+    sval.s0 = scon.s0 ? src[spos.s0] : 0;
+    sval.s1 = scon.s1 ? src[spos.s1] : 0;
+    sval.s2 = scon.s2 ? src[spos.s2] : 0;
+    sval.s3 = scon.s3 ? src[spos.s3] : 0;
+    dval = convert_uchar4(dcon != 0) ? sval : dval;
+    *d = dval;
+
+}
+
+__kernel void warpPerspectiveLinear_C1_D0(__global const uchar * restrict src, __global uchar * dst,
+                            int src_cols, int src_rows, int dst_cols, int dst_rows, int srcStep, 
+                            int dstStep, int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    F X0 = M[0]*dx + M[1]*dy + M[2];
+    F Y0 = M[3]*dx + M[4]*dy + M[5];
+    F W = M[6]*dx + M[7]*dy + M[8];
+    W = (W != 0.0) ? INTER_TAB_SIZE/W : 0.0;
+    int X = rint(X0*W);
+    int Y = rint(Y0*W);
+    
+    int sx = (short)(X >> INTER_BITS);
+    int sy = (short)(Y >> INTER_BITS);
+    int ay = (short)(Y & (INTER_TAB_SIZE-1));
+    int ax = (short)(X & (INTER_TAB_SIZE-1));
+   
+    uchar v[4];
+    int i;
+#pragma unroll 4
+    for(i=0; i<4;  i++)
+       v[i] = (sx+(i&1) >= 0 && sx+(i&1) < src_cols && sy+(i>>1) >= 0 && sy+(i>>1) < src_rows) ? src[src_offset + (sy+(i>>1)) * srcStep + (sx+(i&1))] : 0;
+
+    short itab[4];
+    float tab1y[2], tab1x[2];
+    tab1y[0] = 1.0 - 1.f/INTER_TAB_SIZE*ay;
+    tab1y[1] = 1.f/INTER_TAB_SIZE*ay;
+    tab1x[0] = 1.0 - 1.f/INTER_TAB_SIZE*ax;
+    tab1x[1] = 1.f/INTER_TAB_SIZE*ax;
+    
+#pragma unroll 4
+    for(i=0; i<4;  i++)
+    {
+        float v = tab1y[(i>>1)] * tab1x[(i&1)];
+        itab[i] = convert_short_sat(rint( v * INTER_REMAP_COEF_SCALE ));
+    }
+    if(dx >=0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
+    {
+        int sum = 0;
+        for ( i =0; i<4; i++ )
+        {
+            sum += v[i] * itab[i] ;
+        }
+        dst[dst_offset+dy*dstStep+dx] = convert_uchar_sat ( (sum + (1 << (INTER_REMAP_COEF_BITS-1))) >> INTER_REMAP_COEF_BITS ) ;
+    }
+}
+
+__kernel void warpPerspectiveCubic_C1_D0(__global uchar * src, __global uchar * dst, int src_cols, int src_rows,
+                            int dst_cols, int dst_rows, int srcStep, int dstStep, 
+                            int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+       
+       F X0 = M[0]*dx + M[1]*dy + M[2];
+    F Y0 = M[3]*dx + M[4]*dy + M[5];
+    F W = M[6]*dx + M[7]*dy + M[8];
+    W = (W != 0.0) ? INTER_TAB_SIZE/W : 0.0;
+    int X = rint(X0*W);
+    int Y = rint(Y0*W);
+    
+    short sx = (short)(X >> INTER_BITS) - 1;
+    short sy = (short)(Y >> INTER_BITS) - 1;
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+       uchar v[16];
+    int i, j;
+   
+#pragma unroll 4
+    for(i=0; i<4;  i++)
+    for(j=0; j<4;  j++)
+    {
+        v[i*4+j] = (sx+j >= 0 && sx+j < src_cols && sy+i >= 0 && sy+i < src_rows) ? src[src_offset+(sy+i) * srcStep + (sx+j)] : 0;
+    }
+
+    short itab[16];
+    float tab1y[4], tab1x[4];
+    float axx, ayy;
+
+    ayy = 1.f/INTER_TAB_SIZE * ay;
+    axx = 1.f/INTER_TAB_SIZE * ax;
+    interpolateCubic(ayy, tab1y);
+    interpolateCubic(axx, tab1x);
+    
+    int isum = 0;
+#pragma unroll 16
+    for( i=0; i<16; i++ )
+    {
+        F v = tab1y[(i>>2)] * tab1x[(i&3)];
+        isum += itab[i] = convert_short_sat( rint( v * INTER_REMAP_COEF_SCALE ) );
+    }
+    if( isum != INTER_REMAP_COEF_SCALE )
+    {
+        int k1, k2;
+        int diff = isum - INTER_REMAP_COEF_SCALE;
+        int Mk1=2, Mk2=2, mk1=2, mk2=2;
+        for( k1 = 2; k1 < 4; k1++ )
+            for( k2 = 2; k2 < 4; k2++ )
+            {
+                if( itab[(k1<<2)+k2] < itab[(mk1<<2)+mk2] )
+                    mk1 = k1, mk2 = k2;
+                else if( itab[(k1<<2)+k2] > itab[(Mk1<<2)+Mk2] )
+                     Mk1 = k1, Mk2 = k2;
+            }
+        diff<0 ? (itab[(Mk1<<2)+Mk2]=(short)(itab[(Mk1<<2)+Mk2]-diff)) : (itab[(mk1<<2)+mk2]=(short)(itab[(mk1<<2)+mk2]-diff));
+    }
+
+
+    if( dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
+    {
+        int sum=0;
+        for ( i =0; i<16; i++ )
+        {
+            sum += v[i] * itab[i] ;
+        }
+        dst[dst_offset+dy*dstStep+dx] = convert_uchar_sat( (sum + (1 << (INTER_REMAP_COEF_BITS-1))) >> INTER_REMAP_COEF_BITS ) ;
+    }
+}
+
+/**********************************************8UC4*********************************************
+***********************************************************************************************/
+
+__kernel void warpPerspectiveNN_C4_D0(__global uchar4 const * restrict src, __global uchar4 * dst,
+                            int src_cols, int src_rows, int dst_cols, int dst_rows, int srcStep, 
+                                                       int dstStep, int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+  
+    F X0 = M[0]*dx + M[1]*dy + M[2];
+    F Y0 = M[3]*dx + M[4]*dy + M[5];
+    F W = M[6]*dx + M[7]*dy + M[8];
+    W = (W != 0.0) ? 1./W : 0.0;
+    int X = rint(X0*W);
+    int Y = rint(Y0*W);
+    short sx = (short)X;
+    short sy = (short)Y;
+    if(dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
+        dst[(dst_offset>>2)+dy*(dstStep>>2)+dx]= (sx>=0 && sx<src_cols && sy>=0 && sy<src_rows) ? src[(src_offset>>2)+sy*(srcStep>>2)+sx] : (uchar4)0; 
+}
+
+__kernel void warpPerspectiveLinear_C4_D0(__global uchar4 const * restrict src, __global uchar4 * dst,
+                                                       int src_cols, int src_rows, int dst_cols, int dst_rows, int srcStep,
+                                                       int dstStep, int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    src_offset = (src_offset>>2);
+    srcStep = (srcStep>>2); 
+    F X0 = M[0]*dx + M[1]*dy + M[2];
+    F Y0 = M[3]*dx + M[4]*dy + M[5];
+    F W = M[6]*dx + M[7]*dy + M[8];
+    W = (W != 0.0) ? INTER_TAB_SIZE/W : 0.0;
+    int X = rint(X0*W);
+    int Y = rint(Y0*W);
+    
+    short sx = (short)(X >> INTER_BITS);
+    short sy = (short)(Y >> INTER_BITS);
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+    
+    
+    int4 v0, v1, v2, v3;
+
+    v0 = (sx >= 0 && sx < src_cols && sy >= 0 && sy < src_rows) ? convert_int4(src[src_offset+sy * srcStep + sx]) : 0;
+    v1 = (sx+1 >= 0 && sx+1 < src_cols && sy >= 0 && sy < src_rows) ? convert_int4(src[src_offset+sy * srcStep + sx+1]) : 0;
+    v2 = (sx >= 0 && sx < src_cols && sy+1 >= 0 && sy+1 < src_rows) ? convert_int4(src[src_offset+(sy+1) * srcStep + sx]) : 0;
+    v3 = (sx+1 >= 0 && sx+1 < src_cols && sy+1 >= 0 && sy+1 < src_rows) ? convert_int4(src[src_offset+(sy+1) * srcStep + sx+1]) : 0;
+
+    int itab0, itab1, itab2, itab3;
+    float taby, tabx;
+    taby = 1.f/INTER_TAB_SIZE*ay;
+    tabx = 1.f/INTER_TAB_SIZE*ax;
+    
+    itab0 = convert_short_sat(rint( (1.0f-taby)*(1.0f-tabx) * INTER_REMAP_COEF_SCALE ));
+    itab1 = convert_short_sat(rint( (1.0f-taby)*tabx * INTER_REMAP_COEF_SCALE ));
+    itab2 = convert_short_sat(rint( taby*(1.0f-tabx) * INTER_REMAP_COEF_SCALE ));
+    itab3 = convert_short_sat(rint( taby*tabx * INTER_REMAP_COEF_SCALE ));
+    
+    int4 val;
+    val = v0 * itab0 +  v1 * itab1 + v2 * itab2 + v3 * itab3;
+        
+    if(dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
+        dst[(dst_offset>>2)+dy*(dstStep>>2)+dx] =  convert_uchar4_sat ( (val + (1 << (INTER_REMAP_COEF_BITS-1))) >> INTER_REMAP_COEF_BITS ) ;
+}
+
+__kernel void warpPerspectiveCubic_C4_D0(__global uchar4 const * restrict src, __global uchar4 * dst, 
+                                                       int src_cols, int src_rows, int dst_cols, int dst_rows, int srcStep,
+                                                       int dstStep, int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    src_offset = (src_offset>>2);
+    srcStep = (srcStep>>2); 
+    dst_offset = (dst_offset>>2);
+    dstStep = (dstStep>>2); 
+    
+    F X0 = M[0]*dx + M[1]*dy + M[2];
+    F Y0 = M[3]*dx + M[4]*dy + M[5];
+    F W = M[6]*dx + M[7]*dy + M[8];
+    W = (W != 0.0) ? INTER_TAB_SIZE/W : 0.0;
+    int X = rint(X0*W);
+    int Y = rint(Y0*W);
+    
+    short sx = (short)(X >> INTER_BITS) - 1;
+    short sy = (short)(Y >> INTER_BITS) - 1;
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+    
+    uchar4 v[16];
+    int i,j;
+#pragma unroll 4
+    for(i=0; i<4; i++)
+    for(j=0; j<4; j++)
+    {
+        v[i*4+j] = (sx+j >= 0 && sx+j < src_cols && sy+i >= 0 && sy+i < src_rows) ? (src[src_offset+(sy+i) * srcStep + (sx+j)])  : (uchar4)0;
+    }
+    int itab[16];
+    float tab1y[4], tab1x[4];
+    float axx, ayy;
+
+    ayy = INTER_SCALE * ay;
+    axx = INTER_SCALE * ax;
+    interpolateCubic(ayy, tab1y);
+    interpolateCubic(axx, tab1x);
+    int isum = 0;
+    
+#pragma unroll 16
+    for( i=0; i<16; i++ )
+    {
+        float tmp;
+        tmp = tab1y[(i>>2)] * tab1x[(i&3)] * INTER_REMAP_COEF_SCALE;
+        itab[i] = rint(tmp);
+        isum += itab[i];
+    }
+
+    if( isum != INTER_REMAP_COEF_SCALE )
+    {
+        int k1, k2;
+        int diff = isum - INTER_REMAP_COEF_SCALE;
+        int Mk1=2, Mk2=2, mk1=2, mk2=2;
+        
+           for( k1 = 2; k1 < 4; k1++ )
+            for( k2 = 2; k2 < 4; k2++ )
+            {
+                
+                if( itab[(k1<<2)+k2] < itab[(mk1<<2)+mk2] )
+                    mk1 = k1, mk2 = k2;
+                else if( itab[(k1<<2)+k2] > itab[(Mk1<<2)+Mk2] )
+                     Mk1 = k1, Mk2 = k2;
+            }
+            
+        diff<0 ? (itab[(Mk1<<2)+Mk2]=(short)(itab[(Mk1<<2)+Mk2]-diff)) : (itab[(mk1<<2)+mk2]=(short)(itab[(mk1<<2)+mk2]-diff));
+    }
+
+    if( dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
+    {
+        int4 sum=0;
+        for ( i =0; i<16; i++ )
+        {
+            sum += convert_int4(v[i]) * itab[i];
+        }
+        dst[dst_offset+dy*dstStep+dx] = convert_uchar4_sat( (sum + (1 << (INTER_REMAP_COEF_BITS-1))) >> INTER_REMAP_COEF_BITS ) ;
+    }
+}
+
+
+/**********************************************32FC1********************************************
+***********************************************************************************************/
+
+__kernel void warpPerspectiveNN_C1_D5(__global float * src, __global float * dst, int src_cols, int src_rows,
+                            int dst_cols, int dst_rows, int srcStep, int dstStep, 
+                            int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+     
+    F X0 = M[0]*dx + M[1]*dy + M[2];
+    F Y0 = M[3]*dx + M[4]*dy + M[5];
+    F W = M[6]*dx + M[7]*dy + M[8];
+    W = (W != 0.0) ? 1./W : 0.0;
+    int X = rint(X0*W);
+    int Y = rint(Y0*W);
+    short sx = (short)X;
+    short sy = (short)Y;
+
+    if(dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
+        dst[(dst_offset>>2)+dy*dstStep+dx]= (sx>=0 && sx<src_cols && sy>=0 && sy<src_rows) ? src[(src_offset>>2)+sy*srcStep+sx] : 0; 
+}
+
+__kernel void warpPerspectiveLinear_C1_D5(__global float * src, __global float * dst, int src_cols, int src_rows,
+                            int dst_cols, int dst_rows, int srcStep, int dstStep, 
+                            int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    src_offset = (src_offset>>2);
+     
+    F X0 = M[0]*dx + M[1]*dy + M[2];
+    F Y0 = M[3]*dx + M[4]*dy + M[5];
+    F W = M[6]*dx + M[7]*dy + M[8];
+    W = (W != 0.0) ? INTER_TAB_SIZE/W : 0.0;
+    int X = rint(X0*W);
+    int Y = rint(Y0*W);
+    
+    short sx = (short)(X >> INTER_BITS);
+    short sy = (short)(Y >> INTER_BITS);
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+    
+    float v0, v1, v2, v3;
+
+    v0 = (sx >= 0 && sx < src_cols && sy >= 0 && sy < src_rows) ? src[src_offset+sy * srcStep + sx] : 0;
+    v1 = (sx+1 >= 0 && sx+1 < src_cols && sy >= 0 && sy < src_rows) ? src[src_offset+sy * srcStep + sx+1] : 0;
+    v2 = (sx >= 0 && sx < src_cols && sy+1 >= 0 && sy+1 < src_rows) ? src[src_offset+(sy+1) * srcStep + sx] : 0;
+    v3 = (sx+1 >= 0 && sx+1 < src_cols && sy+1 >= 0 && sy+1 < src_rows) ? src[src_offset+(sy+1) * srcStep + sx+1] : 0;
+
+    float tab[4];
+    float taby[2], tabx[2];
+    taby[0] = 1.0 - 1.f/INTER_TAB_SIZE*ay;
+    taby[1] = 1.f/INTER_TAB_SIZE*ay;
+    tabx[0] = 1.0 - 1.f/INTER_TAB_SIZE*ax;
+    tabx[1] = 1.f/INTER_TAB_SIZE*ax;
+   
+    tab[0] = taby[0] * tabx[0];
+    tab[1] = taby[0] * tabx[1];
+    tab[2] = taby[1] * tabx[0];
+    tab[3] = taby[1] * tabx[1];
+
+    float sum = 0;
+    sum += v0 * tab[0] +  v1 * tab[1] +  v2 * tab[2] +  v3 * tab[3]; 
+    if(dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
+        dst[(dst_offset>>2)+dy*dstStep+dx] = sum;
+}
+    
+__kernel void warpPerspectiveCubic_C1_D5(__global float * src, __global float * dst, int src_cols, int src_rows,
+                            int dst_cols, int dst_rows, int srcStep, int dstStep, 
+                            int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    src_offset = (src_offset>>2);
+    dst_offset = (dst_offset>>2);
+     
+    F X0 = M[0]*dx + M[1]*dy + M[2];
+    F Y0 = M[3]*dx + M[4]*dy + M[5];
+    F W = M[6]*dx + M[7]*dy + M[8];
+    W = (W != 0.0) ? INTER_TAB_SIZE/W : 0.0;
+    int X = rint(X0*W);
+    int Y = rint(Y0*W);
+    
+    short sx = (short)(X >> INTER_BITS) - 1;
+    short sy = (short)(Y >> INTER_BITS) - 1;
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+
+    float v[16];
+    int i;
+
+    for(i=0; i<16;  i++)
+        v[i] = (sx+(i&3) >= 0 && sx+(i&3) < src_cols && sy+(i>>2) >= 0 && sy+(i>>2) < src_rows) ? src[src_offset+(sy+(i>>2)) * srcStep + (sx+(i&3))] : 0;
+
+    float tab[16];
+    float tab1y[4], tab1x[4];
+    float axx, ayy;
+
+    ayy = 1.f/INTER_TAB_SIZE * ay;
+    axx = 1.f/INTER_TAB_SIZE * ax;
+    interpolateCubic(ayy, tab1y);
+    interpolateCubic(axx, tab1x);
+
+#pragma unroll 4
+    for( i=0; i<16; i++ )
+    {
+        tab[i] = tab1y[(i>>2)] * tab1x[(i&3)];
+    }
+    
+    if( dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
+    {
+        float sum = 0;
+#pragma unroll 4
+        for ( i =0; i<16; i++ )
+        {
+            sum += v[i] * tab[i];
+        }
+        dst[dst_offset+dy*dstStep+dx] = sum;
+
+    }
+}
+
+
+/**********************************************32FC4********************************************
+***********************************************************************************************/
+
+__kernel void warpPerspectiveNN_C4_D5(__global float4 * src, __global float4 * dst, int src_cols, int src_rows,
+                            int dst_cols, int dst_rows, int srcStep, int dstStep, 
+                            int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+        
+    F X0 = M[0]*dx + M[1]*dy + M[2];
+    F Y0 = M[3]*dx + M[4]*dy + M[5];
+    F W = M[6]*dx + M[7]*dy + M[8];
+    W =(W != 0.0)? 1./W : 0.0;
+    int X = rint(X0*W);
+    int Y = rint(Y0*W);
+    short sx = (short)X;
+    short sy = (short)Y;
+    
+    if(dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
+        dst[(dst_offset>>4)+dy*(dstStep>>2)+dx]= (sx>=0 && sx<src_cols && sy>=0 && sy<src_rows) ? src[(src_offset>>4)+sy*(srcStep>>2)+sx] : 0; 
+}
+
+__kernel void warpPerspectiveLinear_C4_D5(__global float4 * src, __global float4 * dst, int src_cols, int src_rows,
+                            int dst_cols, int dst_rows, int srcStep, int dstStep, 
+                            int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    src_offset = (src_offset>>4);
+    dst_offset = (dst_offset>>4);
+    srcStep = (srcStep>>2);
+    dstStep = (dstStep>>2);
+        
+    F X0 = M[0]*dx + M[1]*dy + M[2];
+    F Y0 = M[3]*dx + M[4]*dy + M[5];
+    F W = M[6]*dx + M[7]*dy + M[8];
+    W = (W != 0.0) ? INTER_TAB_SIZE/W : 0.0;
+    int X = rint(X0*W);
+    int Y = rint(Y0*W);
+    
+    short sx0 = (short)(X >> INTER_BITS);
+    short sy0 = (short)(Y >> INTER_BITS);
+    short ay0 = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax0 = (short)(X & (INTER_TAB_SIZE-1));
+    
+    float4 v0, v1, v2, v3;
+
+    v0 = (sx0 >= 0 && sx0 < src_cols && sy0 >= 0 && sy0 < src_rows) ? src[src_offset+sy0 * srcStep + sx0] : 0;
+    v1 = (sx0+1 >= 0 && sx0+1 < src_cols && sy0 >= 0 && sy0 < src_rows) ? src[src_offset+sy0 * srcStep + sx0+1] : 0;
+    v2 = (sx0 >= 0 && sx0 < src_cols && sy0+1 >= 0 && sy0+1 < src_rows) ? src[src_offset+(sy0+1) * srcStep + sx0] : 0;
+    v3 = (sx0+1 >= 0 && sx0+1 < src_cols && sy0+1 >= 0 && sy0+1 < src_rows) ? src[src_offset+(sy0+1) * srcStep + sx0+1] : 0;
+
+    float tab[4];
+    float taby[2], tabx[2];
+    taby[0] = 1.0 - 1.f/INTER_TAB_SIZE*ay0;
+    taby[1] = 1.f/INTER_TAB_SIZE*ay0;
+    tabx[0] = 1.0 - 1.f/INTER_TAB_SIZE*ax0;
+    tabx[1] = 1.f/INTER_TAB_SIZE*ax0;
+   
+    tab[0] = taby[0] * tabx[0];
+    tab[1] = taby[0] * tabx[1];
+    tab[2] = taby[1] * tabx[0];
+    tab[3] = taby[1] * tabx[1];
+
+    float4 sum = 0;
+    sum += v0 * tab[0] +  v1 * tab[1] +  v2 * tab[2] +  v3 * tab[3]; 
+    if(dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
+        dst[dst_offset+dy*dstStep+dx] = sum;
+}
+    
+__kernel void warpPerspectiveCubic_C4_D5(__global float4 * src, __global float4 * dst, 
+                            int src_cols, int src_rows, int dst_cols, int dst_rows, int srcStep,
+                                                       int dstStep, int src_offset, int dst_offset,  __constant F * M )
+{
+    int dx = get_global_id(0);
+    int dy = get_global_id(1);
+    
+    src_offset = (src_offset>>4);
+    dst_offset = (dst_offset>>4);
+    srcStep = (srcStep>>2);
+    dstStep = (dstStep>>2);
+        
+    F X0 = M[0]*dx + M[1]*dy + M[2];
+    F Y0 = M[3]*dx + M[4]*dy + M[5];
+    F W = M[6]*dx + M[7]*dy + M[8];
+    W = (W != 0.0) ? INTER_TAB_SIZE/W : 0.0;
+    int X = rint(X0*W);
+    int Y = rint(Y0*W);
+    
+    short sx = (short)(X >> INTER_BITS);
+    short sy = (short)(Y >> INTER_BITS);
+    short ay = (short)(Y & (INTER_TAB_SIZE-1));
+    short ax = (short)(X & (INTER_TAB_SIZE-1));
+    
+    float4 v[16];
+    int i;
+
+    for(i=0; i<16;  i++)
+        v[i] = (sx+(i&3) >= 0 && sx+(i&3) < src_cols && sy+(i>>2) >= 0 && sy+(i>>2) < src_rows) ? src[src_offset+(sy+(i>>2)) * srcStep + (sx+(i&3))] : 0;
+
+    float tab[16];
+    float tab1y[4], tab1x[4];
+    float axx, ayy;
+
+    ayy = 1.f/INTER_TAB_SIZE * ay;
+    axx = 1.f/INTER_TAB_SIZE * ax;
+    interpolateCubic(ayy, tab1y);
+    interpolateCubic(axx, tab1x);
+
+#pragma unroll 4
+    for( i=0; i<16; i++ )
+    {
+        tab[i] = tab1y[(i>>2)] * tab1x[(i&3)];
+    }
+    
+    if( dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
+    {
+        float4 sum = 0;
+#pragma unroll 4
+        for ( i =0; i<16; i++ )
+        {
+            sum += v[i] * tab[i];
+        }
+        dst[dst_offset+dy*dstStep+dx] = sum;
+
+    }
+}
+
diff --git a/modules/ocl/src/kernels/meanShift.cl b/modules/ocl/src/kernels/meanShift.cl
new file mode 100644 (file)
index 0000000..7f82d79
--- /dev/null
@@ -0,0 +1,248 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Shengen Yan,yanshengen@gmail.com
+//    Xu Pang, pangxu010@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 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
+// 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*/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+typedef double F;
+#else
+typedef float F;
+#endif
+
+short2 do_mean_shift(int x0, int y0, __global uchar4* out,int out_step, 
+               __global uchar4* in, int in_step, int dst_off, int src_off, 
+               int cols, int rows, int sp, int sr, int maxIter, float eps)
+{
+    int isr2 = sr*sr;
+    in_step = in_step >> 2;
+    out_step = out_step >> 2;
+    src_off = src_off >> 2;
+    dst_off = dst_off >> 2;
+    int idx = src_off + y0 * in_step + x0;
+//    uchar4 c = vload4(0, (__global uchar*)in+idx);
+    uchar4 c = in[idx];
+    int base = dst_off + get_global_id(1)*out_step + get_global_id(0) ;
+
+    // iterate meanshift procedure
+    for( int iter = 0; iter < maxIter; iter++ )
+    {
+        int count = 0;
+        int4 s = (int4)0;
+        int sx = 0, sy = 0;
+
+        //mean shift: process pixels in window (p-sigmaSp)x(p+sigmaSp)
+        //deal with the image boundary
+        int minx = (x0-sp)>0 ? x0-sp : 0;
+        int miny = (y0-sp)>0 ? y0-sp : 0;
+        int maxx = (x0+sp)<cols ? x0+sp : cols-1;
+        int maxy = (y0+sp)<rows ? y0+sp : rows-1;
+
+        for( int y = miny; y <= maxy; y++)
+        {
+            int rowCount = 0;
+            int x = minx; 
+            for( ; x+3 <= maxx; x+=4 )
+            {                    
+                int id = src_off + y*in_step + x;
+                uchar16 t = (uchar16)(in[id],in[id+1],in[id+2],in[id+3]);
+                int norm2_1 = (t.s0 - c.x) * (t.s0 - c.x) + (t.s1 - c.y) * (t.s1 - c.y) +
+                              (t.s2 - c.z) * (t.s2 - c.z);
+                int norm2_2 = (t.s4 - c.x) * (t.s4 - c.x) + (t.s5 - c.y) * (t.s5 - c.y) +
+                              (t.s6 - c.z) * (t.s6 - c.z);
+                int norm2_3 = (t.s8 - c.x) * (t.s8 - c.x) + (t.s9 - c.y) * (t.s9 - c.y) +
+                              (t.sa - c.z) * (t.sa - c.z);
+                int norm2_4 = (t.sc - c.x) * (t.sc - c.x) + (t.sd - c.y) * (t.sd - c.y) +
+                              (t.se - c.z) * (t.se - c.z);
+                if( norm2_1 <= isr2 )
+                {
+                    s.x += t.s0; s.y += t.s1; s.z += t.s2;
+                    sx += x; rowCount++;
+                }
+                if( norm2_2 <= isr2 )
+                {
+                    s.x += t.s4; s.y += t.s5; s.z += t.s6;
+                    sx += x+1; rowCount++;
+                }
+                if( norm2_3 <= isr2 )
+                {
+                    s.x += t.s8; s.y += t.s9; s.z += t.sa;
+                    sx += x+2; rowCount++;
+                }
+                if( norm2_4 <= isr2 )
+                {
+                    s.x += t.sc; s.y += t.sd; s.z += t.se;
+                    sx += x+3; rowCount++;
+                }
+            }
+            if(x == maxx)
+            {
+                int id = src_off + y*in_step + x;
+                uchar4 t = in[id];
+                int norm2 = (t.s0 - c.x) * (t.s0 - c.x) + (t.s1 - c.y) * (t.s1 - c.y) +
+                            (t.s2 - c.z) * (t.s2 - c.z);
+                if( norm2 <= isr2 )
+                {
+                    s.x += t.s0; s.y += t.s1; s.z += t.s2;
+                    sx += x; rowCount++;
+                }
+                
+            }
+            if(x+1 == maxx)
+            {
+                  int id = src_off + y*in_step + x;
+                  uchar8 t = (uchar8)(in[id],in[id+1]);
+                  int norm2_1 = (t.s0 - c.x) * (t.s0 - c.x) + (t.s1 - c.y) * (t.s1 - c.y) +
+                                (t.s2 - c.z) * (t.s2 - c.z);
+                  int norm2_2 = (t.s4 - c.x) * (t.s4 - c.x) + (t.s5 - c.y) * (t.s5 - c.y) +
+                                (t.s6 - c.z) * (t.s6 - c.z);
+                  if( norm2_1 <= isr2 )
+                  {
+                      s.x += t.s0; s.y += t.s1; s.z += t.s2;
+                      sx += x; rowCount++;
+                  }
+                  if( norm2_2 <= isr2 )
+                  {
+                      s.x += t.s4; s.y += t.s5; s.z += t.s6;
+                      sx += x+1; rowCount++;
+                  }
+            }
+            if(x+2 == maxx)
+            {
+                  int id = src_off + y*in_step + x;
+                  uchar16 t = (uchar16)(in[id],in[id+1],in[id+2],in[id+3]);
+                  int norm2_1 = (t.s0 - c.x) * (t.s0 - c.x) + (t.s1 - c.y) * (t.s1 - c.y) +
+                                (t.s2 - c.z) * (t.s2 - c.z);
+                  int norm2_2 = (t.s4 - c.x) * (t.s4 - c.x) + (t.s5 - c.y) * (t.s5 - c.y) +
+                                (t.s6 - c.z) * (t.s6 - c.z);
+                  int norm2_3 = (t.s8 - c.x) * (t.s8 - c.x) + (t.s9 - c.y) * (t.s9 - c.y) +
+                                (t.sa - c.z) * (t.sa - c.z);
+                  if( norm2_1 <= isr2 )
+                  {
+                      s.x += t.s0; s.y += t.s1; s.z += t.s2;
+                      sx += x; rowCount++;
+                  }
+                  if( norm2_2 <= isr2 )
+                  {
+                      s.x += t.s4; s.y += t.s5; s.z += t.s6;
+                      sx += x+1; rowCount++;
+                  }
+                  if( norm2_3 <= isr2 )
+                  {
+                      s.x += t.s8; s.y += t.s9; s.z += t.sa;
+                      sx += x+2; rowCount++;
+                  }
+            }
+            if(rowCount == 0)
+               continue;
+            count += rowCount;
+            if(y == 0)
+               continue;
+            sy += y*rowCount;
+        }
+
+        if( count == 0 )
+            break;
+
+        F  icount = 1.0/count;
+        int x1 = convert_int_rtz(sx*icount);
+        int y1 = convert_int_rtz(sy*icount);
+        s.x = convert_int_rtz(s.x*icount);
+        s.y = convert_int_rtz(s.y*icount);
+        s.z = convert_int_rtz(s.z*icount);
+
+        int4 tmp = s - convert_int4(c);
+        int norm2 = tmp.x * tmp.x + tmp.y *  tmp.y +
+                    tmp.z * tmp.z;
+
+        bool stopFlag = (x1 == x0 && y1 == y0) || (abs(x1-x0) + abs(y1-y0) + norm2 <= eps);
+
+        x0 = x1;
+        y0 = y1;
+        c.x = s.x;
+        c.y = s.y;
+        c.z = s.z;
+
+        if( stopFlag )
+            break;
+    }
+
+    out[base] = c;
+
+    return (short2)((short)x0, (short)y0);
+}
+
+
+__kernel void meanshift_kernel(__global uchar4* out, int out_step, 
+                               __global uchar4* in, int in_step, 
+                        int dst_off, int src_off, int cols, int rows,
+                        int sp, int sr, int maxIter, float eps)
+{
+    int x0 = get_global_id(0); 
+    int y0 = get_global_id(1); 
+    if( x0 < cols && y0 < rows )
+        do_mean_shift(x0, y0, out, out_step, in, in_step, dst_off, src_off,
+                          cols, rows, sp, sr, maxIter, eps);
+}
+
+__kernel void meanshiftproc_kernel( __global uchar4* in, __global uchar4* outr, 
+                             __global short2* outsp, int instep, int outrstep, 
+                             int outspstep, int in_off, int outr_off, int outsp_off,
+                             int cols, int rows, int sp, int sr, int maxIter, float eps )
+{
+    int x0 = get_global_id(0); 
+    int y0 = get_global_id(1); 
+
+    if( x0 < cols && y0 < rows )
+    {
+        //int basesp = (blockIdx.y * blockDim.y + threadIdx.y) * outspstep + (blockIdx.x * blockDim.x + threadIdx.x) * 2 * sizeof(short);
+        //*(short2*)(outsp + basesp) = do_mean_shift(x0, y0, outr, outrstep, cols, rows, sp, sr, maxIter, eps);
+        // we have ensured before that ((outspstep & 0x11)==0).
+        outsp_off >>= 2; 
+        outspstep >>= 2;
+        int basesp = outsp_off + y0 * outspstep + x0;
+        outsp[basesp] = do_mean_shift(x0, y0, outr, outrstep, in, instep, outr_off, in_off, cols, rows, sp, sr, maxIter, eps);
+//        outsp[basesp] =(short2)((short)x0,(short)y0);
+    }
+}
+
diff --git a/modules/ocl/src/kernels/merge_mat.cl b/modules/ocl/src/kernels/merge_mat.cl
new file mode 100644 (file)
index 0000000..2360de8
--- /dev/null
@@ -0,0 +1,1374 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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*/
+
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////optimized code using vector roi//////////////////////////
+////////////vector fuction name format: merge_vector_C(channels number)D_(data type depth)//////
+////////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void merge_vector_C2_D0(__global uchar *mat_dst,  int dst_step,  int dst_offset,
+                                 __global uchar *mat_src0, int src0_step, int src0_offset,
+                                 __global uchar *mat_src1, int src1_step, int src1_offset,
+                                 int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        x = x << 1;
+
+        #define dst_align  ((dst_offset & 3) >> 1)
+        int src0_index = mad24(y, src0_step, src0_offset + x - dst_align); 
+        int src1_index = mad24(y, src1_step, src1_offset + x - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        __global uchar4 * dst  = (__global uchar4 *)(mat_dst + dst_index); 
+        __global uchar  * src0 = mat_src0 + src0_index; 
+        __global uchar  * src1 = src0     + 1; 
+        __global uchar  * src2 = mat_src1 + src1_index; 
+        __global uchar  * src3 = src2     + 1; 
+
+        uchar4 dst_data = *dst;
+        uchar  data_0   = *(src0);
+        uchar  data_1   = *(src1);
+        uchar  data_2   = *(src2);
+        uchar  data_3   = *(src3);
+
+        uchar4 tmp_data = (uchar4)(data_0, data_2, data_1, data_3);
+
+        tmp_data.xy = dst_index + 0 >= dst_start ? tmp_data.xy : dst_data.xy; 
+        tmp_data.zw = dst_index + 2 <  dst_end   ? tmp_data.zw : dst_data.zw; 
+
+        *dst = tmp_data;
+    }
+}
+__kernel void merge_vector_C2_D1(__global char *mat_dst,  int dst_step,  int dst_offset,
+                                 __global char *mat_src0, int src0_step, int src0_offset,
+                                 __global char *mat_src1, int src1_step, int src1_offset,
+                                 int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        x = x << 1;
+
+        #define dst_align  ((dst_offset & 3) >> 1)
+        int src0_index = mad24(y, src0_step, src0_offset + x - dst_align); 
+        int src1_index = mad24(y, src1_step, src1_offset + x - dst_align); 
+
+        int dst_start  = mad24(y, dst_step, dst_offset);
+        int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
+        int dst_index  = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffffc);
+
+        __global char4 * dst  = (__global char4 *)(mat_dst + dst_index); 
+        __global char  * src0 = mat_src0 + src0_index; 
+        __global char  * src1 = src0     + 1; 
+        __global char  * src2 = mat_src1 + src1_index; 
+        __global char  * src3 = src2     + 1; 
+
+        char4 dst_data = *dst;
+        char  data_0   = *(src0);
+        char  data_1   = *(src1);
+        char  data_2   = *(src2);
+        char  data_3   = *(src3);
+
+        char4 tmp_data = (char4)(data_0, data_2, data_1, data_3);
+
+        tmp_data.xy = dst_index + 0 >= dst_start ? tmp_data.xy : dst_data.xy; 
+        tmp_data.zw = dst_index + 2 <  dst_end   ? tmp_data.zw : dst_data.zw; 
+
+        *dst = tmp_data;
+    }
+}
+__kernel void merge_vector_C2_D2(__global ushort *mat_dst,  int dst_step,  int dst_offset,
+                                 __global ushort *mat_src0, int src0_step, int src0_offset,
+                                 __global ushort *mat_src1, int src1_step, int src1_offset,
+                                 int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        int src0_index = mad24(y, src0_step, src0_offset); 
+        int src1_index = mad24(y, src1_step, src1_offset); 
+
+        int dst_index  = mad24(y, dst_step , dst_offset);
+
+        __global ushort*  src0 = (__global ushort * )((__global uchar *)mat_src0 + src0_index + (x << 1));
+        __global ushort*  src1 = (__global ushort * )((__global uchar *)mat_src1 + src1_index + (x << 1));
+        __global ushort2* dist = (__global ushort2 *)((__global uchar *)mat_dst  + dst_index  + (x << 2));
+
+        ushort  src0_data = *src0;
+        ushort  src1_data = *src1;
+
+        *dist = (ushort2)(src0_data, src1_data);
+
+    }
+}
+__kernel void merge_vector_C2_D3(__global short *mat_dst,  int dst_step,  int dst_offset,
+                                 __global short *mat_src0, int src0_step, int src0_offset,
+                                 __global short *mat_src1, int src1_step, int src1_offset,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        int src0_index = mad24(y, src0_step, src0_offset); 
+        int src1_index = mad24(y, src1_step, src1_offset); 
+
+        int dst_index  = mad24(y, dst_step , dst_offset);
+
+        __global short*  src0 = (__global short * )((__global uchar *)mat_src0 + src0_index + (x << 1));
+        __global short*  src1 = (__global short * )((__global uchar *)mat_src1 + src1_index + (x << 1));
+        __global short2* dist = (__global short2 *)((__global uchar *)mat_dst  + dst_index   + (x << 2));
+
+        short  src0_data = *src0;
+        short  src1_data = *src1;
+
+        *dist = (short2)(src0_data, src1_data);
+    }
+}
+
+__kernel void merge_vector_C2_D4(__global int *mat_dst,  int dst_step,  int dst_offset,
+                                 __global int *mat_src0, int src0_step, int src0_offset,
+                                 __global int *mat_src1, int src1_step, int src1_offset,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        int src0_index = mad24(y, src0_step, src0_offset); 
+        int src1_index = mad24(y, src1_step, src1_offset); 
+        int dst_index  = mad24(y, dst_step , dst_offset);
+
+        int src0 = *((__global int *)((__global uchar *)mat_src0 + src0_index + (x << 2)));
+        int src1 = *((__global int *)((__global uchar *)mat_src1 + src1_index + (x << 2)));
+
+        *((__global int2 *)((__global uchar *)mat_dst  + dst_index + (x << 4))) = (int2)(src0, src1);
+    }
+}
+__kernel void merge_vector_C2_D5(__global float *mat_dst,  int dst_step,  int dst_offset,
+                                 __global float *mat_src0, int src0_step, int src0_offset,
+                                 __global float *mat_src1, int src1_step, int src1_offset,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        int src0_index = mad24(y, src0_step, src0_offset); 
+        int src1_index = mad24(y, src1_step, src1_offset); 
+        int dst_index  = mad24(y, dst_step , dst_offset);
+
+        float src0 = *((__global float *)((__global uchar *)mat_src0 + src0_index + (x << 2)));
+        float src1 = *((__global float *)((__global uchar *)mat_src1 + src1_index + (x << 2)));
+
+        *((__global float2 *)((__global uchar *)mat_dst  + dst_index + (x << 4))) = (float2)(src0, src1);
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void merge_vector_C2_D6(__global double *mat_dst,  int dst_step,  int dst_offset,
+                                 __global double *mat_src0, int src0_step, int src0_offset,
+                                 __global double *mat_src1, int src1_step, int src1_offset,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        int src0_index = mad24(y, src0_step, src0_offset); 
+        int src1_index = mad24(y, src1_step, src1_offset); 
+        int dst_index  = mad24(y, dst_step , dst_offset);
+
+        double src0 = *((__global double *)((__global uchar *)mat_src0 + src0_index + (x << 3)));
+        double src1 = *((__global double *)((__global uchar *)mat_src1 + src1_index + (x << 3)));
+
+        *((__global double2 *)((__global uchar *)mat_dst  + dst_index + (x << 4))) = (double2)(src0, src1);
+    }
+}
+#endif
+
+__kernel void merge_vector_C3_D0(__global uchar *mat_dst,  int dst_step,  int dst_offset,
+                                 __global uchar *mat_src0, int src0_step, int src0_offset,
+                                 __global uchar *mat_src1, int src1_step, int src1_offset,
+                                 __global uchar *mat_src2, int src2_step, int src2_offset, int offset_cols,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        x = x << 2;
+
+        int src0_index = mad24(y, src0_step, x + src0_offset - offset_cols);
+        int src1_index = mad24(y, src1_step, x + src1_offset - offset_cols);
+        int src2_index = mad24(y, src2_step, x + src2_offset - offset_cols);
+
+        int dst_start = mad24(y, dst_step, dst_offset); 
+        int dst_end   = mad24(y, dst_step, dst_offset + dst_step1); 
+        int dst_index = mad24(y, dst_step, dst_offset + 3 * x - offset_cols * 3);
+
+        uchar data0_0 = *(mat_src0 + src0_index + 0);
+        uchar data0_1 = *(mat_src0 + src0_index + 1);
+        uchar data0_2 = *(mat_src0 + src0_index + 2);
+        uchar data0_3 = *(mat_src0 + src0_index + 3);
+
+        uchar data1_0 = *(mat_src1 + src1_index + 0);
+        uchar data1_1 = *(mat_src1 + src1_index + 1);
+        uchar data1_2 = *(mat_src1 + src1_index + 2);
+        uchar data1_3 = *(mat_src1 + src1_index + 3);
+
+        uchar data2_0 = *(mat_src2 + src2_index + 0);
+        uchar data2_1 = *(mat_src2 + src2_index + 1);
+        uchar data2_2 = *(mat_src2 + src2_index + 2);
+        uchar data2_3 = *(mat_src2 + src2_index + 3);
+
+        uchar4 tmp_data0 = (uchar4)(data0_0, data1_0, data2_0, data0_1);
+        uchar4 tmp_data1 = (uchar4)(data1_1, data2_1, data0_2, data1_2);
+        uchar4 tmp_data2 = (uchar4)(data2_2, data0_3, data1_3, data2_3);
+
+        uchar4 dst_data0 = *((__global uchar4*)(mat_dst + dst_index + 0));
+        uchar4 dst_data1 = *((__global uchar4*)(mat_dst + dst_index + 4));
+        uchar4 dst_data2 = *((__global uchar4*)(mat_dst + dst_index + 8));
+
+        tmp_data0.x = ((dst_index + 0  >= dst_start) && (dst_index + 0  < dst_end)) ? tmp_data0.x : dst_data0.x;
+        tmp_data0.y = ((dst_index + 1  >= dst_start) && (dst_index + 1  < dst_end)) ? tmp_data0.y : dst_data0.y;
+        tmp_data0.z = ((dst_index + 2  >= dst_start) && (dst_index + 2  < dst_end)) ? tmp_data0.z : dst_data0.z;
+        tmp_data0.w = ((dst_index + 3  >= dst_start) && (dst_index + 3  < dst_end)) ? tmp_data0.w : dst_data0.w;
+
+        tmp_data1.x = ((dst_index + 4  >= dst_start) && (dst_index + 4  < dst_end)) ? tmp_data1.x : dst_data1.x;
+        tmp_data1.y = ((dst_index + 5  >= dst_start) && (dst_index + 5  < dst_end)) ? tmp_data1.y : dst_data1.y;
+        tmp_data1.z = ((dst_index + 6  >= dst_start) && (dst_index + 6  < dst_end)) ? tmp_data1.z : dst_data1.z;
+        tmp_data1.w = ((dst_index + 7  >= dst_start) && (dst_index + 7  < dst_end)) ? tmp_data1.w : dst_data1.w;
+
+        tmp_data2.x = ((dst_index + 8  >= dst_start) && (dst_index + 8  < dst_end)) ? tmp_data2.x : dst_data2.x;
+        tmp_data2.y = ((dst_index + 9  >= dst_start) && (dst_index + 9  < dst_end)) ? tmp_data2.y : dst_data2.y;
+        tmp_data2.z = ((dst_index + 10 >= dst_start) && (dst_index + 10 < dst_end)) ? tmp_data2.z : dst_data2.z;
+        tmp_data2.w = ((dst_index + 11 >= dst_start) && (dst_index + 11 < dst_end)) ? tmp_data2.w : dst_data2.w;
+
+        *((__global uchar4*)(mat_dst + dst_index + 0)) = tmp_data0;
+        *((__global uchar4*)(mat_dst + dst_index + 4)) = tmp_data1;
+        *((__global uchar4*)(mat_dst + dst_index + 8)) = tmp_data2;
+    }
+}
+__kernel void merge_vector_C3_D1(__global char *mat_dst,  int dst_step,  int dst_offset,
+                                 __global char *mat_src0, int src0_step, int src0_offset,
+                                 __global char *mat_src1, int src1_step, int src1_offset,
+                                 __global char *mat_src2, int src2_step, int src2_offset, int offset_cols,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        x = x << 2;
+
+        int src0_index = mad24(y, src0_step, x + src0_offset - offset_cols);
+        int src1_index = mad24(y, src1_step, x + src1_offset - offset_cols);
+        int src2_index = mad24(y, src2_step, x + src2_offset - offset_cols);
+
+        int dst_start = mad24(y, dst_step, dst_offset); 
+        int dst_end   = mad24(y, dst_step, dst_offset + dst_step1); 
+        int dst_index = mad24(y, dst_step, dst_offset + 3 * x - offset_cols * 3);
+
+        char data0_0 = *(mat_src0 + src0_index + 0);
+        char data0_1 = *(mat_src0 + src0_index + 1);
+        char data0_2 = *(mat_src0 + src0_index + 2);
+        char data0_3 = *(mat_src0 + src0_index + 3);
+
+        char data1_0 = *(mat_src1 + src1_index + 0);
+        char data1_1 = *(mat_src1 + src1_index + 1);
+        char data1_2 = *(mat_src1 + src1_index + 2);
+        char data1_3 = *(mat_src1 + src1_index + 3);
+
+        char data2_0 = *(mat_src2 + src2_index + 0);
+        char data2_1 = *(mat_src2 + src2_index + 1);
+        char data2_2 = *(mat_src2 + src2_index + 2);
+        char data2_3 = *(mat_src2 + src2_index + 3);
+
+        char4 tmp_data0 = (char4)(data0_0, data1_0, data2_0, data0_1);
+        char4 tmp_data1 = (char4)(data1_1, data2_1, data0_2, data1_2);
+        char4 tmp_data2 = (char4)(data2_2, data0_3, data1_3, data2_3);
+
+        char4 dst_data0 = *((__global char4*)(mat_dst + dst_index + 0));
+        char4 dst_data1 = *((__global char4*)(mat_dst + dst_index + 4));
+        char4 dst_data2 = *((__global char4*)(mat_dst + dst_index + 8));
+
+        tmp_data0.x = ((dst_index + 0  >= dst_start) && (dst_index + 0  < dst_end)) ? tmp_data0.x : dst_data0.x;
+        tmp_data0.y = ((dst_index + 1  >= dst_start) && (dst_index + 1  < dst_end)) ? tmp_data0.y : dst_data0.y;
+        tmp_data0.z = ((dst_index + 2  >= dst_start) && (dst_index + 2  < dst_end)) ? tmp_data0.z : dst_data0.z;
+        tmp_data0.w = ((dst_index + 3  >= dst_start) && (dst_index + 3  < dst_end)) ? tmp_data0.w : dst_data0.w;
+
+        tmp_data1.x = ((dst_index + 4  >= dst_start) && (dst_index + 4  < dst_end)) ? tmp_data1.x : dst_data1.x;
+        tmp_data1.y = ((dst_index + 5  >= dst_start) && (dst_index + 5  < dst_end)) ? tmp_data1.y : dst_data1.y;
+        tmp_data1.z = ((dst_index + 6  >= dst_start) && (dst_index + 6  < dst_end)) ? tmp_data1.z : dst_data1.z;
+        tmp_data1.w = ((dst_index + 7  >= dst_start) && (dst_index + 7  < dst_end)) ? tmp_data1.w : dst_data1.w;
+
+        tmp_data2.x = ((dst_index + 8  >= dst_start) && (dst_index + 8  < dst_end)) ? tmp_data2.x : dst_data2.x;
+        tmp_data2.y = ((dst_index + 9  >= dst_start) && (dst_index + 9  < dst_end)) ? tmp_data2.y : dst_data2.y;
+        tmp_data2.z = ((dst_index + 10 >= dst_start) && (dst_index + 10 < dst_end)) ? tmp_data2.z : dst_data2.z;
+        tmp_data2.w = ((dst_index + 11 >= dst_start) && (dst_index + 11 < dst_end)) ? tmp_data2.w : dst_data2.w;
+
+        *((__global char4*)(mat_dst + dst_index + 0)) = tmp_data0;
+        *((__global char4*)(mat_dst + dst_index + 4)) = tmp_data1;
+        *((__global char4*)(mat_dst + dst_index + 8)) = tmp_data2;
+    }
+}
+__kernel void merge_vector_C3_D2(__global ushort *mat_dst,  int dst_step,  int dst_offset,
+                                 __global ushort *mat_src0, int src0_step, int src0_offset,
+                                 __global ushort *mat_src1, int src1_step, int src1_offset,
+                                 __global ushort *mat_src2, int src2_step, int src2_offset, int offset_cols,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        x = x << 1;
+
+        int src0_index = mad24(y, src0_step, (x << 1) + src0_offset - offset_cols);
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - offset_cols);
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - offset_cols);
+
+        int dst_start = mad24(y, dst_step, dst_offset); 
+        int dst_end   = mad24(y, dst_step, dst_offset + dst_step1); 
+        int dst_index = mad24(y, dst_step, dst_offset + 6 * x - offset_cols * 6);
+
+        ushort data0_0 = *((__global ushort *)((__global char *)mat_src0 + src0_index + 0));
+        ushort data0_1 = *((__global ushort *)((__global char *)mat_src0 + src0_index + 2));
+
+        ushort data1_0 = *((__global ushort *)((__global char *)mat_src1 + src1_index + 0));
+        ushort data1_1 = *((__global ushort *)((__global char *)mat_src1 + src1_index + 2));
+
+        ushort data2_0 = *((__global ushort *)((__global char *)mat_src2 + src2_index + 0));
+        ushort data2_1 = *((__global ushort *)((__global char *)mat_src2 + src2_index + 2));
+
+        ushort2 tmp_data0 = (ushort2)(data0_0, data1_0);
+        ushort2 tmp_data1 = (ushort2)(data2_0, data0_1);
+        ushort2 tmp_data2 = (ushort2)(data1_1, data2_1);
+
+        ushort2 dst_data0 = *((__global ushort2*)((__global char *)mat_dst + dst_index + 0));
+        ushort2 dst_data1 = *((__global ushort2*)((__global char *)mat_dst + dst_index + 4));
+        ushort2 dst_data2 = *((__global ushort2*)((__global char *)mat_dst + dst_index + 8));
+
+        tmp_data0.x = ((dst_index + 0  >= dst_start) && (dst_index + 0  < dst_end)) ? tmp_data0.x : dst_data0.x;
+        tmp_data0.y = ((dst_index + 2  >= dst_start) && (dst_index + 2  < dst_end)) ? tmp_data0.y : dst_data0.y;
+
+        tmp_data1.x = ((dst_index + 4  >= dst_start) && (dst_index + 4  < dst_end)) ? tmp_data1.x : dst_data1.x;
+        tmp_data1.y = ((dst_index + 6  >= dst_start) && (dst_index + 6  < dst_end)) ? tmp_data1.y : dst_data1.y;
+
+        tmp_data2.x = ((dst_index + 8  >= dst_start) && (dst_index + 8  < dst_end)) ? tmp_data2.x : dst_data2.x;
+        tmp_data2.y = ((dst_index + 10 >= dst_start) && (dst_index + 10 < dst_end)) ? tmp_data2.y : dst_data2.y;
+
+        *((__global ushort2*)((__global char *)mat_dst + dst_index + 0)) = tmp_data0;
+        *((__global ushort2*)((__global char *)mat_dst + dst_index + 4)) = tmp_data1;
+        *((__global ushort2*)((__global char *)mat_dst + dst_index + 8)) = tmp_data2;
+    }
+}
+__kernel void merge_vector_C3_D3(__global short *mat_dst,  int dst_step,  int dst_offset,
+                                 __global short *mat_src0, int src0_step, int src0_offset,
+                                 __global short *mat_src1, int src1_step, int src1_offset,
+                                 __global short *mat_src2, int src2_step, int src2_offset, int offset_cols,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        x = x << 1;
+
+        int src0_index = mad24(y, src0_step, (x << 1) + src0_offset - offset_cols);
+        int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - offset_cols);
+        int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - offset_cols);
+
+        int dst_start = mad24(y, dst_step, dst_offset); 
+        int dst_end   = mad24(y, dst_step, dst_offset + dst_step1); 
+        int dst_index = mad24(y, dst_step, dst_offset + 6 * x - offset_cols * 6);
+
+        short data0_0 = *((__global short *)((__global char *)mat_src0 + src0_index + 0));
+        short data0_1 = *((__global short *)((__global char *)mat_src0 + src0_index + 2));
+
+        short data1_0 = *((__global short *)((__global char *)mat_src1 + src1_index + 0));
+        short data1_1 = *((__global short *)((__global char *)mat_src1 + src1_index + 2));
+
+        short data2_0 = *((__global short *)((__global char *)mat_src2 + src2_index + 0));
+        short data2_1 = *((__global short *)((__global char *)mat_src2 + src2_index + 2));
+
+        short2 tmp_data0 = (short2)(data0_0, data1_0);
+        short2 tmp_data1 = (short2)(data2_0, data0_1);
+        short2 tmp_data2 = (short2)(data1_1, data2_1);
+
+        short2 dst_data0 = *((__global short2*)((__global char *)mat_dst + dst_index + 0));
+        short2 dst_data1 = *((__global short2*)((__global char *)mat_dst + dst_index + 4));
+        short2 dst_data2 = *((__global short2*)((__global char *)mat_dst + dst_index + 8));
+
+        tmp_data0.x = ((dst_index + 0  >= dst_start) && (dst_index + 0  < dst_end)) ? tmp_data0.x : dst_data0.x;
+        tmp_data0.y = ((dst_index + 2  >= dst_start) && (dst_index + 2  < dst_end)) ? tmp_data0.y : dst_data0.y;
+
+        tmp_data1.x = ((dst_index + 4  >= dst_start) && (dst_index + 4  < dst_end)) ? tmp_data1.x : dst_data1.x;
+        tmp_data1.y = ((dst_index + 6  >= dst_start) && (dst_index + 6  < dst_end)) ? tmp_data1.y : dst_data1.y;
+
+        tmp_data2.x = ((dst_index + 8  >= dst_start) && (dst_index + 8  < dst_end)) ? tmp_data2.x : dst_data2.x;
+        tmp_data2.y = ((dst_index + 10 >= dst_start) && (dst_index + 10 < dst_end)) ? tmp_data2.y : dst_data2.y;
+
+        *((__global short2*)((__global char *)mat_dst + dst_index + 0)) = tmp_data0;
+        *((__global short2*)((__global char *)mat_dst + dst_index + 4)) = tmp_data1;
+        *((__global short2*)((__global char *)mat_dst + dst_index + 8)) = tmp_data2;
+    }
+}
+__kernel void merge_vector_C3_D4(__global int *mat_dst,  int dst_step,  int dst_offset,
+                                 __global int *mat_src0, int src0_step, int src0_offset,
+                                 __global int *mat_src1, int src1_step, int src1_offset,
+                                 __global int *mat_src2, int src2_step, int src2_offset, int offset_cols,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        int src0_index = mad24(y, src0_step, src0_offset); 
+        int src1_index = mad24(y, src1_step, src1_offset); 
+        int src2_index = mad24(y, src2_step, src2_offset); 
+
+        int dst_index  = mad24(y, dst_step , dst_offset);
+
+        __global int* src0 = (__global int * )((__global uchar *)mat_src0 + src0_index + (x << 2));
+        __global int* src1 = (__global int * )((__global uchar *)mat_src1 + src1_index + (x << 2));
+        __global int* src2 = (__global int * )((__global uchar *)mat_src2 + src2_index + (x << 2));
+
+        __global int* dist0 = (__global int *)((__global uchar *)mat_dst  + dst_index  + 3 * (x << 2));
+        __global int* dist1 = dist0 + 1;
+        __global int* dist2 = dist0 + 2;
+
+        int  src0_data = *src0;
+        int  src1_data = *src1;
+        int  src2_data = *src2;
+
+        *dist0 = src0_data;
+        *dist1 = src1_data;
+        *dist2 = src2_data;
+    }
+}
+__kernel void merge_vector_C3_D5(__global float *mat_dst,  int dst_step,  int dst_offset,
+                                 __global float *mat_src0, int src0_step, int src0_offset,
+                                 __global float *mat_src1, int src1_step, int src1_offset,
+                                 __global float *mat_src2, int src2_step, int src2_offset, int offset_cols,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        int src0_index = mad24(y, src0_step, src0_offset); 
+        int src1_index = mad24(y, src1_step, src1_offset); 
+        int src2_index = mad24(y, src2_step, src2_offset); 
+
+        int dst_index  = mad24(y, dst_step , dst_offset);
+
+        __global float* src0 = (__global float * )((__global uchar *)mat_src0 + src0_index + (x << 2));
+        __global float* src1 = (__global float * )((__global uchar *)mat_src1 + src1_index + (x << 2));
+        __global float* src2 = (__global float * )((__global uchar *)mat_src2 + src2_index + (x << 2));
+
+        __global float* dist0 = (__global float *)((__global uchar *)mat_dst  + dst_index  + 3 * (x << 2));
+        __global float* dist1 = dist0 + 1;
+        __global float* dist2 = dist0 + 2;
+
+        float  src0_data = *src0;
+        float  src1_data = *src1;
+        float  src2_data = *src2;
+
+        *dist0 = src0_data;
+        *dist1 = src1_data;
+        *dist2 = src2_data;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void merge_vector_C3_D6(__global double *mat_dst,  int dst_step,  int dst_offset,
+                                 __global double *mat_src0, int src0_step, int src0_offset,
+                                 __global double *mat_src1, int src1_step, int src1_offset,
+                                 __global double *mat_src2, int src2_step, int src2_offset, int offset_cols,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        int src0_index = mad24(y, src0_step, src0_offset); 
+        int src1_index = mad24(y, src1_step, src1_offset); 
+        int src2_index = mad24(y, src2_step, src2_offset); 
+
+        int dst_index  = mad24(y, dst_step , dst_offset);
+
+        __global double* src0 = (__global double * )((__global uchar *)mat_src0 + src0_index + (x << 3));
+        __global double* src1 = (__global double * )((__global uchar *)mat_src1 + src1_index + (x << 3));
+        __global double* src2 = (__global double * )((__global uchar *)mat_src2 + src2_index + (x << 3));
+
+        __global double* dist0 = (__global double *)((__global uchar *)mat_dst  + dst_index  + 3 * (x << 3));
+        __global double* dist1 = dist0 + 1;
+        __global double* dist2 = dist0 + 2;
+
+        double  src0_data = *src0;
+        double  src1_data = *src1;
+        double  src2_data = *src2;
+
+        *dist0 = src0_data;
+        *dist1 = src1_data;
+        *dist2 = src2_data;
+    }
+}
+#endif
+__kernel void merge_vector_C4_D0(__global uchar *mat_dst,  int dst_step,  int dst_offset,
+                                 __global uchar *mat_src0, int src0_step, int src0_offset,
+                                 __global uchar *mat_src1, int src1_step, int src1_offset,
+                                 __global uchar *mat_src2, int src2_step, int src2_offset,
+                                 __global uchar *mat_src3, int src3_step, int src3_offset,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        int src0_index = mad24(y, src0_step, src0_offset); 
+        int src1_index = mad24(y, src1_step, src1_offset); 
+        int src2_index = mad24(y, src2_step, src2_offset); 
+        int src3_index = mad24(y, src3_step, src3_offset); 
+        int dst_index  = mad24(y, dst_step , dst_offset);
+
+        uchar src0 = *(mat_src0 + src0_index + x );
+        uchar src1 = *(mat_src1 + src1_index + x);
+        uchar src2 = *(mat_src2 + src2_index + x);
+        uchar src3 = *(mat_src3 + src3_index + x);
+
+        *((__global uchar4 *)(mat_dst  + dst_index + (x << 2))) = (uchar4)(src0, src1, src2, src3);
+    }
+}
+__kernel void merge_vector_C4_D1(__global char *mat_dst,  int dst_step,  int dst_offset,
+                                 __global char *mat_src0, int src0_step, int src0_offset,
+                                 __global char *mat_src1, int src1_step, int src1_offset,
+                                 __global char *mat_src2, int src2_step, int src2_offset,
+                                 __global char *mat_src3, int src3_step, int src3_offset,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        int src0_index = mad24(y, src0_step, src0_offset); 
+        int src1_index = mad24(y, src1_step, src1_offset); 
+        int src2_index = mad24(y, src2_step, src2_offset); 
+        int src3_index = mad24(y, src3_step, src3_offset); 
+        int dst_index  = mad24(y, dst_step , dst_offset);
+
+        char src0 = *(mat_src0 + src0_index + x );
+        char src1 = *(mat_src1 + src1_index + x);
+        char src2 = *(mat_src2 + src2_index + x);
+        char src3 = *(mat_src3 + src3_index + x);
+
+        *((__global char4 *)(mat_dst  + dst_index + (x << 2))) = (char4)(src0, src1, src2, src3);
+    }
+}
+__kernel void merge_vector_C4_D2(__global ushort *mat_dst,  int dst_step,  int dst_offset,
+                                 __global ushort *mat_src0, int src0_step, int src0_offset,
+                                 __global ushort *mat_src1, int src1_step, int src1_offset,
+                                 __global ushort *mat_src2, int src2_step, int src2_offset,
+                                 __global ushort *mat_src3, int src3_step, int src3_offset,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        int src0_index = mad24(y, src0_step, src0_offset); 
+        int src1_index = mad24(y, src1_step, src1_offset); 
+        int src2_index = mad24(y, src2_step, src2_offset); 
+        int src3_index = mad24(y, src3_step, src3_offset); 
+        int dst_index  = mad24(y, dst_step , dst_offset);
+
+        ushort src0 = *((__global ushort *)((__global uchar *)mat_src0 + src0_index + (x << 1)));
+        ushort src1 = *((__global ushort *)((__global uchar *)mat_src1 + src1_index + (x << 1)));
+        ushort src2 = *((__global ushort *)((__global uchar *)mat_src2 + src2_index + (x << 1)));
+        ushort src3 = *((__global ushort *)((__global uchar *)mat_src3 + src3_index + (x << 1)));
+
+        *((__global ushort4 *)((__global uchar *)mat_dst  + dst_index + (x << 3))) = (ushort4)(src0, src1, src2, src3);
+    }
+}
+__kernel void merge_vector_C4_D3(__global short *mat_dst,  int dst_step,  int dst_offset,
+                                 __global short *mat_src0, int src0_step, int src0_offset,
+                                 __global short *mat_src1, int src1_step, int src1_offset,
+                                 __global short *mat_src2, int src2_step, int src2_offset,
+                                 __global short *mat_src3, int src3_step, int src3_offset,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        int src0_index = mad24(y, src0_step, src0_offset); 
+        int src1_index = mad24(y, src1_step, src1_offset); 
+        int src2_index = mad24(y, src2_step, src2_offset); 
+        int src3_index = mad24(y, src3_step, src3_offset); 
+        int dst_index  = mad24(y, dst_step , dst_offset);
+
+        short src0 = *((__global short *)((__global uchar *)mat_src0 + src0_index + (x << 1)));
+        short src1 = *((__global short *)((__global uchar *)mat_src1 + src1_index + (x << 1)));
+        short src2 = *((__global short *)((__global uchar *)mat_src2 + src2_index + (x << 1)));
+        short src3 = *((__global short *)((__global uchar *)mat_src3 + src3_index + (x << 1)));
+
+        *((__global short4 *)((__global uchar *)mat_dst  + dst_index + (x << 3))) = (short4)(src0, src1, src2, src3);
+    }
+}
+__kernel void merge_vector_C4_D4(__global int *mat_dst,  int dst_step,  int dst_offset,
+                                 __global int *mat_src0, int src0_step, int src0_offset,
+                                 __global int *mat_src1, int src1_step, int src1_offset,
+                                 __global int *mat_src2, int src2_step, int src2_offset,
+                                 __global int *mat_src3, int src3_step, int src3_offset,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        int src0_index = mad24(y, src0_step, src0_offset); 
+        int src1_index = mad24(y, src1_step, src1_offset); 
+        int src2_index = mad24(y, src2_step, src2_offset); 
+        int src3_index = mad24(y, src3_step, src3_offset); 
+        int dst_index  = mad24(y, dst_step , dst_offset);
+
+        int src0 = *((__global int *)((__global uchar *)mat_src0 + src0_index + (x << 2)));
+        int src1 = *((__global int *)((__global uchar *)mat_src1 + src1_index + (x << 2)));
+        int src2 = *((__global int *)((__global uchar *)mat_src2 + src2_index + (x << 2)));
+        int src3 = *((__global int *)((__global uchar *)mat_src3 + src3_index + (x << 2)));
+
+        *((__global int4 *)((__global uchar *)mat_dst  + dst_index + (x << 4))) = (int4)(src0, src1, src2, src3);
+    }
+}
+__kernel void merge_vector_C4_D5(__global float *mat_dst,  int dst_step,  int dst_offset,
+                                 __global float *mat_src0, int src0_step, int src0_offset,
+                                 __global float *mat_src1, int src1_step, int src1_offset,
+                                 __global float *mat_src2, int src2_step, int src2_offset,
+                                 __global float *mat_src3, int src3_step, int src3_offset,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        int src0_index = mad24(y, src0_step, src0_offset); 
+        int src1_index = mad24(y, src1_step, src1_offset); 
+        int src2_index = mad24(y, src2_step, src2_offset); 
+        int src3_index = mad24(y, src3_step, src3_offset); 
+        int dst_index  = mad24(y, dst_step , dst_offset);
+
+        float src0 = *((__global float *)((__global uchar *)mat_src0 + src0_index + (x << 2)));
+        float src1 = *((__global float *)((__global uchar *)mat_src1 + src1_index + (x << 2)));
+        float src2 = *((__global float *)((__global uchar *)mat_src2 + src2_index + (x << 2)));
+        float src3 = *((__global float *)((__global uchar *)mat_src3 + src3_index + (x << 2)));
+
+        *((__global float4 *)((__global uchar *)mat_dst  + dst_index + (x << 4))) = (float4)(src0, src1, src2, src3);
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void merge_vector_C4_D6(__global double *mat_dst,  int dst_step,  int dst_offset,
+                                 __global double *mat_src0, int src0_step, int src0_offset,
+                                 __global double *mat_src1, int src1_step, int src1_offset,
+                                 __global double *mat_src2, int src2_step, int src2_offset,
+                                 __global double *mat_src3, int src3_step, int src3_offset,
+                                 int rows, int cols, int dst_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        int src0_index = mad24(y, src0_step, src0_offset); 
+        int src1_index = mad24(y, src1_step, src1_offset); 
+        int src2_index = mad24(y, src2_step, src2_offset); 
+        int src3_index = mad24(y, src3_step, src3_offset); 
+        int dst_index  = mad24(y, dst_step , dst_offset);
+
+        double src0 = *((__global double *)((__global uchar *)mat_src0 + src0_index + (x << 3)));
+        double src1 = *((__global double *)((__global uchar *)mat_src1 + src1_index + (x << 3)));
+        double src2 = *((__global double *)((__global uchar *)mat_src2 + src2_index + (x << 3)));
+        double src3 = *((__global double *)((__global uchar *)mat_src3 + src3_index + (x << 3)));
+
+        *((__global double4 *)((__global uchar *)mat_dst  + dst_index + (x << 5))) = (double4)(src0, src1, src2, src3);
+    }
+}
+#endif
+///////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////optimized code using vector  no roi//////////////////////////
+////////////vector fuction name format: merge_vector_C(channels number)D_(data type depth)//////
+////////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void merge_vector_C2_D0_1(int rows, int cols,
+                                   __global uchar *mat_dst,  int dst_step,
+                                   __global uchar *mat_src0, int src0_step,
+                                   __global uchar *mat_src1, int src1_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        __global uchar4  *src0_y = (__global uchar4 * )(mat_src0 + y * src0_step);
+        __global uchar4  *src1_y = (__global uchar4 * )(mat_src1 + y * src1_step);
+        __global uchar8 *dst_y  = (__global uchar8 *)(mat_dst  + y * dst_step);
+
+        uchar4 value1 = src0_y[x];
+        uchar4 value2 = src1_y[x];
+
+        uchar8 value;
+        value.even = value1;
+        value.odd = value2;
+
+        dst_y[x] = value;
+    }
+}
+__kernel void merge_vector_C2_D1_1(int rows, int cols,
+                                   __global char *mat_dst,  int dst_step,
+                                   __global char *mat_src0, int src0_step,
+                                   __global char *mat_src1, int src1_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        __global char4  *src0_y = (__global char4 * )(mat_src0 + y * src0_step);
+        __global char4  *src1_y = (__global char4 * )(mat_src1 + y * src1_step);
+        __global char8 *dst_y  = (__global char8 *)(mat_dst  + y * dst_step);
+
+        char4 value1 = src0_y[x];
+        char4 value2 = src1_y[x];
+
+        char8 value;
+        value.even = value1;
+        value.odd = value2;
+
+        dst_y[x] = value;
+    }
+}
+__kernel void merge_vector_C2_D2_1(int rows, int cols,
+                                   __global ushort *mat_dst,  int dst_step,
+                                   __global ushort *mat_src0, int src0_step,
+                                   __global ushort *mat_src1, int src1_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        __global ushort2  *src0_y = (__global ushort2 *)((__global uchar *)mat_src0 + y * src0_step);
+        __global ushort2  *src1_y = (__global ushort2 *)((__global uchar *)mat_src1 + y * src1_step);
+        __global ushort4  *dst_y  = (__global ushort4 *)((__global uchar *)mat_dst  + y * dst_step);
+
+        ushort2 value1 = src0_y[x];
+        ushort2 value2 = src1_y[x];
+
+        ushort4 value;
+        value.even = value1;
+        value.odd = value2;
+
+        dst_y[x] = value;
+    }
+}
+__kernel void merge_vector_C2_D3_1(int rows, int cols,
+                                   __global short *mat_dst,  int dst_step,
+                                   __global short *mat_src0, int src0_step,
+                                   __global short *mat_src1, int src1_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        __global short2  *src0_y = (__global short2 *)((__global uchar *)mat_src0 + y * src0_step);
+        __global short2  *src1_y = (__global short2 *)((__global uchar *)mat_src1 + y * src1_step);
+        __global short4 *dst_y   = (__global short4 *)((__global uchar *)mat_dst  + y * dst_step);
+
+        short2 value1 = src0_y[x];
+        short2 value2 = src1_y[x];
+
+        short4 value;
+        value.even = value1;
+        value.odd = value2;
+
+        dst_y[x] = value;
+    }
+}
+
+__kernel void merge_vector_C2_D4_1(int rows, int cols,
+                                   __global int *mat_dst,  int dst_step,
+                                   __global int *mat_src0, int src0_step,
+                                   __global int *mat_src1, int src1_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        __global int  *src0_y = (__global int *)((__global uchar *)mat_src0 + y * src0_step);
+        __global int  *src1_y = (__global int *)((__global uchar *)mat_src1 + y * src1_step);
+        __global int2  *dst_y  = (__global int2 *)((__global uchar *)mat_dst  + y * dst_step);
+
+        int value1 = src0_y[x];
+        int value2 = src1_y[x];
+
+        int2 value;
+        value.even = value1;
+        value.odd = value2;
+
+        dst_y[x] = value;
+    }
+}
+__kernel void merge_vector_C2_D5_1(int rows, int cols,
+                                   __global float *mat_dst,  int dst_step,
+                                   __global float *mat_src0, int src0_step,
+                                   __global float *mat_src1, int src1_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        __global float  *src0_y = (__global float *)((__global uchar *)mat_src0 + y * src0_step);
+        __global float  *src1_y = (__global float *)((__global uchar *)mat_src1 + y * src1_step);
+        __global float2  *dst_y  = (__global float2 *)((__global uchar *)mat_dst  + y * dst_step);
+
+        float value1 = src0_y[x];
+        float value2 = src1_y[x];
+
+        dst_y[x] = (float2)(value1, value2); 
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void merge_vector_C2_D6_1(int rows, int cols,
+                                   __global double *mat_dst,  int dst_step,
+                                   __global double *mat_src0, int src0_step,
+                                   __global double *mat_src1, int src1_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        __global double  *src0_y = (__global double *)((__global uchar *)mat_src0 + y * src0_step);
+        __global double  *src1_y = (__global double *)((__global uchar *)mat_src1 + y * src1_step);
+        __global double2 *dst_y  = (__global double2 *)((__global uchar *)mat_dst  + y * dst_step);
+
+        double value1 = src0_y[x];
+        double value2 = src1_y[x];
+
+        dst_y[x] = (double2)(value1, value2);
+    }
+}
+#endif
+
+__kernel void merge_vector_C3_D0_1(int rows, int cols,
+                                   __global uchar *mat_dst,  int dst_step,
+                                   __global uchar *mat_src0, int src0_step,
+                                   __global uchar *mat_src1, int src1_step,
+                                   __global uchar *mat_src2, int src2_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        __global uchar4  *src0_y = (__global uchar4 * )(mat_src0 + y * src0_step);
+        __global uchar4  *src1_y = (__global uchar4 * )(mat_src1 + y * src1_step);
+        __global uchar4  *src2_y = (__global uchar4 * )(mat_src2 + y * src0_step);
+
+        __global uchar4 *dst_y  = (__global uchar4 *)(mat_dst  + y * dst_step);
+
+        uchar4 value0 = src0_y[x];
+        uchar4 value1 = src1_y[x];
+        uchar4 value2 = src2_y[x];
+
+        dst_y[3 * x + 0] = (uchar4)(value0.s0, value1.s0, value2.s0,
+                                    value0.s1);
+
+        dst_y[3 * x + 1] = (uchar4)(value1.s1, value2.s1,
+                                    value0.s2, value1.s2);
+
+        dst_y[3 * x + 2] = (uchar4)(value2.s2,
+                                    value0.s3, value1.s3, value2.s3);
+
+    }
+}
+__kernel void merge_vector_C3_D1_1(int rows, int cols,
+                                   __global char *mat_dst,  int dst_step,
+                                   __global char *mat_src0, int src0_step,
+                                   __global char *mat_src1, int src1_step,
+                                   __global char *mat_src2, int src2_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        __global char4  *src0_y = (__global char4 * )(mat_src0 + y * src0_step);
+        __global char4  *src1_y = (__global char4 * )(mat_src1 + y * src1_step);
+        __global char4  *src2_y = (__global char4 * )(mat_src2 + y * src0_step);
+
+        __global char4 *dst_y  = (__global char4 *)(mat_dst  + y * dst_step);
+
+        char4 value0 = src0_y[x];
+        char4 value1 = src1_y[x];
+        char4 value2 = src2_y[x];
+
+        dst_y[3 * x + 0] = (char4)(value0.s0, value1.s0, value2.s0,
+                                   value0.s1);
+
+        dst_y[3 * x + 1] = (char4)(value1.s1, value2.s1,
+                                     value0.s2, value1.s2);
+
+        dst_y[3 * x + 2] = (char4)(value2.s2,
+                                     value0.s3, value1.s3, value2.s3);
+
+        /* for test do not delete
+        dst_y[3 * x + 0] = (char8)(value0.s0, value1.s0, value2.s0,
+                                    value0.s1, value1.s1, value2.s1,
+                                    value0.s2, value1.s2);
+
+        dst_y[3 * x + 1] = (char8)(value2.s2,
+                                    value0.s3, value1.s3, value2.s3,
+                                    value0.s4, value1.s4, value2.s4,
+                                    value0.s5);
+
+        dst_y[3 * x + 2] = (char8)(value1.s5, value2.s5,
+                                    value0.s6, value1.s6, value2.s6,
+                                    value0.s7, value1.s7, value2.s7);
+                                    */
+    }
+}
+__kernel void merge_vector_C3_D2_1(int rows, int cols,
+                                   __global ushort *mat_dst,  int dst_step,
+                                   __global ushort *mat_src0, int src0_step,
+                                   __global ushort *mat_src1, int src1_step,
+                                   __global ushort *mat_src2, int src2_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        __global ushort2  *src0_y = (__global ushort2 * )((__global char *)mat_src0 + y * src0_step);
+        __global ushort2  *src1_y = (__global ushort2 * )((__global char *)mat_src1 + y * src1_step);
+        __global ushort2  *src2_y = (__global ushort2 * )((__global char *)mat_src2 + y * src0_step);
+
+        __global ushort2 *dst_y  = (__global ushort2 *)((__global char *)mat_dst  + y * dst_step);
+
+        ushort2 value0 = src0_y[x];
+        ushort2 value1 = src1_y[x];
+        ushort2 value2 = src2_y[x];
+
+        dst_y[3 * x + 0] = (ushort2)(value0.x, value1.x);
+        dst_y[3 * x + 1] = (ushort2)(value2.x, value0.y);
+        dst_y[3 * x + 2] = (ushort2)(value1.y, value2.y);
+
+    }
+}
+__kernel void merge_vector_C3_D3_1(int rows, int cols,
+                                   __global short *mat_dst,  int dst_step,
+                                   __global short *mat_src0, int src0_step,
+                                   __global short *mat_src1, int src1_step,
+                                   __global short *mat_src2, int src2_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        __global short2  *src0_y = (__global short2 * )((__global char *)mat_src0 + y * src0_step);
+        __global short2  *src1_y = (__global short2 * )((__global char *)mat_src1 + y * src1_step);
+        __global short2  *src2_y = (__global short2 * )((__global char *)mat_src2 + y * src0_step);
+
+        __global short2 *dst_y  = (__global short2 *)((__global char *)mat_dst  + y * dst_step);
+
+        short2 value0 = src0_y[x];
+        short2 value1 = src1_y[x];
+        short2 value2 = src2_y[x];
+
+        dst_y[3 * x + 0] = (short2)(value0.x, value1.x);
+        dst_y[3 * x + 1] = (short2)(value2.x, value0.y);
+        dst_y[3 * x + 2] = (short2)(value1.y, value2.y);
+
+        /*
+        dst_y[3 * x + 0] = (short4)(value0.s0, value1.s0, value2.s0,
+                                    value0.s1);
+
+        dst_y[3 * x + 1] = (short4)(value1.s1, value2.s1,
+                                    value0.s2, value1.s2);
+
+        dst_y[3 * x + 2] = (short4)(value2.s2,
+                                    value0.s3, value1.s3, value2.s3);
+                                    */
+    }
+}
+__kernel void merge_vector_C3_D4_1(int rows, int cols,
+                                   __global int *mat_dst,  int dst_step,
+                                   __global int *mat_src0, int src0_step,
+                                   __global int *mat_src1, int src1_step,
+                                   __global int *mat_src2, int src2_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        __global int  *src0_y = (__global int * )((__global char *)mat_src0 + y * src0_step);
+        __global int  *src1_y = (__global int * )((__global char *)mat_src1 + y * src1_step);
+        __global int  *src2_y = (__global int * )((__global char *)mat_src2 + y * src0_step);
+
+        __global int *dst_y  = (__global int *)((__global char *)mat_dst  + y * dst_step);
+
+        int value0 = src0_y[x];
+        int value1 = src1_y[x];
+        int value2 = src2_y[x];
+
+        dst_y[3 * x + 0] = value0;
+        dst_y[3 * x + 1] = value1;
+        dst_y[3 * x + 2] = value2;
+
+        /*for test do not delete
+        dst_y[3 * x + 0] = (int2)(value0.x, value1.x);
+        dst_y[3 * x + 1] = (int2)(value2.x, value0.y);
+        dst_y[3 * x + 2] = (int2)(value1.y, value2.y);
+        */
+    }
+}
+__kernel void merge_vector_C3_D5_1(int rows, int cols,
+                                   __global float *mat_dst,  int dst_step,
+                                   __global float *mat_src0, int src0_step,
+                                   __global float *mat_src1, int src1_step,
+                                   __global float *mat_src2, int src2_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        __global float  *src0_y = (__global float * )((__global char *)mat_src0 + y * src0_step);
+        __global float  *src1_y = (__global float * )((__global char *)mat_src1 + y * src1_step);
+        __global float  *src2_y = (__global float * )((__global char *)mat_src2 + y * src0_step);
+
+        __global float *dst_y  = (__global float *)((__global char *)mat_dst  + y * dst_step);
+
+        float value0 = src0_y[x];
+        float value1 = src1_y[x];
+        float value2 = src2_y[x];
+
+        dst_y[3 * x + 0] = value0;
+        dst_y[3 * x + 1] = value1;
+        dst_y[3 * x + 2] = value2;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void merge_vector_C3_D6_1(int rows, int cols,
+                                   __global double *mat_dst,  int dst_step,
+                                   __global double *mat_src0, int src0_step,
+                                   __global double *mat_src1, int src1_step,
+                                   __global double *mat_src2, int src2_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        __global double  *src0_y = (__global double * )((__global char *)mat_src0 + y * src0_step);
+        __global double  *src1_y = (__global double * )((__global char *)mat_src1 + y * src1_step);
+        __global double  *src2_y = (__global double * )((__global char *)mat_src2 + y * src0_step);
+
+        __global double *dst_y  = (__global double *)((__global char *)mat_dst  + y * dst_step);
+
+        double value0 = src0_y[x];
+        double value1 = src1_y[x];
+        double value2 = src2_y[x];
+
+        dst_y[3 * x + 0] = value0;
+        dst_y[3 * x + 1] = value1;
+        dst_y[3 * x + 2] = value2;
+    }
+}
+#endif
+__kernel void merge_vector_C4_D0_1(int rows, int cols,
+                                   __global uchar *mat_dst,  int dst_step,
+                                   __global uchar *mat_src0, int src0_step,
+                                   __global uchar *mat_src1, int src1_step,
+                                   __global uchar *mat_src2, int src2_step,
+                                   __global uchar *mat_src3, int src3_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        __global uchar4  *src0_y = (__global uchar4 * )(mat_src0 + y * src0_step);
+        __global uchar4  *src1_y = (__global uchar4 * )(mat_src1 + y * src1_step);
+        __global uchar4  *src2_y = (__global uchar4 * )(mat_src2 + y * src0_step);
+        __global uchar4  *src3_y = (__global uchar4 * )(mat_src3 + y * src1_step);
+
+        __global uchar16 *dst_y  = (__global uchar16 *)(mat_dst  + y * dst_step);
+
+        uchar4 value0 = src0_y[x];
+        uchar4 value1 = src1_y[x];
+        uchar4 value2 = src2_y[x];
+        uchar4 value3 = src3_y[x];
+
+        dst_y[x] = (uchar16)(value0.x, value1.x, value2.x, value3.x,
+                             value0.y, value1.y, value2.y, value3.y,   
+                             value0.z, value1.z, value2.z, value3.z,
+                             value0.w, value1.w, value2.w, value3.w);
+    }
+}
+
+__kernel void merge_vector_C4_D1_1(int rows, int cols,
+                                   __global char *mat_dst,  int dst_step,
+                                   __global char *mat_src0, int src0_step,
+                                   __global char *mat_src1, int src1_step,
+                                   __global char *mat_src2, int src2_step,
+                                   __global char *mat_src3, int src3_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        __global char4  *src0_y = (__global char4 * )(mat_src0 + y * src0_step);
+        __global char4  *src1_y = (__global char4 * )(mat_src1 + y * src1_step);
+        __global char4  *src2_y = (__global char4 * )(mat_src2 + y * src0_step);
+        __global char4  *src3_y = (__global char4 * )(mat_src3 + y * src1_step);
+
+        __global char16 *dst_y  = (__global char16 *)(mat_dst  + y * dst_step);
+
+        char4 value0 = src0_y[x];
+        char4 value1 = src1_y[x];
+        char4 value2 = src2_y[x];
+        char4 value3 = src3_y[x];
+
+        dst_y[x] = (char16)(value0.x, value1.x, value2.x, value3.x,
+                            value0.y, value1.y, value2.y, value3.y,   
+                            value0.z, value1.z, value2.z, value3.z,
+                            value0.w, value1.w, value2.w, value3.w);
+    }
+}
+__kernel void merge_vector_C4_D2_1(int rows, int cols,
+                                   __global ushort *mat_dst,  int dst_step,
+                                   __global ushort *mat_src0, int src0_step,
+                                   __global ushort *mat_src1, int src1_step,
+                                   __global ushort *mat_src2, int src2_step,
+                                   __global ushort *mat_src3, int src3_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        __global ushort2  *src0_y = (__global ushort2 * )((__global uchar*)mat_src0 + y * src0_step);
+        __global ushort2  *src1_y = (__global ushort2 * )((__global uchar*)mat_src1 + y * src1_step);
+        __global ushort2  *src2_y = (__global ushort2 * )((__global uchar*)mat_src2 + y * src0_step);
+        __global ushort2  *src3_y = (__global ushort2 * )((__global uchar*)mat_src3 + y * src1_step);
+
+        __global ushort8 *dst_y  = (__global ushort8 *)((__global uchar*)mat_dst  + y * dst_step);
+
+        ushort2 value0 = src0_y[x];
+        ushort2 value1 = src1_y[x];
+        ushort2 value2 = src2_y[x];
+        ushort2 value3 = src3_y[x];
+
+        dst_y[x] = (ushort8)(value0.x, value1.x, value2.x, value3.x,
+                             value0.y, value1.y, value2.y, value3.y);   
+    }
+}
+__kernel void merge_vector_C4_D3_1(int rows, int cols,
+                                   __global short *mat_dst,  int dst_step,
+                                   __global short *mat_src0, int src0_step,
+                                   __global short *mat_src1, int src1_step,
+                                   __global short *mat_src2, int src2_step,
+                                   __global short *mat_src3, int src3_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        __global short2  *src0_y = (__global short2 * )((__global uchar*)mat_src0 + y * src0_step);
+        __global short2  *src1_y = (__global short2 * )((__global uchar*)mat_src1 + y * src1_step);
+        __global short2  *src2_y = (__global short2 * )((__global uchar*)mat_src2 + y * src0_step);
+        __global short2  *src3_y = (__global short2 * )((__global uchar*)mat_src3 + y * src1_step);
+
+        __global short8 *dst_y  = (__global short8 *)((__global uchar*)mat_dst  + y * dst_step);
+
+        short2 value0 = src0_y[x];
+        short2 value1 = src1_y[x];
+        short2 value2 = src2_y[x];
+        short2 value3 = src3_y[x];
+
+        dst_y[x] = (short8)(value0.x, value1.x, value2.x, value3.x,
+                            value0.y, value1.y, value2.y, value3.y);   
+    }
+}
+__kernel void merge_vector_C4_D4_1(int rows, int cols,
+                                   __global int *mat_dst,  int dst_step,
+                                   __global int *mat_src0, int src0_step,
+                                   __global int *mat_src1, int src1_step,
+                                   __global int *mat_src2, int src2_step,
+                                   __global int *mat_src3, int src3_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        __global int *src0_y = (__global int * )((__global uchar*)mat_src0 + y * src0_step);
+        __global int *src1_y = (__global int * )((__global uchar*)mat_src1 + y * src1_step);
+        __global int *src2_y = (__global int * )((__global uchar*)mat_src2 + y * src0_step);
+        __global int *src3_y = (__global int * )((__global uchar*)mat_src3 + y * src1_step);
+
+        __global int4 *dst_y  = (__global int4 *)((__global uchar*)mat_dst  + y * dst_step);
+
+        int value0 = src0_y[x];
+        int value1 = src1_y[x];
+        int value2 = src2_y[x];
+        int value3 = src3_y[x];
+
+        dst_y[x] = (int4)(value0, value1, value2, value3);
+    }
+}
+__kernel void merge_vector_C4_D5_1(int rows, int cols,
+                                   __global float *mat_dst,  int dst_step,
+                                   __global float *mat_src0, int src0_step,
+                                   __global float *mat_src1, int src1_step,
+                                   __global float *mat_src2, int src2_step,
+                                   __global float *mat_src3, int src3_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        __global float *src0_y = (__global float * )((__global uchar*)mat_src0 + y * src0_step);
+        __global float *src1_y = (__global float * )((__global uchar*)mat_src1 + y * src1_step);
+        __global float *src2_y = (__global float * )((__global uchar*)mat_src2 + y * src0_step);
+        __global float *src3_y = (__global float * )((__global uchar*)mat_src3 + y * src1_step);
+
+        __global float4 *dst_y  = (__global float4 *)((__global uchar*)mat_dst  + y * dst_step);
+
+        float value0 = src0_y[x];
+        float value1 = src1_y[x];
+        float value2 = src2_y[x];
+        float value3 = src3_y[x];
+
+        dst_y[x] = (float4)(value0, value1, value2, value3);
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void merge_vector_C4_D6_1(int rows, int cols,
+                                   __global double *mat_dst,  int dst_step,
+                                   __global double *mat_src0, int src0_step,
+                                   __global double *mat_src1, int src1_step,
+                                   __global double *mat_src2, int src2_step,
+                                   __global double *mat_src3, int src3_step)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1); 
+  
+    if ((x < cols) && (y < rows))
+    {
+        __global double *src0_y = (__global double * )((__global uchar*)mat_src0 + y * src0_step);
+        __global double *src1_y = (__global double * )((__global uchar*)mat_src1 + y * src1_step);
+        __global double *src2_y = (__global double * )((__global uchar*)mat_src2 + y * src0_step);
+        __global double *src3_y = (__global double * )((__global uchar*)mat_src3 + y * src1_step);
+
+        __global double4 *dst_y  = (__global double4 *)((__global uchar*)mat_dst  + y * dst_step);
+
+        double value0 = src0_y[x];
+        double value1 = src1_y[x];
+        double value2 = src2_y[x];
+        double value3 = src3_y[x];
+
+        dst_y[x] = (double4)(value0, value1, value2, value3);
+    }
+}
+#endif
diff --git a/modules/ocl/src/kernels/operator_convertTo.cl b/modules/ocl/src/kernels/operator_convertTo.cl
new file mode 100644 (file)
index 0000000..52f576e
--- /dev/null
@@ -0,0 +1,335 @@
+//                           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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Niko Li, newlife20080214@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 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.
+//
+//
+#define F float
+
+__kernel void convert_to_S4_C1_D0(
+               __global const int* restrict srcMat,
+               __global uchar* dstMat,
+               int cols,
+               int rows,
+               int srcStep_in_pixel,
+               int srcoffset_in_pixel,                 
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel, 
+               F alpha,
+               F beta)
+{
+               int x=get_global_id(0)<<2;
+               int y=get_global_id(1);
+               //int src_addr_start = mad24(y,srcStep_in_pixel,srcoffset_in_pixel);
+               //int src_addr_end = mad24(y,srcStep_in_pixel,cols+srcoffset_in_pixel);
+               int off_src = (dstoffset_in_pixel & 3); 
+               int srcidx = mad24(y,srcStep_in_pixel,x+ srcoffset_in_pixel - off_src);         
+               int dst_addr_start = mad24(y,dstStep_in_pixel,dstoffset_in_pixel);
+               int dst_addr_end = mad24(y,dstStep_in_pixel,cols+dstoffset_in_pixel);
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel & (int)0xfffffffc);
+
+               if ( (x < cols + off_src) & (y < rows) )
+               {
+                       float4 temp_src = convert_float4(vload4(0,srcMat+srcidx));                              
+                       uchar4 temp_dst = *(__global uchar4*)(dstMat+dstidx);           
+                       //int trans_src[10] = {temp_src1.y,temp_src1.z,temp_src1.w,temp_src.x,temp_src.y,temp_src.z,temp_src.w,temp_src2.x,temp_src2.y,temp_src2.z};            
+                       temp_dst.x = (dstidx>=dst_addr_start)&(dstidx<dst_addr_end) ? convert_uchar_sat(temp_src.x*alpha+beta) : temp_dst.x;
+                       temp_dst.y = (dstidx+1>=dst_addr_start)&(dstidx+1<dst_addr_end) ? convert_uchar_sat(temp_src.y*alpha+beta) : temp_dst.y;
+                       temp_dst.z = (dstidx+2>=dst_addr_start)&(dstidx+2<dst_addr_end) ? convert_uchar_sat(temp_src.z*alpha+beta) : temp_dst.z;
+                       temp_dst.w = (dstidx+3>=dst_addr_start)&(dstidx+3<dst_addr_end) ? convert_uchar_sat(temp_src.w*alpha+beta) : temp_dst.w;
+                       *(__global uchar4*)(dstMat+dstidx) = temp_dst;
+               }
+}
+
+__kernel void convert_to_S4_C4_D0(
+               __global const int4* restrict srcMat,
+               __global uchar4* dstMat,
+               int cols,
+               int rows,
+               int srcStep_in_pixel,
+               int srcoffset_in_pixel,                 
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel, 
+               F alpha,
+               F beta)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               int srcidx = mad24(y,srcStep_in_pixel,x+ srcoffset_in_pixel);           
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel);
+               if ( (x < cols) & (y < rows) )
+               {       
+                       float4 temp_src = convert_float4(srcMat[srcidx]);
+                       dstMat[dstidx] = convert_uchar4_sat(temp_src*alpha+beta);
+               }
+}
+
+__kernel void convert_to_S5_C1_D0(
+               __global const float* restrict srcMat,
+               __global uchar* dstMat,
+               int cols,
+               int rows,
+               int srcStep_in_pixel,
+               int srcoffset_in_pixel,                 
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel, 
+               F alpha,
+               F beta)
+{
+               int x=get_global_id(0)<<2;
+               int y=get_global_id(1);
+               //int src_addr_start = mad24(y,srcStep_in_pixel,srcoffset_in_pixel);
+               //int src_addr_end = mad24(y,srcStep_in_pixel,cols+srcoffset_in_pixel);
+               int off_src = (dstoffset_in_pixel & 3); 
+               int srcidx = mad24(y,srcStep_in_pixel,x+ srcoffset_in_pixel - off_src);         
+               int dst_addr_start = mad24(y,dstStep_in_pixel,dstoffset_in_pixel);
+               int dst_addr_end = mad24(y,dstStep_in_pixel,cols+dstoffset_in_pixel);
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel & (int)0xfffffffc);
+
+               if ( (x < cols + off_src) & (y < rows) )
+               {
+                       float4 temp_src = vload4(0,srcMat+srcidx);                              
+                       uchar4 temp_dst = *(__global uchar4*)(dstMat+dstidx);           
+                       //int trans_src[10] = {temp_src1.y,temp_src1.z,temp_src1.w,temp_src.x,temp_src.y,temp_src.z,temp_src.w,temp_src2.x,temp_src2.y,temp_src2.z};            
+                       temp_dst.x = (dstidx>=dst_addr_start)&(dstidx<dst_addr_end) ? convert_uchar_sat(temp_src.x*alpha+beta) : temp_dst.x;
+                       temp_dst.y = (dstidx+1>=dst_addr_start)&(dstidx+1<dst_addr_end) ? convert_uchar_sat(temp_src.y*alpha+beta) : temp_dst.y;
+                       temp_dst.z = (dstidx+2>=dst_addr_start)&(dstidx+2<dst_addr_end) ? convert_uchar_sat(temp_src.z*alpha+beta) : temp_dst.z;
+                       temp_dst.w = (dstidx+3>=dst_addr_start)&(dstidx+3<dst_addr_end) ? convert_uchar_sat(temp_src.w*alpha+beta) : temp_dst.w;
+                       *(__global uchar4*)(dstMat+dstidx) = temp_dst;
+               }
+}
+__kernel void convert_to_S5_C4_D0(
+               __global const float4* restrict srcMat,
+               __global uchar4* dstMat,
+               int cols,
+               int rows,
+               int srcStep_in_pixel,
+               int srcoffset_in_pixel,                 
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel, 
+               F alpha,
+               F beta)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               int srcidx = mad24(y,srcStep_in_pixel,x+ srcoffset_in_pixel);           
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel);
+               if ( (x < cols) & (y < rows) )
+               {       
+                       float4 temp_src = srcMat[srcidx];
+                       dstMat[dstidx] = convert_uchar4_sat(temp_src*alpha+beta);
+               }
+}
+
+__kernel void convert_to_S0_C1_D4(
+               __global const uchar* restrict srcMat,
+               __global int* dstMat,
+               int cols,
+               int rows,
+               int srcStep_in_pixel,
+               int srcoffset_in_pixel,                 
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel, 
+               F alpha,
+               F beta)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               int srcidx = mad24(y,srcStep_in_pixel,x+ srcoffset_in_pixel);           
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel);
+               if ( (x < cols) & (y < rows) )
+               {       
+                       float temp_src = convert_float(srcMat[srcidx]);
+                       dstMat[dstidx] = convert_int_sat(temp_src*alpha+beta);
+               }
+}
+
+__kernel void convert_to_S5_C1_D4(
+               __global const float* restrict srcMat,
+               __global int* dstMat,
+               int cols,
+               int rows,
+               int srcStep_in_pixel,
+               int srcoffset_in_pixel,                 
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel, 
+               F alpha,
+               F beta)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               int srcidx = mad24(y,srcStep_in_pixel,x+ srcoffset_in_pixel);           
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel);
+               if ( (x < cols) & (y < rows) )
+               {       
+                       float temp_src = srcMat[srcidx];
+                       dstMat[dstidx] = convert_int_sat(temp_src*alpha+beta);
+               }
+}
+
+__kernel void convert_to_S0_C4_D4(
+               __global const uchar4* restrict srcMat,
+               __global int4* dstMat,
+               int cols,
+               int rows,
+               int srcStep_in_pixel,
+               int srcoffset_in_pixel,                 
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel, 
+               F alpha,
+               F beta)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               int srcidx = mad24(y,srcStep_in_pixel,x+ srcoffset_in_pixel);           
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel);
+               if ( (x < cols) & (y < rows) )
+               {       
+                       float4 temp_src = convert_float4(srcMat[srcidx]);
+                       dstMat[dstidx] = convert_int4_sat(temp_src*alpha+beta);
+               }
+}
+
+__kernel void convert_to_S5_C4_D4(
+               __global const float4* restrict srcMat,
+               __global int4* dstMat,
+               int cols,
+               int rows,
+               int srcStep_in_pixel,
+               int srcoffset_in_pixel,                 
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel, 
+               F alpha,
+               F beta)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               int srcidx = mad24(y,srcStep_in_pixel,x+ srcoffset_in_pixel);           
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel);
+               if ( (x < cols) & (y < rows) )
+               {       
+                       float4 temp_src = srcMat[srcidx];
+                       dstMat[dstidx] = convert_int4_sat(temp_src*alpha+beta);
+               }
+}
+
+__kernel void convert_to_S0_C1_D5(
+               __global const uchar* restrict srcMat,
+               __global float* dstMat,
+               int cols,
+               int rows,
+               int srcStep_in_pixel,
+               int srcoffset_in_pixel,                 
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel, 
+               F alpha,
+               F beta)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               int srcidx = mad24(y,srcStep_in_pixel,x+ srcoffset_in_pixel);           
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel);
+               if ( (x < cols) & (y < rows) )
+               {       
+                       float temp_src = convert_float(srcMat[srcidx]);
+                       dstMat[dstidx] = temp_src*alpha+beta;
+               }
+}
+
+__kernel void convert_to_S4_C1_D5(
+               __global const int* restrict srcMat,
+               __global float* dstMat,
+               int cols,
+               int rows,
+               int srcStep_in_pixel,
+               int srcoffset_in_pixel,                 
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel, 
+               F alpha,
+               F beta)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               int srcidx = mad24(y,srcStep_in_pixel,x+ srcoffset_in_pixel);           
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel);
+               if ( (x < cols) & (y < rows) )
+               {       
+                       float temp_src = convert_float(srcMat[srcidx]);
+                       dstMat[dstidx] = temp_src*alpha+beta;
+               }
+}
+
+__kernel void convert_to_S0_C4_D5(
+               __global const uchar4* restrict srcMat,
+               __global float4* dstMat,
+               int cols,
+               int rows,
+               int srcStep_in_pixel,
+               int srcoffset_in_pixel,                 
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel, 
+               F alpha,
+               F beta)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               int srcidx = mad24(y,srcStep_in_pixel,x+ srcoffset_in_pixel);           
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel);
+               if ( (x < cols) & (y < rows) )
+               {       
+                       float4 temp_src = convert_float4(srcMat[srcidx]);
+                       dstMat[dstidx] = temp_src*alpha+beta;
+               }
+}
+
+__kernel void convert_to_S4_C4_D5(
+               __global const int4* restrict srcMat,
+               __global float4* dstMat,
+               int cols,
+               int rows,
+               int srcStep_in_pixel,
+               int srcoffset_in_pixel,                 
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel, 
+               F alpha,
+               F beta)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               int srcidx = mad24(y,srcStep_in_pixel,x+ srcoffset_in_pixel);           
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel);
+               if ( (x < cols) & (y < rows) )
+               {       
+                       float4 temp_src = convert_float4(srcMat[srcidx]);
+                       dstMat[dstidx] = temp_src*alpha+beta;
+               }
+}
diff --git a/modules/ocl/src/kernels/operator_copyToM.cl b/modules/ocl/src/kernels/operator_copyToM.cl
new file mode 100644 (file)
index 0000000..0ff4d11
--- /dev/null
@@ -0,0 +1,209 @@
+//                           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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Niko Li, newlife20080214@gmail.com
+//    Jia Haipeng, jiahaipeng95@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 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
+// 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.
+//
+//
+
+__kernel void copy_to_with_mask_C1_D0(
+               __global const uchar* restrict srcMat,
+               __global uchar* dstMat,
+               __global const uchar* restrict maskMat,
+               int cols,
+               int rows,
+               int srcStep_in_pixel,
+               int srcoffset_in_pixel,                 
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel, 
+               int maskStep,
+               int maskoffset)
+{
+               int x=get_global_id(0)<<2;
+               int y=get_global_id(1);
+
+    int dst_addr_start = mad24((uint)y, (uint)dstStep_in_pixel, (uint)dstoffset_in_pixel); 
+               int dst_addr_end = mad24((uint)y, (uint)dstStep_in_pixel, (uint)cols+dstoffset_in_pixel);
+               int dstidx = mad24((uint)y, (uint)dstStep_in_pixel, (uint)x+ dstoffset_in_pixel) & (int)0xfffffffc;
+
+    int vector_off = dstoffset_in_pixel & 3; 
+
+               int srcidx = mad24((uint)y, (uint)srcStep_in_pixel, (uint)x + srcoffset_in_pixel - vector_off);         
+
+    int mask_addr_start = mad24((uint)y, (uint)maskStep, (uint)maskoffset);
+               int mask_addr_end = mad24((uint)y, (uint)maskStep, (uint)cols+maskoffset);
+               int maskidx = mad24((uint)y, (uint)maskStep, (uint)x + maskoffset - vector_off);
+
+               if ( (x < cols + dstoffset_in_pixel) & (y < rows) )
+               {
+        uchar4 src_data  = vload4(0, srcMat + srcidx);
+        uchar4 mask_data = vload4(0, maskMat + maskidx);
+        uchar4 dst_data  = *((__global uchar4 *)(dstMat + dstidx));
+        uchar4 tmp_data;
+
+        mask_data.x = ((maskidx + 0 >= mask_addr_start) && (maskidx + 0 < mask_addr_end)) ? mask_data.x : 0;
+        mask_data.y = ((maskidx + 1 >= mask_addr_start) && (maskidx + 1 < mask_addr_end)) ? mask_data.y : 0;
+        mask_data.z = ((maskidx + 2 >= mask_addr_start) && (maskidx + 2 < mask_addr_end)) ? mask_data.z : 0;
+        mask_data.w = ((maskidx + 3 >= mask_addr_start) && (maskidx + 3 < mask_addr_end)) ? mask_data.w : 0;
+                       
+        tmp_data.x = ((dstidx + 0 >= dst_addr_start) && (dstidx + 0 < dst_addr_end) && (mask_data.x)) 
+                     ? src_data.x : dst_data.x;
+        tmp_data.y = ((dstidx + 1 >= dst_addr_start) && (dstidx + 1 < dst_addr_end) && (mask_data.y)) 
+                     ? src_data.y : dst_data.y;
+        tmp_data.z = ((dstidx + 2 >= dst_addr_start) && (dstidx + 2 < dst_addr_end) && (mask_data.z)) 
+                     ? src_data.z : dst_data.z;
+        tmp_data.w = ((dstidx + 3 >= dst_addr_start) && (dstidx + 3 < dst_addr_end) && (mask_data.w)) 
+                     ? src_data.w : dst_data.w;
+
+        (*(__global uchar4*)(dstMat+dstidx)) = tmp_data;
+               }
+}
+
+__kernel void copy_to_with_mask_C4_D0(
+               __global const uchar4* restrict srcMat,
+               __global uchar4* dstMat,
+               __global const uchar* restrict maskMat,
+               int cols,
+               int rows,
+               int srcStep_in_pixel,
+               int srcoffset_in_pixel,                 
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel, 
+               int maskStep,
+               int maskoffset)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               int srcidx = mad24(y,srcStep_in_pixel,x+ srcoffset_in_pixel);           
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel);
+               int maskidx = mad24(y,maskStep,x+ maskoffset);
+               uchar mask = maskMat[maskidx];          
+               if ( (x < cols) & (y < rows) & mask)
+               {
+                       dstMat[dstidx] = srcMat[srcidx];
+               }
+}
+__kernel void copy_to_with_mask_C1_D4(
+               __global const int* restrict srcMat,
+               __global int* dstMat,
+               __global const uchar* restrict maskMat,
+               int cols,
+               int rows,
+               int srcStep_in_pixel,
+               int srcoffset_in_pixel,                 
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel, 
+               int maskStep,
+               int maskoffset)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               int srcidx = mad24(y,srcStep_in_pixel,x+ srcoffset_in_pixel);           
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel);
+               int maskidx = mad24(y,maskStep,x+ maskoffset);
+               uchar mask = maskMat[maskidx];          
+               if ( (x < cols) & (y < rows) & mask)
+               {
+                       dstMat[dstidx] = srcMat[srcidx];
+               }
+}
+__kernel void copy_to_with_mask_C4_D4(
+               __global const int4* restrict srcMat,
+               __global int4* dstMat,
+               __global const uchar* restrict maskMat,
+               int cols,
+               int rows,
+               int srcStep_in_pixel,
+               int srcoffset_in_pixel,                 
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel, 
+               int maskStep,
+               int maskoffset)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               int srcidx = mad24(y,srcStep_in_pixel,x+ srcoffset_in_pixel);           
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel);
+               int maskidx = mad24(y,maskStep,x+ maskoffset);
+               uchar mask = maskMat[maskidx];          
+               if ( (x < cols) & (y < rows) & mask)
+               {
+                       dstMat[dstidx] = srcMat[srcidx];
+               }
+}
+__kernel void copy_to_with_mask_C1_D5(
+               __global const float* restrict srcMat,
+               __global float* dstMat,
+               __global const uchar* restrict maskMat,
+               int cols,
+               int rows,
+               int srcStep_in_pixel,
+               int srcoffset_in_pixel,                 
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel, 
+               int maskStep,
+               int maskoffset)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               int srcidx = mad24(y,srcStep_in_pixel,x+ srcoffset_in_pixel);           
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel);
+               int maskidx = mad24(y,maskStep,x+ maskoffset);
+               uchar mask = maskMat[maskidx];          
+               if ( (x < cols) & (y < rows) & mask)
+               {
+                       dstMat[dstidx] = srcMat[srcidx];
+               }
+}
+__kernel void copy_to_with_mask_C4_D5(
+               __global const float4* restrict srcMat,
+               __global float4* dstMat,
+               __global const uchar* restrict maskMat,
+               int cols,
+               int rows,
+               int srcStep_in_pixel,
+               int srcoffset_in_pixel,                 
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel, 
+               int maskStep,
+               int maskoffset)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               int srcidx = mad24(y,srcStep_in_pixel,x+ srcoffset_in_pixel);           
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel);
+               int maskidx = mad24(y,maskStep,x+ maskoffset);
+               uchar mask = maskMat[maskidx];          
+               if ( (x < cols) & (y < rows) & mask)
+               {
+                       dstMat[dstidx] = srcMat[srcidx];
+               }
+}
diff --git a/modules/ocl/src/kernels/operator_setTo.cl b/modules/ocl/src/kernels/operator_setTo.cl
new file mode 100644 (file)
index 0000000..8a7010b
--- /dev/null
@@ -0,0 +1,124 @@
+//                           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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Niko Li, newlife20080214@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 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
+// 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.
+//
+//
+
+/*
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+*/
+
+__kernel void set_to_without_mask_C1_D0(float4 scalar,__global uchar * dstMat,
+        int cols,int rows,int dstStep_in_pixel,int offset_in_pixel)
+{
+               int x=get_global_id(0)<<2;
+               int y=get_global_id(1);
+               int addr_start = mad24(y,dstStep_in_pixel,offset_in_pixel);
+               int addr_end = mad24(y,dstStep_in_pixel,cols+offset_in_pixel);
+               int idx = mad24(y,dstStep_in_pixel,(int)(x+ offset_in_pixel & (int)0xfffffffc));
+               uchar4 out;
+               out.x = out.y = out.z = out.w = convert_uchar_sat(scalar.x);
+               if ( (idx>=addr_start)&(idx+3 < addr_end) & (y < rows))
+               {
+                       *(__global uchar4*)(dstMat+idx) = out;
+               }
+               else if(y < rows)
+               {
+                       uchar4 temp = *(__global uchar4*)(dstMat+idx);
+                       temp.x = (idx>=addr_start)&(idx < addr_end)? out.x : temp.x;
+                       temp.y = (idx+1>=addr_start)&(idx+1 < addr_end)? out.y : temp.y;
+                       temp.z = (idx+2>=addr_start)&(idx+2 < addr_end)? out.z : temp.z;
+                       temp.w = (idx+3>=addr_start)&(idx+3 < addr_end)? out.w : temp.w;
+                       *(__global uchar4*)(dstMat+idx) = temp;
+               }
+}
+
+__kernel void set_to_without_mask_C4_D0(float4 scalar,__global uchar4 * dstMat,
+        int cols,int rows,int dstStep_in_pixel,int offset_in_pixel)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               if ( (x < cols) & (y < rows))
+               {
+                   int idx = mad24(y,dstStep_in_pixel,x+ offset_in_pixel);
+                       dstMat[idx] = convert_uchar4_sat(scalar);
+               }
+}
+__kernel void set_to_without_mask_C1_D4(float4 scalar,__global int * dstMat,
+        int cols,int rows,int dstStep_in_pixel,int offset_in_pixel)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               if ( (x < cols) & (y < rows))
+               {
+                   int idx = mad24(y, dstStep_in_pixel, x+offset_in_pixel);
+                       dstMat[idx] = convert_int_sat(scalar.x);
+               }
+}
+__kernel void set_to_without_mask_C4_D4(float4 scalar,__global int4 * dstMat,
+        int cols,int rows,int dstStep_in_pixel,int offset_in_pixel)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               if ( (x < cols) & (y < rows))
+               {
+                   int idx = mad24(y,dstStep_in_pixel,x+ offset_in_pixel);
+                       dstMat[idx] = convert_int4_sat(scalar);
+               }
+}
+
+__kernel void set_to_without_mask_C1_D5(float4 scalar,__global float * dstMat,
+        int cols,int rows,int dstStep_in_pixel,int offset_in_pixel)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               if ( (x < cols) & (y < rows))
+               {
+                   int idx = mad24(y,dstStep_in_pixel,x+ offset_in_pixel);
+                       dstMat[idx] = scalar.x;
+               }
+}
+__kernel void set_to_without_mask_C4_D5(float4 scalar,__global float4 * dstMat,
+        int cols,int rows,int dstStep_in_pixel,int offset_in_pixel)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               if ( (x < cols) & (y < rows))
+               {
+                   int idx = mad24(y,dstStep_in_pixel,x+ offset_in_pixel);
+                       dstMat[idx] = scalar;
+               }
+}
+
diff --git a/modules/ocl/src/kernels/operator_setToM.cl b/modules/ocl/src/kernels/operator_setToM.cl
new file mode 100644 (file)
index 0000000..e306657
--- /dev/null
@@ -0,0 +1,227 @@
+//                           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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Niko Li, newlife20080214@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 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
+// 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.
+//
+//
+
+
+/*#if defined (__ATI__)
+#pragma OPENCL EXTENSION cl_amd_fp64:enable
+#elif defined (__NVIDIA__)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+*/
+/*
+__kernel void set_to_with_mask_C1_D0(
+               float4 scalar,
+               __global uchar* dstMat,
+               int cols,
+               int rows,
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel,                 
+        __global const uchar * maskMat,
+               int maskStep,
+               int maskoffset)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel);
+               int maskidx = mad24(y,maskStep,x+ maskoffset);
+               uchar mask = maskMat[maskidx];          
+               if ( (x < cols) & (y < rows) & mask)
+               {
+                       dstMat[dstidx] = convert_uchar_sat(scalar.x);
+               }
+
+}
+*/
+//#pragma OPENCL EXTENSION cl_amd_printf : enable
+__kernel void set_to_with_mask_C1_D0(
+               float4 scalar,
+               __global uchar* dstMat,
+               int cols,
+               int rows,
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel,                 
+        __global const uchar * restrict maskMat,
+               int maskStep,
+               int maskoffset)
+{
+               int x=get_global_id(0)<<2;
+               int y=get_global_id(1);
+               int dst_addr_start = mad24(y,dstStep_in_pixel,dstoffset_in_pixel);
+               int dst_addr_end = mad24(y,dstStep_in_pixel,cols+dstoffset_in_pixel);
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel & (int)0xfffffffc);
+               int mask_addr_start = mad24(y,maskStep,maskoffset);
+               int mask_addr_end = mad24(y,maskStep,cols+maskoffset);
+               int maskidx = mad24(y,maskStep,x+ maskoffset & (int)0xfffffffc);
+               uchar out = convert_uchar_sat(scalar.x);        
+               int off_mask = (maskoffset & 3) - (dstoffset_in_pixel & 3) +3;  
+               
+               if ( (x < cols) & (y < rows) )
+               {
+                       uchar4 temp_dst = *(__global uchar4*)(dstMat+dstidx);
+                       uchar4 temp_mask1 = *(__global uchar4*)(maskMat+maskidx-4);
+                       uchar4 temp_mask = *(__global uchar4*)(maskMat+maskidx);
+                       uchar4 temp_mask2 = *(__global uchar4*)(maskMat+maskidx+4);             
+                       temp_mask1.x = (maskidx-4 >=mask_addr_start)&(maskidx-4 < mask_addr_end) ? temp_mask1.x : 0;
+                       temp_mask1.y = (maskidx-3 >=mask_addr_start)&(maskidx-3 < mask_addr_end) ? temp_mask1.y : 0;
+                       temp_mask1.z = (maskidx-2 >=mask_addr_start)&(maskidx-2 < mask_addr_end) ? temp_mask1.z : 0;
+                       temp_mask1.w = (maskidx-1 >=mask_addr_start)&(maskidx-1 < mask_addr_end) ? temp_mask1.w : 0;                    
+                       temp_mask.x = (maskidx >=mask_addr_start)&(maskidx < mask_addr_end) ? temp_mask.x : 0;
+                       temp_mask.y = (maskidx+1 >=mask_addr_start)&(maskidx+1 < mask_addr_end) ? temp_mask.y : 0;
+                       temp_mask.z = (maskidx+2 >=mask_addr_start)&(maskidx+2 < mask_addr_end) ? temp_mask.z : 0;
+                       temp_mask.w = (maskidx+3 >=mask_addr_start)&(maskidx+3 < mask_addr_end) ? temp_mask.w : 0;      
+                       temp_mask2.x = (maskidx+4 >=mask_addr_start)&(maskidx+4 < mask_addr_end) ? temp_mask2.x : 0;
+                       temp_mask2.y = (maskidx+5 >=mask_addr_start)&(maskidx+5 < mask_addr_end) ? temp_mask2.y : 0;
+                       temp_mask2.z = (maskidx+6 >=mask_addr_start)&(maskidx+6 < mask_addr_end) ? temp_mask2.z : 0;
+                       temp_mask2.w = (maskidx+7 >=mask_addr_start)&(maskidx+7 < mask_addr_end) ? temp_mask2.w : 0;    
+                       uchar trans_mask[10] = {temp_mask1.y,temp_mask1.z,temp_mask1.w,temp_mask.x,temp_mask.y,temp_mask.z,temp_mask.w,temp_mask2.x,temp_mask2.y,temp_mask2.z};                         
+                       temp_dst.x = (dstidx>=dst_addr_start)&(dstidx<dst_addr_end)& trans_mask[off_mask] ? out : temp_dst.x;
+                       temp_dst.y = (dstidx+1>=dst_addr_start)&(dstidx+1<dst_addr_end)& trans_mask[off_mask+1] ? out : temp_dst.y;
+                       temp_dst.z = (dstidx+2>=dst_addr_start)&(dstidx+2<dst_addr_end)& trans_mask[off_mask+2] ? out : temp_dst.z;
+                       temp_dst.w = (dstidx+3>=dst_addr_start)&(dstidx+3<dst_addr_end)& trans_mask[off_mask+3] ? out : temp_dst.w;
+                       *(__global uchar4*)(dstMat+dstidx) = temp_dst;
+               }
+}
+__kernel void set_to_with_mask_C4_D0(
+               float4 scalar,
+               __global uchar4 * dstMat,
+               int cols,
+               int rows,
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel,                 
+        __global const uchar * restrict maskMat,
+               int maskStep,
+               int maskoffset)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel);
+               int maskidx = mad24(y,maskStep,x+ maskoffset);
+               uchar mask = maskMat[maskidx];          
+               if ( (x < cols) & (y < rows) & mask)
+               {
+                       dstMat[dstidx] = convert_uchar4_sat(scalar);
+               }
+
+}
+__kernel void set_to_with_mask_C1_D4(
+               float4 scalar,
+               __global int * dstMat,
+               int cols,
+               int rows,
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel,                 
+        __global const uchar * restrict maskMat,
+               int maskStep,
+               int maskoffset)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel);
+               int maskidx = mad24(y,maskStep,x+ maskoffset);
+               uchar mask = maskMat[maskidx];          
+               if ( (x < cols) & (y < rows) & mask)
+               {
+                       dstMat[dstidx] = convert_int_sat(scalar.x);
+               }
+
+}
+__kernel void set_to_with_mask_C4_D4(
+               float4 scalar,
+               __global int4 * dstMat,
+               int cols,
+               int rows,
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel,                 
+        __global const uchar * restrict maskMat,
+               int maskStep,
+               int maskoffset)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel);
+               int maskidx = mad24(y,maskStep,x+ maskoffset);
+               uchar mask = maskMat[maskidx];          
+               if ( (x < cols) & (y < rows) & mask)
+               {
+                       dstMat[dstidx] = convert_int4_sat(scalar);
+               }
+
+}
+__kernel void set_to_with_mask_C1_D5(
+               float4 scalar,
+               __global float * dstMat,
+               int cols,
+               int rows,
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel,                 
+        __global const uchar * restrict maskMat,
+               int maskStep,
+               int maskoffset)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel);
+               int maskidx = mad24(y,maskStep,x+ maskoffset);
+               uchar mask = maskMat[maskidx];          
+               if ( (x < cols) & (y < rows) & mask)
+               {
+                       dstMat[dstidx] = scalar.x;
+               }
+
+}
+__kernel void set_to_with_mask_C4_D5(
+               float4 scalar,
+               __global float4 * dstMat,
+               int cols,
+               int rows,
+               int dstStep_in_pixel,
+               int dstoffset_in_pixel,                 
+        __global const uchar * restrict maskMat,
+               int maskStep,
+               int maskoffset)
+{
+               int x=get_global_id(0);
+               int y=get_global_id(1);
+               int dstidx = mad24(y,dstStep_in_pixel,x+ dstoffset_in_pixel);
+               int maskidx = mad24(y,maskStep,x+ maskoffset);
+               uchar mask = maskMat[maskidx];          
+               if ( (x < cols) & (y < rows) & mask)
+               {
+                       dstMat[dstidx] = scalar;
+               }
+
+}
+
diff --git a/modules/ocl/src/kernels/split_mat.cl b/modules/ocl/src/kernels/split_mat.cl
new file mode 100644 (file)
index 0000000..87a43f3
--- /dev/null
@@ -0,0 +1,1153 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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*/
+#if defined (DOUBLE_SUPPORT)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////optimized code using vector ////////////////////////////////
+////////////vector fuction name format: split_vector_C(channels number)_D(data type depth)//////
+////////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void split_vector_C4_D0 (__global uchar *mat_src,  int src_step,  int src_offset,
+                                  __global uchar *mat_dst0, int dst0_step, int dst0_offset,  
+                                  __global uchar *mat_dst1, int dst1_step, int dst1_offset, 
+                                       __global uchar *mat_dst2, int dst2_step, int dst2_offset,  
+                                  __global uchar *mat_dst3, int dst3_step, int dst3_offset,
+                                  int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if((x  < cols) && (y < rows)) 
+    {
+        x = x << 2;
+
+        int src_idx  = mad24(y, src_step, src_offset + (x << 2)); 
+
+        int dst0_start = mad24(y, dst0_step, dst0_offset); 
+        int dst0_end   = mad24(y, dst0_step, dst0_offset + dst_step1);
+        int dst0_idx   = mad24(y, dst0_step, dst0_offset + x) & (int)0xfffffffc;
+
+        int dst1_start = mad24(y, dst1_step, dst1_offset); 
+        int dst1_end   = mad24(y, dst1_step, dst1_offset + dst_step1);
+        int dst1_idx   = mad24(y, dst1_step, dst1_offset + x) & (int)0xfffffffc;
+
+        int dst2_start = mad24(y, dst2_step, dst2_offset); 
+        int dst2_end   = mad24(y, dst2_step, dst2_offset + dst_step1);
+        int dst2_idx   = mad24(y, dst2_step, dst2_offset + x) & (int)0xfffffffc;
+
+        int dst3_start = mad24(y, dst3_step, dst3_offset); 
+        int dst3_end   = mad24(y, dst3_step, dst3_offset + dst_step1);
+        int dst3_idx   = mad24(y, dst3_step, dst3_offset + x) & (int)0xfffffffc;
+           
+        uchar4 data_0 = *((global uchar4 *)(mat_src + (src_idx - 12 >= 0 ? src_idx - 12 : src_idx))); 
+        uchar4 data_1 = *((global uchar4 *)(mat_src + (src_idx - 8  >= 0 ? src_idx - 8  : src_idx))); 
+        uchar4 data_2 = *((global uchar4 *)(mat_src + (src_idx - 4  >= 0 ? src_idx - 4  : src_idx))); 
+        uchar4 data_3 = *((global uchar4 *)(mat_src + src_idx + 0 )); 
+
+        int total_bytes = src_offset + rows * src_step; 
+        uchar4 data_4 = *((global uchar4 *)(mat_src + (src_idx + 4  < total_bytes ? src_idx + 4  : src_idx))); 
+        uchar4 data_5 = *((global uchar4 *)(mat_src + (src_idx + 8  < total_bytes ? src_idx + 8  : src_idx))); 
+        uchar4 data_6 = *((global uchar4 *)(mat_src + (src_idx + 12 < total_bytes ? src_idx + 12 : src_idx)));  
+
+        uchar4 tmp_data0=1, tmp_data1=2, tmp_data2, tmp_data3;
+
+        if((dst0_offset & 3) == 3)
+            tmp_data0 = (uchar4)(data_0.x, data_1.x, data_2.x, data_3.x);
+        if((dst0_offset & 3) == 2)
+            tmp_data0 = (uchar4)(data_1.x, data_2.x, data_3.x, data_4.x);
+        if((dst0_offset & 3) == 1)
+            tmp_data0 = (uchar4)(data_2.x, data_3.x, data_4.x, data_5.x);
+        if((dst0_offset & 3) == 0)
+            tmp_data0 = (uchar4)(data_3.x, data_4.x, data_5.x, data_6.x);
+
+        if((dst1_offset & 3) == 3)
+            tmp_data1 = (uchar4)(data_0.y, data_1.y, data_2.y, data_3.y);
+        if((dst1_offset & 3) == 2)
+            tmp_data1 = (uchar4)(data_1.y, data_2.y, data_3.y, data_4.y);
+        if((dst1_offset & 3) == 1)
+            tmp_data1 = (uchar4)(data_2.y, data_3.y, data_4.y, data_5.y);
+        if((dst1_offset & 3) == 0)
+            tmp_data1 = (uchar4)(data_3.y, data_4.y, data_5.y, data_6.y);
+
+        if((dst2_offset & 3) == 3)
+            tmp_data2 = (uchar4)(data_0.z, data_1.z, data_2.z, data_3.z);
+        if((dst2_offset & 3) == 2)
+            tmp_data2 = (uchar4)(data_1.z, data_2.z, data_3.z, data_4.z);
+        if((dst2_offset & 3) == 1)
+            tmp_data2 = (uchar4)(data_2.z, data_3.z, data_4.z, data_5.z);
+        if((dst2_offset & 3) == 0)
+            tmp_data2 = (uchar4)(data_3.z, data_4.z, data_5.z, data_6.z);
+
+        if((dst3_offset & 3) == 3)
+            tmp_data3 = (uchar4)(data_0.w, data_1.w, data_2.w, data_3.w);
+        if((dst3_offset & 3) == 2)
+            tmp_data3 = (uchar4)(data_1.w, data_2.w, data_3.w, data_4.w);
+        if((dst3_offset & 3) == 1)
+            tmp_data3 = (uchar4)(data_2.w, data_3.w, data_4.w, data_5.w);
+        if((dst3_offset & 3) == 0)
+            tmp_data3 = (uchar4)(data_3.w, data_4.w, data_5.w, data_6.w);
+
+        uchar4 dst0_data  = *((__global uchar4 *)(mat_dst0 + dst0_idx));
+        uchar4 dst1_data  = *((__global uchar4 *)(mat_dst1 + dst1_idx));
+        uchar4 dst2_data  = *((__global uchar4 *)(mat_dst2 + dst2_idx));
+        uchar4 dst3_data  = *((__global uchar4 *)(mat_dst3 + dst3_idx));
+
+        tmp_data0.x = ((dst0_idx + 0 >= dst0_start) && (dst0_idx + 0 < dst0_end)) ? tmp_data0.x : dst0_data.x;
+        tmp_data0.y = ((dst0_idx + 1 >= dst0_start) && (dst0_idx + 1 < dst0_end)) ? tmp_data0.y : dst0_data.y;
+        tmp_data0.z = ((dst0_idx + 2 >= dst0_start) && (dst0_idx + 2 < dst0_end)) ? tmp_data0.z : dst0_data.z;
+        tmp_data0.w = ((dst0_idx + 3 >= dst0_start) && (dst0_idx + 3 < dst0_end)) ? tmp_data0.w : dst0_data.w;
+
+        tmp_data1.x = ((dst1_idx + 0 >= dst1_start) && (dst1_idx + 0 < dst1_end)) ? tmp_data1.x : dst1_data.x;
+        tmp_data1.y = ((dst1_idx + 1 >= dst1_start) && (dst1_idx + 1 < dst1_end)) ? tmp_data1.y : dst1_data.y;
+        tmp_data1.z = ((dst1_idx + 2 >= dst1_start) && (dst1_idx + 2 < dst1_end)) ? tmp_data1.z : dst1_data.z;
+        tmp_data1.w = ((dst1_idx + 3 >= dst1_start) && (dst1_idx + 3 < dst1_end)) ? tmp_data1.w : dst1_data.w;
+
+        tmp_data2.x = ((dst2_idx + 0 >= dst2_start) && (dst2_idx + 0 < dst2_end)) ? tmp_data2.x : dst2_data.x;
+        tmp_data2.y = ((dst2_idx + 1 >= dst2_start) && (dst2_idx + 1 < dst2_end)) ? tmp_data2.y : dst2_data.y;
+        tmp_data2.z = ((dst2_idx + 2 >= dst2_start) && (dst2_idx + 2 < dst2_end)) ? tmp_data2.z : dst2_data.z;
+        tmp_data2.w = ((dst2_idx + 3 >= dst2_start) && (dst2_idx + 3 < dst2_end)) ? tmp_data2.w : dst2_data.w;
+
+        tmp_data3.x = ((dst3_idx + 0 >= dst3_start) && (dst3_idx + 0 < dst3_end)) ? tmp_data3.x : dst3_data.x;
+        tmp_data3.y = ((dst3_idx + 1 >= dst3_start) && (dst3_idx + 1 < dst3_end)) ? tmp_data3.y : dst3_data.y;
+        tmp_data3.z = ((dst3_idx + 2 >= dst3_start) && (dst3_idx + 2 < dst3_end)) ? tmp_data3.z : dst3_data.z;
+        tmp_data3.w = ((dst3_idx + 3 >= dst3_start) && (dst3_idx + 3 < dst3_end)) ? tmp_data3.w : dst3_data.w;
+
+        *((__global uchar4 *)(mat_dst0 + dst0_idx)) = tmp_data0;
+        *((__global uchar4 *)(mat_dst1 + dst1_idx)) = tmp_data1;
+        *((__global uchar4 *)(mat_dst2 + dst2_idx)) = tmp_data2;
+        *((__global uchar4 *)(mat_dst3 + dst3_idx)) = tmp_data3;
+    }
+}
+
+__kernel void split_vector_C3_D0 (__global uchar *mat_src,  int src_step,  int src_offset,
+                                  __global uchar *mat_dst0, int dst0_step, int dst0_offset,  
+                                  __global uchar *mat_dst1, int dst1_step, int dst1_offset, 
+                                       __global uchar *mat_dst2, int dst2_step, int dst2_offset,  
+                                  int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if((x  < cols) && (y < rows)) 
+    {
+        x = x << 2;
+
+        int src_idx  = mad24(y, src_step, src_offset); 
+
+        int dst0_start = mad24(y, dst0_step, dst0_offset); 
+        int dst0_end   = mad24(y, dst0_step, dst0_offset + dst_step1);
+        int dst0_idx   = mad24(y, dst0_step, dst0_offset + x & (int)0xfffffffc);
+
+        int dst1_start = mad24(y, dst1_step, dst1_offset); 
+        int dst1_end   = mad24(y, dst1_step, dst1_offset + dst_step1);
+        int dst1_idx   = mad24(y, dst1_step, dst1_offset + x  & (int)0xfffffffc);
+
+        int dst2_start = mad24(y, dst2_step, dst2_offset); 
+        int dst2_end   = mad24(y, dst2_step, dst2_offset + dst_step1);
+        int dst2_idx   = mad24(y, dst2_step, dst2_offset + x & (int)0xfffffffc);
+           
+        uchar4 dst0_data  = *((__global uchar4 *)(mat_dst0 + dst0_idx));
+        uchar4 dst1_data  = *((__global uchar4 *)(mat_dst1 + dst1_idx));
+        uchar4 dst2_data  = *((__global uchar4 *)(mat_dst2 + dst2_idx));
+
+        uchar4 tmp_data0, tmp_data1, tmp_data2;
+
+        uchar src_data_0  =  *(mat_src + src_idx + 3 * x - 9);
+        uchar src_data_1  =  *(mat_src + src_idx + 3 * x - 8);
+        uchar src_data_2  =  *(mat_src + src_idx + 3 * x - 7);
+
+        uchar src_data_3  =  *(mat_src + src_idx + 3 * x - 6);
+        uchar src_data_4  =  *(mat_src + src_idx + 3 * x - 5);
+        uchar src_data_5  =  *(mat_src + src_idx + 3 * x - 4);
+
+        uchar src_data_6  =  *(mat_src + src_idx + 3 * x - 3);
+        uchar src_data_7  =  *(mat_src + src_idx + 3 * x - 2);
+        uchar src_data_8  =  *(mat_src + src_idx + 3 * x - 1);
+
+        uchar src_data_9  =  *(mat_src + src_idx + 3 * x + 0);
+        uchar src_data_10 =  *(mat_src + src_idx + 3 * x + 1);
+        uchar src_data_11 =  *(mat_src + src_idx + 3 * x + 2);
+
+        uchar src_data_12 =  *(mat_src + src_idx + 3 * x + 3);
+        uchar src_data_13 =  *(mat_src + src_idx + 3 * x + 4);
+        uchar src_data_14 =  *(mat_src + src_idx + 3 * x + 5);
+
+        uchar src_data_15 =  *(mat_src + src_idx + 3 * x + 6);
+        uchar src_data_16 =  *(mat_src + src_idx + 3 * x + 7);
+        uchar src_data_17 =  *(mat_src + src_idx + 3 * x + 8);
+
+        uchar src_data_18 =  *(mat_src + src_idx + 3 * x + 9);
+        uchar src_data_19 =  *(mat_src + src_idx + 3 * x + 10);
+        uchar src_data_20 =  *(mat_src + src_idx + 3 * x + 11);
+
+        uchar data[7] = {src_data_0, src_data_3, src_data_6, src_data_9, src_data_12, src_data_15, src_data_18};
+        int index = 3 - dst0_offset & 3;
+        tmp_data0 = (uchar4)(data[index], data[index + 1], data[index + 2], data[index + 3]); 
+
+        uchar4 data0, data1, data2;
+        
+        data0     = (uchar4)(src_data_1, src_data_4, src_data_7, src_data_10);
+        data1     = (dst1_offset & 3) == 2 ? (uchar4)(src_data_4, src_data_7, src_data_10, src_data_13)  : data0;
+        data2     = (dst1_offset & 3) == 1 ? (uchar4)(src_data_7, src_data_10, src_data_13, src_data_16) : data1;
+        tmp_data1 = (dst1_offset & 3) == 0 ? (uchar4)(src_data_10, src_data_13, src_data_16, src_data_19): data2;
+
+        data0     = (uchar4)(src_data_2, src_data_5, src_data_8, src_data_11);
+        data1     = (dst2_offset & 3) == 2 ? (uchar4)(src_data_5, src_data_8, src_data_11, src_data_14)   : data0;
+        data2     = (dst2_offset & 3) == 1 ? (uchar4)(src_data_8, src_data_11, src_data_14, src_data_17)  : data1;
+        tmp_data2 = (dst2_offset & 3) == 0 ? (uchar4)(src_data_11, src_data_14, src_data_17, src_data_20) : data2;
+
+        tmp_data0.x = ((dst0_idx + 0 >= dst0_start) && (dst0_idx + 0 < dst0_end)) ? tmp_data0.x : dst0_data.x;
+        tmp_data0.y = ((dst0_idx + 1 >= dst0_start) && (dst0_idx + 1 < dst0_end)) ? tmp_data0.y : dst0_data.y;
+        tmp_data0.z = ((dst0_idx + 2 >= dst0_start) && (dst0_idx + 2 < dst0_end)) ? tmp_data0.z : dst0_data.z;
+        tmp_data0.w = ((dst0_idx + 3 >= dst0_start) && (dst0_idx + 3 < dst0_end)) ? tmp_data0.w : dst0_data.w;
+
+        tmp_data1.x = ((dst1_idx + 0 >= dst1_start) && (dst1_idx + 0 < dst1_end)) ? tmp_data1.x : dst1_data.x;
+        tmp_data1.y = ((dst1_idx + 1 >= dst1_start) && (dst1_idx + 1 < dst1_end)) ? tmp_data1.y : dst1_data.y;
+        tmp_data1.z = ((dst1_idx + 2 >= dst1_start) && (dst1_idx + 2 < dst1_end)) ? tmp_data1.z : dst1_data.z;
+        tmp_data1.w = ((dst1_idx + 3 >= dst1_start) && (dst1_idx + 3 < dst1_end)) ? tmp_data1.w : dst1_data.w;
+
+        tmp_data2.x = ((dst2_idx + 0 >= dst2_start) && (dst2_idx + 0 < dst2_end)) ? tmp_data2.x : dst2_data.x;
+        tmp_data2.y = ((dst2_idx + 1 >= dst2_start) && (dst2_idx + 1 < dst2_end)) ? tmp_data2.y : dst2_data.y;
+        tmp_data2.z = ((dst2_idx + 2 >= dst2_start) && (dst2_idx + 2 < dst2_end)) ? tmp_data2.z : dst2_data.z;
+        tmp_data2.w = ((dst2_idx + 3 >= dst2_start) && (dst2_idx + 3 < dst2_end)) ? tmp_data2.w : dst2_data.w;
+
+        *((__global uchar4 *)(mat_dst0 + dst0_idx)) = tmp_data0;
+        *((__global uchar4 *)(mat_dst1 + dst1_idx)) = tmp_data1;
+        *((__global uchar4 *)(mat_dst2 + dst2_idx)) = tmp_data2;
+    }
+}
+
+__kernel void split_vector_C2_D0 (__global uchar *mat_src,  int src_step,  int src_offset,
+                                  __global uchar *mat_dst0, int dst0_step, int dst0_offset,  
+                                  __global uchar *mat_dst1, int dst1_step, int dst1_offset, 
+                                  int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if((x  < cols) && (y < rows)) 
+    {
+        x = x << 2;
+
+        #define dst0_align ((dst0_offset & 3) << 1)
+        #define dst1_align ((dst1_offset & 3) << 1)
+        int src_idx_0  = mad24(y, src_step, src_offset - dst0_align + (x << 1)); 
+        int src_idx_1  = mad24(y, src_step, src_offset - dst1_align + (x << 1)); 
+
+        int dst0_start = mad24(y, dst0_step, dst0_offset); 
+        int dst0_end   = mad24(y, dst0_step, dst0_offset + dst_step1);
+        int dst0_idx   = mad24(y, dst0_step, dst0_offset + x & (int)0xfffffffc);
+
+        int dst1_start = mad24(y, dst1_step, dst1_offset); 
+        int dst1_end   = mad24(y, dst1_step, dst1_offset + dst_step1);
+        int dst1_idx   = mad24(y, dst1_step, dst1_offset + x & (int)0xfffffffc);
+           
+        uchar8 src_data_0 = vload8(0, mat_src + src_idx_0);
+        uchar8 src_data_1 = vload8(0, mat_src + src_idx_1);
+
+        uchar4 dst0_data  = *((__global uchar4 *)(mat_dst0 + dst0_idx));
+        uchar4 dst1_data  = *((__global uchar4 *)(mat_dst1 + dst1_idx));
+
+        uchar4 tmp_data0, tmp_data1;
+
+        tmp_data0.x = ((dst0_idx + 0 >= dst0_start) && (dst0_idx + 0 < dst0_end)) ? src_data_0.s0 : dst0_data.x;
+        tmp_data0.y = ((dst0_idx + 1 >= dst0_start) && (dst0_idx + 1 < dst0_end)) ? src_data_0.s2 : dst0_data.y;
+        tmp_data0.z = ((dst0_idx + 2 >= dst0_start) && (dst0_idx + 2 < dst0_end)) ? src_data_0.s4 : dst0_data.z;
+        tmp_data0.w = ((dst0_idx + 3 >= dst0_start) && (dst0_idx + 3 < dst0_end)) ? src_data_0.s6 : dst0_data.w;
+
+        tmp_data1.x = ((dst1_idx + 0 >= dst1_start) && (dst1_idx + 0 < dst1_end)) ? src_data_1.s1 : dst1_data.x;
+        tmp_data1.y = ((dst1_idx + 1 >= dst1_start) && (dst1_idx + 1 < dst1_end)) ? src_data_1.s3 : dst1_data.y;
+        tmp_data1.z = ((dst1_idx + 2 >= dst1_start) && (dst1_idx + 2 < dst1_end)) ? src_data_1.s5 : dst1_data.z;
+        tmp_data1.w = ((dst1_idx + 3 >= dst1_start) && (dst1_idx + 3 < dst1_end)) ? src_data_1.s7 : dst1_data.w;
+
+        *((__global uchar4 *)(mat_dst0 + dst0_idx)) = tmp_data0;
+        *((__global uchar4 *)(mat_dst1 + dst1_idx)) = tmp_data1;
+    }
+}
+
+__kernel void split_vector_C4_D1 (__global char *mat_src,  int src_step,  int src_offset,
+                                  __global char *mat_dst0, int dst0_step, int dst0_offset,  
+                                  __global char *mat_dst1, int dst1_step, int dst1_offset, 
+                                       __global char *mat_dst2, int dst2_step, int dst2_offset,  
+                                  __global char *mat_dst3, int dst3_step, int dst3_offset,
+                                  int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if((x  < cols) && (y < rows)) 
+    {
+        x = x << 2;
+
+        int src_idx  = mad24(y, src_step, src_offset + (x << 2)); 
+
+        int dst0_start = mad24(y, dst0_step, dst0_offset); 
+        int dst0_end   = mad24(y, dst0_step, dst0_offset + dst_step1);
+        int dst0_idx   = mad24(y, dst0_step, dst0_offset + x & (int)0xfffffffc);
+
+        int dst1_start = mad24(y, dst1_step, dst1_offset); 
+        int dst1_end   = mad24(y, dst1_step, dst1_offset + dst_step1);
+        int dst1_idx   = mad24(y, dst1_step, dst1_offset + x & (int)0xfffffffc);
+
+        int dst2_start = mad24(y, dst2_step, dst2_offset); 
+        int dst2_end   = mad24(y, dst2_step, dst2_offset + dst_step1);
+        int dst2_idx   = mad24(y, dst2_step, dst2_offset + x & (int)0xfffffffc);
+
+        int dst3_start = mad24(y, dst3_step, dst3_offset); 
+        int dst3_end   = mad24(y, dst3_step, dst3_offset + dst_step1);
+        int dst3_idx   = mad24(y, dst3_step, dst3_offset + x & (int)0xfffffffc);
+           
+        char4 data_0 = *((global char4 *)(mat_src + src_idx - 12)); 
+        char4 data_1 = *((global char4 *)(mat_src + src_idx - 8 )); 
+        char4 data_2 = *((global char4 *)(mat_src + src_idx - 4 )); 
+        char4 data_3 = *((global char4 *)(mat_src + src_idx + 0 )); 
+        char4 data_4 = *((global char4 *)(mat_src + src_idx + 4 )); 
+        char4 data_5 = *((global char4 *)(mat_src + src_idx + 8 )); 
+        char4 data_6 = *((global char4 *)(mat_src + src_idx + 12)); 
+
+        char4 tmp_data0=1, tmp_data1=2, tmp_data2, tmp_data3;
+
+        if((dst0_offset & 3) == 3)
+            tmp_data0 = (char4)(data_0.x, data_1.x, data_2.x, data_3.x);
+        if((dst0_offset & 3) == 2)
+            tmp_data0 = (char4)(data_1.x, data_2.x, data_3.x, data_4.x);
+        if((dst0_offset & 3) == 1)
+            tmp_data0 = (char4)(data_2.x, data_3.x, data_4.x, data_5.x);
+        if((dst0_offset & 3) == 0)
+            tmp_data0 = (char4)(data_3.x, data_4.x, data_5.x, data_6.x);
+
+        if((dst1_offset & 3) == 3)
+            tmp_data1 = (char4)(data_0.y, data_1.y, data_2.y, data_3.y);
+        if((dst1_offset & 3) == 2)
+            tmp_data1 = (char4)(data_1.y, data_2.y, data_3.y, data_4.y);
+        if((dst1_offset & 3) == 1)
+            tmp_data1 = (char4)(data_2.y, data_3.y, data_4.y, data_5.y);
+        if((dst1_offset & 3) == 0)
+            tmp_data1 = (char4)(data_3.y, data_4.y, data_5.y, data_6.y);
+
+        if((dst2_offset & 3) == 3)
+            tmp_data2 = (char4)(data_0.z, data_1.z, data_2.z, data_3.z);
+        if((dst2_offset & 3) == 2)
+            tmp_data2 = (char4)(data_1.z, data_2.z, data_3.z, data_4.z);
+        if((dst2_offset & 3) == 1)
+            tmp_data2 = (char4)(data_2.z, data_3.z, data_4.z, data_5.z);
+        if((dst2_offset & 3) == 0)
+            tmp_data2 = (char4)(data_3.z, data_4.z, data_5.z, data_6.z);
+
+        if((dst3_offset & 3) == 3)
+            tmp_data3 = (char4)(data_0.w, data_1.w, data_2.w, data_3.w);
+        if((dst3_offset & 3) == 2)
+            tmp_data3 = (char4)(data_1.w, data_2.w, data_3.w, data_4.w);
+        if((dst3_offset & 3) == 1)
+            tmp_data3 = (char4)(data_2.w, data_3.w, data_4.w, data_5.w);
+        if((dst3_offset & 3) == 0)
+            tmp_data3 = (char4)(data_3.w, data_4.w, data_5.w, data_6.w);
+
+        char4 dst0_data  = *((__global char4 *)(mat_dst0 + dst0_idx));
+        char4 dst1_data  = *((__global char4 *)(mat_dst1 + dst1_idx));
+        char4 dst2_data  = *((__global char4 *)(mat_dst2 + dst2_idx));
+        char4 dst3_data  = *((__global char4 *)(mat_dst3 + dst3_idx));
+
+        tmp_data0.x = ((dst0_idx + 0 >= dst0_start) && (dst0_idx + 0 < dst0_end)) ? tmp_data0.x : dst0_data.x;
+        tmp_data0.y = ((dst0_idx + 1 >= dst0_start) && (dst0_idx + 1 < dst0_end)) ? tmp_data0.y : dst0_data.y;
+        tmp_data0.z = ((dst0_idx + 2 >= dst0_start) && (dst0_idx + 2 < dst0_end)) ? tmp_data0.z : dst0_data.z;
+        tmp_data0.w = ((dst0_idx + 3 >= dst0_start) && (dst0_idx + 3 < dst0_end)) ? tmp_data0.w : dst0_data.w;
+
+        tmp_data1.x = ((dst1_idx + 0 >= dst1_start) && (dst1_idx + 0 < dst1_end)) ? tmp_data1.x : dst1_data.x;
+        tmp_data1.y = ((dst1_idx + 1 >= dst1_start) && (dst1_idx + 1 < dst1_end)) ? tmp_data1.y : dst1_data.y;
+        tmp_data1.z = ((dst1_idx + 2 >= dst1_start) && (dst1_idx + 2 < dst1_end)) ? tmp_data1.z : dst1_data.z;
+        tmp_data1.w = ((dst1_idx + 3 >= dst1_start) && (dst1_idx + 3 < dst1_end)) ? tmp_data1.w : dst1_data.w;
+
+        tmp_data2.x = ((dst2_idx + 0 >= dst2_start) && (dst2_idx + 0 < dst2_end)) ? tmp_data2.x : dst2_data.x;
+        tmp_data2.y = ((dst2_idx + 1 >= dst2_start) && (dst2_idx + 1 < dst2_end)) ? tmp_data2.y : dst2_data.y;
+        tmp_data2.z = ((dst2_idx + 2 >= dst2_start) && (dst2_idx + 2 < dst2_end)) ? tmp_data2.z : dst2_data.z;
+        tmp_data2.w = ((dst2_idx + 3 >= dst2_start) && (dst2_idx + 3 < dst2_end)) ? tmp_data2.w : dst2_data.w;
+
+        tmp_data3.x = ((dst3_idx + 0 >= dst3_start) && (dst3_idx + 0 < dst3_end)) ? tmp_data3.x : dst3_data.x;
+        tmp_data3.y = ((dst3_idx + 1 >= dst3_start) && (dst3_idx + 1 < dst3_end)) ? tmp_data3.y : dst3_data.y;
+        tmp_data3.z = ((dst3_idx + 2 >= dst3_start) && (dst3_idx + 2 < dst3_end)) ? tmp_data3.z : dst3_data.z;
+        tmp_data3.w = ((dst3_idx + 3 >= dst3_start) && (dst3_idx + 3 < dst3_end)) ? tmp_data3.w : dst3_data.w;
+
+        *((__global char4 *)(mat_dst0 + dst0_idx)) = tmp_data0;
+        *((__global char4 *)(mat_dst1 + dst1_idx)) = tmp_data1;
+        *((__global char4 *)(mat_dst2 + dst2_idx)) = tmp_data2;
+        *((__global char4 *)(mat_dst3 + dst3_idx)) = tmp_data3;
+    }
+}
+
+__kernel void split_vector_C3_D1 (__global char *mat_src,  int src_step,  int src_offset,
+                                  __global char *mat_dst0, int dst0_step, int dst0_offset,  
+                                  __global char *mat_dst1, int dst1_step, int dst1_offset, 
+                                       __global char *mat_dst2, int dst2_step, int dst2_offset,  
+                                  int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if((x  < cols) && (y < rows)) 
+    {
+        x = x << 2;
+
+        int src_idx  = mad24(y, src_step, src_offset); 
+
+        int dst0_start = mad24(y, dst0_step, dst0_offset); 
+        int dst0_end   = mad24(y, dst0_step, dst0_offset + dst_step1);
+        int dst0_idx   = mad24(y, dst0_step, dst0_offset + x & (int)0xfffffffc);
+
+        int dst1_start = mad24(y, dst1_step, dst1_offset); 
+        int dst1_end   = mad24(y, dst1_step, dst1_offset + dst_step1);
+        int dst1_idx   = mad24(y, dst1_step, dst1_offset + x  & (int)0xfffffffc);
+
+        int dst2_start = mad24(y, dst2_step, dst2_offset); 
+        int dst2_end   = mad24(y, dst2_step, dst2_offset + dst_step1);
+        int dst2_idx   = mad24(y, dst2_step, dst2_offset + x & (int)0xfffffffc);
+           
+        char4 dst0_data  = *((__global char4 *)(mat_dst0 + dst0_idx));
+        char4 dst1_data  = *((__global char4 *)(mat_dst1 + dst1_idx));
+        char4 dst2_data  = *((__global char4 *)(mat_dst2 + dst2_idx));
+
+        char4 tmp_data0, tmp_data1, tmp_data2;
+
+        char src_data_0  =  *(mat_src + src_idx + 3 * x - 9);
+        char src_data_1  =  *(mat_src + src_idx + 3 * x - 8);
+        char src_data_2  =  *(mat_src + src_idx + 3 * x - 7);
+
+        char src_data_3  =  *(mat_src + src_idx + 3 * x - 6);
+        char src_data_4  =  *(mat_src + src_idx + 3 * x - 5);
+        char src_data_5  =  *(mat_src + src_idx + 3 * x - 4);
+
+        char src_data_6  =  *(mat_src + src_idx + 3 * x - 3);
+        char src_data_7  =  *(mat_src + src_idx + 3 * x - 2);
+        char src_data_8  =  *(mat_src + src_idx + 3 * x - 1);
+
+        char src_data_9  =  *(mat_src + src_idx + 3 * x + 0);
+        char src_data_10 =  *(mat_src + src_idx + 3 * x + 1);
+        char src_data_11 =  *(mat_src + src_idx + 3 * x + 2);
+
+        char src_data_12 =  *(mat_src + src_idx + 3 * x + 3);
+        char src_data_13 =  *(mat_src + src_idx + 3 * x + 4);
+        char src_data_14 =  *(mat_src + src_idx + 3 * x + 5);
+
+        char src_data_15 =  *(mat_src + src_idx + 3 * x + 6);
+        char src_data_16 =  *(mat_src + src_idx + 3 * x + 7);
+        char src_data_17 =  *(mat_src + src_idx + 3 * x + 8);
+
+        char src_data_18 =  *(mat_src + src_idx + 3 * x + 9);
+        char src_data_19 =  *(mat_src + src_idx + 3 * x + 10);
+        char src_data_20 =  *(mat_src + src_idx + 3 * x + 11);
+
+        char data[7] = {src_data_0, src_data_3, src_data_6, src_data_9, src_data_12, src_data_15, src_data_18};
+        int index = 3 - dst0_offset & 3;
+        tmp_data0 = (char4)(data[index], data[index + 1], data[index + 2], data[index + 3]); 
+
+        char4 data0, data1, data2;
+        
+        data0     = (char4)(src_data_1, src_data_4, src_data_7, src_data_10);
+        data1     = (dst1_offset & 3) == 2 ? (char4)(src_data_4, src_data_7, src_data_10, src_data_13)  : data0;
+        data2     = (dst1_offset & 3) == 1 ? (char4)(src_data_7, src_data_10, src_data_13, src_data_16) : data1;
+        tmp_data1 = (dst1_offset & 3) == 0 ? (char4)(src_data_10, src_data_13, src_data_16, src_data_19): data2;
+
+        data0     = (char4)(src_data_2, src_data_5, src_data_8, src_data_11);
+        data1     = (dst2_offset & 3) == 2 ? (char4)(src_data_5, src_data_8, src_data_11, src_data_14)   : data0;
+        data2     = (dst2_offset & 3) == 1 ? (char4)(src_data_8, src_data_11, src_data_14, src_data_17)  : data1;
+        tmp_data2 = (dst2_offset & 3) == 0 ? (char4)(src_data_11, src_data_14, src_data_17, src_data_20) : data2;
+
+        tmp_data0.x = ((dst0_idx + 0 >= dst0_start) && (dst0_idx + 0 < dst0_end)) ? tmp_data0.x : dst0_data.x;
+        tmp_data0.y = ((dst0_idx + 1 >= dst0_start) && (dst0_idx + 1 < dst0_end)) ? tmp_data0.y : dst0_data.y;
+        tmp_data0.z = ((dst0_idx + 2 >= dst0_start) && (dst0_idx + 2 < dst0_end)) ? tmp_data0.z : dst0_data.z;
+        tmp_data0.w = ((dst0_idx + 3 >= dst0_start) && (dst0_idx + 3 < dst0_end)) ? tmp_data0.w : dst0_data.w;
+
+        tmp_data1.x = ((dst1_idx + 0 >= dst1_start) && (dst1_idx + 0 < dst1_end)) ? tmp_data1.x : dst1_data.x;
+        tmp_data1.y = ((dst1_idx + 1 >= dst1_start) && (dst1_idx + 1 < dst1_end)) ? tmp_data1.y : dst1_data.y;
+        tmp_data1.z = ((dst1_idx + 2 >= dst1_start) && (dst1_idx + 2 < dst1_end)) ? tmp_data1.z : dst1_data.z;
+        tmp_data1.w = ((dst1_idx + 3 >= dst1_start) && (dst1_idx + 3 < dst1_end)) ? tmp_data1.w : dst1_data.w;
+
+        tmp_data2.x = ((dst2_idx + 0 >= dst2_start) && (dst2_idx + 0 < dst2_end)) ? tmp_data2.x : dst2_data.x;
+        tmp_data2.y = ((dst2_idx + 1 >= dst2_start) && (dst2_idx + 1 < dst2_end)) ? tmp_data2.y : dst2_data.y;
+        tmp_data2.z = ((dst2_idx + 2 >= dst2_start) && (dst2_idx + 2 < dst2_end)) ? tmp_data2.z : dst2_data.z;
+        tmp_data2.w = ((dst2_idx + 3 >= dst2_start) && (dst2_idx + 3 < dst2_end)) ? tmp_data2.w : dst2_data.w;
+
+        *((__global char4 *)(mat_dst0 + dst0_idx)) = tmp_data0;
+        *((__global char4 *)(mat_dst1 + dst1_idx)) = tmp_data1;
+        *((__global char4 *)(mat_dst2 + dst2_idx)) = tmp_data2;
+    }
+}
+
+__kernel void split_vector_C2_D1 (__global char *mat_src,  int src_step,  int src_offset,
+                                  __global char *mat_dst0, int dst0_step, int dst0_offset,  
+                                  __global char *mat_dst1, int dst1_step, int dst1_offset, 
+                                  int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if((x  < cols) && (y < rows)) 
+    {
+        x = x << 2;
+
+        #define dst0_align ((dst0_offset & 3) << 1)
+        #define dst1_align ((dst1_offset & 3) << 1)
+        int src_idx_0  = mad24(y, src_step, src_offset - dst0_align + (x << 1)); 
+        int src_idx_1  = mad24(y, src_step, src_offset - dst1_align + (x << 1)); 
+
+        int dst0_start = mad24(y, dst0_step, dst0_offset); 
+        int dst0_end   = mad24(y, dst0_step, dst0_offset + dst_step1);
+        int dst0_idx   = mad24(y, dst0_step, dst0_offset + x & (int)0xfffffffc);
+
+        int dst1_start = mad24(y, dst1_step, dst1_offset); 
+        int dst1_end   = mad24(y, dst1_step, dst1_offset + dst_step1);
+        int dst1_idx   = mad24(y, dst1_step, dst1_offset + x & (int)0xfffffffc);
+           
+        char8 src_data_0 = vload8(0, mat_src + src_idx_0);
+        char8 src_data_1 = vload8(0, mat_src + src_idx_1);
+
+        char4 dst0_data  = *((__global char4 *)(mat_dst0 + dst0_idx));
+        char4 dst1_data  = *((__global char4 *)(mat_dst1 + dst1_idx));
+
+        char4 tmp_data0, tmp_data1;
+
+        tmp_data0.x = ((dst0_idx + 0 >= dst0_start) && (dst0_idx + 0 < dst0_end)) ? src_data_0.s0 : dst0_data.x;
+        tmp_data0.y = ((dst0_idx + 1 >= dst0_start) && (dst0_idx + 1 < dst0_end)) ? src_data_0.s2 : dst0_data.y;
+        tmp_data0.z = ((dst0_idx + 2 >= dst0_start) && (dst0_idx + 2 < dst0_end)) ? src_data_0.s4 : dst0_data.z;
+        tmp_data0.w = ((dst0_idx + 3 >= dst0_start) && (dst0_idx + 3 < dst0_end)) ? src_data_0.s6 : dst0_data.w;
+
+        tmp_data1.x = ((dst1_idx + 0 >= dst1_start) && (dst1_idx + 0 < dst1_end)) ? src_data_1.s1 : dst1_data.x;
+        tmp_data1.y = ((dst1_idx + 1 >= dst1_start) && (dst1_idx + 1 < dst1_end)) ? src_data_1.s3 : dst1_data.y;
+        tmp_data1.z = ((dst1_idx + 2 >= dst1_start) && (dst1_idx + 2 < dst1_end)) ? src_data_1.s5 : dst1_data.z;
+        tmp_data1.w = ((dst1_idx + 3 >= dst1_start) && (dst1_idx + 3 < dst1_end)) ? src_data_1.s7 : dst1_data.w;
+
+        *((__global char4 *)(mat_dst0 + dst0_idx)) = tmp_data0;
+        *((__global char4 *)(mat_dst1 + dst1_idx)) = tmp_data1;
+    }
+}
+
+__kernel void split_vector_C4_D2 (__global ushort *mat_src,  int src_step,  int src_offset,
+                                  __global ushort *mat_dst0, int dst0_step, int dst0_offset,  
+                                  __global ushort *mat_dst1, int dst1_step, int dst1_offset, 
+                                       __global ushort *mat_dst2, int dst2_step, int dst2_offset,  
+                                  __global ushort *mat_dst3, int dst3_step, int dst3_offset,
+                                  int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if((x  < cols) && (y < rows)) 
+    {
+        x = x << 1;
+
+        int src_idx_0  = mad24(y, src_step, src_offset + (x << 3) - 8); 
+        int src_idx_1  = mad24(y, src_step, src_offset + (x << 3) + 8); 
+
+        int dst0_start = mad24(y, dst0_step, dst0_offset); 
+        int dst0_end   = mad24(y, dst0_step, dst0_offset + dst_step1);
+        int dst0_idx   = mad24(y, dst0_step, dst0_offset + (x << 1) & (int)0xfffffffc);
+
+        int dst1_start = mad24(y, dst1_step, dst1_offset); 
+        int dst1_end   = mad24(y, dst1_step, dst1_offset + dst_step1);
+        int dst1_idx   = mad24(y, dst1_step, dst1_offset + (x << 1) & (int)0xfffffffc);
+
+        int dst2_start = mad24(y, dst2_step, dst2_offset); 
+        int dst2_end   = mad24(y, dst2_step, dst2_offset + dst_step1);
+        int dst2_idx   = mad24(y, dst2_step, dst2_offset + (x << 1) & (int)0xfffffffc);
+
+        int dst3_start = mad24(y, dst3_step, dst3_offset); 
+        int dst3_end   = mad24(y, dst3_step, dst3_offset + dst_step1);
+        int dst3_idx   = mad24(y, dst3_step, dst3_offset + (x << 1) & (int)0xfffffffc);
+           
+        ushort8 src_data0 = vload8(0, (__global ushort *)((__global char *)mat_src + src_idx_0));
+        ushort4 src_data1 = *((__global ushort4 *)((__global char *)mat_src + src_idx_1));
+
+        ushort2 dst0_data  = *((__global ushort2 *)((__global char *)mat_dst0 + dst0_idx));
+        ushort2 dst1_data  = *((__global ushort2 *)((__global char *)mat_dst1 + dst1_idx));
+        ushort2 dst2_data  = *((__global ushort2 *)((__global char *)mat_dst2 + dst2_idx));
+        ushort2 dst3_data  = *((__global ushort2 *)((__global char *)mat_dst3 + dst3_idx));
+
+        ushort2 tmp_data0, tmp_data1, tmp_data2, tmp_data3;
+
+        tmp_data0 = (dst0_offset & 3) == 0 ? (ushort2)(src_data0.s4, src_data1.s0) : (ushort2)(src_data0.s0, src_data0.s4);
+        tmp_data1 = (dst1_offset & 3) == 0 ? (ushort2)(src_data0.s5, src_data1.s1) : (ushort2)(src_data0.s1, src_data0.s5);
+        tmp_data2 = (dst2_offset & 3) == 0 ? (ushort2)(src_data0.s6, src_data1.s2) : (ushort2)(src_data0.s2, src_data0.s6);
+        tmp_data3 = (dst3_offset & 3) == 0 ? (ushort2)(src_data0.s7, src_data1.s3) : (ushort2)(src_data0.s3, src_data0.s7);
+
+        tmp_data0.x = ((dst0_idx + 0 >= dst0_start) && (dst0_idx + 0 < dst0_end)) ? tmp_data0.x : dst0_data.x;
+        tmp_data0.y = ((dst0_idx + 2 >= dst0_start) && (dst0_idx + 2 < dst0_end)) ? tmp_data0.y : dst0_data.y;
+
+        tmp_data1.x = ((dst1_idx + 0 >= dst1_start) && (dst1_idx + 0 < dst1_end)) ? tmp_data1.x : dst1_data.x;
+        tmp_data1.y = ((dst1_idx + 2 >= dst1_start) && (dst1_idx + 2 < dst1_end)) ? tmp_data1.y : dst1_data.y;
+
+        tmp_data2.x = ((dst2_idx + 0 >= dst2_start) && (dst2_idx + 0 < dst2_end)) ? tmp_data2.x : dst2_data.x;
+        tmp_data2.y = ((dst2_idx + 2 >= dst2_start) && (dst2_idx + 2 < dst2_end)) ? tmp_data2.y : dst2_data.y;
+
+        tmp_data3.x = ((dst3_idx + 0 >= dst3_start) && (dst3_idx + 0 < dst3_end)) ? tmp_data3.x : dst3_data.x;
+        tmp_data3.y = ((dst3_idx + 2 >= dst3_start) && (dst3_idx + 2 < dst3_end)) ? tmp_data3.y : dst3_data.y;
+
+        *((global ushort2 *)((__global char *)mat_dst0 + dst0_idx)) = tmp_data0;
+        *((global ushort2 *)((__global char *)mat_dst1 + dst1_idx)) = tmp_data1;
+        *((global ushort2 *)((__global char *)mat_dst2 + dst2_idx)) = tmp_data2;
+        *((global ushort2 *)((__global char *)mat_dst3 + dst3_idx)) = tmp_data3;
+    }
+}
+
+__kernel void split_vector_C3_D2 (__global ushort *mat_src,  int src_step,  int src_offset,
+                                  __global ushort *mat_dst0, int dst0_step, int dst0_offset,  
+                                  __global ushort *mat_dst1, int dst1_step, int dst1_offset, 
+                                       __global ushort *mat_dst2, int dst2_step, int dst2_offset,  
+                                  int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if((x  < cols) && (y < rows)) 
+    {
+        x = x << 1;
+
+        int src_idx  = mad24(y, src_step, src_offset); 
+
+        int dst0_start = mad24(y, dst0_step, dst0_offset); 
+        int dst0_end   = mad24(y, dst0_step, dst0_offset + dst_step1);
+        int dst0_idx   = mad24(y, dst0_step, dst0_offset + (x << 1) & (int)0xfffffffc);
+
+        int dst1_start = mad24(y, dst1_step, dst1_offset); 
+        int dst1_end   = mad24(y, dst1_step, dst1_offset + dst_step1);
+        int dst1_idx   = mad24(y, dst1_step, dst1_offset + (x << 1) & (int)0xfffffffc);
+
+        int dst2_start = mad24(y, dst2_step, dst2_offset); 
+        int dst2_end   = mad24(y, dst2_step, dst2_offset + dst_step1);
+        int dst2_idx   = mad24(y, dst2_step, dst2_offset + (x << 1) & (int)0xfffffffc);
+           
+        ushort2 dst0_data  = *((__global ushort2 *)((__global char *)mat_dst0 + dst0_idx));
+        ushort2 dst1_data  = *((__global ushort2 *)((__global char *)mat_dst1 + dst1_idx));
+        ushort2 dst2_data  = *((__global ushort2 *)((__global char *)mat_dst2 + dst2_idx));
+
+        ushort2 tmp_data0, tmp_data1, tmp_data2;
+
+        ushort src_data_0 = ((__global ushort *)((__global char *)mat_src + src_idx))[3 * x - 3];
+        ushort src_data_1 = ((__global ushort *)((__global char *)mat_src + src_idx))[3 * x - 2];
+        ushort src_data_2 = ((__global ushort *)((__global char *)mat_src + src_idx))[3 * x - 1];
+        ushort src_data_3 = ((__global ushort *)((__global char *)mat_src + src_idx))[3 * x + 0];
+        ushort src_data_4 = ((__global ushort *)((__global char *)mat_src + src_idx))[3 * x + 1];
+        ushort src_data_5 = ((__global ushort *)((__global char *)mat_src + src_idx))[3 * x + 2];
+        ushort src_data_6 = ((__global ushort *)((__global char *)mat_src + src_idx))[3 * x + 3];
+        ushort src_data_7 = ((__global ushort *)((__global char *)mat_src + src_idx))[3 * x + 4];
+        ushort src_data_8 = ((__global ushort *)((__global char *)mat_src + src_idx))[3 * x + 5];
+
+        tmp_data0 = (dst0_offset & 3) == 0 ? (ushort2)(src_data_3, src_data_6) : (ushort2)(src_data_0, src_data_3);
+        tmp_data1 = (dst1_offset & 3) == 0 ? (ushort2)(src_data_4, src_data_7) : (ushort2)(src_data_1, src_data_4);
+        tmp_data2 = (dst2_offset & 3) == 0 ? (ushort2)(src_data_5, src_data_8) : (ushort2)(src_data_2, src_data_5);
+
+        tmp_data0.x = ((dst0_idx + 0 >= dst0_start) && (dst0_idx + 0 < dst0_end)) ? tmp_data0.x : dst0_data.x;
+        tmp_data0.y = ((dst0_idx + 2 >= dst0_start) && (dst0_idx + 2 < dst0_end)) ? tmp_data0.y : dst0_data.y;
+
+        tmp_data1.x = ((dst1_idx + 0 >= dst1_start) && (dst1_idx + 0 < dst1_end)) ? tmp_data1.x : dst1_data.x;
+        tmp_data1.y = ((dst1_idx + 2 >= dst1_start) && (dst1_idx + 2 < dst1_end)) ? tmp_data1.y : dst1_data.y;
+
+        tmp_data2.x = ((dst2_idx + 0 >= dst2_start) && (dst2_idx + 0 < dst2_end)) ? tmp_data2.x : dst2_data.x;
+        tmp_data2.y = ((dst2_idx + 2 >= dst2_start) && (dst2_idx + 2 < dst2_end)) ? tmp_data2.y : dst2_data.y;
+
+        *((__global ushort2 *)((__global char *)mat_dst0 + dst0_idx)) = tmp_data0;
+        *((__global ushort2 *)((__global char *)mat_dst1 + dst1_idx)) = tmp_data1;
+        *((__global ushort2 *)((__global char *)mat_dst2 + dst2_idx)) = tmp_data2;
+    }
+}
+
+__kernel void split_vector_C2_D2 (__global ushort *mat_src,  int src_step,  int src_offset,
+                                  __global ushort *mat_dst0, int dst0_step, int dst0_offset,  
+                                  __global ushort *mat_dst1, int dst1_step, int dst1_offset, 
+                                  int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if((x  < cols) && (y < rows)) 
+    {
+        x = x << 1;
+
+        #define dst0_align ((dst0_offset & 3) << 1)
+        #define dst1_align ((dst1_offset & 3) << 1)
+        int src_idx_0  = mad24(y, src_step, src_offset - dst0_align + (x << 2)); 
+        int src_idx_1  = mad24(y, src_step, src_offset - dst1_align + (x << 2)); 
+
+        int dst0_start = mad24(y, dst0_step, dst0_offset); 
+        int dst0_end   = mad24(y, dst0_step, dst0_offset + dst_step1);
+        int dst0_idx   = mad24(y, dst0_step, dst0_offset + (x << 1) & (int)0xfffffffc);
+
+        int dst1_start = mad24(y, dst1_step, dst1_offset); 
+        int dst1_end   = mad24(y, dst1_step, dst1_offset + dst_step1);
+        int dst1_idx   = mad24(y, dst1_step, dst1_offset + (x << 1) & (int)0xfffffffc);
+           
+        ushort4 src_data_0 = vload4(0, (__global ushort *)((__global char *)mat_src + src_idx_0));
+        ushort4 src_data_1 = vload4(0, (__global ushort *)((__global char *)mat_src + src_idx_1));
+
+        ushort2 dst0_data  = *((__global ushort2 *)((__global char *)mat_dst0 + dst0_idx));
+        ushort2 dst1_data  = *((__global ushort2 *)((__global char *)mat_dst1 + dst1_idx));
+
+        ushort2 tmp_data0, tmp_data1;
+
+        tmp_data0.x = ((dst0_idx + 0 >= dst0_start) && (dst0_idx + 0 < dst0_end)) ? src_data_0.x : dst0_data.x;
+        tmp_data0.y = ((dst0_idx + 2 >= dst0_start) && (dst0_idx + 2 < dst0_end)) ? src_data_0.z : dst0_data.y;
+
+        tmp_data1.x = ((dst1_idx + 0 >= dst1_start) && (dst1_idx + 0 < dst1_end)) ? src_data_1.y : dst1_data.x;
+        tmp_data1.y = ((dst1_idx + 2 >= dst1_start) && (dst1_idx + 2 < dst1_end)) ? src_data_1.w : dst1_data.y;
+
+        *((global ushort2 *)((__global char *)mat_dst0 + dst0_idx)) = tmp_data0;
+        *((global ushort2 *)((__global char *)mat_dst1 + dst1_idx)) = tmp_data1;
+    }
+}
+__kernel void split_vector_C4_D3 (__global short *mat_src,  int src_step,  int src_offset,
+                                  __global short *mat_dst0, int dst0_step, int dst0_offset,  
+                                  __global short *mat_dst1, int dst1_step, int dst1_offset, 
+                                       __global short *mat_dst2, int dst2_step, int dst2_offset,  
+                                  __global short *mat_dst3, int dst3_step, int dst3_offset,
+                                  int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if((x  < cols) && (y < rows)) 
+    {
+        x = x << 1;
+
+        int src_idx_0  = mad24(y, src_step, src_offset + (x << 3) - 8); 
+        int src_idx_1  = mad24(y, src_step, src_offset + (x << 3) + 8); 
+
+        int dst0_start = mad24(y, dst0_step, dst0_offset); 
+        int dst0_end   = mad24(y, dst0_step, dst0_offset + dst_step1);
+        int dst0_idx   = mad24(y, dst0_step, dst0_offset + (x << 1) & (int)0xfffffffc);
+
+        int dst1_start = mad24(y, dst1_step, dst1_offset); 
+        int dst1_end   = mad24(y, dst1_step, dst1_offset + dst_step1);
+        int dst1_idx   = mad24(y, dst1_step, dst1_offset + (x << 1) & (int)0xfffffffc);
+
+        int dst2_start = mad24(y, dst2_step, dst2_offset); 
+        int dst2_end   = mad24(y, dst2_step, dst2_offset + dst_step1);
+        int dst2_idx   = mad24(y, dst2_step, dst2_offset + (x << 1) & (int)0xfffffffc);
+
+        int dst3_start = mad24(y, dst3_step, dst3_offset); 
+        int dst3_end   = mad24(y, dst3_step, dst3_offset + dst_step1);
+        int dst3_idx   = mad24(y, dst3_step, dst3_offset + (x << 1) & (int)0xfffffffc);
+           
+        short8 src_data0 = vload8(0, (__global short *)((__global char *)mat_src + src_idx_0));
+        short4 src_data1 = *((__global short4 *)((__global char *)mat_src + src_idx_1));
+
+        short2 dst0_data  = *((__global short2 *)((__global char *)mat_dst0 + dst0_idx));
+        short2 dst1_data  = *((__global short2 *)((__global char *)mat_dst1 + dst1_idx));
+        short2 dst2_data  = *((__global short2 *)((__global char *)mat_dst2 + dst2_idx));
+        short2 dst3_data  = *((__global short2 *)((__global char *)mat_dst3 + dst3_idx));
+
+        short2 tmp_data0, tmp_data1, tmp_data2, tmp_data3;
+
+        tmp_data0 = (dst0_offset & 3) == 0 ? (short2)(src_data0.s4, src_data1.s0) : (short2)(src_data0.s0, src_data0.s4);
+        tmp_data1 = (dst1_offset & 3) == 0 ? (short2)(src_data0.s5, src_data1.s1) : (short2)(src_data0.s1, src_data0.s5);
+        tmp_data2 = (dst2_offset & 3) == 0 ? (short2)(src_data0.s6, src_data1.s2) : (short2)(src_data0.s2, src_data0.s6);
+        tmp_data3 = (dst3_offset & 3) == 0 ? (short2)(src_data0.s7, src_data1.s3) : (short2)(src_data0.s3, src_data0.s7);
+
+        tmp_data0.x = ((dst0_idx + 0 >= dst0_start) && (dst0_idx + 0 < dst0_end)) ? tmp_data0.x : dst0_data.x;
+        tmp_data0.y = ((dst0_idx + 2 >= dst0_start) && (dst0_idx + 2 < dst0_end)) ? tmp_data0.y : dst0_data.y;
+
+        tmp_data1.x = ((dst1_idx + 0 >= dst1_start) && (dst1_idx + 0 < dst1_end)) ? tmp_data1.x : dst1_data.x;
+        tmp_data1.y = ((dst1_idx + 2 >= dst1_start) && (dst1_idx + 2 < dst1_end)) ? tmp_data1.y : dst1_data.y;
+
+        tmp_data2.x = ((dst2_idx + 0 >= dst2_start) && (dst2_idx + 0 < dst2_end)) ? tmp_data2.x : dst2_data.x;
+        tmp_data2.y = ((dst2_idx + 2 >= dst2_start) && (dst2_idx + 2 < dst2_end)) ? tmp_data2.y : dst2_data.y;
+
+        tmp_data3.x = ((dst3_idx + 0 >= dst3_start) && (dst3_idx + 0 < dst3_end)) ? tmp_data3.x : dst3_data.x;
+        tmp_data3.y = ((dst3_idx + 2 >= dst3_start) && (dst3_idx + 2 < dst3_end)) ? tmp_data3.y : dst3_data.y;
+
+        *((global short2 *)((__global char *)mat_dst0 + dst0_idx)) = tmp_data0;
+        *((global short2 *)((__global char *)mat_dst1 + dst1_idx)) = tmp_data1;
+        *((global short2 *)((__global char *)mat_dst2 + dst2_idx)) = tmp_data2;
+        *((global short2 *)((__global char *)mat_dst3 + dst3_idx)) = tmp_data3;
+    }
+}
+__kernel void split_vector_C3_D3 (__global short *mat_src,  int src_step,  int src_offset,
+                                  __global short *mat_dst0, int dst0_step, int dst0_offset,  
+                                  __global short *mat_dst1, int dst1_step, int dst1_offset, 
+                                       __global short *mat_dst2, int dst2_step, int dst2_offset,  
+                                  int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if((x  < cols) && (y < rows)) 
+    {
+        x = x << 1;
+
+        int src_idx  = mad24(y, src_step, src_offset); 
+
+        int dst0_start = mad24(y, dst0_step, dst0_offset); 
+        int dst0_end   = mad24(y, dst0_step, dst0_offset + dst_step1);
+        int dst0_idx   = mad24(y, dst0_step, dst0_offset + (x << 1) & (int)0xfffffffc);
+
+        int dst1_start = mad24(y, dst1_step, dst1_offset); 
+        int dst1_end   = mad24(y, dst1_step, dst1_offset + dst_step1);
+        int dst1_idx   = mad24(y, dst1_step, dst1_offset + (x << 1) & (int)0xfffffffc);
+
+        int dst2_start = mad24(y, dst2_step, dst2_offset); 
+        int dst2_end   = mad24(y, dst2_step, dst2_offset + dst_step1);
+        int dst2_idx   = mad24(y, dst2_step, dst2_offset + (x << 1) & (int)0xfffffffc);
+           
+        short2 dst0_data  = *((__global short2 *)((__global char *)mat_dst0 + dst0_idx));
+        short2 dst1_data  = *((__global short2 *)((__global char *)mat_dst1 + dst1_idx));
+        short2 dst2_data  = *((__global short2 *)((__global char *)mat_dst2 + dst2_idx));
+
+        short2 tmp_data0, tmp_data1, tmp_data2;
+
+        short src_data_0 = ((__global short *)((__global char *)mat_src + src_idx))[3 * x - 3];
+        short src_data_1 = ((__global short *)((__global char *)mat_src + src_idx))[3 * x - 2];
+        short src_data_2 = ((__global short *)((__global char *)mat_src + src_idx))[3 * x - 1];
+        short src_data_3 = ((__global short *)((__global char *)mat_src + src_idx))[3 * x + 0];
+        short src_data_4 = ((__global short *)((__global char *)mat_src + src_idx))[3 * x + 1];
+        short src_data_5 = ((__global short *)((__global char *)mat_src + src_idx))[3 * x + 2];
+        short src_data_6 = ((__global short *)((__global char *)mat_src + src_idx))[3 * x + 3];
+        short src_data_7 = ((__global short *)((__global char *)mat_src + src_idx))[3 * x + 4];
+        short src_data_8 = ((__global short *)((__global char *)mat_src + src_idx))[3 * x + 5];
+
+        tmp_data0 = (dst0_offset & 3) == 0 ? (short2)(src_data_3, src_data_6) : (short2)(src_data_0, src_data_3);
+        tmp_data1 = (dst1_offset & 3) == 0 ? (short2)(src_data_4, src_data_7) : (short2)(src_data_1, src_data_4);
+        tmp_data2 = (dst2_offset & 3) == 0 ? (short2)(src_data_5, src_data_8) : (short2)(src_data_2, src_data_5);
+
+        tmp_data0.x = ((dst0_idx + 0 >= dst0_start) && (dst0_idx + 0 < dst0_end)) ? tmp_data0.x : dst0_data.x;
+        tmp_data0.y = ((dst0_idx + 2 >= dst0_start) && (dst0_idx + 2 < dst0_end)) ? tmp_data0.y : dst0_data.y;
+
+        tmp_data1.x = ((dst1_idx + 0 >= dst1_start) && (dst1_idx + 0 < dst1_end)) ? tmp_data1.x : dst1_data.x;
+        tmp_data1.y = ((dst1_idx + 2 >= dst1_start) && (dst1_idx + 2 < dst1_end)) ? tmp_data1.y : dst1_data.y;
+
+        tmp_data2.x = ((dst2_idx + 0 >= dst2_start) && (dst2_idx + 0 < dst2_end)) ? tmp_data2.x : dst2_data.x;
+        tmp_data2.y = ((dst2_idx + 2 >= dst2_start) && (dst2_idx + 2 < dst2_end)) ? tmp_data2.y : dst2_data.y;
+
+        *((__global short2 *)((__global char *)mat_dst0 + dst0_idx)) = tmp_data0;
+        *((__global short2 *)((__global char *)mat_dst1 + dst1_idx)) = tmp_data1;
+        *((__global short2 *)((__global char *)mat_dst2 + dst2_idx)) = tmp_data2;
+    }
+}
+
+
+__kernel void split_vector_C2_D3 (__global short *mat_src,  int src_step,  int src_offset,
+                                  __global short *mat_dst0, int dst0_step, int dst0_offset,  
+                                  __global short *mat_dst1, int dst1_step, int dst1_offset, 
+                                  int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if((x  < cols) && (y < rows)) 
+    {
+        x = x << 1;
+
+        #define dst0_align ((dst0_offset & 3) << 1)
+        #define dst1_align ((dst1_offset & 3) << 1)
+        int src_idx_0  = mad24(y, src_step, src_offset - dst0_align + (x << 2)); 
+        int src_idx_1  = mad24(y, src_step, src_offset - dst1_align + (x << 2)); 
+
+        int dst0_start = mad24(y, dst0_step, dst0_offset); 
+        int dst0_end   = mad24(y, dst0_step, dst0_offset + dst_step1);
+        int dst0_idx   = mad24(y, dst0_step, dst0_offset + (x << 1) & (int)0xfffffffc);
+
+        int dst1_start = mad24(y, dst1_step, dst1_offset); 
+        int dst1_end   = mad24(y, dst1_step, dst1_offset + dst_step1);
+        int dst1_idx   = mad24(y, dst1_step, dst1_offset + (x << 1) & (int)0xfffffffc);
+           
+        short4 src_data_0 = vload4(0, (__global short *)((__global char *)mat_src + src_idx_0));
+        short4 src_data_1 = vload4(0, (__global short *)((__global char *)mat_src + src_idx_1));
+
+        short2 dst0_data  = *((__global short2 *)((__global char *)mat_dst0 + dst0_idx));
+        short2 dst1_data  = *((__global short2 *)((__global char *)mat_dst1 + dst1_idx));
+
+        short2 tmp_data0, tmp_data1;
+
+        tmp_data0.x = ((dst0_idx + 0 >= dst0_start) && (dst0_idx + 0 < dst0_end)) ? src_data_0.x : dst0_data.x;
+        tmp_data0.y = ((dst0_idx + 2 >= dst0_start) && (dst0_idx + 2 < dst0_end)) ? src_data_0.z : dst0_data.y;
+
+        tmp_data1.x = ((dst1_idx + 0 >= dst1_start) && (dst1_idx + 0 < dst1_end)) ? src_data_1.y : dst1_data.x;
+        tmp_data1.y = ((dst1_idx + 2 >= dst1_start) && (dst1_idx + 2 < dst1_end)) ? src_data_1.w : dst1_data.y;
+
+        *((global short2 *)((__global char *)mat_dst0 + dst0_idx)) = tmp_data0;
+        *((global short2 *)((__global char *)mat_dst1 + dst1_idx)) = tmp_data1;
+    }
+}
+__kernel void split_vector_C4_D4 (__global int *mat_src,  int src_step,  int src_offset,
+                                  __global int *mat_dst0, int dst0_step, int dst0_offset,  
+                                  __global int *mat_dst1, int dst1_step, int dst1_offset, 
+                                       __global int *mat_dst2, int dst2_step, int dst2_offset,  
+                                  __global int *mat_dst3, int dst3_step, int dst3_offset,
+                                  int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if((x  < cols) && (y < rows)) 
+    {
+        int src_idx  = mad24(y, src_step,  src_offset); 
+        int dst0_idx = mad24(y, dst0_step, dst0_offset);
+        int dst1_idx = mad24(y, dst1_step, dst1_offset);
+        int dst2_idx = mad24(y, dst2_step, dst2_offset);
+        int dst3_idx = mad24(y, dst3_step, dst3_offset);
+           
+        int4 src_data = ((__global int4 *)((__global char *)mat_src + src_idx))[x];
+
+        ((__global int *)((__global char *)mat_dst0 + dst0_idx))[x] = src_data.x;
+        ((__global int *)((__global char *)mat_dst1 + dst1_idx))[x] = src_data.y;
+        ((__global int *)((__global char *)mat_dst2 + dst2_idx))[x] = src_data.z;
+        ((__global int *)((__global char *)mat_dst3 + dst3_idx))[x] = src_data.w;
+    }
+}
+__kernel void split_vector_C3_D4 (__global int *mat_src,  int src_step,  int src_offset,
+                                  __global int *mat_dst0, int dst0_step, int dst0_offset,  
+                                  __global int *mat_dst1, int dst1_step, int dst1_offset, 
+                                       __global int *mat_dst2, int dst2_step, int dst2_offset,  
+                                  int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if((x  < cols) && (y < rows)) 
+    {
+        int src_idx  = mad24(y, src_step,  src_offset); 
+        int dst0_idx = mad24(y, dst0_step, dst0_offset);
+        int dst1_idx = mad24(y, dst1_step, dst1_offset);
+        int dst2_idx = mad24(y, dst2_step, dst2_offset);
+
+        int src_data_0 = ((__global int *)((__global char *)mat_src + src_idx))[3 * x + 0];
+        int src_data_1 = ((__global int *)((__global char *)mat_src + src_idx))[3 * x + 1];
+        int src_data_2 = ((__global int *)((__global char *)mat_src + src_idx))[3 * x + 2];
+
+        ((__global int *)((__global char *)mat_dst0 + dst0_idx))[x] = src_data_0;
+        ((__global int *)((__global char *)mat_dst1 + dst1_idx))[x] = src_data_1;
+        ((__global int *)((__global char *)mat_dst2 + dst2_idx))[x] = src_data_2;
+    }
+}
+
+__kernel void split_vector_C2_D4 (__global int *mat_src,  int src_step,  int src_offset,
+                                  __global int *mat_dst0, int dst0_step, int dst0_offset,  
+                                  __global int *mat_dst1, int dst1_step, int dst1_offset, 
+                                  int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if((x  < cols) && (y < rows)) 
+    {
+        int src_idx  = mad24(y, src_step,  src_offset); 
+        int dst0_idx = mad24(y, dst0_step, dst0_offset);
+        int dst1_idx = mad24(y, dst1_step, dst1_offset);
+           
+        int2 src_data = ((__global int2 *)((__global char *)mat_src + src_idx))[x];
+
+        ((__global int *)((__global char *)mat_dst0 + dst0_idx))[x] = src_data.x;
+        ((__global int *)((__global char *)mat_dst1 + dst1_idx))[x] = src_data.y;
+    }
+}
+
+__kernel void split_vector_C4_D5 (__global float *mat_src,  int src_step,  int src_offset,
+                                  __global float *mat_dst0, int dst0_step, int dst0_offset,  
+                                  __global float *mat_dst1, int dst1_step, int dst1_offset, 
+                                       __global float *mat_dst2, int dst2_step, int dst2_offset,  
+                                  __global float *mat_dst3, int dst3_step, int dst3_offset,
+                                  int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if((x  < cols) && (y < rows)) 
+    {
+        int src_idx  = mad24(y, src_step,  src_offset); 
+        int dst0_idx = mad24(y, dst0_step, dst0_offset);
+        int dst1_idx = mad24(y, dst1_step, dst1_offset);
+        int dst2_idx = mad24(y, dst2_step, dst2_offset);
+        int dst3_idx = mad24(y, dst3_step, dst3_offset);
+           
+        float4 src_data = ((__global float4 *)((__global char *)mat_src + src_idx))[x];
+
+        ((__global float *)((__global char *)mat_dst0 + dst0_idx))[x] = src_data.x;
+        ((__global float *)((__global char *)mat_dst1 + dst1_idx))[x] = src_data.y;
+        ((__global float *)((__global char *)mat_dst2 + dst2_idx))[x] = src_data.z;
+        ((__global float *)((__global char *)mat_dst3 + dst3_idx))[x] = src_data.w;
+    }
+}
+
+__kernel void split_vector_C3_D5 (__global float *mat_src,  int src_step,  int src_offset,
+                                  __global float *mat_dst0, int dst0_step, int dst0_offset,  
+                                  __global float *mat_dst1, int dst1_step, int dst1_offset, 
+                                       __global float *mat_dst2, int dst2_step, int dst2_offset,  
+                                  int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if((x  < cols) && (y < rows)) 
+    {
+        int src_idx  = mad24(y, src_step,  src_offset); 
+        int dst0_idx = mad24(y, dst0_step, dst0_offset);
+        int dst1_idx = mad24(y, dst1_step, dst1_offset);
+        int dst2_idx = mad24(y, dst2_step, dst2_offset);
+
+        float src_data_0 = ((__global float *)((__global char *)mat_src + src_idx))[3 * x + 0];
+        float src_data_1 = ((__global float *)((__global char *)mat_src + src_idx))[3 * x + 1];
+        float src_data_2 = ((__global float *)((__global char *)mat_src + src_idx))[3 * x + 2];
+
+        ((__global float *)((__global char *)mat_dst0 + dst0_idx))[x] = src_data_0;
+        ((__global float *)((__global char *)mat_dst1 + dst1_idx))[x] = src_data_1;
+        ((__global float *)((__global char *)mat_dst2 + dst2_idx))[x] = src_data_2;
+    }
+}
+
+__kernel void split_vector_C2_D5 (__global float *mat_src,  int src_step,  int src_offset,
+                                  __global float *mat_dst0, int dst0_step, int dst0_offset,  
+                                  __global float *mat_dst1, int dst1_step, int dst1_offset, 
+                                  int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if((x  < cols) && (y < rows)) 
+    {
+        int src_idx  = mad24(y, src_step,  src_offset); 
+        int dst0_idx = mad24(y, dst0_step, dst0_offset);
+        int dst1_idx = mad24(y, dst1_step, dst1_offset);
+           
+        float2 src_data = ((__global float2 *)((__global char *)mat_src + src_idx))[x];
+
+        ((__global float *)((__global char *)mat_dst0 + dst0_idx))[x] = src_data.x;
+        ((__global float *)((__global char *)mat_dst1 + dst1_idx))[x] = src_data.y;
+    }
+}
+
+#if defined (DOUBLE_SUPPORT)
+__kernel void split_vector_C4_D6 (__global double *mat_src,  int src_step,  int src_offset,
+                                  __global double *mat_dst0, int dst0_step, int dst0_offset,  
+                                  __global double *mat_dst1, int dst1_step, int dst1_offset, 
+                                       __global double *mat_dst2, int dst2_step, int dst2_offset,  
+                                  __global double *mat_dst3, int dst3_step, int dst3_offset,
+                                  int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if((x  < cols) && (y < rows)) 
+    {
+        int src_idx  = mad24(y, src_step,  src_offset); 
+        int dst0_idx = mad24(y, dst0_step, dst0_offset);
+        int dst1_idx = mad24(y, dst1_step, dst1_offset);
+        int dst2_idx = mad24(y, dst2_step, dst2_offset);
+        int dst3_idx = mad24(y, dst3_step, dst3_offset);
+           
+        double4 src_data = ((__global double4 *)((__global char *)mat_src + src_idx))[x];
+
+        ((__global double *)((__global char *)mat_dst0 + dst0_idx))[x] = src_data.x;
+        ((__global double *)((__global char *)mat_dst1 + dst1_idx))[x] = src_data.y;
+        ((__global double *)((__global char *)mat_dst2 + dst2_idx))[x] = src_data.z;
+        ((__global double *)((__global char *)mat_dst3 + dst3_idx))[x] = src_data.w;
+    }
+}
+
+__kernel void split_vector_C3_D6 (__global double *mat_src,  int src_step,  int src_offset,
+                                  __global double *mat_dst0, int dst0_step, int dst0_offset,  
+                                  __global double *mat_dst1, int dst1_step, int dst1_offset, 
+                                       __global double *mat_dst2, int dst2_step, int dst2_offset,  
+                                  int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if((x  < cols) && (y < rows)) 
+    {
+        int src_idx  = mad24(y, src_step,  src_offset); 
+        int dst0_idx = mad24(y, dst0_step, dst0_offset);
+        int dst1_idx = mad24(y, dst1_step, dst1_offset);
+        int dst2_idx = mad24(y, dst2_step, dst2_offset);
+
+        double src_data_0 = ((__global double *)((__global char *)mat_src + src_idx))[3 * x + 0];
+        double src_data_1 = ((__global double *)((__global char *)mat_src + src_idx))[3 * x + 1];
+        double src_data_2 = ((__global double *)((__global char *)mat_src + src_idx))[3 * x + 2];
+
+        ((__global double *)((__global char *)mat_dst0 + dst0_idx))[x] = src_data_0;
+        ((__global double *)((__global char *)mat_dst1 + dst1_idx))[x] = src_data_1;
+        ((__global double *)((__global char *)mat_dst2 + dst2_idx))[x] = src_data_2;
+    }
+}
+
+__kernel void split_vector_C2_D6 (__global double *mat_src,  int src_step,  int src_offset,
+                                  __global double *mat_dst0, int dst0_step, int dst0_offset,  
+                                  __global double *mat_dst1, int dst1_step, int dst1_offset, 
+                                  int rows, int cols, int dst_step1)
+
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if((x  < cols) && (y < rows)) 
+    {
+        int src_idx  = mad24(y, src_step,  src_offset); 
+        int dst0_idx = mad24(y, dst0_step, dst0_offset);
+        int dst1_idx = mad24(y, dst1_step, dst1_offset);
+           
+        double2 src_data = ((__global double2 *)((__global char *)mat_src + src_idx))[x];
+
+        ((__global double *)((__global char *)mat_dst0 + dst0_idx))[x] = src_data.x;
+        ((__global double *)((__global char *)mat_dst1 + dst1_idx))[x] = src_data.y;
+    }
+}
+#endif
diff --git a/modules/ocl/src/kernels/stereobm.cl b/modules/ocl/src/kernels/stereobm.cl
new file mode 100644 (file)
index 0000000..026680f
--- /dev/null
@@ -0,0 +1,427 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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 ROWSperTHREAD 21     // the number of rows a thread will process
+#define BLOCK_W       128    // the thread block width (464)
+#define N_DISPARITIES 8
+
+#define STEREO_MIND 0                    // The minimum d range to check
+#define STEREO_DISP_STEP N_DISPARITIES   // the d step, must be <= 1 to avoid aliasing
+
+int SQ(int a)
+{
+    return a * a;
+}
+
+unsigned int CalcSSD(volatile __local unsigned int *col_ssd_cache, 
+                     volatile __local unsigned int *col_ssd, int radius)
+{      
+    unsigned int cache = 0;
+    unsigned int cache2 = 0;
+
+    for(int i = 1; i <= radius; i++)
+        cache += col_ssd[i];
+
+    col_ssd_cache[0] = cache;
+
+    barrier(CLK_LOCAL_MEM_FENCE);
+
+    if (get_local_id(0) < BLOCK_W - radius)
+        cache2 = col_ssd_cache[radius];
+    else
+        for(int i = radius + 1; i < (2 * radius + 1); i++)
+            cache2 += col_ssd[i];
+
+    return col_ssd[0] + cache + cache2;
+}
+
+uint2 MinSSD(volatile __local unsigned int *col_ssd_cache, 
+             volatile __local unsigned int *col_ssd, int radius)
+{
+    unsigned int ssd[N_DISPARITIES];
+
+    //See above:  #define COL_SSD_SIZE (BLOCK_W + 2 * radius)
+    ssd[0] = CalcSSD(col_ssd_cache, col_ssd + 0 * (BLOCK_W + 2 * radius), radius);
+    barrier(CLK_LOCAL_MEM_FENCE);
+    ssd[1] = CalcSSD(col_ssd_cache, col_ssd + 1 * (BLOCK_W + 2 * radius), radius);
+    barrier(CLK_LOCAL_MEM_FENCE);
+    ssd[2] = CalcSSD(col_ssd_cache, col_ssd + 2 * (BLOCK_W + 2 * radius), radius);
+    barrier(CLK_LOCAL_MEM_FENCE);
+    ssd[3] = CalcSSD(col_ssd_cache, col_ssd + 3 * (BLOCK_W + 2 * radius), radius);
+    barrier(CLK_LOCAL_MEM_FENCE);
+    ssd[4] = CalcSSD(col_ssd_cache, col_ssd + 4 * (BLOCK_W + 2 * radius), radius);
+    barrier(CLK_LOCAL_MEM_FENCE);
+    ssd[5] = CalcSSD(col_ssd_cache, col_ssd + 5 * (BLOCK_W + 2 * radius), radius);
+    barrier(CLK_LOCAL_MEM_FENCE);
+    ssd[6] = CalcSSD(col_ssd_cache, col_ssd + 6 * (BLOCK_W + 2 * radius), radius);
+    barrier(CLK_LOCAL_MEM_FENCE);
+    ssd[7] = CalcSSD(col_ssd_cache, col_ssd + 7 * (BLOCK_W + 2 * radius), radius);
+    barrier(CLK_LOCAL_MEM_FENCE);
+
+    unsigned int mssd = min(min(min(ssd[0], ssd[1]), min(ssd[4], ssd[5])), min(min(ssd[2], ssd[3]), min(ssd[6], ssd[7])));
+
+    int bestIdx = 0;
+    for (int i = 0; i < N_DISPARITIES; i++)
+    {
+        if (mssd == ssd[i])
+            bestIdx = i;
+    }
+
+    return (uint2)(mssd, bestIdx);
+}
+
+void StepDown(int idx1, int idx2, __global unsigned char* imageL, 
+              __global unsigned char* imageR, int d, volatile  __local unsigned int *col_ssd, int radius)
+{
+    unsigned char leftPixel1;
+    unsigned char leftPixel2;
+    unsigned char rightPixel1[8];
+    unsigned char rightPixel2[8];
+    unsigned int diff1, diff2;
+
+    leftPixel1 = imageL[idx1];
+    leftPixel2 = imageL[idx2];
+
+    idx1 = idx1 - d;
+    idx2 = idx2 - d;
+
+    rightPixel1[7] = imageR[idx1 - 7];
+    rightPixel1[0] = imageR[idx1 - 0];
+    rightPixel1[1] = imageR[idx1 - 1];
+    rightPixel1[2] = imageR[idx1 - 2];
+    rightPixel1[3] = imageR[idx1 - 3];
+    rightPixel1[4] = imageR[idx1 - 4];
+    rightPixel1[5] = imageR[idx1 - 5];
+    rightPixel1[6] = imageR[idx1 - 6];
+
+    rightPixel2[7] = imageR[idx2 - 7];
+    rightPixel2[0] = imageR[idx2 - 0];
+    rightPixel2[1] = imageR[idx2 - 1];
+    rightPixel2[2] = imageR[idx2 - 2];
+    rightPixel2[3] = imageR[idx2 - 3];
+    rightPixel2[4] = imageR[idx2 - 4];
+    rightPixel2[5] = imageR[idx2 - 5];
+    rightPixel2[6] = imageR[idx2 - 6];
+
+    //See above:  #define COL_SSD_SIZE (BLOCK_W + 2 * radius)
+    diff1 = leftPixel1 - rightPixel1[0];
+    diff2 = leftPixel2 - rightPixel2[0];
+    col_ssd[0 * (BLOCK_W + 2 * radius)] += SQ(diff2) - SQ(diff1);
+
+    diff1 = leftPixel1 - rightPixel1[1];
+    diff2 = leftPixel2 - rightPixel2[1];
+    col_ssd[1 * (BLOCK_W + 2 * radius)] += SQ(diff2) - SQ(diff1);
+
+    diff1 = leftPixel1 - rightPixel1[2];
+    diff2 = leftPixel2 - rightPixel2[2];
+    col_ssd[2 * (BLOCK_W + 2 * radius)] += SQ(diff2) - SQ(diff1);
+
+    diff1 = leftPixel1 - rightPixel1[3];
+    diff2 = leftPixel2 - rightPixel2[3];
+    col_ssd[3 * (BLOCK_W + 2 * radius)] += SQ(diff2) - SQ(diff1);
+
+    diff1 = leftPixel1 - rightPixel1[4];
+    diff2 = leftPixel2 - rightPixel2[4];
+    col_ssd[4 * (BLOCK_W + 2 * radius)] += SQ(diff2) - SQ(diff1);
+
+    diff1 = leftPixel1 - rightPixel1[5];
+    diff2 = leftPixel2 - rightPixel2[5];
+    col_ssd[5 * (BLOCK_W + 2 * radius)] += SQ(diff2) - SQ(diff1);
+
+    diff1 = leftPixel1 - rightPixel1[6];
+    diff2 = leftPixel2 - rightPixel2[6];
+    col_ssd[6 * (BLOCK_W + 2 * radius)] += SQ(diff2) - SQ(diff1);
+
+    diff1 = leftPixel1 - rightPixel1[7];
+    diff2 = leftPixel2 - rightPixel2[7];
+    col_ssd[7 * (BLOCK_W + 2 * radius)] += SQ(diff2) - SQ(diff1);
+}
+
+void InitColSSD(int x_tex, int y_tex, int im_pitch, __global unsigned char* imageL, 
+                __global unsigned char* imageR, int d, 
+                volatile __local unsigned int *col_ssd, int radius)
+{
+    unsigned char leftPixel1;
+    int idx;
+    unsigned int diffa[] = {0, 0, 0, 0, 0, 0, 0, 0};
+
+    for(int i = 0; i < (2 * radius + 1); i++)
+    {
+        idx = y_tex * im_pitch + x_tex;
+        leftPixel1 = imageL[idx];
+        idx = idx - d;
+
+        diffa[0] += SQ(leftPixel1 - imageR[idx - 0]);
+        diffa[1] += SQ(leftPixel1 - imageR[idx - 1]);
+        diffa[2] += SQ(leftPixel1 - imageR[idx - 2]);
+        diffa[3] += SQ(leftPixel1 - imageR[idx - 3]);
+        diffa[4] += SQ(leftPixel1 - imageR[idx - 4]);
+        diffa[5] += SQ(leftPixel1 - imageR[idx - 5]);
+        diffa[6] += SQ(leftPixel1 - imageR[idx - 6]);
+        diffa[7] += SQ(leftPixel1 - imageR[idx - 7]);
+
+        y_tex += 1;
+    }
+    //See above:  #define COL_SSD_SIZE (BLOCK_W + 2 * radius)
+    col_ssd[0 * (BLOCK_W + 2 * radius)] = diffa[0];
+    col_ssd[1 * (BLOCK_W + 2 * radius)] = diffa[1];
+    col_ssd[2 * (BLOCK_W + 2 * radius)] = diffa[2];
+    col_ssd[3 * (BLOCK_W + 2 * radius)] = diffa[3];
+    col_ssd[4 * (BLOCK_W + 2 * radius)] = diffa[4];
+    col_ssd[5 * (BLOCK_W + 2 * radius)] = diffa[5];
+    col_ssd[6 * (BLOCK_W + 2 * radius)] = diffa[6];
+    col_ssd[7 * (BLOCK_W + 2 * radius)] = diffa[7];
+}
+
+__kernel void stereoKernel(__global unsigned char *left, __global unsigned char *right,  
+                           __global unsigned int *cminSSDImage, int cminSSD_step,
+                           __global unsigned char *disp, int disp_step,int cwidth, int cheight,
+                           int img_step, int maxdisp, int radius,  
+                           __local unsigned int *col_ssd_cache)
+{
+
+    volatile __local unsigned int *col_ssd = col_ssd_cache + BLOCK_W + get_local_id(0);
+    volatile __local unsigned int *col_ssd_extra = get_local_id(0) < (2 * radius) ? col_ssd + BLOCK_W : 0;  
+
+    int X = get_group_id(0) * BLOCK_W + get_local_id(0) + maxdisp + radius;
+   // int Y = get_group_id(1) * ROWSperTHREAD + radius;
+
+    #define Y (get_group_id(1) * ROWSperTHREAD + radius)
+
+    volatile __global unsigned int* minSSDImage = cminSSDImage + X + Y * cminSSD_step;
+    __global unsigned char* disparImage = disp + X + Y * disp_step;
+
+    int end_row = ROWSperTHREAD < (cheight - Y) ? ROWSperTHREAD:(cheight - Y);
+    int y_tex;
+    int x_tex = X - radius;
+
+    if (x_tex >= cwidth)
+        return;
+
+    for(int d = STEREO_MIND; d < maxdisp; d += STEREO_DISP_STEP)
+    {
+        y_tex = Y - radius;
+
+        InitColSSD(x_tex, y_tex, img_step, left, right, d, col_ssd, radius);
+        if (col_ssd_extra > 0)
+            if (x_tex + BLOCK_W < cwidth)
+                InitColSSD(x_tex + BLOCK_W, y_tex, img_step, left, right, d, col_ssd_extra, radius);
+
+        barrier(CLK_LOCAL_MEM_FENCE); //before MinSSD function
+
+        if (X < cwidth - radius && Y < cheight - radius)
+        {
+            uint2 minSSD = MinSSD(col_ssd_cache + get_local_id(0), col_ssd, radius);
+            if (minSSD.x < minSSDImage[0])
+            {
+                disparImage[0] = (unsigned char)(d + minSSD.y);
+                minSSDImage[0] = minSSD.x;
+            }
+        }
+
+        for(int row = 1; row < end_row; row++)
+        {
+            int idx1 = y_tex * img_step + x_tex;
+            int idx2 = (y_tex + (2 * radius + 1)) * img_step + x_tex;
+
+            barrier(CLK_GLOBAL_MEM_FENCE); 
+            barrier(CLK_LOCAL_MEM_FENCE); 
+
+            StepDown(idx1, idx2, left, right, d, col_ssd, radius);
+            if (col_ssd_extra > 0)
+                if (x_tex + BLOCK_W < cwidth)
+                    StepDown(idx1, idx2, left + BLOCK_W, right + BLOCK_W, d, col_ssd_extra, radius);
+
+            y_tex += 1;
+
+            barrier(CLK_LOCAL_MEM_FENCE); 
+
+            if (X < cwidth - radius && row < cheight - radius - Y)
+            {
+                int idx = row * cminSSD_step;
+                uint2 minSSD = MinSSD(col_ssd_cache + get_local_id(0), col_ssd, radius);
+                if (minSSD.x < minSSDImage[idx])
+                {
+                    disparImage[disp_step * row] = (unsigned char)(d + minSSD.y);
+                    minSSDImage[idx] = minSSD.x;
+                }
+            }
+        } // for row loop
+    } // for d loop
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Sobel Prefiler (signal channel)//////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+__kernel void prefilter_xsobel(__global unsigned char *input, __global unsigned char *output, 
+                               int rows, int cols, int prefilterCap)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if(x < cols && y < rows)
+    {
+        int cov = input[(y-1) * cols + (x-1)] * (-1) + input[(y-1) * cols + (x+1)] * (1) + 
+                  input[(y)   * cols + (x-1)] * (-2) + input[(y)   * cols + (x+1)] * (2) +
+                  input[(y+1) * cols + (x-1)] * (-1) + input[(y+1) * cols + (x+1)] * (1);
+
+        cov = min(min(max(-prefilterCap, cov), prefilterCap) + prefilterCap, 255);
+        output[y * cols + x] = cov & 0xFF;
+    }
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////// Textureness filtering ////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+float sobel(__global unsigned char *input, int x, int y, int rows, int cols)
+{
+    float conv = 0;
+    int y1 = y==0? 0 : y-1;
+    int x1 = x==0? 0 : x-1;
+    if(x < cols && y < rows)
+    {
+        conv = (float)input[(y1)  * cols + (x1)] * (-1) + (float)input[(y1)  * cols + (x+1)] * (1) + 
+               (float)input[(y)   * cols + (x1)] * (-2) + (float)input[(y)   * cols + (x+1)] * (2) +
+               (float)input[(y+1) * cols + (x1)] * (-1) + (float)input[(y+1) * cols + (x+1)] * (1);
+    
+    }
+    return fabs(conv);
+}
+
+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);
+
+    for(int i = 1; i <= winsz2; 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;
+}
+
+#define RpT (2 * ROWSperTHREAD)  // got experimentally
+__kernel void textureness_kernel(__global unsigned char *disp, int disp_rows, int disp_cols, 
+                                 int disp_step, __global unsigned char *input, int input_rows, 
+                                 int input_cols,int winsz, float threshold, 
+                                 __local float *cols_cache)
+{
+    int winsz2 = winsz/2;
+    int n_dirty_pixels = (winsz2) * 2;
+
+    int local_id_x = get_local_id(0);
+    int group_size_x = get_local_size(0);
+    int group_id_y = get_group_id(1);
+
+    __local float *cols = cols_cache + group_size_x + local_id_x;
+    __local float *cols_extra = local_id_x < n_dirty_pixels ? cols + group_size_x : 0;
+
+    int x = get_global_id(0);
+    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;
+        float sum_extra = 0;
+
+        for(int i = y - winsz2; i <= y + winsz2; ++i)
+        {
+            sum += sobel(input, x - winsz2, i, input_rows, input_cols);
+            if (cols_extra)
+                sum_extra += sobel(input, x + group_size_x - winsz2, i, input_rows, input_cols);
+        }
+        *cols = sum;
+        if (cols_extra)
+            *cols_extra = sum_extra;
+
+        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;
+
+        barrier(CLK_LOCAL_MEM_FENCE);
+
+        for(int y = beg_row + 1; y < end_row; ++y)
+        {
+            sum = sum - sobel(input, x - winsz2, y - winsz2 - 1, input_rows, input_cols) + 
+                  sobel(input, x - winsz2, y + winsz2, input_rows, input_cols);
+            *cols = sum;
+
+            if (cols_extra)
+            {
+                sum_extra = sum_extra - sobel(input, x + group_size_x - winsz2, y - winsz2 - 1,input_rows, input_cols) 
+                            + sobel(input, x + group_size_x - winsz2, y + winsz2, input_rows, input_cols);
+                *cols_extra = sum_extra;
+            }
+
+            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;
+
+            barrier(CLK_LOCAL_MEM_FENCE);
+        }
+    }
+}
diff --git a/modules/ocl/src/kernels/stereobp.cl b/modules/ocl/src/kernels/stereobp.cl
new file mode 100644 (file)
index 0000000..9118e50
--- /dev/null
@@ -0,0 +1,580 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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
+// 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*/
+
+#if defined (__ATI__)
+#pragma OPENCL EXTENSION cl_amd_fp64:enable
+#elif defined (__NVIDIA__)
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+///////////////////////////////////////////////////////////////
+/////////////////common///////////////////////////////////////
+/////////////////////////////////////////////////////////////
+short round_short(float v){
+    return convert_short_sat_rte(v); 
+}
+#define FLOAT_MAX 3.402823466e+38f
+typedef struct
+{
+    int   cndisp;
+    float cmax_data_term;
+    float cdata_weight;
+    float cmax_disc_term;
+    float cdisc_single_jump;
+}con_srtuct_t;
+///////////////////////////////////////////////////////////////
+////////////////////////// comp data //////////////////////////
+///////////////////////////////////////////////////////////////
+
+float pix_diff_1(__global const uchar *ls, __global const uchar *rs)
+{
+    return abs((int)(*ls) - *rs); 
+}
+
+float pix_diff_3(__global const uchar *ls, __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);
+    r = *((__global uchar4 *)rs);
+
+    const float tr = 0.299f;
+    const float tg = 0.587f;
+    const float tb = 0.114f;
+
+    float val;
+             
+    val  = tb * abs((int)l.x - r.x);
+    val += tg * abs((int)l.y - r.y);
+    val += tr * abs((int)l.z - r.z);
+
+    return val;
+}
+
+__kernel void comp_data_0(__global uchar *left,  int left_rows,  int left_cols,  int left_step,
+                          __global uchar *right, int right_step,
+                          __global short  *data, int data_cols,  int data_step,
+                          __constant con_srtuct_t *con_st, int cn)
+                        //  int cndisp, float cmax_data_term, float cdata_weight, int cn)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (y > 0 && y < (left_rows - 1) && x > 0 && x < (left_cols - 1))
+    {
+        const __global uchar* ls = left  + y * left_step  + x * cn;
+        const __global uchar* rs = right + y * right_step + x * cn;
+
+        __global short *ds = (__global short *)((__global uchar *)data + y * data_step) + x;
+
+        const unsigned int disp_step = data_cols * left_rows ;
+
+        for (int disp = 0; disp < con_st -> cndisp; disp++)
+        {
+            if (x - disp >= 1)
+            {
+                float val = 0;
+                if(cn == 1)
+                    val = pix_diff_1(ls, rs - disp * cn);
+                if(cn == 3)
+                    val = pix_diff_3(ls, rs - disp * cn);
+                if(cn == 4)
+                    val = pix_diff_4(ls, rs - disp *cn);
+
+                ds[disp * disp_step] =  round_short(fmin(con_st -> cdata_weight * val, 
+                                                         con_st -> cdata_weight * con_st -> cmax_data_term));
+            }
+            else
+            {
+                ds[disp * disp_step] =  round_short(con_st -> cdata_weight * con_st -> cmax_data_term);
+            }
+        }
+    }
+}
+
+__kernel void comp_data_1(__global uchar *left,  int left_rows,  int left_cols,  int left_step,
+                          __global uchar *right, int right_step,
+                          __global float *data,  int data_cols,  int data_step,
+                          __constant con_srtuct_t *con_st, int cn)
+                          //int cndisp, float cmax_data_term, float cdata_weight, int cn)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (y > 0 && y < left_rows - 1 && x > 0 && x < left_cols - 1)
+    {
+        const __global uchar* ls = left  + y * left_step  + x * cn;
+        const __global uchar* rs = right + y * right_step + x * cn;
+
+        __global float *ds = (__global float *)((__global char *)data + y * data_step) + x;
+
+        const unsigned int disp_step = data_cols * left_rows;
+
+        for (int disp = 0; disp < con_st -> cndisp; disp++)
+        {
+            if (x - disp >= 1)
+            {
+                float val = 0;
+                if(cn == 1)
+                    val = pix_diff_1(ls, rs - disp * cn);
+                if(cn == 3)
+                    val = pix_diff_3(ls, rs - disp * cn);
+                if(cn == 4)
+                    val = pix_diff_4(ls, rs - disp *cn);
+
+                ds[disp * disp_step] = fmin(con_st -> cdata_weight * val, 
+                                            con_st -> cdata_weight * con_st -> cmax_data_term);
+            }
+            else
+            {
+                ds[disp * disp_step] = con_st -> cdata_weight * con_st -> cmax_data_term;
+            }
+        }
+    }
+}
+
+///////////////////////////////////////////////////////////////
+//////////////////////// data step down ///////////////////////
+///////////////////////////////////////////////////////////////
+__kernel void data_step_down_0(__global short *src, int src_rows, int src_cols, 
+                               __global short *dst, int dst_rows, int dst_cols, int dst_real_cols, 
+                               int cndisp)
+{
+    const int x = get_global_id(0);
+    const int y = get_global_id(1);;
+   
+    if (x < dst_cols && y < dst_rows)
+    {
+        for (int d = 0; d < cndisp; ++d)
+        {
+            //float dst_reg  = src.ptr(d * src_rows + (2*y+0))[(2*x+0)];
+            float dst_reg;
+            dst_reg  = src[(d * src_rows + (2*y+0)) * src_cols + 2*x+0];
+            dst_reg += src[(d * src_rows + (2*y+1)) * src_cols + 2*x+0];
+            dst_reg += src[(d * src_rows + (2*y+0)) * src_cols + 2*x+1];
+            dst_reg += src[(d * src_rows + (2*y+1)) * src_cols + 2*x+1];
+              
+            //dst.ptr(d * dst_rows + y)[x] = saturate_cast<T>(dst_reg);
+            dst[(d * dst_rows + y) * dst_real_cols + x] = round_short(dst_reg);
+        }
+    }
+}
+__kernel void data_step_down_1(__global float *src, int src_rows, int src_cols,
+                               __global float *dst, int dst_rows, int dst_cols, int dst_real_cols, 
+                               int cndisp)
+{
+    const int x = get_global_id(0);
+    const int y = get_global_id(1);;
+   
+    if (x < dst_cols && y < dst_rows)
+    {
+        for (int d = 0; d < cndisp; ++d)
+        {
+            //float dst_reg  = src.ptr(d * src_rows + (2*y+0))[(2*x+0)];
+            float dst_reg;
+            dst_reg = src[(d * src_rows + (2*y+0)) * src_cols + 2*x+0];
+            dst_reg += src[(d * src_rows + (2*y+1)) * src_cols + 2*x+0];
+            dst_reg += src[(d * src_rows + (2*y+0)) * src_cols + 2*x+1];
+            dst_reg += src[(d * src_rows + (2*y+1)) * src_cols + 2*x+1];
+              
+            //dst.ptr(d * dst_rows + y)[x] = saturate_cast<T>(dst_reg);
+            dst[(d * dst_rows + y) * dst_real_cols + x] = round_short(dst_reg);
+        }
+    }
+}
+
+///////////////////////////////////////////////////////////////
+/////////////////// level up messages  ////////////////////////
+///////////////////////////////////////////////////////////////
+__kernel void level_up_message_0(__global short *src, int src_rows, int src_step,
+                                 __global short *dst, int dst_rows, int dst_cols, int dst_step,
+                                 int cndisp)
+    
+{
+    const int x = get_global_id(0);
+    const int y = get_global_id(1);
+    
+    if (x < dst_cols && y < dst_rows)
+    {
+        const int dst_disp_step = (dst_step / sizeof(short)) * dst_rows;
+        const int src_disp_step = (src_step / sizeof(short)) * src_rows;
+       
+        __global short        *dstr = (__global short *)((__global char *)dst + y   * dst_step) + x;
+        __global const short  *srcr = (__global short *)((__global char *)src + y/2 * src_step) + x/2;
+       
+        for (int d = 0; d < cndisp; ++d)
+            dstr[d * dst_disp_step] = srcr[d * src_disp_step];
+    }
+}
+__kernel void level_up_message_1(__global float *src, int src_rows, int src_step,
+                                 __global float *dst, int dst_rows, int dst_cols, int dst_step,
+                                 int cndisp)
+    
+{
+    const int x = get_global_id(0);
+    const int y = get_global_id(1);
+    
+    if (x < dst_cols && y < dst_rows)
+    {
+        const int dst_disp_step = (dst_step/sizeof(float)) * dst_rows;
+        const int src_disp_step = (src_step/sizeof(float)) * src_rows;
+       
+        __global float       *dstr = (__global float *)((__global char *)dst + y   * dst_step) + x;
+        __global const float *srcr = (__global float *)((__global char *)src + y/2 * src_step) + x/2;
+       
+        for (int d = 0; d < cndisp; ++d)
+            dstr[d * dst_disp_step] = srcr[d * src_disp_step];
+    }
+}
+
+///////////////////////////////////////////////////////////////
+////////////////////  calc all iterations /////////////////////
+///////////////////////////////////////////////////////////////
+void calc_min_linear_penalty_0(__global short * dst, int disp_step, 
+                               int cndisp, float cdisc_single_jump)
+{
+    float prev = dst[0];
+    float cur;
+
+    for (int disp = 1; disp < cndisp; ++disp)
+    {
+        prev += cdisc_single_jump;
+        cur = dst[disp_step * disp];
+
+        if (prev < cur)
+        {
+            cur = prev;
+            dst[disp_step * disp] = round_short(prev);
+        }
+            
+        prev = cur;
+    }
+        
+    prev = dst[(cndisp - 1) * disp_step];
+    for (int disp = cndisp - 2; disp >= 0; disp--)
+    {
+        prev += cdisc_single_jump;
+        cur = dst[disp_step * disp];
+       
+        if (prev < cur)
+        {
+             cur = prev;
+             dst[disp_step * disp] = round_short(prev);
+        }
+        prev = cur;
+    }
+}
+void message_0(const __global short *msg1, const __global short *msg2,
+               const __global short *msg3, const __global short *data, __global short *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)
+    {
+        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;
+           
+        dst[msg_disp_step * i] = round_short(dst_reg);
+    }
+       
+    calc_min_linear_penalty_0(dst, msg_disp_step, cndisp, cdisc_single_jump);
+        
+    minimum += cmax_disc_term;
+
+    float sum = 0;
+    for(int i = 0; i < cndisp; ++i)
+    {
+        float dst_reg = dst[msg_disp_step * i];
+        if (dst_reg > minimum)
+        {
+            dst_reg = minimum;
+            dst[msg_disp_step * i] = round_short(minimum);
+        }
+        sum += dst_reg;
+    }
+    sum /= cndisp;
+        
+    for(int i = 0; i < cndisp; ++i)
+        dst[msg_disp_step * i] -= sum;
+}
+__kernel void one_iteration_0(__global short *u,    int u_step,    int u_cols,
+                              __global short *data, int data_step, int data_cols,
+                              __global short *d,    __global short *l, __global short *r,
+                              int t, int cols, int rows, 
+                              int cndisp, 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);
+    
+    if ((y > 0) && (y < rows - 1) && (x > 0) && (x < cols - 1))
+    {
+        __global short *us = (__global short *)((__global char *)u + y * u_step) + x;
+        __global short *ds = d + y * u_cols + x;
+        __global short *ls = l + y * u_cols + x;
+        __global short *rs = r + y * u_cols + x;
+        const __global  short *dt = (__global short *)((__global char *)data + y * data_step) + x;
+
+        int msg_disp_step = u_cols * rows;
+        int data_disp_step = data_cols * rows;
+
+        message_0(us + u_cols, ls      + 1, rs - 1, dt, us, msg_disp_step, data_disp_step, cndisp, 
+                cmax_disc_term, cdisc_single_jump);
+        message_0(ds - u_cols, ls      + 1, rs - 1, dt, ds, msg_disp_step, data_disp_step, cndisp,
+                cmax_disc_term, cdisc_single_jump);
+
+        message_0(us + u_cols, ds - u_cols, rs - 1, dt, rs, msg_disp_step, data_disp_step, cndisp,
+                cmax_disc_term, cdisc_single_jump);
+        message_0(us + u_cols, ds - u_cols, ls + 1, dt, ls, msg_disp_step, data_disp_step, cndisp,
+                cmax_disc_term, cdisc_single_jump);
+    }
+}
+void calc_min_linear_penalty_1(__global float * dst, int step, 
+                               int cndisp, float cdisc_single_jump)
+{
+    float prev = dst[0];
+    float cur;
+
+    for (int disp = 1; disp < cndisp; ++disp)
+    {
+        prev += cdisc_single_jump;
+        cur = dst[step * disp];
+
+        if (prev < cur)
+        {
+            cur = prev;
+            dst[step * disp] = prev;
+        }
+            
+        prev = cur;
+    }
+        
+    prev = dst[(cndisp - 1) * step];
+    for (int disp = cndisp - 2; disp >= 0; disp--)
+    {
+        prev += cdisc_single_jump;
+        cur = dst[step * disp];
+       
+        if (prev < cur)
+        {
+             cur = prev;
+             dst[step * disp] = prev;
+        }
+        prev = cur;
+    }
+}
+void message_1(const __global float *msg1, const __global float *msg2,
+               const __global float *msg3, const __global float *data, __global float *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)
+    {
+        float dst_reg = 0;
+        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;
+           
+        dst[msg_disp_step * i] = dst_reg;
+    }
+       
+    calc_min_linear_penalty_1(dst, msg_disp_step, cndisp, cdisc_single_jump);
+        
+    minimum += cmax_disc_term;
+
+    float sum = 0;
+    for(int i = 0; i < cndisp; ++i)
+    {
+        float dst_reg = dst[msg_disp_step * i];
+        if (dst_reg > minimum)
+        {
+            dst_reg = minimum;
+            dst[msg_disp_step * i] = minimum;
+        }
+        sum += dst_reg;
+    }
+    sum /= cndisp;
+        
+    for(int i = 0; i < cndisp; ++i)
+        dst[msg_disp_step * i] -= sum;
+}
+__kernel void one_iteration_1(__global float *u,    int u_step,    int u_cols,
+                              __global float *data, int data_step, int data_cols,
+                              __global float *d,    __global float *l, __global float *r,
+                              int t, int cols, int rows, 
+                              int cndisp,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);
+    
+    if ((y > 0) && (y < rows - 1) && (x > 0) && (x < cols - 1))
+    {
+        __global float* us = (__global float *)((__global char *)u + y * u_step) + x;
+        __global float* ds = d + y * u_cols + x;
+        __global float* ls = l + y * u_cols + x;
+        __global float* rs = r + y * u_cols + x;
+        const __global float* dt = (__global float *)((__global char *)data + y * data_step) + x;
+
+        int msg_disp_step = u_cols * rows;
+        int data_disp_step = data_cols * rows;
+
+        message_1(us + u_cols, ls      + 1, rs - 1, dt, us, msg_disp_step, data_disp_step, cndisp,
+                cmax_disc_term, cdisc_single_jump);
+        message_1(ds - u_cols, ls      + 1, rs - 1, dt, ds, msg_disp_step, data_disp_step, cndisp, 
+                cmax_disc_term, cdisc_single_jump);
+        message_1(us + u_cols, ds - u_cols, rs - 1, dt, rs, msg_disp_step, data_disp_step, cndisp,
+                cmax_disc_term, cdisc_single_jump);
+        message_1(us + u_cols, ds - u_cols, ls + 1, dt, ls, msg_disp_step, data_disp_step, cndisp,
+                cmax_disc_term, cdisc_single_jump);
+    }
+}
+
+///////////////////////////////////////////////////////////////
+/////////////////////////// output ////////////////////////////
+///////////////////////////////////////////////////////////////
+__kernel void output_0(const __global short *u, int u_step, int u_cols,
+                       const __global short *d, const __global short *l,
+                       const __global short *r, const __global short *data,
+                       __global short *disp, int disp_rows, int disp_cols, int disp_step,
+                       int cndisp)
+{
+    const int x = get_global_id(0);
+    const int y = get_global_id(1);
+   
+    if (y > 0 && y < disp_rows - 1 && x > 0 && x < disp_cols - 1)
+    {
+        const __global short *us =(__global short *)((__global char *)u + (y + 1) * u_step) + x;
+        const __global short *ds = d + (y - 1) * u_cols + x;
+        const __global short *ls = l + y * u_cols + (x + 1);
+        const __global short *rs = r + y * u_cols + (x - 1);
+        const __global short *dt = data + y * u_cols + x;
+       
+        int disp_steps = disp_rows * u_cols;
+
+        int best = 0;
+        float best_val = FLOAT_MAX;
+        for (int d = 0; d < cndisp; ++d)
+        {
+            float val;
+            val  = us[d * disp_steps];
+            val += ds[d * disp_steps];
+            val += ls[d * disp_steps];
+            val += rs[d * disp_steps];
+            val += dt[d * disp_steps];
+           
+            if (val < best_val)
+            {
+                best_val = val;
+                best = d;
+            }
+        }
+            
+        ((__global short *)((__global char *)disp + y * disp_step))[x] = convert_short_sat(best);
+    }
+}
+__kernel void output_1(const __global float *u, int u_step, int u_cols,
+                       const __global float *d, const __global float *l,
+                       const __global float *r, const __global float *data,
+                       __global short *disp, int disp_rows, int disp_cols, int disp_step,
+                       int cndisp)
+{
+    const int x = get_global_id(0);
+    const int y = get_global_id(1);
+   
+    if (y > 0 && y < disp_rows - 1 && x > 0 && x < disp_cols - 1)
+    {
+        const __global float *us =(__global float *)((__global char *)u + (y + 1) * u_step) + x;
+        const __global float *ds = d + (y - 1) * u_cols + x;
+        const __global float *ls = l + y * u_cols + (x + 1);
+        const __global float *rs = r + y * u_cols + (x - 1);
+        const __global float *dt = data + y * u_cols + x;
+       
+        int disp_steps = disp_rows * u_cols;
+       
+        int best = 0;
+        float best_val = FLOAT_MAX;
+        for (int d = 0; d < cndisp; ++d)
+        {
+            float val;
+            val  = us[d * disp_steps];
+            val += ds[d * disp_steps];
+            val += ls[d * disp_steps];
+            val += rs[d * disp_steps];
+            val += dt[d * disp_steps];
+           
+            if (val < best_val)
+            {
+                best_val = val;
+                best = d;
+            }
+        }
+            
+        //disp[y * disp_cols + x] = convert_short_sat(best);
+        ((__global short *)((__global char *)disp + y * disp_step))[x] = convert_short_sat(best);
+    }
+}
diff --git a/modules/ocl/src/kernels/stereocsbp.cl b/modules/ocl/src/kernels/stereocsbp.cl
new file mode 100644 (file)
index 0000000..cc81405
--- /dev/null
@@ -0,0 +1,1131 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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 FLT_MAX
+#define FLT_MAX  CL_FLT_MAX
+#endif
+
+#ifndef SHRT_MAX
+#define SHRT_MAX  CL_SHORT_MAX
+#endif
+
+    
+///////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////get_first_k_initial_global//////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void get_first_k_initial_global_0(__global short *data_cost_selected_, __global short *selected_disp_pyr,
+                                           __global short *ctemp, int h, int w, int nr_plane,
+                                           int cmsg_step1, int cdisp_step1, int cndisp)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (y < h && x < w)
+    {
+        __global short *selected_disparity = selected_disp_pyr      + y * cmsg_step1 + x;
+        __global short *data_cost_selected = data_cost_selected_    + y * cmsg_step1 + x;
+        __global short *data_cost          = ctemp + y * cmsg_step1 + x;
+
+        for(int i = 0; i < nr_plane; i++)
+        {
+            short minimum = SHRT_MAX;
+            int id = 0;
+           
+            for(int d = 0; d < cndisp; d++)
+            {
+                short cur = data_cost[d * cdisp_step1];
+                if(cur < minimum)
+                {
+                    minimum = cur;
+                    id = d;
+                }
+            }
+                
+            data_cost_selected[i  * cdisp_step1] = minimum;
+            selected_disparity[i  * cdisp_step1] = id;
+            data_cost         [id * cdisp_step1] = SHRT_MAX;
+        }
+    }
+}
+__kernel void get_first_k_initial_global_1(__global  float *data_cost_selected_, __global float *selected_disp_pyr,
+                                           __global  float *ctemp, int h, int w, int nr_plane,
+                                           int cmsg_step1, int cdisp_step1, int cndisp)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (y < h && x < w)
+    {
+        __global   float *selected_disparity = selected_disp_pyr      + y * cmsg_step1 + x;
+        __global   float *data_cost_selected = data_cost_selected_    + y * cmsg_step1 + x;
+        __global   float *data_cost          = ctemp + y * cmsg_step1 + x;
+
+        for(int i = 0; i < nr_plane; i++)
+        {
+            float minimum = FLT_MAX;
+            int id = 0;
+           
+            for(int d = 0; d < cndisp; d++)
+            {
+                float cur = data_cost[d * cdisp_step1];
+                if(cur < minimum)
+                {
+                    minimum = cur;
+                    id = d;
+                }
+            }
+                
+            data_cost_selected[i  * cdisp_step1] = minimum;
+            selected_disparity[i  * cdisp_step1] = id;
+            data_cost         [id * cdisp_step1] = FLT_MAX;
+        }
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////get_first_k_initial_local////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void get_first_k_initial_local_0(__global  short *data_cost_selected_, __global short *selected_disp_pyr, 
+                                          __global  short *ctemp,int h, int w, int nr_plane,
+                                          int cmsg_step1, int cdisp_step1, int cndisp)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (y < h && x < w)
+    {
+        __global short *selected_disparity = selected_disp_pyr   + y * cmsg_step1 + x;
+        __global short *data_cost_selected = data_cost_selected_ + y * cmsg_step1 + x;
+        __global short *data_cost = ctemp + y * cmsg_step1 + x;
+
+        int nr_local_minimum = 0;
+
+        short prev = data_cost[0 * cdisp_step1];
+        short cur  = data_cost[1 * cdisp_step1];
+        short next = data_cost[2 * cdisp_step1];
+            
+        for (int d = 1; d < cndisp - 1 && nr_local_minimum < nr_plane; d++)
+        {
+                
+            if (cur < prev && cur < next)
+            {
+                data_cost_selected[nr_local_minimum * cdisp_step1] = cur;
+                selected_disparity[nr_local_minimum * cdisp_step1] = d;
+                data_cost[d * cdisp_step1] = SHRT_MAX;
+
+                nr_local_minimum++;
+            }
+                
+            prev = cur;
+            cur = next;
+            next = data_cost[(d + 1) * cdisp_step1];
+        }
+
+        for (int i = nr_local_minimum; i < nr_plane; i++)
+        {
+            short minimum = SHRT_MAX;
+            int id = 0;
+                
+            for (int d = 0; d < cndisp; d++)
+            {
+                cur = data_cost[d * cdisp_step1];
+                if (cur < minimum)
+                {
+                    minimum = cur;
+                    id = d;
+                }
+            }
+                
+            data_cost_selected[i * cdisp_step1] = minimum;
+            selected_disparity[i * cdisp_step1] = id;
+            data_cost[id * cdisp_step1] = SHRT_MAX;
+        }
+    }
+}
+
+__kernel void get_first_k_initial_local_1(__global float *data_cost_selected_, __global float *selected_disp_pyr, 
+                                          __global float *ctemp,int h, int w, int nr_plane,
+                                          int cmsg_step1,  int cdisp_step1, int cndisp)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (y < h && x < w)
+    {
+        __global float *selected_disparity = selected_disp_pyr   + y * cmsg_step1 + x;
+        __global float *data_cost_selected = data_cost_selected_ + y * cmsg_step1 + x;
+        __global float *data_cost = ctemp + y * cmsg_step1 + x;
+
+        int nr_local_minimum = 0;
+
+        float prev = data_cost[0 * cdisp_step1];
+        float cur  = data_cost[1 * cdisp_step1];
+        float next = data_cost[2 * cdisp_step1];
+            
+        for (int d = 1; d < cndisp - 1 && nr_local_minimum < nr_plane; d++)
+        {
+            if (cur < prev && cur < next)
+            {
+                data_cost_selected[nr_local_minimum * cdisp_step1] = cur;
+                selected_disparity[nr_local_minimum * cdisp_step1] = d;
+                data_cost[d * cdisp_step1] = FLT_MAX ;
+
+                nr_local_minimum++;
+            }
+                
+            prev = cur;
+            cur = next;
+            next = data_cost[(d + 1) * cdisp_step1];
+        }
+        for (int i = nr_local_minimum; i < nr_plane; i++)
+        {
+            float minimum = FLT_MAX;
+            int id = 0;
+                
+            for (int d = 0; d < cndisp; d++)
+            {
+                cur = data_cost[d * cdisp_step1];
+                if (cur < minimum)
+                {
+                    minimum = cur;
+                    id = d;
+                }
+            }
+                
+            data_cost_selected[i * cdisp_step1] = minimum;
+            selected_disparity[i * cdisp_step1] = id;
+            data_cost[id * cdisp_step1] = FLT_MAX;
+        }
+    }
+}
+
+///////////////////////////////////////////////////////////////
+/////////////////////// init data cost ////////////////////////
+///////////////////////////////////////////////////////////////
+float compute_3(__global uchar* left, __global uchar* right,
+                 float cdata_weight,  float cmax_data_term)
+{
+    float tb = 0.114f * abs((int)left[0] - right[0]);
+    float tg = 0.587f * abs((int)left[1] - right[1]);
+    float tr = 0.299f * abs((int)left[2] - right[2]);
+   
+    return fmin(cdata_weight * (tr + tg + tb), cdata_weight * cmax_data_term);
+}
+float compute_1(__global uchar* left, __global uchar* right, 
+                 float cdata_weight,  float cmax_data_term)
+{
+    return fmin(cdata_weight * abs((int)*left - (int)*right), cdata_weight * cmax_data_term);
+}
+short round_short(float v){
+    return convert_short_sat_rte(v); 
+}
+///////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////init_data_cost///////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void init_data_cost_0(__global short *ctemp, __global uchar *cleft, __global uchar *cright, 
+                               int h, int w, int level, int channels,
+                               int cmsg_step1, float cdata_weight, float cmax_data_term, int cdisp_step1, 
+                               int cth, int cimg_step, int cndisp)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+   
+    if (y < h && x < w)
+    {
+        int y0 = y << level;
+        int yt = (y + 1) << level;
+       
+        int x0 = x << level;
+        int xt = (x + 1) << level;
+
+        __global short *data_cost = ctemp + y * cmsg_step1 + x;
+       
+        for(int d = 0; d < cndisp; ++d)
+        {
+            float val = 0.0f;
+            for(int yi = y0; yi < yt; yi++)
+            {
+                for(int xi = x0; xi < xt; xi++)
+                {
+                    int xr = xi - d;
+                    if(d < cth || xr < 0)
+                        val += cdata_weight * cmax_data_term;
+                    else
+                    {
+                        __global uchar *lle = cleft  + yi * cimg_step + xi * channels;
+                        __global uchar *lri = cright + yi * cimg_step + xr * channels;
+
+                        if(channels == 1)
+                            val += compute_1(lle, lri, cdata_weight, cmax_data_term);
+                        else
+                            val += compute_3(lle, lri, cdata_weight, cmax_data_term);
+                    }
+                }
+            }
+            data_cost[cdisp_step1 * d] = round_short(val);
+        }
+    }
+}
+__kernel void init_data_cost_1(__global float *ctemp, __global uchar *cleft, __global uchar *cright, 
+                               int h, int w, int level, int channels,
+                               int cmsg_step1, float cdata_weight, float cmax_data_term, int cdisp_step1, 
+                               int cth, int cimg_step, int cndisp)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+   
+    if (y < h && x < w)
+    {
+        int y0 = y << level;
+        int yt = (y + 1) << level;
+       
+        int x0 = x << level;
+        int xt = (x + 1) << level;
+
+        __global float *data_cost = ctemp + y * cmsg_step1 + x;
+       
+        for(int d = 0; d < cndisp; ++d)
+        {
+            float val = 0.0f;
+            for(int yi = y0; yi < yt; yi++)
+            {
+                for(int xi = x0; xi < xt; xi++)
+                {
+                    int xr = xi - d;
+                    if(d < cth || xr < 0)
+                        val += cdata_weight * cmax_data_term;
+                    else
+                    {
+                        __global uchar* lle = cleft  + yi * cimg_step + xi * channels;
+                        __global uchar* lri = cright + yi * cimg_step + xr * channels;
+
+                        if(channels == 1)
+                            val += compute_1(lle, lri, cdata_weight, cmax_data_term);
+                        else
+                            val += compute_3(lle, lri, cdata_weight, cmax_data_term);
+                    }
+                }
+            }
+            data_cost[cdisp_step1 * d] = val;
+        }
+    }
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////init_data_cost_reduce//////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void init_data_cost_reduce_0(__global short *ctemp, __global uchar *cleft, __global uchar *cright,
+                                      __local float *smem, int level, int rows, int cols, int h, int winsz, int channels,
+                                      int cndisp,int cimg_step, float cdata_weight, float cmax_data_term, int cth, 
+                                      int cdisp_step1, int cmsg_step1)
+{
+    int x_out = get_group_id(0);
+    int y_out = get_group_id(1) % h;
+    //int d = (blockIdx.y / h) * blockDim.z + threadIdx.z;
+    int d = (get_group_id(1) / h ) * get_local_size(2) + get_local_id(2); 
+
+    int tid = get_local_id(0);
+
+    if (d < cndisp)
+    {
+        int x0 = x_out << level;
+        int y0 = y_out << level;
+       
+        int len = min(y0 + winsz, rows) - y0;
+       
+        float val = 0.0f;
+        if (x0 + tid < cols)
+        {
+            if (x0 + tid - d < 0 || d < cth)
+                val = cdata_weight * cmax_data_term * len;
+            else
+            {
+                __global uchar* lle =  cleft + y0 * cimg_step + channels * (x0 + tid    );
+                __global uchar* lri = cright + y0 * cimg_step + channels * (x0 + tid - d);
+               
+                for(int y = 0; y < len; ++y)
+                {
+                    if(channels == 1)
+                        val += compute_1(lle, lri, cdata_weight, cmax_data_term);
+                    else
+                        val += compute_3(lle, lri, cdata_weight, cmax_data_term);
+
+                    lle += cimg_step;
+                    lri += cimg_step;
+                }
+            }
+        }
+       
+        __local float* dline = smem + winsz * get_local_id(2);
+       
+        dline[tid] = val;
+
+        barrier(CLK_LOCAL_MEM_FENCE);
+
+        if (winsz >= 256) { if (tid < 128) { dline[tid] += dline[tid + 128]; } barrier(CLK_LOCAL_MEM_FENCE); }
+        if (winsz >= 128) { if (tid <  64) { dline[tid] += dline[tid + 64]; }  barrier(CLK_LOCAL_MEM_FENCE); }
+
+                         __local volatile float* vdline = smem + winsz * get_local_id(2);
+
+        if (winsz >= 64) if (tid < 32) vdline[tid] += vdline[tid + 32];
+        if (winsz >= 32) if (tid < 16) vdline[tid] += vdline[tid + 16];
+        if (winsz >= 16) if (tid <  8) vdline[tid] += vdline[tid + 8];
+        if (winsz >=  8) if (tid <  4) vdline[tid] += vdline[tid + 4];
+        if (winsz >=  4) if (tid <  2) vdline[tid] += vdline[tid + 2];
+        if (winsz >=  2) if (tid <  1) vdline[tid] += vdline[tid + 1];
+
+        __global short* data_cost = ctemp + y_out * cmsg_step1 + x_out;
+
+        if (tid == 0)
+            data_cost[cdisp_step1 * d] = convert_short_sat_rte(dline[0]);
+    }
+}
+
+__kernel void init_data_cost_reduce_1(__global float *ctemp, __global uchar *cleft, __global uchar *cright,
+                                      __local float *smem, int level, int rows, int cols, int h, int winsz, int channels,
+                                      int cndisp,int cimg_step, float cdata_weight, float cmax_data_term, int cth,
+                                      int cdisp_step1, int cmsg_step1)
+{
+    int x_out = get_group_id(0);
+    int y_out = get_group_id(1) % h;
+    int d = (get_group_id(1) / h ) * get_local_size(2) + get_local_id(2); 
+
+    int tid = get_local_id(0);
+
+    if (d < cndisp)
+    {
+        int x0 = x_out << level;
+        int y0 = y_out << level;
+       
+        int len = min(y0 + winsz, rows) - y0;
+       
+        float val = 0.0f;
+
+        if (x0 + tid < cols)
+        {
+            if (x0 + tid - d < 0 || d < cth)
+                val = cdata_weight * cmax_data_term * len;
+            else
+            {
+                __global uchar* lle =  cleft + y0 * cimg_step + channels * (x0 + tid    );
+                __global uchar* lri = cright + y0 * cimg_step + channels * (x0 + tid - d);
+               
+                for(int y = 0; y < len; ++y)
+                {
+                    if(channels == 1)
+                        val += compute_1(lle, lri, cdata_weight, cmax_data_term);
+                    else
+                        val += compute_3(lle, lri, cdata_weight, cmax_data_term);
+
+                    lle += cimg_step;
+                    lri += cimg_step;
+                }
+            }
+        }
+       
+        __local float* dline = smem + winsz * get_local_id(2);
+       
+        dline[tid] = val;
+
+        barrier(CLK_LOCAL_MEM_FENCE);
+
+        if (winsz >= 256) { if (tid < 128) { dline[tid] += dline[tid + 128]; } barrier(CLK_LOCAL_MEM_FENCE); }
+        if (winsz >= 128) { if (tid <  64) { dline[tid] += dline[tid + 64]; }  barrier(CLK_LOCAL_MEM_FENCE); }
+
+                         __local volatile float* vdline = smem + winsz * get_local_id(2);
+
+        if (winsz >= 64) if (tid < 32) vdline[tid] += vdline[tid + 32];
+        if (winsz >= 32) if (tid < 16) vdline[tid] += vdline[tid + 16];
+        if (winsz >= 16) if (tid <  8) vdline[tid] += vdline[tid + 8];
+        if (winsz >=  8) if (tid <  4) vdline[tid] += vdline[tid + 4];
+        if (winsz >=  4) if (tid <  2) vdline[tid] += vdline[tid + 2];
+        if (winsz >=  2) if (tid <  1) vdline[tid] += vdline[tid + 1];
+
+        __global float *data_cost = ctemp + y_out * cmsg_step1 + x_out;
+
+        if (tid == 0)
+            data_cost[cdisp_step1 * d] =  dline[0];
+    }
+}
+
+///////////////////////////////////////////////////////////////
+////////////////////// compute data cost //////////////////////
+///////////////////////////////////////////////////////////////
+__kernel void compute_data_cost_0(__global const short *selected_disp_pyr, __global short *data_cost_, 
+                                __global uchar *cleft, __global uchar *cright,
+                                int h, int w, int level, int nr_plane, int channels,
+                                int cmsg_step1, int cmsg_step2, int cdisp_step1, int cdisp_step2, float cdata_weight, 
+                                float cmax_data_term, int cimg_step, int cth)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (y < h && x < w)
+    {
+        int y0 = y << level;
+        int yt = (y + 1) << level;
+       
+        int x0 = x << level;
+        int xt = (x + 1) << level;
+
+        __global const short *selected_disparity = selected_disp_pyr + y/2 * cmsg_step2 + x/2;
+        __global       short *data_cost          = data_cost_ + y * cmsg_step1 + x;
+
+        for(int d = 0; d < nr_plane; d++)
+        {
+            float val = 0.0f;
+            for(int yi = y0; yi < yt; yi++)
+            {
+                for(int xi = x0; xi < xt; xi++)
+                {
+                    int sel_disp = selected_disparity[d * cdisp_step2];
+                    int xr = xi - sel_disp;
+                        
+                    if (xr < 0 || sel_disp < cth)
+                        val += cdata_weight * cmax_data_term;
+                      
+                    else
+                    {
+                        __global uchar* left_x  = cleft + yi * cimg_step + xi * channels;
+                        __global uchar* right_x = cright + yi * cimg_step + xr * channels;
+
+                        if(channels == 1)
+                            val += compute_1(left_x, right_x, cdata_weight, cmax_data_term);
+                        else
+                            val += compute_3(left_x, right_x, cdata_weight, cmax_data_term);
+                    }
+                }
+            }
+            data_cost[cdisp_step1 * d] = convert_short_sat_rte(val);
+        }
+    }
+}
+__kernel void compute_data_cost_1(__global const float *selected_disp_pyr, __global float *data_cost_, 
+                                __global uchar *cleft, __global uchar *cright,
+                                int h, int w, int level, int nr_plane, int channels,
+                                int cmsg_step1, int cmsg_step2, int cdisp_step1, int cdisp_step2, float cdata_weight, 
+                                float cmax_data_term, int cimg_step, int cth)
+{
+
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+
+    if (y < h && x < w)
+    {
+        int y0 = y << level;
+        int yt = (y + 1) << level;
+       
+        int x0 = x << level;
+        int xt = (x + 1) << level;
+
+        __global const float *selected_disparity = selected_disp_pyr + y/2 * cmsg_step2 + x/2;
+        __global       float *data_cost          = data_cost_ + y * cmsg_step1 + x;
+
+        for(int d = 0; d < nr_plane; d++)
+        {
+            float val = 0.0f;
+            for(int yi = y0; yi < yt; yi++)
+            {
+                for(int xi = x0; xi < xt; xi++)
+                {
+                    int sel_disp = selected_disparity[d * cdisp_step2];
+                    int xr = xi - sel_disp;
+                        
+                    if (xr < 0 || sel_disp < cth)
+                        val += cdata_weight * cmax_data_term;
+                    else
+                    {
+                        __global uchar* left_x  = cleft + yi * cimg_step + xi * channels;
+                        __global uchar* right_x = cright + yi * cimg_step + xr * channels;
+
+                        if(channels == 1)
+                            val += compute_1(left_x, right_x, cdata_weight, cmax_data_term);
+                        else
+                            val += compute_3(left_x, right_x, cdata_weight, cmax_data_term);
+                    }
+                }
+            }
+            data_cost[cdisp_step1 * d] = val;
+        }
+    }
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////compute_data_cost_reduce//////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////
+__kernel void compute_data_cost_reduce_0(__global const short* selected_disp_pyr, __global short* data_cost_, 
+                                         __global uchar *cleft, __global uchar *cright,__local float *smem,
+                                         int level, int rows, int cols, int h, int nr_plane, 
+                                         int channels, int winsz,
+                                         int cmsg_step1, int cmsg_step2, int cdisp_step1, int cdisp_step2, 
+                                         float cdata_weight,  float cmax_data_term, int cimg_step,int cth)
+    
+{
+    int x_out = get_group_id(0);
+    int y_out = get_group_id(1) % h;
+    int d = (get_group_id(1)/ h) * get_local_size(2) + get_local_id(2);
+   
+    int tid = get_local_id(0);
+   
+    __global const short* selected_disparity = selected_disp_pyr + y_out/2 * cmsg_step2 + x_out/2;
+    __global short* data_cost = data_cost_ + y_out * cmsg_step1 + x_out;
+   
+    if (d < nr_plane)
+    {
+        int sel_disp = selected_disparity[d * cdisp_step2];
+       
+        int x0 = x_out << level;
+        int y0 = y_out << level;
+       
+        int len = min(y0 + winsz, rows) - y0;
+       
+        float val = 0.0f;
+        if (x0 + tid < cols)
+        {
+            if (x0 + tid - sel_disp < 0 || sel_disp < cth)
+                val = cdata_weight * cmax_data_term * len;
+            else
+            {
+                __global uchar* lle =  cleft + y0 * cimg_step + channels * (x0 + tid    );
+                __global uchar* lri = cright + y0 * cimg_step + channels * (x0 + tid - sel_disp);
+               
+                for(int y = 0; y < len; ++y)
+                {
+                    if(channels == 1)
+                        val += compute_1(lle, lri, cdata_weight, cmax_data_term);
+                    else
+                        val += compute_3(lle, lri, cdata_weight, cmax_data_term);
+
+                    lle += cimg_step;
+                    lri += cimg_step;
+                }
+            }
+         }
+        
+         __local float* dline = smem + winsz * get_local_id(2);
+
+         dline[tid] = val;
+      }
+
+      barrier(CLK_LOCAL_MEM_FENCE);
+      if(d < nr_plane)
+      {
+
+        // if (winsz >= 256) { if (tid < 128) { dline[tid] += dline[tid + 128]; } barrier(CLK_LOCAL_MEM_FENCE); }
+        //if (winsz >= 128) { if (tid <  64) { dline[tid] += dline[tid +  64]; } barrier(CLK_LOCAL_MEM_FENCE); }
+
+         __local volatile float* vdline = smem + winsz * get_local_id(2);
+
+         if (winsz >= 64) if (tid < 32) vdline[tid] += vdline[tid + 32];
+         if (winsz >= 32) if (tid < 16) vdline[tid] += vdline[tid + 16];
+         if (winsz >= 16) if (tid <  8) vdline[tid] += vdline[tid + 8];
+         if (winsz >=  8) if (tid <  4) vdline[tid] += vdline[tid + 4];
+         if (winsz >=  4) if (tid <  2) vdline[tid] += vdline[tid + 2];
+         if (winsz >=  2) if (tid <  1) vdline[tid] += vdline[tid + 1];
+
+         if (tid == 0)
+             data_cost[cdisp_step1 * d] = convert_short_sat_rte(vdline[0]);
+    }
+}
+
+__kernel void compute_data_cost_reduce_1(__global const float *selected_disp_pyr, __global float *data_cost_, 
+                                         __global uchar *cleft, __global uchar *cright, __local float *smem,
+                                         int level, int rows, int cols, int h, int nr_plane, 
+                                         int channels, int winsz,
+                                         int cmsg_step1, int cmsg_step2, int cdisp_step1,int cdisp_step2, float cdata_weight, 
+                                         float cmax_data_term, int cimg_step, int cth)
+    
+{
+    int x_out = get_group_id(0);
+    int y_out = get_group_id(1) % h;
+    int d = (get_group_id(1)/ h) * get_local_size(2) + get_local_id(2);
+   
+    int tid = get_local_id(0);
+   
+    __global const float *selected_disparity = selected_disp_pyr + y_out/2 * cmsg_step2 + x_out/2;
+    __global float *data_cost = data_cost_ + y_out * cmsg_step1 + x_out;
+   
+    if (d < nr_plane)
+    {
+        int sel_disp = selected_disparity[d * cdisp_step2];
+       
+        int x0 = x_out << level;
+        int y0 = y_out << level;
+       
+        int len = min(y0 + winsz, rows) - y0;
+       
+        float val = 0.0f;
+        if (x0 + tid < cols)
+        {
+            if (x0 + tid - sel_disp < 0 || sel_disp < cth)
+                val = cdata_weight * cmax_data_term * len;
+            else
+            {
+                __global uchar* lle =  cleft + y0 * cimg_step + channels * (x0 + tid    );
+                __global uchar* lri = cright + y0 * cimg_step + channels * (x0 + tid - sel_disp);
+               
+                for(int y = 0; y < len; ++y)
+                {
+                    if(channels == 1)
+                        val += compute_1(lle, lri, cdata_weight, cmax_data_term);
+                    else
+                        val += compute_3(lle, lri, cdata_weight, cmax_data_term);
+
+                    lle += cimg_step;
+                    lri += cimg_step;
+                }
+            }
+         }
+        
+         __local float* dline = smem + winsz * get_local_id(2);
+
+         dline[tid] = val;
+     }
+         
+     barrier(CLK_LOCAL_MEM_FENCE);
+     if(d < nr_plane)
+     {
+
+         //if (winsz >= 256) { if (tid < 128) { dline[tid] += dline[tid + 128]; } barrier(CLK_LOCAL_MEM_FENCE); }
+         //if (winsz >= 128) { if (tid <  64) { dline[tid] += dline[tid +  64]; } barrier(CLK_LOCAL_MEM_FENCE); }
+
+         __local volatile float* vdline = smem + winsz * get_local_id(2);
+
+         if (winsz >= 64) if (tid < 32) vdline[tid] += vdline[tid + 32];
+         if (winsz >= 32) if (tid < 16) vdline[tid] += vdline[tid + 16];
+         if (winsz >= 16) if (tid <  8) vdline[tid] += vdline[tid + 8];
+         if (winsz >=  8) if (tid <  4) vdline[tid] += vdline[tid + 4];
+         if (winsz >=  4) if (tid <  2) vdline[tid] += vdline[tid + 2];
+         if (winsz >=  2) if (tid <  1) vdline[tid] += vdline[tid + 1];
+
+         if (tid == 0)
+             data_cost[cdisp_step1 * d] = vdline[0];
+    }
+}
+
+///////////////////////////////////////////////////////////////
+//////////////////////// init message /////////////////////////
+///////////////////////////////////////////////////////////////
+void get_first_k_element_increase_0(__global short* u_new, __global short *d_new, __global short *l_new, 
+                                    __global short *r_new, __global const short *u_cur, __global const short *d_cur, 
+                                    __global const short *l_cur, __global const short *r_cur, 
+                                    __global short *data_cost_selected, __global short *disparity_selected_new, 
+                                    __global short *data_cost_new, __global const short* data_cost_cur, 
+                                    __global const short *disparity_selected_cur,
+                                    int nr_plane, int nr_plane2,
+                                    int cdisp_step1, int cdisp_step2)
+{
+    for(int i = 0; i < nr_plane; i++)
+    {
+        short minimum = SHRT_MAX;
+        int id = 0;
+        for(int j = 0; j < nr_plane2; j++)
+        {
+            short cur = data_cost_new[j * cdisp_step1];
+            if(cur < minimum)
+            {
+                minimum = cur;
+                id = j;
+            }
+        }
+
+        data_cost_selected[i * cdisp_step1] = data_cost_cur[id * cdisp_step1];
+        disparity_selected_new[i * cdisp_step1] = disparity_selected_cur[id * cdisp_step2];
+
+        u_new[i * cdisp_step1] = u_cur[id * cdisp_step2];
+        d_new[i * cdisp_step1] = d_cur[id * cdisp_step2];
+        l_new[i * cdisp_step1] = l_cur[id * cdisp_step2];
+        r_new[i * cdisp_step1] = r_cur[id * cdisp_step2];
+       
+        data_cost_new[id * cdisp_step1] = SHRT_MAX;
+    }
+}
+void get_first_k_element_increase_1(__global float *u_new, __global float *d_new, __global float *l_new, 
+                                    __global float *r_new, __global const float *u_cur, __global const float *d_cur, 
+                                    __global const float *l_cur, __global const float *r_cur,
+                                    __global float *data_cost_selected, __global float *disparity_selected_new, 
+                                    __global float *data_cost_new, __global const float *data_cost_cur, 
+                                    __global const float *disparity_selected_cur,
+                                    int nr_plane, int nr_plane2,
+                                    int cdisp_step1, int cdisp_step2)
+{
+    for(int i = 0; i < nr_plane; i++)
+    {
+        float minimum = FLT_MAX;
+        int id = 0;
+        for(int j = 0; j < nr_plane2; j++)
+        {
+            float cur = data_cost_new[j * cdisp_step1];
+            if(cur < minimum)
+            {
+                minimum = cur;
+                id = j;
+            }
+        }
+
+        data_cost_selected[i * cdisp_step1] = data_cost_cur[id * cdisp_step1];
+        disparity_selected_new[i * cdisp_step1] = disparity_selected_cur[id * cdisp_step2];
+
+        u_new[i * cdisp_step1] = u_cur[id * cdisp_step2];
+        d_new[i * cdisp_step1] = d_cur[id * cdisp_step2];
+        l_new[i * cdisp_step1] = l_cur[id * cdisp_step2];
+        r_new[i * cdisp_step1] = r_cur[id * cdisp_step2];
+       
+        data_cost_new[id * cdisp_step1] = FLT_MAX;
+    }
+}
+__kernel void init_message_0(__global short *u_new_, __global short *d_new_, __global short *l_new_,
+                             __global short *r_new_, __global  short *u_cur_, __global const short *d_cur_, 
+                             __global const short *l_cur_, __global const short *r_cur_, __global short *ctemp,
+                             __global short *selected_disp_pyr_new, __global const short *selected_disp_pyr_cur,
+                             __global short *data_cost_selected_, __global const short *data_cost_,
+                             int h, int w, int nr_plane, int h2, int w2, int nr_plane2,
+                             int cdisp_step1, int cdisp_step2, int cmsg_step1, int cmsg_step2)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+   
+    if (y < h && x < w)
+    {
+        __global const short *u_cur = u_cur_ + min(h2-1, y/2 + 1) * cmsg_step2 + x/2;
+        __global const short *d_cur = d_cur_ + max(0, y/2 - 1)    * cmsg_step2 + x/2;
+        __global const short *l_cur = l_cur_ + y/2                * cmsg_step2 + min(w2-1, x/2 + 1);
+        __global const short *r_cur = r_cur_ + y/2                * cmsg_step2 + max(0, x/2 - 1);
+
+        __global short *data_cost_new = ctemp + y * cmsg_step1 + x;
+       
+        __global const short *disparity_selected_cur = selected_disp_pyr_cur + y/2 * cmsg_step2 + x/2;
+        __global const short *data_cost = data_cost_ + y * cmsg_step1 + x;
+
+        for(int d = 0; d < nr_plane2; d++)
+        {
+            int idx2 = d * cdisp_step2;
+
+            short val  = data_cost[d * cdisp_step1] + u_cur[idx2] + d_cur[idx2] + l_cur[idx2] + r_cur[idx2];
+            data_cost_new[d * cdisp_step1] = val;
+        }
+
+        __global short *data_cost_selected = data_cost_selected_ + y * cmsg_step1 + x;
+        __global short *disparity_selected_new = selected_disp_pyr_new + y * cmsg_step1 + x;
+
+        __global short *u_new = u_new_ + y * cmsg_step1 + x;
+        __global short *d_new = d_new_ + y * cmsg_step1 + x;
+        __global short *l_new = l_new_ + y * cmsg_step1 + x;
+        __global short *r_new = r_new_ + y * cmsg_step1 + x;
+
+        u_cur = u_cur_ + y/2 * cmsg_step2 + x/2;
+        d_cur = d_cur_ + y/2 * cmsg_step2 + x/2;
+        l_cur = l_cur_ + y/2 * cmsg_step2 + x/2;
+        r_cur = r_cur_ + y/2 * cmsg_step2 + x/2;
+
+        get_first_k_element_increase_0(u_new, d_new, l_new, r_new, u_cur, d_cur, l_cur, r_cur,
+                                       data_cost_selected, disparity_selected_new, data_cost_new,
+                                       data_cost, disparity_selected_cur, nr_plane, nr_plane2,
+                                       cdisp_step1, cdisp_step2);
+    }
+}
+__kernel void init_message_1(__global float *u_new_, __global float *d_new_, __global float *l_new_,
+                             __global float *r_new_, __global float *u_cur_, __global const float *d_cur_, 
+                             __global const float *l_cur_, __global const float *r_cur_, __global float *ctemp,
+                             __global float *selected_disp_pyr_new, __global const float *selected_disp_pyr_cur,
+                             __global float *data_cost_selected_, __global const float *data_cost_,
+                             int h, int w, int nr_plane, int h2, int w2, int nr_plane2,
+                             int cdisp_step1, int cdisp_step2, int cmsg_step1, int cmsg_step2)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+   
+    if (y < h && x < w)
+    {
+        __global const float *u_cur = u_cur_ + min(h2-1, y/2 + 1) * cmsg_step2 + x/2;
+        __global const float *d_cur = d_cur_ + max(0, y/2 - 1)    * cmsg_step2 + x/2;
+        __global const float *l_cur = l_cur_ + y/2                * cmsg_step2 + min(w2-1, x/2 + 1);
+        __global const float *r_cur = r_cur_ + y/2                * cmsg_step2 + max(0, x/2 - 1);
+
+        __global float *data_cost_new = ctemp + y * cmsg_step1 + x;
+       
+        __global const float *disparity_selected_cur = selected_disp_pyr_cur + y/2 * cmsg_step2 + x/2;
+        __global const float *data_cost = data_cost_ + y * cmsg_step1 + x;
+
+        for(int d = 0; d < nr_plane2; d++)
+        {
+            int idx2 = d * cdisp_step2;
+
+            float val  = data_cost[d * cdisp_step1] + u_cur[idx2] + d_cur[idx2] + l_cur[idx2] + r_cur[idx2];
+            data_cost_new[d * cdisp_step1] = val;
+        }
+
+        __global float *data_cost_selected = data_cost_selected_ + y * cmsg_step1 + x;
+        __global float *disparity_selected_new = selected_disp_pyr_new + y * cmsg_step1 + x;
+
+        __global float *u_new = u_new_ + y * cmsg_step1 + x;
+        __global float *d_new = d_new_ + y * cmsg_step1 + x;
+        __global float *l_new = l_new_ + y * cmsg_step1 + x;
+        __global float *r_new = r_new_ + y * cmsg_step1 + x;
+
+        u_cur = u_cur_ + y/2 * cmsg_step2 + x/2;
+        d_cur = d_cur_ + y/2 * cmsg_step2 + x/2;
+        l_cur = l_cur_ + y/2 * cmsg_step2 + x/2;
+        r_cur = r_cur_ + y/2 * cmsg_step2 + x/2;
+
+        get_first_k_element_increase_1(u_new, d_new, l_new, r_new, u_cur, d_cur, l_cur, r_cur,
+                                       data_cost_selected, disparity_selected_new, data_cost_new,
+                                       data_cost, disparity_selected_cur, nr_plane, nr_plane2,
+                                       cdisp_step1, cdisp_step2);
+    }
+}
+///////////////////////////////////////////////////////////////
+////////////////////  calc all iterations /////////////////////
+///////////////////////////////////////////////////////////////
+void message_per_pixel_0(__global const short *data, __global short *msg_dst, __global const short *msg1, 
+                         __global const short *msg2, __global const short *msg3,
+                         __global const short *dst_disp, __global const short *src_disp, 
+                         int nr_plane, __global short *temp,
+                         float cmax_disc_term, int cdisp_step1, float cdisc_single_jump)
+{
+    short minimum = SHRT_MAX;
+    for(int d = 0; d < nr_plane; d++)     
+    {
+        int idx = d * cdisp_step1;
+        short val  = data[idx] + msg1[idx] + msg2[idx] + msg3[idx];
+       
+        if(val < minimum)
+            minimum = val;
+           
+        msg_dst[idx] = val;
+    }
+        
+    float sum = 0;
+    for(int d = 0; d < nr_plane; d++)
+    {
+        float cost_min = minimum + cmax_disc_term;
+        short src_disp_reg = src_disp[d * cdisp_step1];
+       
+        for(int d2 = 0; d2 < nr_plane; d2++)
+            cost_min = fmin(cost_min, (msg_dst[d2 * cdisp_step1] + 
+                                       cdisc_single_jump * abs(dst_disp[d2 * cdisp_step1] - src_disp_reg)));
+
+        temp[d * cdisp_step1] = convert_short_sat_rte(cost_min);
+        sum += cost_min;
+    }
+    sum /= nr_plane;
+
+    for(int d = 0; d < nr_plane; d++)
+        msg_dst[d * cdisp_step1] = convert_short_sat_rte(temp[d * cdisp_step1] - sum);
+}
+void message_per_pixel_1(__global const float *data, __global float *msg_dst, __global const float *msg1, 
+                         __global const float *msg2, __global const float *msg3,
+                         __global const float *dst_disp, __global const float *src_disp, 
+                         int nr_plane, __global float *temp,
+                         float cmax_disc_term, int cdisp_step1, float cdisc_single_jump)
+{
+    float minimum = FLT_MAX;
+    for(int d = 0; d < nr_plane; d++)     
+    {
+        int idx = d * cdisp_step1;
+        float val  = data[idx] + msg1[idx] + msg2[idx] + msg3[idx];
+       
+        if(val < minimum)
+            minimum = val;
+           
+        msg_dst[idx] = val;
+    }
+        
+    float sum = 0;
+    for(int d = 0; d < nr_plane; d++)
+    {
+        float cost_min = minimum + cmax_disc_term;
+        float src_disp_reg = src_disp[d * cdisp_step1];
+       
+        for(int d2 = 0; d2 < nr_plane; d2++)
+            cost_min = fmin(cost_min, (msg_dst[d2 * cdisp_step1] + 
+                                       cdisc_single_jump * fabs(dst_disp[d2 * cdisp_step1] - src_disp_reg)));
+
+        temp[d * cdisp_step1] = cost_min;
+        sum += cost_min;
+    }
+    sum /= nr_plane;
+
+    for(int d = 0; d < nr_plane; d++)
+        msg_dst[d * cdisp_step1] = temp[d * cdisp_step1] - sum;
+}
+__kernel void compute_message_0(__global short *u_, __global short *d_, __global short *l_, __global short *r_, 
+                                __global const short *data_cost_selected, __global const short *selected_disp_pyr_cur, 
+                                __global short *ctemp, int h, int w, int nr_plane, int i, 
+                                float cmax_disc_term, int cdisp_step1, int cmsg_step1, float cdisc_single_jump)
+{
+    int y = get_global_id(1);
+    int x = ((get_global_id(0)) << 1) + ((y + i) & 1);
+   
+    if (y > 0 && y < h - 1 && x > 0 && x < w - 1)
+    {
+        __global const short *data = data_cost_selected + y * cmsg_step1 + x;
+      
+        __global short *u = u_ + y * cmsg_step1 + x;
+        __global short *d = d_ + y * cmsg_step1 + x;
+        __global short *l = l_ + y * cmsg_step1 + x;
+        __global short *r = r_ + y * cmsg_step1 + x;
+       
+        __global const short *disp = selected_disp_pyr_cur + y * cmsg_step1 + x;
+
+        __global short *temp = ctemp + y * cmsg_step1 + x;
+
+        message_per_pixel_0(data, u, r - 1, u + cmsg_step1, l + 1, disp, disp - cmsg_step1, nr_plane, temp, 
+                            cmax_disc_term, cdisp_step1, cdisc_single_jump);
+        message_per_pixel_0(data, d, d - cmsg_step1, r - 1, l + 1, disp, disp + cmsg_step1, nr_plane, temp,
+                            cmax_disc_term, cdisp_step1, cdisc_single_jump);
+        message_per_pixel_0(data, l, u + cmsg_step1, d - cmsg_step1, l + 1, disp, disp - 1, nr_plane, temp,
+                            cmax_disc_term, cdisp_step1, cdisc_single_jump);
+        message_per_pixel_0(data, r, u + cmsg_step1, d - cmsg_step1, r - 1, disp, disp + 1, nr_plane, temp,
+                            cmax_disc_term, cdisp_step1, cdisc_single_jump);
+    }
+}
+__kernel void compute_message_1(__global float *u_, __global float *d_, __global float *l_, __global float *r_, 
+                                __global const float *data_cost_selected, __global const float *selected_disp_pyr_cur, 
+                                __global float *ctemp, int h, int w, int nr_plane, int i, 
+                                float cmax_disc_term, int cdisp_step1, int cmsg_step1, float cdisc_single_jump)
+{
+    int y = get_global_id(1);
+    int x = ((get_global_id(0)) << 1) + ((y + i) & 1);
+   
+    if (y > 0 && y < h - 1 && x > 0 && x < w - 1)
+    {
+        __global const float *data = data_cost_selected + y * cmsg_step1 + x;
+      
+        __global float *u = u_ + y * cmsg_step1 + x;
+        __global float *d = d_ + y * cmsg_step1 + x;
+        __global float *l = l_ + y * cmsg_step1 + x;
+        __global float *r = r_ + y * cmsg_step1 + x;
+       
+        __global const float *disp = selected_disp_pyr_cur + y * cmsg_step1 + x;
+        __global float *temp = ctemp + y * cmsg_step1 + x;
+            
+        message_per_pixel_1(data, u, r - 1, u + cmsg_step1, l + 1, disp, disp - cmsg_step1, nr_plane, temp, 
+                            cmax_disc_term, cdisp_step1, cdisc_single_jump);
+        message_per_pixel_1(data, d, d - cmsg_step1, r - 1, l + 1, disp, disp + cmsg_step1, nr_plane, temp,
+                            cmax_disc_term, cdisp_step1, cdisc_single_jump);
+        message_per_pixel_1(data, l, u + cmsg_step1, d - cmsg_step1, l + 1, disp, disp - 1, nr_plane, temp,
+                            cmax_disc_term, cdisp_step1, cdisc_single_jump);
+        message_per_pixel_1(data, r, u + cmsg_step1, d - cmsg_step1, r - 1, disp, disp + 1, nr_plane, temp,
+                            cmax_disc_term, cdisp_step1, cdisc_single_jump);
+    }
+}
+
+///////////////////////////////////////////////////////////////
+/////////////////////////// output ////////////////////////////
+///////////////////////////////////////////////////////////////
+__kernel void compute_disp_0(__global const short *u_, __global const short *d_, __global const short *l_, 
+                             __global const short *r_, __global const short * data_cost_selected, 
+                             __global const short *disp_selected_pyr,
+                             __global short* disp, 
+                             int res_step, int cols, int rows, int nr_plane,
+                             int cmsg_step1, int cdisp_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+   
+    if (y > 0 && y < rows - 1 && x > 0 && x < cols - 1)
+    {
+        __global const short *data = data_cost_selected + y * cmsg_step1 + x;
+        __global const short *disp_selected = disp_selected_pyr + y * cmsg_step1 + x;
+
+        __global const short *u = u_ + (y+1) * cmsg_step1 + (x+0);
+        __global const short *d = d_ + (y-1) * cmsg_step1 + (x+0);
+        __global const short *l = l_ + (y+0) * cmsg_step1 + (x+1);
+        __global const short *r = r_ + (y+0) * cmsg_step1 + (x-1);
+       
+        short best = 0;
+        short best_val = SHRT_MAX;
+       
+        for (int i = 0; i < nr_plane; ++i)
+        {
+            int idx = i * cdisp_step1;
+            short val = data[idx]+ u[idx] + d[idx] + l[idx] + r[idx];
+                
+            if (val < best_val)
+            {
+                best_val = val;
+                best = disp_selected[idx];
+            }
+        }
+        disp[res_step * y + x] = best;
+    }
+}
+__kernel void compute_disp_1(__global const float *u_, __global const float *d_, __global const float *l_, 
+                             __global const float *r_, __global const float *data_cost_selected, 
+                             __global const float *disp_selected_pyr,
+                             __global short *disp, 
+                             int res_step, int cols, int rows, int nr_plane,
+                             int cmsg_step1, int cdisp_step1)
+{
+    int x = get_global_id(0);
+    int y = get_global_id(1);
+   
+    if (y > 0 && y < rows - 1 && x > 0 && x < cols - 1)
+    {
+        __global const float *data = data_cost_selected + y * cmsg_step1 + x;
+        __global const float *disp_selected = disp_selected_pyr + y * cmsg_step1 + x;
+
+        __global const float *u = u_ + (y+1) * cmsg_step1 + (x+0);
+        __global const float *d = d_ + (y-1) * cmsg_step1 + (x+0);
+        __global const float *l = l_ + (y+0) * cmsg_step1 + (x+1);
+        __global const float *r = r_ + (y+0) * cmsg_step1 + (x-1);
+       
+        short best = 0;
+        short best_val = SHRT_MAX;
+        for (int i = 0; i < nr_plane; ++i)
+        {
+            int idx = i * cdisp_step1;
+            float val = data[idx]+ u[idx] + d[idx] + l[idx] + r[idx];
+                
+            if (val < best_val)
+            {
+                best_val = val;
+                best = convert_short_sat_rte(disp_selected[idx]);
+            }
+        }
+        disp[res_step * y + x] = best;
+    }
+}
+
diff --git a/modules/ocl/src/matrix_operations.cpp b/modules/ocl/src/matrix_operations.cpp
new file mode 100644 (file)
index 0000000..7635461
--- /dev/null
@@ -0,0 +1,562 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Niko Li, newlife20080214@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 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"
+
+#define ALIGN 32 
+#define GPU_MATRIX_MALLOC_STEP(step) (((step) + ALIGN - 1) / ALIGN) * ALIGN
+
+using namespace cv;
+using namespace cv::ocl;
+using namespace std;
+
+////////////////////////////////////////////////////////////////////////
+//////////////////////////////// oclMat ////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+#if !defined (HAVE_OPENCL)
+
+namespace cv
+{
+    namespace ocl
+    {
+        void oclMat::upload(const Mat& /*m*/)
+        {
+            throw_nogpu();
+        }
+        void oclMat::download(cv::Mat& /*m*/) const
+        {
+            throw_nogpu();
+        }
+        void oclMat::copyTo( oclMat& /*m*/ ) const
+        {
+            throw_nogpu();
+        }
+        void oclMat::copyTo( oclMat& /*m*/, const oclMat&/* mask */) const
+        {
+            throw_nogpu();
+        }
+        void oclMat::convertTo( oclMat& /*m*/, int /*rtype*/, double /*alpha*/, double /*beta*/ ) const
+        {
+            throw_nogpu();
+        }
+        oclMat &oclMat::operator = (const Scalar& /*s*/)
+        {
+            throw_nogpu();
+            return *this;
+        }
+        oclMat &oclMat::setTo(const Scalar& /*s*/, const oclMat& /*mask*/)
+        {
+            throw_nogpu();
+            return *this;
+        }
+        oclMat oclMat::reshape(int /*new_cn*/, int /*new_rows*/) const
+        {
+            throw_nogpu();
+            return oclMat();
+        }
+        void oclMat::create(int /*_rows*/, int /*_cols*/, int /*_type*/)
+        {
+            throw_nogpu();
+        }
+        void oclMat::release()
+        {
+            throw_nogpu();
+        }
+    }
+}
+
+#else /* !defined (HAVE_OPENCL) */
+
+//helper routines
+namespace cv
+{
+    namespace ocl
+    {
+        ///////////////////////////OpenCL kernel strings///////////////////////////
+        extern const char *operator_copyToM;
+        extern const char *operator_convertTo;
+        extern const char *operator_setTo;
+        extern const char *operator_setToM;
+    }
+}
+
+////////////////////////////////////////////////////////////////////////
+// convert_C3C4
+void convert_C3C4(const cl_mem &src, oclMat &dst, int srcStep)
+{
+    int dstStep = dst.step1() / dst.channels();
+    Context *clCxt = dst.clCxt;
+    string kernelName = "convertC3C4";
+
+    vector< pair<size_t, const void *> > args;
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&src));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.wholecols));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dst.wholerows));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&srcStep));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dstStep));
+
+    size_t globalThreads[3] = {(dst.wholecols *dst.wholerows + 255) / 256 * 256, 1, 1};
+    size_t localThreads[3] = {256, 1, 1};
+
+    openCLExecuteKernel(clCxt, &convertC3C4, kernelName, globalThreads, localThreads, args, -1, dst.elemSize1() >> 1);
+}
+////////////////////////////////////////////////////////////////////////
+// convert_C4C3
+void convert_C4C3(const oclMat &src, cl_mem &dst, int dstStep)
+{
+    int srcStep = src.step1() / src.channels();
+    Context *clCxt = src.clCxt;
+    string kernelName = "convertC4C3";
+
+    vector< pair<size_t, const void *> > args;
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&src.data));
+    args.push_back( make_pair( sizeof(cl_mem), (void *)&dst));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src.wholecols));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&src.wholerows));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&srcStep));
+    args.push_back( make_pair( sizeof(cl_int), (void *)&dstStep));
+
+    size_t globalThreads[3] = {(src.wholecols *src.wholerows + 255) / 256 * 256, 1, 1};
+    size_t localThreads[3] = {256, 1, 1};
+
+    openCLExecuteKernel(clCxt, &convertC3C4, kernelName, globalThreads, localThreads, args, -1, src.elemSize1() >> 1);
+}
+
+void cv::ocl::oclMat::upload(const Mat &m)
+{
+    CV_DbgAssert(!m.empty());
+    Size wholeSize;
+    Point ofs;
+    m.locateROI(wholeSize, ofs);
+    int type = m.type();
+    //if(m.channels() == 3)
+    //type = CV_MAKETYPE(m.depth(), 4);
+    create(wholeSize, type);
+
+    //if(m.channels() == 3)
+    //{
+    //int pitch = GPU_MATRIX_MALLOC_STEP(wholeSize.width * 3 * m.elemSize1());
+    //int err;
+    //cl_mem temp = clCreateBuffer(clCxt->clContext,CL_MEM_READ_WRITE,
+    //pitch*wholeSize.height,0,&err);
+    //CV_DbgAssert(err==0);
+
+    //openCLMemcpy2D(clCxt,temp,pitch,m.datastart,m.step,wholeSize.width*m.elemSize(),wholeSize.height,clMemcpyHostToDevice);
+    //convert_C3C4(temp, *this, pitch);
+    //}
+    //else
+    openCLMemcpy2D(clCxt, data, step, m.datastart, m.step, wholeSize.width * elemSize(), wholeSize.height, clMemcpyHostToDevice);
+
+    rows = m.rows;
+    cols = m.cols;
+    offset = ofs.y * step + ofs.x * elemSize();
+    download_channels = m.channels();
+}
+
+void cv::ocl::oclMat::download(cv::Mat &m) const
+{
+    CV_DbgAssert(!this->empty());
+    int t = type();
+    //if(download_channels == 3)
+    //t = CV_MAKETYPE(depth(), 3);
+    m.create(wholerows, wholecols, t);
+
+    //if(download_channels == 3)
+    //{
+    //int pitch = GPU_MATRIX_MALLOC_STEP(wholecols * 3 * m.elemSize1());
+    //int err;
+    //cl_mem temp = clCreateBuffer(clCxt->clContext,CL_MEM_READ_WRITE,
+    //pitch*wholerows,0,&err);
+    //CV_DbgAssert(err==0);
+
+    //convert_C4C3(*this, temp, pitch/m.elemSize1());
+    //openCLMemcpy2D(clCxt,m.data,m.step,temp,pitch,wholecols*m.elemSize(),wholerows,clMemcpyDeviceToHost);
+    //}
+    //else
+    openCLMemcpy2D(clCxt, m.data, m.step, data, step, wholecols * elemSize(), wholerows, clMemcpyDeviceToHost);
+    Size wholesize;
+    Point ofs;
+    locateROI(wholesize, ofs);
+    m.adjustROI(-ofs.y, ofs.y + rows - wholerows, -ofs.x, ofs.x + cols - wholecols);
+}
+
+/////////////////////common//////////////////////////////////////
+inline int divUp(int total, int grain)
+{
+    return (total + grain - 1) / grain;
+}
+///////////////////////////////////////////////////////////////////////////
+////////////////////////////////// CopyTo /////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+void copy_to_with_mask(const oclMat &src, oclMat &dst, const oclMat &mask, string kernelName)
+{
+    CV_DbgAssert( dst.rows == mask.rows && dst.cols == mask.cols &&
+                  src.rows == dst.rows && src.cols == dst.cols);
+
+    vector<pair<size_t , const void *> > args;
+
+    int vector_lengths[4][7] = {{4, 4, 2, 2, 1, 1, 1},
+        {2, 2, 1, 1, 1, 1, 1},
+        {8, 8, 8, 8 , 4, 4, 4},      //vector length is undefined when channels = 3
+        {1, 1, 1, 1, 1, 1, 1}
+    };
+
+    size_t localThreads[3] = {16, 16, 1};
+    size_t globalThreads[3];
+
+    int vector_length = vector_lengths[dst.channels() -1][dst.depth()];
+    int offset_cols = divUp(dst.offset, dst.elemSize()) & (vector_length - 1);
+    int cols = vector_length == 1 ? divUp(dst.cols, vector_length) : divUp(dst.cols + offset_cols, vector_length);
+
+    globalThreads[0] = divUp(cols, localThreads[0]) * localThreads[0];
+    globalThreads[1] = divUp(dst.rows, localThreads[1]) * localThreads[1];
+    globalThreads[2] = 1;
+
+    int dststep_in_pixel = dst.step / dst.elemSize(), dstoffset_in_pixel = dst.offset / dst.elemSize();
+    int srcstep_in_pixel = src.step / src.elemSize(), srcoffset_in_pixel = src.offset / src.elemSize();
+
+    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_mem) , (void *)&mask.data ));
+    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 *)&srcstep_in_pixel ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&srcoffset_in_pixel ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&dststep_in_pixel ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&dstoffset_in_pixel ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&mask.step ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&mask.offset ));
+
+    openCLExecuteKernel(dst.clCxt , &operator_copyToM, kernelName, globalThreads,
+                        localThreads, args, dst.channels(), dst.depth());
+}
+
+void cv::ocl::oclMat::copyTo( oclMat &m ) const
+{
+    CV_DbgAssert(!this->empty());
+    m.create(size(), type());
+    openCLCopyBuffer2D(clCxt, m.data, m.step, m.offset,
+                       data, step, cols * elemSize(), rows, offset, clMemcpyDeviceToDevice);
+}
+
+void cv::ocl::oclMat::copyTo( oclMat &mat, const oclMat &mask) const
+{
+    if (mask.empty())
+    {
+        copyTo(mat);
+    }
+    else
+    {
+        mat.create(size(), type());
+        copy_to_with_mask(*this, mat, mask, "copy_to_with_mask");
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////
+//////////////////////////////// ConvertTo ////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+void convert_run(const oclMat &src, oclMat &dst, double alpha, double beta)
+{
+    string kernelName = "convert_to_S";
+    stringstream idxStr;
+    idxStr << src.depth();
+    kernelName += idxStr.str();
+    float alpha_f = alpha, beta_f = beta;
+    CV_DbgAssert(src.rows == dst.rows && src.cols == dst.cols);
+    vector<pair<size_t , const void *> > args;
+    size_t localThreads[3] = {16, 16, 1};
+    size_t globalThreads[3];
+    globalThreads[0] = (dst.cols + localThreads[0] - 1) / localThreads[0] * localThreads[0];
+    globalThreads[1] = (dst.rows + localThreads[1] - 1) / localThreads[1] * localThreads[1];
+    globalThreads[2] = 1;
+    int dststep_in_pixel = dst.step / dst.elemSize(), dstoffset_in_pixel = dst.offset / dst.elemSize();
+    int srcstep_in_pixel = src.step / src.elemSize(), srcoffset_in_pixel = src.offset / src.elemSize();
+    if(dst.type() == CV_8UC1)
+    {
+        globalThreads[0] = ((dst.cols + 4) / 4 + localThreads[0]) / localThreads[0] * localThreads[0];
+    }
+    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.cols ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&src.rows ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&srcstep_in_pixel ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&srcoffset_in_pixel ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&dststep_in_pixel ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&dstoffset_in_pixel ));
+    args.push_back( make_pair( sizeof(cl_float) , (void *)&alpha_f ));
+    args.push_back( make_pair( sizeof(cl_float) , (void *)&beta_f ));
+    openCLExecuteKernel(dst.clCxt , &operator_convertTo, kernelName, globalThreads,
+                        localThreads, args, dst.channels(), dst.depth());
+}
+void cv::ocl::oclMat::convertTo( oclMat &dst, int rtype, double alpha, double beta ) const
+{
+    //cout << "cv::ocl::oclMat::convertTo()" << endl;
+
+    bool noScale = fabs(alpha - 1) < std::numeric_limits<double>::epsilon()
+                   && fabs(beta) < std::numeric_limits<double>::epsilon();
+
+    if( rtype < 0 )
+        rtype = type();
+    else
+        rtype = CV_MAKETYPE(CV_MAT_DEPTH(rtype), channels());
+
+    //int scn = channels();
+    int sdepth = depth(), ddepth = CV_MAT_DEPTH(rtype);
+    if( sdepth == ddepth && noScale )
+    {
+        copyTo(dst);
+        return;
+    }
+
+    oclMat temp;
+    const oclMat *psrc = this;
+    if( sdepth != ddepth && psrc == &dst )
+        psrc = &(temp = *this);
+
+    dst.create( size(), rtype );
+    convert_run(*psrc, dst, alpha, beta);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//////////////////////////////// setTo ////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+oclMat &cv::ocl::oclMat::operator = (const Scalar &s)
+{
+    //cout << "cv::ocl::oclMat::=" << endl;
+    setTo(s);
+    return *this;
+}
+void set_to_withoutmask_run(const oclMat &dst, const Scalar &scalar, string kernelName)
+{
+    vector<pair<size_t , const void *> > args;
+    cl_float4 val;
+    val.s[0] = scalar.val[0];
+    val.s[1] = scalar.val[1];
+    val.s[2] = scalar.val[2];
+    val.s[3] = scalar.val[3];
+    size_t localThreads[3] = {16, 16, 1};
+    size_t globalThreads[3];
+    globalThreads[0] = (dst.cols + localThreads[0] - 1) / localThreads[0] * localThreads[0];
+    globalThreads[1] = (dst.rows + localThreads[1] - 1) / localThreads[1] * localThreads[1];
+    globalThreads[2] = 1;
+    int step_in_pixel = dst.step / dst.elemSize(), offset_in_pixel = dst.offset / dst.elemSize();
+    if(dst.type() == CV_8UC1)
+    {
+        globalThreads[0] = ((dst.cols + 4) / 4 + localThreads[0] - 1) / localThreads[0] * localThreads[0];
+    }
+    args.push_back( make_pair( sizeof(cl_float4) , (void *)&val ));
+    args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst.data ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.cols ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.rows ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&step_in_pixel ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&offset_in_pixel));
+    openCLExecuteKernel(dst.clCxt , &operator_setTo, kernelName, globalThreads,
+                        localThreads, args, dst.channels(), dst.depth());
+}
+
+void set_to_withmask_run(const oclMat &dst, const Scalar &scalar, const oclMat &mask, string kernelName)
+{
+    CV_DbgAssert( dst.rows == mask.rows && dst.cols == mask.cols);
+    vector<pair<size_t , const void *> > args;
+    cl_float4 val;
+    val.s[0] = scalar.val[0];
+    val.s[1] = scalar.val[1];
+    val.s[2] = scalar.val[2];
+    val.s[3] = scalar.val[3];
+    size_t localThreads[3] = {16, 16, 1};
+    size_t globalThreads[3];
+    globalThreads[0] = (dst.cols + localThreads[0] - 1) / localThreads[0] * localThreads[0];
+    globalThreads[1] = (dst.rows + localThreads[1] - 1) / localThreads[1] * localThreads[1];
+    globalThreads[2] = 1;
+    if(dst.type() == CV_8UC1)
+    {
+        globalThreads[0] = ((dst.cols + 4) / 4 + localThreads[0] - 1) / localThreads[0] * localThreads[0];
+    }
+    int step_in_pixel = dst.step / dst.elemSize(), offset_in_pixel = dst.offset / dst.elemSize();
+    args.push_back( make_pair( sizeof(cl_float4) , (void *)&val ));
+    args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst.data ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.cols ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.rows ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&step_in_pixel ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&offset_in_pixel ));
+    args.push_back( make_pair( sizeof(cl_mem) , (void *)&mask.data ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&mask.step ));
+    args.push_back( make_pair( sizeof(cl_int) , (void *)&mask.offset ));
+    openCLExecuteKernel(dst.clCxt , &operator_setToM, kernelName, globalThreads,
+                        localThreads, args, dst.channels(), dst.depth());
+}
+
+oclMat &cv::ocl::oclMat::setTo(const Scalar &scalar, const oclMat &mask)
+{
+    //cout << "cv::ocl::oclMat::setTo()" << endl;
+    CV_Assert(mask.type() == CV_8UC1);
+    CV_Assert( this->depth() >= 0 && this->depth() <= 6 );
+    CV_DbgAssert( !this->empty());
+    //cl_int status;
+    //cl_mem mem;
+    //mem = clCreateBuffer(this->clCxt->clContext,CL_MEM_READ_WRITE,
+    //                   sizeof(double)*4,NULL,&status);
+    //openCLVerifyCall(status);
+    //double* s =  (double *)scalar.val;
+    //openCLSafeCall(clEnqueueWriteBuffer(this->clCxt->clCmdQueue,
+    //                   (cl_mem)mem,1,0,sizeof(double)*4,s,0,0,0));
+    if (mask.empty())
+    {
+        set_to_withoutmask_run(*this, scalar, "set_to_without_mask");
+    }
+    else
+    {
+        set_to_withmask_run(*this, scalar, mask, "set_to_with_mask");
+    }
+
+    return *this;
+}
+
+oclMat cv::ocl::oclMat::reshape(int new_cn, int new_rows) const
+{
+       if( new_rows != 0 && new_rows != rows)\r
+       {\r
+                CV_Error( CV_StsBadFunc,\r
+            "oclMat's number of rows can not be changed for current version" );\r
+       }
+
+       oclMat hdr = *this;
+
+    int cn = channels();\r
+    if (new_cn == 0)\r
+        new_cn = cn;\r
+\r
+    int total_width = cols * cn;\r
+\r
+    if ((new_cn > total_width || total_width % new_cn != 0) && new_rows == 0)\r
+        new_rows = rows * total_width / new_cn;\r
+\r
+    if (new_rows != 0 && new_rows != rows)\r
+    {\r
+        int total_size = total_width * rows;\r
+\r
+        if (!isContinuous())\r
+            CV_Error(CV_BadStep, "The matrix is not continuous, thus its number of rows can not be changed");\r
+\r
+        if ((unsigned)new_rows > (unsigned)total_size)\r
+            CV_Error(CV_StsOutOfRange, "Bad new number of rows");\r
+\r
+        total_width = total_size / new_rows;\r
+\r
+        if (total_width * new_rows != total_size)\r
+            CV_Error(CV_StsBadArg, "The total number of matrix elements is not divisible by the new number of rows");\r
+\r
+        hdr.rows = new_rows;\r
+        hdr.step = total_width * elemSize1();\r
+    }\r
+\r
+    int new_width = total_width / new_cn;\r
+\r
+    if (new_width * new_cn != total_width)\r
+        CV_Error(CV_BadNumChannels, "The total width is not divisible by the new number of channels");\r
+\r
+    hdr.cols = new_width;\r
+    hdr.flags = (hdr.flags & ~CV_MAT_CN_MASK) | ((new_cn - 1) << CV_CN_SHIFT);\r
+\r
+    return hdr;
+
+}
+
+void cv::ocl::oclMat::create(int _rows, int _cols, int _type)
+{
+    clCxt = Context::getContext();
+    //cout << "cv::ocl::oclMat::create()." << endl;
+
+    /* core logic */
+    _type &= TYPE_MASK;
+    if( rows == _rows && cols == _cols && type() == _type && data )
+        return;
+    if( data )
+        release();
+    CV_DbgAssert( _rows >= 0 && _cols >= 0 );
+    if( _rows > 0 && _cols > 0 )
+    {
+        flags = Mat::MAGIC_VAL + _type;
+        rows = _rows;
+        cols = _cols;
+        wholerows = _rows;
+        wholecols = _cols;
+        size_t esz = elemSize();
+
+        void *dev_ptr;
+        openCLMallocPitch(clCxt, &dev_ptr, &step, GPU_MATRIX_MALLOC_STEP(esz * cols), rows);
+        //openCLMallocPitch(clCxt,&dev_ptr, &step, esz * cols, rows);
+
+        if (esz *cols == step)
+            flags |= Mat::CONTINUOUS_FLAG;
+
+        int64 _nettosize = (int64)step * rows;
+        size_t nettosize = (size_t)_nettosize;
+
+        datastart = data = (uchar *)dev_ptr;
+        dataend = data + nettosize;
+
+        refcount = (int *)fastMalloc(sizeof(*refcount));
+        *refcount = 1;
+    }
+}
+
+void cv::ocl::oclMat::release()
+{
+    //cout << "cv::ocl::oclMat::release()" << endl;
+    if( refcount && CV_XADD(refcount, -1) == 1 )
+    {
+        fastFree(refcount);
+        openCLFree(datastart);
+    }
+    data = datastart = dataend = 0;
+    step = rows = cols = 0;
+    offset = wholerows = wholecols = 0;
+    refcount = 0;
+}
+
+#endif /* !defined (HAVE_OPENCL) */
diff --git a/modules/ocl/src/mssegmentation.cpp b/modules/ocl/src/mssegmentation.cpp
new file mode 100644 (file)
index 0000000..fa4012a
--- /dev/null
@@ -0,0 +1,414 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//
+// 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"
+
+#if !defined(HAVE_OPENCL)
+
+namespace cv
+{
+    namespace ocl
+    {
+
+        void meanShiftSegmentation(const oclMat &, Mat &, int, int, int, TermCriteria)
+        {
+            throw_nogpu();
+        }
+
+    }
+}
+
+#else
+
+using namespace std;
+
+// Auxiliray stuff
+namespace
+{
+
+    //
+    // Declarations
+    //
+
+    class DjSets
+    {
+    public:
+        DjSets(int n);
+        int find(int elem);
+        int merge(int set1, int set2);
+
+        vector<int> parent;
+        vector<int> rank;
+        vector<int> size;
+    private:
+        DjSets(const DjSets &) {}
+        DjSets operator =(const DjSets &);
+    };
+
+    template <typename T>
+    struct GraphEdge
+    {
+        GraphEdge() {}
+        GraphEdge(int to, int next, const T &val) : to(to), next(next), val(val) {}
+        int to;
+        int next;
+        T val;
+    };
+
+
+    template <typename T>
+    class Graph
+    {
+    public:
+        typedef GraphEdge<T> Edge;
+
+        Graph(int numv, int nume_max);
+
+        void addEdge(int from, int to, const T &val = T());
+
+        vector<int> start;
+        vector<Edge> edges;
+
+        int numv;
+        int nume_max;
+        int nume;
+    private:
+        Graph(const Graph &) {}
+        Graph operator =(const Graph &) {}
+    };
+
+
+    struct SegmLinkVal
+    {
+        SegmLinkVal() {}
+        SegmLinkVal(int dr, int dsp) : dr(dr), dsp(dsp) {}
+        bool operator <(const SegmLinkVal &other) const
+        {
+            return dr + dsp < other.dr + other.dsp;
+        }
+        int dr;
+        int dsp;
+    };
+
+
+    struct SegmLink
+    {
+        SegmLink() {}
+        SegmLink(int from, int to, const SegmLinkVal &val)
+            : from(from), to(to), val(val) {}
+        bool operator <(const SegmLink &other) const
+        {
+            return val < other.val;
+        }
+        int from;
+        int to;
+        SegmLinkVal val;
+    };
+
+    //
+    // Implementation
+    //
+
+    DjSets DjSets::operator = (const DjSets &obj)
+    {
+        //cout << "Invalid DjSets constructor\n";
+        CV_Error(-1, "Invalid DjSets constructor\n");
+        return *this;
+    }
+
+    DjSets::DjSets(int n) : parent(n), rank(n, 0), size(n, 1)
+    {
+        for (int i = 0; i < n; ++i)
+            parent[i] = i;
+    }
+
+
+    inline int DjSets::find(int elem)
+    {
+        int set = elem;
+        while (set != parent[set])
+            set = parent[set];
+        while (elem != parent[elem])
+        {
+            int next = parent[elem];
+            parent[elem] = set;
+            elem = next;
+        }
+        return set;
+    }
+
+
+    inline int DjSets::merge(int set1, int set2)
+    {
+        if (rank[set1] < rank[set2])
+        {
+            parent[set1] = set2;
+            size[set2] += size[set1];
+            return set2;
+        }
+        if (rank[set2] < rank[set1])
+        {
+            parent[set2] = set1;
+            size[set1] += size[set2];
+            return set1;
+        }
+        parent[set1] = set2;
+        rank[set2]++;
+        size[set2] += size[set1];
+        return set2;
+    }
+
+
+    template <typename T>
+    Graph<T>::Graph(int numv, int nume_max) : start(numv, -1), edges(nume_max)
+    {
+        this->numv = numv;
+        this->nume_max = nume_max;
+        nume = 0;
+    }
+
+
+    template <typename T>
+    inline void Graph<T>::addEdge(int from, int to, const T &val)
+    {
+        edges[nume] = Edge(to, start[from], val);
+        start[from] = nume;
+        nume++;
+    }
+
+
+    inline int pix(int y, int x, int ncols)
+    {
+        return y * ncols + x;
+    }
+
+
+    inline int sqr(int x)
+    {
+        return x * x;
+    }
+
+
+    inline int dist2(const cv::Vec4b &lhs, const cv::Vec4b &rhs)
+    {
+        return sqr(lhs[0] - rhs[0]) + sqr(lhs[1] - rhs[1]) + sqr(lhs[2] - rhs[2]);
+    }
+
+
+    inline int dist2(const cv::Vec2s &lhs, const cv::Vec2s &rhs)
+    {
+        return sqr(lhs[0] - rhs[0]) + sqr(lhs[1] - rhs[1]);
+    }
+
+} // anonymous namespace
+
+namespace cv
+{
+    namespace ocl
+    {
+
+        void meanShiftSegmentation(const oclMat &src, Mat &dst, int sp, int sr, int minsize, TermCriteria criteria)
+        {
+            CV_Assert(src.type() == CV_8UC4);
+            const int nrows = src.rows;
+            const int ncols = src.cols;
+            const int hr = sr;
+            const int hsp = sp;
+
+            // Perform mean shift procedure and obtain region and spatial maps
+            oclMat h_rmap, h_spmap;
+            meanShiftProc(src, h_rmap, h_spmap, sp, sr, criteria);
+            Mat rmap = h_rmap;
+            Mat spmap = h_spmap;
+
+            Graph<SegmLinkVal> g(nrows * ncols, 4 * (nrows - 1) * (ncols - 1)
+                                 + (nrows - 1) + (ncols - 1));
+
+            // Make region adjacent graph from image
+            Vec4b r1;
+            Vec4b r2[4];
+            Vec2s sp1;
+            Vec2s sp2[4];
+            int dr[4];
+            int dsp[4];
+            for (int y = 0; y < nrows - 1; ++y)
+            {
+                Vec4b *ry = rmap.ptr<Vec4b>(y);
+                Vec4b *ryp = rmap.ptr<Vec4b>(y + 1);
+                Vec2s *spy = spmap.ptr<Vec2s>(y);
+                Vec2s *spyp = spmap.ptr<Vec2s>(y + 1);
+                for (int x = 0; x < ncols - 1; ++x)
+                {
+                    r1 = ry[x];
+                    sp1 = spy[x];
+
+                    r2[0] = ry[x + 1];
+                    r2[1] = ryp[x];
+                    r2[2] = ryp[x + 1];
+                    r2[3] = ryp[x];
+
+                    sp2[0] = spy[x + 1];
+                    sp2[1] = spyp[x];
+                    sp2[2] = spyp[x + 1];
+                    sp2[3] = spyp[x];
+
+                    dr[0] = dist2(r1, r2[0]);
+                    dr[1] = dist2(r1, r2[1]);
+                    dr[2] = dist2(r1, r2[2]);
+                    dsp[0] = dist2(sp1, sp2[0]);
+                    dsp[1] = dist2(sp1, sp2[1]);
+                    dsp[2] = dist2(sp1, sp2[2]);
+
+                    r1 = ry[x + 1];
+                    sp1 = spy[x + 1];
+
+                    dr[3] = dist2(r1, r2[3]);
+                    dsp[3] = dist2(sp1, sp2[3]);
+
+                    g.addEdge(pix(y, x, ncols), pix(y, x + 1, ncols), SegmLinkVal(dr[0], dsp[0]));
+                    g.addEdge(pix(y, x, ncols), pix(y + 1, x, ncols), SegmLinkVal(dr[1], dsp[1]));
+                    g.addEdge(pix(y, x, ncols), pix(y + 1, x + 1, ncols), SegmLinkVal(dr[2], dsp[2]));
+                    g.addEdge(pix(y, x + 1, ncols), pix(y + 1, x, ncols), SegmLinkVal(dr[3], dsp[3]));
+                }
+            }
+            for (int y = 0; y < nrows - 1; ++y)
+            {
+                r1 = rmap.at<Vec4b>(y, ncols - 1);
+                r2[0] = rmap.at<Vec4b>(y + 1, ncols - 1);
+                sp1 = spmap.at<Vec2s>(y, ncols - 1);
+                sp2[0] = spmap.at<Vec2s>(y + 1, ncols - 1);
+                dr[0] = dist2(r1, r2[0]);
+                dsp[0] = dist2(sp1, sp2[0]);
+                g.addEdge(pix(y, ncols - 1, ncols), pix(y + 1, ncols - 1, ncols), SegmLinkVal(dr[0], dsp[0]));
+            }
+            for (int x = 0; x < ncols - 1; ++x)
+            {
+                r1 = rmap.at<Vec4b>(nrows - 1, x);
+                r2[0] = rmap.at<Vec4b>(nrows - 1, x + 1);
+                sp1 = spmap.at<Vec2s>(nrows - 1, x);
+                sp2[0] = spmap.at<Vec2s>(nrows - 1, x + 1);
+                dr[0] = dist2(r1, r2[0]);
+                dsp[0] = dist2(sp1, sp2[0]);
+                g.addEdge(pix(nrows - 1, x, ncols), pix(nrows - 1, x + 1, ncols), SegmLinkVal(dr[0], dsp[0]));
+            }
+
+            DjSets comps(g.numv);
+
+            // Find adjacent components
+            for (int v = 0; v < g.numv; ++v)
+            {
+                for (int e_it = g.start[v]; e_it != -1; e_it = g.edges[e_it].next)
+                {
+                    int c1 = comps.find(v);
+                    int c2 = comps.find(g.edges[e_it].to);
+                    if (c1 != c2 && g.edges[e_it].val.dr < hr && g.edges[e_it].val.dsp < hsp)
+                        comps.merge(c1, c2);
+                }
+            }
+
+            vector<SegmLink> edges;
+            edges.reserve(g.numv);
+
+            // Prepare edges connecting differnet components
+            for (int v = 0; v < g.numv; ++v)
+            {
+                int c1 = comps.find(v);
+                for (int e_it = g.start[v]; e_it != -1; e_it = g.edges[e_it].next)
+                {
+                    int c2 = comps.find(g.edges[e_it].to);
+                    if (c1 != c2)
+                        edges.push_back(SegmLink(c1, c2, g.edges[e_it].val));
+                }
+            }
+
+            // Sort all graph's edges connecting differnet components (in asceding order)
+            sort(edges.begin(), edges.end());
+
+            // Exclude small components (starting from the nearest couple)
+            for (size_t i = 0; i < edges.size(); ++i)
+            {
+                int c1 = comps.find(edges[i].from);
+                int c2 = comps.find(edges[i].to);
+                if (c1 != c2 && (comps.size[c1] < minsize || comps.size[c2] < minsize))
+                    comps.merge(c1, c2);
+            }
+
+            // Compute sum of the pixel's colors which are in the same segment
+            Mat h_src = src;
+            vector<Vec4i> sumcols(nrows * ncols, Vec4i(0, 0, 0, 0));
+            for (int y = 0; y < nrows; ++y)
+            {
+                Vec4b *h_srcy = h_src.ptr<Vec4b>(y);
+                for (int x = 0; x < ncols; ++x)
+                {
+                    int parent = comps.find(pix(y, x, ncols));
+                    Vec4b col = h_srcy[x];
+                    Vec4i &sumcol = sumcols[parent];
+                    sumcol[0] += col[0];
+                    sumcol[1] += col[1];
+                    sumcol[2] += col[2];
+                }
+            }
+
+            // Create final image, color of each segment is the average color of its pixels
+            dst.create(src.size(), src.type());
+
+            for (int y = 0; y < nrows; ++y)
+            {
+                Vec4b *dsty = dst.ptr<Vec4b>(y);
+                for (int x = 0; x < ncols; ++x)
+                {
+                    int parent = comps.find(pix(y, x, ncols));
+                    const Vec4i &sumcol = sumcols[parent];
+                    Vec4b &dstcol = dsty[x];
+                    dstcol[0] = static_cast<uchar>(sumcol[0] / comps.size[parent]);
+                    dstcol[1] = static_cast<uchar>(sumcol[1] / comps.size[parent]);
+                    dstcol[2] = static_cast<uchar>(sumcol[2] / comps.size[parent]);
+                }
+            }
+        }
+
+    }
+}
+#endif // #if !defined (HAVE_OPENCL)
diff --git a/modules/ocl/src/precomp.cpp b/modules/ocl/src/precomp.cpp
new file mode 100644 (file)
index 0000000..766138c
--- /dev/null
@@ -0,0 +1,47 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+//  By downloading, copying, installing or using the software you agree to this license.
+//  If you do not agree to this license, do not download, install,
+//  copy or use the software.
+//
+//
+//                           License Agreement
+//                For Open Source Computer Vision Library
+//
+// Copyright (C) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved.
+// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//
+// 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"
+//CriticalSection cs;
+/* End of file. */
diff --git a/modules/ocl/src/precomp.hpp b/modules/ocl/src/precomp.hpp
new file mode 100644 (file)
index 0000000..587d70d
--- /dev/null
@@ -0,0 +1,161 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Guoping Long, longguoping@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 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 __OPENCV_PRECOMP_H__
+#define __OPENCV_PRECOMP_H__
+
+#if _MSC_VER >= 1200
+#pragma warning( disable: 4251 4710 4711 4514 4996 )
+#endif
+
+#ifdef HAVE_CVCONFIG_H
+#include "cvconfig.h"
+#endif
+
+#include <map>
+#include <iostream>
+#include <limits>
+#include <vector>
+#include <algorithm>
+#include <sstream>
+#include <exception>
+#include <stdio.h>
+
+#include "opencv2/ocl/ocl.hpp"
+
+#include "opencv2/imgproc/imgproc.hpp"
+
+#include "opencv2/objdetect/objdetect.hpp"
+#include "opencv2/imgproc/imgproc.hpp"
+#include "opencv2/imgproc/imgproc_c.h"
+#include "opencv2/core/core_c.h"
+//#include "opencv2/highgui/highgui.hpp"
+#include "opencv2/core/internal.hpp"
+
+#define __ATI__
+
+#if defined (HAVE_OPENCL)
+
+#if defined __APPLE__
+#include <OpenCL/OpenCL.h>
+#else
+#include <CL/cl.h>
+#endif
+
+#include "safe_call.hpp"
+
+using namespace std;
+
+namespace cv
+{
+    namespace ocl
+    {
+        ///////////////////////////OpenCL call wrappers////////////////////////////
+        void openCLMallocPitch(Context *clCxt, void **dev_ptr, size_t *pitch,
+                               size_t widthInBytes, size_t height);
+        void openCLMemcpy2D(Context *clCxt, void *dst, size_t dpitch,
+                            const void *src, size_t spitch,
+                            size_t width, size_t height, enum openCLMemcpyKind kind);
+        void openCLCopyBuffer2D(Context *clCxt, void *dst, size_t dpitch, int dst_offset,
+                                const void *src, size_t spitch,
+                                size_t width, size_t height, int src_offset, enum openCLMemcpyKind kind);
+        void openCLFree(void *devPtr);
+        cl_mem openCLCreateBuffer(Context *clCxt,size_t flag, size_t size);
+        void openCLReadBuffer(Context *clCxt, cl_mem dst_buffer, void* host_buffer, size_t size);
+        cl_kernel openCLGetKernelFromSource(const Context *clCxt,
+                                            const char **source, string kernelName);
+        cl_kernel openCLGetKernelFromSource(const Context *clCxt,
+                                            const char **source, string kernelName, const char *build_options);
+        void openCLVerifyKernel(const Context *clCxt, cl_kernel kernel, size_t *blockSize,
+                                size_t *globalThreads, size_t *localThreads);
+        void openCLExecuteKernel(Context *clCxt , const char **source, string kernelName, vector< std::pair<size_t, const void *> > &args,
+                                 int globalcols , int globalrows, size_t blockSize = 16, int kernel_expand_depth = -1, int kernel_expand_channel = -1);
+        void openCLExecuteKernel(Context *clCxt , const char **source, string kernelName,
+                                 size_t globalThreads[3], size_t localThreads[3],
+                                 vector< pair<size_t, const void *> > &args, int channels, int depth, char *build_options);
+        void openCLExecuteKernel(Context *clCxt , const char **source, string kernelName, size_t globalThreads[3],
+                                 size_t localThreads[3],  vector< pair<size_t, const void *> > &args, int channels, int depth);
+        void openCLExecuteKernel(Context *clCxt , const char **source, string kernelName, size_t globalThreads[3],
+                                 size_t localThreads[3],  vector< pair<size_t, const void *> > &args, int channels,
+                                 int depth, char *build_options);
+
+        cl_mem load_constant(cl_context context, cl_command_queue command_queue, const void *value,
+                             const size_t size);
+
+        cl_mem openCLMalloc(cl_context clCxt, size_t size, cl_mem_flags flags, void *host_ptr);
+
+        void openCLMemcpy2DWithNoPadding(cl_command_queue command_queue, cl_mem buffer, size_t size, size_t offset, void *ptr,
+                                         enum openCLMemcpyKind kind, cl_bool blocking_write);
+               int savetofile(const Context *clcxt,  cl_program &program, const char *fileName);
+               struct Context::Impl
+               {
+            //Information of the OpenCL context
+            cl_context clContext;
+            cl_command_queue clCmdQueue;
+            cl_device_id *devices;
+                       string devName;
+            cl_uint maxDimensions;
+            size_t maxWorkGroupSize;
+            size_t *maxWorkItemSizes;
+            cl_uint maxComputeUnits;
+            int double_support;
+            //extra options to recognize vendor specific fp64 extensions
+            char *extra_options;
+                       string Binpath;
+               };
+    }
+}
+
+
+#else /* defined(HAVE_OPENCL) */
+
+static inline void throw_nogpu()
+{
+    CV_Error(CV_GpuNotSupported, "The library is compilled without OpenCL support.\n");
+}
+
+#endif /* defined(HAVE_OPENCL) */
+
+#endif /* __OPENCV_PRECOMP_H__ */
diff --git a/modules/ocl/src/safe_call.hpp b/modules/ocl/src/safe_call.hpp
new file mode 100644 (file)
index 0000000..c8c19f6
--- /dev/null
@@ -0,0 +1,85 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//   Long Guoping , longguoping@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 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
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef __OPENCV_OPENCL_SAFE_CALL_HPP__
+#define __OPENCV_OPENCL_SAFE_CALL_HPP__
+
+#if defined __APPLE__
+#include <OpenCL/OpenCL.h>
+#else
+#include <CL/cl.h>
+#endif
+
+#if defined(__GNUC__)
+#define openCLSafeCall(expr)  ___openCLSafeCall(expr, __FILE__, __LINE__, __func__)
+#define openCLVerifyCall(res) ___openCLSafeCall(res, __FILE__, __LINE__, __func__)
+#else /* defined(__OPENCLCC__) || defined(__MSVC__) */
+#define openCLSafeCall(expr)  ___openCLSafeCall(expr, __FILE__, __LINE__)
+#define openCLVerifyCall(res) ___openCLSafeCall(res, __FILE__, __LINE__)
+#endif
+
+
+namespace cv
+{
+    namespace ocl
+    {
+        enum openCLMemcpyKind
+        {
+            clMemcpyHostToDevice = 0,
+            clMemcpyDeviceToHost,
+            clMemcpyDeviceToDevice
+        };
+        void error( const char *error_string, const char *file, const int line, const char *func = "");
+        const char *getOpenCLErrorString( int err );
+
+        static inline void ___openCLSafeCall(int err, const char *file, const int line, const char *func = "")
+        {
+            if( CL_SUCCESS != err)
+                cv::ocl::error(getOpenCLErrorString(err), file, line, func);
+        }
+    }
+}
+
+#endif /* __OPENCV_OPENCL_SAFE_CALL_HPP__ */
diff --git a/modules/ocl/src/split_merge.cpp b/modules/ocl/src/split_merge.cpp
new file mode 100644 (file)
index 0000000..bc19773
--- /dev/null
@@ -0,0 +1,410 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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 <vector>
+
+using namespace cv;
+using namespace cv::ocl;
+using namespace std;
+
+
+using std::cout;
+using std::endl;
+
+////////////////////////////////////////////////////////////////////////
+///////////////// oclMat merge and split ///////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+#if !defined (HAVE_OPENCL)
+
+namespace cv
+{
+    namespace ocl
+    {
+        void cv::ocl::merge(const oclMat *src_mat, size_t count, oclMat &dst_mat)
+        {
+            throw_nogpu();
+        }
+        void cv::ocl::merge(const vector<oclMat> &src_mat, oclMat &dst_mat)
+        {
+            throw_nogpu();
+        }
+
+        void cv::ocl::split(const oclMat &src, oclMat *dst)
+        {
+            throw_nogpu();
+        }
+        void cv::ocl::split(const oclMat &src, vector<oclMat> &dst)
+        {
+            throw_nogpu();
+        }
+    }
+}
+
+#else /* !defined (HAVE_OPENCL) */
+
+namespace cv
+{
+    namespace ocl
+    {
+        ///////////////////////////OpenCL kernel strings///////////////////////////
+        extern const char *merge_mat;
+        extern const char *split_mat;
+    }
+}
+namespace cv
+{
+    namespace ocl
+    {
+        namespace split_merge
+        {
+            ///////////////////////////////////////////////////////////
+            ///////////////common/////////////////////////////////////
+            /////////////////////////////////////////////////////////
+            inline int divUp(int total, int grain)
+            {
+                return (total + grain - 1) / grain;
+            }
+            ////////////////////////////////////////////////////////////////////////////
+            ////////////////////merge//////////////////////////////////////////////////
+            ////////////////////////////////////////////////////////////////////////////
+            void merge_vector_run_no_roi(const oclMat *mat_src, size_t n, oclMat &mat_dst)
+            {
+                Context  *clCxt = mat_dst.clCxt;
+                int channels = mat_dst.channels();
+                int depth = mat_dst.depth();
+
+                string kernelName = "merge_vector";
+
+                int indexes[4][7] = {{0, 0, 0, 0, 0, 0, 0},
+                    {4, 4, 2, 2, 1, 1, 1},
+                    {4, 4, 2, 2 , 1, 1, 1},
+                    {4, 4, 2, 2, 1, 1, 1}
+                };
+
+                size_t index = indexes[channels-1][mat_dst.depth()];
+                int    cols = divUp(mat_dst.cols, index);
+                size_t localThreads[3]  = { 64, 4, 1 };
+                size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                            divUp(mat_dst.rows, localThreads[1]) * localThreads[1],
+                                            1
+                                          };
+
+                vector<pair<size_t , const void *> > args;
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_dst.rows));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&cols));
+                args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_dst.data));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_dst.step));
+                args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_src[0].data));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_src[0].step));
+                args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_src[1].data));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_src[1].step));
+                if(n >= 3)
+                {
+                    args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_src[2].data));
+                    args.push_back( make_pair( sizeof(cl_int), (void *)&mat_src[2].step));
+                }
+                if(n >= 4)
+                {
+                    args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_src[3].data));
+                    args.push_back( make_pair( sizeof(cl_int), (void *)&mat_src[3].step));
+                }
+
+                openCLExecuteKernel(clCxt, &merge_mat, kernelName, globalThreads, localThreads, args, channels, depth);
+            }
+
+            void merge_vector_run(const oclMat *mat_src, size_t n, oclMat &mat_dst)
+            {
+                if(mat_dst.clCxt -> impl -> double_support ==0 && mat_dst.type() == CV_64F)
+                {
+                    CV_Error(-217,"Selected device don't support double\r\n");
+                    return;
+                }
+
+                Context  *clCxt = mat_dst.clCxt;
+                int channels = mat_dst.channels();
+                int depth = mat_dst.depth();
+
+                string kernelName = "merge_vector";
+
+                int vector_lengths[4][7] = {{0, 0, 0, 0, 0, 0, 0},
+                    {2, 2, 1, 1, 1, 1, 1},
+                    {4, 4, 2, 2 , 1, 1, 1},
+                    {1, 1, 1, 1, 1, 1, 1}
+                };
+
+                size_t vector_length = vector_lengths[channels-1][depth];
+                int offset_cols = (mat_dst.offset / mat_dst.elemSize()) & (vector_length - 1);
+                int cols = divUp(mat_dst.cols + offset_cols, vector_length);
+
+                size_t localThreads[3]  = { 64, 4, 1 };
+                size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                    divUp(mat_dst.rows, localThreads[1]) * localThreads[1],
+                    1
+                };
+
+                int dst_step1 = mat_dst.cols * mat_dst.elemSize();
+                vector<pair<size_t , const void *> > args;
+                args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_dst.data));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_dst.step));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_dst.offset));
+                args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_src[0].data));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_src[0].step));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_src[0].offset));
+                args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_src[1].data));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_src[1].step));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_src[1].offset));
+                if(n >= 3)
+                {
+                    args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_src[2].data));
+                    args.push_back( make_pair( sizeof(cl_int), (void *)&mat_src[2].step));
+                    args.push_back( make_pair( sizeof(cl_int), (void *)&mat_src[2].offset));
+                    if(n == 3)
+                        args.push_back( make_pair( sizeof(cl_int), (void *)&offset_cols));
+                }
+                if(n >= 4)
+                {
+                    args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_src[3].data));
+                    args.push_back( make_pair( sizeof(cl_int), (void *)&mat_src[3].step));
+                    args.push_back( make_pair( sizeof(cl_int), (void *)&mat_src[3].offset));
+                }
+
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_dst.rows));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&cols));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&dst_step1));
+
+                openCLExecuteKernel(clCxt, &merge_mat, kernelName, globalThreads, localThreads, args, channels, depth);
+            }
+            void merge(const oclMat *mat_src, size_t n, oclMat &mat_dst)
+            {
+                CV_Assert(mat_src);
+                CV_Assert(n > 0);
+
+                int depth = mat_src[0].depth();
+                Size size = mat_src[0].size();
+
+                int total_channels = 0;
+
+                for(size_t i = 0; i < n; ++i)
+                {
+                    CV_Assert(depth == mat_src[i].depth());
+                    CV_Assert(size == mat_src[i].size());
+
+                    total_channels += mat_src[i].channels();
+                }
+
+                CV_Assert(total_channels <= 4);
+
+                if(total_channels == 1)
+                {
+                    mat_src[0].copyTo(mat_dst);
+                    return;
+                }
+
+                mat_dst.create(size, CV_MAKETYPE(depth, total_channels));
+                merge_vector_run(mat_src, n, mat_dst);
+            }
+            ////////////////////////////////////////////////////////////////////////////////////////////////////
+            //////////////////////////////////////split/////////////////////////////////////////////////////////////
+            //////////////////////////////////////////////////////////////////////////////////////////////////
+            void split_vector_run_no_roi(const oclMat &mat_src, oclMat *mat_dst)
+            {
+                Context  *clCxt = mat_src.clCxt;
+                int channels = mat_src.channels();
+                int depth = mat_src.depth();
+
+                string kernelName = "split_vector";
+
+                int indexes[4][7] = {{0, 0, 0, 0, 0, 0, 0},
+                    {8, 8, 8, 8, 4, 4, 2},
+                    {8, 8, 8, 8 , 4, 4, 4},
+                    {4, 4, 2, 2, 1, 1, 1}
+                };
+
+                size_t index = indexes[channels-1][mat_dst[0].depth()];
+                int cols = divUp(mat_src.cols, index);
+                size_t localThreads[3]  = { 64, 4, 1 };
+                size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                            divUp(mat_src.rows, localThreads[1]) * localThreads[1],
+                                            1
+                                          };
+
+                vector<pair<size_t , const void *> > args;
+                args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_src.data));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_src.step));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_src.rows));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&cols));
+                args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_dst[0].data));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_dst[0].step));
+                args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_dst[1].data));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_dst[1].step));
+                if(channels >= 3)
+                {
+                    args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_dst[2].data));
+                    args.push_back( make_pair( sizeof(cl_int), (void *)&mat_dst[2].step));
+                }
+                if(channels >= 4)
+                {
+                    args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_dst[3].data));
+                    args.push_back( make_pair( sizeof(cl_int), (void *)&mat_dst[3].step));
+                }
+
+                openCLExecuteKernel(clCxt, &split_mat, kernelName, globalThreads, localThreads, args, channels, depth);
+            }
+            void split_vector_run(const oclMat &mat_src, oclMat *mat_dst)
+            {
+
+                if(mat_src.clCxt -> impl -> double_support ==0 && mat_src.type() == CV_64F)
+                {
+                    CV_Error(-217,"Selected device don't support double\r\n");
+                    return;
+                }
+
+                Context  *clCxt = mat_src.clCxt;
+                int channels = mat_src.channels();
+                int depth = mat_src.depth();
+
+                string kernelName = "split_vector";
+
+                int vector_lengths[4][7] = {{0, 0, 0, 0, 0, 0, 0},
+                    {4, 4, 2, 2, 1, 1, 1},
+                    {4, 4, 2, 2 , 1, 1, 1},
+                    {4, 4, 2, 2, 1, 1, 1}
+                };
+
+                size_t vector_length = vector_lengths[channels-1][mat_dst[0].depth()];
+
+                int max_offset_cols = 0;
+                for(int i = 0; i < channels; i++)
+                {
+                    int offset_cols = (mat_dst[i].offset / mat_dst[i].elemSize()) & (vector_length - 1);
+                    if(max_offset_cols < offset_cols)
+                        max_offset_cols = offset_cols;
+                }
+
+                int cols =  vector_length == 1 ? divUp(mat_src.cols, vector_length)
+                            : divUp(mat_src.cols + max_offset_cols, vector_length);
+
+                size_t localThreads[3]  = { 64, 4, 1 };
+                size_t globalThreads[3] = { divUp(cols, localThreads[0]) * localThreads[0],
+                                            divUp(mat_src.rows, localThreads[1]) * localThreads[1], 1
+                                          };
+
+                int dst_step1 = mat_dst[0].cols * mat_dst[0].elemSize();
+                vector<pair<size_t , const void *> > args;
+                args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_src.data));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_src.step));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_src.offset));
+                args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_dst[0].data));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_dst[0].step));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_dst[0].offset));
+                args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_dst[1].data));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_dst[1].step));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_dst[1].offset));
+                if(channels >= 3)
+                {
+
+                    args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_dst[2].data));
+                    args.push_back( make_pair( sizeof(cl_int), (void *)&mat_dst[2].step));
+                    args.push_back( make_pair( sizeof(cl_int), (void *)&mat_dst[2].offset));
+                }
+                if(channels >= 4)
+                {
+                    args.push_back( make_pair( sizeof(cl_mem), (void *)&mat_dst[3].data));
+                    args.push_back( make_pair( sizeof(cl_int), (void *)&mat_dst[3].step));
+                    args.push_back( make_pair( sizeof(cl_int), (void *)&mat_dst[3].offset));
+                }
+
+                args.push_back( make_pair( sizeof(cl_int), (void *)&mat_src.rows));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&cols));
+                args.push_back( make_pair( sizeof(cl_int), (void *)&dst_step1));
+
+                openCLExecuteKernel(clCxt, &split_mat, kernelName, globalThreads, localThreads, args, channels, depth);
+            }
+            void split(const oclMat &mat_src, oclMat *mat_dst)
+            {
+                CV_Assert(mat_dst);
+
+                int depth = mat_src.depth();
+                int num_channels = mat_src.channels();
+                Size size = mat_src.size();
+
+                if(num_channels == 1)
+                {
+                    mat_src.copyTo(mat_dst[0]);
+                    return;
+                }
+
+                int i;
+                for(i = 0; i < num_channels; i++)
+                    mat_dst[i].create(size, CV_MAKETYPE(depth, 1));
+
+                split_vector_run(mat_src, mat_dst);
+            }
+        }
+    }
+}
+
+void cv::ocl::merge(const oclMat *src, size_t n, oclMat &dst)
+{
+    split_merge::merge(src, n, dst);
+}
+void cv::ocl::merge(const vector<oclMat> &src, oclMat &dst)
+{
+    split_merge::merge(&src[0], src.size(), dst);
+}
+
+void cv::ocl::split(const oclMat &src, oclMat *dst)
+{
+    split_merge::split(src, dst);
+}
+void cv::ocl::split(const oclMat &src, vector<oclMat> &dst)
+{
+    dst.resize(src.channels());
+    if(src.channels() > 0)
+        split_merge::split(src, &dst[0]);
+}
+#endif /* !defined (HAVE_OPENCL) */
diff --git a/modules/ocl/src/stereo_csbp.cpp b/modules/ocl/src/stereo_csbp.cpp
new file mode 100644 (file)
index 0000000..ac614e1
--- /dev/null
@@ -0,0 +1,786 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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"
+
+using namespace cv;
+using namespace cv::ocl;
+using namespace std;
+
+#if !defined (HAVE_OPENCL)
+
+namespace cv
+{
+    namespace ocl
+    {
+
+        void cv::ocl::StereoConstantSpaceBP::estimateRecommendedParams(int, int, int &, int &, int &, int &)
+        {
+            throw_nogpu();
+        }
+        cv::ocl::StereoConstantSpaceBP::StereoConstantSpaceBP(int, int, int, int, int)
+        {
+            throw_nogpu();
+        }
+        cv::ocl::StereoConstantSpaceBP::StereoConstantSpaceBP(int, int, int, int, float, float,
+                float, float, int, int)
+        {
+            throw_nogpu();
+        }
+
+        void cv::ocl::StereoConstantSpaceBP::operator()(const oclMat &, const oclMat &, oclMat &)
+        {
+            throw_nogpu();
+        }
+    }
+}
+
+#else /* !defined (HAVE_OPENCL) */
+
+namespace cv
+{
+    namespace ocl
+    {
+
+        ///////////////////////////OpenCL kernel strings///////////////////////////
+        extern const char *stereocsbp;
+    }
+
+}
+namespace cv
+{
+    namespace ocl
+    {
+        namespace stereoCSBP
+        {
+            //////////////////////////////////////////////////////////////////////////
+            //////////////////////////////common////////////////////////////////////
+            ////////////////////////////////////////////////////////////////////////
+            static inline int divUp(int total, int grain)
+            {
+                return (total + grain - 1) / grain;
+            }
+            static string get_kernel_name(string kernel_name, int data_type)
+            {
+                stringstream idxStr;
+                if(data_type == CV_16S)
+                    idxStr << "0";
+                else
+                    idxStr << "1";
+                kernel_name += idxStr.str();
+
+                return kernel_name;
+            }
+            using cv::ocl::StereoConstantSpaceBP;
+            //////////////////////////////////////////////////////////////////////////////////
+            /////////////////////////////////init_data_cost//////////////////////////////////
+            //////////////////////////////////////////////////////////////////////////////////
+            static void init_data_cost_caller(const oclMat &left, const oclMat &right, oclMat &temp,
+                                              StereoConstantSpaceBP &rthis,
+                                              int msg_step, int h, int w, int level)
+            {
+                Context  *clCxt = left.clCxt;
+                int data_type = rthis.msg_type;
+                int channels = left.channels();
+
+                string kernelName = get_kernel_name("init_data_cost_", data_type);
+
+                cl_kernel kernel = openCLGetKernelFromSource(clCxt, &stereocsbp, kernelName);
+
+                size_t blockSize = 256;
+                size_t localThreads[]  = {32, 8};
+                size_t globalThreads[] = {divUp(w, localThreads[0]) * localThreads[0],
+                                          divUp(h, localThreads[1]) * localThreads[1]
+                                         };
+
+                int cdisp_step1 = msg_step * h;
+                openCLVerifyKernel(clCxt, kernel, &blockSize, globalThreads, localThreads);
+                openCLSafeCall(clSetKernelArg(kernel, 0, sizeof(cl_mem),  (void *)&temp.data));
+                openCLSafeCall(clSetKernelArg(kernel, 1, sizeof(cl_mem),  (void *)&left.data));
+                openCLSafeCall(clSetKernelArg(kernel, 2, sizeof(cl_mem),  (void *)&right.data));
+                openCLSafeCall(clSetKernelArg(kernel, 3, sizeof(cl_int),  (void *)&h));
+                openCLSafeCall(clSetKernelArg(kernel, 4, sizeof(cl_int),  (void *)&w));
+                openCLSafeCall(clSetKernelArg(kernel, 5, sizeof(cl_int),  (void *)&level));
+                openCLSafeCall(clSetKernelArg(kernel, 6, sizeof(cl_int),  (void *)&channels));
+                openCLSafeCall(clSetKernelArg(kernel, 7, sizeof(cl_int),  (void *)&msg_step));
+                openCLSafeCall(clSetKernelArg(kernel, 8, sizeof(cl_float), (void *)&rthis.data_weight));
+                openCLSafeCall(clSetKernelArg(kernel, 9, sizeof(cl_float), (void *)&rthis.max_data_term));
+                openCLSafeCall(clSetKernelArg(kernel, 10, sizeof(cl_int), (void *)&cdisp_step1));
+                openCLSafeCall(clSetKernelArg(kernel, 11, sizeof(cl_int), (void *)&rthis.min_disp_th));
+                openCLSafeCall(clSetKernelArg(kernel, 12, sizeof(cl_int), (void *)&left.step));
+                openCLSafeCall(clSetKernelArg(kernel, 13, sizeof(cl_int), (void *)&rthis.ndisp));
+                openCLSafeCall(clEnqueueNDRangeKernel(clCxt->impl->clCmdQueue, kernel, 2, NULL,
+                                                      globalThreads, localThreads, 0, NULL, NULL));
+
+                clFinish(clCxt->impl->clCmdQueue);
+                openCLSafeCall(clReleaseKernel(kernel));
+            }
+
+            static void init_data_cost_reduce_caller(const oclMat &left, const oclMat &right, oclMat &temp,
+                    StereoConstantSpaceBP &rthis,
+                    int msg_step, int h, int w, int level)
+            {
+                Context  *clCxt = left.clCxt;
+                int data_type = rthis.msg_type;
+                int channels = left.channels();
+                int win_size = (int)std::pow(2.f, level);
+
+                string kernelName = get_kernel_name("init_data_cost_reduce_", data_type);
+
+                cl_kernel kernel = openCLGetKernelFromSource(clCxt, &stereocsbp, kernelName);
+
+                const int threadsNum = 256;
+                size_t blockSize = threadsNum;
+                size_t localThreads[3]  = {win_size, 1, threadsNum / win_size};
+                size_t globalThreads[3] = {w *localThreads[0],
+                                           h *divUp(rthis.ndisp, localThreads[2]) * localThreads[1], 1 * localThreads[2]
+                                          };
+
+                int local_mem_size = threadsNum * sizeof(float);
+                int cdisp_step1 = msg_step * h;
+
+                openCLVerifyKernel(clCxt, kernel, &blockSize, globalThreads, localThreads);
+                openCLSafeCall(clSetKernelArg(kernel, 0,  sizeof(cl_mem),  (void *)&temp.data));
+                openCLSafeCall(clSetKernelArg(kernel, 1,  sizeof(cl_mem),  (void *)&left.data));
+                openCLSafeCall(clSetKernelArg(kernel, 2,  sizeof(cl_mem),  (void *)&right.data));
+                openCLSafeCall(clSetKernelArg(kernel, 3,  local_mem_size,  (void *)NULL));
+                openCLSafeCall(clSetKernelArg(kernel, 4,  sizeof(cl_int),  (void *)&level));
+                openCLSafeCall(clSetKernelArg(kernel, 5,  sizeof(cl_int),  (void *)&left.rows));
+                openCLSafeCall(clSetKernelArg(kernel, 6,  sizeof(cl_int),  (void *)&left.cols));
+                openCLSafeCall(clSetKernelArg(kernel, 7,  sizeof(cl_int),  (void *)&h));
+                openCLSafeCall(clSetKernelArg(kernel, 8,  sizeof(cl_int),  (void *)&win_size));
+                openCLSafeCall(clSetKernelArg(kernel, 9,  sizeof(cl_int),  (void *)&channels));
+                openCLSafeCall(clSetKernelArg(kernel, 10, sizeof(cl_int),  (void *)&rthis.ndisp));
+                openCLSafeCall(clSetKernelArg(kernel, 11, sizeof(cl_int),  (void *)&left.step));
+                openCLSafeCall(clSetKernelArg(kernel, 12, sizeof(cl_float), (void *)&rthis.data_weight));
+                openCLSafeCall(clSetKernelArg(kernel, 13, sizeof(cl_float), (void *)&rthis.max_data_term));
+                openCLSafeCall(clSetKernelArg(kernel, 14, sizeof(cl_int),  (void *)&rthis.min_disp_th));
+                openCLSafeCall(clSetKernelArg(kernel, 15, sizeof(cl_int),  (void *)&cdisp_step1));
+                openCLSafeCall(clSetKernelArg(kernel, 16, sizeof(cl_int),  (void *)&msg_step));
+                openCLSafeCall(clEnqueueNDRangeKernel(clCxt->impl->clCmdQueue, kernel, 3, NULL,
+                                                      globalThreads, localThreads, 0, NULL, NULL));
+
+                clFinish(clCxt->impl->clCmdQueue);
+                openCLSafeCall(clReleaseKernel(kernel));
+
+            }
+
+            static void get_first_initial_local_caller(uchar *data_cost_selected, uchar *disp_selected_pyr,
+                    oclMat &temp, StereoConstantSpaceBP &rthis,
+                    int h, int w, int nr_plane, int msg_step)
+            {
+                Context  *clCxt = temp.clCxt;
+                int data_type = rthis.msg_type;
+
+                string kernelName = get_kernel_name("get_first_k_initial_local_", data_type);
+
+                cl_kernel kernel = openCLGetKernelFromSource(clCxt, &stereocsbp, kernelName);
+
+                size_t blockSize = 256;
+                size_t localThreads[]  = {32, 8};
+                size_t globalThreads[] = {divUp(w, localThreads[0]) * localThreads[0],
+                                          divUp(h, localThreads[1]) * localThreads[1]
+                                         };
+
+                int disp_step = msg_step * h;
+                openCLVerifyKernel(clCxt, kernel, &blockSize, globalThreads, localThreads);
+                openCLSafeCall(clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&data_cost_selected));
+                openCLSafeCall(clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&disp_selected_pyr));
+                openCLSafeCall(clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&temp.data));
+                openCLSafeCall(clSetKernelArg(kernel, 3, sizeof(cl_int), (void *)&h));
+                openCLSafeCall(clSetKernelArg(kernel, 4, sizeof(cl_int), (void *)&w));
+                openCLSafeCall(clSetKernelArg(kernel, 5, sizeof(cl_int), (void *)&nr_plane));
+                openCLSafeCall(clSetKernelArg(kernel, 6, sizeof(cl_int), (void *)&msg_step));
+                openCLSafeCall(clSetKernelArg(kernel, 7, sizeof(cl_int), (void *)&disp_step));
+                openCLSafeCall(clSetKernelArg(kernel, 8, sizeof(cl_int), (void *)&rthis.ndisp));
+                openCLSafeCall(clEnqueueNDRangeKernel(clCxt->impl->clCmdQueue, kernel, 2, NULL,
+                                                      globalThreads, localThreads, 0, NULL, NULL));
+
+                clFinish(clCxt->impl->clCmdQueue);
+                openCLSafeCall(clReleaseKernel(kernel));
+            }
+            static void get_first_initial_global_caller(uchar *data_cost_selected, uchar *disp_selected_pyr,
+                    oclMat &temp, StereoConstantSpaceBP &rthis,
+                    int h, int w, int nr_plane, int msg_step)
+            {
+                Context  *clCxt = temp.clCxt;
+                int data_type = rthis.msg_type;
+
+                string kernelName = get_kernel_name("get_first_k_initial_global_", data_type);
+
+                cl_kernel kernel = openCLGetKernelFromSource(clCxt, &stereocsbp, kernelName);
+
+                size_t blockSize = 256;
+                size_t localThreads[]  = {32, 8};
+                size_t globalThreads[] = {divUp(w, localThreads[0]) * localThreads[0],
+                                          divUp(h, localThreads[1]) * localThreads[1]
+                                         };
+
+                int disp_step = msg_step * h;
+                openCLVerifyKernel(clCxt, kernel, &blockSize, globalThreads, localThreads);
+                openCLSafeCall(clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&data_cost_selected));
+                openCLSafeCall(clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&disp_selected_pyr));
+                openCLSafeCall(clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&temp.data));
+                openCLSafeCall(clSetKernelArg(kernel, 3, sizeof(cl_int), (void *)&h));
+                openCLSafeCall(clSetKernelArg(kernel, 4, sizeof(cl_int), (void *)&w));
+                openCLSafeCall(clSetKernelArg(kernel, 5, sizeof(cl_int), (void *)&nr_plane));
+                openCLSafeCall(clSetKernelArg(kernel, 6, sizeof(cl_int), (void *)&msg_step));
+                openCLSafeCall(clSetKernelArg(kernel, 7, sizeof(cl_int), (void *)&disp_step));
+                openCLSafeCall(clSetKernelArg(kernel, 8, sizeof(cl_int), (void *)&rthis.ndisp));
+                openCLSafeCall(clEnqueueNDRangeKernel(clCxt->impl->clCmdQueue, kernel, 2, NULL,
+                                                      globalThreads, localThreads, 0, NULL, NULL));
+
+                clFinish(clCxt->impl->clCmdQueue);
+                openCLSafeCall(clReleaseKernel(kernel));
+            }
+
+            void init_data_cost(const oclMat &left, const oclMat &right, oclMat &temp, StereoConstantSpaceBP &rthis,
+                                uchar *disp_selected_pyr, uchar *data_cost_selected,
+                                size_t msg_step, int h, int w, int level, int nr_plane)
+            {
+
+                if(level <= 1)
+                    init_data_cost_caller(left, right, temp, rthis, msg_step, h, w, level);
+                else
+                    init_data_cost_reduce_caller(left, right, temp, rthis, msg_step, h, w, level);
+
+                if(rthis.use_local_init_data_cost == true)
+                    get_first_initial_local_caller(data_cost_selected, disp_selected_pyr, temp, rthis, h, w,
+                                                   nr_plane, msg_step);
+                else
+                    get_first_initial_global_caller(data_cost_selected, disp_selected_pyr, temp, rthis, h, w,
+                                                    nr_plane, msg_step);
+            }
+
+            ///////////////////////////////////////////////////////////////////////////////////////////////////
+            ///////////////////////////////////compute_data_cost//////////////////////////////////////////////
+            ////////////////////////////////////////////////////////////////////////////////////////////////
+            static void compute_data_cost_caller(uchar *disp_selected_pyr, uchar *data_cost,
+                                                 StereoConstantSpaceBP &rthis, int msg_step1,
+                                                 int msg_step2, const oclMat &left, const oclMat &right, int h,
+                                                 int w, int h2, int level, int nr_plane)
+            {
+                Context  *clCxt = left.clCxt;
+                int channels = left.channels();
+                int data_type = rthis.msg_type;
+
+                string kernelName = get_kernel_name("compute_data_cost_", data_type);
+
+                cl_kernel kernel = openCLGetKernelFromSource(clCxt, &stereocsbp, kernelName);
+
+                size_t blockSize = 256;
+                size_t localThreads[]  = {32, 8};
+                size_t globalThreads[] = {divUp(w, localThreads[0]) * localThreads[0],
+                                          divUp(h, localThreads[1]) * localThreads[1]
+                                         };
+
+                int disp_step1 = msg_step1 * h;
+                int disp_step2 = msg_step2 * h2;
+                openCLVerifyKernel(clCxt, kernel, &blockSize, globalThreads, localThreads);
+                openCLSafeCall(clSetKernelArg(kernel, 0,  sizeof(cl_mem),  (void *)&disp_selected_pyr));
+                openCLSafeCall(clSetKernelArg(kernel, 1,  sizeof(cl_mem),  (void *)&data_cost));
+                openCLSafeCall(clSetKernelArg(kernel, 2,  sizeof(cl_mem),  (void *)&left.data));
+                openCLSafeCall(clSetKernelArg(kernel, 3,  sizeof(cl_mem),  (void *)&right.data));
+                openCLSafeCall(clSetKernelArg(kernel, 4,  sizeof(cl_int),  (void *)&h));
+                openCLSafeCall(clSetKernelArg(kernel, 5,  sizeof(cl_int),  (void *)&w));
+                openCLSafeCall(clSetKernelArg(kernel, 6,  sizeof(cl_int),  (void *)&level));
+                openCLSafeCall(clSetKernelArg(kernel, 7,  sizeof(cl_int),  (void *)&nr_plane));
+                openCLSafeCall(clSetKernelArg(kernel, 8,  sizeof(cl_int),  (void *)&channels));
+                openCLSafeCall(clSetKernelArg(kernel, 9,  sizeof(cl_int),  (void *)&msg_step1));
+                openCLSafeCall(clSetKernelArg(kernel, 10, sizeof(cl_int),  (void *)&msg_step2));
+                openCLSafeCall(clSetKernelArg(kernel, 11, sizeof(cl_int),  (void *)&disp_step1));
+                openCLSafeCall(clSetKernelArg(kernel, 12, sizeof(cl_int),  (void *)&disp_step2));
+                openCLSafeCall(clSetKernelArg(kernel, 13, sizeof(cl_float), (void *)&rthis.data_weight));
+                openCLSafeCall(clSetKernelArg(kernel, 14, sizeof(cl_float), (void *)&rthis.max_data_term));
+                openCLSafeCall(clSetKernelArg(kernel, 15, sizeof(cl_int),  (void *)&left.step));
+                openCLSafeCall(clSetKernelArg(kernel, 16, sizeof(cl_int),  (void *)&rthis.min_disp_th));
+                openCLSafeCall(clEnqueueNDRangeKernel(clCxt->impl->clCmdQueue, kernel, 2, NULL,
+                                                      globalThreads, localThreads, 0, NULL, NULL));
+
+                clFinish(clCxt->impl->clCmdQueue);
+                openCLSafeCall(clReleaseKernel(kernel));
+            }
+            static void compute_data_cost_reduce_caller(uchar *disp_selected_pyr, uchar *data_cost,
+                    StereoConstantSpaceBP &rthis, int msg_step1,
+                    int msg_step2, const oclMat &left, const oclMat &right, int h,
+                    int w, int h2, int level, int nr_plane)
+            {
+                Context  *clCxt = left.clCxt;
+                int data_type = rthis.msg_type;
+                int channels = left.channels();
+                int win_size = (int)std::pow(2.f, level);
+
+                string kernelName = get_kernel_name("compute_data_cost_reduce_", data_type);
+
+                cl_kernel kernel = openCLGetKernelFromSource(clCxt, &stereocsbp, kernelName);
+
+                const size_t threadsNum = 256;
+                size_t blockSize = threadsNum;
+                size_t localThreads[3]  = {win_size, 1, threadsNum / win_size};
+                size_t globalThreads[3] = {w *localThreads[0],
+                                           h *divUp(nr_plane, localThreads[2]) * localThreads[1], 1 * localThreads[2]
+                                          };
+
+                int disp_step1 = msg_step1 * h;
+                int disp_step2 = msg_step2 * h2;
+                size_t local_mem_size = threadsNum * sizeof(float);
+                openCLVerifyKernel(clCxt, kernel, &blockSize, globalThreads, localThreads);
+                openCLSafeCall(clSetKernelArg(kernel, 0,  sizeof(cl_mem),  (void *)&disp_selected_pyr));
+                openCLSafeCall(clSetKernelArg(kernel, 1,  sizeof(cl_mem),  (void *)&data_cost));
+                openCLSafeCall(clSetKernelArg(kernel, 2,  sizeof(cl_mem),  (void *)&left.data));
+                openCLSafeCall(clSetKernelArg(kernel, 3,  sizeof(cl_mem),  (void *)&right.data));
+                openCLSafeCall(clSetKernelArg(kernel, 4, local_mem_size,   (void *)NULL));
+                openCLSafeCall(clSetKernelArg(kernel, 5,  sizeof(cl_int),  (void *)&level));
+                openCLSafeCall(clSetKernelArg(kernel, 6,  sizeof(cl_int),  (void *)&left.rows));
+                openCLSafeCall(clSetKernelArg(kernel, 7,  sizeof(cl_int),  (void *)&left.cols));
+                openCLSafeCall(clSetKernelArg(kernel, 8,  sizeof(cl_int),  (void *)&h));
+                openCLSafeCall(clSetKernelArg(kernel, 9,  sizeof(cl_int),  (void *)&nr_plane));
+                openCLSafeCall(clSetKernelArg(kernel, 10, sizeof(cl_int),  (void *)&channels));
+                openCLSafeCall(clSetKernelArg(kernel, 11, sizeof(cl_int),  (void *)&win_size));
+                openCLSafeCall(clSetKernelArg(kernel, 12, sizeof(cl_int),  (void *)&msg_step1));
+                openCLSafeCall(clSetKernelArg(kernel, 13, sizeof(cl_int),  (void *)&msg_step2));
+                openCLSafeCall(clSetKernelArg(kernel, 14, sizeof(cl_int),  (void *)&disp_step1));
+                openCLSafeCall(clSetKernelArg(kernel, 15, sizeof(cl_int),  (void *)&disp_step2));
+                openCLSafeCall(clSetKernelArg(kernel, 16, sizeof(cl_float), (void *)&rthis.data_weight));
+                openCLSafeCall(clSetKernelArg(kernel, 17, sizeof(cl_float), (void *)&rthis.max_data_term));
+                openCLSafeCall(clSetKernelArg(kernel, 18, sizeof(cl_int),  (void *)&left.step));
+                openCLSafeCall(clSetKernelArg(kernel, 19, sizeof(cl_int),  (void *)&rthis.min_disp_th));
+                openCLSafeCall(clEnqueueNDRangeKernel(clCxt->impl->clCmdQueue, kernel, 3, NULL,
+                                                      globalThreads, localThreads, 0, NULL, NULL));
+
+                clFinish(clCxt->impl->clCmdQueue);
+                openCLSafeCall(clReleaseKernel(kernel));
+            }
+            void compute_data_cost(uchar *disp_selected_pyr, uchar *data_cost, StereoConstantSpaceBP &rthis,
+                                   int msg_step1, int msg_step2, const oclMat &left, const oclMat &right, int h, int w,
+                                   int h2, int level, int nr_plane)
+            {
+                if(level <= 1)
+                    compute_data_cost_caller(disp_selected_pyr, data_cost, rthis, msg_step1, msg_step2,
+                                             left, right, h, w, h2, level, nr_plane);
+                else
+                    compute_data_cost_reduce_caller(disp_selected_pyr, data_cost, rthis,  msg_step1, msg_step2,
+                                                    left, right, h, w, h2, level, nr_plane);
+            }
+            ////////////////////////////////////////////////////////////////////////////////////////////////
+            //////////////////////////////////////init message//////////////////////////////////////////////
+            ////////////////////////////////////////////////////////////////////////////////////////////////
+            void init_message(uchar *u_new, uchar *d_new, uchar *l_new, uchar *r_new,
+                              uchar *u_cur, uchar *d_cur, uchar *l_cur, uchar *r_cur,
+                              uchar *disp_selected_pyr_new, uchar *disp_selected_pyr_cur,
+                              uchar *data_cost_selected, uchar *data_cost, oclMat &temp, StereoConstantSpaceBP rthis,
+                              size_t msg_step1, size_t msg_step2, int h, int w, int nr_plane,
+                              int h2, int w2, int nr_plane2)
+            {
+                Context  *clCxt = temp.clCxt;
+                int data_type = rthis.msg_type;
+
+                string kernelName = get_kernel_name("init_message_", data_type);
+
+                cl_kernel kernel = openCLGetKernelFromSource(clCxt, &stereocsbp, kernelName);
+
+                size_t blockSize = 256;
+                size_t localThreads[]  = {32, 8};
+                size_t globalThreads[] = {divUp(w, localThreads[0]) * localThreads[0],
+                                          divUp(h, localThreads[1]) * localThreads[1]
+                                         };
+
+                int disp_step1 = msg_step1 * h;
+                int disp_step2 = msg_step2 * h2;
+                openCLVerifyKernel(clCxt, kernel, &blockSize, globalThreads, localThreads);
+                openCLSafeCall(clSetKernelArg(kernel, 0,  sizeof(cl_mem), (void *)&u_new));
+                openCLSafeCall(clSetKernelArg(kernel, 1,  sizeof(cl_mem), (void *)&d_new));
+                openCLSafeCall(clSetKernelArg(kernel, 2,  sizeof(cl_mem), (void *)&l_new));
+                openCLSafeCall(clSetKernelArg(kernel, 3,  sizeof(cl_mem), (void *)&r_new));
+                openCLSafeCall(clSetKernelArg(kernel, 4,  sizeof(cl_mem), (void *)&u_cur));
+                openCLSafeCall(clSetKernelArg(kernel, 5,  sizeof(cl_mem), (void *)&d_cur));
+                openCLSafeCall(clSetKernelArg(kernel, 6,  sizeof(cl_mem), (void *)&l_cur));
+                openCLSafeCall(clSetKernelArg(kernel, 7,  sizeof(cl_mem), (void *)&r_cur));
+                openCLSafeCall(clSetKernelArg(kernel, 8,  sizeof(cl_mem), (void *)&temp.data));
+                openCLSafeCall(clSetKernelArg(kernel, 9,  sizeof(cl_mem), (void *)&disp_selected_pyr_new));
+                openCLSafeCall(clSetKernelArg(kernel, 10, sizeof(cl_mem), (void *)&disp_selected_pyr_cur));
+                openCLSafeCall(clSetKernelArg(kernel, 11, sizeof(cl_mem), (void *)&data_cost_selected));
+                openCLSafeCall(clSetKernelArg(kernel, 12, sizeof(cl_mem), (void *)&data_cost));
+                openCLSafeCall(clSetKernelArg(kernel, 13, sizeof(cl_int), (void *)&h));
+                openCLSafeCall(clSetKernelArg(kernel, 14, sizeof(cl_int), (void *)&w));
+                openCLSafeCall(clSetKernelArg(kernel, 15, sizeof(cl_int), (void *)&nr_plane));
+                openCLSafeCall(clSetKernelArg(kernel, 16, sizeof(cl_int), (void *)&h2));
+                openCLSafeCall(clSetKernelArg(kernel, 17, sizeof(cl_int), (void *)&w2));
+                openCLSafeCall(clSetKernelArg(kernel, 18, sizeof(cl_int), (void *)&nr_plane2));
+                openCLSafeCall(clSetKernelArg(kernel, 19, sizeof(cl_int), (void *)&disp_step1));
+                openCLSafeCall(clSetKernelArg(kernel, 20, sizeof(cl_int), (void *)&disp_step2));
+                openCLSafeCall(clSetKernelArg(kernel, 21, sizeof(cl_int), (void *)&msg_step1));
+                openCLSafeCall(clSetKernelArg(kernel, 22, sizeof(cl_int), (void *)&msg_step2));
+                openCLSafeCall(clEnqueueNDRangeKernel(clCxt->impl->clCmdQueue, kernel, 2, NULL,
+                                                      globalThreads, localThreads, 0, NULL, NULL));
+
+                clFinish(clCxt->impl->clCmdQueue);
+                openCLSafeCall(clReleaseKernel(kernel));
+            }
+            ////////////////////////////////////////////////////////////////////////////////////////////////
+            ///////////////////////////calc_all_iterations////////////////////////////////////////////////
+            //////////////////////////////////////////////////////////////////////////////////////////////
+            void calc_all_iterations_caller(uchar *u, uchar *d, uchar *l, uchar *r, uchar *data_cost_selected,
+                                            uchar *disp_selected_pyr, oclMat &temp, StereoConstantSpaceBP rthis,
+                                            int msg_step, int h, int w, int nr_plane, int i)
+            {
+                Context  *clCxt = temp.clCxt;
+                int data_type = rthis.msg_type;
+
+                string kernelName = get_kernel_name("compute_message_", data_type);
+
+                cl_kernel kernel = openCLGetKernelFromSource(clCxt, &stereocsbp, kernelName);
+
+                size_t blockSize = 256;
+                size_t localThreads[]  = {32, 8};
+                size_t globalThreads[] = {divUp(w, (localThreads[0]) << 1) * localThreads[0],
+                                          divUp(h, localThreads[1]) * localThreads[1]
+                                         };
+
+                int disp_step = msg_step * h;
+                openCLVerifyKernel(clCxt, kernel, &blockSize, globalThreads, localThreads);
+                openCLSafeCall(clSetKernelArg(kernel, 0,  sizeof(cl_mem),  (void *)&u));
+                openCLSafeCall(clSetKernelArg(kernel, 1,  sizeof(cl_mem),  (void *)&d));
+                openCLSafeCall(clSetKernelArg(kernel, 2,  sizeof(cl_mem),  (void *)&l));
+                openCLSafeCall(clSetKernelArg(kernel, 3,  sizeof(cl_mem),  (void *)&r));
+                openCLSafeCall(clSetKernelArg(kernel, 4,  sizeof(cl_mem),  (void *)&data_cost_selected));
+                openCLSafeCall(clSetKernelArg(kernel, 5,  sizeof(cl_mem),  (void *)&disp_selected_pyr));
+                openCLSafeCall(clSetKernelArg(kernel, 6,  sizeof(cl_mem),  (void *)&temp.data));
+                openCLSafeCall(clSetKernelArg(kernel, 7,  sizeof(cl_int),  (void *)&h));
+                openCLSafeCall(clSetKernelArg(kernel, 8,  sizeof(cl_int),  (void *)&w));
+                openCLSafeCall(clSetKernelArg(kernel, 9,  sizeof(cl_int),  (void *)&nr_plane));
+                openCLSafeCall(clSetKernelArg(kernel, 10, sizeof(cl_int),  (void *)&i));
+                openCLSafeCall(clSetKernelArg(kernel, 11, sizeof(cl_float), (void *)&rthis.max_disc_term));
+                openCLSafeCall(clSetKernelArg(kernel, 12, sizeof(cl_int),  (void *)&disp_step));
+                openCLSafeCall(clSetKernelArg(kernel, 13, sizeof(cl_int),  (void *)&msg_step));
+                openCLSafeCall(clSetKernelArg(kernel, 14, sizeof(cl_float), (void *)&rthis.disc_single_jump));
+                openCLSafeCall(clEnqueueNDRangeKernel(clCxt->impl->clCmdQueue, kernel, 2, NULL,
+                                                      globalThreads, localThreads, 0, NULL, NULL));
+
+                clFinish(clCxt->impl->clCmdQueue);
+                openCLSafeCall(clReleaseKernel(kernel));
+            }
+            void calc_all_iterations(uchar *u, uchar *d, uchar *l, uchar *r, uchar *data_cost_selected,
+                                     uchar *disp_selected_pyr, oclMat &temp, StereoConstantSpaceBP rthis,
+                                     int msg_step, int h, int w, int nr_plane)
+            {
+                for(int t = 0; t < rthis.iters; t++)
+                    calc_all_iterations_caller(u, d, l, r, data_cost_selected, disp_selected_pyr, temp, rthis,
+                                               msg_step, h, w, nr_plane, t & 1);
+            }
+
+            ///////////////////////////////////////////////////////////////////////////////////////////////
+            //////////////////////////compute_disp////////////////////////////////////////////////////////
+            /////////////////////////////////////////////////////////////////////////////////////////////
+            void compute_disp(uchar *u, uchar *d, uchar *l, uchar *r, uchar *data_cost_selected,
+                              uchar *disp_selected_pyr, StereoConstantSpaceBP &rthis, size_t msg_step,
+                              oclMat &disp, int nr_plane)
+            {
+                Context  *clCxt = disp.clCxt;
+                int data_type = rthis.msg_type;
+
+                string kernelName = get_kernel_name("compute_disp_", data_type);
+
+                cl_kernel kernel = openCLGetKernelFromSource(clCxt, &stereocsbp, kernelName);
+
+                size_t blockSize = 256;
+                size_t localThreads[]  = {32, 8};
+                size_t globalThreads[] = {divUp(disp.cols, localThreads[0]) * localThreads[0],
+                                          divUp(disp.rows, localThreads[1]) * localThreads[1]
+                                         };
+
+                int step_size = disp.step / disp.elemSize();
+                int disp_step = disp.rows * msg_step;
+                openCLVerifyKernel(clCxt, kernel, &blockSize, globalThreads, localThreads);
+                openCLSafeCall(clSetKernelArg(kernel, 0,  sizeof(cl_mem), (void *)&u));
+                openCLSafeCall(clSetKernelArg(kernel, 1,  sizeof(cl_mem), (void *)&d));
+                openCLSafeCall(clSetKernelArg(kernel, 2,  sizeof(cl_mem), (void *)&l));
+                openCLSafeCall(clSetKernelArg(kernel, 3,  sizeof(cl_mem), (void *)&r));
+                openCLSafeCall(clSetKernelArg(kernel, 4,  sizeof(cl_mem), (void *)&data_cost_selected));
+                openCLSafeCall(clSetKernelArg(kernel, 5,  sizeof(cl_mem), (void *)&disp_selected_pyr));
+                openCLSafeCall(clSetKernelArg(kernel, 6,  sizeof(cl_mem), (void *)&disp.data));
+                openCLSafeCall(clSetKernelArg(kernel, 7,  sizeof(cl_int), (void *)&step_size));
+                openCLSafeCall(clSetKernelArg(kernel, 8,  sizeof(cl_int), (void *)&disp.cols));
+                openCLSafeCall(clSetKernelArg(kernel, 9,  sizeof(cl_int), (void *)&disp.rows));
+                openCLSafeCall(clSetKernelArg(kernel, 10, sizeof(cl_int), (void *)&nr_plane));
+                openCLSafeCall(clSetKernelArg(kernel, 11, sizeof(cl_int), (void *)&msg_step));
+                openCLSafeCall(clSetKernelArg(kernel, 12, sizeof(cl_int), (void *)&disp_step));
+                openCLSafeCall(clEnqueueNDRangeKernel(clCxt->impl->clCmdQueue, kernel, 2, NULL,
+                                                      globalThreads, localThreads, 0, NULL, NULL));
+
+                clFinish(clCxt->impl->clCmdQueue);
+                openCLSafeCall(clReleaseKernel(kernel));
+            }
+        }
+    }
+}
+namespace
+{
+    const float DEFAULT_MAX_DATA_TERM = 30.0f;
+    const float DEFAULT_DATA_WEIGHT = 1.0f;
+    const float DEFAULT_MAX_DISC_TERM = 160.0f;
+    const float DEFAULT_DISC_SINGLE_JUMP = 10.0f;
+
+    template<typename T>
+    void print_gpu_mat(const oclMat &mat)
+    {
+        T *data_1 = new T[mat.rows * mat.cols * mat.channels()];
+        Context  *clCxt = mat.clCxt;
+        int status = clEnqueueReadBuffer(clCxt -> impl->clCmdQueue, (cl_mem)mat.data, CL_TRUE, 0,
+                                         mat.rows * mat.cols * mat.channels() * sizeof(T), data_1, 0, NULL, NULL);
+
+        if(status != CL_SUCCESS)
+            cout << "error " << status << endl;
+
+        cout << ".........................................................." << endl;
+        cout << "elemSize() " << mat.elemSize() << endl;
+        cout << "elemSize() " << mat.elemSize1() << endl;
+        cout << "channels: " << mat.channels() << endl;
+        cout << "rows: " << mat.rows << endl;
+        cout << "cols: " << mat.cols << endl;
+
+        for(int i = 0; i < 100; i++)
+        {
+            for(int j = 0; j < 30; j++)
+            {
+                cout << (int)data_1[i * mat.cols * mat.channels() + j] << " ";
+            }
+            cout << endl;
+        }
+    }
+}
+
+
+void cv::ocl::StereoConstantSpaceBP::estimateRecommendedParams(int width, int height, int &ndisp, int &iters, int &levels, int &nr_plane)
+{
+    ndisp = (int) ((float) width / 3.14f);
+    if ((ndisp & 1) != 0)
+        ndisp++;
+
+    int mm = ::max(width, height);
+    iters = mm / 100 + ((mm > 1200) ? - 4 : 4);
+
+    levels = (int)::log(static_cast<double>(mm)) * 2 / 3;
+    if (levels == 0) levels++;
+
+    nr_plane = (int) ((float) ndisp / std::pow(2.0, levels + 1));
+}
+
+cv::ocl::StereoConstantSpaceBP::StereoConstantSpaceBP(int ndisp_, int iters_, int levels_, int nr_plane_,
+        int msg_type_)
+
+    : ndisp(ndisp_), iters(iters_), levels(levels_), nr_plane(nr_plane_),
+      max_data_term(DEFAULT_MAX_DATA_TERM), data_weight(DEFAULT_DATA_WEIGHT),
+      max_disc_term(DEFAULT_MAX_DISC_TERM), disc_single_jump(DEFAULT_DISC_SINGLE_JUMP), min_disp_th(0),
+      msg_type(msg_type_), use_local_init_data_cost(true)
+{
+    CV_Assert(msg_type_ == CV_32F || msg_type_ == CV_16S);
+}
+
+
+cv::ocl::StereoConstantSpaceBP::StereoConstantSpaceBP(int ndisp_, int iters_, int levels_, int nr_plane_,
+        float max_data_term_, float data_weight_, float max_disc_term_, float disc_single_jump_,
+        int min_disp_th_, int msg_type_)
+    : ndisp(ndisp_), iters(iters_), levels(levels_), nr_plane(nr_plane_),
+      max_data_term(max_data_term_), data_weight(data_weight_),
+      max_disc_term(max_disc_term_), disc_single_jump(disc_single_jump_), min_disp_th(min_disp_th_),
+      msg_type(msg_type_), use_local_init_data_cost(true)
+{
+    CV_Assert(msg_type_ == CV_32F || msg_type_ == CV_16S);
+}
+
+template<class T>
+static void csbp_operator(StereoConstantSpaceBP &rthis, oclMat u[2], oclMat d[2], oclMat l[2], oclMat r[2],
+                          oclMat disp_selected_pyr[2], oclMat &data_cost, oclMat &data_cost_selected,
+                          oclMat &temp, oclMat &out, const oclMat &left, const oclMat &right, oclMat &disp)
+{
+    CV_DbgAssert(0 < rthis.ndisp && 0 < rthis.iters && 0 < rthis.levels && 0 < rthis.nr_plane
+                 && left.rows == right.rows && left.cols == right.cols && left.type() == right.type());
+
+    CV_Assert(rthis.levels <= 8 && (left.type() == CV_8UC1 || left.type() == CV_8UC3));
+
+    const Scalar zero = Scalar::all(0);
+
+    ////////////////////////////////////Init///////////////////////////////////////////////////
+    int rows = left.rows;
+    int cols = left.cols;
+
+    rthis.levels = min(rthis.levels, int(log((double)rthis.ndisp) / log(2.0)));
+    int levels = rthis.levels;
+
+    AutoBuffer<int> buf(levels * 4);
+
+    int *cols_pyr = buf;
+    int *rows_pyr = cols_pyr + levels;
+    int *nr_plane_pyr = rows_pyr + levels;
+    int *step_pyr = nr_plane_pyr + levels;
+
+    cols_pyr[0] = cols;
+    rows_pyr[0] = rows;
+    nr_plane_pyr[0] = rthis.nr_plane;
+
+    const int n = 64;
+    step_pyr[0] = alignSize(cols * sizeof(T), n) / sizeof(T);
+    for (int i = 1; i < levels; i++)
+    {
+        cols_pyr[i] = (cols_pyr[i-1] + 1) / 2;
+        rows_pyr[i] = (rows_pyr[i-1] + 1) / 2;
+
+        nr_plane_pyr[i] = nr_plane_pyr[i-1] * 2;
+
+        step_pyr[i] = alignSize(cols_pyr[i] * sizeof(T), n) / sizeof(T);
+    }
+
+    Size msg_size(step_pyr[0], rows * nr_plane_pyr[0]);
+    Size data_cost_size(step_pyr[0], rows * nr_plane_pyr[0] * 2);
+
+    u[0].create(msg_size, DataType<T>::type);
+    d[0].create(msg_size, DataType<T>::type);
+    l[0].create(msg_size, DataType<T>::type);
+    r[0].create(msg_size, DataType<T>::type);
+
+    u[1].create(msg_size, DataType<T>::type);
+    d[1].create(msg_size, DataType<T>::type);
+    l[1].create(msg_size, DataType<T>::type);
+    r[1].create(msg_size, DataType<T>::type);
+
+    disp_selected_pyr[0].create(msg_size, DataType<T>::type);
+    disp_selected_pyr[1].create(msg_size, DataType<T>::type);
+
+    data_cost.create(data_cost_size, DataType<T>::type);
+    data_cost_selected.create(msg_size, DataType<T>::type);
+
+    step_pyr[0] = data_cost.step / sizeof(T);
+
+    Size temp_size = data_cost_size;
+    if (data_cost_size.width * data_cost_size.height < step_pyr[levels - 1] * rows_pyr[levels - 1] * rthis.ndisp)
+        temp_size = Size(step_pyr[levels - 1], rows_pyr[levels - 1] * rthis.ndisp);
+
+    temp.create(temp_size, DataType<T>::type);
+
+    ///////////////////////////////// Compute////////////////////////////////////////////////
+
+    //csbp::load_constants(rthis.ndisp, rthis.max_data_term, rthis.data_weight,
+    //   rthis.max_disc_term, rthis.disc_single_jump, rthis.min_disp_th, left, right, temp);
+
+    l[0] = zero;
+    d[0] = zero;
+    r[0] = zero;
+    u[0] = zero;
+
+    l[1] = zero;
+    d[1] = zero;
+    r[1] = zero;
+    u[1] = zero;
+
+    data_cost = zero;
+    data_cost_selected = zero;
+
+    int cur_idx = 0;
+
+    for (int i = levels - 1; i >= 0; i--)
+    {
+        if (i == levels - 1)
+        {
+            cv::ocl::stereoCSBP::init_data_cost(left, right, temp, rthis, disp_selected_pyr[cur_idx].ptr(),
+                                                data_cost_selected.ptr(), step_pyr[i], rows_pyr[i], cols_pyr[i],
+                                                i, nr_plane_pyr[i]);
+        }
+        else
+        {
+            cv::ocl::stereoCSBP::compute_data_cost(disp_selected_pyr[cur_idx].ptr(), data_cost.ptr(), rthis, step_pyr[i],
+                                                   step_pyr[i+1], left, right, rows_pyr[i], cols_pyr[i], rows_pyr[i+1], i,
+                                                   nr_plane_pyr[i+1]);
+
+
+            int new_idx = (cur_idx + 1) & 1;
+
+            cv::ocl::stereoCSBP::init_message(u[new_idx].ptr(), d[new_idx].ptr(), l[new_idx].ptr(), r[new_idx].ptr(),
+                                              u[cur_idx].ptr(), d[cur_idx].ptr(), l[cur_idx].ptr(), r[cur_idx].ptr(),
+                                              disp_selected_pyr[new_idx].ptr(), disp_selected_pyr[cur_idx].ptr(),
+                                              data_cost_selected.ptr(), data_cost.ptr(), temp, rthis, step_pyr[i],
+                                              step_pyr[i+1], rows_pyr[i], cols_pyr[i], nr_plane_pyr[i], rows_pyr[i+1],
+                                              cols_pyr[i+1], nr_plane_pyr[i+1]);
+
+            cur_idx = new_idx;
+        }
+
+        cv::ocl::stereoCSBP::calc_all_iterations(u[cur_idx].ptr(), d[cur_idx].ptr(), l[cur_idx].ptr(), r[cur_idx].ptr(),
+                data_cost_selected.ptr(), disp_selected_pyr[cur_idx].ptr(), temp,
+                rthis, step_pyr[i], rows_pyr[i], cols_pyr[i], nr_plane_pyr[i]);
+    }
+
+
+    if (disp.empty())
+        disp.create(rows, cols, CV_16S);
+
+    out = ((disp.type() == CV_16S) ? disp : (out.create(rows, cols, CV_16S), out));
+    out = zero;
+
+    stereoCSBP::compute_disp(u[cur_idx].ptr(), d[cur_idx].ptr(), l[cur_idx].ptr(), r[cur_idx].ptr(),
+                             data_cost_selected.ptr(), disp_selected_pyr[cur_idx].ptr(), rthis, step_pyr[0],
+                             out, nr_plane_pyr[0]);
+
+
+    if (disp.type() != CV_16S)
+        out.convertTo(disp, disp.type());
+}
+
+
+typedef void (*csbp_operator_t)(StereoConstantSpaceBP &rthis, oclMat u[2], oclMat d[2], oclMat l[2], oclMat r[2],
+                                oclMat disp_selected_pyr[2], oclMat &data_cost, oclMat &data_cost_selected,
+                                oclMat &temp, oclMat &out, const oclMat &left, const oclMat &right, oclMat &disp);
+
+const static csbp_operator_t operators[] = {0, 0, 0, csbp_operator<short>, 0, csbp_operator<float>, 0, 0};
+
+void cv::ocl::StereoConstantSpaceBP::operator()(const oclMat &left, const oclMat &right, oclMat &disp)
+{
+
+    CV_Assert(msg_type == CV_32F || msg_type == CV_16S);
+    operators[msg_type](*this, u, d, l, r, disp_selected_pyr, data_cost, data_cost_selected, temp, out,
+                        left, right, disp);
+}
+
+#endif /* !defined (HAVE_OPENCL) */
diff --git a/modules/ocl/src/stereobm.cpp b/modules/ocl/src/stereobm.cpp
new file mode 100644 (file)
index 0000000..a7e06b0
--- /dev/null
@@ -0,0 +1,291 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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 <vector>
+
+using namespace cv;
+using namespace cv::ocl;
+using namespace std;
+
+////////////////////////////////////////////////////////////////////////
+///////////////// stereoBM /////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+#if !defined (HAVE_OPENCL)
+
+namespace cv
+{
+    namespace ocl
+    {
+        cv::ocl::StereoBM_GPU::StereoBM_GPU()
+        {
+            throw_nogpu();
+        }
+        cv::ocl::StereoBM_GPU::StereoBM_GPU(int, int, int)
+        {
+            throw_nogpu();
+        }
+        bool cv::ocl::StereoBM_GPU::checkIfGpuCallReasonable()
+        {
+            throw_nogpu();
+            return false;
+        }
+        void cv::ocl::StereoBM_GPU::operator() ( const oclMat &, const oclMat &, oclMat &)
+        {
+            throw_nogpu();
+        }
+    }
+}
+
+#else /* !defined (HAVE_OPENCL) */
+
+namespace cv
+{
+    namespace ocl
+    {
+
+        ///////////////////////////OpenCL kernel strings///////////////////////////
+        extern const char *stereobm;
+
+    }
+}
+namespace cv
+{
+    namespace ocl
+    {
+        namespace stereoBM
+        {
+            /////////////////////////////////////////////////////////////////////////
+            //////////////////////////prefilter_xsbel////////////////////////////////
+            ////////////////////////////////////////////////////////////////////////
+            void prefilter_xsobel(const oclMat &input, oclMat &output, int prefilterCap)
+            {
+                Context *clCxt = input.clCxt;
+
+                string kernelName = "prefilter_xsobel";
+                cl_kernel kernel = openCLGetKernelFromSource(clCxt, &stereobm, kernelName);
+
+                size_t blockSize = 1;
+                size_t globalThreads[3] = { input.cols, input.rows, 1 };
+                size_t localThreads[3]  = { blockSize, blockSize, 1 };
+
+                openCLVerifyKernel(clCxt, kernel, &blockSize, globalThreads, localThreads);
+                openCLSafeCall(clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&input.data));
+                openCLSafeCall(clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&output.data));
+                openCLSafeCall(clSetKernelArg(kernel, 2, sizeof(cl_int), (void *)&input.rows));
+                openCLSafeCall(clSetKernelArg(kernel, 3, sizeof(cl_int), (void *)&input.cols));
+                openCLSafeCall(clSetKernelArg(kernel, 4, sizeof(cl_int), (void *)&prefilterCap));
+
+                openCLSafeCall(clEnqueueNDRangeKernel(clCxt->impl->clCmdQueue, kernel, 3, NULL,
+                                                      globalThreads, localThreads, 0, NULL, NULL));
+
+                clFinish(clCxt->impl->clCmdQueue);
+                openCLSafeCall(clReleaseKernel(kernel));
+
+            }
+            //////////////////////////////////////////////////////////////////////////
+            //////////////////////////////common////////////////////////////////////
+            ////////////////////////////////////////////////////////////////////////
+#define N_DISPARITIES 8
+#define ROWSperTHREAD 21
+#define BLOCK_W 128
+            static inline int divUp(int total, int grain)
+            {
+                return (total + grain - 1) / grain;
+            }
+            ////////////////////////////////////////////////////////////////////////////
+            ///////////////////////////////stereoBM_GPU////////////////////////////////
+            ////////////////////////////////////////////////////////////////////////////
+            void stereo_bm(const oclMat &left, const oclMat &right,  oclMat &disp,
+                           int maxdisp, int winSize,  oclMat &minSSD_buf)
+            {
+                int winsz2 = winSize >> 1;
+
+                //if(winsz2 == 0 || winsz2 >= calles_num)
+                //cv::ocl:error("Unsupported window size", __FILE__, __LINE__, __FUNCTION__);
+
+                Context *clCxt = left.clCxt;
+
+                string kernelName = "stereoKernel";
+                cl_kernel kernel = openCLGetKernelFromSource(clCxt, &stereobm, kernelName);
+
+                disp.setTo(Scalar_<unsigned char>::all(0));
+                minSSD_buf.setTo(Scalar_<unsigned int>::all(0xFFFFFFFF));
+
+                size_t minssd_step = minSSD_buf.step / minSSD_buf.elemSize();
+                size_t local_mem_size = (BLOCK_W + N_DISPARITIES * (BLOCK_W + 2 * winsz2)) *
+                                        sizeof(cl_uint);
+                size_t blockSize = 1;
+                size_t localThreads[]  = { BLOCK_W, 1};
+                size_t globalThreads[] = { divUp(left.cols - maxdisp - 2 * winsz2, BLOCK_W) * BLOCK_W,
+                                           divUp(left.rows - 2 * winsz2, ROWSperTHREAD)
+                                         };
+
+                openCLVerifyKernel(clCxt, kernel, &blockSize, globalThreads, localThreads);
+                openCLSafeCall(clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&left.data));
+                openCLSafeCall(clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&right.data));
+                openCLSafeCall(clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&minSSD_buf.data));
+                openCLSafeCall(clSetKernelArg(kernel, 3, sizeof(cl_int), (void *)&minssd_step));
+                openCLSafeCall(clSetKernelArg(kernel, 4, sizeof(cl_mem), (void *)&disp.data));
+                openCLSafeCall(clSetKernelArg(kernel, 5, sizeof(cl_int), (void *)&disp.step));
+                openCLSafeCall(clSetKernelArg(kernel, 6, sizeof(cl_int), (void *)&left.cols));
+                openCLSafeCall(clSetKernelArg(kernel, 7, sizeof(cl_int), (void *)&left.rows));
+                openCLSafeCall(clSetKernelArg(kernel, 8, sizeof(cl_int), (void *)&left.step));
+                openCLSafeCall(clSetKernelArg(kernel, 9, sizeof(cl_int), (void *)&maxdisp));
+                openCLSafeCall(clSetKernelArg(kernel, 10, sizeof(cl_int), (void *)&winsz2));
+                openCLSafeCall(clSetKernelArg(kernel, 11, local_mem_size, (void *)NULL));
+
+                openCLSafeCall(clEnqueueNDRangeKernel(clCxt->impl->clCmdQueue, kernel, 2, NULL,
+                                                      globalThreads, localThreads, 0, NULL, NULL));
+
+
+                clFinish(clCxt->impl->clCmdQueue);
+                openCLSafeCall(clReleaseKernel(kernel));
+            }
+            ////////////////////////////////////////////////////////////////////////////
+            ///////////////////////////////postfilter_textureness///////////////////////
+            ////////////////////////////////////////////////////////////////////////////
+            void postfilter_textureness(oclMat &left, int winSize,
+                                        float avergeTexThreshold, oclMat &disparity)
+            {
+                Context *clCxt = left.clCxt;
+
+                string kernelName = "textureness_kernel";
+                cl_kernel kernel = openCLGetKernelFromSource(clCxt, &stereobm, kernelName);
+
+                size_t blockSize = 1;
+                size_t localThreads[]  = { BLOCK_W, blockSize};
+                size_t globalThreads[] = { divUp(left.cols, BLOCK_W) * BLOCK_W,
+                                           divUp(left.rows, 2 * ROWSperTHREAD)
+                                         };
+
+                size_t local_mem_size = (localThreads[0] + localThreads[0] + (winSize / 2) * 2) * sizeof(float);
+
+                openCLVerifyKernel(clCxt, kernel, &blockSize, globalThreads, localThreads);
+                openCLSafeCall(clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&disparity.data));
+                openCLSafeCall(clSetKernelArg(kernel, 1, sizeof(cl_int), (void *)&disparity.rows));
+                openCLSafeCall(clSetKernelArg(kernel, 2, sizeof(cl_int), (void *)&disparity.cols));
+                openCLSafeCall(clSetKernelArg(kernel, 3, sizeof(cl_int), (void *)&disparity.step));
+                openCLSafeCall(clSetKernelArg(kernel, 4, sizeof(cl_mem), (void *)&left.data));
+                openCLSafeCall(clSetKernelArg(kernel, 5, sizeof(cl_int), (void *)&left.rows));
+                openCLSafeCall(clSetKernelArg(kernel, 6, sizeof(cl_int), (void *)&left.cols));
+                openCLSafeCall(clSetKernelArg(kernel, 7, sizeof(cl_int), (void *)&winSize));
+                openCLSafeCall(clSetKernelArg(kernel, 8, sizeof(cl_float), (void *)&avergeTexThreshold));
+                openCLSafeCall(clSetKernelArg(kernel, 9, local_mem_size, NULL));
+                openCLSafeCall(clEnqueueNDRangeKernel(clCxt->impl->clCmdQueue, kernel, 2, NULL,
+                                                      globalThreads, localThreads, 0, NULL, NULL));
+
+                clFinish(clCxt->impl->clCmdQueue);
+                openCLSafeCall(clReleaseKernel(kernel));
+            }
+            //////////////////////////////////////////////////////////////////////////////
+            /////////////////////////////////////operator/////////////////////////////////
+            /////////////////////////////////////////////////////////////////////////////
+            void operator_(oclMat &minSSD, oclMat &leBuf, oclMat &riBuf, int preset, int ndisp,
+                           int winSize, float avergeTexThreshold, const oclMat &left,
+                           const oclMat &right, oclMat &disparity)
+
+            {
+                CV_DbgAssert(left.rows == right.rows && left.cols == right.cols);
+                CV_DbgAssert(left.type() == CV_8UC1);
+                CV_DbgAssert(right.type() == CV_8UC1);
+
+                disparity.create(left.size(), CV_8UC1);
+                minSSD.create(left.size(), CV_32SC1);
+
+                oclMat le_for_bm =  left;
+                oclMat ri_for_bm = right;
+
+                if (preset == cv::ocl::StereoBM_GPU::PREFILTER_XSOBEL)
+                {
+                    leBuf.create( left.size(),  left.type());
+                    riBuf.create(right.size(), right.type());
+
+                    prefilter_xsobel( left, leBuf, 31);
+                    prefilter_xsobel(right, riBuf, 31);
+
+                    le_for_bm = leBuf;
+                    ri_for_bm = riBuf;
+                }
+
+                stereo_bm(le_for_bm, ri_for_bm, disparity, ndisp, winSize, minSSD);
+
+                if (avergeTexThreshold)
+                {
+                    postfilter_textureness(le_for_bm, winSize, avergeTexThreshold, disparity);
+                }
+            }
+        }
+    }
+}
+const float defaultAvgTexThreshold = 3;
+
+cv::ocl::StereoBM_GPU::StereoBM_GPU()
+    : preset(BASIC_PRESET), ndisp(DEFAULT_NDISP), winSize(DEFAULT_WINSZ),
+      avergeTexThreshold(defaultAvgTexThreshold)  {}
+
+cv::ocl::StereoBM_GPU::StereoBM_GPU(int preset_, int ndisparities_, int winSize_)
+    : preset(preset_), ndisp(ndisparities_), winSize(winSize_),
+      avergeTexThreshold(defaultAvgTexThreshold)
+{
+    const int max_supported_ndisp = 1 << (sizeof(unsigned char) * 8);
+    CV_Assert(0 < ndisp && ndisp <= max_supported_ndisp);
+    CV_Assert(ndisp % 8 == 0);
+    CV_Assert(winSize % 2 == 1);
+}
+
+bool cv::ocl::StereoBM_GPU::checkIfGpuCallReasonable()
+{
+    return true;
+}
+
+void cv::ocl::StereoBM_GPU::operator() ( const oclMat &left, const oclMat &right,
+        oclMat &disparity)
+{
+    cv::ocl::stereoBM::operator_(minSSD, leBuf, riBuf, preset, ndisp, winSize, avergeTexThreshold, left, right, disparity);
+}
+
+#endif /* !defined (HAVE_OPENCL) */
diff --git a/modules/ocl/src/stereobp.cpp b/modules/ocl/src/stereobp.cpp
new file mode 100644 (file)
index 0000000..ba53f15
--- /dev/null
@@ -0,0 +1,661 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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 <vector>
+
+using namespace cv;
+using namespace cv::ocl;
+using namespace std;
+
+////////////////////////////////////////////////////////////////////////
+///////////////// stereoBP /////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+#if !defined (HAVE_OPENCL)
+
+namespace cv
+{
+    namespace ocl
+    {
+        void cv::ocl::StereoBeliefPropagation::estimateRecommendedParams(int, int, int &, int &, int &)
+        {
+            throw_nogpu();
+        }
+
+        cv::ocl::StereoBeliefPropagation::StereoBeliefPropagation(int, int, int, int)
+        {
+            throw_nogpu();
+        }
+
+        cv::ocl::StereoBeliefPropagation::StereoBeliefPropagation(int, int, int, float, float, float, float, int)
+        {
+            throw_nogpu();
+        }
+
+        void cv::ocl::StereoBeliefPropagation::operator()(const oclMat &, const oclMat &, oclMat &)
+        {
+            throw_nogpu();
+        }
+
+        void cv::ocl::StereoBeliefPropagation::operator()(const oclMat &, oclMat &)
+        {
+            throw_nogpu();
+        }
+    }
+}
+
+#else /* !defined (HAVE_OPENCL) */
+
+namespace cv
+{
+    namespace ocl
+    {
+
+        ///////////////////////////OpenCL kernel strings///////////////////////////
+        extern const char *stereobp;
+    }
+
+}
+namespace cv
+{
+    namespace ocl
+    {
+        namespace stereoBP
+        {
+            //////////////////////////////////////////////////////////////////////////
+            //////////////////////////////common////////////////////////////////////
+            ////////////////////////////////////////////////////////////////////////
+            typedef struct
+            {
+                int   cndisp;
+                float cmax_data_term;
+                float cdata_weight;
+                float cmax_disc_term;
+                float cdisc_single_jump;
+            } con_struct_t;
+
+            cl_mem cl_con_struct =  NULL;
+            void load_constants(Context *clCxt, int ndisp, float max_data_term, float data_weight,
+                                float max_disc_term, float disc_single_jump)
+            {
+                con_struct_t *con_struct = new con_struct_t;
+                con_struct -> cndisp            = ndisp;
+                con_struct -> cmax_data_term    = max_data_term;
+                con_struct -> cdata_weight      = data_weight;
+                con_struct -> cmax_disc_term    = max_data_term;
+                con_struct -> cdisc_single_jump = disc_single_jump;
+
+                cl_con_struct = load_constant(clCxt->impl->clContext, clCxt->impl->clCmdQueue, (void *)con_struct,
+                                              sizeof(con_struct_t));
+
+                delete con_struct;
+            }
+            void release_constants()
+            {
+                openCLFree(cl_con_struct);
+            }
+            static inline int divUp(int total, int grain)
+            {
+                return (total + grain - 1) / grain;
+            }
+            /////////////////////////////////////////////////////////////////////////////
+            ///////////////////////////comp data////////////////////////////////////////
+            /////////////////////////////////////////////////////////////////////////
+            void  comp_data_call(const oclMat &left, const oclMat &right, oclMat &data, int disp,                                float cmax_data_term, float cdata_weight)
+            {
+                Context  *clCxt = left.clCxt;
+                int channels = left.channels();
+                int data_type = data.type();
+
+                string kernelName = "comp_data_";
+                stringstream idxStr;
+                if(data_type == CV_16S)
+                    idxStr << "0";
+                else
+                    idxStr << "1";
+                kernelName += idxStr.str();
+
+                cl_kernel kernel = openCLGetKernelFromSource(clCxt, &stereobp, kernelName);
+
+                size_t blockSize = 32;
+                size_t localThreads[]  = {32, 8};
+                size_t globalThreads[] = {divUp(left.cols, localThreads[0]) * localThreads[0],
+                                          divUp(left.rows, localThreads[1]) * localThreads[1]
+                                         };
+
+                openCLVerifyKernel(clCxt, kernel, &blockSize, globalThreads, localThreads);
+                openCLSafeCall(clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&left.data));
+                openCLSafeCall(clSetKernelArg(kernel, 1, sizeof(cl_int), (void *)&left.rows));
+                openCLSafeCall(clSetKernelArg(kernel, 2, sizeof(cl_int), (void *)&left.cols));
+                openCLSafeCall(clSetKernelArg(kernel, 3, sizeof(cl_int), (void *)&left.step));
+                openCLSafeCall(clSetKernelArg(kernel, 4, sizeof(cl_mem), (void *)&right.data));
+                openCLSafeCall(clSetKernelArg(kernel, 5, sizeof(cl_int), (void *)&right.step));
+                openCLSafeCall(clSetKernelArg(kernel, 6, sizeof(cl_mem), (void *)&data.data));
+                openCLSafeCall(clSetKernelArg(kernel, 7, sizeof(cl_int), (void *)&data.cols));
+                openCLSafeCall(clSetKernelArg(kernel, 8, sizeof(cl_int), (void *)&data.step));
+                openCLSafeCall(clSetKernelArg(kernel, 9, sizeof(cl_mem), (void *)&cl_con_struct));
+                //openCLSafeCall(clSetKernelArg(kernel,12,sizeof(cl_int),(void*)&disp));
+                //openCLSafeCall(clSetKernelArg(kernel,13,sizeof(cl_float),(void*)&cmax_data_term));
+                //openCLSafeCall(clSetKernelArg(kernel,14,sizeof(cl_float),(void*)&cdata_weight));
+                openCLSafeCall(clSetKernelArg(kernel, 10, sizeof(cl_int), (void *)&channels));
+
+                openCLSafeCall(clEnqueueNDRangeKernel(clCxt->impl->clCmdQueue, kernel, 2, NULL,
+                                                      globalThreads, localThreads, 0, NULL, NULL));
+
+                clFinish(clCxt->impl->clCmdQueue);
+                openCLSafeCall(clReleaseKernel(kernel));
+            }
+            ///////////////////////////////////////////////////////////////////////////////////
+            /////////////////////////data set down////////////////////////////////////////////
+            /////////////////////////////////////////////////////////////////////////////////
+            void data_step_down_call(int dst_cols, int dst_rows, int src_rows,
+                                     const oclMat &src, oclMat &dst, int disp)
+            {
+                Context  *clCxt = src.clCxt;
+                int data_type = src.type();
+
+                string kernelName = "data_step_down_";
+                stringstream idxStr;
+                if(data_type == CV_16S)
+                    idxStr << "0";
+                else
+                    idxStr << "1";
+                kernelName += idxStr.str();
+
+                cl_kernel kernel = openCLGetKernelFromSource(clCxt, &stereobp, kernelName);
+
+                size_t blockSize = 32;
+                size_t localThreads[]  = {32, 8};
+                size_t globalThreads[] = {divUp(dst_cols, localThreads[0]) * localThreads[0],
+                                          divUp(dst_rows, localThreads[1]) * localThreads[1]
+                                         };
+
+                openCLVerifyKernel(clCxt, kernel, &blockSize, globalThreads, localThreads);
+                openCLSafeCall(clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&src.data));
+                openCLSafeCall(clSetKernelArg(kernel, 1, sizeof(cl_int), (void *)&src_rows));
+                openCLSafeCall(clSetKernelArg(kernel, 2, sizeof(cl_int), (void *)&src.cols));
+                openCLSafeCall(clSetKernelArg(kernel, 3, sizeof(cl_mem), (void *)&dst.data));
+                openCLSafeCall(clSetKernelArg(kernel, 4, sizeof(cl_int), (void *)&dst_rows));
+                openCLSafeCall(clSetKernelArg(kernel, 5, sizeof(cl_int), (void *)&dst_cols));
+                openCLSafeCall(clSetKernelArg(kernel, 6, sizeof(cl_int), (void *)&dst.cols));
+                openCLSafeCall(clSetKernelArg(kernel, 7, sizeof(cl_int), (void *)&disp));
+
+                openCLSafeCall(clEnqueueNDRangeKernel(clCxt->impl->clCmdQueue, kernel, 2, NULL,
+                                                      globalThreads, localThreads, 0, NULL, NULL));
+
+                clFinish(clCxt->impl->clCmdQueue);
+                openCLSafeCall(clReleaseKernel(kernel));
+            }
+            /////////////////////////////////////////////////////////////////////////////////
+            ///////////////////////////live up message////////////////////////////////////////
+            /////////////////////////////////////////////////////////////////////////////////
+            void level_up_message_call(int dst_idx, int dst_cols, int dst_rows, int src_rows,
+                                       oclMat &src, oclMat &dst, int ndisp)
+            {
+                Context  *clCxt = src.clCxt;
+                int data_type = src.type();
+
+                string kernelName = "level_up_message_";
+                stringstream idxStr;
+                if(data_type == CV_16S)
+                    idxStr << "0";
+                else
+                    idxStr << "1";
+                kernelName += idxStr.str();
+
+                cl_kernel kernel = openCLGetKernelFromSource(clCxt, &stereobp, kernelName);
+
+                size_t blockSize = 32;
+                size_t localThreads[]  = {32, 8};
+                size_t globalThreads[] = {divUp(dst_cols, localThreads[0]) * localThreads[0],
+                                          divUp(dst_rows, localThreads[1]) * localThreads[1]
+                                         };
+
+                openCLVerifyKernel(clCxt, kernel, &blockSize, globalThreads, localThreads);
+                openCLSafeCall(clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&src.data));
+                openCLSafeCall(clSetKernelArg(kernel, 1, sizeof(cl_int), (void *)&src_rows));
+                openCLSafeCall(clSetKernelArg(kernel, 2, sizeof(cl_int), (void *)&src.step));
+                openCLSafeCall(clSetKernelArg(kernel, 3, sizeof(cl_mem), (void *)&dst.data));
+                openCLSafeCall(clSetKernelArg(kernel, 4, sizeof(cl_int), (void *)&dst_rows));
+                openCLSafeCall(clSetKernelArg(kernel, 5, sizeof(cl_int), (void *)&dst_cols));
+                openCLSafeCall(clSetKernelArg(kernel, 6, sizeof(cl_int), (void *)&dst.step));
+                openCLSafeCall(clSetKernelArg(kernel, 7, sizeof(cl_int), (void *)&ndisp));
+
+                openCLSafeCall(clEnqueueNDRangeKernel(clCxt->impl->clCmdQueue, kernel, 2, NULL,
+                                                      globalThreads, localThreads, 0, NULL, NULL));
+
+                clFinish(clCxt->impl->clCmdQueue);
+                openCLSafeCall(clReleaseKernel(kernel));
+            }
+            void level_up_messages_calls(int dst_idx, int dst_cols, int dst_rows, int src_rows,
+                                         oclMat *mus, oclMat *mds, oclMat *mls, oclMat *mrs,
+                                         int ndisp)
+            {
+                int src_idx = (dst_idx + 1) & 1;
+
+                level_up_message_call(dst_idx, dst_cols, dst_rows, src_rows,
+                                      mus[src_idx], mus[dst_idx], ndisp);
+
+                level_up_message_call(dst_idx, dst_cols, dst_rows, src_rows,
+                                      mds[src_idx], mds[dst_idx], ndisp);
+
+                level_up_message_call(dst_idx, dst_cols, dst_rows, src_rows,
+                                      mls[src_idx], mls[dst_idx], ndisp);
+
+                level_up_message_call(dst_idx, dst_cols, dst_rows, src_rows,
+                                      mrs[src_idx], mrs[dst_idx], ndisp);
+            }
+            //////////////////////////////////////////////////////////////////////////////////
+            //////////////////////////////cals_all_iterations_call///////////////////////////
+            /////////////////////////////////////////////////////////////////////////////////
+            void calc_all_iterations_call(int cols, int rows, oclMat &u, oclMat &d,
+                                          oclMat &l, oclMat &r, oclMat &data,
+                                          int t, int cndisp, float cmax_disc_term,
+                                          float cdisc_single_jump)
+            {
+                Context  *clCxt = l.clCxt;
+                int data_type = u.type();
+
+                string kernelName = "one_iteration_";
+                stringstream idxStr;
+                if(data_type == CV_16S)
+                    idxStr << "0";
+                else
+                    idxStr << "1";
+                kernelName += idxStr.str();
+
+                cl_kernel kernel = openCLGetKernelFromSource(clCxt, &stereobp, kernelName);
+
+                size_t blockSize = 32;
+                size_t localThreads[]  = {32, 8};
+                size_t globalThreads[] = {divUp(cols, (localThreads[0] << 1)) * (localThreads[0] << 1),
+                                          divUp(rows, localThreads[1]) * localThreads[1]
+                                         };
+
+                openCLVerifyKernel(clCxt, kernel, &blockSize, globalThreads, localThreads);
+                openCLSafeCall(clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&u.data));
+                openCLSafeCall(clSetKernelArg(kernel, 1, sizeof(cl_int), (void *)&u.step));
+                openCLSafeCall(clSetKernelArg(kernel, 2, sizeof(cl_int), (void *)&u.cols));
+                openCLSafeCall(clSetKernelArg(kernel, 3, sizeof(cl_mem), (void *)&data.data));
+                openCLSafeCall(clSetKernelArg(kernel, 4, sizeof(cl_int), (void *)&data.step));
+                openCLSafeCall(clSetKernelArg(kernel, 5, sizeof(cl_int), (void *)&data.cols));
+                openCLSafeCall(clSetKernelArg(kernel, 6, sizeof(cl_mem), (void *)&d.data));
+                openCLSafeCall(clSetKernelArg(kernel, 7, sizeof(cl_mem), (void *)&l.data));
+                openCLSafeCall(clSetKernelArg(kernel, 8, sizeof(cl_mem), (void *)&r.data));
+                openCLSafeCall(clSetKernelArg(kernel, 9, sizeof(cl_int), (void *)&t));
+                openCLSafeCall(clSetKernelArg(kernel, 10, sizeof(cl_int), (void *)&cols));
+                openCLSafeCall(clSetKernelArg(kernel, 11, sizeof(cl_int), (void *)&rows));
+                openCLSafeCall(clSetKernelArg(kernel, 12, sizeof(cl_int), (void *)&cndisp));
+                openCLSafeCall(clSetKernelArg(kernel, 13, sizeof(cl_float), (void *)&cmax_disc_term));
+                openCLSafeCall(clSetKernelArg(kernel, 14, sizeof(cl_float), (void *)&cdisc_single_jump));
+
+                openCLSafeCall(clEnqueueNDRangeKernel(clCxt->impl->clCmdQueue, kernel, 2, NULL,
+                                                      globalThreads, localThreads, 0, NULL, NULL));
+
+                clFinish(clCxt->impl->clCmdQueue);
+                openCLSafeCall(clReleaseKernel(kernel));
+            }
+
+            void calc_all_iterations_calls(int cols, int rows, int iters, oclMat &u,
+                                           oclMat &d, oclMat &l, oclMat &r,
+                                           oclMat &data, int cndisp, float cmax_disc_term,
+                                           float cdisc_single_jump)
+            {
+                for(int t = 0; t < iters; ++t)
+                    calc_all_iterations_call(cols, rows, u, d, l, r, data, t, cndisp,
+                                             cmax_disc_term, cdisc_single_jump);
+            }
+            ///////////////////////////////////////////////////////////////////////////////
+            ///////////////////////output///////////////////////////////////////////////////
+            ////////////////////////////////////////////////////////////////////////////////
+            void output_call(const oclMat &u, const oclMat &d, const oclMat l, const oclMat &r,
+                             const oclMat &data, oclMat &disp, int ndisp)
+            {
+                Context  *clCxt = u.clCxt;
+                int data_type = u.type();
+
+                string kernelName = "output_";
+                stringstream idxStr;
+                if(data_type == CV_16S)
+                    idxStr << "0";
+                else
+                    idxStr << "1";
+                kernelName += idxStr.str();
+
+                cl_kernel kernel = openCLGetKernelFromSource(clCxt, &stereobp, kernelName);
+
+                size_t blockSize = 32;
+                size_t localThreads[]  = {32, 8};
+                size_t globalThreads[] = {divUp(disp.cols, localThreads[0]) * localThreads[0],
+                                          divUp(disp.rows, localThreads[1]) * localThreads[1]
+                                         };
+
+                openCLVerifyKernel(clCxt, kernel, &blockSize, globalThreads, localThreads);
+                openCLSafeCall(clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&u.data));
+                openCLSafeCall(clSetKernelArg(kernel, 1, sizeof(cl_int), (void *)&u.step));
+                openCLSafeCall(clSetKernelArg(kernel, 2, sizeof(cl_int), (void *)&u.cols));
+                openCLSafeCall(clSetKernelArg(kernel, 3, sizeof(cl_mem), (void *)&d.data));
+                openCLSafeCall(clSetKernelArg(kernel, 4, sizeof(cl_mem), (void *)&l.data));
+                openCLSafeCall(clSetKernelArg(kernel, 5, sizeof(cl_mem), (void *)&r.data));
+                openCLSafeCall(clSetKernelArg(kernel, 6, sizeof(cl_mem), (void *)&data.data));
+                openCLSafeCall(clSetKernelArg(kernel, 7, sizeof(cl_mem), (void *)&disp.data));
+                openCLSafeCall(clSetKernelArg(kernel, 8, sizeof(cl_int), (void *)&disp.rows));
+                openCLSafeCall(clSetKernelArg(kernel, 9, sizeof(cl_int), (void *)&disp.cols));
+                openCLSafeCall(clSetKernelArg(kernel, 10, sizeof(cl_int), (void *)&disp.step));
+                openCLSafeCall(clSetKernelArg(kernel, 11, sizeof(cl_int), (void *)&ndisp));
+
+                openCLSafeCall(clEnqueueNDRangeKernel(clCxt->impl->clCmdQueue, kernel, 2, NULL,
+                                                      globalThreads, localThreads, 0, NULL, NULL));
+
+                clFinish(clCxt->impl->clCmdQueue);
+                openCLSafeCall(clReleaseKernel(kernel));
+
+            }
+        }
+    }
+}
+namespace
+{
+    const float DEFAULT_MAX_DATA_TERM = 10.0f;
+    const float DEFAULT_DATA_WEIGHT = 0.07f;
+    const float DEFAULT_MAX_DISC_TERM = 1.7f;
+    const float DEFAULT_DISC_SINGLE_JUMP = 1.0f;
+
+    template<typename T>
+    void print_gpu_mat(const oclMat &mat)
+    {
+        T *data_1 = new T[mat.rows * mat.cols * mat.channels()];
+        Context  *clCxt = mat.clCxt;
+        int status = clEnqueueReadBuffer(clCxt -> impl-> clCmdQueue, (cl_mem)mat.data, CL_TRUE, 0,
+                                         mat.rows * mat.cols * mat.channels() * sizeof(T), data_1, 0, NULL, NULL);
+
+        if(status != CL_SUCCESS)
+            cout << "error " << status << endl;
+
+        cout << ".........................................................." << endl;
+        cout << "elemSize() " << mat.elemSize() << endl;
+        cout << "elemSize() " << mat.elemSize1() << endl;
+        cout << "channels: " << mat.channels() << endl;
+        cout << "rows: " << mat.rows << endl;
+        cout << "cols: " << mat.cols << endl;
+
+        for(int i = 0; i < 30; i++)
+        {
+            for(int j = 0; j < 30; j++)
+            {
+                cout << (int)data_1[i * mat.cols * mat.channels() + j] << " ";
+            }
+            cout << endl;
+        }
+    }
+}
+
+void cv::ocl::StereoBeliefPropagation::estimateRecommendedParams(int width, int height, int &ndisp, int &iters, int &levels)
+{
+    ndisp = width / 4;
+    if ((ndisp & 1) != 0)
+        ndisp++;
+
+    int mm = ::max(width, height);
+    iters = mm / 100 + 2;
+
+    levels = (int)(::log(static_cast<double>(mm)) + 1) * 4 / 5;
+    if (levels == 0) levels++;
+}
+
+cv::ocl::StereoBeliefPropagation::StereoBeliefPropagation(int ndisp_, int iters_, int levels_, int msg_type_)
+    : ndisp(ndisp_), iters(iters_), levels(levels_),
+      max_data_term(DEFAULT_MAX_DATA_TERM), data_weight(DEFAULT_DATA_WEIGHT),
+      max_disc_term(DEFAULT_MAX_DISC_TERM), disc_single_jump(DEFAULT_DISC_SINGLE_JUMP),
+      msg_type(msg_type_), datas(levels_)
+{
+}
+
+cv::ocl::StereoBeliefPropagation::StereoBeliefPropagation(int ndisp_, int iters_, int levels_, float max_data_term_, float data_weight_, float max_disc_term_, float disc_single_jump_, int msg_type_)
+    : ndisp(ndisp_), iters(iters_), levels(levels_),
+      max_data_term(max_data_term_), data_weight(data_weight_),
+      max_disc_term(max_disc_term_), disc_single_jump(disc_single_jump_),
+      msg_type(msg_type_), datas(levels_)
+{
+}
+
+namespace
+{
+    class StereoBeliefPropagationImpl
+    {
+    public:
+        StereoBeliefPropagationImpl(StereoBeliefPropagation &rthis_,
+                                    oclMat &u_, oclMat &d_, oclMat &l_, oclMat &r_,
+                                    oclMat &u2_, oclMat &d2_, oclMat &l2_, oclMat &r2_,
+                                    vector<oclMat>& datas_, oclMat &out_)
+            : rthis(rthis_), u(u_), d(d_), l(l_), r(r_), u2(u2_), d2(d2_), l2(l2_), r2(r2_), datas(datas_), out(out_),
+              zero(Scalar::all(0)), scale(rthis_.msg_type == CV_32F ? 1.0f : 10.0f)
+        {
+            CV_Assert(0 < rthis.ndisp && 0 < rthis.iters && 0 < rthis.levels);
+            CV_Assert(rthis.msg_type == CV_32F || rthis.msg_type == CV_16S);
+            CV_Assert(rthis.msg_type == CV_32F || (1 << (rthis.levels - 1)) * scale * rthis.max_data_term < numeric_limits<short>::max());
+        }
+
+        void operator()(const oclMat &left, const oclMat &right, oclMat &disp)
+        {
+            CV_Assert(left.size() == right.size() && left.type() == right.type());
+            CV_Assert(left.type() == CV_8UC1 || left.type() == CV_8UC3 || left.type() == CV_8UC4);
+
+            rows = left.rows;
+            cols = left.cols;
+
+            int divisor = (int)pow(2.f, rthis.levels - 1.0f);
+            int lowest_cols = cols / divisor;
+            int lowest_rows = rows / divisor;
+            const int min_image_dim_size = 2;
+            CV_Assert(min(lowest_cols, lowest_rows) > min_image_dim_size);
+
+            init();
+
+            datas[0].create(rows * rthis.ndisp, cols, rthis.msg_type);
+            datas[0].setTo(Scalar_<short>::all(0));
+
+            cv::ocl::stereoBP::comp_data_call(left, right, datas[0], rthis.ndisp, rthis.max_data_term, scale * rthis.data_weight);
+
+            calcBP(disp);
+        }
+
+        void operator()(const oclMat &data, oclMat &disp)
+        {
+            CV_Assert((data.type() == rthis.msg_type) && (data.rows % rthis.ndisp == 0));
+
+            rows = data.rows / rthis.ndisp;
+            cols = data.cols;
+
+            int divisor = (int)pow(2.f, rthis.levels - 1.0f);
+            int lowest_cols = cols / divisor;
+            int lowest_rows = rows / divisor;
+            const int min_image_dim_size = 2;
+            CV_Assert(min(lowest_cols, lowest_rows) > min_image_dim_size);
+
+            init();
+
+            datas[0] = data;
+
+            calcBP(disp);
+        }
+    private:
+        void init()
+        {
+            u.create(rows * rthis.ndisp, cols, rthis.msg_type);
+            d.create(rows * rthis.ndisp, cols, rthis.msg_type);
+            l.create(rows * rthis.ndisp, cols, rthis.msg_type);
+            r.create(rows * rthis.ndisp, cols, rthis.msg_type);
+
+            if (rthis.levels & 1)
+            {
+                //can clear less area
+                u = zero;
+                d = zero;
+                l = zero;
+                r = zero;
+            }
+
+            if (rthis.levels > 1)
+            {
+                int less_rows = (rows + 1) / 2;
+                int less_cols = (cols + 1) / 2;
+
+                u2.create(less_rows * rthis.ndisp, less_cols, rthis.msg_type);
+                d2.create(less_rows * rthis.ndisp, less_cols, rthis.msg_type);
+                l2.create(less_rows * rthis.ndisp, less_cols, rthis.msg_type);
+                r2.create(less_rows * rthis.ndisp, less_cols, rthis.msg_type);
+
+                if ((rthis.levels & 1) == 0)
+                {
+                    u2 = zero;
+                    d2 = zero;
+                    l2 = zero;
+                    r2 = zero;
+                }
+            }
+
+            cv::ocl::stereoBP::load_constants(u.clCxt, rthis.ndisp, rthis.max_data_term, scale * rthis.data_weight,
+                                              scale * rthis.max_disc_term, scale * rthis.disc_single_jump);
+
+            datas.resize(rthis.levels);
+
+            cols_all.resize(rthis.levels);
+            rows_all.resize(rthis.levels);
+
+            cols_all[0] = cols;
+            rows_all[0] = rows;
+        }
+
+        void calcBP(oclMat &disp)
+        {
+            using namespace cv::ocl::stereoBP;
+
+            for (int i = 1; i < rthis.levels; ++i)
+            {
+                cols_all[i] = (cols_all[i-1] + 1) / 2;
+                rows_all[i] = (rows_all[i-1] + 1) / 2;
+
+                datas[i].create(rows_all[i] * rthis.ndisp, cols_all[i], rthis.msg_type);
+                datas[i].setTo(Scalar_<short>::all(0));
+
+                data_step_down_call(cols_all[i], rows_all[i], rows_all[i-1],
+                                    datas[i-1], datas[i], rthis.ndisp);
+            }
+
+            oclMat mus[] = {u, u2};
+            oclMat mds[] = {d, d2};
+            oclMat mrs[] = {r, r2};
+            oclMat mls[] = {l, l2};
+
+            int mem_idx = (rthis.levels & 1) ? 0 : 1;
+
+            for (int i = rthis.levels - 1; i >= 0; --i)
+            {
+                // for lower level we have already computed messages by setting to zero
+                if (i != rthis.levels - 1)
+                    level_up_messages_calls(mem_idx, cols_all[i], rows_all[i], rows_all[i+1],
+                                            mus, mds, mls, mrs, rthis.ndisp);
+
+                calc_all_iterations_calls(cols_all[i], rows_all[i], rthis.iters, mus[mem_idx],
+                                          mds[mem_idx], mls[mem_idx], mrs[mem_idx], datas[i],
+                                          rthis.ndisp, scale * rthis.max_disc_term,
+                                          scale * rthis.disc_single_jump);
+
+                mem_idx = (mem_idx + 1) & 1;
+            }
+
+            if (disp.empty())
+                disp.create(rows, cols, CV_16S);
+
+            out = ((disp.type() == CV_16S) ? disp : (out.create(rows, cols, CV_16S), out));
+            out = zero;
+
+            output_call(u, d, l, r, datas.front(), out, rthis.ndisp);
+
+
+            if (disp.type() != CV_16S)
+                out.convertTo(disp, disp.type());
+
+            release_constants();
+        }
+
+        StereoBeliefPropagation &rthis;
+
+        oclMat &u;
+        oclMat &d;
+        oclMat &l;
+        oclMat &r;
+
+        oclMat &u2;
+        oclMat &d2;
+        oclMat &l2;
+        oclMat &r2;
+
+        vector<oclMat>& datas;
+        oclMat &out;
+
+        const Scalar zero;
+        const float scale;
+
+        int rows, cols;
+
+        vector<int> cols_all, rows_all;
+    };
+}
+
+void cv::ocl::StereoBeliefPropagation::operator()(const oclMat &left, const oclMat &right, oclMat &disp)
+{
+    ::StereoBeliefPropagationImpl impl(*this, u, d, l, r, u2, d2, l2, r2, datas, out);
+    impl(left, right, disp);
+}
+
+void cv::ocl::StereoBeliefPropagation::operator()(const oclMat &data, oclMat &disp)
+{
+    ::StereoBeliefPropagationImpl impl(*this, u, d, l, r, u2, d2, l2, r2, datas, out);
+    impl(data, disp);
+}
+#endif /* !defined (HAVE_OPENCL) */
diff --git a/modules/ocl/src/threadsafe.cpp b/modules/ocl/src/threadsafe.cpp
new file mode 100644 (file)
index 0000000..59b3d7b
--- /dev/null
@@ -0,0 +1,83 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Niko Li, newlife20080214@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 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 "threadsafe.h"
+
+CriticalSection::CriticalSection()
+{
+#if defined WIN32 || defined _WIN32
+    InitializeCriticalSection(&m_CritSec);
+#else
+    pthread_mutex_init(&m_CritSec, NULL);
+#endif
+}
+
+CriticalSection::~CriticalSection()
+{
+#if defined WIN32 || defined _WIN32
+    DeleteCriticalSection(&m_CritSec);
+#else
+    pthread_mutex_destroy(&m_CritSec);
+#endif
+}
+
+void CriticalSection::Lock()
+{
+#if defined WIN32 || defined _WIN32
+    EnterCriticalSection(&m_CritSec);
+#else
+    pthread_mutex_lock(&m_CritSec);
+#endif
+}
+
+void CriticalSection::Unlock()
+{
+#if defined WIN32 || defined _WIN32
+    LeaveCriticalSection(&m_CritSec);
+#else
+    pthread_mutex_unlock(&m_CritSec);
+#endif
+}
diff --git a/modules/ocl/src/threadsafe.h b/modules/ocl/src/threadsafe.h
new file mode 100644 (file)
index 0000000..b7954fd
--- /dev/null
@@ -0,0 +1,92 @@
+/*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.
+// 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 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
+// 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*/
+
+#if defined WIN32 || defined _WIN32
+#include <Windows.h>
+#undef min
+#undef max
+#else
+#include <pthread.h>
+#endif
+
+class CriticalSection
+{
+public:
+    CriticalSection();
+    ~CriticalSection();
+    //    Jia Haipeng, jiahaipeng95@gmail.com
+    void Lock();
+    void Unlock();
+protected:
+#if defined WIN32 || defined _WIN32
+    CRITICAL_SECTION m_CritSec;
+#else
+    pthread_mutex_t m_CritSec;
+#endif
+};
+
+class AutoLock
+{
+public:
+    explicit AutoLock(CriticalSection *lock)
+    {
+        m_lock = lock;
+        m_lock->Lock();
+    };
+    ~AutoLock()
+    {
+        m_lock->Unlock();
+    };
+protected:
+    CriticalSection *m_lock;
+};
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/ocl/test/interpolation.hpp b/modules/ocl/test/interpolation.hpp
new file mode 100644 (file)
index 0000000..fb89e70
--- /dev/null
@@ -0,0 +1,120 @@
+/*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*/
+
+#ifndef __OPENCV_TEST_INTERPOLATION_HPP__
+#define __OPENCV_TEST_INTERPOLATION_HPP__
+
+template <typename T> T readVal(const cv::Mat &src, int y, int x, int c, int border_type, cv::Scalar borderVal = cv::Scalar())
+{
+    if (border_type == cv::BORDER_CONSTANT)
+        return (y >= 0 && y < src.rows && x >= 0 && x < src.cols) ? src.at<T>(y, x * src.channels() + c) : cv::saturate_cast<T>(borderVal.val[c]);
+
+    return src.at<T>(cv::borderInterpolate(y, src.rows, border_type), cv::borderInterpolate(x, src.cols, border_type) * src.channels() + c);
+}
+
+template <typename T> struct NearestInterpolator
+{
+    static T getValue(const cv::Mat &src, float y, float x, int c, int border_type, cv::Scalar borderVal = cv::Scalar())
+    {
+        return readVal<T>(src, cvFloor(y), cvFloor(x), c, border_type, borderVal);
+    }
+};
+
+template <typename T> struct LinearInterpolator
+{
+    static T getValue(const cv::Mat &src, float y, float x, int c, int border_type, cv::Scalar borderVal = cv::Scalar())
+    {
+        x -= 0.5f;
+        y -= 0.5f;
+
+        int x1 = cvFloor(x);
+        int y1 = cvFloor(y);
+        int x2 = x1 + 1;
+        int y2 = y1 + 1;
+
+        float res = 0;
+
+        res += readVal<T>(src, y1, x1, c, border_type, borderVal) * ((x2 - x) * (y2 - y));
+        res += readVal<T>(src, y1, x2, c, border_type, borderVal) * ((x - x1) * (y2 - y));
+        res += readVal<T>(src, y2, x1, c, border_type, borderVal) * ((x2 - x) * (y - y1));
+        res += readVal<T>(src, y2, x2, c, border_type, borderVal) * ((x - x1) * (y - y1));
+
+        return cv::saturate_cast<T>(res);
+    }
+};
+
+template <typename T> struct CubicInterpolator
+{
+    static float getValue(float p[4], float x)
+    {
+        return p[1] + 0.5 * x * (p[2] - p[0] + x * (2.0 * p[0] - 5.0 * p[1] + 4.0 * p[2] - p[3] + x * (3.0 * (p[1] - p[2]) + p[3] - p[0])));
+    }
+
+    static float getValue(float p[4][4], float x, float y)
+    {
+        float arr[4];
+
+        arr[0] = getValue(p[0], x);
+        arr[1] = getValue(p[1], x);
+        arr[2] = getValue(p[2], x);
+        arr[3] = getValue(p[3], x);
+
+        return getValue(arr, y);
+    }
+
+    static T getValue(const cv::Mat &src, float y, float x, int c, int border_type, cv::Scalar borderVal = cv::Scalar())
+    {
+        int ix = cvRound(x);
+        int iy = cvRound(y);
+
+        float vals[4][4] =
+        {
+            {readVal<T>(src, iy - 2, ix - 2, c, border_type, borderVal), readVal<T>(src, iy - 2, ix - 1, c, border_type, borderVal), readVal<T>(src, iy - 2, ix, c, border_type, borderVal), readVal<T>(src, iy - 2, ix + 1, c, border_type, borderVal)},
+            {readVal<T>(src, iy - 1, ix - 2, c, border_type, borderVal), readVal<T>(src, iy - 1, ix - 1, c, border_type, borderVal), readVal<T>(src, iy - 1, ix, c, border_type, borderVal), readVal<T>(src, iy - 1, ix + 1, c, border_type, borderVal)},
+            {readVal<T>(src, iy    , ix - 2, c, border_type, borderVal), readVal<T>(src, iy    , ix - 1, c, border_type, borderVal), readVal<T>(src, iy    , ix, c, border_type, borderVal), readVal<T>(src, iy    , ix + 1, c, border_type, borderVal)},
+            {readVal<T>(src, iy + 1, ix - 2, c, border_type, borderVal), readVal<T>(src, iy + 1, ix - 1, c, border_type, borderVal), readVal<T>(src, iy + 1, ix, c, border_type, borderVal), readVal<T>(src, iy + 1, ix + 1, c, border_type, borderVal)},
+        };
+
+        return cv::saturate_cast<T>(getValue(vals, (x - ix + 2.0) / 4.0, (y - iy + 2.0) / 4.0));
+    }
+};
+
+#endif // __OPENCV_TEST_INTERPOLATION_HPP__
diff --git a/modules/ocl/test/main.cpp b/modules/ocl/test/main.cpp
new file mode 100644 (file)
index 0000000..410a301
--- /dev/null
@@ -0,0 +1,110 @@
+/*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"
+
+#ifdef HAVE_OPENCL
+
+using namespace std;
+using namespace cv;
+using namespace cv::ocl;
+using namespace cvtest;
+using namespace testing;
+
+void print_info()
+{
+    printf("\n");
+#if defined _WIN32
+#   if defined _WIN64
+    puts("OS: Windows 64");
+#   else
+    puts("OS: Windows 32");
+#   endif
+#elif defined linux
+#   if defined _LP64
+    puts("OS: Linux 64");
+#   else
+    puts("OS: Linux 32");
+#   endif
+#elif defined __APPLE__
+#   if defined _LP64
+    puts("OS: Apple 64");
+#   else
+    puts("OS: Apple 32");
+#   endif
+#endif
+
+}
+
+#if PERF_TEST_OCL
+int main(int argc, char **argv)
+{
+    run_perf_test();
+    return 0;
+}
+#else
+int main(int argc, char **argv)
+{
+    TS::ptr()->init("ocl");
+    InitGoogleTest(&argc, argv);
+
+    print_info();
+
+       std::vector<cv::ocl::Info> oclinfo;
+       int devnums = getDevice(oclinfo, OPENCV_DEFAULT_OPENCL_DEVICE);
+       if(devnums<1){
+               std::cout << "no device found\n";
+               return -1;
+       }
+    return RUN_ALL_TESTS();
+}
+#endif // PERF_TEST_OCL
+
+#else // HAVE_OPENC
+
+int main()
+{
+    printf("OpenCV was built without OpenCL support\n");
+    return 0;
+}
+
+
+#endif // HAVE_OPENCL
diff --git a/modules/ocl/test/precomp.cpp b/modules/ocl/test/precomp.cpp
new file mode 100644 (file)
index 0000000..7d28700
--- /dev/null
@@ -0,0 +1,44 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+//  By downloading, copying, installing or using the software you agree to this license.
+//  If you do not agree to this license, do not download, install,
+//  copy or use the software.
+//
+//
+//                        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"
+
+
diff --git a/modules/ocl/test/precomp.hpp b/modules/ocl/test/precomp.hpp
new file mode 100644 (file)
index 0000000..d3ab3a2
--- /dev/null
@@ -0,0 +1,73 @@
+/*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*/
+#ifndef __OPENCV_TEST_PRECOMP_HPP__
+#define __OPENCV_TEST_PRECOMP_HPP__
+
+#include <cmath>
+#include <cstdio>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <limits>
+#include <algorithm>
+#include <iterator>
+#include <string>
+#include <cstdarg>
+#include "cvconfig.h"
+#include "opencv2/core/core.hpp"
+#include "opencv2/highgui/highgui.hpp"
+#include "opencv2/calib3d/calib3d.hpp"
+#include "opencv2/imgproc/imgproc.hpp"
+#include "opencv2/video/video.hpp"
+#include "opencv2/ts/ts.hpp"
+#include "opencv2/ts/ts_perf.hpp"
+#include "opencv2/ocl/ocl.hpp"
+#include "opencv2/nonfree/nonfree.hpp"
+
+#include "utility.hpp"
+#include "interpolation.hpp"
+//#include "add_test_info.h"
+
+#define OPENCV_DEFAULT_OPENCL_DEVICE CVCL_DEVICE_TYPE_ALL
+
+#endif
+
diff --git a/modules/ocl/test/test_arithm.cpp b/modules/ocl/test/test_arithm.cpp
new file mode 100644 (file)
index 0000000..a3f3508
--- /dev/null
@@ -0,0 +1,1626 @@
+///////////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Niko Li, newlife20080214@gmail.com
+//    Jia Haipeng, jiahaipeng95@gmail.com
+//    Shengen Yan, yanshengen@gmail.com
+//    Jiang Liyuan,jlyuan001.good@163.com
+//    Rock Li, Rock.Li@amd.com
+//    Zailong Wu, bullet@yeah.net
+//
+// 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 PRINT_CPU_TIME 1000
+//#define PRINT_TIME
+
+
+#include "precomp.hpp"
+#include <iomanip>
+
+#ifdef HAVE_OPENCL
+
+using namespace cv;
+using namespace cv::ocl;
+using namespace cvtest;
+using namespace testing;
+using namespace std;
+
+PARAM_TEST_CASE(ArithmTestBase, MatType, bool)
+{
+    int type;
+    cv::Scalar val;
+
+    //src mat
+    cv::Mat mat1;
+    cv::Mat mat2;
+    cv::Mat mask;
+    cv::Mat dst;
+    cv::Mat dst1; //bak, for two outputs
+
+    // set up roi
+    int roicols;
+    int roirows;
+    int src1x;
+    int src1y;
+    int src2x;
+    int src2y;
+    int dstx;
+    int dsty;
+    int maskx;
+    int masky;
+
+
+    //src mat with roi
+    cv::Mat mat1_roi;
+    cv::Mat mat2_roi;
+    cv::Mat mask_roi;
+    cv::Mat dst_roi;
+    cv::Mat dst1_roi; //bak
+    std::vector<cv::ocl::Info> oclinfo;
+    //ocl dst mat for testing
+    cv::ocl::oclMat gdst_whole;
+    cv::ocl::oclMat gdst1_whole; //bak
+
+    //ocl mat with roi
+    cv::ocl::oclMat gmat1;
+    cv::ocl::oclMat gmat2;
+    cv::ocl::oclMat gdst;
+    cv::ocl::oclMat gdst1;   //bak
+    cv::ocl::oclMat gmask;
+
+    virtual void SetUp()
+    {
+        type = GET_PARAM(0);
+
+        cv::RNG &rng = TS::ptr()->get_rng();
+
+        cv::Size size(MWIDTH, MHEIGHT);
+
+        mat1 = randomMat(rng, size, type, 5, 16, false);
+        mat2 = randomMat(rng, size, type, 5, 16, false);
+        dst  = randomMat(rng, size, type, 5, 16, false);
+        dst1  = randomMat(rng, size, type, 5, 16, false);
+        mask = randomMat(rng, size, CV_8UC1, 0, 2,  false);
+
+        cv::threshold(mask, mask, 0.5, 255., CV_8UC1);
+
+        val = cv::Scalar(rng.uniform(-10.0, 10.0), rng.uniform(-10.0, 10.0), rng.uniform(-10.0, 10.0), rng.uniform(-10.0, 10.0));
+
+        int devnums = getDevice(oclinfo, OPENCV_DEFAULT_OPENCL_DEVICE);
+        CV_Assert(devnums > 0);
+        //if you want to use undefault device, set it here
+        //setDevice(oclinfo[0]);
+    }
+
+    void random_roi()
+    {
+        cv::RNG &rng = TS::ptr()->get_rng();
+
+#ifdef RANDOMROI
+        //randomize ROI
+        roicols = rng.uniform(1, mat1.cols);
+        roirows = rng.uniform(1, mat1.rows);
+        src1x   = rng.uniform(0, mat1.cols - roicols);
+        src1y   = rng.uniform(0, mat1.rows - roirows);
+        dstx    = rng.uniform(0, dst.cols  - roicols);
+        dsty    = rng.uniform(0, dst.rows  - roirows);
+#else
+        roicols = mat1.cols;
+        roirows = mat1.rows;
+        src1x = 0;
+        src1y = 0;
+        dstx = 0;
+        dsty = 0;
+#endif
+        maskx   = rng.uniform(0, mask.cols - roicols);
+        masky   = rng.uniform(0, mask.rows - roirows);
+        src2x   = rng.uniform(0, mat2.cols - roicols);
+        src2y   = rng.uniform(0, mat2.rows - roirows);
+        mat1_roi = mat1(Rect(src1x, src1y, roicols, roirows));
+        mat2_roi = mat2(Rect(src2x, src2y, roicols, roirows));
+        mask_roi = mask(Rect(maskx, masky, roicols, roirows));
+        dst_roi  = dst(Rect(dstx, dsty, roicols, roirows));
+        dst1_roi = dst1(Rect(dstx, dsty, roicols, roirows));
+
+        gdst_whole = dst;
+        gdst = gdst_whole(Rect(dstx, dsty, roicols, roirows));
+
+        gdst1_whole = dst1;
+        gdst1 = gdst1_whole(Rect(dstx, dsty, roicols, roirows));
+
+        gmat1 = mat1_roi;
+        gmat2 = mat2_roi;
+        gmask = mask_roi; //end
+    }
+
+};
+////////////////////////////////lut/////////////////////////////////////////////////
+
+struct Lut : ArithmTestBase {};
+#define VARNAME(A) string(#A);
+
+
+
+TEST_P(Lut, Mat)
+{
+
+    cv::Mat mat2(3, 512, CV_8UC1);
+    cv::RNG &rng = TS::ptr()->get_rng();
+    rng.fill(mat2, cv::RNG::UNIFORM, cv::Scalar::all(0), cv::Scalar::all(256));
+
+    for(int j = 0; j < LOOP_TIMES; j ++)
+    {
+        random_roi();
+
+        src2x = rng.uniform( 0, mat2.cols - 256);
+        src2y = rng.uniform (0, mat2.rows - 1);
+
+        cv::Mat mat2_roi = mat2(Rect(src2x, src2y, 256, 1));
+
+        cv::ocl::oclMat gmat2(mat2_roi);
+
+        cv::LUT(mat1_roi, mat2_roi, dst_roi);
+        cv::ocl::LUT(gmat1, gmat2, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download (cpu_dst);
+        char s[1024];
+        sprintf(s, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0, s);
+    }
+}
+
+
+
+
+////////////////////////////////exp/////////////////////////////////////////////////
+
+struct Exp : ArithmTestBase {};
+
+TEST_P(Exp, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::exp(mat1_roi, dst_roi);
+        cv::ocl::exp(gmat1, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+
+        char s[1024];
+        sprintf(s, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1, s);
+
+    }
+}
+
+
+////////////////////////////////log/////////////////////////////////////////////////
+
+struct Log : ArithmTestBase {};
+
+TEST_P(Log, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+
+        cv::log(mat1_roi, dst_roi);
+        cv::ocl::log(gmat1, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char s[1024];
+        sprintf(s, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1, s);
+
+    }
+}
+
+
+
+
+////////////////////////////////add/////////////////////////////////////////////////
+
+struct Add : ArithmTestBase {};
+
+TEST_P(Add, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::add(mat1_roi, mat2_roi, dst_roi);
+        cv::ocl::add(gmat1, gmat2, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char s[1024];
+        sprintf(s, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.0, s);
+    }
+}
+
+TEST_P(Add, Mat_Mask)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::add(mat1_roi, mat2_roi, dst_roi, mask_roi);
+        cv::ocl::add(gmat1, gmat2, gdst, gmask);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char s[1024];
+        sprintf(s, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.0, s);
+    }
+}
+TEST_P(Add, Scalar)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::add(mat1_roi, val, dst_roi);
+        cv::ocl::add(gmat1, val, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char s[1024];
+        sprintf(s, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1e-5, s);
+    }
+}
+
+TEST_P(Add, Scalar_Mask)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::add(mat1_roi, val, dst_roi, mask_roi);
+        cv::ocl::add(gmat1, val, gdst, gmask);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char s[1024];
+        sprintf(s, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1e-5, s);
+    }
+}
+
+
+
+////////////////////////////////sub/////////////////////////////////////////////////
+struct Sub : ArithmTestBase {};
+
+TEST_P(Sub, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::subtract(mat1_roi, mat2_roi, dst_roi);
+        cv::ocl::subtract(gmat1, gmat2, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char s[1024];
+        sprintf(s, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.0, s);
+    }
+}
+
+TEST_P(Sub, Mat_Mask)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::subtract(mat1_roi, mat2_roi, dst_roi, mask_roi);
+        cv::ocl::subtract(gmat1, gmat2, gdst, gmask);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char s[1024];
+        sprintf(s, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.0, s);
+    }
+}
+TEST_P(Sub, Scalar)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::subtract(mat1_roi, val, dst_roi);
+        cv::ocl::subtract(gmat1, val, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char s[1024];
+        sprintf(s, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1e-5, s);
+    }
+}
+
+TEST_P(Sub, Scalar_Mask)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::subtract(mat1_roi, val, dst_roi, mask_roi);
+        cv::ocl::subtract(gmat1, val, gdst, gmask);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char s[1024];
+        sprintf(s, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1e-5, s);
+    }
+}
+
+
+
+////////////////////////////////Mul/////////////////////////////////////////////////
+struct Mul : ArithmTestBase {};
+
+TEST_P(Mul, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::multiply(mat1_roi, mat2_roi, dst_roi);
+        cv::ocl::multiply(gmat1, gmat2, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char s[1024];
+        sprintf(s, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.0, s);
+    }
+}
+
+TEST_P(Mul, Mat_Scalar)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::RNG &rng = TS::ptr()->get_rng();
+        double s = rng.uniform(-10.0, 10.0);
+
+        cv::multiply(mat1_roi, mat2_roi, dst_roi, s);
+        cv::ocl::multiply(gmat1, gmat2, gdst, s);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.001, sss);
+    }
+}
+
+
+
+struct Div : ArithmTestBase {};
+
+TEST_P(Div, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::divide(mat1_roi, mat2_roi, dst_roi);
+        cv::ocl::divide(gmat1, gmat2, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1, sss);
+    }
+}
+
+TEST_P(Div, Mat_Scalar)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::RNG &rng = TS::ptr()->get_rng();
+        double s = rng.uniform(-10.0, 10.0);
+
+        cv::divide(mat1_roi, mat2_roi, dst_roi, s);
+        cv::ocl::divide(gmat1, gmat2, gdst, s);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.001, sss);
+    }
+}
+
+
+struct Absdiff : ArithmTestBase {};
+
+TEST_P(Absdiff, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::absdiff(mat1_roi, mat2_roi, dst_roi);
+        cv::ocl::absdiff(gmat1, gmat2, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0, sss);
+    }
+}
+
+TEST_P(Absdiff, Mat_Scalar)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::absdiff(mat1_roi, val, dst_roi);
+        cv::ocl::absdiff(gmat1, val, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1e-5, sss);
+    }
+}
+
+
+
+struct CartToPolar : ArithmTestBase {};
+
+TEST_P(CartToPolar, angleInDegree)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::cartToPolar(mat1_roi, mat2_roi, dst_roi, dst1_roi, 1);
+        cv::ocl::cartToPolar(gmat1, gmat2, gdst, gdst1, 1);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+
+        cv::Mat cpu_dst1;
+        gdst1_whole.download(cpu_dst1);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.5, sss);
+        EXPECT_MAT_NEAR(dst1, cpu_dst1, 0.5, sss);
+    }
+}
+
+TEST_P(CartToPolar, angleInRadians)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::cartToPolar(mat1_roi, mat2_roi, dst_roi, dst1_roi, 0);
+        cv::ocl::cartToPolar(gmat1, gmat2, gdst, gdst1, 0);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+
+        cv::Mat cpu_dst1;
+        gdst1_whole.download(cpu_dst1);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.5, sss);
+        EXPECT_MAT_NEAR(dst1, cpu_dst1, 0.5, sss);
+    }
+}
+
+
+
+
+struct PolarToCart : ArithmTestBase {};
+
+TEST_P(PolarToCart, angleInDegree)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::polarToCart(mat1_roi, mat2_roi, dst_roi, dst1_roi, 1);
+        cv::ocl::polarToCart(gmat1, gmat2, gdst, gdst1, 1);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+
+        cv::Mat cpu_dst1;
+        gdst1_whole.download(cpu_dst1);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.5, sss);
+        EXPECT_MAT_NEAR(dst1, cpu_dst1, 0.5, sss);
+    }
+}
+
+TEST_P(PolarToCart, angleInRadians)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::polarToCart(mat1_roi, mat2_roi, dst_roi, dst1_roi, 0);
+        cv::ocl::polarToCart(gmat1, gmat2, gdst, gdst1, 0);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+
+        cv::Mat cpu_dst1;
+        gdst1_whole.download(cpu_dst1);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.5, sss);
+        EXPECT_MAT_NEAR(dst1, cpu_dst1, 0.5, sss);
+    }
+}
+
+
+
+
+struct Magnitude : ArithmTestBase {};
+
+TEST_P(Magnitude, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::magnitude(mat1_roi, mat2_roi, dst_roi);
+        cv::ocl::magnitude(gmat1, gmat2, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1e-5, sss);
+    }
+}
+
+
+
+
+struct Transpose : ArithmTestBase {};
+
+TEST_P(Transpose, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::transpose(mat1_roi, dst_roi);
+        cv::ocl::transpose(gmat1, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1e-5, sss);
+    }
+}
+
+
+
+
+
+struct Flip : ArithmTestBase {};
+
+TEST_P(Flip, X)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::flip(mat1_roi, dst_roi, 0);
+        cv::ocl::flip(gmat1, gdst, 0);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1e-5, sss);
+    }
+}
+
+TEST_P(Flip, Y)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::flip(mat1_roi, dst_roi, 1);
+        cv::ocl::flip(gmat1, gdst, 1);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1e-5, sss);
+    }
+}
+
+TEST_P(Flip, BOTH)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::flip(mat1_roi, dst_roi, -1);
+        cv::ocl::flip(gmat1, gdst, -1);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1e-5, sss);
+    }
+}
+
+
+
+struct MinMax : ArithmTestBase {};
+
+TEST_P(MinMax, MAT)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+        double minVal, maxVal;
+        cv::Point minLoc, maxLoc;
+
+        if (mat1.depth() != CV_8S)
+        {
+            cv::minMaxLoc(mat1_roi, &minVal, &maxVal, &minLoc, &maxLoc);
+        }
+        else
+        {
+            minVal = std::numeric_limits<double>::max();
+            maxVal = -std::numeric_limits<double>::max();
+            for (int i = 0; i < mat1_roi.rows; ++i)
+                for (int j = 0; j < mat1_roi.cols; ++j)
+                {
+                    signed char val = mat1_roi.at<signed char>(i, j);
+                    if (val < minVal) minVal = val;
+                    if (val > maxVal) maxVal = val;
+                }
+        }
+
+        double minVal_, maxVal_;
+        cv::ocl::minMax(gmat1, &minVal_, &maxVal_);
+
+        //check results
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_DOUBLE_EQ(minVal_, minVal) << sss;
+        EXPECT_DOUBLE_EQ(maxVal_, maxVal) << sss;
+    }
+}
+
+TEST_P(MinMax, MASK)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+        double minVal, maxVal;
+        cv::Point minLoc, maxLoc;
+
+        if (mat1.depth() != CV_8S)
+        {
+            cv::minMaxLoc(mat1_roi, &minVal, &maxVal, &minLoc, &maxLoc, mask_roi);
+        }
+        else
+        {
+            minVal = std::numeric_limits<double>::max();
+            maxVal = -std::numeric_limits<double>::max();
+            for (int i = 0; i < mat1_roi.rows; ++i)
+                for (int j = 0; j < mat1_roi.cols; ++j)
+                {
+                    signed char val = mat1_roi.at<signed char>(i, j);
+                    unsigned char m = mask_roi.at<unsigned char>(i, j);
+                    if (val < minVal && m) minVal = val;
+                    if (val > maxVal && m) maxVal = val;
+                }
+        }
+
+        double minVal_, maxVal_;
+        cv::ocl::minMax(gmat1, &minVal_, &maxVal_, gmask);
+
+        //check results
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_DOUBLE_EQ(minVal_, minVal) << sss;
+        EXPECT_DOUBLE_EQ(maxVal_, maxVal) << sss;
+    }
+}
+
+
+struct MinMaxLoc : ArithmTestBase {};
+
+TEST_P(MinMaxLoc, MAT)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+        double minVal, maxVal;
+        cv::Point minLoc, maxLoc;
+        int depth = mat1.depth();
+        if (depth != CV_8S)
+        {
+            cv::minMaxLoc(mat1_roi, &minVal, &maxVal, &minLoc, &maxLoc);
+        }
+        else
+        {
+            minVal = std::numeric_limits<double>::max();
+            maxVal = -std::numeric_limits<double>::max();
+            for (int i = 0; i < mat1_roi.rows; ++i)
+                for (int j = 0; j < mat1_roi.cols; ++j)
+                {
+                    signed char val = mat1_roi.at<signed char>(i, j);
+                    if (val < minVal)
+                    {
+                        minVal = val;
+                        minLoc.x = j;
+                        minLoc.y = i;
+                    }
+                    if (val > maxVal)
+                    {
+                        maxVal = val;
+                        maxLoc.x = j;
+                        maxLoc.y = i;
+                    }
+                }
+        }
+
+        double minVal_, maxVal_;
+        cv::Point minLoc_, maxLoc_;
+        cv::ocl::minMaxLoc(gmat1, &minVal_, &maxVal_, &minLoc_, &maxLoc_, cv::ocl::oclMat());
+
+        double error0, error1, minlocVal, minlocVal_, maxlocVal, maxlocVal_;
+        if(depth == 0)
+        {
+            minlocVal = mat1_roi.at<unsigned char>(minLoc);
+            minlocVal_ = mat1_roi.at<unsigned char>(minLoc_);
+            maxlocVal = mat1_roi.at<unsigned char>(maxLoc);
+            maxlocVal_ = mat1_roi.at<unsigned char>(maxLoc_);
+            error0 = ::abs(mat1_roi.at<unsigned char>(minLoc_) - mat1_roi.at<unsigned char>(minLoc));
+            error1 = ::abs(mat1_roi.at<unsigned char>(maxLoc_) - mat1_roi.at<unsigned char>(maxLoc));
+        }
+        if(depth == 1)
+        {
+            minlocVal = mat1_roi.at<signed char>(minLoc);
+            minlocVal_ = mat1_roi.at<signed char>(minLoc_);
+            maxlocVal = mat1_roi.at<signed char>(maxLoc);
+            maxlocVal_ = mat1_roi.at<signed char>(maxLoc_);
+            error0 = ::abs(mat1_roi.at<signed char>(minLoc_) - mat1_roi.at<signed char>(minLoc));
+            error1 = ::abs(mat1_roi.at<signed char>(maxLoc_) - mat1_roi.at<signed char>(maxLoc));
+        }
+        if(depth == 2)
+        {
+            minlocVal = mat1_roi.at<unsigned short>(minLoc);
+            minlocVal_ = mat1_roi.at<unsigned short>(minLoc_);
+            maxlocVal = mat1_roi.at<unsigned short>(maxLoc);
+            maxlocVal_ = mat1_roi.at<unsigned short>(maxLoc_);
+            error0 = ::abs(mat1_roi.at<unsigned short>(minLoc_) - mat1_roi.at<unsigned short>(minLoc));
+            error1 = ::abs(mat1_roi.at<unsigned short>(maxLoc_) - mat1_roi.at<unsigned short>(maxLoc));
+        }
+        if(depth == 3)
+        {
+            minlocVal = mat1_roi.at<signed short>(minLoc);
+            minlocVal_ = mat1_roi.at<signed short>(minLoc_);
+            maxlocVal = mat1_roi.at<signed short>(maxLoc);
+            maxlocVal_ = mat1_roi.at<signed short>(maxLoc_);
+            error0 = ::abs(mat1_roi.at<signed short>(minLoc_) - mat1_roi.at<signed short>(minLoc));
+            error1 = ::abs(mat1_roi.at<signed short>(maxLoc_) - mat1_roi.at<signed short>(maxLoc));
+        }
+        if(depth == 4)
+        {
+            minlocVal = mat1_roi.at<int>(minLoc);
+            minlocVal_ = mat1_roi.at<int>(minLoc_);
+            maxlocVal = mat1_roi.at<int>(maxLoc);
+            maxlocVal_ = mat1_roi.at<int>(maxLoc_);
+            error0 = ::abs(mat1_roi.at<int>(minLoc_) - mat1_roi.at<int>(minLoc));
+            error1 = ::abs(mat1_roi.at<int>(maxLoc_) - mat1_roi.at<int>(maxLoc));
+        }
+        if(depth == 5)
+        {
+            minlocVal = mat1_roi.at<float>(minLoc);
+            minlocVal_ = mat1_roi.at<float>(minLoc_);
+            maxlocVal = mat1_roi.at<float>(maxLoc);
+            maxlocVal_ = mat1_roi.at<float>(maxLoc_);
+            error0 = ::abs(mat1_roi.at<float>(minLoc_) - mat1_roi.at<float>(minLoc));
+            error1 = ::abs(mat1_roi.at<float>(maxLoc_) - mat1_roi.at<float>(maxLoc));
+        }
+        if(depth == 6)
+        {
+            minlocVal = mat1_roi.at<double>(minLoc);
+            minlocVal_ = mat1_roi.at<double>(minLoc_);
+            maxlocVal = mat1_roi.at<double>(maxLoc);
+            maxlocVal_ = mat1_roi.at<double>(maxLoc_);
+            error0 = ::abs(mat1_roi.at<double>(minLoc_) - mat1_roi.at<double>(minLoc));
+            error1 = ::abs(mat1_roi.at<double>(maxLoc_) - mat1_roi.at<double>(maxLoc));
+        }
+
+        //check results
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_DOUBLE_EQ(minVal_, minVal) << sss;
+        EXPECT_DOUBLE_EQ(maxVal_, maxVal) << sss;
+        EXPECT_DOUBLE_EQ(minlocVal_, minlocVal) << sss;
+        EXPECT_DOUBLE_EQ(maxlocVal_, maxlocVal) << sss;
+
+        EXPECT_DOUBLE_EQ(error0, 0.0) << sss;
+        EXPECT_DOUBLE_EQ(error1, 0.0) << sss;
+    }
+}
+
+
+TEST_P(MinMaxLoc, MASK)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+        double minVal, maxVal;
+        cv::Point minLoc, maxLoc;
+        int depth = mat1.depth();
+        if (depth != CV_8S)
+        {
+            cv::minMaxLoc(mat1_roi, &minVal, &maxVal, &minLoc, &maxLoc, mask_roi);
+        }
+        else
+        {
+            minVal = std::numeric_limits<double>::max();
+            maxVal = -std::numeric_limits<double>::max();
+            for (int i = 0; i < mat1_roi.rows; ++i)
+                for (int j = 0; j < mat1_roi.cols; ++j)
+                {
+                    signed char val = mat1_roi.at<signed char>(i, j);
+                    unsigned char m = mask_roi.at<unsigned char>(i , j);
+                    if (val < minVal && m)
+                    {
+                        minVal = val;
+                        minLoc.x = j;
+                        minLoc.y = i;
+                    }
+                    if (val > maxVal && m)
+                    {
+                        maxVal = val;
+                        maxLoc.x = j;
+                        maxLoc.y = i;
+                    }
+                }
+        }
+
+        double minVal_, maxVal_;
+        cv::Point minLoc_, maxLoc_;
+        cv::ocl::minMaxLoc(gmat1, &minVal_, &maxVal_, &minLoc_, &maxLoc_, gmask);
+
+        double error0, error1, minlocVal, minlocVal_, maxlocVal, maxlocVal_;
+        if(minLoc_.x == -1 || minLoc_.y == -1 || maxLoc_.x == -1 || maxLoc_.y == -1) continue;
+        if(depth == 0)
+        {
+            minlocVal = mat1_roi.at<unsigned char>(minLoc);
+            minlocVal_ = mat1_roi.at<unsigned char>(minLoc_);
+            maxlocVal = mat1_roi.at<unsigned char>(maxLoc);
+            maxlocVal_ = mat1_roi.at<unsigned char>(maxLoc_);
+            error0 = ::abs(mat1_roi.at<unsigned char>(minLoc_) - mat1_roi.at<unsigned char>(minLoc));
+            error1 = ::abs(mat1_roi.at<unsigned char>(maxLoc_) - mat1_roi.at<unsigned char>(maxLoc));
+        }
+        if(depth == 1)
+        {
+            minlocVal = mat1_roi.at<signed char>(minLoc);
+            minlocVal_ = mat1_roi.at<signed char>(minLoc_);
+            maxlocVal = mat1_roi.at<signed char>(maxLoc);
+            maxlocVal_ = mat1_roi.at<signed char>(maxLoc_);
+            error0 = ::abs(mat1_roi.at<signed char>(minLoc_) - mat1_roi.at<signed char>(minLoc));
+            error1 = ::abs(mat1_roi.at<signed char>(maxLoc_) - mat1_roi.at<signed char>(maxLoc));
+        }
+        if(depth == 2)
+        {
+            minlocVal = mat1_roi.at<unsigned short>(minLoc);
+            minlocVal_ = mat1_roi.at<unsigned short>(minLoc_);
+            maxlocVal = mat1_roi.at<unsigned short>(maxLoc);
+            maxlocVal_ = mat1_roi.at<unsigned short>(maxLoc_);
+            error0 = ::abs(mat1_roi.at<unsigned short>(minLoc_) - mat1_roi.at<unsigned short>(minLoc));
+            error1 = ::abs(mat1_roi.at<unsigned short>(maxLoc_) - mat1_roi.at<unsigned short>(maxLoc));
+        }
+        if(depth == 3)
+        {
+            minlocVal = mat1_roi.at<signed short>(minLoc);
+            minlocVal_ = mat1_roi.at<signed short>(minLoc_);
+            maxlocVal = mat1_roi.at<signed short>(maxLoc);
+            maxlocVal_ = mat1_roi.at<signed short>(maxLoc_);
+            error0 = ::abs(mat1_roi.at<signed short>(minLoc_) - mat1_roi.at<signed short>(minLoc));
+            error1 = ::abs(mat1_roi.at<signed short>(maxLoc_) - mat1_roi.at<signed short>(maxLoc));
+        }
+        if(depth == 4)
+        {
+            minlocVal = mat1_roi.at<int>(minLoc);
+            minlocVal_ = mat1_roi.at<int>(minLoc_);
+            maxlocVal = mat1_roi.at<int>(maxLoc);
+            maxlocVal_ = mat1_roi.at<int>(maxLoc_);
+            error0 = ::abs(mat1_roi.at<int>(minLoc_) - mat1_roi.at<int>(minLoc));
+            error1 = ::abs(mat1_roi.at<int>(maxLoc_) - mat1_roi.at<int>(maxLoc));
+        }
+        if(depth == 5)
+        {
+            minlocVal = mat1_roi.at<float>(minLoc);
+            minlocVal_ = mat1_roi.at<float>(minLoc_);
+            maxlocVal = mat1_roi.at<float>(maxLoc);
+            maxlocVal_ = mat1_roi.at<float>(maxLoc_);
+            error0 = ::abs(mat1_roi.at<float>(minLoc_) - mat1_roi.at<float>(minLoc));
+            error1 = ::abs(mat1_roi.at<float>(maxLoc_) - mat1_roi.at<float>(maxLoc));
+        }
+        if(depth == 6)
+        {
+            minlocVal = mat1_roi.at<double>(minLoc);
+            minlocVal_ = mat1_roi.at<double>(minLoc_);
+            maxlocVal = mat1_roi.at<double>(maxLoc);
+            maxlocVal_ = mat1_roi.at<double>(maxLoc_);
+            error0 = ::abs(mat1_roi.at<double>(minLoc_) - mat1_roi.at<double>(minLoc));
+            error1 = ::abs(mat1_roi.at<double>(maxLoc_) - mat1_roi.at<double>(maxLoc));
+        }
+
+        //check results
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_DOUBLE_EQ(minVal_, minVal) << sss;
+        EXPECT_DOUBLE_EQ(maxVal_, maxVal) << sss;
+        EXPECT_DOUBLE_EQ(minlocVal_, minlocVal) << sss;
+        EXPECT_DOUBLE_EQ(maxlocVal_, maxlocVal) << sss;
+
+        EXPECT_DOUBLE_EQ(error0, 0.0) << sss;
+        EXPECT_DOUBLE_EQ(error1, 0.0) << sss;
+    }
+}
+
+
+struct Sum : ArithmTestBase {};
+
+TEST_P(Sum, MAT)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+        Scalar cpures = cv::sum(mat1_roi);
+        Scalar gpures = cv::ocl::sum(gmat1);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        //check results
+        EXPECT_DOUBLE_EQ(cpures[0], gpures[0]) << sss;
+        EXPECT_DOUBLE_EQ(cpures[1], gpures[1]) << sss;
+        EXPECT_DOUBLE_EQ(cpures[2], gpures[2]) << sss;
+        EXPECT_DOUBLE_EQ(cpures[3], gpures[3]) << sss;
+    }
+}
+
+//TEST_P(Sum, MASK)
+//{
+//     for(int j=0; j<LOOP_TIMES; j++)
+//     {
+//             random_roi();
+//
+//     }
+//}
+
+
+
+struct CountNonZero : ArithmTestBase {};
+
+TEST_P(CountNonZero, MAT)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+        int cpures = cv::countNonZero(mat1_roi);
+        int gpures = cv::ocl::countNonZero(gmat1);
+
+        //check results
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_DOUBLE_EQ((double)cpures, (double)gpures) << sss;
+    }
+}
+
+
+
+////////////////////////////////phase/////////////////////////////////////////////////
+struct Phase : ArithmTestBase {};
+
+TEST_P(Phase, Mat)
+{
+    if(mat1.depth() != CV_32F && mat1.depth() != CV_64F)
+    {
+        cout << "\tUnsupported type\t\n";
+    }
+    for(int angelInDegrees = 0; angelInDegrees < 2; angelInDegrees++)
+    {
+        for(int j = 0; j < LOOP_TIMES; j++)
+        {
+            random_roi();
+            cv::phase(mat1_roi, mat2_roi, dst_roi, angelInDegrees);
+            cv::ocl::phase(gmat1, gmat2, gdst, angelInDegrees);
+
+            cv::Mat cpu_dst;
+            gdst_whole.download(cpu_dst);
+
+            char sss[1024];
+            sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+            EXPECT_MAT_NEAR(dst, cpu_dst, 1e-2, sss);
+        }
+    }
+}
+
+
+////////////////////////////////bitwise_and/////////////////////////////////////////////////
+struct Bitwise_and : ArithmTestBase {};
+
+TEST_P(Bitwise_and, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::bitwise_and(mat1_roi, mat2_roi, dst_roi);
+        cv::ocl::bitwise_and(gmat1, gmat2, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.0, sss);
+    }
+}
+
+TEST_P(Bitwise_and, Mat_Mask)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::bitwise_and(mat1_roi, mat2_roi, dst_roi, mask_roi);
+        cv::ocl::bitwise_and(gmat1, gmat2, gdst, gmask);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.0, sss);
+    }
+}
+TEST_P(Bitwise_and, Scalar)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::bitwise_and(mat1_roi, val, dst_roi);
+        cv::ocl::bitwise_and(gmat1, val, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1e-5, sss);
+
+    }
+}
+
+TEST_P(Bitwise_and, Scalar_Mask)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::bitwise_and(mat1_roi, val, dst_roi, mask_roi);
+        cv::ocl::bitwise_and(gmat1, val, gdst, gmask);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char *sss = new char[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1e-5, sss);
+        delete[] sss;
+    }
+}
+
+
+
+////////////////////////////////bitwise_or/////////////////////////////////////////////////
+
+struct Bitwise_or : ArithmTestBase {};
+
+TEST_P(Bitwise_or, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::bitwise_or(mat1_roi, mat2_roi, dst_roi);
+        cv::ocl::bitwise_or(gmat1, gmat2, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.0, sss);
+    }
+}
+
+TEST_P(Bitwise_or, Mat_Mask)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::bitwise_or(mat1_roi, mat2_roi, dst_roi, mask_roi);
+        cv::ocl::bitwise_or(gmat1, gmat2, gdst, gmask);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.0, sss);
+    }
+}
+TEST_P(Bitwise_or, Scalar)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::bitwise_or(mat1_roi, val, dst_roi);
+        cv::ocl::bitwise_or(gmat1, val, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1e-5, sss);
+    }
+}
+
+TEST_P(Bitwise_or, Scalar_Mask)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::bitwise_or(mat1_roi, val, dst_roi, mask_roi);
+        cv::ocl::bitwise_or(gmat1, val, gdst, gmask);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1e-5, sss);
+    }
+}
+
+
+
+////////////////////////////////bitwise_xor/////////////////////////////////////////////////
+
+struct Bitwise_xor : ArithmTestBase {};
+
+TEST_P(Bitwise_xor, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::bitwise_xor(mat1_roi, mat2_roi, dst_roi);
+        cv::ocl::bitwise_xor(gmat1, gmat2, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.0, sss);
+    }
+}
+
+TEST_P(Bitwise_xor, Mat_Mask)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::bitwise_xor(mat1_roi, mat2_roi, dst_roi, mask_roi);
+        cv::ocl::bitwise_xor(gmat1, gmat2, gdst, gmask);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.0, sss);
+    }
+}
+TEST_P(Bitwise_xor, Scalar)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::bitwise_xor(mat1_roi, val, dst_roi);
+        cv::ocl::bitwise_xor(gmat1, val, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1e-5, sss);
+    }
+}
+
+TEST_P(Bitwise_xor, Scalar_Mask)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::bitwise_xor(mat1_roi, val, dst_roi, mask_roi);
+        cv::ocl::bitwise_xor(gmat1, val, gdst, gmask);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1e-5, sss);
+    }
+}
+
+
+////////////////////////////////bitwise_not/////////////////////////////////////////////////
+
+struct Bitwise_not : ArithmTestBase {};
+
+TEST_P(Bitwise_not, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::bitwise_not(mat1_roi, dst_roi);
+        cv::ocl::bitwise_not(gmat1, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.0, sss);
+    }
+}
+
+
+////////////////////////////////compare/////////////////////////////////////////////////
+struct Compare : ArithmTestBase {};
+
+TEST_P(Compare, Mat)
+{
+    if(mat1.type() == CV_8SC1)
+        //if(mat1.type() != CV_8UC1 || mat1.type()!= CV_16UC1 || mat1.type()!= CV_16SC1|| mat1.type()!= CV_32SC1 || mat1.type()!= CV_32FC1|| mat1.type()!= CV_64FC1)
+    {
+        cout << "\tUnsupported type\t\n";
+    }
+
+    int cmp_codes[] = {CMP_EQ, CMP_GT, CMP_GE, CMP_LT, CMP_LE, CMP_NE};
+    const char *cmp_str[] = {"CMP_EQ", "CMP_GT", "CMP_GE", "CMP_LT", "CMP_LE", "CMP_NE"};
+    int cmp_num = sizeof(cmp_codes) / sizeof(int);
+
+    for (int i = 0; i < cmp_num; ++i)
+    {
+
+        for(int j = 0; j < LOOP_TIMES; j++)
+        {
+            random_roi();
+
+            cv::compare(mat1_roi, mat2_roi, dst_roi, cmp_codes[i]);
+            cv::ocl::compare(gmat1, gmat2, gdst, cmp_codes[i]);
+
+            cv::Mat cpu_dst;
+            gdst_whole.download(cpu_dst);
+            char sss[1024];
+            sprintf(sss, "cmptype=%s, roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", cmp_str[i], roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+            EXPECT_MAT_NEAR(dst, cpu_dst, 0.0, sss);
+        }
+    }
+
+}
+
+
+struct Pow : ArithmTestBase {};
+
+TEST_P(Pow, Mat)
+{
+    if(mat1.depth() != CV_32F && mat1.depth() != CV_64F)
+    {
+        cout << "\tUnsupported type\t\n";
+    }
+
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+        double p = 4.5;
+        cv::pow(mat1_roi, p, dst_roi);
+        cv::ocl::pow(gmat1, p, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1, sss);
+    }
+}
+
+
+struct MagnitudeSqr : ArithmTestBase {};
+
+TEST_P(MagnitudeSqr, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        // random_roi();
+        int64 start, end;
+        start = cv::getTickCount();
+        for(int i = 0; i < mat1.rows; ++i)
+            for(int j = 0; j < mat1.cols; ++j)
+            {
+                float val1 = mat1.at<float>(i, j);
+                float val2 = mat2.at<float>(i, j);
+
+                ((float *)(dst.data))[i *dst.step/4 +j] = val1 * val1 + val2 * val2;
+
+                //        float val1 =((float *)( mat1.data))[(i*mat1.step/8 +j)*2];
+                //
+                //     float val2 =((float *)( mat1.data))[(i*mat1.step/8 +j)*2+ 1 ];
+
+                //  ((float *)(dst.data))[i*dst.step/4 +j]= val1 * val1 +val2 * val2;
+            }
+        end = cv::getTickCount();
+
+
+
+        cv::ocl::oclMat clmat1(mat1), clmat2(mat2), cldst;
+        cv::ocl::magnitudeSqr(clmat1, clmat2, cldst);
+
+        cv::Mat cpu_dst;
+        cldst.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1, sss);
+    }
+}
+
+
+struct AddWeighted : ArithmTestBase {};
+
+TEST_P(AddWeighted, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+        double alpha = 2.0, beta = 1.0, gama = 3.0;
+
+
+        cv::addWeighted(mat1_roi, alpha, mat2_roi, beta, gama, dst_roi);
+
+        //     cv::ocl::oclMat clmat1(mat1),clmat2(mat2),cldst;
+
+        cv::ocl::addWeighted(gmat1, alpha, gmat2, beta, gama, gdst);
+
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1e-5, sss);
+    }
+}
+
+
+
+
+
+//********test****************
+
+INSTANTIATE_TEST_CASE_P(Arithm, Lut, Combine(
+                            Values(CV_8UC1, CV_8UC4),
+                            Values(false))); // Values(false) is the reserved parameter
+
+INSTANTIATE_TEST_CASE_P(Arithm, Exp, Combine(
+                            Values(CV_32FC1, CV_32FC1),
+                            Values(false))); // Values(false) is the reserved parameter
+
+INSTANTIATE_TEST_CASE_P(Arithm, Log, Combine(
+                            Values(CV_32FC1, CV_32FC1),
+                            Values(false))); // Values(false) is the reserved parameter
+
+INSTANTIATE_TEST_CASE_P(Arithm, Add, Combine(
+                            Values(CV_8UC1, CV_8UC4, CV_32SC1, CV_32SC4, CV_32FC1,  CV_32FC4),
+                            Values(false)));
+
+INSTANTIATE_TEST_CASE_P(Arithm, Mul, Combine(
+                            Values(CV_8UC1, CV_8UC4, CV_32SC1, CV_32SC4, CV_32FC1, CV_32FC4),
+                            Values(false))); // Values(false) is the reserved parameter
+
+INSTANTIATE_TEST_CASE_P(Arithm, Div, Combine(
+                            Values(CV_8UC1, CV_8UC4, CV_32SC1, CV_32SC4, CV_32FC1, CV_32FC4),
+                            Values(false))); // Values(false) is the reserved parameter
+
+
+INSTANTIATE_TEST_CASE_P(Arithm, Absdiff, Combine(
+                            Values(CV_8UC1, CV_8UC4, CV_32SC1, CV_32SC4, CV_32FC1, CV_32FC4),
+                            Values(false))); // Values(false) is the reserved parameter
+
+INSTANTIATE_TEST_CASE_P(Arithm, CartToPolar, Combine(
+                            Values(CV_32FC1, CV_32FC4),
+                            Values(false))); // Values(false) is the reserved parameter
+
+INSTANTIATE_TEST_CASE_P(Arithm, PolarToCart, Combine(
+                            Values(CV_32FC1, CV_32FC4),
+                            Values(false))); // Values(false) is the reserved parameter
+
+INSTANTIATE_TEST_CASE_P(Arithm, Magnitude, Combine(
+                            Values(CV_32FC1, CV_32FC4),
+                            Values(false))); // Values(false) is the reserved parameter
+
+INSTANTIATE_TEST_CASE_P(Arithm, Transpose, Combine(
+                            Values(CV_8UC1, CV_8UC4, CV_32SC1, CV_32FC1),
+                            Values(false))); // Values(false) is the reserved parameter
+
+INSTANTIATE_TEST_CASE_P(Arithm, Flip, Combine(
+                            Values(CV_8UC1, CV_8UC4, CV_32SC1, CV_32SC4, CV_32FC1, CV_32FC4),
+                            Values(false))); // Values(false) is the reserved parameter
+
+INSTANTIATE_TEST_CASE_P(Arithm, MinMax, Combine(
+                            Values(CV_8UC1, CV_32SC1, CV_32FC1),
+                            Values(false)));
+
+INSTANTIATE_TEST_CASE_P(Arithm, MinMaxLoc, Combine(
+                            Values(CV_8UC1, CV_32SC1, CV_32FC1),
+                            Values(false)));
+
+INSTANTIATE_TEST_CASE_P(Arithm, Sum, Combine(
+                            Values(CV_8U, CV_32S, CV_32F),
+                            Values(false)));
+
+INSTANTIATE_TEST_CASE_P(Arithm, CountNonZero, Combine(
+                            Values(CV_8U, CV_32S, CV_32F),
+                            Values(false)));
+
+
+INSTANTIATE_TEST_CASE_P(Arithm, Phase, Combine(Values(CV_32FC1, CV_32FC4), Values(false)));
+// Values(false) is the reserved parameter
+
+
+INSTANTIATE_TEST_CASE_P(Arithm, Bitwise_and, Combine(
+                            Values(CV_8UC1, CV_32SC1, CV_32SC4, CV_32FC1, CV_32FC4), Values(false)));
+//Values(false) is the reserved parameter
+
+INSTANTIATE_TEST_CASE_P(Arithm, Bitwise_or, Combine(
+                            Values(CV_8UC1, CV_32SC1, CV_32FC1, CV_32FC4), Values(false)));
+//Values(false) is the reserved parameter
+
+INSTANTIATE_TEST_CASE_P(Arithm, Bitwise_xor, Combine(
+                            Values(CV_8UC1, CV_32SC1, CV_32FC1, CV_32FC4), Values(false)));
+//Values(false) is the reserved parameter
+
+INSTANTIATE_TEST_CASE_P(Arithm, Bitwise_not, Combine(
+                            Values(CV_8UC1, CV_32SC1, CV_32FC1, CV_32FC4), Values(false)));
+//Values(false) is the reserved parameter
+
+INSTANTIATE_TEST_CASE_P(Arithm, Compare, Combine(Values(CV_8UC1, CV_32SC1, CV_32FC1), Values(false)));
+// Values(false) is the reserved parameter
+
+INSTANTIATE_TEST_CASE_P(Arithm, Pow, Combine(Values(CV_32FC1, CV_32FC4), Values(false)));
+// Values(false) is the reserved parameter
+
+INSTANTIATE_TEST_CASE_P(Arithm, MagnitudeSqr, Combine(
+                            Values(CV_32FC1, CV_32FC1),
+                            Values(false))); // Values(false) is the reserved parameter
+
+INSTANTIATE_TEST_CASE_P(Arithm, AddWeighted, Combine(
+                            Values(CV_8UC1, CV_32SC1, CV_32FC1),
+                            Values(false))); // Values(false) is the reserved parameter
+
+
+
+#endif // HAVE_OPENCL
diff --git a/modules/ocl/test/test_filters.cpp b/modules/ocl/test/test_filters.cpp
new file mode 100644 (file)
index 0000000..9c22faa
--- /dev/null
@@ -0,0 +1,859 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Niko Li, newlife20080214@gmail.com
+//    Jia Haipeng, jiahaipeng95@gmail.com
+//    Zero Lin, Zero.Lin@amd.com
+//    Zhang Ying, zhangying913@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 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"
+
+#ifdef HAVE_OPENCL
+
+using namespace cvtest;
+using namespace testing;
+using namespace std;
+
+
+PARAM_TEST_CASE(FilterTestBase, MatType, bool)
+{
+    int type;
+    cv::Scalar val;
+
+    //src mat
+    cv::Mat mat1;
+    cv::Mat mat2;
+    cv::Mat mask;
+    cv::Mat dst;
+    cv::Mat dst1; //bak, for two outputs
+
+    // set up roi
+    int roicols;
+    int roirows;
+    int src1x;
+    int src1y;
+    int src2x;
+    int src2y;
+    int dstx;
+    int dsty;
+    int maskx;
+    int masky;
+
+    //src mat with roi
+    cv::Mat mat1_roi;
+    cv::Mat mat2_roi;
+    cv::Mat mask_roi;
+    cv::Mat dst_roi;
+    cv::Mat dst1_roi; //bak
+    std::vector<cv::ocl::Info> oclinfo;
+    //ocl dst mat for testing
+    cv::ocl::oclMat gdst_whole;
+    cv::ocl::oclMat gdst1_whole; //bak
+
+    //ocl mat with roi
+    cv::ocl::oclMat gmat1;
+    cv::ocl::oclMat gmat2;
+    cv::ocl::oclMat gdst;
+    cv::ocl::oclMat gdst1;   //bak
+    cv::ocl::oclMat gmask;
+
+    virtual void SetUp()
+    {
+        type = GET_PARAM(0);
+
+        cv::RNG &rng = TS::ptr()->get_rng();
+        cv::Size size(MWIDTH, MHEIGHT);
+
+        mat1 = randomMat(rng, size, type, 5, 16, false);
+        mat2 = randomMat(rng, size, type, 5, 16, false);
+        dst  = randomMat(rng, size, type, 5, 16, false);
+        dst1  = randomMat(rng, size, type, 5, 16, false);
+        mask = randomMat(rng, size, CV_8UC1, 0, 2,  false);
+
+        cv::threshold(mask, mask, 0.5, 255., CV_8UC1);
+
+        val = cv::Scalar(rng.uniform(-10.0, 10.0), rng.uniform(-10.0, 10.0), rng.uniform(-10.0, 10.0), rng.uniform(-10.0, 10.0));
+    }
+
+    void random_roi()
+    {
+#ifdef RANDOMROI
+        //randomize ROI
+               cv::RNG &rng = TS::ptr()->get_rng();
+        roicols = rng.uniform(1, mat1.cols);
+        roirows = rng.uniform(1, mat1.rows);
+        src1x   = rng.uniform(0, mat1.cols - roicols);
+        src1y   = rng.uniform(0, mat1.rows - roirows);
+        src2x   = rng.uniform(0, mat2.cols - roicols);
+        src2y   = rng.uniform(0, mat2.rows - roirows);
+        dstx    = rng.uniform(0, dst.cols  - roicols);
+        dsty    = rng.uniform(0, dst.rows  - roirows);
+        maskx   = rng.uniform(0, mask.cols - roicols);
+        masky   = rng.uniform(0, mask.rows - roirows);
+#else
+        roicols = mat1.cols;
+        roirows = mat1.rows;
+        src1x = 0;
+        src1y = 0;
+        src2x = 0;
+        src2y = 0;
+        dstx = 0;
+        dsty = 0;
+        maskx = 0;
+        masky = 0;
+#endif
+        mat1_roi = mat1(Rect(src1x, src1y, roicols, roirows));
+        mat2_roi = mat2(Rect(src2x, src2y, roicols, roirows));
+        mask_roi = mask(Rect(maskx, masky, roicols, roirows));
+        dst_roi  = dst(Rect(dstx, dsty, roicols, roirows));
+        dst1_roi = dst1(Rect(dstx, dsty, roicols, roirows));
+
+        gdst_whole = dst;
+        gdst = gdst_whole(Rect(dstx, dsty, roicols, roirows));
+
+        gdst1_whole = dst1;
+        gdst1 = gdst1_whole(Rect(dstx, dsty, roicols, roirows));
+
+        gmat1 = mat1_roi;
+        gmat2 = mat2_roi;
+        gmask = mask_roi;
+    }
+
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+// blur
+
+PARAM_TEST_CASE(Blur, MatType, cv::Size, int)
+{
+    int type;
+    cv::Size ksize;
+    int bordertype;
+
+    //src mat
+    cv::Mat mat1;
+    cv::Mat dst;
+
+    // set up roi
+    int roicols;
+    int roirows;
+    int src1x;
+    int src1y;
+    int dstx;
+    int dsty;
+
+    //src mat with roi
+    cv::Mat mat1_roi;
+    cv::Mat dst_roi;
+    std::vector<cv::ocl::Info> oclinfo;
+    //ocl dst mat for testing
+    cv::ocl::oclMat gdst_whole;
+
+    //ocl mat with roi
+    cv::ocl::oclMat gmat1;
+    cv::ocl::oclMat gdst;
+
+    virtual void SetUp()
+    {
+        type = GET_PARAM(0);
+        ksize = GET_PARAM(1);
+        bordertype = GET_PARAM(2);
+
+        cv::RNG &rng = TS::ptr()->get_rng();
+        cv::Size size(MWIDTH, MHEIGHT);
+
+        mat1 = randomMat(rng, size, type, 5, 16, false);
+        dst  = randomMat(rng, size, type, 5, 16, false);
+        int devnums = getDevice(oclinfo, OPENCV_DEFAULT_OPENCL_DEVICE);
+        CV_Assert(devnums > 0);
+        //if you want to use undefault device, set it here
+        //setDevice(oclinfo[0]);
+    }
+
+    void random_roi()
+    {      
+#ifdef RANDOMROI
+        //randomize ROI
+               cv::RNG &rng = TS::ptr()->get_rng();
+        roicols = rng.uniform(2, mat1.cols);
+        roirows = rng.uniform(2, mat1.rows);
+        src1x   = rng.uniform(0, mat1.cols - roicols);
+        src1y   = rng.uniform(0, mat1.rows - roirows);
+        dstx    = rng.uniform(0, dst.cols  - roicols);
+        dsty    = rng.uniform(0, dst.rows  - roirows);
+#else
+        roicols = mat1.cols;
+        roirows = mat1.rows;
+        src1x = 0;
+        src1y = 0;
+        dstx = 0;
+        dsty = 0;
+#endif
+
+        mat1_roi = mat1(Rect(src1x, src1y, roicols, roirows));
+        dst_roi  = dst(Rect(dstx, dsty, roicols, roirows));
+
+        gdst_whole = dst;
+        gdst = gdst_whole(Rect(dstx, dsty, roicols, roirows));
+
+
+        gmat1 = mat1_roi;
+    }
+
+};
+
+TEST_P(Blur, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::blur(mat1_roi, dst_roi, ksize, Point(-1, -1), bordertype);
+        cv::ocl::blur(gmat1, gdst, ksize, Point(-1, -1), bordertype);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d", roicols, roirows, src1x, src1y, dstx, dsty);
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1.0, sss);
+    }
+
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//Laplacian
+
+PARAM_TEST_CASE(LaplacianTestBase, MatType, int)
+{
+    int type;
+    int ksize;
+
+    //src mat
+    cv::Mat mat;
+    cv::Mat dst;
+
+    // set up roi
+    int roicols;
+    int roirows;
+    int srcx;
+    int srcy;
+    int dstx;
+    int dsty;
+
+    //src mat with roi
+    cv::Mat mat_roi;
+    cv::Mat dst_roi;
+    std::vector<cv::ocl::Info> oclinfo;
+    //ocl dst mat for testing
+    cv::ocl::oclMat gdst_whole;
+
+    //ocl mat with roi
+    cv::ocl::oclMat gmat;
+    cv::ocl::oclMat gdst;
+
+    virtual void SetUp()
+    {
+        type = GET_PARAM(0);
+        ksize = GET_PARAM(1);
+
+        cv::RNG &rng = TS::ptr()->get_rng();
+        cv::Size size(MWIDTH, MHEIGHT);
+
+        mat  = randomMat(rng, size, type, 5, 16, false);
+        dst  = randomMat(rng, size, type, 5, 16, false);
+
+        int devnums = getDevice(oclinfo, OPENCV_DEFAULT_OPENCL_DEVICE);
+        CV_Assert(devnums > 0);
+        //if you want to use undefault device, set it here
+        //setDevice(oclinfo[0]);
+    }
+
+    void random_roi()
+    {        
+#ifdef RANDOMROI
+        //randomize ROI
+               cv::RNG &rng = TS::ptr()->get_rng();
+        roicols = rng.uniform(2, mat.cols);
+        roirows = rng.uniform(2, mat.rows);
+        srcx   = rng.uniform(0, mat.cols - roicols);
+        srcy   = rng.uniform(0, mat.rows - roirows);
+        dstx    = rng.uniform(0, dst.cols  - roicols);
+        dsty    = rng.uniform(0, dst.rows  - roirows);
+#else
+        roicols = mat.cols;
+        roirows = mat.rows;
+        srcx = 0;
+        srcy = 0;
+        dstx = 0;
+        dsty = 0;
+#endif
+
+        mat_roi  = mat(Rect(srcx, srcy, roicols, roirows));
+        dst_roi  = dst(Rect(dstx, dsty, roicols, roirows));
+
+        gdst_whole = dst;
+        gdst = gdst_whole(Rect(dstx, dsty, roicols, roirows));
+
+        gmat = mat_roi;
+    }
+};
+
+struct Laplacian : LaplacianTestBase {};
+
+TEST_P(Laplacian, Accuracy)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::Laplacian(mat_roi, dst_roi, -1, ksize, 1);
+        cv::ocl::Laplacian(gmat, gdst, -1, ksize, 1);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d", roicols, roirows, srcx, srcy, dstx, dsty);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1e-5, sss);
+    }
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+// erode & dilate
+
+PARAM_TEST_CASE(ErodeDilateBase, MatType, bool)
+{
+    int type;
+    //int iterations;
+
+    //erode or dilate kernel
+    cv::Mat kernel;
+
+    //src mat
+    cv::Mat mat1;
+    cv::Mat dst;
+
+    // set up roi
+    int roicols;
+    int roirows;
+    int src1x;
+    int src1y;
+    int dstx;
+    int dsty;
+
+    //src mat with roi
+    cv::Mat mat1_roi;
+    cv::Mat dst_roi;
+    std::vector<cv::ocl::Info> oclinfo;
+    //ocl dst mat for testing
+    cv::ocl::oclMat gdst_whole;
+
+    //ocl mat with roi
+    cv::ocl::oclMat gmat1;
+    cv::ocl::oclMat gdst;
+
+    virtual void SetUp()
+    {
+        type = GET_PARAM(0);
+        //  iterations = GET_PARAM(1);
+
+        cv::RNG &rng = TS::ptr()->get_rng();
+        cv::Size size(MWIDTH, MHEIGHT);
+
+        mat1 = randomMat(rng, size, type, 5, 16, false);
+        dst  = randomMat(rng, size, type, 5, 16, false);
+        //             rng.fill(kernel, cv::RNG::UNIFORM, cv::Scalar::all(0), cv::Scalar::all(3));
+        kernel = randomMat(rng, Size(3, 3), CV_8UC1, 0, 3, false);
+
+        int devnums = getDevice(oclinfo, OPENCV_DEFAULT_OPENCL_DEVICE);
+        CV_Assert(devnums > 0);
+        //if you want to use undefault device, set it here
+        //setDevice(oclinfo[0]);
+    }
+
+    void random_roi()
+    {       
+#ifdef RANDOMROI
+        //randomize ROI
+               cv::RNG &rng = TS::ptr()->get_rng();
+        roicols = rng.uniform(2, mat1.cols);
+        roirows = rng.uniform(2, mat1.rows);
+        src1x   = rng.uniform(0, mat1.cols - roicols);
+        src1y   = rng.uniform(0, mat1.rows - roirows);
+        dstx    = rng.uniform(0, dst.cols  - roicols);
+        dsty    = rng.uniform(0, dst.rows  - roirows);
+#else
+        roicols = mat1.cols;
+        roirows = mat1.rows;
+        src1x = 0;
+        src1y = 0;
+        dstx = 0;
+        dsty = 0;
+#endif
+
+        mat1_roi = mat1(Rect(src1x, src1y, roicols, roirows));
+        dst_roi  = dst(Rect(dstx, dsty, roicols, roirows));
+
+        gdst_whole = dst;
+        gdst = gdst_whole(Rect(dstx, dsty, roicols, roirows));
+
+
+        gmat1 = mat1_roi;
+    }
+
+};
+
+// erode
+
+struct Erode : ErodeDilateBase {};
+
+TEST_P(Erode, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+        //int iterations =3;
+        //cv::erode(mat1_roi, dst_roi, kernel, Point(-1, -1), iterations);
+        //cv::ocl::erode(gmat1, gdst, kernel, Point(-1, -1), iterations);
+
+        cv::erode(mat1_roi, dst_roi, kernel);
+        cv::ocl::erode(gmat1, gdst, kernel);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d", roicols, roirows, src1x, src1y, dstx, dsty);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1e-5, sss);
+    }
+
+}
+
+
+
+
+
+// dilate
+
+struct Dilate : ErodeDilateBase {};
+
+TEST_P(Dilate, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+        //int iterations =3;
+        //      cv::erode(mat1_roi, dst_roi, kernel, Point(-1, -1), iterations);
+        //      cv::ocl::erode(gmat1, gdst, kernel, Point(-1, -1), iterations);
+
+        //cv::dilate(mat1_roi, dst_roi, kernel);
+        //cv::ocl::dilate(gmat1, gdst, kernel);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d", roicols, roirows, src1x, src1y, dstx, dsty);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1e-5, sss);
+    }
+
+}
+
+
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+// Sobel
+
+PARAM_TEST_CASE(Sobel, MatType, int, int, int, int)
+{
+    int type;
+    int dx, dy, ksize, bordertype;
+
+    //src mat
+    cv::Mat mat1;
+    cv::Mat dst;
+
+    // set up roi
+    int roicols;
+    int roirows;
+    int src1x;
+    int src1y;
+    int dstx;
+    int dsty;
+
+    //src mat with roi
+    cv::Mat mat1_roi;
+    cv::Mat dst_roi;
+    std::vector<cv::ocl::Info> oclinfo;
+    //ocl dst mat for testing
+    cv::ocl::oclMat gdst_whole;
+
+    //ocl mat with roi
+    cv::ocl::oclMat gmat1;
+    cv::ocl::oclMat gdst;
+
+    virtual void SetUp()
+    {
+        type = GET_PARAM(0);
+        dx = GET_PARAM(1);
+        dy = GET_PARAM(2);
+        ksize = GET_PARAM(3);
+        bordertype = GET_PARAM(4);
+
+
+        cv::RNG &rng = TS::ptr()->get_rng();
+        cv::Size size(MWIDTH, MHEIGHT);
+
+        mat1 = randomMat(rng, size, type, 5, 16, false);
+        dst  = randomMat(rng, size, type, 5, 16, false);
+
+        int devnums = getDevice(oclinfo, OPENCV_DEFAULT_OPENCL_DEVICE);
+        CV_Assert(devnums > 0);
+        //if you want to use undefault device, set it here
+        //setDevice(oclinfo[0]);
+    }
+
+    void random_roi()
+    {        
+#ifdef RANDOMROI
+        //randomize ROI
+               cv::RNG &rng = TS::ptr()->get_rng();
+        roicols = rng.uniform(2, mat1.cols);
+        roirows = rng.uniform(2, mat1.rows);
+        src1x   = rng.uniform(0, mat1.cols - roicols);
+        src1y   = rng.uniform(0, mat1.rows - roirows);
+        dstx    = rng.uniform(0, dst.cols  - roicols);
+        dsty    = rng.uniform(0, dst.rows  - roirows);
+#else
+        roicols = mat1.cols;
+        roirows = mat1.rows;
+        src1x = 0;
+        src1y = 0;
+        dstx = 0;
+        dsty = 0;
+#endif
+
+        mat1_roi = mat1(Rect(src1x, src1y, roicols, roirows));
+        dst_roi  = dst(Rect(dstx, dsty, roicols, roirows));
+
+        gdst_whole = dst;
+        gdst = gdst_whole(Rect(dstx, dsty, roicols, roirows));
+
+
+        gmat1 = mat1_roi;
+    }
+
+};
+
+TEST_P(Sobel, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::Sobel(mat1_roi, dst_roi, -1, dx, dy, ksize, /*scale*/0.00001,/*delta*/0, bordertype);
+        cv::ocl::Sobel(gmat1, gdst, -1, dx, dy, ksize,/*scale*/0.00001,/*delta*/0, bordertype);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d", roicols, roirows, src1x, src1y, dstx, dsty);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1, sss);
+    }
+
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+// Scharr
+
+PARAM_TEST_CASE(Scharr, MatType, int, int, int)
+{
+    int type;
+    int dx, dy, bordertype;
+
+    //src mat
+    cv::Mat mat1;
+    cv::Mat dst;
+
+    // set up roi
+    int roicols;
+    int roirows;
+    int src1x;
+    int src1y;
+    int dstx;
+    int dsty;
+
+    //src mat with roi
+    cv::Mat mat1_roi;
+    cv::Mat dst_roi;
+    std::vector<cv::ocl::Info> oclinfo;
+    //ocl dst mat for testing
+    cv::ocl::oclMat gdst_whole;
+
+    //ocl mat with roi
+    cv::ocl::oclMat gmat1;
+    cv::ocl::oclMat gdst;
+
+    virtual void SetUp()
+    {
+        type = GET_PARAM(0);
+        dx = GET_PARAM(1);
+        dy = GET_PARAM(2);
+        bordertype = GET_PARAM(3);
+        dx = 1;
+        dy = 0;
+
+        cv::RNG &rng = TS::ptr()->get_rng();
+        cv::Size size(MWIDTH, MHEIGHT);
+
+        mat1 = randomMat(rng, size, type, 5, 16, false);
+        dst  = randomMat(rng, size, type, 5, 16, false);
+
+        int devnums = getDevice(oclinfo, OPENCV_DEFAULT_OPENCL_DEVICE);
+        CV_Assert(devnums > 0);
+        //if you want to use undefault device, set it here
+        //setDevice(oclinfo[0]);
+    }
+
+    void random_roi()
+    {       
+#ifdef RANDOMROI
+        //randomize ROI
+               cv::RNG &rng = TS::ptr()->get_rng();
+        roicols = rng.uniform(2, mat1.cols);
+        roirows = rng.uniform(2, mat1.rows);
+        src1x   = rng.uniform(0, mat1.cols - roicols);
+        src1y   = rng.uniform(0, mat1.rows - roirows);
+        dstx    = rng.uniform(0, dst.cols  - roicols);
+        dsty    = rng.uniform(0, dst.rows  - roirows);
+#else
+        roicols = mat1.cols;
+        roirows = mat1.rows;
+        src1x = 0;
+        src1y = 0;
+        dstx = 0;
+        dsty = 0;
+#endif
+
+        mat1_roi = mat1(Rect(src1x, src1y, roicols, roirows));
+        dst_roi  = dst(Rect(dstx, dsty, roicols, roirows));
+
+        gdst_whole = dst;
+        gdst = gdst_whole(Rect(dstx, dsty, roicols, roirows));
+
+
+        gmat1 = mat1_roi;
+    }
+
+};
+
+TEST_P(Scharr, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::Scharr(mat1_roi, dst_roi, -1, dx, dy, /*scale*/1,/*delta*/0, bordertype);
+        cv::ocl::Scharr(gmat1, gdst, -1, dx, dy,/*scale*/1,/*delta*/0, bordertype);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d", roicols, roirows, src1x, src1y, dstx, dsty);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1, sss);
+    }
+
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+// GaussianBlur
+
+PARAM_TEST_CASE(GaussianBlur, MatType, cv::Size, int)
+{
+    int type;
+    cv::Size ksize;
+    int bordertype;
+
+    double sigma1, sigma2;
+
+    //src mat
+    cv::Mat mat1;
+    cv::Mat dst;
+
+    // set up roi
+    int roicols;
+    int roirows;
+    int src1x;
+    int src1y;
+    int dstx;
+    int dsty;
+
+    //src mat with roi
+    cv::Mat mat1_roi;
+    cv::Mat dst_roi;
+    std::vector<cv::ocl::Info> oclinfo;
+    //ocl dst mat for testing
+    cv::ocl::oclMat gdst_whole;
+
+    //ocl mat with roi
+    cv::ocl::oclMat gmat1;
+    cv::ocl::oclMat gdst;
+
+    virtual void SetUp()
+    {
+        type = GET_PARAM(0);
+        ksize = GET_PARAM(1);
+        bordertype = GET_PARAM(2);
+
+        cv::RNG &rng = TS::ptr()->get_rng();
+        cv::Size size(MWIDTH, MHEIGHT);
+
+        sigma1 = rng.uniform(0.1, 1.0);
+        sigma2 = rng.uniform(0.1, 1.0);
+
+        mat1 = randomMat(rng, size, type, 5, 16, false);
+        dst  = randomMat(rng, size, type, 5, 16, false);
+
+        int devnums = getDevice(oclinfo, OPENCV_DEFAULT_OPENCL_DEVICE);
+        CV_Assert(devnums > 0);
+        //if you want to use undefault device, set it here
+        //setDevice(oclinfo[0]);
+    }
+
+    void random_roi()
+    {       
+#ifdef RANDOMROI
+        //randomize ROI
+               cv::RNG &rng = TS::ptr()->get_rng();
+        roicols = rng.uniform(2, mat1.cols);
+        roirows = rng.uniform(2, mat1.rows);
+        src1x   = rng.uniform(0, mat1.cols - roicols);
+        src1y   = rng.uniform(0, mat1.rows - roirows);
+        dstx    = rng.uniform(0, dst.cols  - roicols);
+        dsty    = rng.uniform(0, dst.rows  - roirows);
+#else
+        roicols = mat1.cols;
+        roirows = mat1.rows;
+        src1x = 0;
+        src1y = 0;
+        dstx = 0;
+        dsty = 0;
+#endif
+
+        mat1_roi = mat1(Rect(src1x, src1y, roicols, roirows));
+        dst_roi  = dst(Rect(dstx, dsty, roicols, roirows));
+
+        gdst_whole = dst;
+        gdst = gdst_whole(Rect(dstx, dsty, roicols, roirows));
+
+
+        gmat1 = mat1_roi;
+    }
+
+};
+
+TEST_P(GaussianBlur, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::GaussianBlur(mat1_roi, dst_roi, ksize, sigma1, sigma2, bordertype);
+        cv::ocl::GaussianBlur(gmat1, gdst, ksize, sigma1, sigma2, bordertype);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d", roicols, roirows, src1x, src1y, dstx, dsty);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1.0, sss);
+    }
+
+}
+
+
+
+INSTANTIATE_TEST_CASE_P(Filter, Blur, Combine(Values(CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4),
+                        Values(cv::Size(3, 3), cv::Size(5, 5), cv::Size(7, 7)),
+                        Values((MatType)cv::BORDER_CONSTANT, (MatType)cv::BORDER_REPLICATE, (MatType)cv::BORDER_REFLECT, (MatType)cv::BORDER_REFLECT_101)));
+
+
+INSTANTIATE_TEST_CASE_P(Filters, Laplacian, Combine(
+                            Values(CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4),
+                            Values(1, 3)));
+
+//INSTANTIATE_TEST_CASE_P(Filter, ErodeDilate, Combine(Values(CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4), Values(1, 2, 3)));
+
+INSTANTIATE_TEST_CASE_P(Filter, Erode, Combine(Values(CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4), Values(false)));
+
+//INSTANTIATE_TEST_CASE_P(Filter, ErodeDilate, Combine(Values(CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4), Values(1, 2, 3)));
+
+INSTANTIATE_TEST_CASE_P(Filter, Dilate, Combine(Values(CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4), Values(false)));
+
+
+INSTANTIATE_TEST_CASE_P(Filter, Sobel, Combine(Values(CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4),
+                        Values(1, 2), Values(0, 1), Values(3, 5, 7), Values((MatType)cv::BORDER_CONSTANT,
+                                (MatType)cv::BORDER_REPLICATE, (MatType)cv::BORDER_REFLECT, (MatType)cv::BORDER_REFLECT_101)));
+
+
+INSTANTIATE_TEST_CASE_P(Filter, Scharr, Combine(
+                            Values(CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4), Values(0, 1), Values(0, 1),
+                            Values((MatType)cv::BORDER_CONSTANT, (MatType)cv::BORDER_REPLICATE, (MatType)cv::BORDER_REFLECT, (MatType)cv::BORDER_REFLECT_101)));
+
+INSTANTIATE_TEST_CASE_P(Filter, GaussianBlur, Combine(
+                            Values(CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4),
+                            Values(cv::Size(3, 3), cv::Size(5, 5), cv::Size(7, 7)),
+                            Values((MatType)cv::BORDER_CONSTANT, (MatType)cv::BORDER_REPLICATE, (MatType)cv::BORDER_REFLECT, (MatType)cv::BORDER_REFLECT_101)));
+
+                            
+
+#endif // HAVE_OPENCL
diff --git a/modules/ocl/test/test_haar.cpp b/modules/ocl/test/test_haar.cpp
new file mode 100644 (file)
index 0000000..ea99326
--- /dev/null
@@ -0,0 +1,206 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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;
+
+struct getRect
+{
+    Rect operator ()(const CvAvgComp &e) const
+    {
+        return e.rect;
+    }
+};
+
+PARAM_TEST_CASE(HaarTestBase, int, int)
+{
+       std::vector<cv::ocl::Info> oclinfo;
+    cv::ocl::OclCascadeClassifier cascade, nestedCascade;
+    cv::CascadeClassifier cpucascade, cpunestedCascade;
+    //    Mat img;
+
+    double scale;
+    int index;
+
+    virtual void SetUp()
+    {
+        scale = 1.1;
+
+#if WIN32
+        string cascadeName = "E:\\opencvbuffer\\trunk\\data\\haarcascades\\haarcascade_frontalface_alt.xml";
+#else
+        string cascadeName = "../data/haarcascades/haarcascade_frontalface_alt.xml";
+#endif
+
+        if( (!cascade.load( cascadeName )) || (!cpucascade.load(cascadeName)))
+        {
+            cout << "ERROR: Could not load classifier cascade" << endl;
+            cout << "Usage: facedetect [--cascade=<cascade_path>]\n"
+                 "   [--nested-cascade[=nested_cascade_path]]\n"
+                 "   [--scale[=<image scale>\n"
+                 "   [filename|camera_index]\n" << endl ;
+
+            return;
+        }
+    int devnums = getDevice(oclinfo, OPENCV_DEFAULT_OPENCL_DEVICE);
+    CV_Assert(devnums > 0);
+    //if you want to use undefault device, set it here
+    //setDevice(oclinfo[0]);
+    cv::ocl::setBinpath("E:\\");
+    }
+};
+
+////////////////////////////////faceDetect/////////////////////////////////////////////////
+
+struct Haar : HaarTestBase {};
+
+TEST_P(Haar, FaceDetect)
+{
+   
+    for(int index = 1; index < 2; index++)
+    {
+        Mat img;
+        char buff[256];
+#if WIN32
+        sprintf(buff, "E:\\myDataBase\\%d.jpg", index);
+        img = imread( buff, 1 );
+#else
+        sprintf(buff, "%d.jpg", index);
+        img = imread( buff, 1 );
+        std::cout << "Now test " << index << ".jpg" << std::endl;
+#endif
+        if(img.empty())
+        {
+            std::cout << "Couldn't read test" << index << ".jpg" << std::endl;
+            continue;
+        }
+
+        int i = 0;
+        double t = 0;
+        vector<Rect> faces;
+
+        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)
+                                        } ;
+
+        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 );
+        CvMat _image = smallImg;
+
+        Mat tempimg(&_image, false);
+
+        cv::ocl::oclMat image(tempimg);
+        CvSeq *_objects;
+
+#if 1
+        for(int k = 0; k < 10; k++)
+        {
+            t = (double)cvGetTickCount();
+            _objects = cascade.oclHaarDetectObjects( image, storage, 1.1,
+                       2, 0
+                       | CV_HAAR_SCALE_IMAGE
+                       , Size(30, 30), Size(0, 0) );
+
+            t = (double)cvGetTickCount() - t ;
+            printf( "detection time = %g ms\n", t / ((double)cvGetTickFrequency() * 1000.) );
+        }
+
+#else
+        cpucascade.detectMultiScale( image, faces,  1.1,
+                                     2, 0
+                                     | CV_HAAR_SCALE_IMAGE
+                                     , Size(30, 30), Size(0, 0) );
+
+#endif
+        vector<CvAvgComp> vecAvgComp;
+        Seq<CvAvgComp>(_objects).copyTo(vecAvgComp);
+        faces.resize(vecAvgComp.size());
+        std::transform(vecAvgComp.begin(), vecAvgComp.end(), faces.begin(), getRect());
+
+        for( vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++, i++ )
+        {
+            Mat smallImgROI;
+            vector<Rect> nestedObjects;
+            Point center;
+            Scalar color = colors[i%8];
+            int radius;
+            center.x = cvRound((r->x + r->width * 0.5) * scale);
+            center.y = cvRound((r->y + r->height * 0.5) * scale);
+            radius = cvRound((r->width + r->height) * 0.25 * scale);
+            circle( img, center, radius, color, 3, 8, 0 );
+        }
+
+#if WIN32
+        sprintf(buff, "E:\\result1\\%d.jpg", index);
+        imwrite(buff, img);
+#else
+        sprintf(buff, "testdet_%d.jpg", index);
+        imwrite(buff, img);
+#endif
+    }
+}
+
+
+//INSTANTIATE_TEST_CASE_P(HaarTestBase, Haar, Combine(Values(1),
+  //          Values(1)));
+
+
+#endif // HAVE_OPENCL
diff --git a/modules/ocl/test/test_imgproc.cpp b/modules/ocl/test/test_imgproc.cpp
new file mode 100644 (file)
index 0000000..2b8a29c
--- /dev/null
@@ -0,0 +1,1455 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Niko Li, newlife20080214@gmail.com
+//    Jia Haipeng, jiahaipeng95@gmail.com
+//    Shengen Yan, yanshengen@gmail.com
+//    Jiang Liyuan, lyuan001.good@163.com
+//    Rock Li, Rock.Li@amd.com
+//    Wu Zailong, bullet@yeah.net
+//    Xu Pang, pangxu010@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 "precomp.hpp"
+
+#ifdef HAVE_OPENCL
+
+using namespace cvtest;
+using namespace testing;
+using namespace std;
+
+MatType nulltype = -1;
+
+#define ONE_TYPE(type)  testing::ValuesIn(typeVector(type))
+#define NULL_TYPE  testing::ValuesIn(typeVector(nulltype))
+
+vector<MatType> typeVector(MatType type)
+{
+    vector<MatType> v;
+    v.push_back(type);
+    return v;
+}
+
+typedef struct
+{
+    short x;
+    short y;
+} COOR;
+
+COOR do_meanShift(int x0, int y0, uchar *sptr, uchar *dptr, int sstep, cv::Size size, int sp, int sr, int maxIter, float eps, int *tab)
+{
+
+    int isr2 = sr * sr;
+    int c0, c1, c2, c3;
+    int iter;
+    uchar *ptr = NULL;
+    uchar *pstart = NULL;
+    int revx = 0, revy = 0;
+    c0 = sptr[0];
+    c1 = sptr[1];
+    c2 = sptr[2];
+    c3 = sptr[3];
+    // iterate meanshift procedure
+    for(iter = 0; iter < maxIter; iter++ )
+    {
+        int count = 0;
+        int s0 = 0, s1 = 0, s2 = 0, sx = 0, sy = 0;
+
+        //mean shift: process pixels in window (p-sigmaSp)x(p+sigmaSp)
+        int minx = x0 - sp;
+        int miny = y0 - sp;
+        int maxx = x0 + sp;
+        int maxy = y0 + sp;
+
+        //deal with the image boundary
+        if(minx < 0) minx = 0;
+        if(miny < 0) miny = 0;
+        if(maxx >= size.width) maxx = size.width - 1;
+        if(maxy >= size.height) maxy = size.height - 1;
+        if(iter == 0)
+        {
+            pstart = sptr;
+        }
+        else
+        {
+            pstart = pstart + revy * sstep + (revx << 2); //point to the new position
+        }
+        ptr = pstart;
+        ptr = ptr + (miny - y0) * sstep + ((minx - x0) << 2); //point to the start in the row
+
+        for( int y = miny; y <= maxy; y++, ptr += sstep - ((maxx - minx + 1) << 2))
+        {
+            int rowCount = 0;
+            int x = minx;
+#if CV_ENABLE_UNROLLED
+            for( ; x + 4 <= maxx; x += 4, ptr += 16)
+            {
+                int t0, t1, t2;
+                t0 = ptr[0], t1 = ptr[1], t2 = ptr[2];
+                if(tab[t0-c0+255] + tab[t1-c1+255] + tab[t2-c2+255] <= isr2)
+                {
+                    s0 += t0;
+                    s1 += t1;
+                    s2 += t2;
+                    sx += x;
+                    rowCount++;
+                }
+                t0 = ptr[4], t1 = ptr[5], t2 = ptr[6];
+                if(tab[t0-c0+255] + tab[t1-c1+255] + tab[t2-c2+255] <= isr2)
+                {
+                    s0 += t0;
+                    s1 += t1;
+                    s2 += t2;
+                    sx += x + 1;
+                    rowCount++;
+                }
+                t0 = ptr[8], t1 = ptr[9], t2 = ptr[10];
+                if(tab[t0-c0+255] + tab[t1-c1+255] + tab[t2-c2+255] <= isr2)
+                {
+                    s0 += t0;
+                    s1 += t1;
+                    s2 += t2;
+                    sx += x + 2;
+                    rowCount++;
+                }
+                t0 = ptr[12], t1 = ptr[13], t2 = ptr[14];
+                if(tab[t0-c0+255] + tab[t1-c1+255] + tab[t2-c2+255] <= isr2)
+                {
+                    s0 += t0;
+                    s1 += t1;
+                    s2 += t2;
+                    sx += x + 3;
+                    rowCount++;
+                }
+            }
+#endif
+            for(; x <= maxx; x++, ptr += 4)
+            {
+                int t0 = ptr[0], t1 = ptr[1], t2 = ptr[2];
+                if(tab[t0-c0+255] + tab[t1-c1+255] + tab[t2-c2+255] <= isr2)
+                {
+                    s0 += t0;
+                    s1 += t1;
+                    s2 += t2;
+                    sx += x;
+                    rowCount++;
+                }
+            }
+            if(rowCount == 0)
+                continue;
+            count += rowCount;
+            sy += y * rowCount;
+        }
+
+        if( count == 0 )
+            break;
+
+        double icount = 1.0 / count;
+        int x1 = cvFloor(sx * icount);
+        int y1 = cvFloor(sy * icount);
+        s0 = cvFloor(s0 * icount);
+        s1 = cvFloor(s1 * icount);
+        s2 = cvFloor(s2 * icount);
+
+        bool stopFlag = (x0 == x1 && y0 == y1) || (abs(x1 - x0) + abs(y1 - y0) +
+                        tab[s0-c0+255] + tab[s1-c1+255] + tab[s2-c2+255] <= eps);
+
+        //revise the pointer corresponding to the new (y0,x0)
+        revx = x1 - x0;
+        revy = y1 - y0;
+
+        x0 = x1;
+        y0 = y1;
+        c0 = s0;
+        c1 = s1;
+        c2 = s2;
+
+        if( stopFlag )
+            break;
+    } //for iter
+
+    dptr[0] = (uchar)c0;
+    dptr[1] = (uchar)c1;
+    dptr[2] = (uchar)c2;
+    dptr[3] = (uchar)c3;
+
+    COOR coor;
+    coor.x = x0;
+    coor.y = y0;
+    return coor;
+}
+
+void meanShiftFiltering_(const Mat &src_roi, Mat &dst_roi, int sp, int sr, cv::TermCriteria crit)
+{
+    if( src_roi.empty() )
+        CV_Error( CV_StsBadArg, "The input image is empty" );
+
+    if( src_roi.depth() != CV_8U || src_roi.channels() != 4 )
+        CV_Error( CV_StsUnsupportedFormat, "Only 8-bit, 4-channel images are supported" );
+
+    CV_Assert( (src_roi.cols == dst_roi.cols) && (src_roi.rows == dst_roi.rows) );
+    CV_Assert( !(dst_roi.step & 0x3) );
+
+    if( !(crit.type & cv::TermCriteria::MAX_ITER) )
+        crit.maxCount = 5;
+    int maxIter = std::min(std::max(crit.maxCount, 1), 100);
+    float eps;
+    if( !(crit.type & cv::TermCriteria::EPS) )
+        eps = 1.f;
+    eps = (float)std::max(crit.epsilon, 0.0);
+
+    int tab[512];
+    for(int i = 0; i < 512; i++)
+        tab[i] = (i - 255) * (i - 255);
+    uchar *sptr = src_roi.data;
+    uchar *dptr = dst_roi.data;
+    int sstep = (int)src_roi.step;
+    int dstep = (int)dst_roi.step;
+    cv::Size size = src_roi.size();
+
+    for(int i = 0; i < size.height; i++, sptr += sstep - (size.width << 2),
+            dptr += dstep - (size.width << 2))
+    {
+        for(int j = 0; j < size.width; j++, sptr += 4, dptr += 4)
+        {
+            do_meanShift(j, i, sptr, dptr, sstep, size, sp, sr, maxIter, eps, tab);
+        }
+    }
+}
+
+void meanShiftProc_(const Mat &src_roi, Mat &dst_roi, Mat &dstCoor_roi, int sp, int sr, cv::TermCriteria crit)
+{
+
+    if( src_roi.empty() )
+        CV_Error( CV_StsBadArg, "The input image is empty" );
+    if( src_roi.depth() != CV_8U || src_roi.channels() != 4 )
+        CV_Error( CV_StsUnsupportedFormat, "Only 8-bit, 4-channel images are supported" );
+    CV_Assert( (src_roi.cols == dst_roi.cols) && (src_roi.rows == dst_roi.rows) &&
+               (src_roi.cols == dstCoor_roi.cols) && (src_roi.rows == dstCoor_roi.rows));
+    CV_Assert( !(dstCoor_roi.step & 0x3) );
+
+    if( !(crit.type & cv::TermCriteria::MAX_ITER) )
+        crit.maxCount = 5;
+    int maxIter = std::min(std::max(crit.maxCount, 1), 100);
+    float eps;
+    if( !(crit.type & cv::TermCriteria::EPS) )
+        eps = 1.f;
+    eps = (float)std::max(crit.epsilon, 0.0);
+
+    int tab[512];
+    for(int i = 0; i < 512; i++)
+        tab[i] = (i - 255) * (i - 255);
+    uchar *sptr = src_roi.data;
+    uchar *dptr = dst_roi.data;
+    short *dCoorptr = (short *)dstCoor_roi.data;
+    int sstep = (int)src_roi.step;
+    int dstep = (int)dst_roi.step;
+    int dCoorstep = (int)dstCoor_roi.step >> 1;
+    cv::Size size = src_roi.size();
+
+    for(int i = 0; i < size.height; i++, sptr += sstep - (size.width << 2),
+            dptr += dstep - (size.width << 2), dCoorptr += dCoorstep - (size.width << 1))
+    {
+        for(int j = 0; j < size.width; j++, sptr += 4, dptr += 4, dCoorptr += 2)
+        {
+            *((COOR *)dCoorptr) = do_meanShift(j, i, sptr, dptr, sstep, size, sp, sr, maxIter, eps, tab);
+        }
+    }
+
+}
+
+PARAM_TEST_CASE(ImgprocTestBase, MatType, MatType, MatType, MatType, MatType, bool)
+{
+    int type1, type2, type3, type4, type5;
+    cv::Scalar val;
+    // set up roi
+    int roicols;
+    int roirows;
+    int src1x;
+    int src1y;
+    int src2x;
+    int src2y;
+    int dstx;
+    int dsty;
+    int dst1x;
+    int dst1y;
+    int maskx;
+    int masky;
+
+    //mat
+    cv::Mat mat1;
+    cv::Mat mat2;
+    cv::Mat mask;
+    cv::Mat dst;
+    cv::Mat dst1; //bak, for two outputs
+
+    //mat with roi
+    cv::Mat mat1_roi;
+    cv::Mat mat2_roi;
+    cv::Mat mask_roi;
+    cv::Mat dst_roi;
+    cv::Mat dst1_roi; //bak
+    std::vector<cv::ocl::Info> oclinfo;
+    //ocl mat
+    cv::ocl::oclMat clmat1;
+    cv::ocl::oclMat clmat2;
+    cv::ocl::oclMat clmask;
+    cv::ocl::oclMat cldst;
+    cv::ocl::oclMat cldst1; //bak
+
+    //ocl mat with roi
+    cv::ocl::oclMat clmat1_roi;
+    cv::ocl::oclMat clmat2_roi;
+    cv::ocl::oclMat clmask_roi;
+    cv::ocl::oclMat cldst_roi;
+    cv::ocl::oclMat cldst1_roi;
+
+    virtual void SetUp()
+    {
+        type1 = GET_PARAM(0);
+        type2 = GET_PARAM(1);
+        type3 = GET_PARAM(2);
+        type4 = GET_PARAM(3);
+        type5 = GET_PARAM(4);
+        cv::RNG &rng = TS::ptr()->get_rng();
+        cv::Size size(MWIDTH, MHEIGHT);
+        double min = 1, max = 20;
+        int devnums = getDevice(oclinfo, OPENCV_DEFAULT_OPENCL_DEVICE);
+        CV_Assert(devnums > 0);
+        //if you want to use undefault device, set it here
+        //setDevice(oclinfo[0]);
+
+        if(type1 != nulltype)
+        {
+            mat1 = randomMat(rng, size, type1, min, max, false);
+            clmat1 = mat1;
+        }
+        if(type2 != nulltype)
+        {
+            mat2 = randomMat(rng, size, type2, min, max, false);
+            clmat2 = mat2;
+        }
+        if(type3 != nulltype)
+        {
+            dst  = randomMat(rng, size, type3, min, max, false);
+            cldst = dst;
+        }
+        if(type4 != nulltype)
+        {
+            dst1 = randomMat(rng, size, type4, min, max, false);
+            cldst1 = dst1;
+        }
+        if(type5 != nulltype)
+        {
+            mask = randomMat(rng, size, CV_8UC1, 0, 2,  false);
+            cv::threshold(mask, mask, 0.5, 255., type5);
+            clmask = mask;
+        }
+        val = cv::Scalar(rng.uniform(-10.0, 10.0), rng.uniform(-10.0, 10.0), rng.uniform(-10.0, 10.0), rng.uniform(-10.0, 10.0));
+    }
+
+    void random_roi()
+    {     
+#ifdef RANDOMROI
+        //randomize ROI
+               cv::RNG &rng = TS::ptr()->get_rng();
+        roicols = rng.uniform(1, mat1.cols);
+        roirows = rng.uniform(1, mat1.rows);
+        src1x   = rng.uniform(0, mat1.cols - roicols);
+        src1y   = rng.uniform(0, mat1.rows - roirows);
+        src2x   = rng.uniform(0, mat2.cols - roicols);
+        src2y   = rng.uniform(0, mat2.rows - roirows);
+        dstx    = rng.uniform(0, dst.cols  - roicols);
+        dsty    = rng.uniform(0, dst.rows  - roirows);
+        dst1x    = rng.uniform(0, dst1.cols  - roicols);
+        dst1y    = rng.uniform(0, dst1.rows  - roirows);
+        maskx   = rng.uniform(0, mask.cols - roicols);
+        masky   = rng.uniform(0, mask.rows - roirows);
+#else
+        roicols = mat1.cols;
+        roirows = mat1.rows;
+        src1x = 0;
+        src1y = 0;
+        src2x = 0;
+        src2y = 0;
+        dstx = 0;
+        dsty = 0;
+        dst1x = 0;
+        dst1y = 0;
+        maskx = 0;
+        masky = 0;
+#endif
+
+
+        if(type1 != nulltype)
+        {
+            mat1_roi = mat1(Rect(src1x, src1y, roicols, roirows));
+            clmat1_roi = clmat1(Rect(src1x, src1y, roicols, roirows));
+        }
+        if(type2 != nulltype)
+        {
+            mat2_roi = mat2(Rect(src2x, src2y, roicols, roirows));
+            clmat2_roi = clmat2(Rect(src2x, src2y, roicols, roirows));
+        }
+        if(type3 != nulltype)
+        {
+            dst_roi  = dst(Rect(dstx, dsty, roicols, roirows));
+            cldst_roi = cldst(Rect(dstx, dsty, roicols, roirows));
+        }
+        if(type4 != nulltype)
+        {
+            dst1_roi = dst1(Rect(dst1x, dst1y, roicols, roirows));
+            cldst1_roi = cldst1(Rect(dst1x, dst1y, roicols, roirows));
+        }
+        if(type5 != nulltype)
+        {
+            mask_roi = mask(Rect(maskx, masky, roicols, roirows));
+            clmask_roi = clmask(Rect(maskx, masky, roicols, roirows));
+        }
+    }
+};
+////////////////////////////////equalizeHist//////////////////////////////////////////
+
+struct equalizeHist : ImgprocTestBase {};
+
+TEST_P(equalizeHist, Mat)
+{
+    if (mat1.type() != CV_8UC1 || mat1.type() != dst.type())
+    {
+        cout << "Unsupported type" << endl;
+        EXPECT_DOUBLE_EQ(0.0, 0.0);
+    }
+    else
+    {
+        for(int j = 0; j < LOOP_TIMES; j++)
+        {
+            random_roi();
+            cv::equalizeHist(mat1_roi, dst_roi);
+            cv::ocl::equalizeHist(clmat1_roi, cldst_roi);
+            cv::Mat cpu_cldst;
+            cldst.download(cpu_cldst);
+            char sss[1024];
+            sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,dst1x=%d,dst1y=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, dst1x, dst1y, maskx, masky, src2x, src2y);
+            EXPECT_MAT_NEAR(dst, cpu_cldst, 1.1, sss);
+        }
+    }
+}
+
+
+
+
+
+////////////////////////////////bilateralFilter////////////////////////////////////////////
+
+struct bilateralFilter : ImgprocTestBase {};
+
+TEST_P(bilateralFilter, Mat)
+{
+    double sigmacolor = 50.0;
+    int radius = 9;
+    int d = 2 * radius + 1;
+    double sigmaspace = 20.0;
+    int bordertype[] = {cv::BORDER_CONSTANT, cv::BORDER_REPLICATE/*,BORDER_REFLECT,BORDER_WRAP,BORDER_REFLECT_101*/};
+    //const char* borderstr[]={"BORDER_CONSTANT", "BORDER_REPLICATE"/*, "BORDER_REFLECT","BORDER_WRAP","BORDER_REFLECT_101"*/};
+
+    if (mat1.type() != CV_8UC1 || mat1.type() != dst.type())
+    {
+        cout << "Unsupported type" << endl;
+        EXPECT_DOUBLE_EQ(0.0, 0.0);
+    }
+    else
+    {
+        for(int i = 0; i < sizeof(bordertype) / sizeof(int); i++)
+            for(int j = 0; j < LOOP_TIMES; j++)
+            {
+                random_roi();
+                cv::bilateralFilter(mat1_roi, dst_roi, d, sigmacolor, sigmaspace, bordertype[i]);
+                cv::ocl::bilateralFilter(clmat1_roi, cldst_roi, d, sigmacolor, sigmaspace, bordertype[i]);
+
+                cv::Mat cpu_cldst;
+                cldst.download(cpu_cldst);
+                char sss[1024];
+                sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,dst1x=%d,dst1y=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, dst1x, dst1y, maskx, masky, src2x, src2y);
+
+                EXPECT_MAT_NEAR(dst, cpu_cldst, 0.0, sss);
+            }
+    }
+}
+
+
+
+////////////////////////////////copyMakeBorder////////////////////////////////////////////
+
+struct CopyMakeBorder : ImgprocTestBase {};
+
+TEST_P(CopyMakeBorder, Mat)
+{
+    int bordertype[] = {cv::BORDER_CONSTANT, cv::BORDER_REPLICATE/*,BORDER_REFLECT,BORDER_WRAP,BORDER_REFLECT_101*/};
+    //const char* borderstr[]={"BORDER_CONSTANT", "BORDER_REPLICATE"/*, "BORDER_REFLECT","BORDER_WRAP","BORDER_REFLECT_101"*/};
+
+    if ((mat1.type() != CV_8UC1 && mat1.type() != CV_8UC4 && mat1.type() != CV_32SC1) || mat1.type() != dst.type())
+    {
+        cout << "Unsupported type" << endl;
+        EXPECT_DOUBLE_EQ(0.0, 0.0);
+    }
+    else
+    {
+        for(int i = 0; i < sizeof(bordertype) / sizeof(int); i++)
+            for(int j = 0; j < LOOP_TIMES; j++)
+            {
+                random_roi();
+                cv::copyMakeBorder(mat1_roi, dst_roi, 7, 5, 5, 7, bordertype[i], cv::Scalar(1.0));
+                cv::ocl::copyMakeBorder(clmat1_roi, cldst_roi, 7, 5, 5, 7,  bordertype[i], cv::Scalar(1.0));
+
+                cv::Mat cpu_cldst;
+                cldst.download(cpu_cldst);
+                char sss[1024];
+                sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,dst1x=%d,dst1y=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, dst1x, dst1y, maskx, masky, src2x, src2y);
+
+                EXPECT_MAT_NEAR(dst, cpu_cldst, 0.0, sss);
+            }
+    }
+}
+
+
+
+////////////////////////////////cornerMinEigenVal//////////////////////////////////////////
+
+struct cornerMinEigenVal : ImgprocTestBase {};
+
+TEST_P(cornerMinEigenVal, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+
+        random_roi();
+        int blockSize = 7, apertureSize = 1 + 2 * (rand() % 4);
+        //int borderType = cv::BORDER_CONSTANT;
+        //int borderType = cv::BORDER_REPLICATE;
+        int borderType = cv::BORDER_REFLECT;
+        cv::cornerMinEigenVal(mat1_roi, dst_roi, blockSize, apertureSize, borderType);
+        cv::ocl::cornerMinEigenVal(clmat1_roi, cldst_roi, blockSize, apertureSize, borderType);
+
+
+        cv::Mat cpu_cldst;
+        cldst.download(cpu_cldst);
+
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,dst1x=%d,dst1y=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, dst1x, dst1y, maskx, masky, src2x, src2y);
+        EXPECT_MAT_NEAR(dst, cpu_cldst, 1, sss);
+    }
+}
+
+
+
+////////////////////////////////cornerHarris//////////////////////////////////////////
+
+struct cornerHarris : ImgprocTestBase {};
+
+TEST_P(cornerHarris, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+
+        random_roi();
+        int blockSize = 7, apertureSize = 3; //1 + 2 * (rand() % 4);
+        double k = 2;
+        //int borderType = cv::BORDER_CONSTANT;
+        //int borderType = cv::BORDER_REPLICATE;
+        int borderType = cv::BORDER_REFLECT;
+        cv::cornerHarris(mat1_roi, dst_roi, blockSize, apertureSize, k, borderType);
+        cv::ocl::cornerHarris(clmat1_roi, cldst_roi, blockSize, apertureSize, k, borderType);
+        cv::Mat cpu_cldst;
+        cldst.download(cpu_cldst);
+
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,dst1x=%d,dst1y=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, dst1x, dst1y, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_cldst, 1, sss);
+    }
+}
+
+
+////////////////////////////////integral/////////////////////////////////////////////////
+
+struct integral : ImgprocTestBase {};
+
+TEST_P(integral, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::ocl::integral(clmat1_roi, cldst_roi, cldst1_roi);
+        cv::integral(mat1_roi, dst_roi, dst1_roi);
+
+        cv::Mat cpu_cldst, cpu_cldst1;
+        cldst.download(cpu_cldst);
+        cldst1.download(cpu_cldst1);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x=%d,src1y=%d,dstx=%d,dsty=%d,dst1x=%d,dst1y=%d,maskx=%d,masky=%d,src2x=%d,src2y=%d", roicols, roirows, src1x, src1y, dstx, dsty, dst1x, dst1y, maskx, masky, src2x, src2y);
+
+        EXPECT_MAT_NEAR(dst, cpu_cldst, 0.0, sss);
+        EXPECT_MAT_NEAR(dst1, cpu_cldst1, 0.0, sss);
+    }
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+// warpAffine  & warpPerspective
+
+PARAM_TEST_CASE(WarpTestBase, MatType, int)
+{
+    int type;
+    cv::Size size;
+    int interpolation;
+
+    //src mat
+    cv::Mat mat1;
+    cv::Mat dst;
+
+    // set up roi
+    int src_roicols;
+    int src_roirows;
+    int dst_roicols;
+    int dst_roirows;
+    int src1x;
+    int src1y;
+    int dstx;
+    int dsty;
+
+
+    //src mat with roi
+    cv::Mat mat1_roi;
+    cv::Mat dst_roi;
+    std::vector<cv::ocl::Info> oclinfo;
+    //ocl dst mat for testing
+    cv::ocl::oclMat gdst_whole;
+
+    //ocl mat with roi
+    cv::ocl::oclMat gmat1;
+    cv::ocl::oclMat gdst;
+
+    virtual void SetUp()
+    {
+        type = GET_PARAM(0);
+        //dsize = GET_PARAM(1);
+        interpolation = GET_PARAM(1);
+
+        cv::RNG &rng = TS::ptr()->get_rng();
+        size = cv::Size(MWIDTH, MHEIGHT);
+
+        mat1 = randomMat(rng, size, type, 5, 16, false);
+        dst  = randomMat(rng, size, type, 5, 16, false);
+
+        int devnums = getDevice(oclinfo, OPENCV_DEFAULT_OPENCL_DEVICE);
+        CV_Assert(devnums > 0);
+        //if you want to use undefault device, set it here
+        //setDevice(oclinfo[0]);
+    }
+
+    void random_roi()
+    {       
+#ifdef RANDOMROI
+        //randomize ROI
+               cv::RNG &rng = TS::ptr()->get_rng();
+        src_roicols = rng.uniform(1, mat1.cols);
+        src_roirows = rng.uniform(1, mat1.rows);
+        dst_roicols = rng.uniform(1, dst.cols);
+        dst_roirows = rng.uniform(1, dst.rows);
+        src1x   = rng.uniform(0, mat1.cols - src_roicols);
+        src1y   = rng.uniform(0, mat1.rows - src_roirows);
+        dstx    = rng.uniform(0, dst.cols  - dst_roicols);
+        dsty    = rng.uniform(0, dst.rows  - dst_roirows);
+#else
+        src_roicols = mat1.cols;
+        src_roirows = mat1.rows;
+        dst_roicols = dst.cols;
+        dst_roirows = dst.rows;
+        src1x   = 0;
+        src1y   = 0;
+        dstx    = 0;
+        dsty    = 0;
+#endif
+
+
+        mat1_roi = mat1(Rect(src1x, src1y, src_roicols, src_roirows));
+        dst_roi  = dst(Rect(dstx, dsty, dst_roicols, dst_roirows));
+
+        gdst_whole = dst;
+        gdst = gdst_whole(Rect(dstx, dsty, dst_roicols, dst_roirows));
+
+
+        gmat1 = mat1_roi;
+    }
+
+};
+
+/////warpAffine
+
+struct WarpAffine : WarpTestBase {};
+
+TEST_P(WarpAffine, Mat)
+{
+    static const double coeffs[2][3] =
+    {
+        {cos(3.14 / 6), -sin(3.14 / 6), 100.0},
+        {sin(3.14 / 6), cos(3.14 / 6), -100.0}
+    };
+    Mat M(2, 3, CV_64F, (void *)coeffs);
+
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::warpAffine(mat1_roi, dst_roi, M, size, interpolation);
+        cv::ocl::warpAffine(gmat1, gdst, M, size, interpolation);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "src_roicols=%d,src_roirows=%d,dst_roicols=%d,dst_roirows=%d,src1x =%d,src1y=%d,dstx=%d,dsty=%d", src_roicols, src_roirows, dst_roicols, dst_roirows, src1x, src1y, dstx, dsty);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1.0, sss);
+    }
+
+}
+
+
+// warpPerspective
+
+struct WarpPerspective : WarpTestBase {};
+
+TEST_P(WarpPerspective, Mat)
+{
+    static const double coeffs[3][3] =
+    {
+        {cos(3.14 / 6), -sin(3.14 / 6), 100.0},
+        {sin(3.14 / 6), cos(3.14 / 6), -100.0},
+        {0.0, 0.0, 1.0}
+    };
+    Mat M(3, 3, CV_64F, (void *)coeffs);
+
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::warpPerspective(mat1_roi, dst_roi, M, size, interpolation);
+        cv::ocl::warpPerspective(gmat1, gdst, M, size, interpolation);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "src_roicols=%d,src_roirows=%d,dst_roicols=%d,dst_roirows=%d,src1x =%d,src1y=%d,dstx=%d,dsty=%d", src_roicols, src_roirows, dst_roicols, dst_roirows, src1x, src1y, dstx, dsty);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1.0, sss);
+    }
+
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+// remap
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+PARAM_TEST_CASE(Remap, MatType, MatType, MatType, int, int)
+{
+    int srcType;
+    // int dstType;
+    int map1Type;
+    int map2Type;
+    cv::Scalar val;
+
+    int interpolation;
+    int bordertype;
+    //Scalar& borderValue;
+
+    cv::Mat src;
+    cv::Mat dst;
+    cv::Mat map1;
+    cv::Mat map2;
+
+    std::vector<cv::ocl::Info> oclinfo;
+    
+    int src_roicols;
+    int src_roirows;
+    int dst_roicols;
+    int dst_roirows;
+    int map1_roicols;
+    int map1_roirows;
+    int map2_roicols;
+    int map2_roirows;
+    int srcx;
+    int srcy;
+    int dstx;
+    int dsty;
+    int map1x;
+    int map1y;
+    int map2x;
+    int map2y;
+
+    cv::Mat src_roi;
+    cv::Mat dst_roi;
+    cv::Mat map1_roi;
+    cv::Mat map2_roi;
+
+    //ocl mat for testing
+    cv::ocl::oclMat gdst;
+    cv::ocl::oclMat gsrc;
+    cv::ocl::oclMat gmap1;
+    cv::ocl::oclMat gmap2;
+
+    //ocl mat with roi
+    cv::ocl::oclMat gsrc_roi;
+    cv::ocl::oclMat gdst_roi;
+    cv::ocl::oclMat gmap1_roi;
+    cv::ocl::oclMat gmap2_roi;
+
+    virtual void SetUp()
+    {
+        srcType = GET_PARAM(0);
+        //  dstType = GET_PARAM(1);
+        map1Type = GET_PARAM(1);
+        map2Type = GET_PARAM(2);
+        interpolation = GET_PARAM(3);
+        bordertype = GET_PARAM(4);
+        // borderValue = GET_PARAM(6);
+
+        int devnums = getDevice(oclinfo, OPENCV_DEFAULT_OPENCL_DEVICE);
+        CV_Assert(devnums > 0);
+
+        cv::RNG& rng = TS::ptr()->get_rng();
+        //cv::Size size = cv::Size(20, 20);
+        cv::Size srcSize = cv::Size(15, 20);
+        cv::Size dstSize = cv::Size(20, 20);
+        cv::Size map1Size = cv::Size(20, 20);
+        double min = 1, max = 20;
+
+        if(srcType != nulltype)
+        {
+            src = randomMat(rng, srcSize, srcType, min, max, false);
+            gsrc = src;
+        }
+        if((map1Type == CV_16SC2 && map2Type == nulltype) || (map1Type == CV_32FC2&& map2Type == nulltype))
+        {
+            map1 = randomMat(rng, map1Size, map1Type, min, max, false);
+            gmap1 = map1;
+
+        }
+        else if (map1Type == CV_32FC1 && map2Type == CV_32FC1)
+        {
+            map1 = randomMat(rng, map1Size, map1Type, min, max, false);
+            map2 = randomMat(rng, map1Size, map1Type, min, max, false);
+            gmap1 = map1;
+            gmap2 = map2;
+        }
+
+        else
+            cout<<"The wrong input type"<<endl;
+
+        dst = randomMat(rng, map1Size, srcType, min, max, false);
+        gdst = dst;
+    }
+    void random_roi()
+    {
+        cv::RNG& rng = TS::ptr()->get_rng();
+
+        dst_roicols = rng.uniform(1, dst.cols);
+        dst_roirows = rng.uniform(1, dst.rows);
+
+        src_roicols = rng.uniform(1, src.cols);
+        src_roirows = rng.uniform(1, src.rows);
+
+        cout << "dst_roicols: " << dst_roicols << "dst_roirows: "<< dst_roirows << endl;
+        cout << "src_roicols: " << src_roicols << "dst_roirows: "<< src_roirows << endl;
+        
+        srcx = rng.uniform(0, src.cols - src_roicols);
+        srcy = rng.uniform(0, src.rows - src_roirows);
+        dstx = rng.uniform(0, dst.cols - dst_roicols);
+        dsty = rng.uniform(0, dst.rows - dst_roirows);
+        cout << "srcx: " << srcx << "srcy: " << srcy << "dstx: " << dstx << "dsty: " << dsty << endl;
+        map1_roicols = dst_roicols;
+        map1_roirows = dst_roirows;
+        map2_roicols = dst_roicols;
+        map2_roirows = dst_roirows;
+        map1x = dstx;
+        map1y = dsty;
+        map2x = dstx;
+        map2y = dsty;
+
+        switch (src.channels())
+        {
+            case 1:
+                val = cv::Scalar(rng.uniform(0.0, 10.0), 0, 0, 0);
+                break;
+            case 2:
+                val = cv::Scalar(rng.uniform(0.0, 10.0), rng.uniform(0.0, 10.0), 0, 0);
+                break;
+            case 3:
+                val = cv::Scalar(rng.uniform(0.0, 10.0), rng.uniform(0.0, 10.0), rng.uniform(0.0, 10.0), 0);
+                break;
+            case 4:
+                val = cv::Scalar(rng.uniform(0.0, 10.0), rng.uniform(0.0, 10.0), rng.uniform(0.0, 10.0), rng.uniform(0.0, 10.0));
+                break;
+        }
+        if(srcType != nulltype)
+        {
+            src_roi = src(Rect(srcx,srcy,src_roicols,src_roirows));
+            gsrc_roi = gsrc(Rect(srcx,srcy,src_roicols,src_roirows));
+            gsrc_roi = src_roi;
+        }
+        if((map1Type == CV_16SC2 && map2Type == nulltype) || (map1Type == CV_32FC2&& map2Type == nulltype))
+        {
+            map1_roi = map1(Rect(map1x,map1y,map1_roicols,map1_roirows));
+            gmap1_roi = map1_roi;
+          //  cv::Mat maptest(gmap1_roi);
+           // cout << "maptest " << endl;
+            //cout << maptest << endl;
+            //gmap1_roi = gmap1(Rect(map1x,map1y,map1_roicols,map1_roirows));
+        }
+
+        else if (map1Type == CV_32FC1 && map2Type == CV_32FC1)
+        {
+            map1_roi = map1(Rect(map1x,map1y,map1_roicols,map1_roirows));
+            gmap1_roi = map1_roi;
+            map2_roi = map2(Rect(map2x,map2y,map2_roicols,map2_roirows));
+            gmap2_roi = map2_roi;
+        }
+        dst_roi = dst(Rect(dstx, dsty, dst_roicols, dst_roirows));
+        gdst_roi = gdst(Rect(dstx,dsty,dst_roicols,dst_roirows));
+
+   
+    }
+};
+
+TEST_P(Remap, Mat)
+{
+    int bordertype[] = {cv::BORDER_CONSTANT,cv::BORDER_REPLICATE/*,BORDER_REFLECT,BORDER_WRAP,BORDER_REFLECT_101*/};
+    const char* borderstr[]={"BORDER_CONSTANT", "BORDER_REPLICATE"/*, "BORDER_REFLECT","BORDER_WRAP","BORDER_REFLECT_101"*/};
+    // for(int i = 0; i < sizeof(bordertype)/sizeof(int); i++)
+    for(int j=0; j<1; j++)
+    {
+        random_roi();
+        cv::remap(src_roi, dst_roi, map1_roi, map2_roi, interpolation, bordertype[0], val);
+        cv::ocl::remap(gsrc_roi, gdst_roi, gmap1_roi, gmap2_roi, interpolation, bordertype[0], val);
+        cv::Mat cpu_dst;
+        gdst_roi.download(cpu_dst);
+
+        char sss[1024];
+        sprintf(sss, "src_roicols=%d,src_roirows=%d,dst_roicols=%d,dst_roirows=%d,src1x =%d,src1y=%d,dstx=%d,dsty=%d", src_roicols, src_roirows, dst_roicols, dst_roirows, srcx, srcy, dstx, dsty);
+
+   
+        EXPECT_MAT_NEAR(dst_roi, cpu_dst, 1.0, sss);
+    }
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+// resize
+
+PARAM_TEST_CASE(Resize, MatType, cv::Size, double, double, int)
+{
+    int type;
+    cv::Size dsize;
+    double fx, fy;
+    int interpolation;
+
+    //src mat
+    cv::Mat mat1;
+    cv::Mat dst;
+
+    // set up roi
+    int src_roicols;
+    int src_roirows;
+    int dst_roicols;
+    int dst_roirows;
+    int src1x;
+    int src1y;
+    int dstx;
+    int dsty;
+
+    std::vector<cv::ocl::Info> oclinfo;
+    //src mat with roi
+    cv::Mat mat1_roi;
+    cv::Mat dst_roi;
+
+    //ocl dst mat for testing
+    cv::ocl::oclMat gdst_whole;
+
+    //ocl mat with roi
+    cv::ocl::oclMat gmat1;
+    cv::ocl::oclMat gdst;
+
+    virtual void SetUp()
+    {
+        type = GET_PARAM(0);
+        dsize = GET_PARAM(1);
+        fx = GET_PARAM(2);
+        fy = GET_PARAM(3);
+        interpolation = GET_PARAM(4);
+
+        cv::RNG &rng = TS::ptr()->get_rng();
+
+        cv::Size size(MWIDTH, MHEIGHT);
+
+        if(dsize == cv::Size() && !(fx > 0 && fy > 0))
+        {
+            cout << "invalid dsize and fx fy" << endl;
+            return;
+        }
+
+        if(dsize == cv::Size())
+        {
+            dsize.width = (int)(size.width * fx);
+            dsize.height = (int)(size.height * fy);
+        }
+
+        mat1 = randomMat(rng, size, type, 5, 16, false);
+        dst  = randomMat(rng, dsize, type, 5, 16, false);
+
+        int devnums = getDevice(oclinfo, OPENCV_DEFAULT_OPENCL_DEVICE);
+        CV_Assert(devnums > 0);
+        //if you want to use undefault device, set it here
+        //setDevice(oclinfo[0]);
+    }
+
+    void random_roi()
+    {        
+#ifdef RANDOMROI
+        //randomize ROI
+               cv::RNG &rng = TS::ptr()->get_rng();
+        src_roicols = rng.uniform(1, mat1.cols);
+        src_roirows = rng.uniform(1, mat1.rows);
+        dst_roicols = rng.uniform(1, dst.cols);
+        dst_roirows = rng.uniform(1, dst.rows);
+        src1x   = rng.uniform(0, mat1.cols - src_roicols);
+        src1y   = rng.uniform(0, mat1.rows - src_roirows);
+        dstx    = rng.uniform(0, dst.cols  - dst_roicols);
+        dsty    = rng.uniform(0, dst.rows  - dst_roirows);
+#else
+        src_roicols = mat1.cols;
+        src_roirows = mat1.rows;
+        dst_roicols = dst.cols;
+        dst_roirows = dst.rows;
+        src1x   = 0;
+        src1y   = 0;
+        dstx    = 0;
+        dsty    = 0;
+#endif
+
+        mat1_roi = mat1(Rect(src1x, src1y, src_roicols, src_roirows));
+        dst_roi  = dst(Rect(dstx, dsty, dst_roicols, dst_roirows));
+
+        gdst_whole = dst;
+        gdst = gdst_whole(Rect(dstx, dsty, dst_roicols, dst_roirows));
+
+
+        gmat1 = mat1_roi;
+    }
+
+};
+
+TEST_P(Resize, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        // cv::resize(mat1_roi, dst_roi, dsize, fx, fy, interpolation);
+        // cv::ocl::resize(gmat1, gdst, dsize, fx, fy, interpolation);
+
+        cv::resize(mat1_roi, dst_roi, dsize, fx, fy, interpolation);
+        cv::ocl::resize(gmat1, gdst, dsize, fx, fy, interpolation);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "src_roicols=%d,src_roirows=%d,dst_roicols=%d,dst_roirows=%d,src1x =%d,src1y=%d,dstx=%d,dsty=%d", src_roicols, src_roirows, dst_roicols, dst_roirows, src1x, src1y, dstx, dsty);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1.0, sss);
+    }
+
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//threshold
+
+PARAM_TEST_CASE(Threshold, MatType, ThreshOp)
+{
+    int type;
+    int threshOp;
+
+    //src mat
+    cv::Mat mat1;
+    cv::Mat dst;
+
+    // set up roi
+    int roicols;
+    int roirows;
+    int src1x;
+    int src1y;
+    int dstx;
+    int dsty;
+
+    //src mat with roi
+    cv::Mat mat1_roi;
+    cv::Mat dst_roi;
+    std::vector<cv::ocl::Info> oclinfo;
+    //ocl dst mat for testing
+    cv::ocl::oclMat gdst_whole;
+
+    //ocl mat with roi
+    cv::ocl::oclMat gmat1;
+    cv::ocl::oclMat gdst;
+
+    virtual void SetUp()
+    {
+        type = GET_PARAM(0);
+        threshOp = GET_PARAM(1);
+
+        cv::RNG &rng = TS::ptr()->get_rng();
+        cv::Size size(MWIDTH, MHEIGHT);
+
+        mat1 = randomMat(rng, size, type, 5, 16, false);
+        dst  = randomMat(rng, size, type, 5, 16, false);
+
+        int devnums = getDevice(oclinfo, OPENCV_DEFAULT_OPENCL_DEVICE);
+        CV_Assert(devnums > 0);
+        //if you want to use undefault device, set it here
+        //setDevice(oclinfo[0]);
+    }
+
+    void random_roi()
+    {       
+#ifdef RANDOMROI
+        //randomize ROI
+               cv::RNG &rng = TS::ptr()->get_rng();
+        roicols = rng.uniform(1, mat1.cols);
+        roirows = rng.uniform(1, mat1.rows);
+        src1x   = rng.uniform(0, mat1.cols - roicols);
+        src1y   = rng.uniform(0, mat1.rows - roirows);
+        dstx    = rng.uniform(0, dst.cols  - roicols);
+        dsty    = rng.uniform(0, dst.rows  - roirows);
+#else
+        roicols = mat1.cols;
+        roirows = mat1.rows;
+        src1x   = 0;
+        src1y   = 0;
+        dstx    = 0;
+        dsty    = 0;
+#endif
+
+        mat1_roi = mat1(Rect(src1x, src1y, roicols, roirows));
+        dst_roi  = dst(Rect(dstx, dsty, roicols, roirows));
+
+        gdst_whole = dst;
+        gdst = gdst_whole(Rect(dstx, dsty, roicols, roirows));
+
+
+        gmat1 = mat1_roi;
+    }
+
+};
+
+TEST_P(Threshold, Mat)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+        double maxVal = randomDouble(20.0, 127.0);
+        double thresh = randomDouble(0.0, maxVal);
+
+        cv::threshold(mat1_roi, dst_roi, thresh, maxVal, threshOp);
+        cv::ocl::threshold(gmat1, gdst, thresh, maxVal, threshOp);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+
+        //EXPECT_MAT_NEAR(dst, cpu_dst, 1e-5)
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x =%d,src1y=%d,dstx=%d,dsty=%d", roicols, roirows, src1x , src1y, dstx, dsty);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 1, sss);
+    }
+
+}
+
+PARAM_TEST_CASE(meanShiftTestBase, MatType, MatType, int, int, cv::TermCriteria)
+{
+    int type, typeCoor;
+    int sp, sr;
+    cv::TermCriteria crit;
+    //src mat
+    cv::Mat src;
+    cv::Mat dst;
+    cv::Mat dstCoor;
+
+    //set up roi
+    int roicols;
+    int roirows;
+    int srcx;
+    int srcy;
+    int dstx;
+    int dsty;
+
+    //src mat with roi
+    cv::Mat src_roi;
+    cv::Mat dst_roi;
+    cv::Mat dstCoor_roi;
+
+    //ocl dst mat
+    cv::ocl::oclMat gdst;
+    cv::ocl::oclMat gdstCoor;
+
+    std::vector<cv::ocl::Info> oclinfo;
+    //ocl mat with roi
+    cv::ocl::oclMat gsrc_roi;
+    cv::ocl::oclMat gdst_roi;
+    cv::ocl::oclMat gdstCoor_roi;
+
+    virtual void SetUp()
+    {
+        type     = GET_PARAM(0);
+        typeCoor = GET_PARAM(1);
+        sp       = GET_PARAM(2);
+        sr       = GET_PARAM(3);
+        crit     = GET_PARAM(4);
+
+        cv::RNG &rng = TS::ptr()->get_rng();
+
+        // MWIDTH=256, MHEIGHT=256. defined in utility.hpp
+        cv::Size size = cv::Size(MWIDTH, MHEIGHT);
+
+        src = randomMat(rng, size, type, 5, 16, false);
+        dst = randomMat(rng, size, type, 5, 16, false);
+        dstCoor = randomMat(rng, size, typeCoor, 5, 16, false);
+
+        int devnums = getDevice(oclinfo, OPENCV_DEFAULT_OPENCL_DEVICE);
+        CV_Assert(devnums > 0);
+        //if you want to use undefault device, set it here
+        //setDevice(oclinfo[0]);
+    }
+
+    void random_roi()
+    {
+#ifdef RANDOMROI
+        cv::RNG &rng = TS::ptr()->get_rng();
+
+        //randomize ROI
+        roicols = rng.uniform(1, src.cols);
+        roirows = rng.uniform(1, src.rows);
+        srcx = rng.uniform(0, src.cols - roicols);
+        srcy = rng.uniform(0, src.rows - roirows);
+        dstx = rng.uniform(0, dst.cols - roicols);
+        dsty = rng.uniform(0, dst.rows - roirows);
+#else
+        roicols = src.cols;
+        roirows = src.rows;
+        srcx = 0;
+        srcy = 0;
+        dstx = 0;
+        dsty = 0;
+#endif
+        src_roi = src(Rect(srcx, srcy, roicols, roirows));
+        dst_roi = dst(Rect(dstx, dsty, roicols, roirows));
+        dstCoor_roi = dstCoor(Rect(dstx, dsty, roicols, roirows));
+
+        gdst = dst;
+        gdstCoor = dstCoor;
+
+        gsrc_roi = src_roi;
+        gdst_roi = gdst(Rect(dstx, dsty, roicols, roirows));  //gdst_roi
+        gdstCoor_roi = gdstCoor(Rect(dstx, dsty, roicols, roirows));
+    }
+};
+
+/////////////////////////meanShiftFiltering/////////////////////////////
+struct meanShiftFiltering : meanShiftTestBase {};
+
+TEST_P(meanShiftFiltering, Mat)
+{
+
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::Mat cpu_gdst;
+        gdst.download(cpu_gdst);
+
+        meanShiftFiltering_(src_roi, dst_roi, sp, sr, crit);
+        cv::ocl::meanShiftFiltering(gsrc_roi, gdst_roi, sp, sr, crit);
+
+        gdst.download(cpu_gdst);
+
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,srcx=%d,srcy=%d,dstx=%d,dsty=%d\n", roicols, roirows, srcx, srcy, dstx, dsty);
+        EXPECT_MAT_NEAR(dst, cpu_gdst, 0.0, sss);
+
+    }
+}
+
+///////////////////////////meanShiftProc//////////////////////////////////
+struct meanShiftProc : meanShiftTestBase {};
+
+TEST_P(meanShiftProc, Mat)
+{
+
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::Mat cpu_gdst;
+        cv::Mat cpu_gdstCoor;
+
+        meanShiftProc_(src_roi, dst_roi, dstCoor_roi, sp, sr, crit);
+        cv::ocl::meanShiftProc(gsrc_roi, gdst_roi, gdstCoor_roi, sp, sr, crit);
+
+        gdst.download(cpu_gdst);
+        gdstCoor.download(cpu_gdstCoor);
+
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,srcx=%d,srcy=%d,dstx=%d,dsty=%d\n", roicols, roirows, srcx, srcy, dstx, dsty);
+        EXPECT_MAT_NEAR(dst, cpu_gdst, 0.0, sss);
+        EXPECT_MAT_NEAR(dstCoor, cpu_gdstCoor, 0.0, sss);
+    }
+}
+
+INSTANTIATE_TEST_CASE_P(ImgprocTestBase, equalizeHist, Combine(
+                            ONE_TYPE(CV_8UC1),
+                            NULL_TYPE,
+                            ONE_TYPE(CV_8UC1),
+                            NULL_TYPE,
+                            NULL_TYPE,
+                            Values(false))); // Values(false) is the reserved parameter
+
+//INSTANTIATE_TEST_CASE_P(ImgprocTestBase, bilateralFilter, Combine(
+//     ONE_TYPE(CV_8UC1),
+//     NULL_TYPE,
+//     ONE_TYPE(CV_8UC1),
+//     NULL_TYPE,
+//     NULL_TYPE,
+//     Values(false))); // Values(false) is the reserved parameter
+//
+//
+//INSTANTIATE_TEST_CASE_P(ImgprocTestBase, CopyMakeBorder, Combine(
+//     Values(CV_8UC1, CV_8UC4, CV_32SC1),
+//     NULL_TYPE,
+//     Values(CV_8UC1,CV_8UC4,CV_32SC1),
+//     NULL_TYPE,
+//     NULL_TYPE,
+//     Values(false))); // Values(false) is the reserved parameter
+//
+//INSTANTIATE_TEST_CASE_P(ImgprocTestBase, cornerMinEigenVal, Combine(
+//     Values(CV_8UC1,CV_32FC1),
+//     NULL_TYPE,
+//     ONE_TYPE(CV_32FC1),
+//     NULL_TYPE,
+//     NULL_TYPE,
+//     Values(false))); // Values(false) is the reserved parameter
+//
+//INSTANTIATE_TEST_CASE_P(ImgprocTestBase, cornerHarris, Combine(
+//     Values(CV_8UC1,CV_32FC1),
+//     NULL_TYPE,
+//     ONE_TYPE(CV_32FC1),
+//     NULL_TYPE,
+//     NULL_TYPE,
+//     Values(false))); // Values(false) is the reserved parameter
+
+
+INSTANTIATE_TEST_CASE_P(ImgprocTestBase, integral, Combine(
+                            ONE_TYPE(CV_8UC1),
+                            NULL_TYPE,
+                            ONE_TYPE(CV_32SC1),
+                            ONE_TYPE(CV_32FC1),
+                            NULL_TYPE,
+                            Values(false))); // Values(false) is the reserved parameter
+
+INSTANTIATE_TEST_CASE_P(Imgproc, WarpAffine, Combine(
+                            Values(CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4),
+                            Values((MatType)cv::INTER_NEAREST, (MatType)cv::INTER_LINEAR,
+                                    (MatType)cv::INTER_CUBIC, (MatType)(cv::INTER_NEAREST | cv::WARP_INVERSE_MAP),
+                                    (MatType)(cv::INTER_LINEAR | cv::WARP_INVERSE_MAP), (MatType)(cv::INTER_CUBIC | cv::WARP_INVERSE_MAP))));
+
+
+INSTANTIATE_TEST_CASE_P(Imgproc, WarpPerspective, Combine
+                        (Values(CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4),
+                         Values((MatType)cv::INTER_NEAREST, (MatType)cv::INTER_LINEAR,
+                                (MatType)cv::INTER_CUBIC, (MatType)(cv::INTER_NEAREST | cv::WARP_INVERSE_MAP),
+                                (MatType)(cv::INTER_LINEAR | cv::WARP_INVERSE_MAP), (MatType)(cv::INTER_CUBIC | cv::WARP_INVERSE_MAP))));
+
+
+INSTANTIATE_TEST_CASE_P(Imgproc, Resize, Combine(
+                            Values(CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4),  Values(cv::Size()),
+                            Values(0.5, 1.5, 2), Values(0.5, 1.5, 2), Values((MatType)cv::INTER_NEAREST, (MatType)cv::INTER_LINEAR)));
+
+
+INSTANTIATE_TEST_CASE_P(Imgproc, Threshold, Combine(
+                            Values(CV_8UC1, CV_32FC1), Values(ThreshOp(cv::THRESH_BINARY),
+                                    ThreshOp(cv::THRESH_BINARY_INV), ThreshOp(cv::THRESH_TRUNC),
+                                    ThreshOp(cv::THRESH_TOZERO), ThreshOp(cv::THRESH_TOZERO_INV))));
+
+
+INSTANTIATE_TEST_CASE_P(Imgproc, meanShiftFiltering, Combine(
+                            ONE_TYPE(CV_8UC4),
+                            ONE_TYPE(CV_16SC2),
+                            Values(5),
+                            Values(6),
+                            Values(cv::TermCriteria(cv::TermCriteria::COUNT + cv::TermCriteria::EPS, 5, 1))
+                        ));
+                        
+
+INSTANTIATE_TEST_CASE_P(Imgproc, meanShiftProc, Combine(
+       ONE_TYPE(CV_8UC4),
+       ONE_TYPE(CV_16SC2),
+       Values(5),
+       Values(6),
+       Values(cv::TermCriteria(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, 5, 1))
+));
+
+INSTANTIATE_TEST_CASE_P(Imgproc, Remap, Combine(
+            Values(CV_8UC1, CV_8UC2, CV_8UC4),
+            Values(CV_16SC2, CV_32FC2), NULL_TYPE,
+            Values((int)cv::INTER_NEAREST, (int)cv::INTER_LINEAR), 
+            Values((int)cv::BORDER_CONSTANT)));
+#endif // HAVE_OPENCL
diff --git a/modules/ocl/test/test_matrix_operation.cpp b/modules/ocl/test/test_matrix_operation.cpp
new file mode 100644 (file)
index 0000000..997fbe7
--- /dev/null
@@ -0,0 +1,412 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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"
+
+#ifdef HAVE_OPENCL
+
+using namespace cvtest;
+using namespace testing;
+using namespace std;
+
+////////////////////////////////converto/////////////////////////////////////////////////
+PARAM_TEST_CASE(ConvertToTestBase, MatType, MatType)
+{
+    int type;
+    int dst_type;
+
+    //src mat
+    cv::Mat mat;
+    cv::Mat dst;
+
+    // set up roi
+    int roicols;
+    int roirows;
+    int srcx;
+    int srcy;
+    int dstx;
+    int dsty;
+
+    //src mat with roi
+    cv::Mat mat_roi;
+    cv::Mat dst_roi;
+    std::vector<cv::ocl::Info> oclinfo;
+    //ocl dst mat for testing
+    cv::ocl::oclMat gdst_whole;
+
+    //ocl mat with roi
+    cv::ocl::oclMat gmat;
+    cv::ocl::oclMat gdst;
+
+    virtual void SetUp()
+    {
+        type     = GET_PARAM(0);
+        dst_type = GET_PARAM(1);
+
+        cv::RNG &rng = TS::ptr()->get_rng();
+        cv::Size size(MWIDTH, MHEIGHT);
+
+        mat = randomMat(rng, size, type, 5, 16, false);
+        dst  = randomMat(rng, size, type, 5, 16, false);
+        //std::vector<cv::ocl::Info> oclinfo;
+        int devnums = getDevice(oclinfo, OPENCV_DEFAULT_OPENCL_DEVICE);
+        CV_Assert(devnums > 0);
+        //if you want to use undefault device, set it here
+        //setDevice(oclinfo[0]);
+    }
+
+    void random_roi()
+    {        
+#ifdef RANDOMROI
+        //randomize ROI
+               cv::RNG &rng = TS::ptr()->get_rng();
+        roicols = rng.uniform(1, mat.cols);
+        roirows = rng.uniform(1, mat.rows);
+        srcx   = rng.uniform(0, mat.cols - roicols);
+        srcy   = rng.uniform(0, mat.rows - roirows);
+        dstx    = rng.uniform(0, dst.cols  - roicols);
+        dsty    = rng.uniform(0, dst.rows  - roirows);
+#else
+        roicols = mat.cols;
+        roirows = mat.rows;
+        srcx = 0;
+        srcy = 0;
+        dstx = 0;
+        dsty = 0;
+#endif
+
+        mat_roi = mat(Rect(srcx, srcy, roicols, roirows));
+        dst_roi  = dst(Rect(dstx, dsty, roicols, roirows));
+
+        gdst_whole = dst;
+        gdst = gdst_whole(Rect(dstx, dsty, roicols, roirows));
+
+        gmat = mat_roi;
+    }
+};
+
+
+struct ConvertTo : ConvertToTestBase {};
+
+TEST_P(ConvertTo, Accuracy)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        mat_roi.convertTo(dst_roi, dst_type);
+        gmat.convertTo(gdst, dst_type);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,srcx =%d,srcy=%d,dstx=%d,dsty=%d", roicols, roirows, srcx , srcy, dstx, dsty);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.0, sss);
+    }
+}
+
+
+
+
+///////////////////////////////////////////copyto/////////////////////////////////////////////////////////////
+
+PARAM_TEST_CASE(CopyToTestBase, MatType, bool)
+{
+    int type;
+
+    cv::Mat mat;
+    cv::Mat mask;
+    cv::Mat dst;
+
+    // set up roi
+    int roicols;
+    int roirows;
+    int srcx;
+    int srcy;
+    int dstx;
+    int dsty;
+    int maskx;
+    int masky;
+
+    //src mat with roi
+    cv::Mat mat_roi;
+    cv::Mat mask_roi;
+    cv::Mat dst_roi;
+    std::vector<cv::ocl::Info> oclinfo;
+    //ocl dst mat for testing
+    cv::ocl::oclMat gdst_whole;
+
+    //ocl mat with roi
+    cv::ocl::oclMat gmat;
+    cv::ocl::oclMat gdst;
+    cv::ocl::oclMat gmask;
+
+    virtual void SetUp()
+    {
+        type = GET_PARAM(0);
+
+        cv::RNG &rng = TS::ptr()->get_rng();
+        cv::Size size(MWIDTH, MHEIGHT);
+
+        mat = randomMat(rng, size, type, 5, 16, false);
+        dst  = randomMat(rng, size, type, 5, 16, false);
+        mask = randomMat(rng, size, CV_8UC1, 0, 2,  false);
+
+        cv::threshold(mask, mask, 0.5, 255., CV_8UC1);
+
+        int devnums = getDevice(oclinfo, OPENCV_DEFAULT_OPENCL_DEVICE);
+        CV_Assert(devnums > 0);
+        //if you want to use undefault device, set it here
+        //setDevice(oclinfo[0]);
+    }
+
+    void random_roi()
+    {       
+#ifdef RANDOMROI
+        //randomize ROI
+               cv::RNG &rng = TS::ptr()->get_rng();
+        roicols = rng.uniform(1, mat.cols);
+        roirows = rng.uniform(1, mat.rows);
+        srcx   = rng.uniform(0, mat.cols - roicols);
+        srcy   = rng.uniform(0, mat.rows - roirows);
+        dstx    = rng.uniform(0, dst.cols  - roicols);
+        dsty    = rng.uniform(0, dst.rows  - roirows);
+        maskx   = rng.uniform(0, mask.cols - roicols);
+        masky   = rng.uniform(0, mask.rows - roirows);
+#else
+        roicols = mat.cols;
+        roirows = mat.rows;
+        srcx = 0;
+        srcy = 0;
+        dstx = 0;
+        dsty = 0;
+        maskx = 0;
+        masky = 0;
+#endif
+
+        mat_roi = mat(Rect(srcx, srcy, roicols, roirows));
+        mask_roi = mask(Rect(maskx, masky, roicols, roirows));
+        dst_roi  = dst(Rect(dstx, dsty, roicols, roirows));
+
+        gdst_whole = dst;
+        gdst = gdst_whole(Rect(dstx, dsty, roicols, roirows));
+
+        gmat = mat_roi;
+        gmask = mask_roi;
+    }
+};
+
+struct CopyTo : CopyToTestBase {};
+
+TEST_P(CopyTo, Without_mask)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        mat_roi.copyTo(dst_roi);
+        gmat.copyTo(gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,srcx =%d,srcy=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d", roicols, roirows, srcx , srcy, dstx, dsty, maskx, masky);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.0, sss);
+    }
+}
+
+TEST_P(CopyTo, With_mask)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        mat_roi.copyTo(dst_roi, mask_roi);
+        gmat.copyTo(gdst, gmask);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,srcx =%d,srcy=%d,dstx=%d,dsty=%d,maskx=%d,masky=%d", roicols, roirows, srcx , srcy, dstx, dsty, maskx, masky);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.0, sss);
+    }
+}
+
+
+
+
+///////////////////////////////////////////copyto/////////////////////////////////////////////////////////////
+
+PARAM_TEST_CASE(SetToTestBase, MatType, bool)
+{
+    int type;
+    cv::Scalar val;
+
+    cv::Mat mat;
+    cv::Mat mask;
+
+    // set up roi
+    int roicols;
+    int roirows;
+    int srcx;
+    int srcy;
+    int maskx;
+    int masky;
+
+    //src mat with roi
+    cv::Mat mat_roi;
+    cv::Mat mask_roi;
+    std::vector<cv::ocl::Info> oclinfo;
+    //ocl dst mat for testing
+    cv::ocl::oclMat gmat_whole;
+
+    //ocl mat with roi
+    cv::ocl::oclMat gmat;
+    cv::ocl::oclMat gmask;
+
+    virtual void SetUp()
+    {
+        type = GET_PARAM(0);
+
+        cv::RNG &rng = TS::ptr()->get_rng();
+        cv::Size size(MWIDTH, MHEIGHT);
+
+        mat = randomMat(rng, size, type, 5, 16, false);
+        mask = randomMat(rng, size, CV_8UC1, 0, 2,  false);
+
+        cv::threshold(mask, mask, 0.5, 255., CV_8UC1);
+        val = cv::Scalar(rng.uniform(-10.0, 10.0), rng.uniform(-10.0, 10.0), rng.uniform(-10.0, 10.0), rng.uniform(-10.0, 10.0));
+
+        int devnums = getDevice(oclinfo, OPENCV_DEFAULT_OPENCL_DEVICE);
+        CV_Assert(devnums > 0);
+        //if you want to use undefault device, set it here
+        //setDevice(oclinfo[0]);
+    }
+
+    void random_roi()
+    {        
+#ifdef RANDOMROI
+        //randomize ROI
+               cv::RNG &rng = TS::ptr()->get_rng();
+        roicols = rng.uniform(1, mat.cols);
+        roirows = rng.uniform(1, mat.rows);
+        srcx   = rng.uniform(0, mat.cols - roicols);
+        srcy   = rng.uniform(0, mat.rows - roirows);
+        maskx   = rng.uniform(0, mask.cols - roicols);
+        masky   = rng.uniform(0, mask.rows - roirows);
+#else
+        roicols = mat.cols;
+        roirows = mat.rows;
+        srcx = 0;
+        srcy = 0;
+        maskx = 0;
+        masky = 0;
+#endif
+
+        mat_roi = mat(Rect(srcx, srcy, roicols, roirows));
+        mask_roi = mask(Rect(maskx, masky, roicols, roirows));
+
+        gmat_whole = mat;
+        gmat = gmat_whole(Rect(srcx, srcy, roicols, roirows));
+
+        gmask = mask_roi;
+    }
+};
+
+struct SetTo : SetToTestBase {};
+
+TEST_P(SetTo, Without_mask)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        mat_roi.setTo(val);
+        gmat.setTo(val);
+
+        cv::Mat cpu_dst;
+        gmat_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,srcx =%d,srcy=%d,maskx=%d,masky=%d", roicols, roirows, srcx , srcy, maskx, masky);
+
+        EXPECT_MAT_NEAR(mat, cpu_dst, 1., sss);
+    }
+}
+
+TEST_P(SetTo, With_mask)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        mat_roi.setTo(val, mask_roi);
+        gmat.setTo(val, gmask);
+
+        cv::Mat cpu_dst;
+        gmat_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,srcx =%d,srcy=%d,maskx=%d,masky=%d", roicols, roirows, srcx , srcy, maskx, masky);
+
+        EXPECT_MAT_NEAR(mat, cpu_dst, 1., sss);
+    }
+}
+
+
+INSTANTIATE_TEST_CASE_P(MatrixOperation, ConvertTo, Combine(
+                            Values(CV_8UC1, CV_8UC4, CV_32SC1, CV_32SC4, CV_32FC1, CV_32FC4),
+                            Values(CV_8UC1, CV_8UC4, CV_32SC1, CV_32SC4, CV_32FC1, CV_32FC4)));
+
+INSTANTIATE_TEST_CASE_P(MatrixOperation, CopyTo, Combine(
+                            Values(CV_8UC1, CV_8UC4, CV_32SC1, CV_32SC4, CV_32FC1, CV_32FC4),
+                            Values(false))); // Values(false) is the reserved parameter
+
+INSTANTIATE_TEST_CASE_P(MatrixOperation, SetTo, Combine(
+                            Values(CV_8UC1, CV_8UC4, CV_32SC1, CV_32SC4, CV_32FC1, CV_32FC4),
+                            Values(false))); // Values(false) is the reserved parameter
+                            
+#endif
diff --git a/modules/ocl/test/test_split_merge.cpp b/modules/ocl/test/test_split_merge.cpp
new file mode 100644 (file)
index 0000000..e13d524
--- /dev/null
@@ -0,0 +1,374 @@
+/*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.
+// Third party copyrights are property of their respective owners.
+//
+// @Authors
+//    Jia Haipeng, jiahaipeng95@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 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"
+
+#ifdef HAVE_OPENCL
+
+using namespace cvtest;
+using namespace testing;
+using namespace std;
+
+PARAM_TEST_CASE(MergeTestBase, MatType, int)
+{
+    int type;
+    int channels;
+
+    //src mat
+    cv::Mat mat1;
+    cv::Mat mat2;
+    cv::Mat mat3;
+    cv::Mat mat4;
+
+    //dst mat
+    cv::Mat dst;
+
+    // set up roi
+    int roicols;
+    int roirows;
+    int src1x;
+    int src1y;
+    int src2x;
+    int src2y;
+    int src3x;
+    int src3y;
+    int src4x;
+    int src4y;
+    int dstx;
+    int dsty;
+
+    //src mat with roi
+    cv::Mat mat1_roi;
+    cv::Mat mat2_roi;
+    cv::Mat mat3_roi;
+    cv::Mat mat4_roi;
+
+    //dst mat with roi
+    cv::Mat dst_roi;
+    std::vector<cv::ocl::Info> oclinfo;
+    //ocl dst mat for testing
+    cv::ocl::oclMat gdst_whole;
+
+    //ocl mat with roi
+    cv::ocl::oclMat gmat1;
+    cv::ocl::oclMat gmat2;
+    cv::ocl::oclMat gmat3;
+    cv::ocl::oclMat gmat4;
+    cv::ocl::oclMat gdst;
+
+    virtual void SetUp()
+    {
+        type = GET_PARAM(0);
+        channels = GET_PARAM(1);
+
+        cv::RNG &rng = TS::ptr()->get_rng();
+        cv::Size size(MWIDTH, MHEIGHT);
+
+        mat1 = randomMat(rng, size, CV_MAKETYPE(type, 1), 5, 16, false);
+        mat2 = randomMat(rng, size, CV_MAKETYPE(type, 1), 5, 16, false);
+        mat3 = randomMat(rng, size, CV_MAKETYPE(type, 1), 5, 16, false);
+        mat4 = randomMat(rng, size, CV_MAKETYPE(type, 1), 5, 16, false);
+        dst  = randomMat(rng, size, CV_MAKETYPE(type, channels), 5, 16, false);
+
+        int devnums = getDevice(oclinfo, OPENCV_DEFAULT_OPENCL_DEVICE);
+        CV_Assert(devnums > 0);
+        //if you want to use undefault device, set it here
+        //setDevice(oclinfo[0]);
+    }
+
+    void random_roi()
+    {        
+#ifdef RANDOMROI
+        //randomize ROI
+               cv::RNG &rng = TS::ptr()->get_rng();
+        roicols = rng.uniform(1, mat1.cols);
+        roirows = rng.uniform(1, mat1.rows);
+        src1x   = rng.uniform(0, mat1.cols - roicols);
+        src1y   = rng.uniform(0, mat1.rows - roirows);
+        src2x   = rng.uniform(0, mat2.cols - roicols);
+        src2y   = rng.uniform(0, mat2.rows - roirows);
+        src3x   = rng.uniform(0, mat3.cols - roicols);
+        src3y   = rng.uniform(0, mat3.cols - roirows);
+        src4x   = rng.uniform(0, mat4.rows - roicols);
+        src4y   = rng.uniform(0, mat4.rows - roirows);
+        dstx    = rng.uniform(0, dst.cols  - roicols);
+        dsty    = rng.uniform(0, dst.rows  - roirows);
+#else
+        roicols = mat1.cols;
+        roirows = mat1.rows;
+        src1x   = 0;
+        src1y   = 0;
+        src2x   = 0;
+        src2y   = 0;
+        src3x   = 0;
+        src3y   = 0;
+        src4x   = 0;
+        src4y   = 0;
+        dstx    = 0;
+        dsty    = 0;
+#endif
+
+
+        mat1_roi = mat1(Rect(src1x, src1y, roicols, roirows));
+        mat2_roi = mat2(Rect(src2x, src2y, roicols, roirows));
+        mat3_roi = mat3(Rect(src3x, src3y, roicols, roirows));
+        mat4_roi = mat4(Rect(src4x, src4y, roicols, roirows));
+
+
+        dst_roi = dst(Rect(dstx, dsty, roicols, roirows));
+
+        gdst_whole = dst;
+        gdst = gdst_whole(Rect(dstx, dsty, roicols, roirows));
+
+        gmat1 = mat1_roi;
+        gmat2 = mat2_roi;
+        gmat3 = mat3_roi;
+        gmat4 = mat4_roi;
+    }
+
+};
+
+struct Merge : MergeTestBase {};
+
+TEST_P(Merge, Accuracy)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        std::vector<cv::Mat> dev_src;
+        dev_src.push_back(mat1_roi);
+        dev_src.push_back(mat2_roi);
+        dev_src.push_back(mat3_roi);
+        dev_src.push_back(mat4_roi);
+
+        std::vector<cv::ocl::oclMat> dev_gsrc;
+        dev_gsrc.push_back(gmat1);
+        dev_gsrc.push_back(gmat2);
+        dev_gsrc.push_back(gmat3);
+        dev_gsrc.push_back(gmat4);
+
+        cv::merge(dev_src, dst_roi);
+        cv::ocl::merge(dev_gsrc, gdst);
+
+        cv::Mat cpu_dst;
+        gdst_whole.download(cpu_dst);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,src1x =%d,src1y=%d,src2x =%d,src2y=%d,src3x =%d,src3y=%d,src4x =%d,src4y=%d,dstx=%d,dsty=%d", roicols, roirows, src1x, src1y, src2x , src2y, src3x , src3y, src4x , src4y, dstx, dsty);
+
+        EXPECT_MAT_NEAR(dst, cpu_dst, 0.0, sss);
+    }
+}
+
+
+
+PARAM_TEST_CASE(SplitTestBase, MatType, int)
+{
+    int type;
+    int channels;
+
+    //src mat
+    cv::Mat mat;
+
+    //dstmat
+    cv::Mat dst1;
+    cv::Mat dst2;
+    cv::Mat dst3;
+    cv::Mat dst4;
+
+    // set up roi
+    int roicols;
+    int roirows;
+    int srcx;
+    int srcy;
+    int dst1x;
+    int dst1y;
+    int dst2x;
+    int dst2y;
+    int dst3x;
+    int dst3y;
+    int dst4x;
+    int dst4y;
+
+    //src mat with roi
+    cv::Mat mat_roi;
+
+    //dst mat with roi
+    cv::Mat dst1_roi;
+    cv::Mat dst2_roi;
+    cv::Mat dst3_roi;
+    cv::Mat dst4_roi;
+    std::vector<cv::ocl::Info> oclinfo;
+    //ocl dst mat for testing
+    cv::ocl::oclMat gdst1_whole;
+    cv::ocl::oclMat gdst2_whole;
+    cv::ocl::oclMat gdst3_whole;
+    cv::ocl::oclMat gdst4_whole;
+
+    //ocl mat with roi
+    cv::ocl::oclMat gmat;
+    cv::ocl::oclMat gdst1;
+    cv::ocl::oclMat gdst2;
+    cv::ocl::oclMat gdst3;
+    cv::ocl::oclMat gdst4;
+
+    virtual void SetUp()
+    {
+        type = GET_PARAM(0);
+        channels = GET_PARAM(1);
+
+        cv::RNG &rng = TS::ptr()->get_rng();
+        cv::Size size(MWIDTH, MHEIGHT);
+
+        mat  = randomMat(rng, size, CV_MAKETYPE(type, channels), 5, 16, false);
+        dst1 = randomMat(rng, size, CV_MAKETYPE(type, 1), 5, 16, false);
+        dst2 = randomMat(rng, size, CV_MAKETYPE(type, 1), 5, 16, false);
+        dst3 = randomMat(rng, size, CV_MAKETYPE(type, 1), 5, 16, false);
+        dst4 = randomMat(rng, size, CV_MAKETYPE(type, 1), 5, 16, false);
+
+        int devnums = getDevice(oclinfo, OPENCV_DEFAULT_OPENCL_DEVICE);
+        CV_Assert(devnums > 0);
+        //if you want to use undefault device, set it here
+        //setDevice(oclinfo[0]);
+    }
+
+    void random_roi()
+    {        
+#ifdef RANDOMROI
+        //randomize ROI
+               cv::RNG &rng = TS::ptr()->get_rng();
+        roicols = rng.uniform(1, mat.cols);
+        roirows = rng.uniform(1, mat.rows);
+        srcx    = rng.uniform(0, mat.cols - roicols);
+        srcy    = rng.uniform(0, mat.rows - roirows);
+        dst1x   = rng.uniform(0, dst1.cols  - roicols);
+        dst1y   = rng.uniform(0, dst1.rows  - roirows);
+        dst2x   = rng.uniform(0, dst2.cols  - roicols);
+        dst2y   = rng.uniform(0, dst2.rows  - roirows);
+        dst3x   = rng.uniform(0, dst3.cols  - roicols);
+        dst3y   = rng.uniform(0, dst3.rows  - roirows);
+        dst4x   = rng.uniform(0, dst4.cols  - roicols);
+        dst4y   = rng.uniform(0, dst4.rows  - roirows);
+#else
+        roicols = mat.cols;
+        roirows = mat.rows;
+        srcx    = 0;
+        srcy    = 0;
+        dst1x   = 0;
+        dst1y   = 0;
+        dst2x   = 0;
+        dst2y   = 0;
+        dst3x   = 0;
+        dst3y   = 0;
+        dst4x   = 0;
+        dst4y   = 0;
+#endif
+
+        mat_roi = mat(Rect(srcx, srcy, roicols, roirows));
+
+        dst1_roi = dst1(Rect(dst1x, dst1y, roicols, roirows));
+        dst2_roi = dst2(Rect(dst2x, dst2y, roicols, roirows));
+        dst3_roi = dst3(Rect(dst3x, dst3y, roicols, roirows));
+        dst4_roi = dst4(Rect(dst4x, dst4y, roicols, roirows));
+
+        gdst1_whole = dst1;
+        gdst1 = gdst1_whole(Rect(dst1x, dst1y, roicols, roirows));
+
+        gdst2_whole = dst2;
+        gdst2 = gdst2_whole(Rect(dst2x, dst2y, roicols, roirows));
+
+        gdst3_whole = dst3;
+        gdst3 = gdst3_whole(Rect(dst3x, dst3y, roicols, roirows));
+
+        gdst4_whole = dst4;
+        gdst4 = gdst4_whole(Rect(dst4x, dst4y, roicols, roirows));
+
+        gmat = mat_roi;
+    }
+
+};
+
+struct Split : SplitTestBase {};
+
+TEST_P(Split, Accuracy)
+{
+    for(int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        cv::Mat         dev_dst[4]  = {dst1_roi, dst2_roi, dst3_roi, dst4_roi};
+        cv::ocl::oclMat dev_gdst[4] = {gdst1, gdst2, gdst3, gdst4};
+
+        cv::split(mat_roi, dev_dst);
+        cv::ocl::split(gmat, dev_gdst);
+
+        cv::Mat cpu_dst1;
+        cv::Mat cpu_dst2;
+        cv::Mat cpu_dst3;
+        cv::Mat cpu_dst4;
+        gdst1_whole.download(cpu_dst1);
+        gdst2_whole.download(cpu_dst2);
+        gdst3_whole.download(cpu_dst3);
+        gdst4_whole.download(cpu_dst4);
+        char sss[1024];
+        sprintf(sss, "roicols=%d,roirows=%d,dst1x =%d,dsty=%d,dst2x =%d,dst2y=%d,dst3x =%d,dst3y=%d,dst4x =%d,dst4y=%d,srcx=%d,srcy=%d", roicols, roirows, dst1x , dst1y, dst2x , dst2y, dst3x , dst3y, dst4x , dst4y, srcx, srcy);
+
+        EXPECT_MAT_NEAR(dst1, cpu_dst1, 0.0, sss);
+        EXPECT_MAT_NEAR(dst2, cpu_dst2, 0.0, sss);
+        EXPECT_MAT_NEAR(dst3, cpu_dst3, 0.0, sss);
+        EXPECT_MAT_NEAR(dst4, cpu_dst4, 0.0, sss);
+    }
+}
+
+
+INSTANTIATE_TEST_CASE_P(SplitMerge, Merge, Combine(
+                            Values(CV_8U, CV_32S, CV_32F), Values(1, 4)));
+
+
+INSTANTIATE_TEST_CASE_P(SplitMerge, Split , Combine(
+                            Values(CV_8U, CV_32S, CV_32F), Values(1, 4)));
+                           
+
+#endif // HAVE_OPENCL
diff --git a/modules/ocl/test/utility.cpp b/modules/ocl/test/utility.cpp
new file mode 100644 (file)
index 0000000..e961347
--- /dev/null
@@ -0,0 +1,284 @@
+/*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"
+#define VARNAME(A) #A
+using namespace std;
+using namespace cv;
+using namespace cv::gpu;
+using namespace cvtest;
+
+
+//std::string generateVarList(int first,...)
+//{
+//     vector<std::string> varname;
+//
+//     va_list argp;
+//     string s;
+//     stringstream ss;
+//     va_start(argp,first);
+//     int i=first;
+//     while(i!=-1)
+//     {
+//             ss<<i<<",";
+//             i=va_arg(argp,int);
+//     };
+//     s=ss.str();
+//     va_end(argp);
+//     return s;
+//};
+
+//std::string generateVarList(int& p1,int& p2)
+//{
+//     stringstream ss;
+//     ss<<VARNAME(p1)<<":"<<src1x<<","<<VARNAME(p2)<<":"<<src1y;
+//     return ss.str();
+//};
+
+int randomInt(int minVal, int maxVal)
+{
+    RNG &rng = TS::ptr()->get_rng();
+    return rng.uniform(minVal, maxVal);
+}
+
+double randomDouble(double minVal, double maxVal)
+{
+    RNG &rng = TS::ptr()->get_rng();
+    return rng.uniform(minVal, maxVal);
+}
+
+Size randomSize(int minVal, int maxVal)
+{
+    return cv::Size(randomInt(minVal, maxVal), randomInt(minVal, maxVal));
+}
+
+Scalar randomScalar(double minVal, double maxVal)
+{
+    return Scalar(randomDouble(minVal, maxVal), randomDouble(minVal, maxVal), randomDouble(minVal, maxVal), randomDouble(minVal, maxVal));
+}
+
+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)
+{
+    Mat gold;
+    if (gold_.kind() == _InputArray::MAT)
+        gold = gold_.getMat();
+    else
+        gold_.getGpuMat().download(gold);
+
+    Mat actual;
+    if (actual_.kind() == _InputArray::MAT)
+        actual = actual_.getMat();
+    else
+        actual_.getGpuMat().download(actual);
+
+    Mat diff;
+    absdiff(gold, actual, diff);
+    threshold(diff, diff, eps, 255.0, cv::THRESH_BINARY);
+
+    namedWindow("gold", WINDOW_NORMAL);
+    namedWindow("actual", WINDOW_NORMAL);
+    namedWindow("diff", WINDOW_NORMAL);
+
+    imshow("gold", gold);
+    imshow("actual", actual);
+    imshow("diff", diff);
+
+    waitKey();
+}
+*/
+
+/*
+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)
+{
+    vector<MatType> v;
+
+    v.reserve((depth_end - depth_start + 1) * (cn_end - cn_start + 1));
+
+    for (int depth = depth_start; depth <= depth_end; ++depth)
+    {
+        for (int cn = cn_start; cn <= cn_end; ++cn)
+        {
+            v.push_back(CV_MAKETYPE(depth, cn));
+        }
+    }
+
+    return v;
+}
+
+const vector<MatType>& all_types()
+{
+    static vector<MatType> v = types(CV_8U, CV_64F, 1, 4);
+
+    return v;
+}
+
+Mat readImage(const string &fileName, int flags)
+{
+    return imread(string(cvtest::TS::ptr()->get_data_path()) + fileName, flags);
+}
+
+Mat readImageType(const string &fname, int type)
+{
+    Mat src = readImage(fname, CV_MAT_CN(type) == 1 ? IMREAD_GRAYSCALE : IMREAD_COLOR);
+    if (CV_MAT_CN(type) == 4)
+    {
+        Mat temp;
+        cvtColor(src, temp, cv::COLOR_BGR2BGRA);
+        swap(src, temp);
+    }
+    src.convertTo(src, CV_MAT_DEPTH(type));
+    return src;
+}
+
+double checkNorm(const Mat &m)
+{
+    return norm(m, NORM_INF);
+}
+
+double checkNorm(const Mat &m1, const Mat &m2)
+{
+    return norm(m1, m2, NORM_INF);
+}
+
+double checkSimilarity(const Mat &m1, const Mat &m2)
+{
+    Mat diff;
+    matchTemplate(m1, m2, diff, CV_TM_CCORR_NORMED);
+    return std::abs(diff.at<float>(0, 0) - 1.f);
+}
+
+/*
+void cv::ocl::PrintTo(const DeviceInfo& info, ostream* os)
+{
+    (*os) << info.name();
+}
+*/
+
+void PrintTo(const Inverse &inverse, std::ostream *os)
+{
+    if (inverse)
+        (*os) << "inverse";
+    else
+        (*os) << "direct";
+}
+       cv::ocl::oclMat createMat(cv::Size size,int type,bool useRoi)
+       {
+               cv::Size size0 = size;
+               if (useRoi)
+               {
+                       size0.width += randomInt(5, 15);
+                       size0.height += randomInt(5, 15);
+               }
+               cv::ocl::oclMat d_m(size0, type);
+               if (size0 != size)
+                       d_m = cv::ocl::oclMat(size.width,size.height,type); // suspicious point
+               return d_m;
+       }
+       cv::ocl::oclMat loadMat(const cv::Mat& m, bool useRoi)
+       {
+               cv::ocl::oclMat d_m = ::createMat(m.size(), m.type(), useRoi);
+               d_m.upload(m);
+               return d_m;
+       }
diff --git a/modules/ocl/test/utility.hpp b/modules/ocl/test/utility.hpp
new file mode 100644 (file)
index 0000000..db873fe
--- /dev/null
@@ -0,0 +1,242 @@
+/*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*/
+
+#ifndef __OPENCV_TEST_UTILITY_HPP__
+#define __OPENCV_TEST_UTILITY_HPP__
+#define LOOP_TIMES 1
+#define MWIDTH 256
+#define MHEIGHT 256
+//#define RANDOMROI
+int randomInt(int minVal, int maxVal);
+double randomDouble(double minVal, double maxVal);
+//std::string generateVarList(int first,...);
+std::string generateVarList(int &p1, int &p2);
+cv::Size randomSize(int minVal, int maxVal);
+cv::Scalar randomScalar(double minVal, double maxVal);
+cv::Mat randomMat(cv::Size size, int type, double minVal = 0.0, double maxVal = 255.0);
+
+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);
+
+//! 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);
+cv::Mat readImageType(const std::string &fname, int type);
+
+double checkNorm(const cv::Mat &m);
+double checkNorm(const cv::Mat &m1, const cv::Mat &m2);
+double checkSimilarity(const cv::Mat &m1, const cv::Mat &m2);
+
+#define EXPECT_MAT_NORM(mat, eps) \
+{ \
+    EXPECT_LE(checkNorm(cv::Mat(mat)), eps) \
+}
+
+//#define EXPECT_MAT_NEAR(mat1, mat2, eps) \
+//{ \
+//    ASSERT_EQ(mat1.type(), mat2.type()); \
+//    ASSERT_EQ(mat1.size(), mat2.size()); \
+//    EXPECT_LE(checkNorm(cv::Mat(mat1), cv::Mat(mat2)), eps); \
+//}
+
+#define EXPECT_MAT_NEAR(mat1, mat2, eps,s) \
+{ \
+    ASSERT_EQ(mat1.type(), mat2.type()); \
+    ASSERT_EQ(mat1.size(), mat2.size()); \
+    EXPECT_LE(checkNorm(cv::Mat(mat1), cv::Mat(mat2)), eps)<<s; \
+}
+
+#define EXPECT_MAT_SIMILAR(mat1, mat2, eps) \
+{ \
+    ASSERT_EQ(mat1.type(), mat2.type()); \
+    ASSERT_EQ(mat1.size(), mat2.size()); \
+    EXPECT_LE(checkSimilarity(cv::Mat(mat1), cv::Mat(mat2)), eps); \
+}
+
+namespace cv
+{
+    namespace ocl
+    {
+        // void PrintTo(const DeviceInfo& info, std::ostream* os);
+    }
+}
+
+using perf::MatDepth;
+using perf::MatType;
+
+//! return vector with types from specified range.
+std::vector<MatType> types(int depth_start, int depth_end, int cn_start, int cn_end);
+
+//! return vector with all types (depth: CV_8U-CV_64F, channels: 1-4).
+const std::vector<MatType>& all_types();
+
+class Inverse
+{
+public:
+    inline Inverse(bool val = false) : val_(val) {}
+
+    inline operator bool() const
+    {
+        return val_;
+    }
+
+private:
+    bool val_;
+};
+
+void PrintTo(const Inverse &useRoi, std::ostream *os);
+
+CV_ENUM(CmpCode, cv::CMP_EQ, cv::CMP_GT, cv::CMP_GE, cv::CMP_LT, cv::CMP_LE, cv::CMP_NE)
+
+CV_ENUM(NormCode, cv::NORM_INF, cv::NORM_L1, cv::NORM_L2, cv::NORM_TYPE_MASK, cv::NORM_RELATIVE, cv::NORM_MINMAX)
+
+enum {FLIP_BOTH = 0, FLIP_X = 1, FLIP_Y = -1};
+CV_ENUM(FlipCode, FLIP_BOTH, FLIP_X, FLIP_Y)
+
+CV_ENUM(ReduceOp, CV_REDUCE_SUM, CV_REDUCE_AVG, CV_REDUCE_MAX, CV_REDUCE_MIN)
+
+CV_FLAGS(GemmFlags, cv::GEMM_1_T, cv::GEMM_2_T, cv::GEMM_3_T);
+
+CV_ENUM(MorphOp, cv::MORPH_OPEN, cv::MORPH_CLOSE, cv::MORPH_GRADIENT, cv::MORPH_TOPHAT, cv::MORPH_BLACKHAT)
+
+CV_ENUM(ThreshOp, cv::THRESH_BINARY, cv::THRESH_BINARY_INV, cv::THRESH_TRUNC, cv::THRESH_TOZERO, cv::THRESH_TOZERO_INV)
+
+CV_ENUM(Interpolation, cv::INTER_NEAREST, cv::INTER_LINEAR, cv::INTER_CUBIC)
+
+CV_ENUM(Border, cv::BORDER_REFLECT101, cv::BORDER_REPLICATE, cv::BORDER_CONSTANT, cv::BORDER_REFLECT, cv::BORDER_WRAP)
+
+CV_FLAGS(WarpFlags, cv::INTER_NEAREST, cv::INTER_LINEAR, cv::INTER_CUBIC, cv::WARP_INVERSE_MAP)
+
+CV_ENUM(TemplateMethod, cv::TM_SQDIFF, cv::TM_SQDIFF_NORMED, cv::TM_CCORR, cv::TM_CCORR_NORMED, cv::TM_CCOEFF, cv::TM_CCOEFF_NORMED)
+
+CV_FLAGS(DftFlags, cv::DFT_INVERSE, cv::DFT_SCALE, cv::DFT_ROWS, cv::DFT_COMPLEX_OUTPUT, cv::DFT_REAL_OUTPUT)
+
+void  run_perf_test();
+
+#define PARAM_TEST_CASE(name, ...) struct name : testing::TestWithParam< std::tr1::tuple< __VA_ARGS__ > >
+
+#define GET_PARAM(k) std::tr1::get< k >(GetParam())
+
+#define ALL_DEVICES testing::ValuesIn(devices())
+#define DEVICES(feature) testing::ValuesIn(devices(feature))
+
+#define ALL_TYPES testing::ValuesIn(all_types())
+#define TYPES(depth_start, depth_end, cn_start, cn_end) testing::ValuesIn(types(depth_start, depth_end, cn_start, cn_end))
+
+#define DIFFERENT_SIZES testing::Values(cv::Size(128, 128), cv::Size(113, 113))
+
+#define DIRECT_INVERSE testing::Values(Inverse(false), Inverse(true))
+
+#ifndef ALL_DEPTH
+#define ALL_DEPTH testing::Values(MatDepth(CV_8U), MatDepth(CV_8S), MatDepth(CV_16U), MatDepth(CV_16S), MatDepth(CV_32S), MatDepth(CV_32F), MatDepth(CV_64F))
+#endif
+#define REPEAT   1000
+#define COUNT_U  0 // count the uploading execution time for ocl mat structures
+#define COUNT_D  0
+// the following macro section tests the target function (kernel) performance
+// upload is the code snippet for converting cv::mat to cv::ocl::oclMat
+// downloading is the code snippet for converting cv::ocl::oclMat back to cv::mat
+// change COUNT_U and COUNT_D to take downloading and uploading time into account
+#define P_TEST_FULL( upload, kernel_call, download ) \
+{ \
+    std::cout<< "\n" #kernel_call "\n----------------------"; \
+    {upload;} \
+    R_TEST( kernel_call, 2 ); \
+    double t = (double)cvGetTickCount(); \
+    R_T( { \
+            if( COUNT_U ) {upload;} \
+            kernel_call; \
+            if( COUNT_D ) {download;} \
+            } ); \
+    t = (double)cvGetTickCount() - t; \
+    std::cout << "runtime is  " << t/((double)cvGetTickFrequency()* 1000.) << "ms" << std::endl; \
+}
+
+#define R_T2( test ) \
+{ \
+    std::cout<< "\n" #test "\n----------------------"; \
+    R_TEST( test, 15 ) \
+    clock_t st = clock(); \
+    R_T( test ) \
+    std::cout<< clock() - st << "ms\n"; \
+}
+#define R_T( test ) \
+    R_TEST( test, REPEAT )
+#define R_TEST( test, repeat ) \
+    try{ \
+        for( int i = 0; i < repeat; i ++ ) { test; } \
+    } catch( ... ) { std::cout << "||||| Exception catched! |||||\n"; return; }
+
+//////// Utility
+#ifndef DIFFERENT_SIZES
+#else
+#undef DIFFERENT_SIZES
+#endif
+#define DIFFERENT_SIZES testing::Values(cv::Size(256, 256), cv::Size(3000, 3000))
+
+#define IMAGE_CHANNELS testing::Values(Channels(1), Channels(3), Channels(4))
+#ifndef IMPLEMENT_PARAM_CLASS
+#define IMPLEMENT_PARAM_CLASS(name, type) \
+    class name \
+    { \
+    public: \
+        name ( type arg = type ()) : val_(arg) {} \
+        operator type () const {return val_;} \
+    private: \
+        type val_; \
+    }; \
+    inline void PrintTo( name param, std::ostream* os) \
+    { \
+        *os << #name <<  "(" << testing::PrintToString(static_cast< type >(param)) << ")"; \
+    }
+
+IMPLEMENT_PARAM_CLASS(Channels, int)
+#endif // IMPLEMENT_PARAM_CLASS
+
+       cv::ocl::oclMat createMat(cv::Size size,int type,bool useRoi);
+       cv::ocl::oclMat loadMat(const cv::Mat& m, bool useRoi);
+#endif // __OPENCV_TEST_UTILITY_HPP__